163 lines
4.7 KiB
TypeScript
163 lines
4.7 KiB
TypeScript
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<string, unknown>).get(
|
|
'notifications',
|
|
) as Immutable.Map<string, Immutable.Map<string, unknown> | 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 (
|
|
<section role='group' aria-labelledby={`notifications-${type}`}>
|
|
<h3 id={`notifications-${type}`}>{label}</h3>
|
|
|
|
<div className='column-settings__row'>
|
|
<SettingToggle
|
|
disabled={!browserPermission}
|
|
prefix='notifications_desktop'
|
|
settings={settings}
|
|
settingPath={['alerts', type]}
|
|
onChange={handleChange}
|
|
label={
|
|
<FormattedMessage
|
|
id='notifications.column_settings.alert'
|
|
defaultMessage='Desktop notifications'
|
|
/>
|
|
}
|
|
/>
|
|
|
|
{showPushSettings && (
|
|
<SettingToggle
|
|
prefix='notifications_push'
|
|
settings={pushSettings}
|
|
settingPath={['alerts', type]}
|
|
onChange={handlePushChange}
|
|
label={
|
|
<FormattedMessage
|
|
id='notifications.column_settings.push'
|
|
defaultMessage='Push notifications'
|
|
/>
|
|
}
|
|
/>
|
|
)}
|
|
|
|
<SettingToggle
|
|
prefix='notifications'
|
|
settings={settings}
|
|
settingPath={['shows', type]}
|
|
onChange={handleChange}
|
|
label={
|
|
<FormattedMessage
|
|
id='notifications.column_settings.show'
|
|
defaultMessage='Show in column'
|
|
/>
|
|
}
|
|
/>
|
|
|
|
<SettingToggle
|
|
prefix='notifications'
|
|
settings={settings}
|
|
settingPath={['sounds', type]}
|
|
onChange={handleChange}
|
|
label={
|
|
<FormattedMessage
|
|
id='notifications.column_settings.sound'
|
|
defaultMessage='Play sound'
|
|
/>
|
|
}
|
|
/>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|