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:
parent
247c515b01
commit
2b87417eb4
15 changed files with 120 additions and 303 deletions
|
|
@ -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 }) => {
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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]}
|
||||
|
|
|
|||
Loading…
Reference in a new issue