diff --git a/scripts/build-plugins/rollup-plugin-build-themes.js b/scripts/build-plugins/rollup-plugin-build-themes.js index 805590f4..f36db855 100644 --- a/scripts/build-plugins/rollup-plugin-build-themes.js +++ b/scripts/build-plugins/rollup-plugin-build-themes.js @@ -31,12 +31,13 @@ function appendVariablesToCSS(variables, cssSource) { return cssSource + getRootSectionWithVariables(variables); } -function addThemesToConfig(bundle, themeSummary) { +function addThemesToConfig(bundle, themeSummary, defaultThemes) { for (const [fileName, info] of Object.entries(bundle)) { if (fileName === "assets/config.json") { const source = new TextDecoder().decode(info.source); const config = JSON.parse(source); config["themes"] = themeSummary; + config["defaultTheme"] = defaultThemes; info.source = new TextEncoder().encode(JSON.stringify(config)); } } @@ -83,7 +84,7 @@ function parseBundle(bundle) { } module.exports = function buildThemes(options) { - let manifest, variants, defaultDark, defaultLight; + let manifest, variants, defaultDark, defaultLight,defaultThemes = {}; let isDevelopment = false; const virtualModuleId = '@theme/' const resolvedVirtualModuleId = '\0' + virtualModuleId; @@ -110,9 +111,11 @@ module.exports = function buildThemes(options) { // This is the default theme, stash the file name for later if (details.dark) { defaultDark = fileName; + defaultThemes["dark"] = `${name}-${variant}`; } else { defaultLight = fileName; + defaultThemes["light"] = `${name}-${variant}`; } } // emit the css as built theme bundle @@ -274,7 +277,7 @@ module.exports = function buildThemes(options) { themeSummary[`${name}-${variant}`] = assetHashedFileName; }); } - addThemesToConfig(bundle, themeSummary); + addThemesToConfig(bundle, themeSummary, defaultThemes); this.emitFile({ type: "asset", name: "theme-summary.json", diff --git a/src/domain/session/settings/SettingsViewModel.js b/src/domain/session/settings/SettingsViewModel.js index 0bdb1355..083c209e 100644 --- a/src/domain/session/settings/SettingsViewModel.js +++ b/src/domain/session/settings/SettingsViewModel.js @@ -50,6 +50,7 @@ export class SettingsViewModel extends ViewModel { this.minSentImageSizeLimit = 400; this.maxSentImageSizeLimit = 4000; this.pushNotifications = new PushNotificationStatus(); + this._activeTheme = undefined; } get _session() { @@ -76,6 +77,7 @@ export class SettingsViewModel extends ViewModel { this.sentImageSizeLimit = await this.platform.settingsStorage.getInt("sentImageSizeLimit"); this.pushNotifications.supported = await this.platform.notificationService.supportsPush(); this.pushNotifications.enabled = await this._session.arePushNotificationsEnabled(); + this._activeTheme = await this.platform.getActiveTheme(); this.emitChange(""); } @@ -131,6 +133,10 @@ export class SettingsViewModel extends ViewModel { return this.platform.themes; } + get activeTheme() { + return this._activeTheme; + } + setTheme(name) { this.platform.setTheme(name); this.platform.settingsStorage.setString("theme", name); diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index d1b96909..415081ba 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -319,6 +319,23 @@ export class Platform { return Object.keys(this.config["themes"]); } + async getActiveTheme() { + // check if theme is set via settings + let theme = await this.settingsStorage.getString("theme"); + if (theme) { + return theme; + } + // return default theme + if (window.matchMedia) { + if (window.matchMedia("(prefers-color-scheme: dark)")) { + return this.config["defaultTheme"].dark; + } else if (window.matchMedia("(prefers-color-scheme: light)")) { + return this.config["defaultTheme"].light; + } + } + return undefined; + } + setTheme(themeName) { const themeLocation = this.config["themes"][themeName]; if (!themeLocation) { diff --git a/src/platform/web/ui/session/settings/SettingsView.js b/src/platform/web/ui/session/settings/SettingsView.js index b2c78f58..3e62bba6 100644 --- a/src/platform/web/ui/session/settings/SettingsView.js +++ b/src/platform/web/ui/session/settings/SettingsView.js @@ -97,7 +97,9 @@ export class SettingsView extends TemplateView { settingNodes.push( t.h3("Preferences"), row(t, vm.i18n`Scale down images when sending`, this._imageCompressionRange(t, vm)), - row(t, vm.i18n`Use the following theme`, this._themeOptions(t, vm)), + t.map(vm => vm.activeTheme, (theme, t) => { + return row(t, vm.i18n`Use the following theme`, this._themeOptions(t, vm, theme)); + }), ); settingNodes.push( t.h3("Application"), @@ -137,10 +139,10 @@ export class SettingsView extends TemplateView { })]; } - _themeOptions(t, vm) { + _themeOptions(t, vm, activeTheme) { const optionTags = []; for (const name of vm.themes) { - optionTags.push(t.option({value: name}, name)); + optionTags.push(t.option({value: name, selected: name === activeTheme}, name)); } return t.select({onChange: (e) => vm.setTheme(e.target.value)}, optionTags); }