import * as React from "bloatless-react"; import CoreViewModel from "./coreViewModel"; import { Languages, ThemeSettings } from "../../Model/Global/settingsModel"; export default class SettingsViewModel { // state username: React.State = new React.State(""); usernameInput: React.State = new React.State(""); isShowingSettingsModal: React.State = new React.State(false); selectedModalPage: React.State = new React.State(undefined); requiresReload = new React.State(false); firstDayOfWeek: React.State = new React.State("0"); language: React.State = new React.State( Languages.English, ); theme: React.State = new React.State( ThemeSettings.System, ); // guards cannotSetName: React.State = React.createProxyState( [this.usernameInput], () => this.usernameInput.value == "" || this.usernameInput.value == this.coreViewModel.settingsModel.username, ); // methods setName = (): void => { this.coreViewModel.settingsModel.setName(this.usernameInput.value); this.username.value = this.coreViewModel.settingsModel.username; this.usernameInput.callSubscriptions(); }; setFirstDayofWeek = (): void => { this.coreViewModel.settingsModel.setFirstDayOfWeek( this.firstDayOfWeek.value, ); }; showSettingsModal = (): void => { this.isShowingSettingsModal.value = true; }; hideSettingsModal = (): void => { this.isShowingSettingsModal.value = false; if (this.requiresReload.value == true) { window.location.reload(); } }; showModalPage = (page: SettingsModalPages): void => { this.selectedModalPage.value = page; }; // view applyTheme = (): void => { let theme = this.theme.value; if (theme == ThemeSettings.System) { theme = SettingsViewModel.getSystemTheme(); } document.body.setAttribute("theme", theme); }; // init constructor(public coreViewModel: CoreViewModel) { this.username.value = coreViewModel.settingsModel.username; this.usernameInput.value = coreViewModel.settingsModel.username; this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek; this.language.value = coreViewModel.settingsModel.language; this.theme.value = coreViewModel.settingsModel.theme; // subscriptions this.firstDayOfWeek.subscribe(this.setFirstDayofWeek); this.language.subscribeSilent((newValue) => { this.coreViewModel.settingsModel.setLanguage(newValue); this.requiresReload.value = true; }); this.theme.subscribeSilent((newValue) => { this.coreViewModel.settingsModel.setTheme(newValue); }); // set theme this.theme.subscribe(() => { this.applyTheme(); }); SettingsViewModel.generateThemeMedia().addEventListener("change", () => this.applyTheme(), ); } static generateThemeMedia(): MediaQueryList { return window.matchMedia("(prefers-color-scheme: dark)"); } static getSystemTheme(): string { const media = SettingsViewModel.generateThemeMedia(); return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light; } } export enum SettingsModalPages { Appearance, Regional, Info, }