-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
335 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<template> | ||
<k-comment v-for="item in notifiers" :type="item.type"> | ||
<render :children="Element.parse(item.content)"></render> | ||
</k-comment> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { Element } from '@cordisjs/element' | ||
import {} from '@cordisjs/plugin-config/client' | ||
import { useContext, useRpc, send } from '@cordisjs/client' | ||
import type NotifierService from '../src' | ||
import { h, computed, resolveComponent, FunctionalComponent } from 'vue' | ||
const data = useRpc<NotifierService.Data>() | ||
const ctx = useContext() | ||
const notifiers = computed(() => { | ||
return data.value.notifiers.filter((item) => { | ||
return item.paths?.includes(ctx.manager.current.value!.path) && item.content | ||
}) | ||
}) | ||
const forward = ['div', 'ul', 'ol', 'li', 'br', 'span', 'p', 'img', 'audio', 'video', 'b', 'strong', 'i', 'em', 'u', 'ins', 's', 'del', 'code'] | ||
const render: FunctionalComponent<{ children: Element[] }> = ({ children }, ctx) => { | ||
return children.map(({ type, attrs, children }) => { | ||
if (type === 'text') { | ||
return attrs.content | ||
} else if (forward.includes(type)) { | ||
return h(type, attrs, { | ||
default: () => render({ children }, ctx), | ||
}) | ||
} else if (type === 'spl') { | ||
return h('span', { class: 'spoiler', ...attrs }, { | ||
default: () => render({ children }, ctx), | ||
}) | ||
} else if (type === 'button') { | ||
return h(resolveComponent('el-button'), { | ||
...attrs, | ||
onClick: () => send('notifier/button', attrs.onClick), | ||
}, { | ||
default: () => render({ children }, ctx), | ||
}) | ||
} else if (type === 'progress') { | ||
return h(resolveComponent('el-progress'), attrs, { | ||
default: () => render({ children }, ctx), | ||
}) | ||
} else if (type === 'template') { | ||
return render({ children }, ctx) | ||
} | ||
}) | ||
} | ||
</script> | ||
|
||
<style scoped lang="scss"> | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Context, message } from '@cordisjs/client' | ||
import {} from '../src' | ||
import Config from './config.vue' | ||
|
||
interface NotifierMessage { | ||
content: string | ||
type: 'success' | 'warning' | 'error' | 'primary' | ||
} | ||
|
||
declare module '@cordisjs/client' { | ||
interface Events<C> { | ||
'notifier/message'(this: C, payload: NotifierMessage): void | ||
} | ||
} | ||
|
||
export default (ctx: Context) => { | ||
ctx.slot({ | ||
type: 'plugin-details', | ||
component: Config, | ||
order: 0, | ||
}) | ||
|
||
ctx.on('notifier/message', ({ content, type }) => { | ||
ctx.effect(() => { | ||
const handler = message({ | ||
message: content, | ||
type: type === 'primary' ? 'info' : type, | ||
}) | ||
return () => handler.close() | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "../../../tsconfig.client", | ||
"include": [ | ||
".", | ||
], | ||
"references": [ | ||
{ | ||
"path": "../tsconfig.json", | ||
}, | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
{ | ||
"name": "@cordisjs/plugin-notifier", | ||
"description": "Notifier service for Koishi", | ||
"version": "0.1.0", | ||
"main": "lib/index.cjs", | ||
"types": "lib/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./lib/index.mjs", | ||
"require": "./lib/index.cjs", | ||
"types": "./lib/index.d.ts" | ||
}, | ||
"./src/*": "./src/*", | ||
"./client": "./client/index.ts", | ||
"./package.json": "./package.json" | ||
}, | ||
"files": [ | ||
"lib", | ||
"dist", | ||
"src" | ||
], | ||
"author": "Shigma <shigma10826@gmail.com>", | ||
"license": "MIT", | ||
"scripts": { | ||
"lint": "eslint src --ext .ts" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/cordiverse/webui.git", | ||
"directory": "plugins/notifier" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/cordiverse/webui/issues" | ||
}, | ||
"keywords": [ | ||
"cordis", | ||
"plugin", | ||
"notifier", | ||
"webui" | ||
], | ||
"cordis": { | ||
"public": [ | ||
"dist" | ||
], | ||
"description": { | ||
"en": "Notifier service for Cordis WebUI", | ||
"zh": "Cordis WebUI 通知服务" | ||
}, | ||
"service": { | ||
"implements": [ | ||
"notifier" | ||
], | ||
"optional": [ | ||
"manager", | ||
"webui" | ||
] | ||
} | ||
}, | ||
"peerDependencies": { | ||
"@cordisjs/plugin-webui": "^0.1.1", | ||
"cordis": "^3.15.0" | ||
}, | ||
"devDependencies": { | ||
"@cordisjs/client": "^0.1.1", | ||
"@cordisjs/plugin-config": "^2.8.6" | ||
}, | ||
"dependencies": { | ||
"@cordisjs/element": "^0.1.0", | ||
"cosmokit": "^1.6.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { Context, Schema, Service } from 'cordis' | ||
import { Dict, isNullable, remove } from 'cosmokit' | ||
import { h } from '@cordisjs/element' | ||
import type { Entry } from '@cordisjs/plugin-webui' | ||
import { resolve } from 'path' | ||
|
||
declare module 'cordis' { | ||
interface Context { | ||
notifier: NotifierService | ||
} | ||
} | ||
|
||
declare module '@cordisjs/plugin-webui' { | ||
interface Events { | ||
'notifier/button'(id: string): void | ||
} | ||
} | ||
|
||
export class Notifier { | ||
public options: Notifier.Config | ||
public dispose: () => void | ||
|
||
private actionKeys: string[] = [] | ||
|
||
constructor(public ctx: Context, options: h.Fragment | Notifier.Options) { | ||
this.options = { | ||
type: 'primary', | ||
content: [], | ||
} | ||
ctx.notifier.store.push(this) | ||
this.update(options) | ||
ctx.notifier.entry?.refresh() | ||
this.dispose = ctx.collect('entry', () => { | ||
this.clearActions() | ||
remove(ctx.notifier.store, this) | ||
ctx.notifier.entry?.refresh() | ||
}) | ||
} | ||
|
||
clearActions() { | ||
for (const key of this.actionKeys) { | ||
delete this.ctx.notifier.actions[key] | ||
} | ||
this.actionKeys = [] | ||
} | ||
|
||
update(options: h.Fragment | Notifier.Options) { | ||
if (typeof options === 'string' || h.isElement(options) || Array.isArray(options)) { | ||
options = { content: options } | ||
} | ||
if (!isNullable(options?.content)) { | ||
this.clearActions() | ||
const content = typeof options.content === 'string' | ||
? [h('p', options.content)] | ||
: h.toElementArray(options.content) | ||
options.content = h.transform(content, ({ type, attrs }) => { | ||
if (type === 'button' && typeof attrs.onClick === 'function') { | ||
const key = Math.random().toString(36).slice(2) | ||
this.ctx.notifier.actions[key] = attrs.onClick | ||
this.actionKeys.push(key) | ||
attrs.onClick = key | ||
} | ||
return true | ||
}) | ||
} | ||
Object.assign(this.options, options) | ||
this.ctx.notifier.entry?.refresh() | ||
} | ||
|
||
toJSON(): Notifier.Data { | ||
return { | ||
...this.options, | ||
content: this.options.content.join(''), | ||
paths: this.ctx.get('loader')?.paths(this.ctx.scope), | ||
} | ||
} | ||
} | ||
|
||
export namespace Notifier { | ||
export type Type = 'primary' | 'success' | 'warning' | 'danger' | ||
|
||
export interface Options<T = h.Fragment> { | ||
type?: Type | ||
content?: T | ||
} | ||
|
||
export interface Config extends Required<Options> { | ||
content: h[] | ||
} | ||
|
||
export interface Data extends Required<Options> { | ||
content: string | ||
paths?: string[] | ||
} | ||
} | ||
|
||
class NotifierService extends Service { | ||
public store: Notifier[] = [] | ||
public actions: Dict<() => void> = Object.create(null) | ||
public entry?: Entry<NotifierService.Data> | ||
|
||
constructor(ctx: Context, public config: NotifierService.Config) { | ||
super(ctx, 'notifier', true) | ||
|
||
ctx.inject(['webui'], (ctx) => { | ||
ctx.on('dispose', () => this.entry = undefined) | ||
|
||
this.entry = ctx.webui.addEntry(process.env.KOISHI_BASE ? [ | ||
process.env.KOISHI_BASE + '/dist/index.js', | ||
process.env.KOISHI_BASE + '/dist/style.css', | ||
] : process.env.KOISHI_ENV === 'browser' ? [ | ||
// @ts-ignore | ||
import.meta.url.replace(/\/src\/[^/]+$/, '/client/index.ts'), | ||
] : { | ||
dev: resolve(__dirname, '../client/index.ts'), | ||
prod: resolve(__dirname, '../dist'), | ||
}, () => ({ | ||
notifiers: this.store.map(notifier => notifier.toJSON()), | ||
})) | ||
|
||
ctx.webui.addListener('notifier/button', (id: string) => { | ||
return this.actions[id]() | ||
}) | ||
}) | ||
} | ||
|
||
message(options: string | Notifier.Options<string>) { | ||
if (typeof options === 'string') { | ||
options = { content: options } | ||
} | ||
options.type ||= 'primary' | ||
this.ctx.get('console').broadcast('notifier/message', options) | ||
} | ||
|
||
create(options: h.Fragment | Notifier.Options) { | ||
return new Notifier(this[Context.current], options) | ||
} | ||
} | ||
|
||
namespace NotifierService { | ||
export interface Data { | ||
notifiers: Notifier.Data[] | ||
} | ||
|
||
export interface Config {} | ||
|
||
export const Config: Schema<Config> = Schema.object({}) | ||
} | ||
|
||
export default NotifierService |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "../../tsconfig.base", | ||
"compilerOptions": { | ||
"rootDir": "src", | ||
"outDir": "lib", | ||
}, | ||
"include": [ | ||
"src", | ||
], | ||
} |