diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 1509958f1..8186d1ad0 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -305,6 +305,10 @@
"message": "Theme",
"description": "Theme"
},
+ "theme_system": {
+ "message": "System",
+ "description": "Theme that follows the system light/dark setting"
+ },
"theme_light": {
"message": "Light",
"description": "Light theme"
diff --git a/src/components/Popup.vue b/src/components/Popup.vue
index 5ef9d0fd8..e3c91cae5 100644
--- a/src/components/Popup.vue
+++ b/src/components/Popup.vue
@@ -3,16 +3,16 @@
v-cloak
v-bind:class="{
'theme-normal':
- theme !== 'accessibility' &&
- theme !== 'dark' &&
- theme !== 'simple' &&
- theme !== 'compact' &&
- theme !== 'flat',
- 'theme-accessibility': theme === 'accessibility',
- 'theme-dark': theme === 'dark',
- 'theme-simple': theme === 'simple',
- 'theme-compact': theme === 'compact',
- 'theme-flat': theme === 'flat',
+ effectiveTheme !== 'accessibility' &&
+ effectiveTheme !== 'dark' &&
+ effectiveTheme !== 'simple' &&
+ effectiveTheme !== 'compact' &&
+ effectiveTheme !== 'flat',
+ 'theme-accessibility': effectiveTheme === 'accessibility',
+ 'theme-dark': effectiveTheme === 'dark',
+ 'theme-simple': effectiveTheme === 'simple',
+ 'theme-compact': effectiveTheme === 'compact',
+ 'theme-flat': effectiveTheme === 'flat',
hideoutline,
}"
v-on:mousedown="hideoutline = true"
@@ -88,14 +88,35 @@ for (const module of computedPrototype) {
Object.assign(computed, module);
}
+Object.assign(computed, {
+ effectiveTheme(this: { theme: string; systemDark: boolean }) {
+ if (this.theme === "system") {
+ return this.systemDark ? "dark" : "normal";
+ }
+ return this.theme;
+ },
+});
+
+const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
+
export default Vue.extend({
data: function () {
return {
hideoutline: true,
+ systemDark: darkQuery.matches,
};
},
computed,
+ created() {
+ darkQuery.addEventListener("change", this.onSystemThemeChange);
+ },
+ beforeDestroy() {
+ darkQuery.removeEventListener("change", this.onSystemThemeChange);
+ },
methods: {
+ onSystemThemeChange(event: MediaQueryListEvent) {
+ this.systemDark = event.matches;
+ },
hideQr() {
this.$store.commit("style/hideQr");
},
diff --git a/src/components/Popup/PreferencesPage.vue b/src/components/Popup/PreferencesPage.vue
index 299b9d8d1..71d0e80d0 100644
--- a/src/components/Popup/PreferencesPage.vue
+++ b/src/components/Popup/PreferencesPage.vue
@@ -5,6 +5,7 @@
v-model="theme"
style="margin-left: 10px"
>
+
diff --git a/src/store/Menu.ts b/src/store/Menu.ts
index 48487d6ed..2af149119 100644
--- a/src/store/Menu.ts
+++ b/src/store/Menu.ts
@@ -13,7 +13,7 @@ export class Menu implements Module {
useAutofill: UserSettings.items.autofill === true,
smartFilter: UserSettings.items.smartFilter === true,
enableContextMenu: UserSettings.items.enableContextMenu === true,
- theme: UserSettings.items.theme || (isSafari ? "flat" : "normal"),
+ theme: UserSettings.items.theme || (isSafari ? "flat" : "system"),
autolock: Number(UserSettings.items.autolock) || 30,
backupDisabled: await ManagedStorage.get("disableBackup", false),
exportDisabled: await ManagedStorage.get("disableExport", false),