Skip to content

Commit

Permalink
feat(client): support schema-respected useConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 29, 2024
1 parent 9061bf8 commit 4c8378c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
12 changes: 7 additions & 5 deletions packages/client/client/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RemovableRef, useLocalStorage, usePreferredDark } from '@vueuse/core'
import { computed, reactive, watchEffect } from 'vue'
import { computed, reactive, ref, watchEffect } from 'vue'
import { Config } from '.'

export let useStorage = <T extends object>(key: string, version: number, fallback?: () => T): RemovableRef<T> => {
Expand Down Expand Up @@ -32,7 +32,7 @@ export function createStorage<T extends object>(key: string, version: number, fa
return reactive<T>(storage.value['data'])
}

export const config = useStorage<Config>('config', undefined, () => ({
export const rawConfig = useStorage<Config>('config', undefined, () => ({
theme: {
mode: 'auto',
dark: 'default-dark',
Expand All @@ -44,17 +44,19 @@ export const config = useStorage<Config>('config', undefined, () => ({
const preferDark = usePreferredDark()

const mode = computed(() => {
const mode = config.value.theme.mode
const mode = rawConfig.value.theme.mode
if (mode !== 'auto') return mode
return preferDark.value ? 'dark' : 'light'
})

export const useConfig = () => config
export const resolvedConfig = ref<Config>(rawConfig.value)

export const useConfig = (raw = false) => raw ? rawConfig : resolvedConfig
export const useColorMode = () => mode

watchEffect(() => {
const root = window.document.querySelector('html')
root.setAttribute('theme', config.value.theme[mode.value])
root.setAttribute('theme', rawConfig.value.theme[mode.value])
if (mode.value === 'dark') {
root.classList.add('dark')
} else {
Expand Down
56 changes: 42 additions & 14 deletions packages/client/client/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ import * as cordis from 'cordis'
import { Schema, SchemaBase } from '@koishijs/components'
import { Dict, Intersect, remove } from 'cosmokit'
import {
App, Component, createApp, defineComponent, h, inject, markRaw, MaybeRefOrGetter,
onBeforeUnmount, provide, reactive, Ref, resolveComponent, shallowReactive, toValue,
App, Component, computed, createApp, defineComponent, h, inject, markRaw, MaybeRefOrGetter,
onBeforeUnmount, provide, reactive, Ref, resolveComponent, shallowReactive, toValue, watch,
} from 'vue'
import { activities, Activity } from './activity'
import { SlotOptions } from './components'
import { useColorMode, useConfig } from './config'
import { rawConfig, resolvedConfig, useColorMode } from './config'
import { extensions, LoadResult } from './loader'
import { ActionContext } from '.'

export const Service = cordis.Service<Context>

const config = useConfig()
const mode = useColorMode()

// layout api
Expand Down Expand Up @@ -194,6 +193,35 @@ export class Context extends cordis.Context {
action.action(this.internal.createScope())
}
})

const schema = computed(() => {
const list: Schema[] = []
for (const settings of Object.values(this.internal.settings)) {
for (const options of settings) {
if (options.schema) {
list.push(options.schema)
}
}
}
return Schema.intersect(list)
})

const doWatch = () => watch(resolvedConfig, (value) => {
console.debug('config', value)
rawConfig.value = schema.value.simplify(value)
}, { deep: true })

let stop = doWatch()

watch(schema, () => {
stop?.()
try {
resolvedConfig.value = schema.value(rawConfig.value, { autofix: true })
} catch (error) {
console.error(error)
}
stop = doWatch()
})
}

wrapComponent(component: Component) {
Expand Down Expand Up @@ -261,16 +289,16 @@ export class Context extends cordis.Context {
markRaw(options)
options.order ??= 0
options.component = this.wrapComponent(options.component)
const list = this.internal.settings[options.id] ||= []
insert(list, options)
if (options.schema) {
try {
options.schema(config.value, { autofix: true })
} catch (error) {
console.error(error)
return this.effect(() => {
const list = this.internal.settings[options.id] ||= []
insert(list, options)
return () => {
remove(list, options)
if (!list.length) {
delete this.internal.settings[options.id]
}
}
}
return this.scope.collect('settings', () => remove(list, options))
})
}

theme(options: ThemeOptions) {
Expand All @@ -279,7 +307,7 @@ export class Context extends cordis.Context {
for (const [type, component] of Object.entries(options.components || {})) {
this.slot({
type,
disabled: () => config.value.theme[mode.value] !== options.id,
disabled: () => resolvedConfig.value.theme[mode.value] !== options.id,
component,
})
}
Expand Down
4 changes: 3 additions & 1 deletion packages/client/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { global } from './data'
import install, { Dict } from './components'
import Overlay from './components/chat/overlay.vue'
import { redirectTo } from './activity'
import { config } from './config'
import { useConfig } from './config'
import { initTask } from './loader'
import { Context, routeCache } from './context'
import { createI18n } from 'vue-i18n'
Expand Down Expand Up @@ -66,6 +66,8 @@ export const i18n = createI18n({
fallbackLocale: 'zh-CN',
})

const config = useConfig()

watchEffect(() => {
i18n.global.locale.value = config.value.locale
})
Expand Down

0 comments on commit 4c8378c

Please sign in to comment.