diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index c91a4eeab5..ac3033dd34 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -413,21 +413,31 @@ export const ComposePost = ({ const onPressCancel = useCallback(() => { if (textInput.current?.maybeClosePopup()) { return - } else if ( - thread.posts.some( - post => - post.shortenedGraphemeLength > 0 || - post.embed.media || - post.embed.link, - ) - ) { + } + + const hasContent = thread.posts.some( + post => + post.shortenedGraphemeLength > 0 || post.embed.media || post.embed.link, + ) + + // Show discard prompt if there's content AND either: + // - No draft is loaded (new composition) + // - Draft is loaded but has been modified + if (hasContent && (!composerState.draftId || composerState.isDirty)) { closeAllDialogs() Keyboard.dismiss() discardPromptControl.open() } else { onClose() } - }, [thread, closeAllDialogs, discardPromptControl, onClose]) + }, [ + thread, + composerState.draftId, + composerState.isDirty, + closeAllDialogs, + discardPromptControl, + onClose, + ]) useImperativeHandle(cancelRef, () => ({onPressCancel})) diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts index 17d76ddd84..8ac26d1feb 100644 --- a/src/view/com/composer/state/composer.ts +++ b/src/view/com/composer/state/composer.ts @@ -104,6 +104,8 @@ export type ComposerState = { mutableNeedsFocusActive: boolean /** ID of the draft being edited, if any. Used to update existing draft on save. */ draftId?: string + /** Whether the composer has been modified since loading a draft. */ + isDirty: boolean } export type ComposerAction = @@ -145,6 +147,7 @@ export function composerReducer( case 'update_postgate': { return { ...state, + isDirty: true, thread: { ...state.thread, postgate: action.postgate, @@ -154,6 +157,7 @@ export function composerReducer( case 'update_threadgate': { return { ...state, + isDirty: true, thread: { ...state.thread, threadgate: action.threadgate, @@ -174,6 +178,7 @@ export function composerReducer( } return { ...state, + isDirty: true, thread: { ...state.thread, posts: nextPosts, @@ -196,6 +201,7 @@ export function composerReducer( }) return { ...state, + isDirty: true, thread: { ...state.thread, posts: nextPosts, @@ -221,6 +227,7 @@ export function composerReducer( } return { ...state, + isDirty: true, activePostIndex: nextActivePostIndex, mutableNeedsFocusActive: true, thread: { @@ -305,6 +312,7 @@ export function composerReducer( activePostIndex: 0, mutableNeedsFocusActive: true, draftId: draft.id, + isDirty: false, thread: { posts, postgate: draft.postgate || state.thread.postgate, @@ -317,6 +325,7 @@ export function composerReducer( activePostIndex: 0, mutableNeedsFocusActive: true, draftId: undefined, + isDirty: false, thread: { posts: [ { @@ -699,6 +708,7 @@ export function createComposerState({ return { activePostIndex: 0, mutableNeedsFocusActive: false, + isDirty: false, thread: { posts: [ {