From 9f4b57f5b57420f560451ba908ff21bf7b7c52a1 Mon Sep 17 00:00:00 2001 From: Shigma Date: Sat, 20 May 2023 23:53:00 +0800 Subject: [PATCH] refa: initialize @koishijs/theme-default --- .../client/client/components/layout/index.ts | 4 -- .../client/client/components/layout/utils.ts | 3 -- packages/client/client/components/slot.ts | 14 ++++++- packages/client/client/config.ts | 15 +++++++ packages/client/client/context.ts | 21 +++++++++- packages/client/client/data.ts | 10 ++--- .../client/client/extensions}/settings.vue | 19 +-------- packages/client/client/index.ts | 21 ++++++++-- packages/components/client/k-form.vue | 8 ---- packages/theme-default/client/index.ts | 36 ++++++++++++++++ .../client}/layouts/activity/group.vue | 0 .../client}/layouts/activity/index.vue | 0 .../client}/layouts/activity/item.vue | 0 .../theme-default/client}/layouts/blank.vue | 0 .../theme-default/client}/layouts/index.vue | 2 +- .../client/layouts}/layout-header.vue | 0 .../client/layouts/layout.vue} | 0 .../client}/layouts/status-bar.vue | 0 .../client}/layouts/status-loading.vue | 0 .../client/layouts/status.vue} | 6 +-- .../theme-default/client}/layouts/utils.ts | 4 +- .../theme-default/client}/pages/home.vue | 0 .../client}/pages/welcome.en-US.yml | 0 .../theme-default/client}/pages/welcome.vue | 0 .../client}/pages/welcome.zh-CN.yml | 0 .../client/tsconfig.json} | 4 ++ packages/theme-default/package.json | 34 +++++++++++++++ plugins/console/app/index.ts | 42 +++---------------- plugins/explorer/client/index.ts | 2 - 29 files changed, 156 insertions(+), 89 deletions(-) create mode 100644 packages/client/client/config.ts rename {plugins/console/app/pages => packages/client/client/extensions}/settings.vue (55%) create mode 100644 packages/theme-default/client/index.ts rename {plugins/console/app => packages/theme-default/client}/layouts/activity/group.vue (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/activity/index.vue (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/activity/item.vue (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/blank.vue (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/index.vue (94%) rename packages/{client/client/components/layout => theme-default/client/layouts}/layout-header.vue (100%) rename packages/{client/client/components/layout/k-layout.vue => theme-default/client/layouts/layout.vue} (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/status-bar.vue (100%) rename {plugins/console/app => packages/theme-default/client}/layouts/status-loading.vue (100%) rename packages/{client/client/components/layout/k-status.vue => theme-default/client/layouts/status.vue} (94%) rename {plugins/console/app => packages/theme-default/client}/layouts/utils.ts (85%) rename {plugins/console/app => packages/theme-default/client}/pages/home.vue (100%) rename {plugins/console/app => packages/theme-default/client}/pages/welcome.en-US.yml (100%) rename {plugins/console/app => packages/theme-default/client}/pages/welcome.vue (100%) rename {plugins/console/app => packages/theme-default/client}/pages/welcome.zh-CN.yml (100%) rename packages/{client/tsconfig.client.json => theme-default/client/tsconfig.json} (88%) create mode 100644 packages/theme-default/package.json diff --git a/packages/client/client/components/layout/index.ts b/packages/client/client/components/layout/index.ts index a0b167a0..e1733129 100644 --- a/packages/client/client/components/layout/index.ts +++ b/packages/client/client/components/layout/index.ts @@ -1,6 +1,4 @@ import { App } from 'vue' -import Layout from './k-layout.vue' -import Status from './k-status.vue' import CardNumeric from './card-numeric.vue' import Card from './card.vue' import Content from './content.vue' @@ -11,8 +9,6 @@ import TabItem from './tab-item.vue' export * from './utils' export default function (app: App) { - app.component('k-layout', Layout) - app.component('k-status', Status) app.component('k-numeric', CardNumeric) app.component('k-card', Card) app.component('k-content', Content) diff --git a/packages/client/client/components/layout/utils.ts b/packages/client/client/components/layout/utils.ts index ba6b65e8..e69de29b 100644 --- a/packages/client/client/components/layout/utils.ts +++ b/packages/client/client/components/layout/utils.ts @@ -1,3 +0,0 @@ -import { ref } from 'vue' - -export const isLeftAsideOpen = ref(false) diff --git a/packages/client/client/components/slot.ts b/packages/client/client/components/slot.ts index f81ab7b9..6d5d0e59 100644 --- a/packages/client/client/components/slot.ts +++ b/packages/client/client/components/slot.ts @@ -24,7 +24,11 @@ export const KSlot = defineComponent({ .map(node => ({ node, order: node.props?.order || 0 })) const external = [...views[props.name] || []] .filter(item => !item.when || item.when()) - .map(item => ({ node: h(item.component, { data: props.data }), order: item.order, layer: 1 })) + .map(item => ({ + node: h(item.component, { data: props.data, ...props.data }, slots), + order: item.order, + layer: 1, + })) const children = [...internal, ...external].sort((a, b) => b.order - a.order) if (props.single) { return children[0]?.node || slots.default?.() @@ -43,7 +47,15 @@ const KSlotItem = defineComponent({ }, }) +function defineSlotComponent(name: string) { + return defineComponent((_, { attrs, slots }) => { + return () => h(KSlot, { name, data: attrs, single: true }, slots) + }) +} + export default (app: App) => { app.component('k-slot', KSlot) app.component('k-slot-item', KSlotItem) + app.component('k-layout', defineSlotComponent('layout')) + app.component('k-status', defineSlotComponent('status')) } diff --git a/packages/client/client/config.ts b/packages/client/client/config.ts new file mode 100644 index 00000000..a2b207a3 --- /dev/null +++ b/packages/client/client/config.ts @@ -0,0 +1,15 @@ +import { useDark } from '@vueuse/core' +import { computed } from 'vue' +import { i18n } from '.' + +const isDark = useDark() + +export const config = computed({ + get() { + return { isDark: isDark.value, locale: i18n.global.locale.value } + }, + set(value) { + isDark.value = value?.isDark + i18n.global.locale.value = value?.locale + }, +}) diff --git a/packages/client/client/context.ts b/packages/client/client/context.ts index b04a11b7..3860285e 100644 --- a/packages/client/client/context.ts +++ b/packages/client/client/context.ts @@ -1,7 +1,7 @@ import * as cordis from 'cordis' import components from '@koishijs/components' import { Dict, remove } from 'cosmokit' -import { App, markRaw, reactive } from 'vue' +import { App, createApp, defineComponent, h, inject, markRaw, reactive, resolveComponent } from 'vue' import { Activity } from './activity' import { SlotOptions } from './components' @@ -19,8 +19,25 @@ export interface Context { [Context.events]: Events } +export function useContext() { + return inject('root') as Context +} + export class Context extends cordis.Context { - static app: App + app: App + + constructor() { + super() + this.app = createApp(defineComponent({ + setup() { + return () => [ + h(resolveComponent('k-slot'), { name: 'root', single: true }), + h(resolveComponent('k-slot'), { name: 'global' }), + ] + }, + })) + this.app.provide('root', this) + } /** @deprecated */ addView(options: SlotOptions) { diff --git a/packages/client/client/data.ts b/packages/client/client/data.ts index 4fd419bd..d230d487 100644 --- a/packages/client/client/data.ts +++ b/packages/client/client/data.ts @@ -38,11 +38,9 @@ export type Store = { } declare const KOISHI_CONFIG: ClientConfig -export const config = KOISHI_CONFIG +export const global = KOISHI_CONFIG export const store = reactive({}) -export { config as global } - export const socket = ref(null) const listeners: Record void> = {} const responseHooks: Record = {} @@ -94,11 +92,11 @@ export function connect(callback: () => AbstractWebSocket) { let sendTimer: number let closeTimer: number const refresh = () => { - if (!config.heartbeat) return + if (!global.heartbeat) return clearTimeout(sendTimer) clearTimeout(closeTimer) - sendTimer = +setTimeout(() => send('ping'), config.heartbeat.interval) - closeTimer = +setTimeout(() => value?.close(), config.heartbeat.timeout) + sendTimer = +setTimeout(() => send('ping'), global.heartbeat.interval) + closeTimer = +setTimeout(() => value?.close(), global.heartbeat.timeout) } const reconnect = () => { diff --git a/plugins/console/app/pages/settings.vue b/packages/client/client/extensions/settings.vue similarity index 55% rename from plugins/console/app/pages/settings.vue rename to packages/client/client/extensions/settings.vue index eb162630..e7e0e430 100644 --- a/plugins/console/app/pages/settings.vue +++ b/packages/client/client/extensions/settings.vue @@ -8,32 +8,15 @@ diff --git a/packages/client/client/index.ts b/packages/client/client/index.ts index f5131fa7..8dd968f7 100644 --- a/packages/client/client/index.ts +++ b/packages/client/client/index.ts @@ -1,9 +1,10 @@ import { Console } from '@koishijs/plugin-console' import { defineComponent, h, resolveComponent } from 'vue' import { createRouter, createWebHistory, START_LOCATION } from 'vue-router' -import { config, Store, store } from './data' +import { global, Store, store } from './data' import install, { isNullable } from './components' import Overlay from './components/chat/overlay.vue' +import Settings from './extensions/settings.vue' import { initTask } from './loader' import { Context } from './context' import { createI18n } from 'vue-i18n' @@ -12,14 +13,17 @@ import './styles/index.scss' export * from './activity' export * from './components' +export * from './config' export * from './context' export * from './loader' export * from './data' export default install +export const root = new Context() + export const router = createRouter({ - history: createWebHistory(config.uiPath), + history: createWebHistory(global.uiPath), linkActiveClass: 'active', routes: [], }) @@ -30,13 +34,24 @@ export const i18n = createI18n({ fallbackLocale: 'zh-CN', }) -export const root = new Context() +root.app.use(install) +root.app.use(i18n) +root.app.use(router) root.slot({ type: 'global', component: Overlay, }) +root.page({ + path: '/settings', + name: '用户设置', + icon: 'activity:settings', + position: 'bottom', + order: -100, + component: Settings, +}) + root.on('activity', data => !data) router.beforeEach(async (to, from) => { diff --git a/packages/components/client/k-form.vue b/packages/components/client/k-form.vue index 6aef663d..215e7aad 100644 --- a/packages/components/client/k-form.vue +++ b/packages/components/client/k-form.vue @@ -58,11 +58,3 @@ const config = computed({ }) - - diff --git a/packages/theme-default/client/index.ts b/packages/theme-default/client/index.ts new file mode 100644 index 00000000..ebf702d0 --- /dev/null +++ b/packages/theme-default/client/index.ts @@ -0,0 +1,36 @@ +import { defineExtension } from '@koishijs/client' +import Home from './pages/home.vue' +import App from './layouts/index.vue' +import Layout from './layouts/layout.vue' +import Status from './layouts/status.vue' +import Progress from './layouts/status-loading.vue' + +export default defineExtension((ctx) => { + ctx.page({ + path: '/', + name: '欢迎', + icon: 'activity:home', + order: 1000, + component: Home, + }) + + ctx.slot({ + type: 'status-right', + component: Progress, + }) + + ctx.slot({ + type: 'root', + component: App, + }) + + ctx.slot({ + type: 'layout', + component: Layout, + }) + + ctx.slot({ + type: 'status', + component: Status, + }) +}) diff --git a/plugins/console/app/layouts/activity/group.vue b/packages/theme-default/client/layouts/activity/group.vue similarity index 100% rename from plugins/console/app/layouts/activity/group.vue rename to packages/theme-default/client/layouts/activity/group.vue diff --git a/plugins/console/app/layouts/activity/index.vue b/packages/theme-default/client/layouts/activity/index.vue similarity index 100% rename from plugins/console/app/layouts/activity/index.vue rename to packages/theme-default/client/layouts/activity/index.vue diff --git a/plugins/console/app/layouts/activity/item.vue b/packages/theme-default/client/layouts/activity/item.vue similarity index 100% rename from plugins/console/app/layouts/activity/item.vue rename to packages/theme-default/client/layouts/activity/item.vue diff --git a/plugins/console/app/layouts/blank.vue b/packages/theme-default/client/layouts/blank.vue similarity index 100% rename from plugins/console/app/layouts/blank.vue rename to packages/theme-default/client/layouts/blank.vue diff --git a/plugins/console/app/layouts/index.vue b/packages/theme-default/client/layouts/index.vue similarity index 94% rename from plugins/console/app/layouts/index.vue rename to packages/theme-default/client/layouts/index.vue index 12e53a63..1666330f 100644 --- a/plugins/console/app/layouts/index.vue +++ b/packages/theme-default/client/layouts/index.vue @@ -17,7 +17,7 @@ import { store } from './utils' import { computed } from 'vue' import { useRoute } from 'vue-router' -import { isLeftAsideOpen } from '@koishijs/client' +import { isLeftAsideOpen } from './utils' import ActivityBar from './activity/index.vue' import StatusBar from './status-bar.vue' diff --git a/packages/client/client/components/layout/layout-header.vue b/packages/theme-default/client/layouts/layout-header.vue similarity index 100% rename from packages/client/client/components/layout/layout-header.vue rename to packages/theme-default/client/layouts/layout-header.vue diff --git a/packages/client/client/components/layout/k-layout.vue b/packages/theme-default/client/layouts/layout.vue similarity index 100% rename from packages/client/client/components/layout/k-layout.vue rename to packages/theme-default/client/layouts/layout.vue diff --git a/plugins/console/app/layouts/status-bar.vue b/packages/theme-default/client/layouts/status-bar.vue similarity index 100% rename from plugins/console/app/layouts/status-bar.vue rename to packages/theme-default/client/layouts/status-bar.vue diff --git a/plugins/console/app/layouts/status-loading.vue b/packages/theme-default/client/layouts/status-loading.vue similarity index 100% rename from plugins/console/app/layouts/status-loading.vue rename to packages/theme-default/client/layouts/status-loading.vue diff --git a/packages/client/client/components/layout/k-status.vue b/packages/theme-default/client/layouts/status.vue similarity index 94% rename from packages/client/client/components/layout/k-status.vue rename to packages/theme-default/client/layouts/status.vue index 42289ef8..8938f5a8 100644 --- a/packages/client/client/components/layout/k-status.vue +++ b/packages/theme-default/client/layouts/status.vue @@ -11,11 +11,11 @@ - diff --git a/plugins/console/app/layouts/utils.ts b/packages/theme-default/client/layouts/utils.ts similarity index 85% rename from plugins/console/app/layouts/utils.ts rename to packages/theme-default/client/layouts/utils.ts index 07a494cc..46cd3411 100644 --- a/plugins/console/app/layouts/utils.ts +++ b/packages/theme-default/client/layouts/utils.ts @@ -1,9 +1,11 @@ -import { reactive } from 'vue' +import { reactive, ref } from 'vue' import { RouteRecordName } from 'vue-router' import { global, router } from '@koishijs/client' export * from '@koishijs/client' +export const isLeftAsideOpen = ref(false) + export const routeCache = reactive>({}) router.afterEach((route) => { diff --git a/plugins/console/app/pages/home.vue b/packages/theme-default/client/pages/home.vue similarity index 100% rename from plugins/console/app/pages/home.vue rename to packages/theme-default/client/pages/home.vue diff --git a/plugins/console/app/pages/welcome.en-US.yml b/packages/theme-default/client/pages/welcome.en-US.yml similarity index 100% rename from plugins/console/app/pages/welcome.en-US.yml rename to packages/theme-default/client/pages/welcome.en-US.yml diff --git a/plugins/console/app/pages/welcome.vue b/packages/theme-default/client/pages/welcome.vue similarity index 100% rename from plugins/console/app/pages/welcome.vue rename to packages/theme-default/client/pages/welcome.vue diff --git a/plugins/console/app/pages/welcome.zh-CN.yml b/packages/theme-default/client/pages/welcome.zh-CN.yml similarity index 100% rename from plugins/console/app/pages/welcome.zh-CN.yml rename to packages/theme-default/client/pages/welcome.zh-CN.yml diff --git a/packages/client/tsconfig.client.json b/packages/theme-default/client/tsconfig.json similarity index 88% rename from packages/client/tsconfig.client.json rename to packages/theme-default/client/tsconfig.json index 3489b674..8815b7b3 100644 --- a/packages/client/tsconfig.client.json +++ b/packages/theme-default/client/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "rootDir": ".", "target": "es2020", "module": "esnext", "declaration": true, @@ -15,4 +16,7 @@ "@koishijs/client/global", ], }, + "include": [ + ".", + ], } \ No newline at end of file diff --git a/packages/theme-default/package.json b/packages/theme-default/package.json new file mode 100644 index 00000000..9303b850 --- /dev/null +++ b/packages/theme-default/package.json @@ -0,0 +1,34 @@ +{ + "name": "@koishijs/theme-default", + "description": "Koishi Console Theme Default", + "version": "1.0.0", + "main": "client/index.ts", + "files": [ + "client", + "lib" + ], + "author": "Shigma ", + "license": "AGPL-3.0", + "repository": { + "type": "git", + "url": "git+https://github.com/koishijs/webui.git", + "directory": "packages/theme-default" + }, + "bugs": { + "url": "https://github.com/koishijs/webui/issues" + }, + "homepage": "https://koishi.chat", + "keywords": [ + "bot", + "chatbot", + "koishi", + "plugin", + "webui", + "console", + "theme", + "default" + ], + "dependencies": { + "@koishijs/client": "5.8.3" + } +} diff --git a/plugins/console/app/index.ts b/plugins/console/app/index.ts index 7b0d5b52..319bb0f0 100644 --- a/plugins/console/app/index.ts +++ b/plugins/console/app/index.ts @@ -1,9 +1,5 @@ -import { createApp } from 'vue' -import client, { connect, Context, Dict, global, i18n, root, router } from '@koishijs/client' -import App from './layouts/index.vue' -import Home from './pages/home.vue' -import Settings from './pages/settings.vue' -import Progress from './layouts/status-loading.vue' +import { connect, Dict, global, root } from '@koishijs/client' +import themeDefault from '@koishijs/theme-default' import './index.scss' @@ -14,39 +10,11 @@ declare module '@koishijs/plugin-console' { } } -const app = createApp(App) +root.plugin(themeDefault) -app.use(client) -app.use(i18n) -app.use(router) +root.app.provide('ecTheme', 'dark-blue') -app.provide('ecTheme', 'dark-blue') - -Context.app = app - -root.page({ - path: '/', - name: '欢迎', - icon: 'activity:home', - order: 1000, - component: Home, -}) - -root.page({ - path: '/settings', - name: '用户设置', - icon: 'activity:settings', - position: 'bottom', - order: -100, - component: Settings, -}) - -root.slot({ - type: 'status-right', - component: Progress, -}) - -app.mount('#app') +root.app.mount('#app') if (!global.static) { const endpoint = new URL(global.endpoint, location.origin).toString() diff --git a/plugins/explorer/client/index.ts b/plugins/explorer/client/index.ts index e328ae27..3b5b2673 100644 --- a/plugins/explorer/client/index.ts +++ b/plugins/explorer/client/index.ts @@ -6,8 +6,6 @@ import Status from './status.vue' import './icons' import './editor' -Context.app.component('k-file-picker', FilePicker) - export default (ctx: Context) => { ctx.schema({ type: 'string',