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