From 34621dd00fb77484bdcfd7d87c177a3570cb083b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Mon, 19 May 2025 17:58:40 +0530 Subject: [PATCH] notes --- .../Collections/CollectionHeader.tsx | 4 +- web/packages/media/collection.ts | 54 ++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/web/apps/photos/src/components/Collections/CollectionHeader.tsx b/web/apps/photos/src/components/Collections/CollectionHeader.tsx index 456ed16038..aa85534a57 100644 --- a/web/apps/photos/src/components/Collections/CollectionHeader.tsx +++ b/web/apps/photos/src/components/Collections/CollectionHeader.tsx @@ -582,9 +582,9 @@ const EmptyTrashQuickOption: React.FC = ({ onClick }) => ( ); const showDownloadQuickOption = (type: CollectionSummaryType) => + type == "album" || type == "folder" || type == "favorites" || - type == "album" || type == "uncategorized" || type == "hiddenItems" || type == "incomingShareViewer" || @@ -620,10 +620,10 @@ const DownloadQuickOption: React.FC = ({ ); const showShareQuickOption = (type: CollectionSummaryType) => + type == "album" || type == "folder" || (type == "favorites" && /* TODO(FAV): */ settingsSnapshot().isInternalUser) || - type == "album" || type == "outgoingShare" || type == "sharedOnlyViaLink" || type == "archived" || diff --git a/web/packages/media/collection.ts b/web/packages/media/collection.ts index cf078880db..03469265e1 100644 --- a/web/packages/media/collection.ts +++ b/web/packages/media/collection.ts @@ -6,10 +6,55 @@ import { ItemVisibility } from "ente-media/file-metadata"; // TODO: Audit this file -export type CollectionType = "folder" | "favorites" | "album" | "uncategorized"; +/** + * The type of a collection. + * + * - "album" - A regular "Ente Album" that the user sees in their library. + * + * - "folder" - An Ente Album that is also associated with an OS album on the + * user's mobile device. + * + * A collection of type "folder" is created by the mobile app if there is an + * associated on-device album for the new Ente album being created. + * + * The web/desktop app does not create collections of type "folder", and + * otherwise treats them as aliases for "album". + * + * - "favorites" - A special collection consisting of the items that the user + * has marked as their favorites. + * + * The user can have at most one collection of type "favorites" (enforced at + * remote). This collection is created on demand by the client where the user + * first marks an item as a favorite. The user can choose to share their + * "favorites" with other users, so it is possible for there to be multiple + * collections of type "favorites" present in our local database, however only + * one of those will belong to the logged in user (cf `owner.id`). + * + * - "uncategorized" - A special collection consisting of items that do not + * belong to any other collection. + * + * In the remote schema, each item ({@link EnteFile}) is always associated + * with a collection. The same item may belong to multiple collections (See: + * [Note: Collection File]), but it must belong to at least one collection. + * + * In some scenarios, e.g. when deleting the last collection to which a file + * belongs, the file would thus get orphaned and violate the schema + * invariants. So in such cases, the client which is performing the + * corresponding operation moves the file to the user's special + * "uncategorized" collection, creating it if needed. + * + * Similar to "favorites", the user can have only one "uncategorized" + * collection. However, unlike "favorites", the "uncategorized" collection + * cannot be shared. + */ +export type CollectionType = "album" | "folder" | "favorites" | "uncategorized"; export type CollectionRole = "VIEWER" | "OWNER" | "COLLABORATOR" | "UNKNOWN"; +/** + * Information about the user associated with a collection, either as an owner, + * or as someone with whom the collection has been shared with. + */ export interface CollectionUser { id: number; email: string; @@ -25,6 +70,13 @@ export interface EncryptedCollection { * all collections on an Ente instance (i.e., it is not scoped to a user). */ id: number; + /** + * Information about the user who owns the collection. + * + * Each collection is owned by exactly one user. The owner may optionally + * choose to share it with additional users, granting them varying level of + * privileges. + */ owner: CollectionUser; // collection name was unencrypted in the past, so we need to keep it as optional name?: string;