From 0efb7e5b70052deab35f786054ab0fae30e002f0 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Sun, 15 Jan 2023 13:40:12 +0100 Subject: [PATCH] Fix #615 --- src/utils/push/updateExpoToken.ts | 11 ++++-- src/utils/push/useConnect.ts | 63 +++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/utils/push/updateExpoToken.ts b/src/utils/push/updateExpoToken.ts index 543e8c6e..fe2cbc67 100644 --- a/src/utils/push/updateExpoToken.ts +++ b/src/utils/push/updateExpoToken.ts @@ -4,7 +4,7 @@ import { getGlobalStorage, setGlobalStorage } from '@utils/storage/actions' import * as Notifications from 'expo-notifications' import { Platform } from 'react-native' -export const updateExpoToken = async () => { +export const updateExpoToken = async (): Promise => { const expoToken = getGlobalStorage.string('app.expo_token') if (Platform.OS === 'android') { @@ -12,16 +12,19 @@ export const updateExpoToken = async () => { } if (expoToken?.length) { - return Promise.resolve() + return Promise.resolve(expoToken) } else { if (isDevelopment) { setGlobalStorage('app.expo_token', 'ExponentPushToken[DEVELOPMENT_1]') - return Promise.resolve() + return Promise.resolve('ExponentPushToken[DEVELOPMENT_1]') } return await Notifications.getExpoPushTokenAsync({ experienceId: '@xmflsct/tooot', applicationId: 'com.xmflsct.app.tooot' - }).then(({ data }) => setGlobalStorage('app.expo_token', data)) + }).then(({ data }) => { + setGlobalStorage('app.expo_token', data) + return data + }) } } diff --git a/src/utils/push/useConnect.ts b/src/utils/push/useConnect.ts index d583c165..e77aa0d4 100644 --- a/src/utils/push/useConnect.ts +++ b/src/utils/push/useConnect.ts @@ -5,6 +5,7 @@ import apiGeneral from '@utils/api/general' import apiTooot from '@utils/api/tooot' import navigationRef from '@utils/navigation/navigationRef' import { + generateAccountKey, getAccountDetails, getGlobalStorage, setAccountStorage, @@ -12,7 +13,7 @@ import { } from '@utils/storage/actions' import { AxiosError } from 'axios' import * as Notifications from 'expo-notifications' -import { useEffect } from 'react' +import { useEffect, useRef } from 'react' import { useTranslation } from 'react-i18next' import { AppState } from 'react-native' import { updateExpoToken } from './updateExpoToken' @@ -20,22 +21,32 @@ import { updateExpoToken } from './updateExpoToken' const pushUseConnect = () => { const { t } = useTranslation('screens') - useEffect(() => { - updateExpoToken() - }, []) + const startupChecked = useRef(false) const [expoToken] = useGlobalStorage.string('app.expo_token') - const pushEnabledCount = getGlobalStorage.object('accounts')?.filter(account => { - return getAccountDetails(['push'], account)?.push?.global - }).length + const accounts = getGlobalStorage.object('accounts') + const pushEnabled = accounts + ?.map(account => { + const details = getAccountDetails(['push', 'auth.domain', 'auth.account.id'], account) + if (details?.push?.global) { + return { + accountKey: generateAccountKey({ + domain: details['auth.domain'], + id: details['auth.account.id'] + }), + push: details.push + } + } + }) + .filter(d => !!d) - const connectQuery = useQuery( + const connectQuery = useQuery<{ accounts: string[] } | undefined, AxiosError>( ['tooot', { endpoint: 'push/connect' }], () => - apiTooot({ + apiTooot<{ accounts: string[] } | undefined>({ method: 'get', url: `push/connect/${expoToken}` - }), + }).then(res => res.body), { enabled: false, retry: (failureCount, error) => { @@ -48,6 +59,17 @@ const pushUseConnect = () => { refetchOnWindowFocus: false, refetchOnReconnect: false, onSettled: () => Notifications.setBadgeCountAsync(0), + onSuccess: data => { + if (!startupChecked.current && data?.accounts) { + startupChecked.current = true + for (const acct of data.accounts) { + const matchedAcct = pushEnabled?.find(p => p?.accountKey === acct) + if (matchedAcct && !matchedAcct.push.global) { + setAccountStorage([{ key: 'push', value: { ...matchedAcct.push, global: true } }]) + } + } + } + }, onError: error => { if (error?.status == 404) { displayMessage({ @@ -96,18 +118,21 @@ const pushUseConnect = () => { ) useEffect(() => { - Sentry.setTags({ expoToken, pushEnabledCount }) + updateExpoToken().then(async token => { + const badgeCount = await Notifications.getBadgeCountAsync() + if (token && (pushEnabled?.length || badgeCount)) { + connectQuery.refetch() + } + }) + }, []) - if (expoToken && pushEnabledCount) { - connectQuery.refetch() - } + useEffect(() => { + Sentry.setTags({ expoToken, pushEnabledCount: pushEnabled?.length }) const appStateListener = AppState.addEventListener('change', state => { - if (expoToken && pushEnabledCount && state === 'active') { + if (expoToken && pushEnabled?.length && state === 'active') { Notifications.getBadgeCountAsync().then(count => { - if (count > 0) { - connectQuery.refetch() - } + if (count > 0) connectQuery.refetch() }) } }) @@ -115,7 +140,7 @@ const pushUseConnect = () => { return () => { appStateListener.remove() } - }, [expoToken, pushEnabledCount]) + }, [expoToken, pushEnabled?.length]) } export default pushUseConnect