Extract theme domain into useThemeStore

main
Warinyourself 4 weeks ago
parent 30507d76de
commit 861f406d45

@ -1,5 +1,5 @@
import { defineComponent, computed, h } from 'vue'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import flow from '@/components/themes/flow'
import sphere from '@/components/themes/sphere'
@ -24,8 +24,8 @@ const themeMap: Record<string, any> = {
export default defineComponent({
name: 'BackgroundImage',
setup() {
const appStore = useAppStore()
const theme = computed(() => appStore.activeTheme)
const themeStore = useThemeStore()
const theme = computed(() => themeStore.activeTheme)
return () => {
const component = themeMap[theme.value.component ?? 'random'] ?? themeMap.random

@ -1,14 +1,14 @@
import { CircleX, Palette, SlidersHorizontal, Settings } from '@lucide/vue'
import { defineComponent, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import { usePageStore } from '@/store/page'
import SettingsView from './settings/SettingsView'
export default defineComponent({
name: 'SettingsComponent',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const pageStore = usePageStore()
const { t } = useI18n()
@ -19,7 +19,7 @@ export default defineComponent({
{ label: t('settings.choice-themes'), icon: Palette },
{ label: t('settings.title'), icon: Settings }
]
if (appStore.activeTheme?.settings?.length !== undefined) {
if (themeStore.activeTheme?.settings?.length !== undefined) {
list.splice(1, 0, { label: t('settings.customize-theme'), icon: SlidersHorizontal })
}
return list

@ -1,6 +1,6 @@
import { defineComponent, computed, type VNode } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import AppSlider from '@/components/app/AppSlider'
import AppButton from '@/components/app/AppButton'
import AppSwitch from '@/components/app/AppSwitch'
@ -19,10 +19,10 @@ import type {
export default defineComponent({
name: 'SettingsCustom',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const { t } = useI18n()
const inputs = computed(() => appStore.activeTheme?.settings || [])
const inputs = computed(() => themeStore.activeTheme?.settings || [])
const buildSlider = (input: AppInputThemeSlider) => {
const { label, value, options: { step, min: from, max: to } } = input
@ -34,7 +34,7 @@ export default defineComponent({
label={label}
modelValue={value as number}
onUpdate:modelValue={(v: number) => {
appStore.changeSettingsThemeInput({ key: input.name, value: v })
themeStore.changeSettingsThemeInput({ key: input.name, value: v })
input.callback?.(v)
}}
/>
@ -49,7 +49,7 @@ export default defineComponent({
items={[...values]}
modelValue={value as string}
onUpdate:modelValue={(v: string) => {
appStore.changeSettingsThemeInput({ key: input.name, value: v })
themeStore.changeSettingsThemeInput({ key: input.name, value: v })
}}
/>
)
@ -63,7 +63,7 @@ export default defineComponent({
label={label}
modelValue={value as string}
onUpdate:modelValue={(color: AppInputColor) => {
appStore.changeSettingsThemeInput({ key: input.name, value: color.hex })
themeStore.changeSettingsThemeInput({ key: input.name, value: color.hex })
input.callback?.(color.hex)
}}
/>
@ -77,7 +77,7 @@ export default defineComponent({
label={t(label)}
modelValue={value as boolean}
onUpdate:modelValue={(v: boolean) => {
appStore.changeSettingsThemeInput({ key: input.name, value: v })
themeStore.changeSettingsThemeInput({ key: input.name, value: v })
input.callback?.(v)
}}
/>
@ -92,7 +92,7 @@ export default defineComponent({
modelValue={value as number}
values={values}
onUpdate:modelValue={(v: number) => {
appStore.changeSettingsThemeInput({ key: input.name, value: v })
themeStore.changeSettingsThemeInput({ key: input.name, value: v })
}}
/>
)

@ -1,5 +1,5 @@
import { defineComponent, computed } from 'vue'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
const themeImages = import.meta.glob('@/assets/images/themes/*/index.png', { eager: true, import: 'default' }) as Record<string, string>
@ -11,9 +11,9 @@ function getThemeImage(name: string): string {
export default defineComponent({
name: 'SettingsThemes',
setup() {
const appStore = useAppStore()
const themes = computed(() => appStore.themes)
const activeTheme = computed(() => appStore.activeTheme)
const themeStore = useThemeStore()
const themes = computed(() => themeStore.themes)
const activeTheme = computed(() => themeStore.activeTheme)
return () => (
<div class="user-settings-themes">
@ -22,7 +22,7 @@ export default defineComponent({
return (
<img
class={`user-settings-theme ${isActive ? 'active' : ''}`}
onClick={() => appStore.changeTheme(theme.name)}
onClick={() => themeStore.changeTheme(theme.name)}
src={getThemeImage(theme.name)}
/>
)

@ -1,5 +1,5 @@
import { defineComponent, computed } from 'vue'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import { usePageStore } from '@/store/page'
import SettingsThemes from './SettingsThemes'
import SettingsCustom from './SettingsCustom'
@ -8,13 +8,13 @@ import SettingsGeneral from './general/SettingsGeneral'
export default defineComponent({
name: 'SettingsView',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const pageStore = usePageStore()
const mainTabIndex = computed(() => pageStore.mainTabIndex)
return () => {
const mapTabs = [<SettingsThemes />, <SettingsGeneral />]
const hasThemeSettings = appStore.activeTheme?.settings?.length
const hasThemeSettings = themeStore.activeTheme?.settings?.length
if (hasThemeSettings) {
mapTabs.splice(1, 0, <SettingsCustom />)

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,13 +9,13 @@ let render: GL
export default defineComponent({
name: 'DestructionTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const perspective = computed(() => appStore.getThemeInput('perspective')?.value as number || 0.2)
const position = computed(() => appStore.getThemeInput('position')?.value as number || 0.2)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const perspective = computed(() => themeStore.getThemeInput('perspective')?.value as number || 0.2)
const position = computed(() => themeStore.getThemeInput('position')?.value as number || 0.2)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
onMounted(() => {
render = new GL(

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,15 +9,15 @@ let render: GL
export default defineComponent({
name: 'FlowTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const hue = computed(() => appStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => appStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => appStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const size = computed(() => appStore.getThemeInput('size')?.value as number || 0.2)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const hue = computed(() => themeStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => themeStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => themeStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const size = computed(() => themeStore.getThemeInput('size')?.value as number || 0.2)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
const styleCanvas = computed(() => ({
filter: `hue-rotate(${hue.value}deg) invert(${Number(invert.value)}) brightness(${brightness.value})`

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,12 +9,12 @@ let render: GL
export default defineComponent({
name: 'PlanetTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const position = computed(() => appStore.getThemeInput('position')?.value as number || 2.14)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const position = computed(() => themeStore.getThemeInput('position')?.value as number || 2.14)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
onMounted(() => {
render = new GL(

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,12 +9,12 @@ let render: GL
export default defineComponent({
name: 'PlasmaTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const hue = computed(() => appStore.getThemeInput('hue')?.value as number || 0)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const hue = computed(() => themeStore.getThemeInput('hue')?.value as number || 0)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
const styleCanvas = computed(() => ({
filter: `hue-rotate(${hue.value}deg)`

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,16 +9,16 @@ let render: GL
export default defineComponent({
name: 'RandomTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const hue = computed(() => appStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => appStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => appStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const symmetry = computed(() => appStore.getThemeInput('symmetry')?.value as number || 64)
const thickness = computed(() => appStore.getThemeInput('thickness')?.value as number || 64)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const hue = computed(() => themeStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => themeStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => themeStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const symmetry = computed(() => themeStore.getThemeInput('symmetry')?.value as number || 64)
const thickness = computed(() => themeStore.getThemeInput('thickness')?.value as number || 64)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
const styleCanvas = computed(() => ({
filter: `hue-rotate(${hue.value}deg) invert(${Number(invert.value)}) brightness(${brightness.value})`

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,13 +9,13 @@ let render: GL
export default defineComponent({
name: 'RingsTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const hue = computed(() => appStore.getThemeInput('hue')?.value as number || 0)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const zoom = computed(() => appStore.getThemeInput('zoom')?.value as number || 32)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const hue = computed(() => themeStore.getThemeInput('hue')?.value as number || 0)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const zoom = computed(() => themeStore.getThemeInput('zoom')?.value as number || 32)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
onMounted(() => {
render = new GL(

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,15 +9,15 @@ let render: GL
export default defineComponent({
name: 'SphereTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const hue = computed(() => appStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => appStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => appStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const size = computed(() => appStore.getThemeInput('size')?.value as number || 0.2)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const hue = computed(() => themeStore.getThemeInput('hue')?.value as number || 0)
const brightness = computed(() => themeStore.getThemeInput('brightness')?.value as number || 0)
const invert = computed(() => themeStore.getThemeInput('invert')?.value as boolean || false)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const size = computed(() => themeStore.getThemeInput('size')?.value as number || 0.2)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
const styleCanvas = computed(() => ({
filter: `hue-rotate(${hue.value}deg) invert(${Number(invert.value)}) brightness(${brightness.value})`

@ -1,6 +1,6 @@
import { defineComponent, ref, computed, onMounted, onBeforeUnmount } from 'vue'
import GL from '@/utils/gl'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import fragmentShader from './fragment.glsl'
import vertexShader from './vertex.glsl'
@ -9,11 +9,11 @@ let render: GL
export default defineComponent({
name: 'TendernessTheme',
setup() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const canvasRef = ref<HTMLCanvasElement | null>(null)
const animationSpeed = computed(() => appStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => appStore.getThemeInput('pxratio')?.value as number || 0.8)
const animationSpeed = computed(() => themeStore.getThemeInput('animation-speed')?.value as number || 45)
const pxratio = computed(() => themeStore.getThemeInput('pxratio')?.value as number || 0.8)
onMounted(() => {
render = new GL(

@ -2,19 +2,21 @@ import { watch } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import router from '@/router'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import { isDifferentRoute, parseQueryValue } from '@/utils/helper'
export function useQuerySync() {
const appStore = useAppStore()
const themeStore = useThemeStore()
const applyQueryToStore = () => {
const query = router.currentRoute.value.query
if (query.themeName && appStore.getThemeByName(query.themeName as string)) {
appStore.currentTheme = query.themeName as string
if (query.themeName && themeStore.getThemeByName(query.themeName as string)) {
themeStore.currentTheme = query.themeName as string
}
appStore.activeTheme.settings = appStore.activeTheme.settings?.map((input) => {
themeStore.activeTheme.settings = themeStore.activeTheme.settings?.map((input) => {
if (!(input.name in query)) return input
return { ...input, value: parseQueryValue(query[input.name] as string) }
})
@ -23,7 +25,7 @@ export function useQuerySync() {
const syncQueryFromStore = () => {
const route = router.currentRoute.value
const inputQuery = appStore.activeTheme.settings?.reduce<Record<string, string>>((query, input) => {
const inputQuery = themeStore.activeTheme.settings?.reduce<Record<string, string>>((query, input) => {
query[input.name] = input.value + ''
return query
}, {})
@ -33,7 +35,7 @@ export function useQuerySync() {
return query
}, {})
const query = { ...inputQuery, ...bodyClassQuery, themeName: appStore.currentTheme }
const query = { ...inputQuery, ...bodyClassQuery, themeName: themeStore.currentTheme }
const routeTo = { name: route.name || '/', query }
if (isDifferentRoute(routeTo)) router.replace(routeTo)
@ -42,7 +44,7 @@ export function useQuerySync() {
applyQueryToStore()
watch(
() => [appStore.activeTheme.settings, appStore.bodyClass, appStore.currentTheme],
() => [themeStore.activeTheme.settings, appStore.bodyClass, themeStore.currentTheme],
useDebounceFn(syncQueryFromStore, 300),
{ deep: true }
)

@ -1,19 +1,19 @@
import { defineStore } from 'pinia'
import { computed, reactive, ref, type Ref } from 'vue'
import type { AppTheme, AppSettings, AppInputTheme, AppInputThemeValue } from '@/models/app'
import type { AppSettings } from '@/models/app'
import type { LightdmSession, LightdmUsers } from '@/models/lightdm'
import { randomizeSettingsTheme as buildRandomThemeSettings, setCSSVariable } from '@/utils/helper'
import { AppThemes, defaultTheme } from '@/utils/constant'
import { useThemeStore } from '@/store/theme'
import { LightdmHandler } from '@/utils/lightdm'
import { version as appVersion } from '../../package.json'
export const useAppStore = defineStore('app', () => {
const themeStore = useThemeStore()
const version = appVersion as string
const isGithubMode = import.meta.env.VITE_APP_VIEW === 'github'
const currentTheme = ref('')
const desktop = ref(LightdmHandler.defaultSession)
const username = ref(LightdmHandler.username)
const password = ref('')
@ -22,7 +22,6 @@ export const useAppStore = defineStore('app', () => {
const users = ref(LightdmHandler.users as LightdmUsers[])
const desktops = ref(LightdmHandler.sessions as LightdmSession[])
const showPassword = ref(false)
const themes = ref(AppThemes as AppTheme[])
const bodyClass = reactive<Record<string, boolean>>({
blur: true,
'no-transition': false,
@ -33,73 +32,33 @@ export const useAppStore = defineStore('app', () => {
const showFrameRate = computed(() => bodyClass['show-framerate'])
const viewThemeOnly = computed(() => bodyClass['only-ui'])
const activeTheme = computed((): AppTheme =>
themes.value.find(({ name }) => name === currentTheme.value) || defaultTheme)
const currentUser = computed(() => users.value.find((user) => user.username === username.value))
const currentDesktop = computed(() => desktops.value.find(({ key }) => key === desktop.value))
const getThemeByName = (theme: string) => themes.value.find(({ name }) => name === theme)
const getThemeInput = (name: string, theme?: AppTheme) => {
const active = themes.value.find((t) => t.name === currentTheme.value) || defaultTheme
return (theme || active).settings?.find((input) => input.name === name)
}
const getMainSettings = computed((): AppSettings => ({
zoom: zoom.value,
themes: themes.value,
themes: themeStore.themes,
desktop: desktop.value,
username: username.value,
bodyClass,
currentTheme: currentTheme.value,
currentTheme: themeStore.currentTheme,
defaultColor: defaultColor.value
}))
const personalInfo = computed(() => ({
username: username.value,
currentTheme: currentTheme.value,
currentTheme: themeStore.currentTheme,
desktop: desktop.value,
version,
defaultColor: defaultColor.value
}))
const settableRefs: Record<string, Ref<any>> = { desktop, username, password, defaultColor, zoom, currentTheme }
function randomizeSettingsTheme() {
const theme = activeTheme.value
theme.settings = buildRandomThemeSettings(theme)
}
async function changeTheme(themeName: string, themeSettings?: AppTheme['settings']) {
const isExistTheme = getThemeByName(themeName)
const finalTheme = isExistTheme ? themeName : themes.value[0]!.name
currentTheme.value = finalTheme
if (isExistTheme && themeSettings) {
changeSettingsTheme({ theme: finalTheme, settings: themeSettings })
}
}
const settableRefs: Record<string, Ref<any>> = { desktop, username, password, defaultColor, zoom }
function login() {
LightdmHandler.login(username.value, password.value, currentDesktop.value?.key)
}
function changeSettingsTheme({ theme, settings }: { theme: string; settings: AppTheme['settings'] }) {
const target = themes.value.find(({ name }) => name === theme)
if (target) target.settings = settings
}
function changeThemeInput({ input, value }: { input: AppInputTheme; value: AppInputThemeValue }) {
input.value = value
}
function changeSettingsThemeInput({ key, value }: { key: string; value: AppInputThemeValue }) {
const input = activeTheme.value.settings?.find((i) => i.name === key)
if (input) input.value = value
}
function toggleShowPassword() {
showPassword.value = !showPassword.value
}
@ -117,41 +76,11 @@ export const useAppStore = defineStore('app', () => {
localStorage.setItem('settings', JSON.stringify(getMainSettings.value))
}
function syncThemeColor() {
const { color } = activeTheme.value
setCSSVariable('--color-bg', color.background)
}
function syncThemeWithStore(settings: AppSettings) {
const themeName = settings.currentTheme
const syncTheme = themes.value.reduce((acc: AppTheme[], theme) => {
const cachedTheme = settings.themes.find(({ name }) => name === theme.name)
const isActiveTheme = theme.name === themeName
const hasCachedTheme = cachedTheme && cachedTheme.settings
if (hasCachedTheme) {
theme.settings = theme.settings?.map((input) => {
const cachedInput = getThemeInput(input.name, cachedTheme)
const value = cachedInput?.value ?? input.value
return { ...input, value }
})
}
acc.push(theme)
if (isActiveTheme) currentTheme.value = themeName
return acc
}, [])
themes.value = syncTheme
}
function setUpSettings() {
try {
const settings: AppSettings = JSON.parse(localStorage.getItem('settings') || '{}')
if (settings.themes) syncThemeWithStore(settings)
if (settings.themes) themeStore.syncThemeWithStore(settings)
const isExistDE = window.lightdm?.sessions.find(({ key }) => key === settings.desktop)
if (!isExistDE) settings.desktop = window.lightdm?.sessions[0]?.key || 'openbox'
@ -170,7 +99,6 @@ export const useAppStore = defineStore('app', () => {
return {
version,
isGithubMode,
currentTheme,
desktop,
username,
password,
@ -179,29 +107,18 @@ export const useAppStore = defineStore('app', () => {
users,
desktops,
showPassword,
themes,
bodyClass,
showFrameRate,
viewThemeOnly,
activeTheme,
currentUser,
currentDesktop,
getThemeByName,
getThemeInput,
getMainSettings,
personalInfo,
randomizeSettingsTheme,
changeTheme,
login,
changeSettingsTheme,
changeThemeInput,
changeSettingsThemeInput,
toggleShowPassword,
changeBodyClass,
saveStateApp,
syncSettingsWithCache,
syncThemeColor,
syncThemeWithStore,
setUpSettings
}
})

@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import type { InteractiveBlock, InteractiveBlockIds, AppMenu, AppMenuMain, DialogInterface } from '@/models/page'
export const usePageStore = defineStore('page', () => {
@ -80,7 +81,7 @@ export const usePageStore = defineStore('page', () => {
}
function openTab({ type }: { type: 'settings' | 'themes' | 'custom' }) {
const hasCustomCurrentTheme = useAppStore().activeTheme?.settings?.length !== undefined
const hasCustomCurrentTheme = useThemeStore().activeTheme?.settings?.length !== undefined
let updatedTabIndex = mainTabIndex.value
switch (type) {

@ -0,0 +1,97 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import type { AppTheme, AppSettings, AppInputTheme, AppInputThemeValue } from '@/models/app'
import { randomizeSettingsTheme as buildRandomThemeSettings, setCSSVariable } from '@/utils/helper'
import { AppThemes, defaultTheme } from '@/utils/constant'
export const useThemeStore = defineStore('theme', () => {
const currentTheme = ref('')
const themes = ref(AppThemes as AppTheme[])
const activeTheme = computed((): AppTheme =>
themes.value.find(({ name }) => name === currentTheme.value) || defaultTheme)
const getThemeByName = (theme: string) => themes.value.find(({ name }) => name === theme)
const getThemeInput = (name: string, theme?: AppTheme) => {
const active = themes.value.find((t) => t.name === currentTheme.value) || defaultTheme
return (theme || active).settings?.find((input) => input.name === name)
}
function randomizeSettingsTheme() {
const theme = activeTheme.value
theme.settings = buildRandomThemeSettings(theme)
}
async function changeTheme(themeName: string, themeSettings?: AppTheme['settings']) {
const isExistTheme = getThemeByName(themeName)
const finalTheme = isExistTheme ? themeName : themes.value[0]!.name
currentTheme.value = finalTheme
if (isExistTheme && themeSettings) {
changeSettingsTheme({ theme: finalTheme, settings: themeSettings })
}
}
function changeSettingsTheme({ theme, settings }: { theme: string; settings: AppTheme['settings'] }) {
const target = themes.value.find(({ name }) => name === theme)
if (target) target.settings = settings
}
function changeThemeInput({ input, value }: { input: AppInputTheme; value: AppInputThemeValue }) {
input.value = value
}
function changeSettingsThemeInput({ key, value }: { key: string; value: AppInputThemeValue }) {
const input = activeTheme.value.settings?.find((i) => i.name === key)
if (input) input.value = value
}
function syncThemeColor() {
const { color } = activeTheme.value
setCSSVariable('--color-bg', color.background)
}
function syncThemeWithStore(settings: AppSettings) {
const themeName = settings.currentTheme
const syncTheme = themes.value.reduce((acc: AppTheme[], theme) => {
const cachedTheme = settings.themes.find(({ name }) => name === theme.name)
const isActiveTheme = theme.name === themeName
const hasCachedTheme = cachedTheme && cachedTheme.settings
if (hasCachedTheme) {
theme.settings = theme.settings?.map((input) => {
const cachedInput = getThemeInput(input.name, cachedTheme)
const value = cachedInput?.value ?? input.value
return { ...input, value }
})
}
acc.push(theme)
if (isActiveTheme) currentTheme.value = themeName
return acc
}, [])
themes.value = syncTheme
}
return {
currentTheme,
themes,
activeTheme,
getThemeByName,
getThemeInput,
randomizeSettingsTheme,
changeTheme,
changeSettingsTheme,
changeThemeInput,
changeSettingsThemeInput,
syncThemeColor,
syncThemeWithStore
}
})

@ -7,6 +7,7 @@ import { LightdmHandler } from '@/utils/lightdm'
// This is safe thanks to ES module live bindings (no circular dep issue at runtime)
import { useAppStore } from '@/store/app'
import { usePageStore } from '@/store/page'
import { useThemeStore } from '@/store/theme'
export const modKey = 'ctrl'
export const languageMap: Record<string, string> = {
@ -142,7 +143,7 @@ export const randomButton: AppInputButton = {
type: 'button',
icon: 'random',
callback() {
useAppStore().randomizeSettingsTheme()
useThemeStore().randomizeSettingsTheme()
}
}

@ -1,5 +1,6 @@
import { usePageStore } from '@/store/page'
import { useAppStore } from '@/store/app'
import { useThemeStore } from '@/store/theme'
import { systemActionsObject, modKey } from '@/utils/helper'
const prefixTitle = 'settings.keyboard.'
@ -51,7 +52,7 @@ export const hotkeys = [
{
keys: [modKey, 'r'],
title: `${prefixTitle}randomize-theme`,
callback: () => useAppStore().randomizeSettingsTheme()
callback: () => useThemeStore().randomizeSettingsTheme()
},
{
keys: [modKey, 'i'],

Loading…
Cancel
Save