| ... | @@ -1,9 +1,11 @@ | ... | @@ -1,9 +1,11 @@ |
| 1 | import { NativeHeaderToolbar, NativeStackScreenOptions } from "../../native/StackHeader"; | 1 | import { NativeHeaderToolbar, NativeStackScreenOptions } from "../../native/StackHeader"; |
| 2 | import { | 2 | import { |
| | 3 | CommonActions, |
| 3 | StackActions, | 4 | StackActions, |
| 4 | useFocusEffect, | 5 | useFocusEffect, |
| 5 | useNavigation, | 6 | useNavigation, |
| 6 | usePreventRemove, | 7 | usePreventRemove, |
| | 8 | type NavigationAction, |
| 7 | } from "@react-navigation/native"; | 9 | } from "@react-navigation/native"; |
| 8 | import { useCallback, useEffect, useRef, useState } from "react"; | 10 | import { useCallback, useEffect, useRef, useState } from "react"; |
| 9 | import { Alert, Platform, Pressable, ScrollView, View } from "react-native"; | 11 | import { Alert, Platform, Pressable, ScrollView, View } from "react-native"; |
| ... | @@ -212,6 +214,9 @@ export function NewTaskDraftScreen(props: { | ... | @@ -212,6 +214,9 @@ export function NewTaskDraftScreen(props: { |
| 212 | const [isCancellingShareImport, setIsCancellingShareImport] = useState(false); | 214 | const [isCancellingShareImport, setIsCancellingShareImport] = useState(false); |
| 213 | const [cancelledIncomingShareId, setCancelledIncomingShareId] = useState<string | null>(null); | 215 | const [cancelledIncomingShareId, setCancelledIncomingShareId] = useState<string | null>(null); |
| 214 | const [isReturningToProjectPicker, setIsReturningToProjectPicker] = useState(false); | 216 | const [isReturningToProjectPicker, setIsReturningToProjectPicker] = useState(false); |
| | 217 | const [submitNavigationAction, setSubmitNavigationAction] = useState<NavigationAction | null>( |
| | 218 | null, |
| | 219 | ); |
| 215 | const [shareImportAttempt, setShareImportAttempt] = useState(0); | 220 | const [shareImportAttempt, setShareImportAttempt] = useState(0); |
| 216 | const startedShareImportKeyRef = useRef<string | null>(null); | 221 | const startedShareImportKeyRef = useRef<string | null>(null); |
| 217 | const cancellingShareImportKeyRef = useRef<string | null>(null); | 222 | const cancellingShareImportKeyRef = useRef<string | null>(null); |
| ... | @@ -275,12 +280,23 @@ export function NewTaskDraftScreen(props: { | ... | @@ -275,12 +280,23 @@ export function NewTaskDraftScreen(props: { |
| 275 | voiceInput.elapsedSeconds, | 280 | voiceInput.elapsedSeconds, |
| 276 | ); | 281 | ); |
| 277 | const isVoiceInputPresented = voicePresentation.statusLabel !== null; | 282 | const isVoiceInputPresented = voicePresentation.statusLabel !== null; |
| 278 | usePreventRemove( | 283 | const preventRemove = |
| 279 | (isIncomingShareTransferPending && !isProjectPickerReturnActive) || | 284 | (isIncomingShareTransferPending && !isProjectPickerReturnActive) || |
| 280 | isCancellingShareImport || | 285 | isCancellingShareImport || |
| 281 | flow.submitting, | 286 | flow.submitting; |
| 282 | () => undefined, | 287 | usePreventRemove(preventRemove, () => undefined); |
| 283 | ); | 288 | useEffect(() => { |
| | 289 | if (preventRemove || submitNavigationAction === null) { |
| | 290 | return; |
| | 291 | } |
| | 292 | // Give the guard update a frame to reach the parent sheet before navigating, |
| | 293 | // just like the project-picker fallback below. |
| | 294 | const frame = requestAnimationFrame(() => { |
| | 295 | setSubmitNavigationAction(null); |
| | 296 | (navigation.getParent() ?? navigation).dispatch(submitNavigationAction); |
| | 297 | }); |
| | 298 | return () => cancelAnimationFrame(frame); |
| | 299 | }, [navigation, preventRemove, submitNavigationAction]); |
| 284 | const hasImportedIncomingShare = Boolean( | 300 | const hasImportedIncomingShare = Boolean( |
| 285 | props.incomingShareId && | 301 | props.incomingShareId && |
| 286 | flow.draftKey && | 302 | flow.draftKey && |
| ... | @@ -872,7 +888,7 @@ export function NewTaskDraftScreen(props: { | ... | @@ -872,7 +888,7 @@ export function NewTaskDraftScreen(props: { |
| 872 | clearWorkspaceSelection: true, | 888 | clearWorkspaceSelection: true, |
| 873 | }); | 889 | }); |
| 874 | } | 890 | } |
| 875 | navigation.getParent()?.goBack(); | 891 | setSubmitNavigationAction(CommonActions.goBack()); |
| 876 | return; | 892 | return; |
| 877 | } | 893 | } |
| 878 | | 894 | |
| ... | @@ -943,7 +959,7 @@ export function NewTaskDraftScreen(props: { | ... | @@ -943,7 +959,7 @@ export function NewTaskDraftScreen(props: { |
| 943 | clearWorkspaceSelection: true, | 959 | clearWorkspaceSelection: true, |
| 944 | }); | 960 | }); |
| 945 | } | 961 | } |
| 946 | navigation.dispatch( | 962 | setSubmitNavigationAction( |
| 947 | StackActions.replace("Thread", { | 963 | StackActions.replace("Thread", { |
| 948 | environmentId: String(result.value.environmentId), | 964 | environmentId: String(result.value.environmentId), |
| 949 | threadId: String(result.value.threadId), | 965 | threadId: String(result.value.threadId), |