diff --git a/ui/packages/artalk/src/artalk.ts b/ui/packages/artalk/src/artalk.ts index 5eb295a62..bc857aacc 100644 --- a/ui/packages/artalk/src/artalk.ts +++ b/ui/packages/artalk/src/artalk.ts @@ -10,68 +10,54 @@ import { DefaultPlugins } from './plugins' import * as Stat from './plugins/stat' import Api from './api' +/** Global Plugins for all instances */ +const GlobalPlugins: ArtalkPlugin[] = [ ...DefaultPlugins ] + /** * Artalk * * @see https://artalk.js.org */ export default class Artalk { - private static instance?: Artalk - - public static readonly defaults: ArtalkConfig = defaults - public conf!: ArtalkConfig public ctx!: ContextApi public $root!: HTMLElement /** Plugins */ - protected static plugins: ArtalkPlugin[] = [ ...DefaultPlugins ] - public static DisabledComponents: string[] = [] + protected plugins: ArtalkPlugin[] = [ ...GlobalPlugins ] constructor(conf: Partial) { - if (Artalk.instance) Artalk.destroy() - - // 初始化基本配置 + // Init Config this.conf = handelCustomConf(conf) if (this.conf.el instanceof HTMLElement) this.$root = this.conf.el - // 初始化 Context + // Init Context this.ctx = new ConcreteContext(this.conf, this.$root) - // 内建服务初始化 + // Init Services Object.entries(Services).forEach(([name, initService]) => { - if (Artalk.DisabledComponents.includes(name)) return const obj = initService(this.ctx) if (obj) this.ctx.inject(name as any, obj) // auto inject deps to ctx }) - // 插件初始化 (global scope) - Artalk.plugins.forEach(plugin => { - if (typeof plugin === 'function') - plugin(this.ctx) + // Init Plugins + this.plugins.forEach(plugin => { + if (typeof plugin === 'function') plugin(this.ctx) }) + // Trigger inited event this.ctx.trigger('inited') } - /** Init Artalk */ - public static init(conf: Partial): Artalk { - if (this.instance) Artalk.destroy() - this.instance = new Artalk(conf) - return this.instance - } - /** Use Plugin (plugin will be called in instance `use` func) */ public use(plugin: ArtalkPlugin) { - Artalk.plugins.push(plugin) if (typeof plugin === 'function') plugin(this.ctx) } /** Update config of Artalk */ public update(conf: Partial) { - if (!Artalk.instance) throw Error('cannot call `update` function before call `load`') - Artalk.instance.ctx.updateConf(conf) - return Artalk.instance + this.ctx.updateConf(conf) + return this } /** Reload comment list of Artalk */ @@ -81,10 +67,8 @@ export default class Artalk { /** Destroy instance of Artalk */ public destroy() { - if (!Artalk.instance) throw Error('cannot call `destroy` function before call `load`') this.ctx.trigger('destroy') - Artalk.instance.$root.remove() - delete Artalk.instance + this.$root.remove() } /** Add an event listener */ @@ -108,48 +92,20 @@ export default class Artalk { } // =========================== - // Static methods + // Static Members // =========================== - /** Use Plugin (static method) */ - public static use(plugin: ArtalkPlugin) { - this.plugins.push(plugin) - if (this.instance && typeof plugin === 'function') plugin(this.instance.ctx) - } - - /** Update config of Artalk */ - public static update(conf: Partial) { - return this.instance?.update(conf) - } - - /** Reload comment list of Artalk */ - public static reload() { - this.instance?.reload() - } - - /** Destroy instance of Artalk */ - public static destroy() { - this.instance?.destroy() - } - - /** Add an event listener */ - public static on(name: K, handler: EventHandler) { - this.instance?.on(name, handler) - } - - /** Remove an event listener */ - public static off(name: K, handler: EventHandler) { - this.instance?.off(name, handler) - } + /** Default Configs */ + public static readonly defaults: ArtalkConfig = defaults - /** Trigger an event */ - public static trigger(name: K, payload?: EventPayloadMap[K]) { - this.instance?.trigger(name, payload) + /** Init Artalk */ + public static init(conf: Partial): Artalk { + return new Artalk(conf) } - /** Set dark mode */ - public static setDarkMode(darkMode: boolean) { - this.instance?.setDarkMode(darkMode) + /** Use Plugin for all instances */ + public static use(plugin: ArtalkPlugin) { + GlobalPlugins.push(plugin) } /** Load count widget */ diff --git a/ui/packages/artalk/src/config.ts b/ui/packages/artalk/src/config.ts index 597f17e7c..2e1037e0e 100644 --- a/ui/packages/artalk/src/config.ts +++ b/ui/packages/artalk/src/config.ts @@ -13,6 +13,9 @@ export function handelCustomConf(customConf: Partial): ArtalkConfi // 合并默认配置 const conf: ArtalkConfig = Utils.mergeDeep(Defaults, customConf) + // TODO the type of el options may HTMLElement, use it directly instead of from mergeDeep + if (customConf.el) conf.el = customConf.el + // 绑定元素 if (typeof conf.el === 'string' && !!conf.el) { try { diff --git a/ui/packages/artalk/src/plugins/conf-remoter.ts b/ui/packages/artalk/src/plugins/conf-remoter.ts index aca53d05c..e894b2d75 100644 --- a/ui/packages/artalk/src/plugins/conf-remoter.ts +++ b/ui/packages/artalk/src/plugins/conf-remoter.ts @@ -2,11 +2,9 @@ import type { ArtalkConfig, ArtalkPlugin, ContextApi } from '~/types' import { handleConfFormServer } from '@/config' import { showErrorDialog } from '../components/error-dialog' -let confLoaded = false - export const ConfRemoter: ArtalkPlugin = (ctx) => { ctx.on('inited', () => { - if (!confLoaded) loadConf(ctx) + loadConf(ctx) }) } @@ -26,7 +24,6 @@ function loadConf(ctx: ContextApi) { ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf) ctx.updateConf(conf) - confLoaded = true }).catch((err) => { ctx.updateConf({})