From 8e9eb79f2bb8598f6dc359db82d97dcf71255f6f Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 4 Mar 2025 14:17:30 +0530 Subject: [PATCH] Slightly better --- .../gallery/components/viewer/FileViewer.tsx | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/web/packages/gallery/components/viewer/FileViewer.tsx b/web/packages/gallery/components/viewer/FileViewer.tsx index 9d32737208..b85980f2f1 100644 --- a/web/packages/gallery/components/viewer/FileViewer.tsx +++ b/web/packages/gallery/components/viewer/FileViewer.tsx @@ -225,9 +225,21 @@ const FileViewer: React.FC = ({ const { show: showConfirmDelete, props: confirmDeleteVisibilityProps } = useModalVisibility(); + // Callbacks to be invoked (only once) the next time we get an update to the + // `files` prop. + const [, setOnNextFilesUpdate] = useState<(() => void)[]>([]); + // If `true`, then we need to trigger a sync with remote when we close. const [, setNeedsSync] = useState(false); + /** + * Add a callback to be fired (only once) the next time we get an update to + * the `files` prop. + */ + const awaitNextFilesUpdate = useCallback((cb: () => void) => { + setOnNextFilesUpdate((cbs) => cbs.concat(cb)); + }, []); + const handleClose = useCallback(() => { setNeedsSync((needSync) => { if (needSync) onTriggerSyncWithRemote?.(); @@ -288,18 +300,23 @@ const FileViewer: React.FC = ({ const handleDelete = async () => { const file = activeAnnotatedFile!.file; await onDelete(file); + // Be careful here. This works currently, deterministically, but it + // relies on the assumption that `onDelete` will asynchronously result + // in updates to the `files` prop. + awaitNextFilesUpdate(() => { + // Refreshing the current slide after the current file has gone will + // show the subsequent slide (since that will move down to the current + // index). TODO: What if it's the last file? + psRef.current!.refreshCurrentSlideContent(); + + handleNeedsRemoteSync(); + }); // TODO: We currently have a setTimeout to ensure that the updated // `files` prop has made its way to us delegate before we query for the // status again. // // See: [Note: File viewer action setTimeout TODO] - await new Promise((r) => setTimeout(r, 100)); - // Refreshing the current slide after the current file has gone will - // show the subsequent slide (since that will move down to the current - // index). TODO: What if it's the last file? - psRef.current!.refreshCurrentSlideContent(); - - handleNeedsRemoteSync(); + // await new Promise((r) => setTimeout(r, 100)); }; const handleEditImage = useMemo(() => { @@ -411,6 +428,14 @@ const FileViewer: React.FC = ({ delegate.toggleFavorite = toggleFavorite; }, [getFiles, isFavorite, toggleFavorite]); + // Notify the listeners, if any, for updates to files. + useEffect(() => { + setOnNextFilesUpdate((cbs) => { + cbs.forEach((cb) => cb()); + return []; + }); + }, [files]); + useEffect(() => { if (open) { // We're open. Create psRef. This will show the file viewer dialog.