This commit is contained in:
Manav Rathi
2025-06-17 15:17:36 +05:30
parent e8e0ff63fc
commit 8b7e630bed
4 changed files with 100 additions and 73 deletions

View File

@@ -72,6 +72,8 @@ import { usePeopleStateSnapshot } from "ente-new/photos/components/utils/use-sna
import { shouldShowWhatsNew } from "ente-new/photos/services/changelog";
import {
ALL_SECTION,
createAlbum,
createUncategorizedCollection,
DUMMY_UNCATEGORIZED_COLLECTION,
} from "ente-new/photos/services/collection";
import { areOnlySystemCollections } from "ente-new/photos/services/collection/ui";
@@ -114,8 +116,6 @@ import { FileWithPath } from "react-dropzone";
import { Trans } from "react-i18next";
import {
addToFavorites,
createAlbum,
createUnCategorizedCollection,
removeFromFavorites,
} from "services/collectionService";
import { uploadManager } from "services/upload-manager";
@@ -1342,7 +1342,7 @@ const findCollectionCreatingUncategorizedIfNeeded = async (
collectionID: number,
) => {
if (collectionID == DUMMY_UNCATEGORIZED_COLLECTION) {
return await createUnCategorizedCollection();
return await createUncategorizedCollection();
} else {
return collections.find((c) => c.id === collectionID);
}

View File

@@ -2,17 +2,13 @@ import type { User } from "ente-accounts/services/user";
import { ensureLocalUser } from "ente-accounts/services/user";
import log from "ente-base/log";
import { apiURL } from "ente-base/origins";
import {
Collection,
CollectionPrivateMagicMetadataData,
CollectionSubType,
type CollectionType,
} from "ente-media/collection";
import { Collection } from "ente-media/collection";
import { EnteFile } from "ente-media/file";
import { ItemVisibility } from "ente-media/file-metadata";
import {
addToCollection,
createCollection2,
createDefaultHiddenCollection,
createFavoritesCollection,
createUncategorizedCollection,
isDefaultHiddenCollection,
moveToCollection,
} from "ente-new/photos/services/collection";
@@ -33,25 +29,8 @@ import { getToken } from "ente-shared/storage/localStorage/helpers";
import { batch } from "ente-utils/array";
import { isValidMoveTarget } from "utils/collection";
const uncategorizedCollectionName = "Uncategorized";
const defaultHiddenCollectionName = ".hidden";
const favoritesCollectionName = "Favorites";
const REQUEST_BATCH_SIZE = 1000;
export const createAlbum = (albumName: string) =>
createCollection(albumName, "album");
const createCollection = async (
collectionName: string,
type: CollectionType,
magicMetadataProps?: CollectionPrivateMagicMetadataData,
): Promise<Collection> =>
createCollection2(collectionName, type, magicMetadataProps);
export const createFavoritesCollection = () =>
createCollection(favoritesCollectionName, "favorites");
export const addToFavorites = async (
file: EnteFile,
disableOldWorkaround?: boolean,
@@ -179,7 +158,7 @@ export const removeUserFiles = async (
}
let uncategorizedCollection = await getUncategorizedCollection();
if (!uncategorizedCollection) {
uncategorizedCollection = await createUnCategorizedCollection();
uncategorizedCollection = await createUncategorizedCollection();
}
await moveToCollection(
sourceCollectionID,
@@ -320,9 +299,6 @@ export async function getUncategorizedCollection(
return uncategorizedCollection;
}
export const createUnCategorizedCollection = () =>
createCollection(uncategorizedCollectionName, "uncategorized");
export async function getDefaultHiddenCollection(): Promise<Collection> {
const collections = await getLocalCollections("hidden");
const hiddenCollection = collections.find((collection) =>
@@ -332,12 +308,6 @@ export async function getDefaultHiddenCollection(): Promise<Collection> {
return hiddenCollection;
}
const createDefaultHiddenCollection = () =>
createCollection(defaultHiddenCollectionName, "album", {
subType: CollectionSubType.defaultHidden,
visibility: ItemVisibility.hidden,
});
export async function moveToHiddenCollection(files: EnteFile[]) {
try {
let hiddenCollection = await getDefaultHiddenCollection();

View File

@@ -13,6 +13,7 @@ import {
isIncomingShare,
moveToCollection,
restoreToCollection,
createAlbum,
} from "ente-new/photos/services/collection";
import {
getAllLocalCollections,
@@ -25,7 +26,6 @@ import {
import { safeDirectoryName } from "ente-new/photos/utils/native-fs";
import { getData } from "ente-shared/storage/localStorage";
import {
createAlbum,
removeFromCollection,
unhideToCollection,
} from "services/collectionService";

View File

@@ -45,45 +45,16 @@ import { ensureUserKeyPair, getPublicKey } from "./user";
*/
const requestBatchSize = 1000;
const uncategorizedCollectionName = "Uncategorized";
const defaultHiddenCollectionName = ".hidden";
const favoritesCollectionName = "Favorites";
export const ARCHIVE_SECTION = -1;
export const TRASH_SECTION = -2;
export const DUMMY_UNCATEGORIZED_COLLECTION = -3;
export const HIDDEN_ITEMS_SECTION = -4;
export const ALL_SECTION = 0;
/**
* Return true if this is a default hidden collection.
*
* See also: [Note: Multiple "default" hidden collections].
*/
export const isDefaultHiddenCollection = (collection: Collection) =>
collection.magicMetadata?.data.subType == CollectionSubType.defaultHidden;
/**
* Extract the IDs of all the "default" hidden collections.
*
* [Note: Multiple "default" hidden collections].
*
* Normally, there is only expected to be one such collection. But to provide
* clients laxity in synchronization, we don't enforce this and instead allow
* for multiple such default hidden collections to exist.
*/
export const findDefaultHiddenCollectionIDs = (collections: Collection[]) =>
new Set<number>(
collections
.filter(isDefaultHiddenCollection)
.map((collection) => collection.id),
);
/**
* Return true if this is a collection that the user doesn't own.
*/
export const isIncomingShare = (collection: Collection, user: User) =>
collection.owner.id !== user.id;
export const isHiddenCollection = (collection: Collection) =>
collection.magicMetadata?.data.visibility === ItemVisibility.hidden;
export const DEFAULT_HIDDEN_COLLECTION_USER_FACING_NAME = "Hidden";
/**
@@ -99,6 +70,17 @@ export const getCollectionUserFacingName = (collection: Collection) => {
return collection.name;
};
/**
* Create a new album (a collection of type "album") on remote, and return its
* local representation.
*
* Remote only, does not modify local state.
*
* @param albumName The name to use for the new album.
*/
export const createAlbum = (albumName: string) =>
createCollection(albumName, "album");
/**
* Create a new collection on remote, and return its local representation.
*
@@ -111,7 +93,7 @@ export const getCollectionUserFacingName = (collection: Collection) => {
* @param magicMetadataData Optional metadata to use as the collection's private
* mutable metadata when creating the new collection.
*/
export const createCollection2 = async (
const createCollection = async (
name: string,
type: CollectionType,
magicMetadataData?: CollectionPrivateMagicMetadataData,
@@ -708,6 +690,81 @@ const putCollectionsShareeMagicMetadata = async (
}),
);
/**
* Create a new collection of type "favorites" for the user on remote, and
* return its local representation.
*
* Remote only, does not modify local state.
*
* Each user can have at most one collection of type "favorites" owned by them.
* While this function does not enforce the constraint locally, it will fail
* because remote will enforce the constraint and fail the request when we
* attempt to create a second collection of type "favorites".
*/
export const createFavoritesCollection = () =>
createCollection(favoritesCollectionName, "favorites");
/**
* Create a new collection of type "uncategorized" for the user on remote, and
* return its local representation.
*
* Remote only, does not modify local state.
*
* Each user can have at most one collection of type "uncategorized" owned by
* them. While this function does not enforce the constraint locally, it will
* fail because remote will enforce the constraint and fail the request when we
* attempt to create a second collection of type "uncategorized".
*/
export const createUncategorizedCollection = () =>
createCollection(uncategorizedCollectionName, "uncategorized");
/**
* Create a new collection with hidden visibility on remote, marking it as the
* default hidden collection, and return its local representation.
*
* Remote only, does not modify local state.
*
* See also: [Note: Multiple "default" hidden collections].
*/
export const createDefaultHiddenCollection = () =>
createCollection(defaultHiddenCollectionName, "album", {
subType: CollectionSubType.defaultHidden,
visibility: ItemVisibility.hidden,
});
/**
* Return true if the provided collection is the default hidden collection.
*
* See also: [Note: Multiple "default" hidden collections].
*/
export const isDefaultHiddenCollection = (collection: Collection) =>
collection.magicMetadata?.data.subType == CollectionSubType.defaultHidden;
/**
* Extract the IDs of all the "default" hidden collections.
*
* [Note: Multiple "default" hidden collections].
*
* Normally, there is only expected to be one such collection. But to provide
* clients laxity in synchronization, we don't enforce this and instead allow
* for multiple such default hidden collections to exist.
*/
export const findDefaultHiddenCollectionIDs = (collections: Collection[]) =>
new Set<number>(
collections
.filter(isDefaultHiddenCollection)
.map((collection) => collection.id),
);
/**
* Return true if this is a collection that the user doesn't own.
*/
export const isIncomingShare = (collection: Collection, user: User) =>
collection.owner.id !== user.id;
export const isHiddenCollection = (collection: Collection) =>
collection.magicMetadata?.data.visibility === ItemVisibility.hidden;
/**
* Share the provided collection with another Ente user.
*