Files
session-notify/src/client/core/actions.js
T

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