11import * as Dialog from "../../components/ui/Dialog" ;
22import Constants from "expo-constants" ;
33import * as Crypto from "expo-crypto" ;
4- import { PROVIDER_SEND_TURN_MAX_FILE_BYTES } from "@t3tools/contracts" ;
4+ import { EnvironmentId , PROVIDER_SEND_TURN_MAX_FILE_BYTES } from "@t3tools/contracts" ;
55import {
66 clearSharedPayloads ,
77 getResolvedSharedPayloadsAsync ,
@@ -11,10 +11,12 @@ import {
1111} from "expo-sharing" ;
1212import { useSyncExternalStore } from "react" ;
1313import { Platform } from "react-native" ;
14+ import { CommonActions } from "@react-navigation/native" ;
1415
1516import {
1617 buildIncomingShareDraft ,
1718 isShareFileUriUnderOwnedRoots ,
19+ selectIncomingShareAttachmentsForServer ,
1820 type IncomingShareDestination ,
1921 type IncomingShareDraft ,
2022} from "./incoming-share-model" ;
@@ -26,6 +28,16 @@ import { coalescedRun } from "../../lib/coalescedRun";
2628import { rootNavigationRef } from "../../lib/rootNavigation" ;
2729import { selectWorkspaceDetail } from "../workspace/workspace-detail-selection" ;
2830import { isDraftThreadRoute } from "../threads/thread-route-state" ;
31+ import { makeIncomingShareImports } from "../threads/incomingShareImport" ;
32+ import { liveNewTaskFlowKeys } from "../threads/new-task-flow-state" ;
33+ import { appAtomRegistry } from "../../state/atom-registry" ;
34+ import { serverEnvironment } from "../../state/server" ;
35+ import {
36+ getComposerDraftSnapshot ,
37+ mergeComposerDraftContent ,
38+ scheduleUnusedComposerAttachmentCleanup ,
39+ undoComposerDraftMerge ,
40+ } from "../../state/use-composer-drafts" ;
2941import {
3042 EMPTY_INCOMING_SHARE_PRESENTATION_STATE ,
3143 transitionIncomingSharePresentation ,
@@ -282,6 +294,67 @@ async function releaseShareReservation(
282294 publish ( await incomingShareInbox . releaseReservation ( shareId , expectedDestination ) ) ;
283295}
284296
297+ /** Moves shares into new-task drafts; see makeIncomingShareImports. */
298+ export const incomingShareImports = makeIncomingShareImports ( {
299+ registry : appAtomRegistry ,
300+ getShare : ( shareId ) => snapshot . drafts . find ( ( draft ) => draft . id === shareId ) ?? null ,
301+ reserve : reserveShare ,
302+ release : releaseShareReservation ,
303+ consume : consumeShare ,
304+ readDraft : getComposerDraftSnapshot ,
305+ undoMerge : undoComposerDraftMerge ,
306+ mergeIntoDraft : mergeComposerDraftContent ,
307+ selectAttachments : ( share , environmentId ) =>
308+ selectIncomingShareAttachmentsForServer ( {
309+ attachments : share . attachments ,
310+ serverConfig : appAtomRegistry . get (
311+ serverEnvironment . configValueAtom ( EnvironmentId . make ( environmentId ) ) ,
312+ ) ,
313+ } ) ,
314+ releaseUnusedAttachments : scheduleUnusedComposerAttachmentCleanup ,
315+ onWarnings : ( warnings ) => {
316+ Dialog . alert ( "Some shared content was skipped" , warnings . join ( "\n" ) ) ;
317+ } ,
318+ onImportFailure : ( target , error ) => {
319+ Dialog . alert (
320+ "Could not import shared content" ,
321+ error instanceof Error ? error . message : "The shared content could not be saved." ,
322+ [
323+ {
324+ text : "Cancel import" ,
325+ style : "cancel" ,
326+ onPress : ( ) => void incomingShareImports . cancel ( target ) ,
327+ } ,
328+ { text : "Retry" , onPress : ( ) => incomingShareImports . retry ( target ) } ,
329+ ] ,
330+ { cancelable : false } ,
331+ ) ;
332+ } ,
333+ onCancelFailure : ( target , error ) => {
334+ Dialog . alert (
335+ "Could not cancel import" ,
336+ error instanceof Error ? error . message : "The shared content could not be restored safely." ,
337+ [
338+ { text : "Retry import" , onPress : ( ) => incomingShareImports . retry ( target ) } ,
339+ { text : "Retry cancel" , onPress : ( ) => void incomingShareImports . cancel ( target ) } ,
340+ ] ,
341+ { cancelable : false } ,
342+ ) ;
343+ } ,
344+ leave : ( target ) => {
345+ rootNavigationRef . dispatch ( {
346+ ...CommonActions . goBack ( ) ,
347+ source : target . routeKey ,
348+ target : rootNavigationRef . getRootState ( ) ?. key ,
349+ } ) ;
350+ } ,
351+ } ) ;
352+
353+ /** Abandons the share imports of draft routes that left the stack. */
354+ export function pruneIncomingShareImports ( state : Parameters < typeof liveNewTaskFlowKeys > [ 0 ] ) {
355+ void incomingShareImports . prune ( liveNewTaskFlowKeys ( state ) ) ;
356+ }
357+
285358export function useIncomingShare ( ) {
286359 const { drafts, isLoading } = useSyncExternalStore (
287360 subscribeIncomingShares ,
@@ -291,8 +364,6 @@ export function useIncomingShare() {
291364 pendingShare : drafts [ 0 ] ?? null ,
292365 isLoading,
293366 getShare : ( shareId : string ) => drafts . find ( ( draft ) => draft . id === shareId ) ?? null ,
294- reserveShare,
295367 releaseShareReservation,
296- consumeShare,
297368 } ;
298369}
0 commit comments