Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
CollectionSubType,
type Collection,
} from "ente-media/collection";
import type { EnteFile } from "ente-media/file";
import { ItemVisibility } from "ente-media/file-metadata";
import type { RemotePullOpts } from "ente-new/photos/components/gallery";
import {
Expand Down Expand Up @@ -94,6 +95,7 @@ export interface CollectionHeaderProps
> {
collectionSummary: CollectionSummary;
activeCollection: Collection | undefined;
files: EnteFile[];
setActiveCollectionID: (collectionID: number) => void;
isActiveCollectionDownloadInProgress: () => boolean;
/**
Expand Down Expand Up @@ -158,6 +160,7 @@ const shouldShowOptions = (type: CollectionSummaryType) =>
const CollectionHeaderOptions: React.FC<CollectionHeaderProps> = ({
activeCollection,
collectionSummary,
files,
setActiveCollectionID,
onRemotePull,
onCollectionShare,
Expand Down Expand Up @@ -789,6 +792,7 @@ const CollectionHeaderOptions: React.FC<CollectionHeaderProps> = ({
{...mapDialogVisibilityProps}
collectionSummary={collectionSummary}
activeCollection={activeCollection}
files={files}
onRemotePull={onRemotePull}
onAddSaveGroup={onAddSaveGroup}
onMarkTempDeleted={onMarkTempDeleted}
Expand Down
100 changes: 14 additions & 86 deletions web/apps/photos/src/components/Collections/CollectionMapDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import {
import type { RemotePullOpts } from "ente-new/photos/components/gallery";
import {
addToFavoritesCollection,
isArchivedCollection,
isHiddenCollection,
removeFromFavoritesCollection,
} from "ente-new/photos/services/collection";
import { type CollectionSummary } from "ente-new/photos/services/collection-summary";
Expand Down Expand Up @@ -74,6 +72,7 @@ interface CollectionMapDialogProps
> {
collectionSummary: CollectionSummary;
activeCollection: Collection | undefined;
files: EnteFile[];
onRemotePull?: (opts?: RemotePullOpts) => Promise<void>;
}

Expand Down Expand Up @@ -440,7 +439,7 @@ const getLatestFileIdFromPoints = (points: MapIndexPoint[]) =>
function useMapData(
open: boolean,
collectionSummary: CollectionSummary,
activeCollection: Collection | undefined,
files: EnteFile[],
onGenericError: (e: unknown) => void,
): MapDataResult {
const [state, setState] = useState<MapDataState>({
Expand All @@ -466,9 +465,9 @@ function useMapData(
// Include fileCount to detect when collection content changes
const loadedCollectionRef = useRef<{
summaryId: number;
collectionId: number | undefined;
fileCount: number;
updationTime: number | null;
files: EnteFile[];
} | null>(null);

//Syncing the refs with the state for the stale closure prevention.
Expand Down Expand Up @@ -569,7 +568,6 @@ function useMapData(

// Skip reload if we already have data for this collection with same file count
const currentSummaryId = collectionSummary.id;
const currentCollectionId = activeCollection?.id;
const currentFileCount = collectionSummary.fileCount;
const currentUpdationTime = collectionSummary.updationTime ?? null;
const loaded = loadedCollectionRef.current;
Expand All @@ -578,9 +576,9 @@ function useMapData(
if (
loaded &&
loaded.summaryId === currentSummaryId &&
loaded.collectionId === currentCollectionId &&
loaded.fileCount === currentFileCount &&
loaded.updationTime === currentUpdationTime
loaded.updationTime === currentUpdationTime &&
loaded.files === files
) {
return;
}
Expand All @@ -591,18 +589,17 @@ function useMapData(
setState((prev) => ({ ...prev, isLoading: true, error: null }));

try {
const files = await getFilesForCollection(
collectionSummary,
activeCollection,
);
const uniqueFiles = uniqueFilesByID(files);

//Creating a id <- file mapping to drive renders and update the UI, changes to this will result in UI re-renders
const filesByID = new Map(files.map((file) => [file.id, file]));
const filesByID = new Map(
uniqueFiles.map((file) => [file.id, file]),
);
//ref mirrow for using in the useCallbacks
filesByIDRef.current = filesByID;

const { points, latestFileId } =
await buildMapIndexPoints(files);
await buildMapIndexPoints(uniqueFiles);

//mapIndex has the SuperCluster Spatial Index
const mapIndex = buildMapIndex(points);
Expand All @@ -628,9 +625,9 @@ function useMapData(
// Mark this collection as loaded
loadedCollectionRef.current = {
summaryId: currentSummaryId,
collectionId: currentCollectionId,
fileCount: currentFileCount,
updationTime: currentUpdationTime,
files,
};

const coverId = collectionSummary.coverFile?.id ?? latestFileId;
Expand All @@ -655,13 +652,7 @@ function useMapData(
};

void loadMapData();
}, [
open,
collectionSummary,
activeCollection,
onGenericError,
queueThumbnailFetch,
]);
}, [open, collectionSummary, files, onGenericError, queueThumbnailFetch]);

/**
* This function is used to update the map view, after a file has been
Expand Down Expand Up @@ -1131,70 +1122,6 @@ function createClusterIcon(
// Helper Functions
// ============================================================================

/**
* Returns true if the file is visible (not archived or hidden).
*/
function isFileVisible(file: EnteFile): boolean {
const visibility = file.magicMetadata?.data.visibility;
// Files without visibility metadata are considered visible (default state)
return visibility === undefined || visibility === ItemVisibility.visible;
}

/**
* Loads every locally stored file, filters those belonging to the
* target collection, removes duplicates by ID, filters out hidden/archived
* files, and returns the unique set of visible files. For "All", it also
* excludes files that belong to hidden or archived collections.
*/
async function getFilesForCollection(
collectionSummary: CollectionSummary,
activeCollection: Collection | undefined,
): Promise<EnteFile[]> {
if (collectionSummary.type === "all") {
const [allFiles, collections] = await Promise.all([
savedCollectionFiles(),
savedCollections(),
]);
// Filter out hidden and archived files to prevent leaking items users expect to remain hidden.
const visibleFiles = allFiles.filter(isFileVisible);
const hiddenCollectionIDs = new Set(
collections
.filter(isHiddenCollection)
.map((collection) => collection.id),
);
const archivedCollectionIDs = new Set(
collections
.filter(isArchivedCollection)
.map((collection) => collection.id),
);
const hiddenFileIDs = new Set(
allFiles
.filter((file) => hiddenCollectionIDs.has(file.collectionID))
.map((file) => file.id),
);
const archivedFileIDs = new Set(
allFiles
.filter((file) => archivedCollectionIDs.has(file.collectionID))
.map((file) => file.id),
);
const filtered = visibleFiles.filter(
(file) =>
!hiddenFileIDs.has(file.id) && !archivedFileIDs.has(file.id),
);
return uniqueFilesByID(filtered);
}
const allFiles = await savedCollectionFiles();
// Filter out hidden and archived files to prevent leaking items users expect to remain hidden.
const visibleFiles = allFiles.filter(isFileVisible);
if (!activeCollection) {
return [];
}
const filtered = visibleFiles.filter(
(file) => file.collectionID === activeCollection.id,
);
return uniqueFilesByID(filtered);
}

// ============================================================================
// Main Component
// ============================================================================
Expand All @@ -1208,6 +1135,7 @@ export const CollectionMapDialog: React.FC<CollectionMapDialogProps> = ({
onClose,
collectionSummary,
activeCollection,
files,
onRemotePull,
onAddSaveGroup,
onMarkTempDeleted,
Expand Down Expand Up @@ -1237,7 +1165,7 @@ export const CollectionMapDialog: React.FC<CollectionMapDialogProps> = ({
removeFiles: removeFilesFromMap,
updateFileVisibility,
queueThumbnailFetch,
} = useMapData(open, collectionSummary, activeCollection, onGenericError);
} = useMapData(open, collectionSummary, files, onGenericError);

const {
visiblePhotos,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type GalleryBarAndListHeaderProps = Omit<
saveGroups: SaveGroup[];
} & Pick<
CollectionHeaderProps,
| "files"
| "onRemotePull"
| "onAddSaveGroup"
| "onMarkTempDeleted"
Expand Down Expand Up @@ -115,6 +116,7 @@ export const GalleryBarAndListHeader: React.FC<
setBlockingLoad,
people,
saveGroups,
files,
activePerson,
emailByUserID,
shareSuggestionEmails,
Expand Down Expand Up @@ -210,6 +212,7 @@ export const GalleryBarAndListHeader: React.FC<
<CollectionHeader
{...{
activeCollection,
files,
setActiveCollectionID,
isActiveCollectionDownloadInProgress,
onRemotePull,
Expand Down Expand Up @@ -255,6 +258,7 @@ export const GalleryBarAndListHeader: React.FC<
activeCollection,
activeCollectionID,
isActiveCollectionDownloadInProgress,
files,
activePerson,
showCollectionShare,
openCollectionShare,
Expand Down
1 change: 1 addition & 0 deletions web/apps/photos/src/components/FileListWithViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ export const FileListWithViewer: React.FC<FileListWithViewerProps> = ({
{...mapDialogVisibilityProps}
collectionSummary={activeCollectionSummary}
activeCollection={activeCollection}
files={files}
onRemotePull={onRemotePull}
{...{
onAddSaveGroup,
Expand Down
3 changes: 3 additions & 0 deletions web/apps/photos/src/pages/gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,9 @@ const Page: React.FC = () => {
// component need to be updated.
activeCollection: activeCollection!,
activeCollectionID: activeCollectionID!,
files: activeCollection
? activeCollectionFiles
: filteredFiles,
activePerson,
setFileListHeader,
saveGroups,
Expand Down
Loading