import { GmBuiltinPanelId, GmKind, type IGmCommand, type IGmConfirmData, type IGmNumberStepperData, type IGmTextAreaData } from './GmTypes'; import { GmRegistry } from './GmRegistry'; /** * 极简 GM 注册器:链式写几行即可挂命令,不必手拼 IGmCommand。 * * @example * ```ts * new GmEasy() * .tab('常用') * .btn('复制存档', () => copy()) * .sw('显示广告', () => on, v => set(v)) * .num('金钱', () => get(), v => set(v)) * .page('道具', 'itemPicker', () => '点选') * .commit(); * ``` */ export class GmEasy { private readonly _cmds: IGmCommand[] = []; private _group = '常用'; private _order = 0; private _seq = 0; /** * 切换 Tab 分组(后续命令都进这个分组)。 */ tab(name: string): this { if (!name) { console.warn('[GmEasy] tab 名为空'); return this; } this._group = name; return this; } /** * 快捷按钮:点一下执行。 */ btn(title: string, run: () => void | Promise): this { this._push({ id: this._id('btn'), title, group: this._group, kind: GmKind.Quick, order: ++this._order, run, }); return this; } /** * 滑动开关。 */ sw(title: string, get: () => boolean, set: (on: boolean) => void): this { this._push({ id: this._id('sw'), title, group: this._group, kind: GmKind.Toggle, order: ++this._order, get, set, }); return this; } /** * 数值:列表内「设为」覆盖 + ± 增减。 * @param setValue 写入绝对值(增减由壳层算好再传入) */ num(title: string, getValue: () => number, setValue: (v: number) => void, min = 0): this { const panelData: IGmNumberStepperData = { getValue, apply: (v) => setValue(v), min, defaultMode: 'set', }; this._push({ id: this._id('num'), title, group: this._group, kind: GmKind.Content, order: ++this._order, panelId: GmBuiltinPanelId.numberStepper, panelData, summary: () => `${Math.floor(Number(getValue()) || 0)}`, }); return this; } /** * 打开已注册的内容面板(如道具点选)。 */ page(title: string, panelId: string, summary?: () => string, panelData?: unknown): this { this._push({ id: this._id('page'), title, group: this._group, kind: GmKind.Content, order: ++this._order, panelId, panelData, summary: summary ?? (() => '›'), }); return this; } /** * 危险操作(二次确认)。 */ danger(title: string, message: string, onConfirm: () => void): this { const panelData: IGmConfirmData = { message, onConfirm }; this._push({ id: this._id('danger'), title, group: this._group, kind: GmKind.Content, order: ++this._order, panelId: GmBuiltinPanelId.confirmQuick, panelData, summary: () => '危险', }); return this; } /** * 大段文本(如粘贴存档 JSON)。 */ text(title: string, apply: (raw: string) => void, placeholder = '粘贴内容'): this { const panelData: IGmTextAreaData = { placeholder, apply }; this._push({ id: this._id('text'), title, group: this._group, kind: GmKind.Content, order: ++this._order, panelId: GmBuiltinPanelId.textArea, panelData, summary: () => '粘贴', }); return this; } /** * 当前 Tab 直接嵌入内容面板(整页展示,无列表入口)。 */ embed(panelId: string): this { this._push({ id: this._id('embed'), title: this._group, group: this._group, kind: GmKind.Content, order: ++this._order, panelId, embed: true, }); return this; } /** * 提交注册到 Registry。 */ commit(): void { if (this._cmds.length <= 0) { console.warn('[GmEasy] commit 时没有任何命令'); return; } GmRegistry.register(this._cmds); } private _id(prefix: string): string { this._seq++; return `easy.${prefix}.${this._seq}`; } private _push(cmd: IGmCommand): void { if (!cmd.title) { console.warn('[GmEasy] 跳过无标题命令'); return; } this._cmds.push(cmd); } }