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 13let 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 = window.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) state.primaryColor = colors.primaryColor 114 if (colors.primaryColorDark !== undefined) state.primaryColorDark = colors.primaryColorDark 115 if (colors.secondaryColor !== undefined) state.secondaryColor = colors.secondaryColor 116 if (colors.secondaryColorDark !== undefined) state.secondaryColorDark = colors.secondaryColorDark 117 applyColors() 118} 119 120export function setHasLogo(hasLogo: boolean) { 121 state.hasLogo = hasLogo 122 setFavicon(hasLogo) 123}