fix: mode listeners not removed

This commit is contained in:
stevapple 2020-04-02 18:02:58 +08:00
parent c820b79095
commit 3843aa3c37
2 changed files with 28 additions and 18 deletions

View File

@ -6,14 +6,14 @@
v-for="(mode, index) in modeOptions" v-for="(mode, index) in modeOptions"
:key="index" :key="index"
:class="getClass(mode.mode)" :class="getClass(mode.mode)"
@click="selectMode(mode)" @click="selectMode(mode.mode)"
>{{ mode.title }}</li> >{{ mode.title }}</li>
</ul> </ul>
</div> </div>
</template> </template>
<script> <script>
import setMode, { activateMode } from './setMode' import setMode from './setMode'
export default { export default {
name: 'ModeOptions', name: 'ModeOptions',
@ -32,21 +32,17 @@ export default {
mounted () { mounted () {
const mode = localStorage.getItem('mode') const mode = localStorage.getItem('mode')
const { mode: customizeMode } = this.$themeConfig const { mode: customizeMode } = this.$themeConfig
this.currentMode = mode === null ? customizeMode === undefined ? 'auto' : customizeMode : mode this.currentMode = mode ?? (customizeMode === null || customizeMode === undefined ? 'auto' : customizeMode)
activateMode(this.currentMode) setMode(this.currentMode)
}, },
methods: { methods: {
selectMode (mode) { selectMode (mode) {
if (mode.mode === this.currentMode) { if (mode !== this.currentMode) {
return this.currentMode = mode
} else if (mode.mode === 'auto') { setMode(mode)
setMode() localStorage.setItem('mode', mode)
} else {
activateMode(mode.mode)
} }
localStorage.setItem('mode', mode.mode)
this.currentMode = mode.mode
}, },
getClass (mode) { getClass (mode) {
return mode !== this.currentMode ? mode : `${mode} active` return mode !== this.currentMode ? mode : `${mode} active`

View File

@ -1,6 +1,6 @@
import modeOptions from './modeOptions' import modeOptions from './modeOptions'
export function activateMode (mode) { function activateMode (mode) {
const rootElement = document.querySelector(':root') const rootElement = document.querySelector(':root')
const options = modeOptions[mode] const options = modeOptions[mode]
@ -9,19 +9,33 @@ export function activateMode (mode) {
} }
} }
// Dark and Light autoswitches
const onDark = (e) => e.matches && activateMode('dark')
const onLight = (e) => e.matches && activateMode('light')
const darkScheme = window.matchMedia('(prefers-color-scheme: dark)')
const lightScheme = window.matchMedia('(prefers-color-scheme: light)')
/** /**
* Sets a color scheme for the website. * Sets a color scheme for the website.
* If browser supports "prefers-color-scheme" it will respect the setting for light or dark mode * If browser supports "prefers-color-scheme" it will respect the setting for light or dark mode
* otherwise it will set a dark theme during night time * otherwise it will set a dark theme during night time
*/ */
export default function setMode () { export default function setMode (mode = 'auto') {
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches if (mode !== 'auto') {
const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches darkScheme.removeListener(onDark)
lightScheme.removeListener(onLight)
activateMode(mode)
return
}
const isDarkMode = darkScheme.matches
const isLightMode = lightScheme.matches
const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
window.matchMedia('(prefers-color-scheme: dark)').addListener(e => e.matches && activateMode('dark')) darkScheme.addListener(onDark)
window.matchMedia('(prefers-color-scheme: light)').addListener(e => e.matches && activateMode('light')) lightScheme.addListener(onLight)
if (isDarkMode) activateMode('dark') if (isDarkMode) activateMode('dark')
if (isLightMode) activateMode('light') if (isLightMode) activateMode('light')