diff --git a/src/Screens.tsx b/src/Screens.tsx index 98bd115b..4bd2f3a0 100644 --- a/src/Screens.tsx +++ b/src/Screens.tsx @@ -27,8 +27,9 @@ import { addScreenshotListener } from 'expo-screen-capture' import React, { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Alert, Platform, StatusBar } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import * as Sentry from 'sentry-expo' +import { useAppDispatch } from './store' const Stack = createNativeStackNavigator() @@ -38,7 +39,7 @@ export interface Props { const Screens: React.FC = ({ localCorrupt }) => { const { t } = useTranslation('screens') - const dispatch = useDispatch() + const dispatch = useAppDispatch() const instanceActive = useSelector(getInstanceActive) const { colors, theme } = useTheme() diff --git a/src/components/Emojis/List.tsx b/src/components/Emojis/List.tsx index 1f60f338..df213f1c 100644 --- a/src/components/Emojis/List.tsx +++ b/src/components/Emojis/List.tsx @@ -1,3 +1,4 @@ +import { useAppDispatch } from '@root/store' import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { countInstanceEmoji } from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' @@ -15,13 +16,12 @@ import { View } from 'react-native' import FastImage from 'react-native-fast-image' -import { useDispatch } from 'react-redux' import validUrl from 'valid-url' import EmojisContext from './helpers/EmojisContext' const EmojisList = React.memo( () => { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { reduceMotionEnabled } = useAccessibility() const { t } = useTranslation() diff --git a/src/components/Instance/Auth.tsx b/src/components/Instance/Auth.tsx index 305174dc..2418bb49 100644 --- a/src/components/Instance/Auth.tsx +++ b/src/components/Instance/Auth.tsx @@ -1,11 +1,12 @@ import { useNavigation } from '@react-navigation/native' +import { useAppDispatch } from '@root/store' import { TabMeStackNavigationProp } from '@utils/navigation/navigators' import addInstance from '@utils/slices/instances/add' import { checkInstanceFeature, Instance } from '@utils/slices/instancesSlice' import * as AuthSession from 'expo-auth-session' import React, { useEffect } from 'react' import { useQueryClient } from 'react-query' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' export interface Props { instanceDomain: string @@ -25,7 +26,7 @@ const InstanceAuth = React.memo( const navigation = useNavigation>() const queryClient = useQueryClient() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const deprecateAuthFollow = useSelector( checkInstanceFeature('deprecate_auth_follow') diff --git a/src/components/Timeline.tsx b/src/components/Timeline.tsx index d2a8040f..9d41b3fd 100644 --- a/src/components/Timeline.tsx +++ b/src/components/Timeline.tsx @@ -1,5 +1,6 @@ import ComponentSeparator from '@components/Separator' import { useScrollToTop } from '@react-navigation/native' +import { useAppDispatch } from '@root/store' import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline' import { getInstanceActive, @@ -20,7 +21,7 @@ import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import TimelineEmpty from './Timeline/Empty' import TimelineFooter from './Timeline/Footer' import TimelineRefresh, { @@ -127,7 +128,7 @@ const Timeline: React.FC = ({ } }) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const viewabilityPairs = useRef([ { viewabilityConfig: { diff --git a/src/screens/Actions/NotificationsFilter.tsx b/src/screens/Actions/NotificationsFilter.tsx index de21fcb3..5bf31102 100644 --- a/src/screens/Actions/NotificationsFilter.tsx +++ b/src/screens/Actions/NotificationsFilter.tsx @@ -11,9 +11,10 @@ import { StyleConstants } from '@utils/styles/constants' import React, { useMemo } from 'react' import { StyleSheet } from 'react-native' import { useTranslation } from 'react-i18next' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import { useQueryClient } from 'react-query' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' +import { useAppDispatch } from '@root/store' const ActionsNotificationsFilter: React.FC = () => { const navigation = useNavigation() @@ -22,7 +23,7 @@ const ActionsNotificationsFilter: React.FC = () => { const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Notifications' }] const queryClient = useQueryClient() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const instanceNotificationsFilter = useSelector( getInstanceNotificationsFilter ) @@ -35,21 +36,23 @@ const ActionsNotificationsFilter: React.FC = () => { const options = useMemo(() => { return ( instanceNotificationsFilter && - ([ - 'follow', - 'favourite', - 'reblog', - 'mention', - 'poll', - 'follow_request' - ] as [ - 'follow', - 'favourite', - 'reblog', - 'mention', - 'poll', - 'follow_request' - ]).map(type => ( + ( + [ + 'follow', + 'favourite', + 'reblog', + 'mention', + 'poll', + 'follow_request' + ] as [ + 'follow', + 'favourite', + 'reblog', + 'mention', + 'poll', + 'follow_request' + ] + ).map(type => ( > = ({ ), [composeState] ) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const headerRightDisabled = useMemo(() => { if (totalTextCount > maxTootChars) { return true diff --git a/src/screens/Compose/DraftsList/Root.tsx b/src/screens/Compose/DraftsList/Root.tsx index 2321b4e4..37606dd5 100644 --- a/src/screens/Compose/DraftsList/Root.tsx +++ b/src/screens/Compose/DraftsList/Root.tsx @@ -3,6 +3,7 @@ import Icon from '@components/Icon' import ComponentSeparator from '@components/Separator' import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' import { useNavigation } from '@react-navigation/native' +import { useAppDispatch } from '@root/store' import { getInstanceDrafts, removeInstanceDraft @@ -23,7 +24,7 @@ import { } from 'react-native' import { PanGestureHandler } from 'react-native-gesture-handler' import { SwipeListView } from 'react-native-swipe-list-view' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import formatText from '../formatText' import ComposeContext from '../utils/createContext' import { ComposeStateDraft, ExtendedAttachment } from '../utils/types' @@ -36,7 +37,7 @@ const ComposeDraftsListRoot: React.FC = ({ timestamp }) => { const { composeDispatch } = useContext(ComposeContext) const { t } = useTranslation('screenCompose') const navigation = useNavigation() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { colors, theme } = useTheme() const instanceDrafts = useSelector(getInstanceDrafts)?.filter( draft => draft.timestamp !== timestamp diff --git a/src/screens/Compose/Root/Footer/Emojis.tsx b/src/screens/Compose/Root/Footer/Emojis.tsx index 71841734..1dd2e507 100644 --- a/src/screens/Compose/Root/Footer/Emojis.tsx +++ b/src/screens/Compose/Root/Footer/Emojis.tsx @@ -1,4 +1,5 @@ import haptics from '@components/haptics' +import { useAppDispatch } from '@root/store' import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { countInstanceEmoji } from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' @@ -15,7 +16,6 @@ import { View } from 'react-native' import FastImage from 'react-native-fast-image' -import { useDispatch } from 'react-redux' import validUrl from 'valid-url' import updateText from '../../updateText' import ComposeContext from '../../utils/createContext' @@ -29,7 +29,7 @@ const ComposeEmojis: React.FC = ({ accessibleRefEmojis }) => { const { reduceMotionEnabled } = useAccessibility() const { colors } = useTheme() const { t } = useTranslation() - const dispatch = useDispatch() + const dispatch = useAppDispatch() useEffect(() => { const tagEmojis = findNodeHandle(accessibleRefEmojis.current) diff --git a/src/screens/Tabs.tsx b/src/screens/Tabs.tsx index b4cf8053..48f1cf6a 100644 --- a/src/screens/Tabs.tsx +++ b/src/screens/Tabs.tsx @@ -5,6 +5,7 @@ import { BottomTabNavigationOptions, createBottomTabNavigator } from '@react-navigation/bottom-tabs' +import { useAppDispatch } from '@root/store' import { RootStackScreenProps, ScreenTabsStackParamList @@ -21,7 +22,7 @@ import { import { useTheme } from '@utils/styles/ThemeManager' import React, { useCallback, useEffect, useMemo } from 'react' import { Platform } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import TabLocal from './Tabs/Local' import TabMe from './Tabs/Me' import TabNotifications from './Tabs/Notifications' @@ -118,7 +119,7 @@ const ScreenTabs = React.memo( const previousTab = useSelector(getPreviousTab, () => true) const versionUpdate = useSelector(getVersionUpdate) - const dispatch = useDispatch() + const dispatch = useAppDispatch() useEffect(() => { dispatch(retriveVersionLatest()) }, []) diff --git a/src/screens/Tabs/Me/Profile/Root.tsx b/src/screens/Tabs/Me/Profile/Root.tsx index 7d39fdeb..ae0abbe1 100644 --- a/src/screens/Tabs/Me/Profile/Root.tsx +++ b/src/screens/Tabs/Me/Profile/Root.tsx @@ -1,6 +1,7 @@ import analytics from '@components/analytics' import { MenuContainer, MenuRow } from '@components/Menu' import { useActionSheet } from '@expo/react-native-action-sheet' +import { useAppDispatch } from '@root/store' import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators' import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile' import { updateAccountPreferences } from '@utils/slices/instances/updateAccountPreferences' @@ -9,7 +10,6 @@ import React, { RefObject, useCallback } from 'react' import { useTranslation } from 'react-i18next' import FlashMessage from 'react-native-flash-message' import { ScrollView } from 'react-native-gesture-handler' -import { useDispatch } from 'react-redux' import ProfileAvatarHeader from './Root/AvatarHeader' const TabMeProfileRoot: React.FC< @@ -24,7 +24,7 @@ const TabMeProfileRoot: React.FC< const { data, isLoading } = useProfileQuery({}) const { mutateAsync } = useProfileMutation() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const onPressVisibility = useCallback(() => { showActionSheetWithOptions( diff --git a/src/screens/Tabs/Me/Push.tsx b/src/screens/Tabs/Me/Push.tsx index 5ca7e819..b220a7b8 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 { useAppDispatch } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' import { updateInstancePush } from '@utils/slices/instances/updatePush' import { updateInstancePushAlert } from '@utils/slices/instances/updatePushAlert' @@ -20,7 +21,7 @@ import * as WebBrowser from 'expo-web-browser' import React, { useState, useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { AppState, Linking, ScrollView, Text, View } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' const TabMePush: React.FC = () => { const { colors } = useTheme() @@ -31,7 +32,7 @@ const TabMePush: React.FC = () => { ) const instanceUri = useSelector(getInstanceUri) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const instancePush = useSelector(getInstancePush) const [pushAvailable, setPushAvailable] = useState( diff --git a/src/screens/Tabs/Me/Root/Collections.tsx b/src/screens/Tabs/Me/Root/Collections.tsx index 3f0aecc6..504d5305 100644 --- a/src/screens/Tabs/Me/Root/Collections.tsx +++ b/src/screens/Tabs/Me/Root/Collections.tsx @@ -1,5 +1,6 @@ import { MenuContainer, MenuRow } from '@components/Menu' import { useNavigation } from '@react-navigation/native' +import { useAppDispatch } from '@root/store' import { useAnnouncementQuery } from '@utils/queryHooks/announcement' import { useListsQuery } from '@utils/queryHooks/lists' import { @@ -9,13 +10,13 @@ import { import { getInstancePush } from '@utils/slices/instancesSlice' import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' const Collections: React.FC = () => { const { t } = useTranslation('screenTabs') const navigation = useNavigation() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const mePage = useSelector(getInstanceMePage) const listsQuery = useListsQuery({ diff --git a/src/screens/Tabs/Me/Root/Logout.tsx b/src/screens/Tabs/Me/Root/Logout.tsx index f7b2db67..5a07c7f0 100644 --- a/src/screens/Tabs/Me/Root/Logout.tsx +++ b/src/screens/Tabs/Me/Root/Logout.tsx @@ -1,5 +1,6 @@ import Button from '@components/Button' import haptics from '@root/components/haptics' +import { useAppDispatch } from '@root/store' import removeInstance from '@utils/slices/instances/remove' import { getInstance } from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' @@ -7,11 +8,11 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { Alert } from 'react-native' import { useQueryClient } from 'react-query' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' const Logout: React.FC = () => { const { t } = useTranslation('screenTabs') - const dispatch = useDispatch() + const dispatch = useAppDispatch() const queryClient = useQueryClient() const instance = useSelector(getInstance) diff --git a/src/screens/Tabs/Me/Settings/Analytics.tsx b/src/screens/Tabs/Me/Settings/Analytics.tsx index 68e547e0..aa5f7d44 100644 --- a/src/screens/Tabs/Me/Settings/Analytics.tsx +++ b/src/screens/Tabs/Me/Settings/Analytics.tsx @@ -1,4 +1,5 @@ import { MenuContainer, MenuRow } from '@components/Menu' +import { useAppDispatch } from '@root/store' import { changeAnalytics, getSettingsAnalytics @@ -9,10 +10,10 @@ import Constants from 'expo-constants' import React from 'react' import { useTranslation } from 'react-i18next' import { StyleSheet, Text } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' const SettingsAnalytics: React.FC = () => { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { colors } = useTheme() const { t } = useTranslation('screenTabs') diff --git a/src/screens/Tabs/Me/Settings/App.tsx b/src/screens/Tabs/Me/Settings/App.tsx index 14366261..f204232b 100644 --- a/src/screens/Tabs/Me/Settings/App.tsx +++ b/src/screens/Tabs/Me/Settings/App.tsx @@ -4,6 +4,7 @@ import { MenuContainer, MenuRow } from '@components/Menu' import { useActionSheet } from '@expo/react-native-action-sheet' import { useNavigation } from '@react-navigation/native' import { LOCALES } from '@root/i18n/locales' +import { useAppDispatch } from '@root/store' import androidDefaults from '@utils/slices/instances/push/androidDefaults' import { getInstances } from '@utils/slices/instancesSlice' import { @@ -21,12 +22,12 @@ import * as Notifications from 'expo-notifications' import React from 'react' import { useTranslation } from 'react-i18next' import { Platform } from 'react-native' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' import { mapFontsizeToName } from '../SettingsFontsize' const SettingsApp: React.FC = () => { const navigation = useNavigation() - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { showActionSheetWithOptions } = useActionSheet() const { mode } = useTheme() const { t, i18n } = useTranslation('screenTabs') diff --git a/src/screens/Tabs/Me/SettingsFontsize.tsx b/src/screens/Tabs/Me/SettingsFontsize.tsx index 02935db6..5aa4ad17 100644 --- a/src/screens/Tabs/Me/SettingsFontsize.tsx +++ b/src/screens/Tabs/Me/SettingsFontsize.tsx @@ -2,6 +2,7 @@ import Button from '@components/Button' import haptics from '@components/haptics' import ComponentSeparator from '@components/Separator' import TimelineDefault from '@components/Timeline/Default' +import { useAppDispatch } from '@root/store' import { TabMeStackScreenProps } from '@utils/navigation/navigators' import { changeFontsize, @@ -15,7 +16,7 @@ import React, { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { StyleSheet, Text, View } from 'react-native' import { ScrollView } from 'react-native-gesture-handler' -import { useDispatch, useSelector } from 'react-redux' +import { useSelector } from 'react-redux' export const mapFontsizeToName = (size: SettingsState['fontsize']) => { switch (size) { @@ -38,7 +39,7 @@ const TabMeSettingsFontsize: React.FC< const { colors, theme } = useTheme() const { t } = useTranslation('screenTabs') const initialSize = useSelector(getSettingsFontsize) - const dispatch = useDispatch() + const dispatch = useAppDispatch() const item = { id: 'demo', diff --git a/src/store.ts b/src/store.ts index 5e4e8afc..c66366d6 100644 --- a/src/store.ts +++ b/src/store.ts @@ -8,6 +8,7 @@ import contextsSlice, { ContextsState } from '@utils/slices/contextsSlice' import instancesSlice, { InstancesState } from '@utils/slices/instancesSlice' import settingsSlice, { SettingsState } from '@utils/slices/settingsSlice' import versionSlice from '@utils/slices/versionSlice' +import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' import { createMigrate, persistReducer, persistStore } from 'redux-persist' const secureStorage = createSecureStore() @@ -69,3 +70,7 @@ let persistor = persistStore(store) export { store, persistor } export type RootState = ReturnType + +type AppDispatch = typeof store.dispatch +export const useAppDispatch = () => useDispatch() +export const useAppSelector: TypedUseSelectorHook = useSelector diff --git a/src/utils/push/useConnect.ts b/src/utils/push/useConnect.ts index 88f44000..b9a6692f 100644 --- a/src/utils/push/useConnect.ts +++ b/src/utils/push/useConnect.ts @@ -2,13 +2,13 @@ import apiGeneral from '@api/general' import apiTooot from '@api/tooot' import { displayMessage } from '@components/Message' import navigationRef from '@helpers/navigationRef' +import { useAppDispatch } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' import { disableAllPushes, Instance } from '@utils/slices/instancesSlice' import { useTheme } from '@utils/styles/ThemeManager' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' import { TFunction } from 'react-i18next' -import { useDispatch } from 'react-redux' export interface Params { t: TFunction<'screens'> @@ -16,7 +16,7 @@ export interface Params { } const pushUseConnect = ({ t, instances }: Params) => { - const dispatch = useDispatch() + const dispatch = useAppDispatch() const { theme } = useTheme() return useEffect(() => { diff --git a/src/utils/push/useReceive.ts b/src/utils/push/useReceive.ts index 82577526..b5997966 100644 --- a/src/utils/push/useReceive.ts +++ b/src/utils/push/useReceive.ts @@ -2,10 +2,9 @@ import { displayMessage } from '@components/Message' import queryClient from '@helpers/queryClient' import initQuery from '@utils/initQuery' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import { Instance, updateInstanceActive } from '@utils/slices/instancesSlice' +import { Instance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' -import { useDispatch } from 'react-redux' import pushUseNavigate from './useNavigate' export interface Params { @@ -13,8 +12,6 @@ export interface Params { } const pushUseReceive = ({ instances }: Params) => { - const dispatch = useDispatch() - return useEffect(() => { const subscription = Notifications.addNotificationReceivedListener( notification => { diff --git a/src/utils/push/useRespond.ts b/src/utils/push/useRespond.ts index d891197b..8121029a 100644 --- a/src/utils/push/useRespond.ts +++ b/src/utils/push/useRespond.ts @@ -4,7 +4,6 @@ import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { Instance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' -import { useDispatch } from 'react-redux' import pushUseNavigate from './useNavigate' export interface Params { @@ -12,8 +11,6 @@ export interface Params { } const pushUseRespond = ({ instances }: Params) => { - const dispatch = useDispatch() - return useEffect(() => { const subscription = Notifications.addNotificationResponseReceivedListener( ({ notification }) => {