♻️ refactor(client): 浏览器半拆成 src 模块,client.js 改由构建产出
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* What the settings page can do: the two test buttons, the permission request,
|
||||
* and the trigger switches.
|
||||
*
|
||||
* @module @dsh-plugin/session-notify/client/core/actions
|
||||
*/
|
||||
|
||||
import { notificationApi, notificationPermission } from '../platform.js'
|
||||
import { writeStoredKinds } from './storage.js'
|
||||
import { text } from './log.js'
|
||||
|
||||
/**
|
||||
* Build the actions over one store.
|
||||
* @param deps - the plugin store; the translate function; the delivery path (the
|
||||
* test alert goes through the ordinary channel decision); the system channel
|
||||
* (the channel-specific test); the popup stack (used when the system channel
|
||||
* refuses a test); and `publish` for the one branch that only re-renders.
|
||||
* @returns the actions the settings page and the permission row call.
|
||||
*/
|
||||
export function createActions({ store, t, delivery, system, toasts, publish }) {
|
||||
/** Build one test alert that skips the throttle and the "on screen" rule. */
|
||||
const testCandidate = (title) => ({
|
||||
kind: 'completion',
|
||||
sessionId: 'test',
|
||||
title,
|
||||
detail: '',
|
||||
pendingKind: '',
|
||||
test: true,
|
||||
})
|
||||
|
||||
/**
|
||||
* Raise one test alert through whichever channel the window state selects.
|
||||
* Verified from the config page, where the user is looking at the app, so it
|
||||
* normally lands in the popup — the way to prove the system channel is to
|
||||
* press the button in a channel-specific test instead.
|
||||
*/
|
||||
const sendTest = () => {
|
||||
delivery.deliver(testCandidate(t('config.testAny')), true)
|
||||
}
|
||||
|
||||
/** Raise the test alert on the system channel specifically, whatever the focus is. */
|
||||
const sendTestSystem = () => {
|
||||
const candidate = testCandidate(t('config.testSystem'))
|
||||
const result = system.notifySystem(candidate, true)
|
||||
if (result.outcome === 'raised') {
|
||||
delivery.recordDelivery('system', candidate, result)
|
||||
return
|
||||
}
|
||||
toasts.showToast(candidate)
|
||||
delivery.recordDelivery(`system-refused-${result.outcome}`, candidate)
|
||||
}
|
||||
|
||||
/** Request notification permission inside a user gesture, then report the outcome. */
|
||||
const requestPermission = async () => {
|
||||
const Ctor = notificationApi()
|
||||
if (Ctor === undefined) {
|
||||
publish()
|
||||
return
|
||||
}
|
||||
try {
|
||||
let result = Ctor.requestPermission()
|
||||
if (result === undefined) {
|
||||
result = new Promise((resolve) => {
|
||||
Ctor.requestPermission((value) => resolve(value))
|
||||
})
|
||||
}
|
||||
await result
|
||||
} catch (error) {
|
||||
const snapshot = store.getSnapshot()
|
||||
store.set({ ...snapshot, promptError: t('settings.permission.promptFailed', { message: text(error) }) })
|
||||
return
|
||||
}
|
||||
const snapshot = store.getSnapshot()
|
||||
store.set({ ...snapshot, permission: notificationPermission(), promptError: '' })
|
||||
if (notificationPermission() === 'granted') sendTest()
|
||||
}
|
||||
|
||||
/** Toggle one trigger and remember the choice. */
|
||||
const setKindEnabled = (kind, enabled) => {
|
||||
const snapshot = store.getSnapshot()
|
||||
const kinds = { ...snapshot.kinds, [kind]: enabled }
|
||||
writeStoredKinds(kinds)
|
||||
store.set({ ...snapshot, kinds })
|
||||
}
|
||||
|
||||
return { sendTest, sendTestSystem, requestPermission, setKindEnabled }
|
||||
}
|
||||
Reference in New Issue
Block a user