From 7ee48f14432c66196d384e528a8d11bcd451e750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Fri, 15 Nov 2024 16:50:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=BF=81=E7=A7=BB=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E4=B8=8E=E5=89=8D=E7=AB=AF=20=E5=A4=A7=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/webui/src/api/OB11Config.ts | 6 +- src/webui/src/helper/Data.ts | 8 +- src/webui/ui/NapCat.ts | 393 ------------------ src/webui/ui/components/SettingButton.ts | 3 - src/webui/ui/components/SettingItem.ts | 15 - src/webui/ui/components/SettingList.ts | 14 - src/webui/ui/components/SettingOption.ts | 3 - src/webui/ui/components/SettingSelect.ts | 86 ---- src/webui/ui/components/SettingSwitch.ts | 8 - src/webui/ui/components/WebUiApiOB11Config.ts | 79 ---- 10 files changed, 7 insertions(+), 608 deletions(-) delete mode 100644 src/webui/ui/NapCat.ts delete mode 100644 src/webui/ui/components/SettingButton.ts delete mode 100644 src/webui/ui/components/SettingItem.ts delete mode 100644 src/webui/ui/components/SettingList.ts delete mode 100644 src/webui/ui/components/SettingOption.ts delete mode 100644 src/webui/ui/components/SettingSelect.ts delete mode 100644 src/webui/ui/components/SettingSwitch.ts delete mode 100644 src/webui/ui/components/WebUiApiOB11Config.ts diff --git a/src/webui/src/api/OB11Config.ts b/src/webui/src/api/OB11Config.ts index f2fbd145..421466bd 100644 --- a/src/webui/src/api/OB11Config.ts +++ b/src/webui/src/api/OB11Config.ts @@ -1,7 +1,7 @@ import { RequestHandler } from 'express'; import { WebUiDataRuntime } from '../helper/Data'; import { existsSync, readFileSync } from 'node:fs'; -import { OB11Config } from '@/webui/ui/components/WebUiApiOB11Config'; +import { OnebotConfig } from '@/onebot/config/config'; import { resolve } from 'node:path'; import { webUiPathWrapper } from '@/webui'; @@ -19,7 +19,7 @@ export const OB11GetConfigHandler: RequestHandler = async (req, res) => { const uin = await WebUiDataRuntime.getQQLoginUin(); const configFilePath = resolve(webUiPathWrapper.configPath, `./onebot11_${uin}.json`); //console.log(configFilePath); - let data: OB11Config; + let data: OnebotConfig; try { data = JSON.parse( existsSync(configFilePath) @@ -27,7 +27,7 @@ export const OB11GetConfigHandler: RequestHandler = async (req, res) => { : readFileSync(resolve(webUiPathWrapper.configPath, './onebot11.json')).toString(), ); } catch (e) { - data = {} as OB11Config; + data = {} as OnebotConfig; res.send({ code: -1, message: 'Config Get Error', diff --git a/src/webui/src/helper/Data.ts b/src/webui/src/helper/Data.ts index c569d912..cecdfed5 100644 --- a/src/webui/src/helper/Data.ts +++ b/src/webui/src/helper/Data.ts @@ -1,4 +1,4 @@ -import { OB11Config } from '@/onebot/config'; +import { OnebotConfig } from '@/onebot/config/config'; interface LoginRuntimeType { LoginCurrentTime: number; @@ -8,7 +8,7 @@ interface LoginRuntimeType { QQLoginUin: string; NapCatHelper: { onQuickLoginRequested: (uin: string) => Promise<{ result: boolean, message: string }>; - onOB11ConfigChanged: (ob11: OB11Config) => Promise; + onOB11ConfigChanged: (ob11: OnebotConfig) => Promise; QQLoginList: string[] }; } @@ -82,11 +82,11 @@ export const WebUiDataRuntime = { return await LoginRuntime.NapCatHelper.onQuickLoginRequested(uin); }, - setOnOB11ConfigChanged: async function(func: (ob11: OB11Config) => Promise): Promise { + setOnOB11ConfigChanged: async function(func: (ob11: OnebotConfig) => Promise): Promise { LoginRuntime.NapCatHelper.onOB11ConfigChanged = func; }, - setOB11Config: async function(ob11: OB11Config): Promise { + setOB11Config: async function(ob11: OnebotConfig): Promise { await LoginRuntime.NapCatHelper.onOB11ConfigChanged(ob11); }, }; diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts deleted file mode 100644 index 7519f00d..00000000 --- a/src/webui/ui/NapCat.ts +++ /dev/null @@ -1,393 +0,0 @@ -import { SettingList } from './components/SettingList'; -import { SettingItem } from './components/SettingItem'; -import { SettingButton } from './components/SettingButton'; -import { SettingSwitch } from './components/SettingSwitch'; -import { SettingSelect } from './components/SettingSelect'; -import { OB11Config, OB11ConfigWrapper } from './components/WebUiApiOB11Config'; - -async function onSettingWindowCreated(view: Element) { - const isEmpty = (value: any) => value === undefined || false || value === ''; - await OB11ConfigWrapper.Init(localStorage.getItem('auth') as string); - const ob11Config: OB11Config = await OB11ConfigWrapper.GetOB11Config(); - const setOB11Config = (key: string, value: any) => { - const configKey = key.split('.'); - if (configKey.length === 2) { - ob11Config[configKey[1]] = value; - } else if (configKey.length === 3) { - ob11Config[configKey[1]][configKey[2]] = value; - } - // OB11ConfigWrapper.SetOB11Config(ob11Config); // 只有当点保存时才下发配置,而不是在修改值后立即下发 - }; - - const parser = new DOMParser(); - const doc = parser.parseFromString( - [ - '
', - ` -
-
`, - SettingList([ - SettingItem( - 'Napcat', - undefined, - SettingButton('V3.3.12', 'napcat-update-button', 'secondary'), - ), - ]), - SettingList([ - SettingItem( - '启用 HTTP 服务', - undefined, - SettingSwitch('ob11.http.enable', ob11Config.http.enable, { - 'control-display-id': 'config-ob11-http-port', - }), - ), - SettingItem( - 'HTTP 服务监听端口', - undefined, - `
`, - 'config-ob11-http-port', - ob11Config.http.enable, - ), - SettingItem( - '启用 HTTP 心跳', - undefined, - SettingSwitch('ob11.http.enableHeart', ob11Config.http.enableHeart, { - 'control-display-id': 'config-ob11-HTTP.enableHeart', - }), - ), - SettingItem( - '启用 HTTP 事件上报', - undefined, - SettingSwitch('ob11.http.enablePost', ob11Config.http.enablePost, { - 'control-display-id': 'config-ob11-http-postUrls', - }), - ), - `
- -
- HTTP 事件上报密钥 -
-
- -
-
- -
- HTTP 事件上报地址 -
- 添加 -
-
-
`, - SettingItem( - '启用正向 WebSocket 服务', - undefined, - SettingSwitch('ob11.ws.enable', ob11Config.ws.enable, { - 'control-display-id': 'config-ob11-ws-port', - }), - ), - SettingItem( - '正向 WebSocket 服务监听端口', - undefined, - `
`, - 'config-ob11-ws-port', - ob11Config.ws.enable, - ), - SettingItem( - '启用反向 WebSocket 服务', - undefined, - SettingSwitch('ob11.reverseWs.enable', ob11Config.reverseWs.enable, { - 'control-display-id': 'config-ob11-reverseWs-urls', - }), - ), - `
- -
- 反向 WebSocket 监听地址 -
- 添加 -
-
-
`, - SettingItem( - ' WebSocket 服务心跳间隔', - '控制每隔多久发送一个心跳包,单位为毫秒', - `
`, - ), - SettingItem( - 'Access token', - undefined, - `
`, - ), - SettingItem( - '新消息上报格式', - '如客户端无特殊需求推荐保持默认设置,两者的详细差异可参考 OneBot v11 文档', - SettingSelect( - [ - { text: '消息段', value: 'array' }, - { text: 'CQ码', value: 'string' }, - ], - 'ob11.messagePostFormat', - ob11Config.messagePostFormat, - ), - ), - SettingItem( - '音乐卡片签名地址', - undefined, - `
`, - 'ob11.musicSignUrl', - ), - SettingItem( - '启用本地进群时间与发言时间记录', - undefined, - SettingSwitch('ob11.GroupLocalTime.Record', ob11Config.GroupLocalTime.Record, { - 'control-display-id': 'config-ob11-GroupLocalTime-RecordList', - }), - ), - `
- -
- 群列表 -
- 添加 -
-
-
`, - SettingItem( - '', - undefined, - SettingButton('保存', 'config-ob11-save', 'primary'), - ), - ]), - SettingList([ - SettingItem( - '上报 Bot 自身发送的消息', - '上报 event 为 message_sent', - SettingSwitch('ob11.reportSelfMessage', ob11Config.reportSelfMessage), - ), - ]), - SettingList([ - SettingItem( - 'GitHub 仓库', - 'https://github.com/NapNeko/NapCatQQ', - SettingButton('点个星星', 'open-github'), - ), - SettingItem('NapCat 文档', '', SettingButton('看看文档', 'open-docs')), - ]), - SettingItem( - 'Telegram 群', - 'https://t.me/+nLZEnpne-pQ1OWFl', - SettingButton('进去逛逛', 'open-telegram'), - ), - SettingItem( - 'QQ 群', - '518662028', - SettingButton('我要进去', 'open-qq-group'), - ), - '
', - ].join(''), - 'text/html', - ); - - // 外链按钮 - doc.querySelector('#open-github')?.addEventListener('click', () => { - window.open('https://github.com/NapNeko/NapCatQQ', '_blank'); - }); - doc.querySelector('#open-docs')?.addEventListener('click', () => { - window.open('https://napneko.github.io/', '_blank'); - }); - doc.querySelector('#open-telegram')?.addEventListener('click', () => { - window.open('https://t.me/+nLZEnpne-pQ1OWFl', '_blank'); - }); - doc.querySelector('#open-qq-group')?.addEventListener('click', () => { - window.open('https://qm.qq.com/q/VfjAq5HIMS', '_blank'); - }); - // 生成反向地址列表 - const buildHostListItem = ( - type: string, - host: string, - index: number, - inputAttrs: any = {}, - ) => { - const dom = { - container: document.createElement('setting-item'), - input: document.createElement('input'), - inputContainer: document.createElement('div'), - deleteBtn: document.createElement('setting-button'), - }; - dom.container.classList.add('setting-host-list-item'); - dom.container.dataset.direction = 'row'; - Object.assign(dom.input, inputAttrs); - dom.input.classList.add('q-input__inner'); - dom.input.type = 'url'; - dom.input.value = host; - dom.input.addEventListener('input', () => { - ob11Config[type.split('-')[0]][type.split('-')[1]][index] = - dom.input.value; - }); - - dom.inputContainer.classList.add('q-input'); - dom.inputContainer.appendChild(dom.input); - - dom.deleteBtn.innerHTML = '删除'; - dom.deleteBtn.dataset.type = 'secondary'; - dom.deleteBtn.addEventListener('click', () => { - ob11Config[type.split('-')[0]][type.split('-')[1]].splice(index, 1); - initReverseHost(type); - }); - - dom.container.appendChild(dom.inputContainer); - dom.container.appendChild(dom.deleteBtn); - - return dom.container; - }; - const buildHostList = ( - hosts: string[], - type: string, - inputAttr: any = {}, - ) => { - const result: HTMLElement[] = []; - - hosts?.forEach((host, index) => { - result.push(buildHostListItem(type, host, index, inputAttr)); - }); - - return result; - }; - const addReverseHost = ( - type: string, - doc: Document = document, - inputAttr: any = {}, - ) => { - type = type.replace(/\./g, '-');//替换操作 - const hostContainerDom = doc.body.querySelector( - `#config-ob11-${type}-list`, - ); - hostContainerDom?.appendChild( - buildHostListItem( - type, - '', - ob11Config[type.split('-')[0]][type.split('-')[1]].length, - inputAttr, - ), - ); - ob11Config[type.split('-')[0]][type.split('-')[1]].push(''); - }; - const initReverseHost = (type: string, doc: Document = document) => { - type = type.replace(/\./g, '-');//替换操作 - const hostContainerDom = doc.body?.querySelector( - `#config-ob11-${type}-list`, - ); - if (hostContainerDom) { - [...hostContainerDom.childNodes].forEach((dom) => dom.remove()); - buildHostList( - ob11Config[type.split('-')[0]][type.split('-')[1]], - type, - ).forEach((dom) => { - hostContainerDom?.appendChild(dom); - }); - } - }; - - initReverseHost('http.postUrls', doc); - initReverseHost('reverseWs.urls', doc); - initReverseHost('GroupLocalTime.RecordList', doc); - - doc - .querySelector('#config-ob11-http-postUrls-add') - ?.addEventListener('click', () => - addReverseHost('http.postUrls', document, { - placeholder: '如:http://127.0.0.1:5140/onebot', - }), - ); - - doc - .querySelector('#config-ob11-reverseWs-urls-add') - ?.addEventListener('click', () => - addReverseHost('reverseWs.urls', document, { - placeholder: '如:ws://127.0.0.1:5140/onebot', - }), - ); - doc - .querySelector('#config-ob11-GroupLocalTime-RecordList-add') - ?.addEventListener('click', () => - addReverseHost('GroupLocalTime.RecordList', document, { - placeholder: '此处填写群号 -1为全部', - }), - ); - doc.querySelector('#config-ffmpeg-select')?.addEventListener('click', () => { - //选择ffmpeg - }); - - doc.querySelector('#config-open-log-path')?.addEventListener('click', () => { - //打开日志 - }); - - // 开关 - doc - .querySelectorAll('setting-switch[data-config-key]') - .forEach((dom: Element) => { - dom.addEventListener('click', () => { - const active = dom.getAttribute('is-active') == undefined; - //@ts-expect-error 等待修复 - setOB11Config(dom.dataset.configKey, active); - if (active) dom.setAttribute('is-active', ''); - else dom.removeAttribute('is-active'); - //@ts-expect-error 等待修复 - if (!isEmpty(dom.dataset.controlDisplayId)) { - const displayDom = document.querySelector( - //@ts-expect-error 等待修复 - `#${dom.dataset.controlDisplayId}`, - ); - if (active) displayDom?.removeAttribute('is-hidden'); - else displayDom?.setAttribute('is-hidden', ''); - } - }); - }); - - // 输入框 - doc - .querySelectorAll( - 'setting-item .q-input input.q-input__inner[data-config-key]', - ) - .forEach((dom: Element) => { - dom.addEventListener('input', () => { - const Type = dom.getAttribute('type'); - //@ts-expect-error等待修复 - const configKey = dom.dataset.configKey; - const configValue = - Type === 'number' - ? parseInt((dom as HTMLInputElement).value) >= 1 - ? parseInt((dom as HTMLInputElement).value) - : 1 - : (dom as HTMLInputElement).value; - - setOB11Config(configKey, configValue); - }); - }); - - // 下拉框 - doc - .querySelectorAll('ob-setting-select[data-config-key]') - .forEach((dom: Element) => { - //@ts-expect-error等待修复 - dom?.addEventListener('selected', (e: CustomEvent) => { - //@ts-expect-error等待修复 - const configKey = dom.dataset.configKey; - const configValue = e.detail.value; - setOB11Config(configKey, configValue); - }); - }); - - // 保存按钮 - doc.querySelector('#config-ob11-save')?.addEventListener('click', () => { - OB11ConfigWrapper.SetOB11Config(ob11Config); - alert('保存成功'); - }); - doc.body.childNodes.forEach((node) => { - view.appendChild(node); - }); -} - -export { onSettingWindowCreated }; diff --git a/src/webui/ui/components/SettingButton.ts b/src/webui/ui/components/SettingButton.ts deleted file mode 100644 index 02132f3c..00000000 --- a/src/webui/ui/components/SettingButton.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const SettingButton = (text: string, id?: string, type: string = 'secondary') => { - return `${text}`; -}; \ No newline at end of file diff --git a/src/webui/ui/components/SettingItem.ts b/src/webui/ui/components/SettingItem.ts deleted file mode 100644 index 11c15426..00000000 --- a/src/webui/ui/components/SettingItem.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const SettingItem = ( - title: string, - subtitle?: string, - action?: string, - id?: string, - visible: boolean = true, -) => { - return ` -
- ${title} - ${subtitle ? `${subtitle}` : ''} -
- ${action ? `
${action}
` : ''} -
`; -}; \ No newline at end of file diff --git a/src/webui/ui/components/SettingList.ts b/src/webui/ui/components/SettingList.ts deleted file mode 100644 index 8db03dc2..00000000 --- a/src/webui/ui/components/SettingList.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const SettingList = ( - items: string[], - title?: string, - isCollapsible: boolean = false, - direction: string = 'column', -) => { - return ` - - - ${items.join('')} - - - `; -}; \ No newline at end of file diff --git a/src/webui/ui/components/SettingOption.ts b/src/webui/ui/components/SettingOption.ts deleted file mode 100644 index ce44e2e4..00000000 --- a/src/webui/ui/components/SettingOption.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const SettingOption = (text: string, value?: string, isSelected: boolean = false) => { - return `${text}`; -}; \ No newline at end of file diff --git a/src/webui/ui/components/SettingSelect.ts b/src/webui/ui/components/SettingSelect.ts deleted file mode 100644 index 461f1388..00000000 --- a/src/webui/ui/components/SettingSelect.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { SettingOption } from './SettingOption'; - -interface MouseEventExtend extends MouseEvent { - target: HTMLElement; -} - -// -const SelectTemplate = document.createElement('template'); -SelectTemplate.innerHTML = ` -
-
- - - - -
- -
`; - -window.customElements.define( - 'ob-setting-select', - class extends HTMLElement { - readonly _button: HTMLDivElement; - readonly _text: HTMLInputElement; - readonly _context: HTMLUListElement; - - constructor() { - super(); - - this.attachShadow({ mode: 'open' }); - this.shadowRoot?.append(SelectTemplate.content.cloneNode(true)); - - this._button = this.shadowRoot!.querySelector('div[part="button"]')!; - this._text = this.shadowRoot!.querySelector('input[part="current-text"]')!; - this._context = this.shadowRoot!.querySelector('ul[part="option-list"]')!; - - const buttonClick = () => { - const isHidden = this._context.classList.toggle('hidden'); - window[`${isHidden ? 'remove' : 'add'}EventListener`]('pointerdown', windowPointerDown); - }; - - const windowPointerDown = ({ target }: any) => { - if (!this.contains(target)) buttonClick(); - }; - - this._button.addEventListener('click', buttonClick); - this._context.addEventListener('click', (event) => { - const { target } = event as MouseEventExtend; - - if (target.tagName !== 'SETTING-OPTION') return; - buttonClick(); - - if (target.hasAttribute('is-selected')) return; - - this.querySelectorAll('setting-option[is-selected]').forEach((dom) => dom.toggleAttribute('is-selected')); - target.toggleAttribute('is-selected'); - - this._text.value = target.textContent as string; - this.dispatchEvent( - new CustomEvent('selected', { - bubbles: true, - composed: true, - detail: { - name: target.textContent, - value: target.dataset.value, - }, - }), - ); - }); - - this._text.value = this.querySelector('setting-option[is-selected]')?.textContent as string; - } - }, -); - -export const SettingSelect = (items: Array<{ text: string; value: string }>, configKey?: string, configValue?: any) => { - return ` - ${items - .map((e, i) => { - return SettingOption(e.text, e.value, configKey && configValue ? configValue === e.value : i === 0); - }) - .join('')} -`; -}; diff --git a/src/webui/ui/components/SettingSwitch.ts b/src/webui/ui/components/SettingSwitch.ts deleted file mode 100644 index 65573b7d..00000000 --- a/src/webui/ui/components/SettingSwitch.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const SettingSwitch = (configKey?: string, isActive: boolean = false, extraData?: Record) => { - return ` `data-${key}="${extraData[key]}"`) : ''} - > - `; -}; \ No newline at end of file diff --git a/src/webui/ui/components/WebUiApiOB11Config.ts b/src/webui/ui/components/WebUiApiOB11Config.ts deleted file mode 100644 index 2d510ecd..00000000 --- a/src/webui/ui/components/WebUiApiOB11Config.ts +++ /dev/null @@ -1,79 +0,0 @@ -export interface OB11Config { - [key: string]: any; - - http: { - enable: boolean; - host: ''; - port: number; - secret: ''; - enableHeart: boolean; - enablePost: boolean; - postUrls: string[]; - }; - ws: { - enable: boolean; - host: ''; - port: number; - }; - reverseWs: { - enable: boolean; - urls: string[]; - }; - GroupLocalTime: { - Record: boolean, - RecordList: Array - }; - debug: boolean; - heartInterval: number; - messagePostFormat: 'array' | 'string'; - enableLocalFile2Url: boolean; - musicSignUrl: ''; - reportSelfMessage: boolean; - token: ''; - -} - -class WebUiApiOB11ConfigWrapper { - private retCredential: string = ''; - - async Init(Credential: string) { - this.retCredential = Credential; - } - - async GetOB11Config(): Promise { - const ConfigResponse = await fetch('../api/OB11Config/GetConfig', { - method: 'POST', - headers: { - Authorization: 'Bearer ' + this.retCredential, - 'Content-Type': 'application/json', - }, - }); - if (ConfigResponse.status == 200) { - const ConfigResponseJson = await ConfigResponse.json(); - if (ConfigResponseJson.code == 0) { - return ConfigResponseJson?.data; - } - } - return {} as OB11Config; - } - - async SetOB11Config(config: OB11Config): Promise { - const ConfigResponse = await fetch('../api/OB11Config/SetConfig', { - method: 'POST', - headers: { - Authorization: 'Bearer ' + this.retCredential, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ config: JSON.stringify(config) }), - }); - if (ConfigResponse.status == 200) { - const ConfigResponseJson = await ConfigResponse.json(); - if (ConfigResponseJson.code == 0) { - return true; - } - } - return false; - } -} - -export const OB11ConfigWrapper = new WebUiApiOB11ConfigWrapper();