added auto switch theme

allows auto switching between light and dark theme based on system theme
closes #2088 and #1629
This commit is contained in:
Miodec 2022-02-20 17:07:02 +01:00
parent 2c9125124c
commit 775fe34851
8 changed files with 206 additions and 8 deletions

View file

@ -13,6 +13,9 @@ const CARET_STYLES = [
const CONFIG_SCHEMA = joi.object({
theme: joi.string(),
themeLight: joi.string(),
themeDark: joi.string(),
autoSwitchTheme: joi.boolean(),
customTheme: joi.boolean(),
customThemeColors: joi
.array()

View file

@ -24,6 +24,9 @@ let loadDone: (...stuff: any[]) => any;
const defaultConfig: MonkeyTypes.Config = {
theme: "serika_dark",
themeLight: "serika",
themeDark: "serika_dark",
autoSwitchTheme: false,
customTheme: false,
customThemeColors: [
"#323437",
@ -1036,6 +1039,13 @@ export function setIndicateTypos(
ConfigEvent.dispatch("indicateTypos", config.indicateTypos);
}
export function setAutoSwitchTheme(boolean: boolean, nosave?: boolean): void {
boolean = boolean ?? defaultConfig.autoSwitchTheme;
config.autoSwitchTheme = boolean;
if (!nosave) saveToLocalStorage();
ConfigEvent.dispatch("autoSwitchTheme", config.autoSwitchTheme);
}
export function setCustomTheme(boolean: boolean, nosave?: boolean): void {
if (boolean !== undefined) config.customTheme = boolean;
if (!nosave) saveToLocalStorage();
@ -1049,6 +1059,18 @@ export function setTheme(name: string, nosave?: boolean): void {
ConfigEvent.dispatch("theme", config.theme);
}
export function setThemeLight(name: string, nosave?: boolean): void {
config.themeLight = name;
if (!nosave) saveToLocalStorage();
ConfigEvent.dispatch("themeLight", config.themeLight, nosave);
}
export function setThemeDark(name: string, nosave?: boolean): void {
config.themeDark = name;
if (!nosave) saveToLocalStorage();
ConfigEvent.dispatch("themeDark", config.themeDark, nosave);
}
function setThemes(
theme: string,
customState: boolean,
@ -1379,6 +1401,9 @@ export function apply(configObj: MonkeyTypes.Config | null | "null"): void {
);
if (configObj && configObj !== null) {
setCustomThemeColors(configObj.customThemeColors, true);
setThemeLight(configObj.themeLight, true);
setThemeDark(configObj.themeDark, true);
setAutoSwitchTheme(configObj.autoSwitchTheme, true);
setThemes(configObj.theme, configObj.customTheme, true);
// setTheme(configObj.theme, true);
// setCustomTheme(configObj.customTheme, true, true);

View file

@ -224,7 +224,18 @@ export function applyCustomBackground(): void {
}
}
ConfigEvent.subscribe((eventKey, eventValue) => {
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (!Config.autoSwitchTheme || Config.customTheme) return;
if (event.matches) {
set(Config.themeDark);
} else {
set(Config.themeLight);
}
});
ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
if (eventKey === "customTheme")
eventValue ? set("custom") : set(Config.theme);
if (eventKey === "theme") {
@ -236,10 +247,55 @@ ConfigEvent.subscribe((eventKey, eventValue) => {
if (eventValue) {
set("custom");
} else {
set(Config.theme);
if (Config.autoSwitchTheme) {
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
set(Config.themeDark);
} else {
set(Config.themeLight);
}
} else {
set(Config.theme);
}
}
}
if (eventKey === "randomTheme" && eventValue === "off") clearRandom();
if (eventKey === "customBackground") applyCustomBackground();
if (eventKey === "customBackgroundSize") applyCustomBackgroundSize();
if (eventKey === "autoSwitchTheme") {
if (eventValue) {
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
set(Config.themeDark);
} else {
set(Config.themeLight);
}
} else {
set(Config.theme);
}
}
if (
eventKey === "themeLight" &&
Config.autoSwitchTheme &&
!(
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) &&
!nosave
) {
set(Config.themeLight);
}
if (
eventKey === "themeDark" &&
Config.autoSwitchTheme &&
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches &&
!nosave
) {
set(Config.themeDark);
}
});

View file

@ -209,6 +209,11 @@ async function initGroups(): Promise<void> {
UpdateConfig.setStartGraphsAtZero,
"button"
);
groups["autoSwitchTheme"] = new SettingsGroup(
"autoSwitchTheme",
UpdateConfig.setAutoSwitchTheme,
"button"
);
groups["randomTheme"] = new SettingsGroup(
"randomTheme",
UpdateConfig.setRandomTheme,
@ -377,9 +382,7 @@ export function reset(): void {
$(".pageSettings .section.themes .favThemes.buttons").empty();
$(".pageSettings .section.themes .allThemes.buttons").empty();
$(".pageSettings .section.languageGroups .buttons").empty();
$(".pageSettings .section.layout select").empty().select2("destroy");
$(".pageSettings .section.keymapLayout select").empty().select2("destroy");
$(".pageSettings .section.language select").empty().select2("destroy");
$(".pageSettings select").empty().select2("destroy");
$(".pageSettings .section.funbox .buttons").empty();
$(".pageSettings .section.fontFamily .buttons").empty();
}
@ -404,7 +407,9 @@ export async function fillSettingsPage(): Promise<void> {
langComboBox += `</optgroup>`;
languageEl.append(langComboBox);
});
languageEl.select2();
languageEl.select2({
width: "100%",
});
const layoutEl = $(".pageSettings .section.layout select").empty();
layoutEl.append(`<option value='default'>off</option>`);
@ -413,7 +418,9 @@ export async function fillSettingsPage(): Promise<void> {
`<option value='${layout}'>${layout.replace(/_/g, " ")}</option>`
);
});
layoutEl.select2();
layoutEl.select2({
width: "100%",
});
const keymapEl = $(".pageSettings .section.keymapLayout select").empty();
keymapEl.append(`<option value='overrideSync'>emulator sync</option>`);
@ -424,7 +431,37 @@ export async function fillSettingsPage(): Promise<void> {
);
}
});
keymapEl.select2();
keymapEl.select2({
width: "100%",
});
const themeEl1 = $(
".pageSettings .section.autoSwitchThemeInputs select.light"
).empty();
const themeEl2 = $(
".pageSettings .section.autoSwitchThemeInputs select.dark"
).empty();
for (const theme of await Misc.getThemesList()) {
themeEl1.append(
`<option value='${theme.name}'>${theme.name.replace(/_/g, " ")}</option>`
);
themeEl2.append(
`<option value='${theme.name}'>${theme.name.replace(/_/g, " ")}</option>`
);
}
themeEl1.select2({
width: "100%",
});
themeEl2.select2({
width: "100%",
});
$(`.pageSettings .section.autoSwitchThemeInputs select.light`)
.val(Config.themeLight)
.trigger("change.select2");
$(`.pageSettings .section.autoSwitchThemeInputs select.dark`)
.val(Config.themeDark)
.trigger("change.select2");
const funboxEl = $(".pageSettings .section.funbox .buttons").empty();
funboxEl.append(`<div class="funbox button" funbox='none'>none</div>`);
@ -680,6 +717,12 @@ export function update(): void {
$(".pageSettings .section.minBurst input.customMinBurst").val(
Config.minBurstCustomSpeed
);
if (Config.autoSwitchTheme) {
$(".pageSettings .section.autoSwitchThemeInputs").removeClass("hidden");
} else {
$(".pageSettings .section.autoSwitchThemeInputs").addClass("hidden");
}
}
function toggleSettingsGroup(groupName: string): void {
@ -954,6 +997,28 @@ $(".quickNav .links a").on("click", (e) => {
isOpen && toggleSettingsGroup(settingsGroup);
});
$(document).on(
"change",
`.pageSettings .section.autoSwitchThemeInputs select.light`,
(e) => {
const target = $(e.currentTarget);
if (target.hasClass("disabled") || target.hasClass("no-auto-handle"))
return;
UpdateConfig.setThemeLight(target.val() as string);
}
);
$(document).on(
"change",
`.pageSettings .section.autoSwitchThemeInputs select.dark`,
(e) => {
const target = $(e.currentTarget);
if (target.hasClass("disabled") || target.hasClass("no-auto-handle"))
return;
UpdateConfig.setThemeDark(target.val() as string);
}
);
let configEventDisabled = false;
export function setEventDisabled(value: boolean): void {
configEventDisabled = value;

View file

@ -229,6 +229,9 @@ declare namespace MonkeyTypes {
interface Config {
theme: string;
themeLight: string;
themeDark: string;
autoSwitchTheme: boolean;
customTheme: boolean;
customThemeColors: string[];
favThemes: string[];

View file

@ -85,6 +85,15 @@
}
}
&.autoSwitchThemeInputs {
grid-template-areas: unset;
grid-template-columns: 1fr 3fr 1fr 3fr;
gap: 1rem;
select {
width: 100%;
}
}
&.themes .tabContainer [tabcontent="custom"] {
label.button:first-child {
color: var(--text-color);

View file

@ -119,6 +119,11 @@
padding: 0.25rem 0;
}
}
.pageSettings {
.section.autoSwitchThemeInputs {
grid-template-columns: 1fr 3fr;
}
}
.pageAccount {
.group.personalBestTables {
.tables {

View file

@ -3513,6 +3513,38 @@
</div>
</div>
</div>
<div class="section autoSwitchTheme">
<h1>auto switch theme</h1>
<div class="text">
Enabling this will automatically switch the theme between
light and dark depending on the system theme (this will not
override custom theme).
</div>
<div class="buttons">
<div
class="button"
autoSwitchTheme="false"
tabindex="0"
onclick="this.blur();"
>
off
</div>
<div
class="button"
autoSwitchTheme="true"
tabindex="0"
onclick="this.blur();"
>
on
</div>
</div>
</div>
<div class="section autoSwitchThemeInputs">
<div>light</div>
<div><select class="light"></select></div>
<div>dark</div>
<div><select class="dark"></select></div>
</div>
<div class="section randomTheme fullWidth">
<h1>randomize theme</h1>
<div class="text">