From 21989b558bd074bf84ac08c174d7a411fda1ffb7 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Tue, 17 Jun 2025 12:37:14 +0300 Subject: Granular notification settings (#8484) * add mockup screen * add notification index screen * add redirect screen * upgrade sdk * new icons * add new screens * make router typesafe, finish adding screens * add routes to go server * load settings * push notif settings * improve web * fix lockfile lint * no $type on preferences * prompt to enable push notifications * fix reply prefs * space out options * fix copy error * Update RepostsOnRepostsNotificationSettings.tsx * only send minimal diff to putPrefs * fix yarn.lock * Update Navigation.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/screens/Settings/NotificationSettings/index.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * add description to `syncOthers` --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> --- .../components/PreferenceControls.tsx | 194 +++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx (limited to 'src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx') diff --git a/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx b/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx new file mode 100644 index 000000000..336e08695 --- /dev/null +++ b/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx @@ -0,0 +1,194 @@ +import {useMemo} from 'react' +import {View} from 'react-native' +import {type AppBskyNotificationDefs} from '@atproto/api' +import {type FilterablePreference} from '@atproto/api/dist/client/types/app/bsky/notification/defs' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useNotificationSettingsUpdateMutation} from '#/state/queries/notifications/settings' +import {atoms as a, platform, useTheme} from '#/alf' +import * as Toggle from '#/components/forms/Toggle' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' +import {Divider} from '../../components/SettingsList' + +export function PreferenceControls({ + name, + syncOthers, + preference, + allowDisableInApp = true, +}: { + name: Exclude + /** + * Keep other prefs in sync with `name`. For use in the "everything else" category + * which groups starterpack joins + verified + unverified notifications into a single toggle. + */ + syncOthers?: Exclude[] + preference?: AppBskyNotificationDefs.Preference | FilterablePreference + allowDisableInApp?: boolean +}) { + if (!preference) + return ( + + + + ) + + return ( + + ) +} + +export function Inner({ + name, + syncOthers = [], + preference, + allowDisableInApp, +}: { + name: Exclude + syncOthers?: Exclude[] + preference: AppBskyNotificationDefs.Preference | FilterablePreference + allowDisableInApp: boolean +}) { + const t = useTheme() + const {_} = useLingui() + const {mutate} = useNotificationSettingsUpdateMutation() + + const channels = useMemo(() => { + const arr = [] + if (preference.list) arr.push('list') + if (preference.push) arr.push('push') + return arr + }, [preference]) + + const onChangeChannels = (change: string[]) => { + const newPreference = { + ...preference, + list: change.includes('list'), + push: change.includes('push'), + } satisfies typeof preference + + mutate({ + [name]: newPreference, + ...Object.fromEntries(syncOthers.map(key => [key, newPreference])), + }) + } + + const onChangeFilter = ([change]: string[]) => { + if (change !== 'all' && change !== 'follows') + throw new Error('Invalid filter') + + const newPreference = { + ...preference, + filter: change, + } satisfies typeof preference + + mutate({ + [name]: newPreference, + ...Object.fromEntries(syncOthers.map(key => [key, newPreference])), + }) + } + + return ( + + + + + + Push notifications + + + + {allowDisableInApp && ( + + + In-app notifications + + + + )} + + + {'filter' in preference && ( + <> + + From + + + + + 0 && t.atoms.text, + a.font_normal, + a.text_md, + ]}> + Everyone + + + + + 0 && t.atoms.text, + a.font_normal, + a.text_md, + ]}> + People I follow + + + + + + )} + + ) +} -- cgit 1.4.1