Remove unused fix-large-thumbnail feature

This was disabled years ago. Specifically removing this now to reduce the amount
of work in removing bootstrap.
This commit is contained in:
Manav Rathi 2024-03-31 18:06:43 +05:30
parent e5edeae370
commit 1d02fe4f32
No known key found for this signature in database
4 changed files with 9 additions and 387 deletions

View file

@ -1,235 +0,0 @@
import DialogBox from "@ente/shared/components/DialogBox/";
import { logError } from "@ente/shared/sentry";
import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
import { t } from "i18next";
import React, { useEffect, useState } from "react";
import { Button, ProgressBar } from "react-bootstrap";
import {
getLargeThumbnailFiles,
replaceThumbnail,
} from "services/migrateThumbnailService";
import { ComfySpan } from "./ExportInProgress";
export type SetProgressTracker = React.Dispatch<
React.SetStateAction<{
current: number;
total: number;
}>
>;
interface Props {
isOpen: boolean;
show: () => void;
hide: () => void;
}
export enum FIX_STATE {
NOT_STARTED,
FIX_LATER,
NOOP,
RUNNING,
COMPLETED,
COMPLETED_WITH_ERRORS,
}
function Message({ fixState }: { fixState: FIX_STATE }) {
let message = null;
switch (fixState) {
case FIX_STATE.NOT_STARTED:
case FIX_STATE.FIX_LATER:
message = t("REPLACE_THUMBNAIL_NOT_STARTED");
break;
case FIX_STATE.COMPLETED:
message = t("REPLACE_THUMBNAIL_COMPLETED");
break;
case FIX_STATE.NOOP:
message = t("REPLACE_THUMBNAIL_NOOP");
break;
case FIX_STATE.COMPLETED_WITH_ERRORS:
message = t("REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR");
break;
}
return message ? (
<div style={{ marginBottom: "30px" }}>{message}</div>
) : (
<></>
);
}
export default function FixLargeThumbnails(props: Props) {
const [fixState, setFixState] = useState(FIX_STATE.NOT_STARTED);
const [progressTracker, setProgressTracker] = useState({
current: 0,
total: 0,
});
const [largeThumbnailFiles, setLargeThumbnailFiles] = useState<number[]>(
[],
);
const init = (): FIX_STATE => {
let fixState = getData(LS_KEYS.THUMBNAIL_FIX_STATE)?.state;
if (!fixState || fixState === FIX_STATE.RUNNING) {
fixState = FIX_STATE.NOT_STARTED;
updateFixState(fixState);
}
if (fixState === FIX_STATE.COMPLETED) {
fixState = FIX_STATE.NOOP;
updateFixState(fixState);
}
setFixState(fixState);
return fixState;
};
const fetchLargeThumbnail = async () => {
const largeThumbnailFiles = (await getLargeThumbnailFiles()) ?? [];
setLargeThumbnailFiles(largeThumbnailFiles);
return largeThumbnailFiles;
};
const main = async () => {
const largeThumbnailFiles = await fetchLargeThumbnail();
if (
fixState === FIX_STATE.NOT_STARTED &&
largeThumbnailFiles.length > 0
) {
props.show();
}
if (
(fixState === FIX_STATE.COMPLETED || fixState === FIX_STATE.NOOP) &&
largeThumbnailFiles.length > 0
) {
updateFixState(FIX_STATE.NOT_STARTED);
logError(Error(), "large thumbnail files left after migration");
}
if (largeThumbnailFiles.length === 0 && fixState !== FIX_STATE.NOOP) {
updateFixState(FIX_STATE.NOOP);
}
};
useEffect(() => {
if (props.isOpen && fixState !== FIX_STATE.RUNNING) {
main();
}
}, [props.isOpen]);
useEffect(() => {
const fixState = init();
if (fixState === FIX_STATE.NOT_STARTED) {
main();
}
}, []);
const startFix = async (newlyFetchedLargeThumbnailFiles?: number[]) => {
updateFixState(FIX_STATE.RUNNING);
const completedWithError = await replaceThumbnail(
setProgressTracker,
new Set(
newlyFetchedLargeThumbnailFiles ?? largeThumbnailFiles ?? [],
),
);
if (typeof completedWithError !== "undefined") {
updateFixState(
completedWithError
? FIX_STATE.COMPLETED_WITH_ERRORS
: FIX_STATE.COMPLETED,
);
}
await fetchLargeThumbnail();
};
const updateFixState = (fixState: FIX_STATE) => {
setFixState(fixState);
setData(LS_KEYS.THUMBNAIL_FIX_STATE, { state: fixState });
};
return (
<DialogBox
open={props.isOpen}
onClose={props.hide}
attributes={{
title: t("COMPRESS_THUMBNAILS"),
}}
>
<div
style={{
marginBottom: "20px",
padding: "0 5%",
display: "flex",
alignItems: "center",
flexDirection: "column",
}}
>
<Message fixState={fixState} />
{fixState === FIX_STATE.RUNNING && (
<>
<div style={{ marginBottom: "10px" }}>
<ComfySpan>
{" "}
{progressTracker.current} /{" "}
{progressTracker.total}{" "}
</ComfySpan>{" "}
<span style={{ marginLeft: "10px" }}>
{" "}
{t("THUMBNAIL_REPLACED")}
</span>
</div>
<div
style={{
width: "100%",
marginTop: "10px",
marginBottom: "20px",
}}
>
<ProgressBar
now={Math.round(
(progressTracker.current * 100) /
progressTracker.total,
)}
animated={true}
variant="upload-progress-bar"
/>
</div>
</>
)}
<div
style={{
width: "100%",
display: "flex",
justifyContent: "space-around",
}}
>
{fixState === FIX_STATE.NOT_STARTED ||
fixState === FIX_STATE.FIX_LATER ? (
<Button
block
variant={"outline-secondary"}
onClick={() => {
updateFixState(FIX_STATE.FIX_LATER);
props.hide();
}}
>
{t("FIX_THUMBNAIL_LATER")}
</Button>
) : (
<Button
block
variant={"outline-secondary"}
onClick={props.hide}
>
{t("CLOSE")}
</Button>
)}
{(fixState === FIX_STATE.NOT_STARTED ||
fixState === FIX_STATE.FIX_LATER ||
fixState === FIX_STATE.COMPLETED_WITH_ERRORS) && (
<>
<div style={{ width: "30px" }} />
<Button
block
variant={"outline-success"}
onClick={() => startFix()}
>
{t("FIX_THUMBNAIL")}
</Button>
</>
)}
</div>
</div>
</DialogBox>
);
}

