diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js --- a/native/chat/chat-input-bar.react.js +++ b/native/chat/chat-input-bar.react.js @@ -165,6 +165,7 @@ text: string, ) => Promise, +navigation: ?ChatNavigationProp<'MessageList'>, + +isFocused?: boolean, }; type State = { +text: string, @@ -404,6 +405,21 @@ this.expandButtons(); this.setIOSKeyboardHeight(); } + + if (!this.props.isFocused && prevProps.isFocused && this.isEditMode()) { + this.setState({ text: this.props.draft, isExitingEditMode: true }, () => { + this.exitEditMode(); + }); + } + if (this.props.isFocused && !prevProps.isFocused) { + this.setState({ isExitingEditMode: false }); + } + if ( + this.props.inputState?.editState.editedMessage && + !prevProps.inputState?.editState.editedMessage + ) { + this.blockNavigation(); + } } addEditInputMessageListener() { @@ -725,8 +741,11 @@ }; updateText = (text: string) => { + if (this.state.isExitingEditMode) { + return; + } this.setState({ text, textEdited: true }); - if (this.isEditMode() || this.state.isExitingEditMode) { + if (this.isEditMode()) { return; } this.saveDraft(text); @@ -840,6 +859,44 @@ return text !== originalText; }; + unblockNavigation = () => { + if (!this.props.navigation) { + return; + } + this.props.navigation.setParams({ removeEditMode: null }); + }; + + removeEditMode = action => { + if (!this.props.navigation) { + return; + } + if (this.state.isExitingEditMode) { + return; + } + const { navigation: nav } = this.props; + if (!this.isMessageEdited()) { + this.unblockNavigation(); + nav.dispatch(action); + return; + } + const onDiscard = () => { + this.unblockNavigation(); + this.setState({ isExitingEditMode: true }, () => { + nav.dispatch(action); + }); + }; + exitEditAlert(onDiscard); + }; + + blockNavigation = () => { + if (!this.props.navigation) { + return; + } + this.props.navigation.setParams({ + removeEditMode: this.removeEditMode, + }); + }; + editMessage = async (messageID: string, text: string) => { if (!this.isMessageEdited()) { this.exitEditMode(); @@ -885,6 +942,7 @@ exitEditMode = () => { this.props.inputState?.setEditedMessage(null, () => { + this.unblockNavigation(); this.updateText(this.props.draft); this.focusAndUpdateButtonsVisibility(); this.updateSendButton(this.props.draft); @@ -911,19 +969,7 @@ saveExit(); return; } - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the ' + - 'screen?', - [ - { text: 'Don’t leave', style: 'cancel' }, - { - text: 'Discard edit', - style: 'destructive', - onPress: saveExit, - }, - ], - ); + exitEditAlert(saveExit); }; onPressJoin = () => { @@ -1108,6 +1154,7 @@ +onInputBarLayout?: (event: LayoutEvent) => mixed, +openCamera: () => mixed, +navigation?: ChatNavigationProp<'MessageList'>, + +isFocused?: boolean, }; function ConnectedChatInputBarBase(props: ConnectedChatInputBarBaseProps) { const navContext = React.useContext(NavContext); @@ -1298,12 +1345,15 @@ }); }, [keyboardState, navigation, route.key, threadInfo]); + const isFocused = props.navigation.isFocused(); + return ( ); }); diff --git a/native/chat/chat-router.js b/native/chat/chat-router.js --- a/native/chat/chat-router.js +++ b/native/chat/chat-router.js @@ -128,7 +128,19 @@ ); return baseGetStateForAction(clearedState, navigateAction, options); } else { - return baseGetStateForAction(lastState, action, options); + const result = baseGetStateForAction(lastState, action, options); + if ( + result !== null && + result?.index && + result.index > lastState.index && + lastState.routes[lastState.index].params?.removeEditMode + ) { + const removeEditMode: Function = + lastState.routes[lastState.index].params?.removeEditMode; + removeEditMode(action); + return lastState; + } + return result; } }, actionCreators: { diff --git a/native/chat/message-list-types.js b/native/chat/message-list-types.js --- a/native/chat/message-list-types.js +++ b/native/chat/message-list-types.js @@ -7,6 +7,7 @@ import type { ThreadInfo } from 'lib/types/thread-types.js'; import { type UserInfo } from 'lib/types/user-types.js'; +import type { ChatRouterNavigationAction } from './chat-router.js'; import type { MarkdownRules } from '../markdown/rules.react.js'; import { useTextMessageRulesFunc } from '../markdown/rules.react.js'; import { MessageListRouteName } from '../navigation/route-names.js'; @@ -15,6 +16,7 @@ +threadInfo: ThreadInfo, +pendingPersonalThreadUserInfo?: UserInfo, +searching?: boolean, + +removeEditMode?: ?(ChatRouterNavigationAction) => void, }; export type MessageListContextType = {