Reset cache

This commit is contained in:
Manav Rathi
2025-03-03 16:38:39 +05:30
parent 6676668c86
commit 9c5adfe7cb
7 changed files with 107 additions and 26 deletions

View File

@@ -18,6 +18,7 @@ import {
CollectionSelector,
type CollectionSelectorAttributes,
} from "@/new/photos/components/CollectionSelector";
import { resetFileViewerDataSourceOnClose } from "@/new/photos/components/FileViewerComponents-temp";
import { PlanSelector } from "@/new/photos/components/PlanSelector";
import {
SearchBar,
@@ -564,11 +565,14 @@ const Page: React.FC = () => {
(hiddenFiles) =>
dispatch({ type: "fetchHiddenFiles", hiddenFiles }),
);
if (didUpdateNormalFiles || didUpdateHiddenFiles)
exportService.onLocalFilesUpdated();
await syncTrash(allCollections, (trashedFiles: EnteFile[]) =>
dispatch({ type: "setTrashedFiles", trashedFiles }),
);
if (didUpdateNormalFiles || didUpdateHiddenFiles) {
exportService.onLocalFilesUpdated();
// TODO(PS): Use direct one
resetFileViewerDataSourceOnClose();
}
// syncWithRemote is called with the force flag set to true before
// doing an upload. So it is possible, say when resuming a pending
// upload, that we get two syncWithRemotes happening in parallel.

View File

@@ -213,7 +213,6 @@ const FileViewer: React.FC<FileViewerProps> = ({
const handleClose = useCallback(() => {
setNeedsSync((needSync) => {
console.log("needs sync", needSync);
if (needSync) onTriggerSyncWithRemote?.();
return false;
});

View File

@@ -38,6 +38,15 @@ interface PhotoSwipeSlideData {
* The height (in pixels) of the {@link src} image.
*/
height?: number | undefined;
/**
* The alt text associated with the file.
*
* This will be set to the file's caption. PhotoSwipe will use it as the alt
* text when constructing img elements (if any) for this item. We will also
* use this for displaying the visible "caption" element atop the file (both
* images and video).
*/
alt?: string;
}
/**
@@ -98,15 +107,6 @@ export type ItemData = PhotoSwipeSlideData & {
* It is set while the thumbnail is loaded.
*/
isContentZoomable?: boolean;
/**
* The alt text associated with the file.
*
* This will be set to the file's caption. PhotoSwipe will use it as the alt
* text when constructing img elements (if any) for this item. We will also
* use this for displaying the visible "caption" element atop the file (both
* images and video).
*/
alt?: string;
/**
* This will be `true` if the fetch for the file's data has failed.
*
@@ -127,6 +127,19 @@ export type ItemData = PhotoSwipeSlideData & {
* This will be cleared on logout.
*/
class FileViewerDataSourceState {
/**
* Non-zero if a file viewer is currently open.
*
* This is a counter, but the file viewer data source has other many
* assumptions about only a single instance of PhotoSwipe being active at a
* time, so this could've been a boolean as well.
*/
viewerCount = 0;
/**
* True if our state needs to be cleared the next time the file viewer is
* closed.
*/
needsReset = false;
/**
* The best data we have for a particular file (ID).
*/
@@ -154,12 +167,59 @@ class FileViewerDataSourceState {
*/
let _state = new FileViewerDataSourceState();
const resetState = () => {
_state = new FileViewerDataSourceState();
};
/**
* Clear any internal state maintained by the file viewer data source.
*/
// TODO(PS): Call me during logout sequence once this is integrated.
export const logoutFileViewerDataSource = () => {
_state = new FileViewerDataSourceState();
export const logoutFileViewerDataSource = resetState;
/**
* Clear any internal state if possible. This is invoked when files have been
* updated on remote, and those changes synced locally.
*
* Because we also retain callbacks, clearing existing item data when the file
* viewer is open can lead to problematic edge cases. Thus, this function
* behaves in two different ways:
*
* - If the file viewer is already open, then we enqueue a reset for when it is
* closed the next time.
*
* - Otherwise we immediately reset our state.
*
* See: [Note: Changes to underlying files when file viewer is open]
*/
export const resetFileViewerDataSourceOnClose = () => {
if (_state.viewerCount) {
_state.needsReset = true;
} else {
resetState();
}
};
/**
* Called by the file viewer whenever it is opened.
*/
export const fileViewerWillOpen = () => {
_state.viewerCount++;
};
/**
* Called by the file viewer whenever it has been closed.
*/
export const fileViewerDidClose = () => {
_state.viewerCount--;
if (_state.needsReset && _state.viewerCount == 0) {
// Reset everything.
resetState();
} else {
// Selectively clear.
forgetFailedItems();
forgetExif();
}
};
/**
@@ -246,7 +306,7 @@ export const forgetFailedItemDataForFileID = (fileID: number) => {
* This is called when the user closes the file viewer so that we attempt a full
* retry when they reopen the viewer the next time.
*/
export const forgetFailedItems = () =>
const forgetFailedItems = () =>
[..._state.itemDataByFileID.keys()].forEach(forgetFailedItemDataForFileID);
const enqueueUpdates = async (file: EnteFile) => {
@@ -258,7 +318,12 @@ const enqueueUpdates = async (file: EnteFile) => {
// the visible caption).
const alt = fileCaption(file);
_state.itemDataByFileID.set(file.id, { ...itemData, fileType, fileID, alt });
_state.itemDataByFileID.set(file.id, {
...itemData,
fileType,
fileID,
alt,
});
_state.needsRefreshByFileID.get(file.id)?.();
};

View File

@@ -7,10 +7,10 @@ import type { EnteFile } from "@/media/file";
import { FileType } from "@/media/file-type";
import { t } from "i18next";
import {
forgetExif,
fileViewerDidClose,
fileViewerWillOpen,
forgetExifForItemData,
forgetFailedItemDataForFileID,
forgetFailedItems,
itemDataForFile,
updateFileInfoExifIfNeeded,
} from "./data-source";
@@ -58,10 +58,6 @@ export interface FileViewerFileAnnotation {
* and the edit action should therefore be shown for this file.
*/
isEditableImage: boolean;
/**
* The caption ("description") of the file (if any).
*/
caption: string | undefined;
}
export interface FileViewerPhotoSwipeDelegate {
@@ -464,8 +460,7 @@ export class FileViewerPhotoSwipe {
// completed.
pswp.on("destroy", () => {
this.clearAutoHideIntervalIfNeeded();
forgetFailedItems();
forgetExif();
fileViewerDidClose();
// Let our parent know that we have been closed.
onClose();
});
@@ -654,6 +649,9 @@ export class FileViewerPhotoSwipe {
return element;
});
// Let our data source know.
fileViewerWillOpen();
// Initializing PhotoSwipe adds it to the DOM as a dialog-like div with
// the class "pswp".
pswp.init();

View File

@@ -0,0 +1,7 @@
// TODO(PS): Temporary trampoline
export const resetFileViewerDataSourceOnClose = async () => {
if (!process.env.NEXT_PUBLIC_ENTE_WIP_PS5) return;
(
await import("@/gallery/components/viewer/data-source")
).resetFileViewerDataSourceOnClose();
};

View File

@@ -16,6 +16,7 @@ import dynamic from "next/dynamic";
const FV5 = dynamic(() => import("@/gallery/components/viewer/FileViewer"), {
ssr: false,
});
const FVD = () => <></>;
export const FileViewer: React.FC = (props) => {

View File

@@ -9,6 +9,7 @@ import { isMLSupported, mlStatusSync, mlSync } from "@/new/photos/services/ml";
import { searchDataSync } from "@/new/photos/services/search";
import { syncSettings } from "@/new/photos/services/settings";
import { splitByPredicate } from "@/utils/array";
import { resetFileViewerDataSourceOnClose } from "../components/FileViewerComponents-temp";
/**
* Part 1 of {@link sync}. See TODO below for why this is split.
@@ -62,17 +63,23 @@ export const syncFilesAndCollections = async () => {
allCollections,
isHiddenCollection,
);
await syncFiles(
const didUpdateNormalFiles = await syncFiles(
"normal",
normalCollections,
() => {},
() => {},
);
await syncFiles(
const didUpdateHiddenFiles = await syncFiles(
"hidden",
hiddenCollections,
() => {},
() => {},
);
await syncTrash(allCollections, () => {});
if (didUpdateNormalFiles || didUpdateHiddenFiles) {
// TODO:
// exportService.onLocalFilesUpdated();
// TODO(PS): Use direct one
await resetFileViewerDataSourceOnClose();
}
};