import {useEffect} from 'react' import {Linking, View} from 'react-native' import * as Notification from 'expo-notifications' import {Trans, useLingui} from '@lingui/react/macro' import {useQuery, useQueryClient} from '@tanstack/react-query' import {useAppState} from '#/lib/appState' import { type AllNavigatorParams, type NativeStackScreenProps, } from '#/lib/routes/types' import { useChatNotificationSettingsQuery, useNotificationSettingsQuery, } from '#/state/queries/notifications/settings' import {atoms as a} from '#/alf' import {Admonition} from '#/components/Admonition' import * as Dialog from '#/components/Dialog' import {NotificationSettingsDialog} from '#/components/dialogs/NotificationSettingsDialog' import {At_Stroke2_Corner2_Rounded as AtIcon} from '#/components/icons/At' import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging' import {Bubble_Stroke2_Corner2_Rounded as BubbleIcon} from '#/components/icons/Bubble' import {Envelope_Stroke2_Corner2_Rounded as EnvelopeIcon} from '#/components/icons/Envelope' import {Haptic_Stroke2_Corner2_Rounded as HapticIcon} from '#/components/icons/Haptic' import { Heart2_Stroke2_Corner0_Rounded as HeartIcon, LikeRepost_Stroke2_Corner2_Rounded as LikeRepostIcon, } from '#/components/icons/Heart2' import {Message_Stroke2_Corner0_Rounded as MessageIcon} from '#/components/icons/Message' import {PersonPlus_Stroke2_Corner2_Rounded as PersonPlusIcon} from '#/components/icons/Person' import {CloseQuote_Stroke2_Corner0_Rounded as CloseQuoteIcon} from '#/components/icons/Quote' import { Repost_Stroke2_Corner2_Rounded as RepostIcon, RepostRepost_Stroke2_Corner2_Rounded as RepostRepostIcon, } from '#/components/icons/Repost' import {Shapes_Stroke2_Corner0_Rounded as ShapesIcon} from '#/components/icons/Shapes' import * as Layout from '#/components/Layout' import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env' import * as SettingsList from '../components/SettingsList' import {ChatNotificationDialogs} from './components/ChatNotificationDialogs' import {ItemTextWithSubtitle} from './components/ItemTextWithSubtitle' import {SettingPreview} from './components/SettingPreview' const RQKEY = ['notification-permissions'] type Props = NativeStackScreenProps export function NotificationSettingsScreen({}: Props) { const {t: l} = useLingui() const queryClient = useQueryClient() const {data: settings, isError} = useNotificationSettingsQuery() const {data: chatSettings, isError: chatError} = useChatNotificationSettingsQuery() const likeDialogControl = Dialog.useDialogControl() const followDialogControl = Dialog.useDialogControl() const replyDialogControl = Dialog.useDialogControl() const mentionDialogControl = Dialog.useDialogControl() const quoteDialogControl = Dialog.useDialogControl() const repostDialogControl = Dialog.useDialogControl() const activityDialogControl = Dialog.useDialogControl() const likeRepostDialogControl = Dialog.useDialogControl() const repostRepostDialogControl = Dialog.useDialogControl() const chatDialogControl = Dialog.useDialogControl() const chatRequestDialogControl = Dialog.useDialogControl() const miscDialogControl = Dialog.useDialogControl() const {data: permissions, refetch} = useQuery({ queryKey: RQKEY, queryFn: async () => { if (IS_WEB) return null return await Notification.getPermissionsAsync() }, }) const appState = useAppState() useEffect(() => { if (appState === 'active') { void refetch() } }, [appState, refetch]) const onRequestPermissions = async () => { if (IS_WEB) return if (permissions?.canAskAgain) { const response = await Notification.requestPermissionsAsync({ ios: { /* * These default to true only when no argument is passed, so set them * explicitly to preserve behavior alongside * provideAppNotificationSettings. */ allowAlert: true, allowBadge: true, allowSound: true, provideAppNotificationSettings: true, }, }) queryClient.setQueryData(RQKEY, response) } else { if (IS_ANDROID) { try { await Linking.sendIntent( 'android.settings.APP_NOTIFICATION_SETTINGS', [ { key: 'android.provider.extra.APP_PACKAGE', value: 'xyz.blueskyweb.app', }, ], ) } catch { void Linking.openSettings() } } else if (IS_IOS) { void Linking.openSettings() } } } return ( Notifications {permissions && !permissions.granted && ( <> void onRequestPermissions()}> Enable push notifications )} {isError && ( Failed to load notification settings. )} Likes} subtitleText={} showSkeleton={!settings} /> New followers} subtitleText={} showSkeleton={!settings} /> Replies} subtitleText={} showSkeleton={!settings} /> Mentions} subtitleText={} showSkeleton={!settings} /> Quotes} subtitleText={} showSkeleton={!settings} /> Reposts} subtitleText={} showSkeleton={!settings} /> Activity from others} subtitleText={ } showSkeleton={!settings} /> Likes of your reposts} subtitleText={ } showSkeleton={!settings} /> Reposts of your reposts} subtitleText={ } showSkeleton={!settings} /> New messages} subtitleText={ chatError ? ( Failed to load notification settings. ) : ( ) } showSkeleton={!chatSettings && !chatError} /> New message requests} subtitleText={ chatError ? ( Failed to load notification settings. ) : ( ) } showSkeleton={!chatSettings && !chatError} /> Everything else} // technically a bundle of several settings, but since they're set together // and are most likely in sync we'll just show the state of one of them subtitleText={ } showSkeleton={!settings} /> Likes} subtitleText={ Get notifications when people like your posts. } /> New followers} subtitleText={Get notifications when people follow you.} /> Replies} subtitleText={ Get notifications when people reply to your posts. } /> Mentions} subtitleText={Get notifications when people mention you.} /> Quotes} subtitleText={ Get notifications when people quote your posts. } /> Reposts} subtitleText={ Get notifications when people repost your posts. } /> Activity from others} subtitleText={ Get notifications when there's activity on posts you're subscribed to. } allowDisableInApp={false} /> Likes of your reposts} subtitleText={ Get notifications when people like your reposts. } /> Reposts of your reposts} subtitleText={ Get notifications when people repost your reposts. } /> Everything else} subtitleText={ Get notifications for starter pack joins, verification, and other activity. } allowDisableInApp={false} /> ) }