feat:webui-2

This commit is contained in:
手瓜一十雪
2024-05-05 13:01:23 +08:00
parent 193b0ad0f0
commit 2f325cfe26
7 changed files with 128 additions and 12 deletions

View File

@@ -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')) {

View 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>`
}

View 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>`
}

View 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>`
}

View 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>`
}

View 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>`
}

View 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>`
}