View file

@ -1,15 +1,13 @@
import { t } from "i18next";
import { useContext, useState } from "react";
// import FixLargeThumbnails from 'components/FixLargeThumbnail';
import RecoveryKey from "@ente/shared/components/RecoveryKey";
import {
ACCOUNTS_PAGES,
PHOTOS_PAGES as PAGES,
} from "@ente/shared/constants/pages";
import TwoFactorModal from "components/TwoFactor/Modal";
import { t } from "i18next";
import { useRouter } from "next/router";
import { AppContext } from "pages/_app";
import { useContext, useState } from "react";
// import mlIDbStorage from 'utils/storage/mlIDbStorage';
import {
configurePasskeyRecovery,

View file

@ -1,147 +0,0 @@
import ComlinkCryptoWorker from "@ente/shared/crypto";
import { DedicatedCryptoWorker } from "@ente/shared/crypto/internal/crypto.worker";
import HTTPService from "@ente/shared/network/HTTPService";
import { getEndpoint } from "@ente/shared/network/api";
import { logError } from "@ente/shared/sentry";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { Remote } from "comlink";
import { SetProgressTracker } from "components/FixLargeThumbnail";
import downloadManager from "services/download";
import { getLocalFiles } from "services/fileService";
import { getFileType } from "services/typeDetectionService";
import { generateThumbnail } from "services/upload/thumbnailService";
import uploadHttpClient from "services/upload/uploadHttpClient";
import { S3FileAttributes } from "types/file";
import { UploadURL } from "types/upload";
import { getLocalTrashedFiles } from "./trashService";
const ENDPOINT = getEndpoint();
const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB
export async function getLargeThumbnailFiles() {
try {
const token = getToken();
if (!token) {
return;
}
const resp = await HTTPService.get(
`${ENDPOINT}/files/large-thumbnails`,
{
threshold: REPLACE_THUMBNAIL_THRESHOLD,
},
{
"X-Auth-Token": token,
},
);
return resp.data.largeThumbnailFiles as number[];
} catch (e) {
logError(e, "failed to get large thumbnail files");
throw e;
}
}
export async function replaceThumbnail(
setProgressTracker: SetProgressTracker,
largeThumbnailFileIDs: Set<number>,
) {
let completedWithError = false;
try {
const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const files = await getLocalFiles();
const trashFiles = await getLocalTrashedFiles();
const largeThumbnailFiles = [...files, ...trashFiles].filter((file) =>
largeThumbnailFileIDs.has(file.id),
);
if (largeThumbnailFileIDs.size !== largeThumbnailFiles.length) {
logError(Error(), "all large thumbnail files not found locally");
}
if (largeThumbnailFiles.length === 0) {
return completedWithError;
}
setProgressTracker({ current: 0, total: largeThumbnailFiles.length });
const uploadURLs: UploadURL[] = [];
await uploadHttpClient.fetchUploadURLs(
largeThumbnailFiles.length,
uploadURLs,
);
for (const [idx, file] of largeThumbnailFiles.entries()) {
try {
setProgressTracker({
current: idx,
total: largeThumbnailFiles.length,
});
const originalThumbnail =
await downloadManager.getThumbnail(file);
const dummyImageFile = new File(
[originalThumbnail],
file.metadata.title,
);
const fileTypeInfo = await getFileType(dummyImageFile);
const { thumbnail: newThumbnail } = await generateThumbnail(
dummyImageFile,
fileTypeInfo,
);
const newUploadedThumbnail = await uploadThumbnail(
cryptoWorker,
file.key,
newThumbnail,
uploadURLs.pop(),
);
await updateThumbnail(file.id, newUploadedThumbnail);
} catch (e) {
logError(e, "failed to replace a thumbnail");
completedWithError = true;
}
}
} catch (e) {
logError(e, "replace Thumbnail function failed");
completedWithError = true;
}
return completedWithError;
}
export async function uploadThumbnail(
worker: Remote<DedicatedCryptoWorker>,
fileKey: string,
updatedThumbnail: Uint8Array,
uploadURL: UploadURL,
): Promise<S3FileAttributes> {
const { file: encryptedThumbnail } = await worker.encryptThumbnail(
updatedThumbnail,
fileKey,
);
const thumbnailObjectKey = await uploadHttpClient.putFile(
uploadURL,
encryptedThumbnail.encryptedData,
() => {},
);
return {
objectKey: thumbnailObjectKey,
decryptionHeader: encryptedThumbnail.decryptionHeader,
};
}
export async function updateThumbnail(
fileID: number,
newThumbnail: S3FileAttributes,
) {
try {
const token = getToken();
if (!token) {
return;
}
await HTTPService.put(
`${ENDPOINT}/files/thumbnail`,
{
fileID: fileID,
thumbnail: newThumbnail,
},
null,
{
"X-Auth-Token": token,
},
);
} catch (e) {
logError(e, "failed to update thumbnail");
throw e;
}
}

View file

@ -1,6 +1,5 @@
import { logError } from "@ente/shared/sentry";
import { FIX_OPTIONS } from "components/FixCreationTime";
import { SetProgressTracker } from "components/FixLargeThumbnail";
import { EnteFile } from "types/file";
import {
changeFileCreationTime,
@ -21,6 +20,13 @@ const EXIF_TIME_TAGS = [
"MetadataDate",
];
export type SetProgressTracker = React.Dispatch<
React.SetStateAction<{
current: number;
total: number;
}>
>;
export async function updateCreationTimeWithExif(
filesToBeUpdated: EnteFile[],
fixOption: FIX_OPTIONS,