Remove unused code
This commit is contained in:
@@ -6,13 +6,10 @@ import log from "@/next/log";
|
||||
import { shuffled } from "@/utils/array";
|
||||
import { ensure, ensureString } from "@/utils/ensure";
|
||||
import ComlinkCryptoWorker from "@ente/shared/crypto";
|
||||
import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
|
||||
import HTTPService from "@ente/shared/network/HTTPService";
|
||||
import { getCastFileURL, getEndpoint } from "@ente/shared/network/api";
|
||||
import localForage from "@ente/shared/storage/localForage";
|
||||
import { wait } from "@ente/shared/utils";
|
||||
import { detectMediaMIMEType } from "services/detect-type";
|
||||
import { Collection, CollectionPublicMagicMetadata } from "types/collection";
|
||||
import {
|
||||
EncryptedEnteFile,
|
||||
EnteFile,
|
||||
@@ -20,13 +17,6 @@ import {
|
||||
FilePublicMagicMetadata,
|
||||
} from "types/file";
|
||||
|
||||
export interface SavedCollectionFiles {
|
||||
collectionLocalID: string;
|
||||
files: EnteFile[];
|
||||
}
|
||||
|
||||
const COLLECTION_FILES_TABLE = "collection-files";
|
||||
|
||||
/**
|
||||
* Save the data received after pairing with a sender into local storage.
|
||||
*
|
||||
@@ -128,8 +118,6 @@ export const renderableImageURLs = async function* (castData: CastData) {
|
||||
lastYieldTime += 7500; /* 7.5 s */
|
||||
|
||||
while (true) {
|
||||
const collection = await getCastCollection(castToken, collectionKey);
|
||||
await syncPublicFiles(castToken, collection, () => {});
|
||||
const encryptedFiles = shuffled(
|
||||
await getEncryptedCollectionFiles(castToken),
|
||||
);
|
||||
@@ -173,47 +161,6 @@ export const renderableImageURLs = async function* (castData: CastData) {
|
||||
}
|
||||
};
|
||||
|
||||
const getCastCollection = async (
|
||||
castToken: string,
|
||||
collectionKey: string,
|
||||
): Promise<Collection> => {
|
||||
const resp = await HTTPService.get(`${getEndpoint()}/cast/info`, null, {
|
||||
"Cache-Control": "no-cache",
|
||||
"X-Cast-Access-Token": castToken,
|
||||
});
|
||||
|
||||
const collection = resp.data.collection;
|
||||
|
||||
const cryptoWorker = await ComlinkCryptoWorker.getInstance();
|
||||
|
||||
const collectionName =
|
||||
collection.name ||
|
||||
(await cryptoWorker.decryptToUTF8(
|
||||
collection.encryptedName,
|
||||
collection.nameDecryptionNonce,
|
||||
collectionKey,
|
||||
));
|
||||
|
||||
let collectionPublicMagicMetadata: CollectionPublicMagicMetadata;
|
||||
if (collection.pubMagicMetadata?.data) {
|
||||
collectionPublicMagicMetadata = {
|
||||
...collection.pubMagicMetadata,
|
||||
data: await cryptoWorker.decryptMetadata(
|
||||
collection.pubMagicMetadata.data,
|
||||
collection.pubMagicMetadata.header,
|
||||
collectionKey,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...collection,
|
||||
name: collectionName,
|
||||
key: collectionKey,
|
||||
pubMagicMetadata: collectionPublicMagicMetadata,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the list of non-deleted files in the given collection.
|
||||
*
|
||||
@@ -309,253 +256,6 @@ const decryptEnteFile = async (
|
||||
return file;
|
||||
};
|
||||
|
||||
const syncPublicFiles = async (
|
||||
castToken: string,
|
||||
collection: Collection,
|
||||
setPublicFiles: (files: EnteFile[]) => void,
|
||||
) => {
|
||||
let files: EnteFile[] = [];
|
||||
const sortAsc = collection?.pubMagicMetadata?.data.asc ?? false;
|
||||
const collectionUID = String(collection.id);
|
||||
const localFiles = await getLocalFiles(collectionUID);
|
||||
files = [...files, ...localFiles];
|
||||
try {
|
||||
const lastSyncTime = await getSyncTime(collectionUID);
|
||||
if (collection.updationTime === lastSyncTime) {
|
||||
return sortFiles(files, sortAsc);
|
||||
}
|
||||
const fetchedFiles = await fetchFiles(
|
||||
castToken,
|
||||
collection,
|
||||
lastSyncTime,
|
||||
files,
|
||||
setPublicFiles,
|
||||
);
|
||||
|
||||
files = [...files, ...fetchedFiles];
|
||||
const latestVersionFiles = new Map<string, EnteFile>();
|
||||
files.forEach((file) => {
|
||||
const uid = `${file.collectionID}-${file.id}`;
|
||||
if (
|
||||
!latestVersionFiles.has(uid) ||
|
||||
latestVersionFiles.get(uid).updationTime < file.updationTime
|
||||
) {
|
||||
latestVersionFiles.set(uid, file);
|
||||
}
|
||||
});
|
||||
files = [];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const [_, file] of latestVersionFiles) {
|
||||
if (file.isDeleted) {
|
||||
continue;
|
||||
}
|
||||
files.push(file);
|
||||
}
|
||||
await savecollectionFiles(collectionUID, files);
|
||||
await updateSyncTime(collectionUID, collection.updationTime);
|
||||
setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
|
||||
} catch (e) {
|
||||
const parsedError = parseSharingErrorCodes(e);
|
||||
log.error("failed to sync shared collection files", e);
|
||||
if (parsedError.message === CustomError.TOKEN_EXPIRED) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return [...sortFiles(mergeMetadata(files), sortAsc)];
|
||||
};
|
||||
|
||||
const getLastSyncKey = (collectionUID: string) => `${collectionUID}-time`;
|
||||
|
||||
export const getLocalFiles = async (
|
||||
collectionUID: string,
|
||||
): Promise<EnteFile[]> => {
|
||||
const localSavedcollectionFiles =
|
||||
(await localForage.getItem<SavedCollectionFiles[]>(
|
||||
COLLECTION_FILES_TABLE,
|
||||
)) || [];
|
||||
const matchedCollection = localSavedcollectionFiles.find(
|
||||
(item) => item.collectionLocalID === collectionUID,
|
||||
);
|
||||
return matchedCollection?.files || [];
|
||||
};
|
||||
|
||||
const savecollectionFiles = async (
|
||||
collectionUID: string,
|
||||
files: EnteFile[],
|
||||
) => {
|
||||
const collectionFiles =
|
||||
(await localForage.getItem<SavedCollectionFiles[]>(
|
||||
COLLECTION_FILES_TABLE,
|
||||
)) || [];
|
||||
await localForage.setItem(
|
||||
COLLECTION_FILES_TABLE,
|
||||
dedupeCollectionFiles([
|
||||
{ collectionLocalID: collectionUID, files },
|
||||
...collectionFiles,
|
||||
]),
|
||||
);
|
||||
};
|
||||
|
||||
const dedupeCollectionFiles = (collectionFiles: SavedCollectionFiles[]) => {
|
||||
const keySet = new Set([]);
|
||||
return collectionFiles.filter(({ collectionLocalID: collectionUID }) => {
|
||||
if (!keySet.has(collectionUID)) {
|
||||
keySet.add(collectionUID);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async function getSyncTime(collectionUID: string): Promise<number> {
|
||||
const lastSyncKey = getLastSyncKey(collectionUID);
|
||||
const lastSyncTime = await localForage.getItem<number>(lastSyncKey);
|
||||
return lastSyncTime ?? 0;
|
||||
}
|
||||
|
||||
const updateSyncTime = async (collectionUID: string, time: number) =>
|
||||
await localForage.setItem(getLastSyncKey(collectionUID), time);
|
||||
|
||||
const fetchFiles = async (
|
||||
castToken: string,
|
||||
collection: Collection,
|
||||
sinceTime: number,
|
||||
files: EnteFile[],
|
||||
setPublicFiles: (files: EnteFile[]) => void,
|
||||
): Promise<EnteFile[]> => {
|
||||
const sortAsc = collection?.pubMagicMetadata?.data.asc ?? false;
|
||||
let decryptedFiles: EnteFile[] = [];
|
||||
let time = sinceTime;
|
||||
let resp;
|
||||
do {
|
||||
resp = await HTTPService.get(
|
||||
`${getEndpoint()}/cast/diff`,
|
||||
{
|
||||
sinceTime: time,
|
||||
},
|
||||
{
|
||||
"Cache-Control": "no-cache",
|
||||
"X-Cast-Access-Token": castToken,
|
||||
},
|
||||
);
|
||||
decryptedFiles = [
|
||||
...decryptedFiles,
|
||||
...(await Promise.all(
|
||||
resp.data.diff.map(async (file: EncryptedEnteFile) => {
|
||||
if (!file.isDeleted) {
|
||||
return await decryptFile(file, collection.key);
|
||||
} else {
|
||||
return file;
|
||||
}
|
||||
}) as Promise<EnteFile>[],
|
||||
)),
|
||||
];
|
||||
|
||||
if (resp.data.diff.length) {
|
||||
time = resp.data.diff.slice(-1)[0].updationTime;
|
||||
}
|
||||
setPublicFiles(
|
||||
sortFiles(
|
||||
mergeMetadata(
|
||||
[...(files || []), ...decryptedFiles].filter(
|
||||
(item) => !item.isDeleted,
|
||||
),
|
||||
),
|
||||
sortAsc,
|
||||
),
|
||||
);
|
||||
} while (resp.data.hasMore);
|
||||
return decryptedFiles;
|
||||
};
|
||||
|
||||
export function sortFiles(files: EnteFile[], sortAsc = false) {
|
||||
// sort based on the time of creation time of the file,
|
||||
// for files with same creation time, sort based on the time of last modification
|
||||
const factor = sortAsc ? -1 : 1;
|
||||
return files.sort((a, b) => {
|
||||
if (a.metadata.creationTime === b.metadata.creationTime) {
|
||||
return (
|
||||
factor *
|
||||
(b.metadata.modificationTime - a.metadata.modificationTime)
|
||||
);
|
||||
}
|
||||
return factor * (b.metadata.creationTime - a.metadata.creationTime);
|
||||
});
|
||||
}
|
||||
|
||||
export async function decryptFile(
|
||||
file: EncryptedEnteFile,
|
||||
collectionKey: string,
|
||||
): Promise<EnteFile> {
|
||||
try {
|
||||
const worker = await ComlinkCryptoWorker.getInstance();
|
||||
const {
|
||||
encryptedKey,
|
||||
keyDecryptionNonce,
|
||||
metadata,
|
||||
magicMetadata,
|
||||
pubMagicMetadata,
|
||||
...restFileProps
|
||||
} = file;
|
||||
const fileKey = await worker.decryptB64(
|
||||
encryptedKey,
|
||||
keyDecryptionNonce,
|
||||
collectionKey,
|
||||
);
|
||||
const fileMetadata = await worker.decryptMetadata(
|
||||
metadata.encryptedData,
|
||||
metadata.decryptionHeader,
|
||||
fileKey,
|
||||
);
|
||||
let fileMagicMetadata: FileMagicMetadata;
|
||||
let filePubMagicMetadata: FilePublicMagicMetadata;
|
||||
if (magicMetadata?.data) {
|
||||
fileMagicMetadata = {
|
||||
...file.magicMetadata,
|
||||
data: await worker.decryptMetadata(
|
||||
magicMetadata.data,
|
||||
magicMetadata.header,
|
||||
fileKey,
|
||||
),
|
||||
};
|
||||
}
|
||||
if (pubMagicMetadata?.data) {
|
||||
filePubMagicMetadata = {
|
||||
...pubMagicMetadata,
|
||||
data: await worker.decryptMetadata(
|
||||
pubMagicMetadata.data,
|
||||
pubMagicMetadata.header,
|
||||
fileKey,
|
||||
),
|
||||
};
|
||||
}
|
||||
return {
|
||||
...restFileProps,
|
||||
key: fileKey,
|
||||
metadata: fileMetadata,
|
||||
magicMetadata: fileMagicMetadata,
|
||||
pubMagicMetadata: filePubMagicMetadata,
|
||||
};
|
||||
} catch (e) {
|
||||
log.error("file decryption failed", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
export function mergeMetadata(files: EnteFile[]): EnteFile[] {
|
||||
return files.map((file) => {
|
||||
if (file.pubMagicMetadata?.data.editedTime) {
|
||||
file.metadata.creationTime = file.pubMagicMetadata.data.editedTime;
|
||||
}
|
||||
if (file.pubMagicMetadata?.data.editedName) {
|
||||
file.metadata.title = file.pubMagicMetadata.data.editedName;
|
||||
}
|
||||
|
||||
return file;
|
||||
});
|
||||
}
|
||||
|
||||
const isFileEligibleForCast = (file: EnteFile) => {
|
||||
if (!isImageOrLivePhoto(file)) return false;
|
||||
if (file.info.fileSize > 100 * 1024 * 1024) return false;
|
||||
|
||||
Reference in New Issue
Block a user