import { useCallback } from 'react'; import type { FC, ReactNode } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import { showAlert } from '@/mastodon/actions/alerts'; import { requestBrowserPermission } from '@/mastodon/actions/notifications'; import { changeAlerts } from '@/mastodon/actions/push_notifications'; import { changeSetting } from '@/mastodon/actions/settings'; import { createAppSelector, useAppDispatch, useAppSelector, } from '@/mastodon/store'; import SettingToggle from './setting_toggle'; const selectNotificationSettings = createAppSelector( [ (state) => (state.settings as Immutable.Map).get( 'notifications', ) as Immutable.Map | boolean>, (state) => state.notifications.get('browserPermission') as string, (state) => state.push_notifications, ], (settings, browserPermission, pushSettings) => ({ settings, browserPermission: browserPermission !== 'denied', pushSettings, showPushSettings: pushSettings.get('supported') && pushSettings.get('enabled'), }), ); const messages = defineMessages({ permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: "Desktop notifications can't be enabled, as browser permission has been denied before", }, }); type SettingsType = 'alerts' | 'shows' | 'sounds'; export const ColumnSettingsGroup: FC<{ label: ReactNode; type: string }> = ({ label, type, }) => { const { settings, browserPermission, pushSettings, showPushSettings } = useAppSelector(selectNotificationSettings); const dispatch = useAppDispatch(); const handleChange = useCallback( (path: [SettingsType, string], checked: boolean) => { if ( path[0] === 'alerts' && checked && typeof window.Notification !== 'undefined' && Notification.permission !== 'granted' ) { dispatch( requestBrowserPermission((permission) => { if (permission === 'granted') { dispatch(changeSetting(['notifications', ...path], checked)); } else { dispatch(showAlert({ message: messages.permissionDenied })); } }), ); } else { dispatch(changeSetting(['notifications', ...path], checked)); } }, [dispatch], ); const handlePushChange = useCallback( (path: string[], checked: boolean) => { if ( checked && typeof window.Notification !== 'undefined' && Notification.permission !== 'granted' ) { dispatch( requestBrowserPermission((permission: NotificationPermission) => { if (permission === 'granted') { dispatch(changeAlerts(path, checked)); } else { dispatch(showAlert({ message: messages.permissionDenied })); } }), ); } else { dispatch(changeAlerts(path, checked)); } }, [dispatch], ); return (

{label}

} /> {showPushSettings && ( } /> )} } /> } />
); };