♻️ refactor(client): 浏览器半拆成 src 模块,client.js 改由构建产出
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* This plugin's configuration, rendered on its own page in the plugin
|
||||
* manager (`plugins.bundle.config`, keyed by this package's name).
|
||||
*
|
||||
* The owner asks for two views: `summary` (a one-liner that stands in for the
|
||||
* row's description) and `page` (the whole form). Everything visible here
|
||||
* belongs to this package, including the platform-specific permission hint.
|
||||
*
|
||||
* @module @dsh-plugin/session-notify/client/ui/ConfigSection
|
||||
*/
|
||||
|
||||
import * as React from 'react'
|
||||
import { KINDS } from '../constants.js'
|
||||
import { windowIsAway } from '../platform.js'
|
||||
import { KindRow } from './KindRow.js'
|
||||
import { seatTranslator, useOwnStore } from './hooks.js'
|
||||
import { CSS } from './styles.js'
|
||||
|
||||
const h = React.createElement
|
||||
|
||||
export function ConfigSection(props) {
|
||||
const snapshot = useOwnStore(props.store)
|
||||
const tr = seatTranslator(props, props.fallbackT)
|
||||
if (props.view === 'summary') return h(React.Fragment, null, tr('settings.description'))
|
||||
const permission = snapshot.permission
|
||||
const supported = permission !== 'unsupported'
|
||||
const failed = permission === 'denied' || snapshot.promptError !== ''
|
||||
const statusKey = permission === 'granted'
|
||||
? 'settings.permission.granted'
|
||||
: permission === 'denied'
|
||||
? 'settings.permission.denied'
|
||||
: supported
|
||||
? 'settings.permission.default'
|
||||
: 'settings.permission.unsupported'
|
||||
const permissionText = snapshot.promptError === ''
|
||||
? `${tr(statusKey)}${permission === 'denied' || !supported ? ` · ${tr(`settings.permission.hint.${props.platform}`)}` : ''}`
|
||||
: snapshot.promptError
|
||||
const health = snapshot.health
|
||||
const healthText = health.state === 'watching'
|
||||
? tr('settings.health.watching')
|
||||
: health.state === 'noHooks'
|
||||
? tr('settings.health.noHooks')
|
||||
: health.state === 'error'
|
||||
? tr('settings.health.error', { message: health.message })
|
||||
: tr('settings.health.starting')
|
||||
const healthFailed = health.state !== 'watching' && health.state !== 'starting'
|
||||
return h(React.Fragment, null,
|
||||
h('style', null, CSS),
|
||||
h('div', { className: 'dsn-sections' },
|
||||
// The page header already shows this bundle's title and description, so
|
||||
// this section opens with what the header cannot say: how alerts are
|
||||
// carried, and what this form changes.
|
||||
h('section', { className: 'dsn-section' },
|
||||
h('p', { className: 'dsn-section-desc' }, tr('config.intro'))),
|
||||
h('section', { className: 'dsn-section' },
|
||||
h('h3', { className: 'dsn-section-title' }, tr('config.section.kinds')),
|
||||
KINDS.map((kind) => h(KindRow, {
|
||||
key: kind,
|
||||
label: tr(`settings.kind.${kind}`),
|
||||
checked: snapshot.kinds[kind] === true,
|
||||
disabled: false,
|
||||
onToggle: () => props.setKind(kind, snapshot.kinds[kind] !== true),
|
||||
})),
|
||||
h('p', { className: 'dsn-section-desc' }, tr('config.saveNote'))),
|
||||
h('section', { className: 'dsn-section' },
|
||||
h('h3', { className: 'dsn-section-title' }, tr('config.section.permission')),
|
||||
h('div', { className: 'dsn-row' },
|
||||
h('div', { className: 'dsn-row-text' },
|
||||
h('p', {
|
||||
className: `dsn-status${failed ? ' dsn-status-error' : ''}`,
|
||||
role: failed ? 'alert' : 'status',
|
||||
}, permissionText)),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dsn-button',
|
||||
disabled: !supported,
|
||||
onClick: permission === 'granted' ? props.testSystem : props.ask,
|
||||
}, tr(!supported
|
||||
? 'settings.action.unsupported'
|
||||
: permission === 'granted' ? 'settings.action.testSystem' : 'settings.action.allow'))),
|
||||
h('p', { className: 'dsn-section-desc' }, tr('config.testHint'))),
|
||||
h('section', { className: 'dsn-section' },
|
||||
h('h3', { className: 'dsn-section-title' }, tr('config.section.status')),
|
||||
h('div', { className: 'dsn-row' },
|
||||
h('div', { className: 'dsn-row-text' },
|
||||
h('p', { className: 'dsn-status' }, `${tr('config.diag.window')}: ${tr(windowIsAway() ? 'config.diag.away' : 'config.diag.inFront')}`),
|
||||
h('p', {
|
||||
className: `dsn-status${healthFailed ? ' dsn-status-error' : ''}`,
|
||||
role: healthFailed ? 'alert' : 'status',
|
||||
}, healthText),
|
||||
h('p', { className: 'dsn-status' }, props.copy.describeDelivery(snapshot.lastDelivery, tr)),
|
||||
h('p', { className: 'dsn-status' }, props.copy.describeReplay(props.replayCount(), tr))),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dsn-button',
|
||||
onClick: props.testAny,
|
||||
}, tr('settings.action.testAny'))))))
|
||||
}
|
||||
Reference in New Issue
Block a user