From e07b5aa988113029ddfa792500f7ff95f41bef16 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Wed, 7 Aug 2024 13:42:10 -0700 Subject: [PATCH] LFS: pairing 1 --- src/common/livefile/LiveFileSyncButton.tsx | 39 +++++++++++++------ src/common/livefile/useLiveFileComparison.tsx | 38 ++++++++---------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/common/livefile/LiveFileSyncButton.tsx b/src/common/livefile/LiveFileSyncButton.tsx index e83c387c4..d249353f1 100644 --- a/src/common/livefile/LiveFileSyncButton.tsx +++ b/src/common/livefile/LiveFileSyncButton.tsx @@ -4,6 +4,7 @@ import { Box, Button, SvgIcon } from '@mui/joy'; import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded'; import { TooltipOutlined } from '~/common/components/TooltipOutlined'; +import { getDataTransferFilesOrPromises } from '~/common/util/fileSystemUtils'; import { useDragDropDataTransfer } from '~/common/components/useDragDropDataTransfer'; import { LiveFileChooseIcon, LiveFileIcon } from './liveFile.icons'; @@ -11,16 +12,30 @@ import { LiveFileChooseIcon, LiveFileIcon } from './liveFile.icons'; export function LiveFileSyncButton(props: { disabled: boolean; + hasContent: boolean; isPaired: boolean; - isRead: boolean; - handleSyncButtonClicked: () => void; + onPairWithFSFHandle: (fsHandle: FileSystemFileHandle) => Promise; + onPairWithPicker: () => Promise; + upUpdateFileContent: () => void; }) { + const { onPairWithFSFHandle } = props; + const handleDataTransfer = React.useCallback(async (dataTransfer: DataTransfer) => { + // get FileSystemFileHandle objects from the DataTransfer + const fileOrFSHandlePromises = getDataTransferFilesOrPromises(dataTransfer.items, false); + if (!fileOrFSHandlePromises.length) + return; - - console.log('LiveFileSyncButton: handleDataTransfer', dataTransfer); - }, []); + // resolve the promises to get the actual files/handles + const filesOrHandles = await Promise.all(fileOrFSHandlePromises); + for (let filesOrHandle of filesOrHandles) { + if (!(filesOrHandle instanceof File) && filesOrHandle?.kind === 'file' && filesOrHandle) { + await onPairWithFSFHandle(filesOrHandle); + break; + } + } + }, [onPairWithFSFHandle]); const { dragContainerSx, @@ -38,27 +53,27 @@ export function LiveFileSyncButton(props: { diff --git a/src/common/livefile/useLiveFileComparison.tsx b/src/common/livefile/useLiveFileComparison.tsx index 295a12e10..6b43dd7bb 100644 --- a/src/common/livefile/useLiveFileComparison.tsx +++ b/src/common/livefile/useLiveFileComparison.tsx @@ -16,7 +16,6 @@ import { useLiveFile } from './liveFile.hooks'; import { LiveFileSyncButton } from '~/common/livefile/LiveFileSyncButton'; - interface DiffSummary { insertions: number; deletions: number; @@ -130,33 +129,28 @@ export function useLiveFileComparison( } }, [fileHasContent, isLoadingFile, reloadFileContent]); - const handlePairNewFileWithPicker = React.useCallback(async () => { - // Open the file picker - const fileWithHandle = await fileOpen({ description: 'Select a File to pair to this document' }).catch(() => null /* The User closed the files picker */); - if (!fileWithHandle) - return; - if (!fileWithHandle.handle) { - setStatus({ message: 'Browser does not support LiveFile operations.', mtype: 'error' }); - return; - } - + const handlePairNewFSFHandle = React.useCallback(async (fsfHandle: FileSystemFileHandle) => { // Pair the file: create a LiveFile, replace it in the Fragment, and load the preview try { - const liveFileId = await liveFileCreateOrThrow(fileWithHandle.handle); + const liveFileId = await liveFileCreateOrThrow(fsfHandle); replaceLiveFileId(liveFileId); // Immediately load the preview on this ID await handleUpdateFileContent(liveFileId); } catch (error: any) { setStatus({ message: `Error pairing the file: ${error?.message || typeof error === 'string' ? error : 'Unknown error'}`, mtype: 'error' }); } - }, [replaceLiveFileId, handleUpdateFileContent]); + }, [handleUpdateFileContent, replaceLiveFileId]); - const handleSyncButtonClicked = React.useCallback(async () => { - if (isPairingValid) - await handleUpdateFileContent(); + const handlePairNewFileWithPicker = React.useCallback(async () => { + // Open the file picker + const fileWithHandle = await fileOpen({ description: 'Select a File to pair to this document' }).catch(() => null /* The User closed the files picker */); + if (!fileWithHandle) + return; + if (fileWithHandle.handle) + await handlePairNewFSFHandle(fileWithHandle.handle); else - await handlePairNewFileWithPicker(); - }, [handlePairNewFileWithPicker, handleUpdateFileContent, isPairingValid]); + setStatus({ message: 'Browser does not support LiveFile operations.', mtype: 'error' }); + }, [handlePairNewFSFHandle]); // Save and Load from Disk @@ -188,10 +182,12 @@ export function useLiveFileComparison( - ), [fileHasContent, handleSyncButtonClicked, isPairingValid, isSavingFile]); + ), [fileHasContent, handlePairNewFSFHandle, handlePairNewFileWithPicker, handleUpdateFileContent, isPairingValid, isSavingFile]); const liveFileActionBox = React.useMemo(() => { if (!status && !fileHasContent) return null;