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}