Skip to content

Commit 1bbea5d

Browse files
committed
wip
1 parent ffe32f1 commit 1bbea5d

File tree

18 files changed

+169
-120
lines changed

18 files changed

+169
-120
lines changed

frontend/scripts/check-assets.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { Layout, ThemeName } from "@monkeytype/schemas/configs";
1717
import { LayoutsList } from "../src/ts/constants/layouts";
1818
import { KnownFontName } from "@monkeytype/schemas/fonts";
1919
import { Fonts } from "../src/ts/constants/fonts";
20-
import { ThemesList } from "../src/ts/constants/themes";
20+
import { themes, ThemeSchema, ThemesList } from "../src/ts/constants/themes";
2121
import { z } from "zod";
2222
import { ChallengeSchema, Challenge } from "@monkeytype/schemas/challenges";
2323
import { LayoutObject, LayoutObjectSchema } from "@monkeytype/schemas/layouts";
@@ -381,20 +381,27 @@ async function validateThemes(): Promise<void> {
381381
//no missing files
382382
const themeFiles = fs.readdirSync("./static/themes");
383383

384-
//missing theme files
385-
ThemesList.filter((it) => !themeFiles.includes(it.name + ".css")).forEach(
386-
(it) =>
387-
problems.add(
388-
it.name,
389-
`missing file frontend/static/themes/${it.name}.css`,
390-
),
384+
//missing or additional theme files (mismatch in hasCss)
385+
ThemesList.filter(
386+
(it) => themeFiles.includes(it.name + ".css") !== (it.hasCss ?? false),
387+
).forEach((it) =>
388+
problems.add(
389+
it.name,
390+
`${it.hasCss ? "missing" : "additional"} file frontend/static/themes/${it.name}.css`,
391+
),
391392
);
392393

393394
//additional theme files
394395
themeFiles
395396
.filter((it) => !ThemesList.some((theme) => theme.name + ".css" === it))
396397
.forEach((it) => problems.add("_additional", it));
397398

399+
//validate theme colors are valid hex colors, not covered by typescipt
400+
for (const name of Object.keys(themes)) {
401+
const theme = themes[name as ThemeName];
402+
problems.addValidation(name as ThemeName, ThemeSchema.safeParse(theme));
403+
}
404+
398405
console.log(problems.toString());
399406

400407
if (problems.hasError()) {

frontend/src/html/head.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
<meta charset="UTF-8" />
2727
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
2828
<title>Monkeytype | A minimalistic, customizable typing test</title>
29-
<!-- default colors in case theme file fails to load -->
30-
<ThemeColors />
29+
<Theme />
3130
<link
3231
rel="icon"
3332
type="image/x-icon"

frontend/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
async
7272
defer
7373
></script>
74-
<link rel="stylesheet" id="currentTheme" />
74+
7575
<link rel="stylesheet" href="" id="globalFunBoxTheme" type="text/css" />
7676
<script type="module" src="ts/index.ts"></script>
7777
</body>

frontend/src/ts/auth.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ export async function onAuthStateChanged(
144144

145145
if (authInitialisedAndConnected) {
146146
console.debug(`auth state changed, user ${user ? "true" : "false"}`);
147-
console.debug(user);
148147
if (user) {
149148
userPromise = loadUser(user);
150149
} else {

frontend/src/ts/commandline/lists/themes.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ import Config, { setConfig } from "../../config";
22
import { capitalizeFirstLetterOfEachWord } from "../../utils/strings";
33
import * as ThemeController from "../../controllers/theme-controller";
44
import { Command, CommandsSubgroup } from "../types";
5-
import { Theme, ThemesList } from "../../constants/themes";
5+
import { ThemesList, ThemeWithName } from "../../constants/themes";
66
import { not } from "@monkeytype/util/predicates";
77
import * as ConfigEvent from "../../observables/config-event";
88
import * as Misc from "../../utils/misc";
99

10-
const isFavorite = (theme: Theme): boolean =>
10+
const isFavorite = (theme: ThemeWithName): boolean =>
1111
Config.favThemes.includes(theme.name);
1212

1313
/**
1414
* creates a theme command object for the given theme
1515
* @param theme the theme to create a command for
1616
* @returns a command object for the theme
1717
*/
18-
const createThemeCommand = (theme: Theme): Command => {
18+
const createThemeCommand = (theme: ThemeWithName): Command => {
1919
return {
2020
id: "changeTheme" + capitalizeFirstLetterOfEachWord(theme.name),
2121
display: theme.name.replace(/_/g, " "),
@@ -43,7 +43,7 @@ const createThemeCommand = (theme: Theme): Command => {
4343
* @param themes the themes to sort
4444
* @returns sorted array of themes
4545
*/
46-
const sortThemesByFavorite = (themes: Theme[]): Theme[] => [
46+
const sortThemesByFavorite = (themes: ThemeWithName[]): ThemeWithName[] => [
4747
...themes.filter(isFavorite),
4848
...themes.filter(not(isFavorite)),
4949
];
@@ -65,7 +65,7 @@ const commands: Command[] = [
6565
},
6666
];
6767

68-
export function update(themes: Theme[]): void {
68+
export function update(themes: ThemeWithName[]): void {
6969
// clear the current list
7070
subgroup.list = [];
7171

frontend/src/ts/components/common/ChartJs.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,10 @@ export function ChartJs<T extends ChartType, TData = DefaultDataPoint<T>>(
4848
chart.options = props.options;
4949
}
5050
chart.update();
51-
void chart.updateColors();
5251
});
5352

5453
createEffect(() => {
55-
//react on theme changes
5654
const colors = getThemeColors();
57-
console.log("#####", { colors });
5855
if (!chart) return;
5956

6057
void chart.updateColors(colors);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { createEffect, createMemo, JSXElement } from "solid-js";
2+
import { getThemeColors } from "../../signals/theme";
3+
import { useRefWithUtils } from "../../hooks/useRefWithUtils";
4+
import { getThemeIndicator } from "../../signals/core";
5+
import { themes, Theme as ThemeType } from "../../constants/themes";
6+
import { ThemeName } from "@monkeytype/schemas/configs";
7+
import { qsr } from "../../utils/dom";
8+
9+
export function Theme(): JSXElement {
10+
// Refs are assigned by SolidJS via the ref attribute
11+
const [styleRef, styleEl] = useRefWithUtils<HTMLStyleElement>();
12+
13+
//Use memo to ignore signals without changes
14+
const themeName = createMemo(() => getThemeIndicator().text);
15+
const themeColors = createMemo(() => getThemeColors());
16+
17+
createEffect(() => {
18+
const colors = themeColors();
19+
styleEl()?.setHtml(`
20+
:root {
21+
22+
--bg-color: ${colors.bg};
23+
--main-color: ${colors.main};
24+
--caret-color: ${colors.caret};
25+
--sub-color: ${colors.sub};
26+
--sub-alt-color: ${colors.subAlt};
27+
--text-color: ${colors.text};
28+
--error-color: ${colors.error};
29+
--error-extra-color:${colors.errorExtra};
30+
--colorful-error-color: ${colors.colorfulError};
31+
--colorful-error-extra-color: ${colors.colorfulErrorExtra};
32+
}
33+
`);
34+
});
35+
36+
createEffect(() => {
37+
const theme: ThemeType | undefined = themes[themeName() as ThemeName];
38+
39+
const cssFile = theme?.hasCss ? `/themes/${themeName()}.css` : "";
40+
41+
//TODO move the code here or add loader animation?
42+
//void loadStyle(themeName(), { hasCss: theme?.hasCss ?? false });
43+
44+
const linkElement = qsr("#currentTheme").setAttribute("href", cssFile);
45+
const parent = qsr("head");
46+
linkElement.remove();
47+
parent.append(linkElement);
48+
});
49+
50+
return (
51+
<>
52+
<style ref={styleRef}></style>;
53+
<link rel="stylesheet" id="currentTheme" />
54+
</>
55+
);
56+
}

frontend/src/ts/components/layout/ThemeColors.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

frontend/src/ts/components/mount.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import { JSXElement } from "solid-js";
55
import { Footer } from "./layout/footer/Footer";
66
import { Modals } from "./modals/Modals";
77
import { AboutPage } from "./pages/AboutPage";
8-
import { ThemeColors } from "./layout/ThemeColors";
8+
import { Theme } from "./layout/Theme";
99

1010
const components: Record<string, () => JSXElement> = {
1111
Footer: () => <Footer />,
1212
Modals: () => <Modals />,
1313
AboutPage: () => <AboutPage />,
14-
ThemeColors: () => <ThemeColors />,
14+
Theme: () => <Theme />,
1515
};
1616

1717
function mountToMountpoint(name: string, component: () => JSXElement): void {

frontend/src/ts/components/pages/AboutPage.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createEffect, createResource, For, JSXElement, Show } from "solid-js";
1+
import { createResource, For, JSXElement, Show } from "solid-js";
22
import "./AboutPage.scss";
33
import { Button } from "../common/Button";
44
import { showModal } from "../../stores/modals";
@@ -10,7 +10,6 @@ import Ape from "../../ape";
1010
import { intervalToDuration } from "date-fns";
1111
import { getNumberWithMagnitude, numberWithSpaces } from "../../utils/numbers";
1212
import { ChartJs } from "../common/ChartJs";
13-
import { getThemeColors } from "../../signals/theme";
1413

1514
export function AboutPage(): JSXElement {
1615
const isOpen = (): boolean => getActivePage() === "about";
@@ -29,10 +28,6 @@ export function AboutPage(): JSXElement {
2928
open ? await fetchSpeedHistogram() : undefined,
3029
);
3130

32-
createEffect(() => {
33-
console.log(getThemeColors());
34-
});
35-
3631
return (
3732
<Show when={isOpen}>
3833
<div class="created">

0 commit comments

Comments
 (0)