import Button from '@components/Button' import Icon from '@components/Icon' import { MenuContainer, MenuRow } from '@components/Menu' import { displayMessage } from '@components/Message' import CustomText from '@components/Text' import * as Sentry from '@sentry/react-native' import apiInstance from '@utils/api/instance' import apiTooot, { TOOOT_API_DOMAIN } from '@utils/api/tooot' import browserPackage from '@utils/helpers/browserPackage' import { isDevelopment } from '@utils/helpers/checkEnvironment' import { PUSH_ADMIN, PUSH_DEFAULT, setChannels } from '@utils/push/constants' import { updateExpoToken } from '@utils/push/updateExpoToken' import { useAppsQuery } from '@utils/queryHooks/apps' import { useProfileQuery } from '@utils/queryHooks/profile' import { setAccountStorage, useAccountStorage, useGlobalStorage } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' import { useTheme } from '@utils/styles/ThemeManager' import * as Notifications from 'expo-notifications' import * as Random from 'expo-random' import * as WebBrowser from 'expo-web-browser' import React, { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { AppState, Linking, Platform, ScrollView, View } from 'react-native' import { fromByteArray } from 'react-native-quick-base64' const TabMePush: React.FC = () => { const { colors } = useTheme() const { t } = useTranslation('screenTabs') const [expoToken] = useGlobalStorage.string('app.expo_token') const [push] = useAccountStorage.object('push') const [domain] = useAccountStorage.string('auth.domain') const [accountAcct] = useAccountStorage.string('auth.account.acct') const [accountDomain] = useAccountStorage.string('auth.account.domain') const [accountId] = useAccountStorage.string('auth.account.id') const appsQuery = useAppsQuery({ options: { enabled: false, onSuccess: async data => { if (data.vapid_key) { await checkPush() if (isDevelopment) { setPushAvailable(true) } else { setPushAvailable(!!expoToken?.length) } } } } }) useEffect(() => { appsQuery.refetch() }, []) const checkPush = async () => { const permissions = await Notifications.getPermissionsAsync() setPushEnabled(permissions.granted) setPushCanAskAgain(permissions.canAskAgain) layoutAnimation() await updateExpoToken() } const [pushAvailable, setPushAvailable] = useState() const [pushEnabled, setPushEnabled] = useState() const [pushCanAskAgain, setPushCanAskAgain] = useState() useEffect(() => { const subscription = AppState.addEventListener('change', checkPush) return () => { subscription.remove() } }, []) const alerts = () => push?.alerts ? PUSH_DEFAULT().map(alert => ( { const alerts = { ...push?.alerts, [alert]: !push?.alerts[alert] } if (pushEnabled && push.global) { const body: { data: { alerts: Mastodon.PushSubscription['alerts'] } } = { data: { alerts } } await apiInstance({ method: 'put', url: 'push/subscription', body }) } setAccountStorage([{ key: 'push', value: { ...push, alerts } }]) }} /> )) : null const profileQuery = useProfileQuery() const adminAlerts = () => profileQuery.data?.role?.permissions ? PUSH_ADMIN().map(({ type }) => ( { const alerts = { ...push?.alerts, [type]: !push?.alerts[type] } if (pushEnabled && push.global) { const body: { data: { alerts: Mastodon.PushSubscription['alerts'] } } = { data: { alerts } } await apiInstance({ method: 'put', url: 'push/subscription', body }) } setAccountStorage([{ key: 'push', value: { ...push, alerts } }]) }} /> )) : null const pushPath = `${expoToken}/${domain}/${accountId}` const accountFull = `@${accountAcct}@${accountDomain}` return ( {!!appsQuery.data?.vapid_key ? ( <> {!!pushAvailable ? ( <> {pushEnabled === false ? (