aboutsummaryrefslogtreecommitdiff
path: root/www/assets/color-scheme.ts
blob: 62a1b5c68af9492bc6c69b3b82472f1f993565f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const key = "color-scheme"

type scheme = "dark" | "light" | null

function createResetTimer(cleanup: () => void, timeout = 1) {
  let tag = 0
  return () => {
    clearTimeout(tag)
    tag = setTimeout(() => {
      cleanup()
    }, timeout * 1000)
  }
}

let current = localStorage.getItem(key) as scheme

let inited = false

function createToast(duration: number = 1): (text: string) => void {
  const toast = document.createElement("div")
  toast.className = "toast"

  const reset = createResetTimer(() => {
      toast.remove()
  }, duration)

  return (text) => {
    if (!toast.isConnected) {
      document.body.appendChild(toast)
    }
    toast.textContent = text
    reset()
  }
}

const themeToast = createToast()

function setTheme(value: scheme) {
  let message = ""
  current = value

  if (value == null) {
    const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches
    value = prefersDarkScheme ? "dark" : "light"
    message = `theme: system(${value})`
    localStorage.removeItem(key)
  } else {
    message = `theme: force(${value})`
    localStorage.setItem(key, value)
  }

  document.body.dataset["theme"] = value

  if (inited) {
    themeToast(message)
  }
}

setTheme(current)
inited = true

function next(scheme: scheme): scheme {
  switch (scheme) {
    case "dark":
      return "light"
    case "light":
      return null
    default:
      return "dark"
  }
}

window.addEventListener("load", () => {
  const slogon = document.getElementById("slogan")!
  let clicks: number = 0

  const reset = createResetTimer(() => {
    clicks = 0
  })

  slogon.addEventListener("click", () => {
    reset()
    clicks += 1
    if (clicks === 3) {
      setTheme(next(current))
      clicks = 0
    }
  })
})