diff --git a/src/App.tsx b/src/App.tsx index fda43418..bfaad105 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -41,10 +41,10 @@ const App: React.FC = () => { Notifications.dismissAllNotificationsAsync() }, []) useEffect(() => { - AppState.addEventListener('change', appStateEffect) + const appStateListener = AppState.addEventListener('change', appStateEffect) return () => { - AppState.removeEventListener('change', appStateEffect) + appStateListener.remove() } }, []) diff --git a/src/api/tooot.ts b/src/api/tooot.ts index 845b70cb..713d2a6c 100644 --- a/src/api/tooot.ts +++ b/src/api/tooot.ts @@ -1,3 +1,4 @@ +import { mapEnvironment } from '@utils/checkEnvironment' import axios from 'axios' import chalk from 'chalk' import Constants from 'expo-constants' @@ -16,7 +17,11 @@ export type Params = { sentry?: boolean } -export const TOOOT_API_DOMAIN = __DEV__ ? 'testapi.tooot.app' : 'api.tooot.app' +export const TOOOT_API_DOMAIN = mapEnvironment({ + release: 'api.tooot.app', + candidate: 'api-candidate.tooot.app', + development: 'api-development.tooot.app' +}) const apiTooot = async ({ method, diff --git a/src/screens/Tabs/Me/Push.tsx b/src/screens/Tabs/Me/Push.tsx index 810c3366..dcfcbb29 100644 --- a/src/screens/Tabs/Me/Push.tsx +++ b/src/screens/Tabs/Me/Push.tsx @@ -2,6 +2,7 @@ import analytics from '@components/analytics' import Button from '@components/Button' import Icon from '@components/Icon' import { MenuContainer, MenuRow } from '@components/Menu' +import { isDevelopment } from '@utils/checkEnvironment' import { updateInstancePush } from '@utils/slices/instances/updatePush' import { updateInstancePushAlert } from '@utils/slices/instances/updatePushAlert' import { updateInstancePushDecode } from '@utils/slices/instances/updatePushDecode' @@ -45,11 +46,16 @@ const TabMePush: React.FC = () => { setPushCanAskAgain(settings.canAskAgain) } useEffect(() => { - Notifications.getExpoPushTokenAsync({ - experienceId: '@xmflsct/tooot' - }) - .then(data => setPushAvailable(!!data)) - .catch(() => setPushAvailable(false)) + if (isDevelopment) { + setPushAvailable(true) + } else { + Notifications.getExpoPushTokenAsync({ + experienceId: '@xmflsct/tooot' + }) + .then(data => setPushAvailable(!!data)) + .catch(() => setPushAvailable(false)) + } + checkPush() const subscription = AppState.addEventListener('change', checkPush) return () => { @@ -106,7 +112,7 @@ const TabMePush: React.FC = () => { return ( - {pushAvailable !== false ? ( + {pushAvailable === true ? ( <> {pushEnabled === false ? ( diff --git a/src/screens/Tabs/Me/Settings.tsx b/src/screens/Tabs/Me/Settings.tsx index 87e01c1d..b2d28954 100644 --- a/src/screens/Tabs/Me/Settings.tsx +++ b/src/screens/Tabs/Me/Settings.tsx @@ -1,4 +1,4 @@ -import * as Updates from 'expo-updates' +import { isDevelopment } from '@utils/checkEnvironment' import React from 'react' import { ScrollView } from 'react-native-gesture-handler' import SettingsAnalytics from './Settings/Analytics' @@ -13,12 +13,7 @@ const TabMeSettings: React.FC = () => { - {__DEV__ || - ['development'].some(channel => - Updates.releaseChannel.includes(channel) - ) ? ( - - ) : null} + {isDevelopment ? : null} ) } diff --git a/src/screens/Tabs/Me/Settings/Tooot.tsx b/src/screens/Tabs/Me/Settings/Tooot.tsx index c488039e..08456970 100644 --- a/src/screens/Tabs/Me/Settings/Tooot.tsx +++ b/src/screens/Tabs/Me/Settings/Tooot.tsx @@ -4,7 +4,6 @@ import { MenuContainer, MenuRow } from '@components/Menu' import { useNavigation } from '@react-navigation/native' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' -import * as Updates from 'expo-updates' import * as Linking from 'expo-linking' import * as StoreReview from 'expo-store-review' import * as WebBrowser from 'expo-web-browser' @@ -12,6 +11,7 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { getInstanceActive } from '@utils/slices/instancesSlice' +import { isCandidate, isDevelopment } from '@utils/checkEnvironment' const SettingsTooot: React.FC = () => { const instanceActive = useSelector(getInstanceActive) @@ -36,10 +36,7 @@ const SettingsTooot: React.FC = () => { Linking.openURL('https://www.buymeacoffee.com/xmflsct') }} /> - {__DEV__ || - ['release', 'development'].some(channel => - Updates.releaseChannel?.includes(channel) - ) ? ( + {isDevelopment || isCandidate ? ( { Sentry.init({ dsn: Constants.manifest?.extra?.sentryDSN, enableInExpoDevelopment: false, - debug: - __DEV__ || - ['development'].some(channel => Updates.releaseChannel.includes(channel)) + debug: isDevelopment }) } diff --git a/src/utils/checkEnvironment.ts b/src/utils/checkEnvironment.ts new file mode 100644 index 00000000..a4824d3f --- /dev/null +++ b/src/utils/checkEnvironment.ts @@ -0,0 +1,49 @@ +import * as Updates from 'expo-updates' + +const mapEnvironment = ({ + release, + candidate, + development +}: { + release: T + candidate?: T + development?: T +}): T => { + if (isDevelopment) { + if (development) { + return development + } else { + throw new Error('Development environment but no development handler') + } + } + + if (isCandidate) { + if (candidate) { + return candidate + } else { + throw new Error('Candidate environment but no candidate handler') + } + } + + if (isRelease) { + return release + } + + throw new Error( + `Environment not set. Please set the environment in the Expo project settings.` + ) +} + +const isDevelopment = + __DEV__ || + ['development'].some(channel => Updates.releaseChannel.includes(channel)) + +const isCandidate = ['candidate'].some(channel => + Updates.releaseChannel.includes(channel) +) + +const isRelease = ['release'].some(channel => + Updates.releaseChannel.includes(channel) +) + +export { mapEnvironment, isDevelopment, isCandidate, isRelease } diff --git a/src/utils/push/useConnect.ts b/src/utils/push/useConnect.ts index 08c30f00..801e6885 100644 --- a/src/utils/push/useConnect.ts +++ b/src/utils/push/useConnect.ts @@ -3,6 +3,7 @@ import apiTooot from '@api/tooot' import { displayMessage } from '@components/Message' import navigationRef from '@helpers/navigationRef' import { Dispatch } from '@reduxjs/toolkit' +import { isDevelopment } from '@utils/checkEnvironment' import { disableAllPushes, Instance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' @@ -18,11 +19,13 @@ export interface Params { const pushUseConnect = ({ mode, t, instances, dispatch }: Params) => { return useEffect(() => { const connect = async () => { - const expoToken = ( - await Notifications.getExpoPushTokenAsync({ - experienceId: '@xmflsct/tooot' - }) - ).data + const expoToken = isDevelopment + ? 'DEVELOPMENT_TOKEN_1' + : ( + await Notifications.getExpoPushTokenAsync({ + experienceId: '@xmflsct/tooot' + }) + ).data apiTooot({ method: 'get', diff --git a/src/utils/slices/instances/updatePush.ts b/src/utils/slices/instances/updatePush.ts index 8a5354d8..75b4e54e 100644 --- a/src/utils/slices/instances/updatePush.ts +++ b/src/utils/slices/instances/updatePush.ts @@ -1,5 +1,6 @@ import { createAsyncThunk } from '@reduxjs/toolkit' import { RootState } from '@root/store' +import { isDevelopment } from '@utils/checkEnvironment' import * as Notifications from 'expo-notifications' import { Instance } from '../instancesSlice' import pushRegister from './push/register' @@ -12,11 +13,13 @@ export const updateInstancePush = createAsyncThunk( { getState } ): Promise => { const state = getState() as RootState - const expoToken = ( - await Notifications.getExpoPushTokenAsync({ - experienceId: '@xmflsct/tooot' - }) - ).data + const expoToken = isDevelopment + ? 'DEVELOPMENT_TOKEN_1' + : ( + await Notifications.getExpoPushTokenAsync({ + experienceId: '@xmflsct/tooot' + }) + ).data if (disable) { return await pushRegister(state, expoToken) diff --git a/src/utils/slices/instances/updatePushDecode.ts b/src/utils/slices/instances/updatePushDecode.ts index 5ef848ed..928a4157 100644 --- a/src/utils/slices/instances/updatePushDecode.ts +++ b/src/utils/slices/instances/updatePushDecode.ts @@ -2,6 +2,7 @@ import apiTooot from '@api/tooot' import { createAsyncThunk } from '@reduxjs/toolkit' import i18n from '@root/i18n/i18n' import { RootState } from '@root/store' +import { isDevelopment } from '@utils/checkEnvironment' import * as Notifications from 'expo-notifications' import { Platform } from 'react-native' import { getInstance, Instance } from '../instancesSlice' @@ -19,11 +20,13 @@ export const updateInstancePushDecode = createAsyncThunk( return Promise.reject() } - const expoToken = ( - await Notifications.getExpoPushTokenAsync({ - experienceId: '@xmflsct/tooot' - }) - ).data + const expoToken = isDevelopment + ? 'DEVELOPMENT_TOKEN_1' + : ( + await Notifications.getExpoPushTokenAsync({ + experienceId: '@xmflsct/tooot' + }) + ).data await apiTooot({ method: 'put',