diff --git a/App.tsx b/App.tsx index 3dc1ac96..8d2f48b4 100644 --- a/App.tsx +++ b/App.tsx @@ -1,6 +1,6 @@ import NetInfo from '@react-native-community/netinfo' import client from '@root/api/client' -import { Index } from '@root/Index' +import Index from '@root/Index' import { persistor, store } from '@root/store' import { resetLocal } from '@root/utils/slices/instancesSlice' import ThemeManager from '@utils/styles/ThemeManager' diff --git a/app.config.ts b/app.config.ts index 7d440467..537d28cb 100644 --- a/app.config.ts +++ b/app.config.ts @@ -13,7 +13,7 @@ export default (): ExpoConfig => ({ developmentClient: { silentLaunch: true }, scheme: 'mastodonct', ios: { - bundleIdentifier: 'com.xmflsct.mastodon', + bundleIdentifier: 'com.xmflsct.app.mastodon', infoPlist: { CFBundleAllowMixedLocalizations: true }, @@ -21,7 +21,8 @@ export default (): ExpoConfig => ({ image: './assets/splash.png', resizeMode: 'contain', backgroundColor: '#ffffff' - } + }, + googleServicesFile: './configs/GoogleService-Info.plist' }, // locales: { // zh: { @@ -31,5 +32,18 @@ export default (): ExpoConfig => ({ // CFBundleDisplayName: 'My Toots' // } // }, - assetBundlePatterns: ['assets/*'] + assetBundlePatterns: ['assets/*'], + web: { + config: { + firebase: { + apiKey: 'AIzaSyAnvo0jyD1WB0tv2FLenz-CSDS-RgaWWR4', + authDomain: 'xmflsct-mastodon-app.firebaseapp.com', + projectId: 'xmflsct-mastodon-app', + storageBucket: 'xmflsct-mastodon-app.appspot.com', + messagingSenderId: '661638997772', + appId: '1:661638997772:web:1e7aab28be7dc06d9f8b29', + measurementId: 'G-3J0FS8WV5J' + } + } + } }) diff --git a/configs/GoogleService-Info.plist b/configs/GoogleService-Info.plist new file mode 100644 index 00000000..1ad6bbe3 --- /dev/null +++ b/configs/GoogleService-Info.plist @@ -0,0 +1,34 @@ + + + + + CLIENT_ID + 661638997772-sqa4raeghhrieqt9guljhcul9b51dvna.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.661638997772-sqa4raeghhrieqt9guljhcul9b51dvna + API_KEY + AIzaSyAOS1Yq_uNVctG89LB6Dl1PVhb_FAQRbRg + GCM_SENDER_ID + 661638997772 + PLIST_VERSION + 1 + BUNDLE_ID + com.xmflsct.app.mastodon + PROJECT_ID + xmflsct-mastodon-app + STORAGE_BUCKET + xmflsct-mastodon-app.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:661638997772:ios:30b6bc26a1c84b5a9f8b29 + + \ No newline at end of file diff --git a/package.json b/package.json index c63b81a8..e39820d5 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ "expo-av": "~8.7.0", "expo-blur": "~8.2.2", "expo-crypto": "~8.4.0", + "expo-firebase-analytics": "~2.6.0", + "expo-firebase-core": "~1.3.0", "expo-gl": "~9.2.0", "expo-image-picker": "~9.2.0", "expo-linear-gradient": "~8.4.0", diff --git a/src/Index.tsx b/src/Index.tsx index ae1cd7e5..c1f4d784 100644 --- a/src/Index.tsx +++ b/src/Index.tsx @@ -5,6 +5,7 @@ import { NavigationContainerRef } from '@react-navigation/native' +import * as Analytics from 'expo-firebase-analytics' import React, { useEffect, useRef, useState } from 'react' import { StatusBar } from 'react-native' import Toast from 'react-native-toast-message' @@ -46,7 +47,7 @@ export interface Props { localCorrupt: boolean } -export const Index: React.FC = ({ localCorrupt }) => { +const Index: React.FC = ({ localCorrupt }) => { const dispatch = useDispatch() const localInstance = useSelector(getLocalUrl) const { i18n } = useTranslation() @@ -98,14 +99,14 @@ export const Index: React.FC = ({ localCorrupt }) => { }) } }) - .catch(() => {}) + .catch(() => null) }, []) // On launch check if there is any unread noficiations const queryNotification = useInfiniteQuery( - ['Notifications', {}] as QueryKey.Timeline, + ['Notifications', {}], timelineFetch, - { enabled: localInstance ? true : false, cacheTime: 1000 * 30 } + { enabled: localInstance ? true : false } ) const prevNotification = useSelector(getLocalNotification) useEffect(() => { @@ -151,6 +152,9 @@ export const Index: React.FC = ({ localCorrupt }) => { ref={navigationRef} theme={themes[mode]} key={i18n.language} + onStateChange={state => { + Analytics.setCurrentScreen(state?.routes[state.index].name) + }} > = ({ localCorrupt }) => { ) } + +export default React.memo(Index, () => true) diff --git a/src/components/Timelines/Timeline.tsx b/src/components/Timelines/Timeline.tsx index 78f444af..48a59c80 100644 --- a/src/components/Timelines/Timeline.tsx +++ b/src/components/Timelines/Timeline.tsx @@ -11,6 +11,8 @@ import TimelineEmpty from '@components/Timelines/Timeline/Empty' import TimelineEnd from '@components/Timelines/Timeline/Shared/End' import { useScrollToTop } from '@react-navigation/native' import { FlatList } from 'react-native-gesture-handler' +import { useDispatch } from 'react-redux' +import { updateNotification } from '@root/utils/slices/instancesSlice' export type TimelineData = | InfiniteData<{ @@ -83,6 +85,19 @@ const Timeline: React.FC = ({ ? data.pages.flatMap(d => [d?.pinnedLength]) : [] + // Clear unread notification badge + const dispatch = useDispatch() + useEffect(() => { + if (page === 'Notifications' && flattenData.length) { + dispatch( + updateNotification({ + unread: false, + latestTime: flattenData[0].created_at + }) + ) + } + }, [flattenData]) + const flRef = useRef>(null) useEffect(() => { if (toot && isSuccess) { diff --git a/src/screens/Notifications.tsx b/src/screens/Notifications.tsx index 7c57b7ba..341b9b56 100644 --- a/src/screens/Notifications.tsx +++ b/src/screens/Notifications.tsx @@ -1,12 +1,11 @@ -import React, { useEffect } from 'react' +import React from 'react' import { createNativeStackNavigator } from 'react-native-screens/native-stack' import Timeline from '@components/Timelines/Timeline' import sharedScreens from '@screens/Shared/sharedScreens' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import { RootState } from '@root/store' import { useTranslation } from 'react-i18next' -import { updateNotification } from '@root/utils/slices/instancesSlice' const Stack = createNativeStackNavigator() @@ -16,12 +15,6 @@ const ScreenNotifications: React.FC = () => { (state: RootState) => state.instances.local.url ) - // Clear notification unread, but keep the time - const dispatch = useDispatch() - useEffect(() => { - dispatch(updateNotification({ unread: false })) - }, []) - return (