this repo has no description
1import { api } from "./api"; 2 3interface ServerConfigState { 4 serverName: string | null; 5 primaryColor: string | null; 6 primaryColorDark: string | null; 7 secondaryColor: string | null; 8 secondaryColorDark: string | null; 9 hasLogo: boolean; 10 loading: boolean; 11} 12 13const state = $state<ServerConfigState>({ 14 serverName: null, 15 primaryColor: null, 16 primaryColorDark: null, 17 secondaryColor: null, 18 secondaryColorDark: null, 19 hasLogo: false, 20 loading: true, 21}); 22 23let initialized = false; 24let darkModeQuery: MediaQueryList | null = null; 25 26function isDarkMode(): boolean { 27 return darkModeQuery?.matches ?? false; 28} 29 30function applyColors() { 31 const root = document.documentElement; 32 const dark = isDarkMode(); 33 34 if (dark) { 35 if (state.primaryColorDark) { 36 root.style.setProperty("--accent", state.primaryColorDark); 37 } else { 38 root.style.removeProperty("--accent"); 39 } 40 if (state.secondaryColorDark) { 41 root.style.setProperty("--secondary", state.secondaryColorDark); 42 } else { 43 root.style.removeProperty("--secondary"); 44 } 45 } else { 46 if (state.primaryColor) { 47 root.style.setProperty("--accent", state.primaryColor); 48 } else { 49 root.style.removeProperty("--accent"); 50 } 51 if (state.secondaryColor) { 52 root.style.setProperty("--secondary", state.secondaryColor); 53 } else { 54 root.style.removeProperty("--secondary"); 55 } 56 } 57} 58 59function setFavicon(hasLogo: boolean) { 60 let link = document.querySelector<HTMLLinkElement>("link[rel~='icon']"); 61 if (hasLogo) { 62 if (!link) { 63 link = document.createElement("link"); 64 link.rel = "icon"; 65 document.head.appendChild(link); 66 } 67 link.href = "/logo"; 68 } else if (link) { 69 link.remove(); 70 } 71} 72 73export async function initServerConfig(): Promise<void> { 74 if (initialized) return; 75 initialized = true; 76 77 darkModeQuery = globalThis.matchMedia("(prefers-color-scheme: dark)"); 78 darkModeQuery.addEventListener("change", applyColors); 79 80 try { 81 const config = await api.getServerConfig(); 82 state.serverName = config.serverName; 83 state.primaryColor = config.primaryColor; 84 state.primaryColorDark = config.primaryColorDark; 85 state.secondaryColor = config.secondaryColor; 86 state.secondaryColorDark = config.secondaryColorDark; 87 state.hasLogo = !!config.logoCid; 88 document.title = config.serverName; 89 applyColors(); 90 setFavicon(state.hasLogo); 91 } catch { 92 state.serverName = null; 93 } finally { 94 state.loading = false; 95 } 96} 97 98export function getServerConfigState() { 99 return state; 100} 101 102export function setServerName(name: string) { 103 state.serverName = name; 104 document.title = name; 105} 106 107export function setColors(colors: { 108 primaryColor?: string | null; 109 primaryColorDark?: string | null; 110 secondaryColor?: string | null; 111 secondaryColorDark?: string | null; 112}) { 113 if (colors.primaryColor !== undefined) { 114 state.primaryColor = colors.primaryColor; 115 } 116 if (colors.primaryColorDark !== undefined) { 117 state.primaryColorDark = colors.primaryColorDark; 118 } 119 if (colors.secondaryColor !== undefined) { 120 state.secondaryColor = colors.secondaryColor; 121 } 122 if (colors.secondaryColorDark !== undefined) { 123 state.secondaryColorDark = colors.secondaryColorDark; 124 } 125 applyColors(); 126} 127 128export function setHasLogo(hasLogo: boolean) { 129 state.hasLogo = hasLogo; 130 setFavicon(hasLogo); 131}