Skip to content

Commit a2788e8

Browse files
committed
refactor(frontend): move appearance stuff into service
1 parent fc9f919 commit a2788e8

File tree

3 files changed

+96
-65
lines changed

3 files changed

+96
-65
lines changed

frontend/app/protected/controller.js

+4-65
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,6 @@ import { service } from "@ember/service";
44
import { tracked } from "@glimmer/tracking";
55
import { keyResponder, onKey } from "ember-keyboard";
66

7-
const getHtml = () => document.querySelector("html");
8-
9-
const COLOR_SCHEME_KEY = "color-scheme";
10-
const THEME_KEY = "theme";
11-
12-
/**
13-
* Sets dark or light mode
14-
* @param {"light" | "dark"} colorScheme
15-
* @param {ReturnType<getHtml>} html
16-
**/
17-
const setColorScheme = (colorScheme, html = null) => {
18-
const _html = html ?? getHtml();
19-
localStorage.setItem(COLOR_SCHEME_KEY, colorScheme);
20-
21-
if (colorScheme === "light") {
22-
_html.classList.remove("dark");
23-
return;
24-
}
25-
_html.classList.add("dark");
26-
};
27-
28-
const THEMES = /** @type {const} */ (["old", "regular"]);
29-
30-
/**
31-
* Sets regular or old color scheme
32-
* @param {typeof THEMES[number]} theme
33-
* @param {ReturnType<getHtml>} html
34-
**/
35-
const setTheme = (theme, html = null) => {
36-
const _html = html ?? getHtml();
37-
localStorage.setItem(THEME_KEY, theme);
38-
39-
if (_html.classList.contains(theme)) {
40-
return;
41-
}
42-
_html.classList.remove(...THEMES.filter((t) => t !== theme));
43-
_html.classList.add(theme);
44-
};
45-
46-
const loadConfiguration = () => {
47-
const colorScheme =
48-
localStorage.getItem(COLOR_SCHEME_KEY) ??
49-
(window.matchMedia("(prefers-color-scheme:dark)").matches
50-
? "dark"
51-
: "light");
52-
const theme = localStorage.getItem(THEME_KEY) ?? THEMES[0];
53-
const html = getHtml();
54-
setTheme(theme, html);
55-
setColorScheme(colorScheme, html);
56-
};
57-
58-
const toggleColorScheme = () =>
59-
setColorScheme(
60-
localStorage.getItem(COLOR_SCHEME_KEY) === "dark" ? "light" : "dark",
61-
);
62-
63-
const cycleTheme = () => {
64-
const currentTheme = localStorage.getItem(THEME_KEY);
65-
const newTheme = THEMES[THEMES.indexOf(currentTheme) + 1] ?? THEMES[0];
66-
setTheme(newTheme);
67-
};
68-
697
@keyResponder
708
export default class ProtectedController extends Controller {
719
@service notify;
@@ -74,6 +12,7 @@ export default class ProtectedController extends Controller {
7412
@service currentUser;
7513
@service("autostart-tour") autostartTour;
7614
@service tour;
15+
@service appearance;
7716

7817
@tracked visible;
7918
@tracked loading;
@@ -141,18 +80,18 @@ export default class ProtectedController extends Controller {
14180

14281
constructor(...args) {
14382
super(...args);
144-
loadConfiguration();
83+
this.appearance.loadConfiguration();
14584
}
14685

14786
@onKey("ctrl+,")
14887
_toggleColorScheme(e) {
14988
e.preventDefault();
150-
toggleColorScheme();
89+
this.appearance.toggleColorScheme();
15190
}
15291

15392
@onKey("ctrl+.")
15493
_cycleTheme(e) {
15594
e.preventDefault();
156-
cycleTheme();
95+
this.appearance.cycleTheme();
15796
}
15897
}

frontend/app/services/appearance.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { action } from "@ember/object";
2+
import Service from "@ember/service";
3+
4+
const getHtml = () => document.querySelector("html");
5+
6+
const COLOR_SCHEME_KEY = "color-scheme";
7+
const THEME_KEY = "theme";
8+
9+
const THEMES = /** @type {const} */ (["old", "regular"]);
10+
11+
export default class AppearanceService extends Service {
12+
constructor(...args) {
13+
super(...args);
14+
this.loadConfiguration();
15+
}
16+
17+
loadConfiguration() {
18+
const colorScheme =
19+
this.colorScheme ??
20+
(window.matchMedia("(prefers-color-scheme:dark)").matches
21+
? "dark"
22+
: "light");
23+
const theme = this.theme ?? THEMES[0];
24+
const html = getHtml();
25+
this.setTheme(theme, html);
26+
this.setColorScheme(colorScheme, html);
27+
}
28+
29+
/**
30+
* Sets dark or light mode
31+
* @param {"light" | "dark"} colorScheme
32+
* @param {ReturnType<getHtml>} html
33+
**/
34+
@action
35+
setColorScheme(colorScheme, html = null) {
36+
const _html = html ?? getHtml();
37+
localStorage.setItem(COLOR_SCHEME_KEY, colorScheme);
38+
39+
if (colorScheme === "light") {
40+
_html.classList.remove("dark");
41+
return;
42+
}
43+
_html.classList.add("dark");
44+
}
45+
46+
/**
47+
* Sets regular or old color scheme
48+
* @param {typeof THEMES[number]} theme
49+
* @param {ReturnType<getHtml>} html
50+
**/
51+
@action
52+
setTheme(theme, html = null) {
53+
const _html = html ?? getHtml();
54+
localStorage.setItem(THEME_KEY, theme);
55+
56+
if (_html.classList.contains(theme)) {
57+
return;
58+
}
59+
_html.classList.remove(...THEMES.filter((t) => t !== theme));
60+
_html.classList.add(theme);
61+
}
62+
63+
@action
64+
toggleColorScheme() {
65+
this.setColorScheme(this.colorScheme === "dark" ? "light" : "dark");
66+
}
67+
68+
@action
69+
cycleTheme() {
70+
const newTheme = THEMES[THEMES.indexOf(this.theme) + 1] ?? THEMES[0];
71+
this.setTheme(newTheme);
72+
}
73+
74+
get theme() {
75+
return localStorage.getItem(THEME_KEY);
76+
}
77+
78+
get colorScheme() {
79+
return localStorage.getItem(COLOR_SCHEME_KEY);
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { module, test } from "qunit";
2+
import { setupTest } from "timed/tests/helpers";
3+
4+
module("Unit | Service | appearance", function (hooks) {
5+
setupTest(hooks);
6+
7+
test("it exists", function (assert) {
8+
const service = this.owner.lookup("service:appearance");
9+
assert.ok(service);
10+
});
11+
});

0 commit comments

Comments
 (0)