From 30927efc60e1428f86a4aa619cb340d9488386ba Mon Sep 17 00:00:00 2001 From: Rocka Date: Sat, 21 Nov 2020 15:14:35 +0800 Subject: [PATCH] renderer: 'auto' theme variety leveraging css prefers-color-scheme --- src/renderer/main.js | 21 +++++++++++++++++++-- src/renderer/page/Settings/Settings.vue | 12 +++++++++--- src/renderer/page/Settings/entries.js | 1 + src/renderer/store/modules/settings.js | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/renderer/main.js b/src/renderer/main.js index 048dd563..0bd59589 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -10,7 +10,7 @@ import App from './App.vue'; import store from './store'; import routes from './routes'; import { isLinux } from './util/globals'; -import { initTheme } from './util/theme'; +import { initTheme, setTheme } from './util/theme'; import DblclickRipple from './util/dblclick-ripple'; import './style.css'; import './transition.css'; @@ -23,12 +23,17 @@ Vue.use(Message); Vue.use(DblclickRipple); Vue.component('RecycleScroller', RecycleScroller); +const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + try { const settings = JSON.parse(sessionStorage.getItem('settings')); + const themeVariety = settings.themeVariety === 'auto' + ? (darkMediaQuery.matches ? 'dark' : 'light') + : settings.themeVariety; initTheme({ primary: settings.themePrimaryColor, secondary: settings.themeSecondaryColor - }, settings.themeVariety); + }, themeVariety); } catch (e) { sessionStorage.removeItem('settings'); } require('@/util/tray').injectStore(store); @@ -76,9 +81,21 @@ if (store.state.settings.startupPage !== 'index') { const app = new Vue({ store, router, + provide: { + darkMediaQuery + }, extends: App }); +darkMediaQuery.addEventListener('change', e => { + if (store.state.settings.themeVariety !== 'auto') return; + const variety = e.matches ? 'dark' : 'light'; + setTheme({ + primary: store.state.settings.themePrimaryColor, + secondary: store.state.settings.themeSecondaryColor + }, variety); +}); + if (isLinux) { app.$once('audio-ready', audio => { const m = require('@/util/mpris'); diff --git a/src/renderer/page/Settings/Settings.vue b/src/renderer/page/Settings/Settings.vue index bf0f94a6..94cb4adc 100644 --- a/src/renderer/page/Settings/Settings.vue +++ b/src/renderer/page/Settings/Settings.vue @@ -51,6 +51,9 @@ export default { versionName: '' }; }, + inject: [ + 'darkMediaQuery' + ], computed: { ...mapState(['settings']) }, @@ -166,10 +169,13 @@ export default { case 'themePrimaryColor': case 'themeSecondaryColor': case 'themeVariety': + const variety = state.settings.themeVariety === 'auto' + ? (this.darkMediaQuery.matches ? 'dark' : 'light') + : state.settings.themeVariety; setTheme({ primary: state.settings.themePrimaryColor, secondary: state.settings.themeSecondaryColor - }, state.settings.themeVariety); + }, variety); break; case 'windowBorder': this.$nextTick(() => this.recreateWindow()); @@ -186,12 +192,12 @@ export default { ipcRenderer.send(IpcTag, key, val); break; case 'bitRate': - if(val === 'ex') { + if (val === 'ex') { this.$toast.message('实际播放码率取决于歌曲最高码率和帐号最高可播放码率'); } break; case 'bitRateDownload': - if(val === 'ex') { + if (val === 'ex') { this.$toast.message('实际下载码率取决于歌曲最高码率和帐号最高可播放码率'); } break; diff --git a/src/renderer/page/Settings/entries.js b/src/renderer/page/Settings/entries.js index d419f39b..241447f2 100644 --- a/src/renderer/page/Settings/entries.js +++ b/src/renderer/page/Settings/entries.js @@ -17,6 +17,7 @@ export const Entries = [ title: '背景色', prop: 'themeVariety', options: [ + { label: '跟随系统', value: 'auto' }, { label: '亮色', value: 'light' }, { label: '暗色', value: 'dark' } ] diff --git a/src/renderer/store/modules/settings.js b/src/renderer/store/modules/settings.js index 462003bb..06272b10 100644 --- a/src/renderer/store/modules/settings.js +++ b/src/renderer/store/modules/settings.js @@ -15,7 +15,7 @@ const DefaultSettings = { minimizeOnStartup: false, themePrimaryColor: '#7e57c2', themeSecondaryColor: '#ff4081', - themeVariety: 'light', + themeVariety: 'auto', autoReplacePlaylist: false };