88 lines
3.1 KiB
JavaScript
88 lines
3.1 KiB
JavaScript
/**
|
|
* 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 }
|
|
}
|