Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/account/dark-mode.ts
5857 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { isEqual, debounce } from "lodash";
7
8
import { DARK_MODE_DEFAULTS } from "@cocalc/util/db-schema/accounts";
9
import { AccountStore } from "./store";
10
11
export const DARK_MODE_KEYS = ["brightness", "contrast", "sepia"] as const;
12
13
type Config = Record<(typeof DARK_MODE_KEYS)[number], number>;
14
15
export const DARK_MODE_MINS: Config = {
16
brightness: 30,
17
contrast: 30,
18
sepia: 0,
19
} as const;
20
21
// Returns number between 0 and 100.
22
function to_number(x: any, default_value: number): number {
23
if (x == null) return default_value;
24
try {
25
x = parseInt(x);
26
if (isNaN(x)) {
27
return default_value;
28
}
29
if (x < 0) {
30
x = 0;
31
}
32
if (x > 100) {
33
x = 100;
34
}
35
return x;
36
} catch (_) {
37
return default_value;
38
}
39
}
40
41
export function get_dark_mode_config(other_settings?: {
42
dark_mode_brightness?: number;
43
dark_mode_contrast?: number;
44
dark_mode_sepia?: number;
45
}): Config {
46
const config = {} as Config;
47
48
for (const key of DARK_MODE_KEYS) {
49
config[key] = Math.max(
50
DARK_MODE_MINS[key],
51
to_number(other_settings?.[`dark_mode_${key}`], DARK_MODE_DEFAULTS[key]),
52
);
53
}
54
55
return config;
56
}
57
58
let currentDarkMode: boolean = false;
59
let last_dark_mode: boolean = false;
60
let last_config: Config | undefined = undefined;
61
62
export function init_dark_mode(account_store: AccountStore): void {
63
account_store.on(
64
"change",
65
debounce(
66
async () => {
67
const dark_mode = !!account_store.getIn([
68
"other_settings",
69
"dark_mode",
70
]);
71
currentDarkMode = dark_mode;
72
const config = get_dark_mode_config(
73
account_store.get("other_settings")?.toJS(),
74
);
75
if (
76
dark_mode == last_dark_mode &&
77
(!dark_mode || isEqual(last_config, config))
78
) {
79
return;
80
}
81
const { enable, disable } = await import("darkreader");
82
last_dark_mode = dark_mode;
83
last_config = config;
84
if (dark_mode) {
85
disable();
86
enable(config);
87
} else {
88
disable();
89
}
90
},
91
1000,
92
{ trailing: true, leading: false },
93
),
94
);
95
}
96
97
export function inDarkMode() {
98
return currentDarkMode;
99
}
100
101