MM-45022 : Gekidou - Refactor code to use custom nav hooks (#6426)

* refactoring code to use useAndroidBackHandler hook - part 1

* useNavButtonPressed - part 2

* useNavButtonPressed hook - part 3

* Apply suggestions from code review

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* PR review corrections

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
Avinash Lingaloo 2022-06-30 19:12:59 +04:00 committed by GitHub
parent 247c515b01
commit 2b87417eb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 120 additions and 303 deletions

View file

@ -4,7 +4,7 @@
import {DependencyList, EffectCallback, useEffect} from 'react';
import {Navigation} from 'react-native-navigation';
const useNavButtonPressed = (navButtonId: string, componentId: string, callback: EffectCallback, deps?: DependencyList) => {
const useNavButtonPressed = (navButtonId: string, componentId: string, callback: EffectCallback | any, deps?: DependencyList) => {
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {

View file

@ -5,7 +5,7 @@ import React, {useCallback, useEffect, useMemo, useReducer, useRef, useState} fr
import {useIntl} from 'react-intl';
import {Keyboard, ScrollView, Text, View} from 'react-native';
import Button from 'react-native-button';
import {ImageResource, Navigation} from 'react-native-navigation';
import {ImageResource} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {handleGotoLocation} from '@actions/remote/command';
@ -15,6 +15,7 @@ import {AppCallResponseTypes} from '@constants/apps';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useDidUpdate from '@hooks/did_update';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {filterEmptyOptions} from '@utils/apps';
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
import {checkDialogElementForError, checkIfErrorsMatchElements} from '@utils/integrations';
@ -125,27 +126,15 @@ function AppsFormComponent({
const theme = useTheme();
const style = getStyleFromTheme(theme);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
switch (buttonId) {
case CLOSE_BUTTON_ID:
close();
break;
case SUBMIT_BUTTON_ID: {
if (!submitting) {
handleSubmit();
}
break;
}
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
const onHandleSubmit = useCallback(() => {
if (!submitting) {
handleSubmit();
}
}, [serverUrl, componentId, submitting]);
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, [close]);
useNavButtonPressed(SUBMIT_BUTTON_ID, componentId, onHandleSubmit, [onHandleSubmit]);
useDidUpdate(() => {
dispatchValues({elements: form.fields});
}, [form]);

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {ReactNode, useCallback, useEffect, useRef} from 'react';
import {BackHandler, DeviceEventEmitter, Keyboard, StyleSheet, useWindowDimensions, View} from 'react-native';
import {DeviceEventEmitter, Keyboard, StyleSheet, useWindowDimensions, View} from 'react-native';
import {State, TapGestureHandler} from 'react-native-gesture-handler';
import {Navigation as RNN} from 'react-native-navigation';
import Animated, {Easing, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
@ -10,9 +10,9 @@ import RNBottomSheet from 'reanimated-bottom-sheet';
import {Events} from '@constants';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useIsTablet} from '@hooks/device';
import {dismissModal} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {hapticFeedback} from '@utils/general';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@ -54,21 +54,15 @@ const BottomSheet = ({closeButtonId, componentId, initialSnapIndex = 0, renderCo
return () => listener.remove();
}, [close]);
useEffect(() => {
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getNavigationTopComponentId() === componentId) {
if (sheetRef.current) {
sheetRef.current.snapTo(1);
} else {
close();
}
return true;
}
return false;
});
const handleClose = useCallback(() => {
if (sheetRef.current) {
sheetRef.current.snapTo(1);
} else {
close();
}
}, []);
return () => listener.remove();
}, [close]);
useAndroidHardwareBackHandler(componentId, handleClose);
useEffect(() => {
hapticFeedback();

View file

@ -4,7 +4,7 @@
import React, {useCallback, useEffect, useState} from 'react';
import {IntlShape, useIntl} from 'react-intl';
import {Keyboard, Platform, StyleSheet, View} from 'react-native';
import {ImageResource, Navigation, OptionsTopBarButton} from 'react-native-navigation';
import {ImageResource, OptionsTopBarButton} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {joinChannel, switchToChannelById} from '@actions/remote/channel';
@ -13,6 +13,7 @@ import Search from '@components/search';
import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal, goToScreen, setButtons} from '@screens/navigation';
import {alertErrorWithFallback} from '@utils/draft';
import {changeOpacity, getKeyboardAppearanceFromTheme} from '@utils/theme';
@ -162,27 +163,15 @@ export default function BrowseChannels(props: Props) {
searchChannels(term);
}, [term, searchChannels]);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
switch (buttonId) {
case CLOSE_BUTTON_ID:
close();
break;
case CREATE_BUTTON_ID: {
const screen = Screens.CREATE_OR_EDIT_CHANNEL;
const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'});
goToScreen(screen, title);
break;
}
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
const handleCreate = useCallback(() => {
const screen = Screens.CREATE_OR_EDIT_CHANNEL;
const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'});
goToScreen(screen, title);
}, [intl.locale]);
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, [close]);
useNavButtonPressed(CREATE_BUTTON_ID, componentId, handleCreate, [handleCreate]);
useEffect(() => {
// Update header buttons in case anything related to the header changes
setHeaderButtons(!adding);

View file

@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useEffect} from 'react';
import React from 'react';
import {ScrollView, View} from 'react-native';
import {Navigation} from 'react-native-navigation';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import ChannelActions from '@components/channel_actions';
import {useTheme} from '@context/theme';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@ -44,19 +44,11 @@ const ChannelInfo = ({channelId, closeButtonId, componentId, type}: Props) => {
const theme = useTheme();
const styles = getStyleSheet(theme);
useEffect(() => {
const update = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: {buttonId: string}) => {
if (buttonId === closeButtonId) {
dismissModal({componentId});
}
},
}, componentId);
const onPressed = () => {
dismissModal({componentId});
};
return () => {
update.remove();
};
}, []);
useNavButtonPressed(closeButtonId, componentId, onPressed, []);
return (
<SafeAreaView

View file

@ -4,7 +4,6 @@
import React, {useCallback, useEffect, useMemo, useReducer, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Keyboard, Platform, View} from 'react-native';
import {Navigation} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {makeDirectChannel, makeGroupChannel} from '@actions/remote/channel';
@ -16,14 +15,11 @@ import {General} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {debounce} from '@helpers/api/general';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {t} from '@i18n';
import {dismissModal, setButtons} from '@screens/navigation';
import {alertErrorWithFallback} from '@utils/draft';
import {
changeOpacity,
makeStyleSheetFromTheme,
getKeyboardAppearanceFromTheme,
} from '@utils/theme';
import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme';
import {displayUsername, filterProfilesMatchingTerm} from '@utils/user';
import SelectedUsers from './selected_users';
@ -303,18 +299,8 @@ export default function CreateDirectMessage({
});
}, [intl.locale, theme]);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({navigationButtonPressed: ({buttonId}) => {
if (buttonId === START_BUTTON) {
startConversation();
} else if (buttonId === CLOSE_BUTTON) {
close();
}
}}, componentId);
return () => {
unsubscribe.remove();
};
}, [startConversation]);
useNavButtonPressed(START_BUTTON, componentId, startConversation, [startConversation]);
useNavButtonPressed(CLOSE_BUTTON, componentId, close, [close]);
useEffect(() => {
mounted.current = true;

View file

@ -1,17 +1,18 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useState, useEffect, useReducer, useCallback, useMemo} from 'react';
import React, {useCallback, useEffect, useMemo, useReducer, useState} from 'react';
import {useIntl} from 'react-intl';
import {Keyboard} from 'react-native';
import {ImageResource, Navigation} from 'react-native-navigation';
import {ImageResource} from 'react-native-navigation';
import {patchChannel as handlePatchChannel, createChannel, switchToChannelById} from '@actions/remote/channel';
import {createChannel, patchChannel as handlePatchChannel, switchToChannelById} from '@actions/remote/channel';
import CompassIcon from '@components/compass_icon';
import {General} from '@constants';
import {MIN_CHANNEL_NAME_LENGTH} from '@constants/channel';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {buildNavigationButton, dismissModal, popTopScreen, setButtons} from '@screens/navigation';
import {validateDisplayName} from '@utils/channel';
@ -220,27 +221,13 @@ const CreateOrEditChannel = ({
close(componentId, isModal);
}, [channel?.id, channel?.type, displayName, header, isModal, purpose, isValidDisplayName]);
useEffect(() => {
const update = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: {buttonId: string}) => {
switch (buttonId) {
case CLOSE_BUTTON_ID:
close(componentId, isModal);
break;
case CREATE_BUTTON_ID:
onCreateChannel();
break;
case EDIT_BUTTON_ID:
onUpdateChannel();
break;
}
},
}, componentId);
const handleClose = useCallback(() => {
close(componentId, isModal);
}, [isModal]);
return () => {
update.remove();
};
}, [onCreateChannel, onUpdateChannel, isModal]);
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, handleClose, [handleClose]);
useNavButtonPressed(CREATE_BUTTON_ID, componentId, onCreateChannel, [onCreateChannel]);
useNavButtonPressed(EDIT_BUTTON_ID, componentId, onUpdateChannel, [onUpdateChannel]);
return (
<ChannelInfoForm

View file

@ -4,7 +4,6 @@
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Alert, Keyboard, KeyboardType, LayoutChangeEvent, Platform, SafeAreaView, useWindowDimensions, View} from 'react-native';
import {Navigation} from 'react-native-navigation';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import {deletePost, editPost} from '@actions/remote/post';
@ -14,6 +13,7 @@ import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import useDidUpdate from '@hooks/did_update';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import PostError from '@screens/edit_post/post_error';
import {buildNavigationButton, dismissModal, setButtons} from '@screens/navigation';
import {switchKeyboardForCodeBlocks} from '@utils/markdown';
@ -115,26 +115,6 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
};
}, []);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
switch (buttonId) {
case closeButtonId: {
onClose();
break;
}
case RIGHT_BUTTON.id:
onSavePostMessage();
break;
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
}, [postMessage]);
useDidUpdate(() => {
// Workaround to avoid iOS emdash autocorrect in Code Blocks
if (Platform.OS === 'ios') {
@ -254,6 +234,9 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
};
});
useNavButtonPressed(RIGHT_BUTTON.id, componentId, onSavePostMessage, [postMessage]);
useNavButtonPressed(closeButtonId, componentId, onClose, []);
if (isUpdating) {
return (
<View style={styles.loader}>

View file

@ -3,9 +3,8 @@
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {BackHandler, DeviceEventEmitter, Keyboard, Platform, StyleSheet, View} from 'react-native';
import {DeviceEventEmitter, Keyboard, Platform, StyleSheet, View} from 'react-native';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import {Navigation} from 'react-native-navigation';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import {updateLocalUser} from '@actions/local/user';
@ -15,8 +14,9 @@ import TabletTitle from '@components/tablet_title';
import {Events} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal, popTopScreen, setButtons} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {preventDoubleTap} from '@utils/tap';
import ProfileForm from './components/form';
@ -85,39 +85,6 @@ const EditProfile = ({
};
}, [isTablet, theme.centerChannelColor]);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
switch (buttonId) {
case UPDATE_BUTTON_ID:
submitUser();
break;
case CLOSE_BUTTON_ID:
close();
break;
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
}, [userInfo]);
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
return false;
});
return () => {
backHandler.remove();
};
}, []);
useEffect(() => {
if (!isTablet) {
setButtons(componentId, {
@ -136,7 +103,6 @@ const EditProfile = ({
popTopScreen(componentId);
}
}, []);
const enableSaveButton = useCallback((value: boolean) => {
if (!isTablet) {
const buttons = {
@ -149,24 +115,6 @@ const EditProfile = ({
}
setCanSave(value);
}, [componentId, rightButton]);
const onUpdateProfilePicture = useCallback((newProfileImage: NewProfileImage) => {
changedProfilePicture.current = newProfileImage;
enableSaveButton(true);
}, [enableSaveButton]);
const onUpdateField = useCallback((fieldKey: string, name: string) => {
const update = {...userInfo};
update[fieldKey] = name;
setUserInfo(update);
// @ts-expect-error access object property by string key
const currentValue = currentUser[fieldKey];
const didChange = currentValue !== name;
hasUpdateUserInfo.current = currentValue !== name;
enableSaveButton(didChange);
}, [userInfo, currentUser, enableSaveButton]);
const submitUser = useCallback(preventDoubleTap(async () => {
enableSaveButton(false);
setError(undefined);
@ -209,6 +157,27 @@ const EditProfile = ({
}
}), [userInfo, enableSaveButton]);
useAndroidHardwareBackHandler(componentId, close);
useNavButtonPressed(UPDATE_BUTTON_ID, componentId, submitUser, [userInfo]);
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, []);
const onUpdateProfilePicture = useCallback((newProfileImage: NewProfileImage) => {
changedProfilePicture.current = newProfileImage;
enableSaveButton(true);
}, [enableSaveButton]);
const onUpdateField = useCallback((fieldKey: string, name: string) => {
const update = {...userInfo};
update[fieldKey] = name;
setUserInfo(update);
// @ts-expect-error access object property by string key
const currentValue = currentUser[fieldKey];
const didChange = currentValue !== name;
hasUpdateUserInfo.current = currentValue !== name;
enableSaveButton(didChange);
}, [userInfo, currentUser, enableSaveButton]);
const resetScreen = useCallback((resetError: Error) => {
setError(resetError?.message);
Keyboard.dismiss();

View file

@ -3,9 +3,9 @@
import React, {useCallback, useEffect} from 'react';
import {Keyboard} from 'react-native';
import {Navigation} from 'react-native-navigation';
import EmojiPicker from '@components/emoji_picker';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal, setButtons} from '@screens/navigation';
type Props = {
@ -14,36 +14,28 @@ type Props = {
closeButton: never;
};
const EMOJI_PICKER_BUTTON = 'close-add-reaction';
const EmojiPickerScreen = ({closeButton, componentId, onEmojiPress}: Props) => {
useEffect(() => {
setButtons(componentId, {
leftButtons: [
{
icon: closeButton,
id: 'close-add-reaction',
id: EMOJI_PICKER_BUTTON,
testID: 'close.emoji_picker.button',
},
],
rightButtons: [],
});
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
if (buttonId === 'close-add-reaction') {
close();
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
}, []);
const close = useCallback(() => {
const close = () => {
Keyboard.dismiss();
dismissModal();
}, []);
dismissModal({componentId});
};
useNavButtonPressed(EMOJI_PICKER_BUTTON, componentId, close, []);
const handleEmojiPress = useCallback((emoji: string) => {
onEmojiPress(emoji);

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {Alert, BackHandler, Text, TouchableOpacity, View} from 'react-native';
import {Alert, Text, TouchableOpacity, View} from 'react-native';
import Animated from 'react-native-reanimated';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
@ -17,10 +17,10 @@ import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import DatabaseManager from '@database/manager';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useIsTablet} from '@hooks/device';
import {getChannelById, getMyChannel} from '@queries/servers/channel';
import {dismissModal} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
import {closePermalink} from '@utils/permalink';
import {preventDoubleTap} from '@utils/tap';
@ -251,20 +251,7 @@ function Permalink({
closePermalink();
}, [error]);
useEffect(() => {
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getNavigationTopComponentId() === Screens.PERMALINK) {
handleClose();
return true;
}
return false;
});
return () => {
listener.remove();
};
}, []);
useAndroidHardwareBackHandler(Screens.PERMALINK, handleClose);
const handlePress = useCallback(preventDoubleTap(() => {
if (channel) {

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {BackHandler, DeviceEventEmitter, FlatList, StyleSheet, View} from 'react-native';
import {DeviceEventEmitter, FlatList, StyleSheet, View} from 'react-native';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import {fetchPinnedPosts} from '@actions/remote/post';
@ -12,9 +12,9 @@ import Post from '@components/post_list/post';
import {Events, Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {popTopScreen} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {isDateLine, getDateForDateLine, selectOrderedPosts} from '@utils/post_list';
import {getDateForDateLine, isDateLine, selectOrderedPosts} from '@utils/post_list';
import EmptyState from './empty';
@ -23,7 +23,7 @@ import type PostModel from '@typings/database/models/servers/post';
type Props = {
channelId: string;
componentId?: string;
componentId: string;
currentTimezone: string | null;
isCRTEnabled: boolean;
isTimezoneEnabled: boolean;
@ -78,18 +78,7 @@ function SavedMessages({
});
}, []);
useEffect(() => {
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
return false;
});
return () => listener.remove();
}, [componentId]);
useAndroidHardwareBackHandler(componentId, close);
const onViewableItemsChanged = useCallback(({viewableItems}: ViewableItemsChanged) => {
if (!viewableItems.length) {

View file

@ -2,12 +2,12 @@
// See LICENSE.txt for license information.
import {useManagedConfig} from '@mattermost/react-native-emm';
import React, {useEffect} from 'react';
import {Navigation} from 'react-native-navigation';
import React from 'react';
import {CopyPermalinkOption, FollowThreadOption, ReplyOption, SaveOption} from '@components/common_post_options';
import {ITEM_HEIGHT} from '@components/menu_item';
import {Screens} from '@constants';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import BottomSheet from '@screens/bottom_sheet';
import {dismissModal} from '@screens/navigation';
import {isSystemMessage} from '@utils/post';
@ -22,6 +22,8 @@ import ReactionBar from './reaction_bar';
import type PostModel from '@typings/database/models/servers/post';
import type ThreadModel from '@typings/database/models/servers/thread';
const POST_OPTIONS_BUTTON = 'close-post-options';
type PostOptionsProps = {
canAddReaction: boolean;
canDelete: boolean;
@ -36,7 +38,6 @@ type PostOptionsProps = {
thread?: ThreadModel;
componentId: string;
};
const PostOptions = ({
canAddReaction, canDelete, canEdit,
canMarkAsUnread, canPin, canReply,
@ -45,22 +46,11 @@ const PostOptions = ({
}: PostOptionsProps) => {
const managedConfig = useManagedConfig<ManagedConfig>();
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
switch (buttonId) {
case 'close-post-options': {
dismissModal({componentId});
break;
}
}
},
}, componentId);
const close = () => {
dismissModal({componentId});
};
return () => {
unsubscribe.remove();
};
}, []);
useNavButtonPressed(POST_OPTIONS_BUTTON, componentId, close, []);
const isSystemPost = isSystemMessage(post);
@ -134,7 +124,7 @@ const PostOptions = ({
return (
<BottomSheet
renderContent={renderContent}
closeButtonId='close-post-options'
closeButtonId={POST_OPTIONS_BUTTON}
componentId={Screens.POST_OPTIONS}
initialSnapIndex={0}
snapPoints={[((snapPoints + additionalSnapPoints) * ITEM_HEIGHT), 10]}

View file

@ -1,18 +1,18 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo} from 'react';
import React, {useEffect, useMemo} from 'react';
import {useIntl} from 'react-intl';
import {Alert, BackHandler, Platform, ScrollView, View} from 'react-native';
import {Navigation} from 'react-native-navigation';
import {Alert, Platform, ScrollView, View} from 'react-native';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import CompassIcon from '@components/compass_icon';
import {Screens} from '@constants';
import {useServerDisplayName} from '@context/server';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal, goToScreen, setButtons} from '@screens/navigation';
import NavigationStore from '@store/navigation_store';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@ -83,9 +83,9 @@ const Settings = ({componentId, showHelp, siteName}: SettingsProps) => {
};
}, [theme.centerChannelColor]);
const close = useCallback(() => {
const close = () => {
dismissModal({componentId});
}, []);
};
useEffect(() => {
setButtons(componentId, {
@ -93,33 +93,9 @@ const Settings = ({componentId, showHelp, siteName}: SettingsProps) => {
});
}, []);
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
useAndroidHardwareBackHandler(componentId, close);
return false;
});
return () => {
backHandler.remove();
};
}, []);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
if (buttonId === CLOSE_BUTTON_ID) {
close();
}
},
}, componentId);
return () => {
unsubscribe.remove();
};
}, []);
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, []);
const onPressHandler = () => {
return Alert.alert(

View file

@ -2,9 +2,8 @@
// See LICENSE.txt for license information.
import {useManagedConfig} from '@mattermost/react-native-emm';
import React, {useEffect} from 'react';
import React from 'react';
import {View} from 'react-native';
import {Navigation} from 'react-native-navigation';
import {CopyPermalinkOption, FollowThreadOption, ReplyOption, SaveOption} from '@components/common_post_options';
import FormattedText from '@components/formatted_text';
@ -12,6 +11,7 @@ import {ITEM_HEIGHT} from '@components/menu_item';
import {Screens} from '@constants';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import BottomSheet from '@screens/bottom_sheet';
import {dismissModal} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@ -45,6 +45,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
};
});
const THREAD_OPTIONS_BUTTON = 'close-thread-options';
const ThreadOptions = ({
componentId,
isSaved,
@ -57,19 +59,11 @@ const ThreadOptions = ({
const style = getStyleSheet(theme);
useEffect(() => {
const unsubscribe = Navigation.events().registerComponentListener({
navigationButtonPressed: ({buttonId}: { buttonId: string }) => {
if (buttonId === 'close-thread-options') {
dismissModal({componentId});
}
},
}, componentId);
const close = () => {
dismissModal({componentId});
};
return () => {
unsubscribe.remove();
};
}, []);
useNavButtonPressed(THREAD_OPTIONS_BUTTON, componentId, close, []);
const options = [
<ReplyOption
@ -127,7 +121,7 @@ const ThreadOptions = ({
return (
<BottomSheet
renderContent={renderContent}
closeButtonId='close-thread-options'
closeButtonId={THREAD_OPTIONS_BUTTON}
componentId={Screens.THREAD_OPTIONS}
initialSnapIndex={0}
snapPoints={[((options.length + 2) * ITEM_HEIGHT), 10]}