import React, { useCallback, useEffect, useState } from 'react'; import { Box, Text, Switch, Button, color, Spinner } from 'folds'; import { IPusherRequest } from 'matrix-js-sdk'; import { SequenceCard } from '../../../components/sequence-card'; import { SequenceCardStyle } from '../styles.css'; import { SettingTile } from '../../../components/setting-tile'; import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; import { getNotificationState, usePermissionState } from '../../../hooks/usePermission'; import { useEmailNotifications } from '../../../hooks/useEmailNotifications'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { isCapacitorNative, requestSystemNotificationPermission } from '../../../utils/tauri'; import { isBackgroundSyncSupported, getBackgroundSyncStatus, requestResetPushRegistration, triggerBackgroundSyncPing, } from '../../../utils/backgroundSync'; function EmailNotification() { const mx = useMatrixClient(); const [result, refreshResult] = useEmailNotifications(); const [setState, setEnable] = useAsyncCallback( useCallback( async (email: string, enable: boolean) => { if (enable) { await mx.setPusher({ kind: 'email', app_id: 'm.email', pushkey: email, app_display_name: 'Email Notifications', device_display_name: email, lang: 'en', data: { brand: 'Paarrot', }, append: true, }); return; } await mx.setPusher({ pushkey: email, app_id: 'm.email', kind: null, } as unknown as IPusherRequest); }, [mx] ) ); const handleChange = (value: boolean) => { if (result && result.email) { setEnable(result.email, value).then(() => { refreshResult(); }); } }; return ( {result && !result.email && ( Your account does not have any email attached. )} {result && result.email && <>Send notification to your email. {`("${result.email}")`}} {result === null && ( Unexpected Error! )} {result === undefined && 'Send notification to your email.'} } after={ <> {setState.status !== AsyncStatus.Loading && typeof result === 'object' && result?.email && } {(setState.status === AsyncStatus.Loading || result === undefined) && ( )} } /> ); } export function SystemNotification() { const notifPermission = usePermissionState('notifications', getNotificationState()); const capacitorNative = isCapacitorNative(); const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications'); const [isNotificationSounds, setIsNotificationSounds] = useSetting( settingsAtom, 'isNotificationSounds' ); const requestNotificationPermission = async () => { await requestSystemNotificationPermission(); }; return ( System {'Notification' in window ? 'Notification permission is blocked. Please allow notification permission from browser address bar.' : 'Notifications are not supported by the system.'} ) : ( Show desktop notifications when message arrive. ) } after={ notifPermission === 'prompt' ? ( ) : ( ) } /> } /> {isBackgroundSyncSupported() && } ); } type PushStatus = { registered: boolean; distributor: string; endpoint: string; }; /** Android-only section showing UnifiedPush registration status and controls. */ function AndroidPushNotifications() { const [status, setStatus] = useState(undefined); const [loading, setLoading] = useState(true); const refresh = useCallback(async () => { setLoading(true); const s = await getBackgroundSyncStatus(); setStatus( s ? { registered: s.registered, distributor: s.distributor || '', endpoint: s.endpoint || '', } : undefined ); setLoading(false); }, []); useEffect(() => { void refresh(); }, [refresh]); const [resetState, reset] = useAsyncCallback( useCallback(async () => { await requestResetPushRegistration(); await refresh(); }, [refresh]) ); const [pingState, ping] = useAsyncCallback( useCallback(async () => { await triggerBackgroundSyncPing('manual-test'); }, []) ); const isBusy = loading || resetState.status === AsyncStatus.Loading || pingState.status === AsyncStatus.Loading; return ( Android Push (UnifiedPush) Failed to read push status. ) : status.registered ? ( <> {`Distributor: ${status.distributor || 'unknown'}`} ) : ( Not registered. Tap "Reset" to choose a distributor app. ) } after={loading ? : undefined} /> void reset()} > {resetState.status === AsyncStatus.Loading ? ( ) : ( Reset )} } /> void ping()} > {pingState.status === AsyncStatus.Loading ? ( ) : ( Send Test )} } /> ); }