After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 465 B |
After Width: | Height: | Size: 595 B |
Before Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 958 B |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,114 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
import { useRef, useEffect, useContext } from "react";
|
||||
|
||||
import themes from "utils/styles/themes";
|
||||
import { ColorContext } from "utils/contexts/color";
|
||||
|
||||
export function Svg({ svgRef = null }) {
|
||||
const { color } = useContext(ColorContext);
|
||||
|
||||
const { iconStart, iconEnd } = themes[color];
|
||||
|
||||
return (
|
||||
<svg
|
||||
ref={svgRef}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1024 1024"
|
||||
style={{
|
||||
enableBackground: "new 0 0 1024 1024",
|
||||
}}
|
||||
xmlSpace="preserve"
|
||||
className="w-full h-full"
|
||||
>
|
||||
<style>
|
||||
{
|
||||
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
|
||||
}
|
||||
</style>
|
||||
<g id="Icon">
|
||||
<path
|
||||
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
|
||||
style={{
|
||||
fill: iconStart,
|
||||
}}
|
||||
/>
|
||||
<linearGradient
|
||||
id="homepage_favicon_gradient"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1={200.746}
|
||||
y1={225.015}
|
||||
x2={764.986}
|
||||
y2={789.255}
|
||||
>
|
||||
<stop
|
||||
offset={0}
|
||||
style={{
|
||||
stopColor: iconStart,
|
||||
}}
|
||||
/>
|
||||
<stop
|
||||
offset={1}
|
||||
style={{
|
||||
stopColor: iconEnd,
|
||||
}}
|
||||
/>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
|
||||
style={{
|
||||
fill: "url(#homepage_favicon_gradient})",
|
||||
}}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Favicon() {
|
||||
const svgRef = useRef();
|
||||
const imgRef = useRef();
|
||||
const canvasRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
const svg = svgRef.current;
|
||||
const img = imgRef.current;
|
||||
const canvas = canvasRef.current;
|
||||
|
||||
if (!svg || !img || !canvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
const xml = new XMLSerializer().serializeToString(svg);
|
||||
|
||||
const svg64 = Buffer.from(xml).toString("base64");
|
||||
const b64Start = "data:image/svg+xml;base64,";
|
||||
|
||||
// prepend a "header"
|
||||
const image64 = b64Start + svg64;
|
||||
|
||||
// set it as the source of the img element
|
||||
img.onload = () => {
|
||||
// draw the image onto the canvas
|
||||
canvas.getContext("2d").drawImage(img, 0, 0);
|
||||
// canvas.width = 256;
|
||||
// canvas.height = 256;
|
||||
|
||||
const link = window.document.createElement("link");
|
||||
link.type = "image/x-icon";
|
||||
link.rel = "shortcut icon";
|
||||
link.href = canvas.toDataURL("image/x-icon");
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
};
|
||||
|
||||
img.src = image64;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="hidden">
|
||||
<Svg svgRef={svgRef} />
|
||||
<img width={64} height={64} ref={imgRef} />
|
||||
<canvas width={64} height={64} ref={canvasRef} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
export default function Logo() {
|
||||
return (
|
||||
<div className="w-12 h-12 flex flex-row items-center align-middle mr-3 self-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1024 1024"
|
||||
style={{
|
||||
enableBackground: "new 0 0 1024 1024",
|
||||
}}
|
||||
xmlSpace="preserve"
|
||||
className="w-full h-full"
|
||||
>
|
||||
<style>
|
||||
{
|
||||
".st0{display:none}.st3{stroke-linecap:square}.st3,.st4{fill:none;stroke:#fff;stroke-miterlimit:10}.st6{display:inline;fill:#333}.st7{fill:#fff}"
|
||||
}
|
||||
</style>
|
||||
<g id="Icon">
|
||||
<path
|
||||
d="M771.9 191c27.7 0 50.1 26.5 50.1 59.3v186.4l-100.2.3V250.3c0-32.8 22.4-59.3 50.1-59.3z"
|
||||
style={{
|
||||
fill: "rgba(var(--color-logo-start))",
|
||||
}}
|
||||
/>
|
||||
<linearGradient
|
||||
id="homepage_logo_gradient"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1={200.746}
|
||||
y1={225.015}
|
||||
x2={764.986}
|
||||
y2={789.255}
|
||||
>
|
||||
<stop
|
||||
offset={0}
|
||||
style={{
|
||||
stopColor: "rgba(var(--color-logo-start))",
|
||||
}}
|
||||
/>
|
||||
<stop
|
||||
offset={1}
|
||||
style={{
|
||||
stopColor: "rgba(var(--color-logo-stop))",
|
||||
}}
|
||||
/>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M721.8 250.3c0-32.7 22.4-59.3 50.1-59.3H253.1c-27.7 0-50.1 26.5-50.1 59.3v582.2l90.2-75.7-.1-130.3H375v61.8l88-73.8 258.8 217.9V250.6"
|
||||
style={{
|
||||
fill: "url(#homepage_logo_gradient)",
|
||||
}}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import checkAndCopyConfig, { getSettings } from "utils/config/config";
|
||||
|
||||
export default function handler({ res }) {
|
||||
checkAndCopyConfig("settings.yaml");
|
||||
const settings = getSettings();
|
||||
|
||||
const color = settings.color || "slate";
|
||||
const theme = settings.theme || "dark";
|
||||
|
||||
return res.status(200).json({
|
||||
color,
|
||||
theme,
|
||||
});
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
import { getSettings } from "utils/config/config";
|
||||
import themes from "utils/styles/themes";
|
||||
|
||||
export async function getServerSideProps({ res }) {
|
||||
const settings = getSettings();
|
||||
|
||||
const color = settings.color || "slate";
|
||||
const theme = settings.theme || "dark";
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png?v=2"/>
|
||||
<TileColor>${themes[color][theme]}</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>`;
|
||||
|
||||
res.setHeader("Content-Type", "text/xml");
|
||||
res.write(xml);
|
||||
res.end();
|
||||
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
}
|
||||
|
||||
export default function BrowserConfig() {}
|
@ -0,0 +1,42 @@
|
||||
import checkAndCopyConfig, { getSettings } from "utils/config/config";
|
||||
import themes from "utils/styles/themes";
|
||||
|
||||
export async function getServerSideProps({ res }) {
|
||||
checkAndCopyConfig("settings.yaml");
|
||||
const settings = getSettings();
|
||||
|
||||
const color = settings.color || "slate";
|
||||
const theme = settings.theme || "dark";
|
||||
|
||||
const manifest = {
|
||||
name: "Homepage",
|
||||
short_name: "Homepage",
|
||||
icons: [
|
||||
{
|
||||
src: "/android-chrome-192x192.png?v=2",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "/android-chrome-512x512.png?v=2",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
theme_color: themes[color][theme],
|
||||
background_color: themes[color][theme],
|
||||
display: "standalone",
|
||||
};
|
||||
|
||||
res.setHeader("Content-Type", "application/manifest+json");
|
||||
res.write(JSON.stringify(manifest));
|
||||
res.end();
|
||||
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
}
|
||||
|
||||
export default function Webmanifest() {
|
||||
return null;
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
const themes = {
|
||||
white: {
|
||||
light: "#ffffff",
|
||||
iconStart: "#ffffff",
|
||||
iconEnd: "#282828",
|
||||
dark: "#ffffff",
|
||||
},
|
||||
slate: {
|
||||
light: "#f8fafc",
|
||||
iconStart: "#94a3b8",
|
||||
iconEnd: "#334155",
|
||||
dark: "#1e293b",
|
||||
},
|
||||
gray: {
|
||||
light: "#f9fafb",
|
||||
iconStart: "#9ca3af",
|
||||
iconEnd: "#374151",
|
||||
dark: "#1f2937",
|
||||
},
|
||||
zinc: {
|
||||
light: "#fafafa",
|
||||
iconStart: "#a1a1aa",
|
||||
iconEnd: "#3f3f46",
|
||||
dark: "#27272a",
|
||||
},
|
||||
neutral: {
|
||||
light: "#fafafa",
|
||||
iconStart: "#a3a3a3",
|
||||
iconEnd: "#404040",
|
||||
dark: "#262626",
|
||||
},
|
||||
stone: {
|
||||
light: "#fafaf9",
|
||||
iconStart: "#a8a29e",
|
||||
iconEnd: "#44403c",
|
||||
dark: "#292524",
|
||||
},
|
||||
red: {
|
||||
light: "#fef2f2",
|
||||
iconStart: "#f87171",
|
||||
iconEnd: "#b91c1c",
|
||||
dark: "#991b1b",
|
||||
},
|
||||
orange: {
|
||||
light: "#fff7ed",
|
||||
iconStart: "#fb923c",
|
||||
iconEnd: "#c2410c",
|
||||
dark: "#9a3412",
|
||||
},
|
||||
amber: {
|
||||
light: "#fffbeb",
|
||||
iconStart: "#fbbf24",
|
||||
iconEnd: "#b45309",
|
||||
dark: "#92400e",
|
||||
},
|
||||
yellow: {
|
||||
light: "#fefce8",
|
||||
iconStart: "#facc15",
|
||||
iconEnd: "#a16207",
|
||||
dark: "#854d0e",
|
||||
},
|
||||
lime: {
|
||||
light: "#f7fee7",
|
||||
iconStart: "#a3e635",
|
||||
iconEnd: "#4d7c0f",
|
||||
dark: "#3f6212",
|
||||
},
|
||||
green: {
|
||||
light: "#f0fdf4",
|
||||
iconStart: "#4ade80",
|
||||
iconEnd: "#15803d",
|
||||
dark: "#166534",
|
||||
},
|
||||
emerald: {
|
||||
light: "#ecfdf5",
|
||||
iconStart: "#34d399",
|
||||
iconEnd: "#047857",
|
||||
dark: "#065f46",
|
||||
},
|
||||
teal: {
|
||||
light: "#f0fdfa",
|
||||
iconStart: "#2dd4bf",
|
||||
iconEnd: "#0f766e",
|
||||
dark: "#115e59",
|
||||
},
|
||||
cyan: {
|
||||
light: "#ecfeff",
|
||||
iconStart: "#22d3ee",
|
||||
iconEnd: "#0e7490",
|
||||
dark: "#155e75",
|
||||
},
|
||||
sky: {
|
||||
light: "#f0f9ff",
|
||||
iconStart: "#38bdf8",
|
||||
iconEnd: "#0369a1",
|
||||
dark: "#075985",
|
||||
},
|
||||
blue: {
|
||||
light: "#eff6ff",
|
||||
iconStart: "#60a5fa",
|
||||
iconEnd: "#1d4ed8",
|
||||
dark: "#1e40af",
|
||||
},
|
||||
indigo: {
|
||||
light: "#eef2ff",
|
||||
iconStart: "#818cf8",
|
||||
iconEnd: "#4338ca",
|
||||
dark: "#3730a3",
|
||||
},
|
||||
violet: {
|
||||
light: "#f5f3ff",
|
||||
iconStart: "#a78bfa",
|
||||
iconEnd: "#6d28d9",
|
||||
dark: "#5b21b6",
|
||||
},
|
||||
purple: {
|
||||
light: "#faf5ff",
|
||||
iconStart: "#c084fc",
|
||||
iconEnd: "#7e22ce",
|
||||
dark: "#6b21a8",
|
||||
},
|
||||
fuchsia: {
|
||||
light: "#fdf4ff",
|
||||
iconStart: "#e879f9",
|
||||
iconEnd: "#a21caf",
|
||||
dark: "#86198f",
|
||||
},
|
||||
pink: {
|
||||
light: "#fdf2f8",
|
||||
iconStart: "#f472b6",
|
||||
iconEnd: "#be185d",
|
||||
dark: "#9d174d",
|
||||
},
|
||||
rose: {
|
||||
light: "#fff1f2",
|
||||
iconStart: "#fb7185",
|
||||
iconEnd: "#be123c",
|
||||
dark: "#9f1239",
|
||||
},
|
||||
};
|
||||
|
||||
export default themes;
|