SwyxWeb: React-Frontend und Spring-Boot-Backend mit SwyxTray-Mock. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
import { describeCall, type CallEvent } from '../swyx/protocol'
|
|
|
|
type Permission = NotificationPermission | 'unsupported'
|
|
|
|
function currentPermission(): Permission {
|
|
return typeof Notification === 'undefined' ? 'unsupported' : Notification.permission
|
|
}
|
|
|
|
/**
|
|
* Zeigt bei einem eingehenden Anruf eine System-Benachrichtigung, damit der
|
|
* Anruf auch bemerkt wird, wenn der Tab im Hintergrund liegt.
|
|
*/
|
|
export function useCallNotifications(ringingCall: CallEvent | null) {
|
|
const [permission, setPermission] = useState<Permission>(currentPermission)
|
|
// Pro klingelnder Leitung nur einmal benachrichtigen.
|
|
const notifiedRef = useRef<number | null>(null)
|
|
|
|
const requestPermission = useCallback(() => {
|
|
if (typeof Notification === 'undefined') return
|
|
void Notification.requestPermission().then(setPermission)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!ringingCall) {
|
|
notifiedRef.current = null
|
|
return
|
|
}
|
|
if (permission !== 'granted' || notifiedRef.current === ringingCall.line) return
|
|
|
|
notifiedRef.current = ringingCall.line
|
|
const notification = new Notification(`Eingehender Anruf · Leitung ${ringingCall.line}`, {
|
|
body: describeCall(ringingCall),
|
|
tag: `swyx-line-${ringingCall.line}`,
|
|
})
|
|
notification.onclick = () => {
|
|
window.focus()
|
|
notification.close()
|
|
}
|
|
return () => notification.close()
|
|
}, [ringingCall, permission])
|
|
|
|
return { permission, requestPermission }
|
|
}
|