新增动态主题“道法自然”

This commit is contained in:
lyswhut
2022-03-10 16:07:51 +08:00
parent d35a6f504f
commit 88b3d8ee4a
22 changed files with 358 additions and 32 deletions
-2
View File
@@ -38,8 +38,6 @@ export default {
watch(theme, (val) => {
dom_root.className = val
}, {
immediate: true,
})
watch(font, (val) => {
document.documentElement.style.fontFamily = val
+5 -1
View File
@@ -1,5 +1,5 @@
import { ref, reactive, shallowRef, markRaw } from '@renderer/utils/vueTools'
import { windowSizeList as configWindowSizeList, themes as configThemes } from '@common/config'
import { windowSizeList as configWindowSizeList, themes as configThemes, themeLights as themeLightIds, themeDarks as themeDarkIds } from '@common/config'
import { version } from '../../../../package.json'
process.versions.app = version
@@ -40,6 +40,10 @@ export const isFullscreen = ref(false)
export const windowSizeList = markRaw(configWindowSizeList)
export const themes = markRaw(configThemes)
export const themeLights = markRaw(configThemes.filter(t => themeLightIds.includes(t.id)))
export const themeDarks = markRaw(configThemes.filter(t => themeDarkIds.includes(t.id)))
export const themeShouldUseDarkColors = ref(window.shouldUseDarkColors)
delete window.shouldUseDarkColors
export const qualityList = shallowRef({})
export const setQualityList = _qualityList => {
+8 -2
View File
@@ -1,7 +1,7 @@
import { openUrl } from '@renderer/utils'
import { base as eventBaseName } from '@renderer/event/names'
import { onSetConfig } from '@renderer/utils/tools'
import { isFullscreen } from '@renderer/core/share'
import { onSetConfig, onSystemThemeChange } from '@renderer/utils/tools'
import { isFullscreen, themeShouldUseDarkColors } from '@renderer/core/share'
import { rendererSend, NAMES, rendererInvoke } from '@common/ipc'
import {
@@ -66,6 +66,11 @@ export default ({
window.eventHub.emit(eventBaseName.set_config, config)
})
const rSystemThemeChange = onSystemThemeChange((event, isDark) => {
// console.log(isDark)
themeShouldUseDarkColors.value = isDark
})
window.eventHub.emit(eventBaseName.bindKey)
window.eventHub.on('key_escape_down', handle_key_esc_down)
window.eventHub.on('key_mod+f12_down', handle_open_devtools)
@@ -87,6 +92,7 @@ export default ({
document.body.removeEventListener('click', handleBodyClick)
window.eventHub.emit(eventBaseName.unbindKey)
rSetConfig()
rSystemThemeChange()
if (isProd && !window.dt && !isLinux) {
document.body.removeEventListener('mouseenter', enableIgnoreMouseEvents)
+6 -6
View File
@@ -6,12 +6,6 @@
<title>洛雪音乐助手</title>
</head>
<body>
<script>
if (/theme=(\w+)/.test(window.location.href)) document.body.classList.add(RegExp.$1)
;/dt=(\w+)/.exec(window.location.href)
window.dt = RegExp.$1 == 'true'
document.body.classList.add(window.dt ? 'disableTransparent' : 'transparent')
</script>
<!-- <div id="waiting-mask">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="50%" viewbox="0 0 447.942 447.943">
<path id="logo-path-1" d="M203.806.482c-19.668-3.346-35.76 11.139-35.76 31.086v206.166c-11.642-4.271-24.165-6.725-37.281-6.725-59.905 0-108.469 48.566-108.469 108.473 0 59.903 48.564 108.461 108.469 108.461 34.141 0 64.54-15.82 84.406-40.482l-49.658-49.664c-15.116-15.112-11.708-28.901-9.542-34.14 2.166-5.233 9.514-17.4 30.883-17.4h18.082v-56.885c0-21.132 14.617-38.862 34.266-43.745.032-44.373.032-81.808.032-81.808 140.147 0 131.724 83.974 115.325 132.196-6.42 18.884-2.601 22.05 10.893 7.354C536.473 77.106 298.38 16.566 203.806.482z"/>
@@ -20,5 +14,11 @@
</div> -->
<div id="root" style="display: none;">
</div>
<script>
if (/theme=(\w+)/.test(window.location.href)) document.getElementById('root').classList.add(RegExp.$1)
window.shouldUseDarkColors = /dark=true/.test(window.location.href)
window.dt = /dt=true/.test(window.location.href)
document.body.classList.add(window.dt ? 'disableTransparent' : 'transparent')
</script>
</body>
</html>
+11 -4
View File
@@ -1,17 +1,24 @@
import music from '../utils/music'
import { themes, windowSizeList } from '@renderer/core/share'
import { themes, windowSizeList, themeShouldUseDarkColors } from '@renderer/core/share'
export default {
theme(state) {
let theme = themes.find(theme => theme.id == state.setting.themeId)
return (theme && theme.className) || ''
const themeId = state.setting.theme.id == 'auto'
? themeShouldUseDarkColors.value
? state.setting.theme.darkId
: state.setting.theme.lightId
: state.setting.theme.id
let theme = themes.find(theme => theme.id == themeId) ?? themes[0]
return theme.className
},
font(state) {
return state.setting.font
},
themes(state) {
return {
active: state.setting.themeId,
active: state.setting.theme.id,
lightId: state.setting.theme.lightId,
darkId: state.setting.theme.darkId,
list: themes,
}
},
+1 -1
View File
@@ -1,6 +1,6 @@
export default {
setTheme(state, val) {
state.setting.themeId = val
state.setting.theme.id = val
},
setSearchSource(state, { searchSource, tempSearchSource }) {
console.log(searchSource, tempSearchSource)
+7
View File
@@ -323,3 +323,10 @@ export const setTaskbarThumbnailClip = (clip) => {
export const setTaskbarThumbarButtons = (buttons) => {
rendererSend(NAMES.mainWindow.taskbar_set_thumbar_buttons, buttons)
}
export const onSystemThemeChange = callback => {
rendererOn(NAMES.mainWindow.system_theme_change, callback)
return () => {
rendererOff(callback)
}
}
@@ -4,9 +4,15 @@ dd
h3#basic_theme {{$t('setting__basic_theme')}}
div
ul(:class="$style.theme")
li(v-for="theme in themes.list" :key="theme.id" :tips="$t('theme_' + theme.className)" @click="currentStting.themeId = theme.id" :class="[theme.className, {[$style.active]: themes.active == theme.id}]")
span
li(v-for="theme in themes.list" :key="theme.id" :tips="$t('theme_' + theme.className)" @click="currentStting.theme.id = theme.id" :class="[theme.className, {[$style.active]: themes.active == theme.id}]")
div(:class="$style.bg")
label {{$t('theme_' + theme.className)}}
li(:tips="$t('theme_auto_tip')" @click="handleSetThemeAuto" @contextmenu="isShowThemeSelectorModal = true" :class="[$style.auto, themeClassName, {[$style.active]: themes.active == 'auto'}]")
div(:class="$style.bg")
div(:class="$style.bgContent")
div(:class="[$style.light, themes.lightTheme.className]")
div(:class="[$style.dark, themes.darkTheme.className]")
label {{$t('theme_auto')}}
dd
div
@@ -55,12 +61,13 @@ dd
div
base-selection.gap-teft(:list="fontList" v-model="currentStting.font" item-key="id" item-name="label")
ThemeSelectorModal(v-model="isShowThemeSelectorModal")
play-timeout-modal(v-model="isShowPlayTimeoutModal")
user-api-modal(v-model="isShowUserApiModal")
</template>
<script>
import { computed, ref, useI18n, watch } from '@renderer/utils/vueTools'
import { computed, ref, useI18n, watch, useRefGetter } from '@renderer/utils/vueTools'
import { themes as themeList, windowSizeList, apiSource, userApi, isFullscreen } from '@renderer/core/share'
import { langList } from '@/lang'
import { currentStting } from '../setting'
@@ -68,7 +75,9 @@ import { setWindowSize } from '@renderer/utils'
import apiSourceInfo from '@renderer/utils/music/api-source-info'
import { useTimeout } from '@renderer/utils/timeoutStop'
import { getSystemFonts } from '@renderer/utils/tools'
import { dialog } from '@renderer/plugins/Dialog'
import ThemeSelectorModal from './ThemeSelectorModal'
import PlayTimeoutModal from './PlayTimeoutModal'
import UserApiModal from './UserApiModal'
@@ -76,19 +85,34 @@ import UserApiModal from './UserApiModal'
export default {
name: 'SettingBasic',
components: {
ThemeSelectorModal,
PlayTimeoutModal,
UserApiModal,
},
setup() {
const { t, locale } = useI18n()
const themeClassName = useRefGetter('theme')
const themes = computed(() => {
return {
active: currentStting.value.themeId,
active: currentStting.value.theme.id,
lightTheme: themeList.find(t => t.id == currentStting.value.theme.lightId) ?? themeList[0],
darkTheme: themeList.find(t => t.id == currentStting.value.theme.darkId) ?? themeList[0],
list: themeList,
}
})
const isShowThemeSelectorModal = ref(false)
const handleSetThemeAuto = () => {
if (currentStting.value.theme.id == 'auto') return
currentStting.value.theme.id = 'auto'
if (window.localStorage.getItem('theme-auto-tip') != 'true') {
window.localStorage.setItem('theme-auto-tip', 'true')
dialog({
message: t('setting__basic_theme_auto_tip'),
confirmButtonText: t('ok'),
})
}
}
watch(() => currentStting.value.apiSource, visible => {
apiSource.value = visible
@@ -161,6 +185,9 @@ export default {
return {
currentStting,
themes,
themeClassName,
isShowThemeSelectorModal,
handleSetThemeAuto,
isShowPlayTimeoutModal,
timeLabel,
apiSources,
@@ -200,7 +227,7 @@ export default {
margin-right: 0;
}
span {
.bg {
display: block;
width: 36px;
height: 36px;
@@ -230,7 +257,7 @@ export default {
each(@themes, {
&:global(.@{value}) {
span {
.bg {
&:after {
background-color: ~'@{color-@{value}-theme}';
background-image: ~'@{color-@{value}-theme-bgimg}';
@@ -238,6 +265,68 @@ export default {
}
}
})
&.auto {
>.bg {
&:after {
content: none;
}
}
.bgContent {
position: relative;
height: 100%;
overflow: hidden;
border-radius: 5px;
}
.light, .dark {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
&:after {
display: block;
content: ' ';
width: 100%;
height: 100%;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
}
.light {
&:after {
clip-path: polygon(0 0, 100% 0, 0 100%);
}
each(@themes, {
&:global(.@{value}) {
svg {
fill: ~'@{color-@{value}-theme}';
}
&:after {
background-color: ~'@{color-@{value}-theme}';
background-image: ~'@{color-@{value}-theme-bgimg}';
}
}
})
}
.dark {
&:after {
clip-path: polygon(0 100%, 100% 0, 100% 100%);
}
each(@themes, {
&:global(.@{value}) {
svg {
fill: ~'@{color-@{value}-theme}';
}
&:after {
background-color: ~'@{color-@{value}-theme}';
background-image: ~'@{color-@{value}-theme-bgimg}';
}
}
})
}
}
}
}
@@ -248,7 +337,7 @@ each(@themes, {
&.active {
&:global(.@{value}) {
color: ~'@{color-@{value}-theme}';
span {
.bg {
border-color: ~'@{color-@{value}-theme}';
}
}
@@ -0,0 +1,160 @@
<template lang="pug">
material-modal(:show="modelValue" bg-close @close="$emit('update:modelValue', false)" teleport="#view")
main(:class="$style.main")
h2 {{$t('theme_selector_modal__title')}}
div.scroll(:class="$style.content")
div
h3 {{$t('theme_selector_modal__light_title')}}
ul(:class="$style.theme")
li(v-for="theme in themeLights" :key="theme.id" :tips="$t('theme_' + theme.className)" @click="currentStting.theme.lightId = theme.id" :class="[theme.className, {[$style.active]: lightId == theme.id}]")
span
label {{$t('theme_' + theme.className)}}
div
h3 {{$t('theme_selector_modal__dark_title')}}
ul(:class="$style.theme")
li(v-for="theme in themeDarks" :key="theme.id" :tips="$t('theme_' + theme.className)" @click="currentStting.theme.darkId = theme.id" :class="[theme.className, {[$style.active]: darkId == theme.id}]")
span
label {{$t('theme_' + theme.className)}}
</template>
<script>
import { computed } from '@renderer/utils/vueTools'
import { themeLights, themeDarks } from '@renderer/core/share'
import { currentStting } from '../setting'
export default {
name: 'ThemeSelectorModal',
props: {
modelValue: {
type: Boolean,
default: false,
},
},
setup() {
const lightId = computed(() => {
return currentStting.value.theme.lightId
})
const darkId = computed(() => {
return currentStting.value.theme.darkId
})
return {
currentStting,
themeLights,
themeDarks,
lightId,
darkId,
}
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.main {
// padding: 15px;
// max-width: 400px;
min-width: 300px;
min-height: 0;
// max-height: 100%;
// overflow: hidden;
h2 {
flex: none;
font-size: 16px;
color: @color-theme_2-font;
line-height: 1.3;
text-align: center;
padding: 15px;
}
h3 {
font-size: 16px;
color: @color-theme_2-font;
line-height: 1.3;
padding-bottom: 15px;
font-size: 15px;
}
}
.content {
flex: auto;
padding: 15px;
display: flex;
flex-flow: column nowrap;
gap: 15px;
}
.theme {
display: flex;
flex-flow: row wrap;
// padding: 0 15px;
li {
display: flex;
flex-flow: column nowrap;
align-items: center;
cursor: pointer;
// color: @color-theme;
margin-right: 30px;
transition: color .3s ease;
margin-bottom: 15px;
width: 56px;
&:last-child {
margin-right: 0;
}
span {
display: block;
width: 36px;
height: 36px;
margin-bottom: 5px;
border: 2px solid transparent;
padding: 2px;
transition: border-color .3s ease;
border-radius: 5px;
&:after {
display: block;
content: ' ';
width: 100%;
height: 100%;
border-radius: @radius-border;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
}
label {
width: 100%;
text-align: center;
height: 1.2em;
font-size: 14px;
.mixin-ellipsis-1;
}
each(@themes, {
&:global(.@{value}) {
span {
&:after {
background-color: ~'@{color-@{value}-theme}';
background-image: ~'@{color-@{value}-theme-bgimg}';
}
}
}
})
}
}
each(@themes, {
.theme {
li {
&:global(.@{value}) {
&.active {
color: ~'@{color-@{value}-theme}';
span {
border-color: ~'@{color-@{value}-theme}';
}
}
}
}
}
})
</style>
+5 -1
View File
@@ -86,7 +86,11 @@ export const currentStting = ref({
},
windowSizeId: 1,
langId: 'cns',
themeId: 0,
theme: {
id: 0,
lightId: 0,
darkId: 13,
},
sourceId: 0,
font: '',
isShowAnimation: true,
+1 -1
View File
@@ -158,7 +158,7 @@ export default {
this.sortId = this.sorts[0] && this.sorts[0].id
}
},
'setting.themeId'() {
'setting.theme.id'() {
this.setTagListWidth()
},
},