mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
feat:webui-2
This commit is contained in:
@@ -1,20 +1,9 @@
|
||||
/// <reference path="../global.d.ts" />
|
||||
import { CheckVersion } from '../common/types'
|
||||
import { SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect } from './components'
|
||||
// @ts-ignore
|
||||
|
||||
import StyleRaw from './style.css?raw'
|
||||
import { iconSvg } from './icon'
|
||||
|
||||
// 打开设置界面时触发
|
||||
|
||||
function aprilFoolsEgg(node: Element) {
|
||||
let today = new Date()
|
||||
if (today.getDate() === 1) {
|
||||
console.log('超时空猫猫!!!')
|
||||
node.querySelector('.name').innerHTML = 'ChronoCat'
|
||||
}
|
||||
}
|
||||
|
||||
function initSideBar() {
|
||||
document.querySelectorAll('.nav-item.liteloader').forEach((node) => {
|
||||
if (node.textContent.startsWith('LLOneBot')) {
|
||||
|
3
static/components/SettingButton.ts
Normal file
3
static/components/SettingButton.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const SettingButton = (text: string, id?: string, type: string = 'secondary') => {
|
||||
return `<setting-button ${type ? `data-type="${type}"` : ''} ${id ? `id="${id}"` : ''}>${text}</setting-button>`
|
||||
}
|
15
static/components/SettingItem.ts
Normal file
15
static/components/SettingItem.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export const SettingItem = (
|
||||
title: string,
|
||||
subtitle?: string,
|
||||
action?: string,
|
||||
id?: string,
|
||||
visible: boolean = true,
|
||||
) => {
|
||||
return `<setting-item ${id ? `id="${id}"` : ''} ${!visible ? 'is-hidden' : ''}>
|
||||
<div>
|
||||
<setting-text>${title}</setting-text>
|
||||
${subtitle ? `<setting-text data-type="secondary">${subtitle}</setting-text>` : ''}
|
||||
</div>
|
||||
${action ? `<div>${action}</div>` : ''}
|
||||
</setting-item>`
|
||||
}
|
14
static/components/SettingList.ts
Normal file
14
static/components/SettingList.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export const SettingList = (
|
||||
items: string[],
|
||||
title?: string,
|
||||
isCollapsible: boolean = false,
|
||||
direction: string = 'column',
|
||||
) => {
|
||||
return `<setting-section ${title && !isCollapsible ? `data-title="${title}"` : ''}>
|
||||
<setting-panel>
|
||||
<setting-list ${direction ? `data-direction="${direction}"` : ''} ${isCollapsible ? 'is-collapsible' : ''} ${title && isCollapsible ? `data-title="${title}"` : ''}>
|
||||
${items.join('')}
|
||||
</setting-list>
|
||||
</setting-panel>
|
||||
</setting-section>`
|
||||
}
|
3
static/components/SettingOption.ts
Normal file
3
static/components/SettingOption.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const SettingOption = (text: string, value?: string, isSelected: boolean = false) => {
|
||||
return `<setting-option ${value ? `data-value="${value}"` : ''} ${isSelected ? 'is-selected' : ''}>${text}</setting-option>`
|
||||
}
|
84
static/components/SettingSelect.ts
Normal file
84
static/components/SettingSelect.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { SettingOption } from './option'
|
||||
|
||||
interface MouseEventExtend extends MouseEvent {
|
||||
target: HTMLElement
|
||||
}
|
||||
|
||||
// <ob-setting-select>
|
||||
const SelectTemplate = document.createElement('template')
|
||||
SelectTemplate.innerHTML = `<style>
|
||||
.hidden { display: none !important; }
|
||||
</style>
|
||||
<div part="parent">
|
||||
<div part="button">
|
||||
<input type="text" placeholder="请选择" part="current-text" />
|
||||
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" part="button-arrow">
|
||||
<path d="M12 6.0001L8.00004 10L4 6" stroke="currentColor" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<ul class="hidden" part="option-list"><slot></slot></ul>
|
||||
</div>`
|
||||
|
||||
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 }) => {
|
||||
if (!this.contains(target)) buttonClick()
|
||||
}
|
||||
|
||||
this._button.addEventListener('click', buttonClick)
|
||||
this._context.addEventListener('click', ({ target }: 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
|
||||
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
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
export const SettingSelect = (items: Array<{ text: string; value: string }>, configKey?: string, configValue?: any) => {
|
||||
return `<ob-setting-select ${configKey ? `data-config-key="${configKey}"` : ''}>
|
||||
${items
|
||||
.map((e, i) => {
|
||||
return SettingOption(e.text, e.value, configKey && configValue ? configValue === e.value : i === 0)
|
||||
})
|
||||
.join('')}
|
||||
</ob-setting-select>`
|
||||
}
|
8
static/components/SettingSwitch.ts
Normal file
8
static/components/SettingSwitch.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const SettingSwitch = (configKey?: string, isActive: boolean = false, extraData?: Record<string, string>) => {
|
||||
return `<setting-switch
|
||||
${configKey ? `data-config-key="${configKey}"` : ''}
|
||||
${isActive ? 'is-active' : ''}
|
||||
${extraData ? Object.keys(extraData).map((key) => `data-${key}="${extraData[key]}"`) : ''}
|
||||
>
|
||||
</setting-switch>`
|
||||
}
|
Reference in New Issue
Block a user