This commit is contained in:
Manav Rathi
2024-11-12 18:59:40 +05:30
parent 8d00796a32
commit 57d6fb3bc9
10 changed files with 81 additions and 82 deletions

View File

@@ -1,4 +1,4 @@
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { type UploadPhase } from "@/new/photos/services/upload/types";
import { createContext } from "react";
import type {
InProgressUpload,
@@ -11,7 +11,7 @@ interface UploadProgressContextType {
open: boolean;
onClose: () => void;
uploadCounter: UploadCounter;
uploadStage: UPLOAD_STAGES;
uploadPhase: UploadPhase;
percentComplete: number;
retryFailed: () => void;
inProgressUploads: InProgressUpload[];
@@ -25,7 +25,7 @@ const defaultUploadProgressContext: UploadProgressContextType = {
open: null,
onClose: () => null,
uploadCounter: null,
uploadStage: null,
uploadPhase: undefined,
percentComplete: null,
retryFailed: () => null,
inProgressUploads: null,

View File

@@ -1,7 +1,4 @@
import {
UPLOAD_RESULT,
UPLOAD_STAGES,
} from "@/new/photos/services/upload/types";
import { UPLOAD_RESULT } from "@/new/photos/services/upload/types";
import { Dialog, DialogContent, type DialogProps } from "@mui/material";
import { t } from "i18next";
import { useContext, useEffect, useState } from "react";
@@ -14,7 +11,7 @@ import { ResultSection } from "./resultSection";
import { NotUploadSectionHeader } from "./styledComponents";
export function UploadProgressDialog() {
const { open, onClose, uploadStage, finishedUploads } = useContext(
const { open, onClose, uploadPhase, finishedUploads } = useContext(
UploadProgressContext,
);
@@ -43,16 +40,13 @@ export function UploadProgressDialog() {
return (
<Dialog open={open} onClose={handleClose} maxWidth="xs" fullWidth>
<UploadProgressHeader />
{(uploadStage === UPLOAD_STAGES.UPLOADING ||
uploadStage === UPLOAD_STAGES.FINISH ||
uploadStage === UPLOAD_STAGES.EXTRACTING_METADATA) && (
{(uploadPhase == "extractingMetadata" ||
uploadPhase == "uploading" ||
uploadPhase == "done") && (
<DialogContent sx={{ "&&&": { px: 0 } }}>
{(uploadStage === UPLOAD_STAGES.UPLOADING ||
uploadStage === UPLOAD_STAGES.EXTRACTING_METADATA) && (
<InProgressSection />
)}
{(uploadStage === UPLOAD_STAGES.UPLOADING ||
uploadStage === UPLOAD_STAGES.FINISH) && (
{(uploadPhase == "extractingMetadata" ||
uploadPhase === "uploading") && <InProgressSection />}
{(uploadPhase == "uploading" || uploadPhase == "done") && (
<>
<ResultSection
uploadResult={UPLOAD_RESULT.UPLOADED}
@@ -69,12 +63,11 @@ export function UploadProgressDialog() {
"THUMBNAIL_GENERATION_FAILED_INFO",
)}
/>
{uploadStage === UPLOAD_STAGES.FINISH &&
hasUnUploadedFiles && (
<NotUploadSectionHeader>
{t("FILE_NOT_UPLOADED_LIST")}
</NotUploadSectionHeader>
)}
{uploadPhase == "done" && hasUnUploadedFiles && (
<NotUploadSectionHeader>
{t("FILE_NOT_UPLOADED_LIST")}
</NotUploadSectionHeader>
)}
<ResultSection
uploadResult={UPLOAD_RESULT.BLOCKED}
sectionTitle={t("BLOCKED_UPLOADS")}
@@ -86,7 +79,7 @@ export function UploadProgressDialog() {
uploadResult={UPLOAD_RESULT.FAILED}
sectionTitle={t("FAILED_UPLOADS")}
sectionInfo={
uploadStage === UPLOAD_STAGES.FINISH
uploadPhase == "done"
? undefined
: t("failed_uploads_hint")
}
@@ -121,7 +114,7 @@ export function UploadProgressDialog() {
)}
</DialogContent>
)}
{uploadStage === UPLOAD_STAGES.FINISH && <UploadProgressFooter />}
{uploadPhase == "done" && <UploadProgressFooter />}
</Dialog>
);
}

View File

@@ -1,20 +1,17 @@
import {
UPLOAD_RESULT,
UPLOAD_STAGES,
} from "@/new/photos/services/upload/types";
import { UPLOAD_RESULT } from "@/new/photos/services/upload/types";
import { Button, DialogActions } from "@mui/material";
import { t } from "i18next";
import { useContext } from "react";
import UploadProgressContext from "./context";
export function UploadProgressFooter() {
const { uploadStage, finishedUploads, retryFailed, onClose } = useContext(
const { uploadPhase, finishedUploads, retryFailed, onClose } = useContext(
UploadProgressContext,
);
return (
<DialogActions>
{uploadStage === UPLOAD_STAGES.FINISH &&
{uploadPhase == "done" &&
(finishedUploads?.get(UPLOAD_RESULT.FAILED)?.length > 0 ||
finishedUploads?.get(UPLOAD_RESULT.BLOCKED)?.length > 0 ? (
<Button variant="contained" fullWidth onClick={retryFailed}>

View File

@@ -11,11 +11,10 @@ import {
} from "./section";
import { InProgressItemContainer } from "./styledComponents";
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { CaptionedText } from "components/CaptionedText";
export const InProgressSection = () => {
const { inProgressUploads, hasLivePhotos, uploadFileNames, uploadStage } =
const { inProgressUploads, hasLivePhotos, uploadFileNames, uploadPhase } =
useContext(UploadProgressContext);
const fileList = inProgressUploads ?? [];
@@ -23,7 +22,7 @@ export const InProgressSection = () => {
return (
<InProgressItemContainer key={localFileID}>
<span>{uploadFileNames.get(localFileID)}</span>
{uploadStage === UPLOAD_STAGES.UPLOADING && (
{uploadPhase == "uploading" && (
<>
{" "}
<span className="separator">{`-`}</span>
@@ -47,7 +46,7 @@ export const InProgressSection = () => {
<UploadProgressSectionTitle expandIcon={<ExpandMoreIcon />}>
<CaptionedText
mainText={
uploadStage === UPLOAD_STAGES.EXTRACTING_METADATA
uploadPhase == "extractingMetadata"
? t("INPROGRESS_METADATA_EXTRACTION")
: t("INPROGRESS_UPLOADS")
}

View File

@@ -1,4 +1,4 @@
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { type UploadPhase } from "@/new/photos/services/upload/types";
import { useAppContext } from "@/new/photos/types/context";
import { t } from "i18next";
import { useEffect, useState } from "react";
@@ -16,7 +16,7 @@ interface Props {
open: boolean;
onClose: () => void;
uploadCounter: UploadCounter;
uploadStage: UPLOAD_STAGES;
uploadPhase: UploadPhase;
percentComplete: number;
retryFailed: () => void;
inProgressUploads: InProgressUpload[];
@@ -29,7 +29,7 @@ interface Props {
export default function UploadProgress({
open,
uploadCounter,
uploadStage,
uploadPhase,
percentComplete,
retryFailed,
uploadFileNames,
@@ -62,7 +62,7 @@ export default function UploadProgress({
}
function onClose() {
if (uploadStage !== UPLOAD_STAGES.FINISH) {
if (uploadPhase != "done") {
confirmCancelUpload();
} else {
props.onClose();
@@ -79,7 +79,7 @@ export default function UploadProgress({
open,
onClose,
uploadCounter,
uploadStage,
uploadPhase,
percentComplete,
retryFailed,
inProgressUploads,

View File

@@ -1,15 +1,14 @@
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { Box, Divider, LinearProgress } from "@mui/material";
import { useContext } from "react";
import UploadProgressContext from "./context";
export function UploadProgressBar() {
const { uploadStage, percentComplete } = useContext(UploadProgressContext);
const { uploadPhase, percentComplete } = useContext(UploadProgressContext);
return (
<Box>
{(uploadStage === UPLOAD_STAGES.READING_GOOGLE_METADATA_FILES ||
uploadStage === UPLOAD_STAGES.EXTRACTING_METADATA ||
uploadStage === UPLOAD_STAGES.UPLOADING) && (
{(uploadPhase == "readingMetadata" ||
uploadPhase == "extractingMetadata" ||
uploadPhase == "uploading") && (
<>
<LinearProgress
sx={{

View File

@@ -1,5 +1,5 @@
import { FilledIconButton } from "@/new/photos/components/mui";
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { type UploadPhase } from "@/new/photos/services/upload/types";
import { SpaceBetweenFlex } from "@ente/shared/components/Container";
import Close from "@mui/icons-material/Close";
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
@@ -7,6 +7,7 @@ import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
import { Box, DialogTitle, Stack, Typography } from "@mui/material";
import { t } from "i18next";
import { useContext } from "react";
import type { UploadCounter } from "services/upload/uploadManager";
import UploadProgressContext from "./context";
const UploadProgressTitleText = ({ expanded }) => {
@@ -18,7 +19,7 @@ const UploadProgressTitleText = ({ expanded }) => {
};
function UploadProgressSubtitleText() {
const { uploadStage, uploadCounter } = useContext(UploadProgressContext);
const { uploadPhase, uploadCounter } = useContext(UploadProgressContext);
return (
<Typography
@@ -27,15 +28,31 @@ function UploadProgressSubtitleText() {
color="text.muted"
marginTop={"4px"}
>
{uploadStage === UPLOAD_STAGES.UPLOADING
? t(`UPLOAD_STAGE_MESSAGE.${uploadStage}`, { uploadCounter })
: uploadStage === UPLOAD_STAGES.EXTRACTING_METADATA
? t(`UPLOAD_STAGE_MESSAGE.${uploadStage}`, { uploadCounter })
: t(`UPLOAD_STAGE_MESSAGE.${uploadStage}`)}
{subtitleText(uploadPhase, uploadCounter)}
</Typography>
);
}
const subtitleText = (
uploadPhase: UploadPhase,
uploadCounter: UploadCounter,
) => {
switch (uploadPhase) {
case "preparing":
return t("UPLOAD_STAGE_MESSAGE.0");
case "readingMetadata":
return t("UPLOAD_STAGE_MESSAGE.1");
case "extractingMetadata":
return t("UPLOAD_STAGE_MESSAGE.2", { uploadCounter });
case "uploading":
return t("UPLOAD_STAGE_MESSAGE.3", { uploadCounter });
case "cancelling":
return t("UPLOAD_STAGE_MESSAGE.4");
case "done":
return t("UPLOAD_STAGE_MESSAGE.5");
}
};
export function UploadProgressTitle() {
const { setExpanded, onClose, expanded } = useContext(
UploadProgressContext,

View File

@@ -12,8 +12,8 @@ import { exportMetadataDirectoryName } from "@/new/photos/services/export";
import type {
FileAndPath,
UploadItem,
UploadPhase,
} from "@/new/photos/services/upload/types";
import { UPLOAD_STAGES } from "@/new/photos/services/upload/types";
import { redirectToCustomerPortal } from "@/new/photos/services/user-details";
import { useAppContext } from "@/new/photos/types/context";
import { NotificationAttributes } from "@/new/photos/types/notification";
@@ -121,9 +121,7 @@ export default function Uploader({
);
const [uploadProgressView, setUploadProgressView] = useState(false);
const [uploadStage, setUploadStage] = useState<UPLOAD_STAGES>(
UPLOAD_STAGES.START,
);
const [uploadPhase, setUploadPhase] = useState<UploadPhase>("preparing");
const [uploadFileNames, setUploadFileNames] = useState<UploadFileNames>();
const [uploadCounter, setUploadCounter] = useState<UploadCounter>({
finished: 0,
@@ -245,7 +243,7 @@ export default function Uploader({
setUploadCounter,
setInProgressUploads,
setFinishedUploads,
setUploadStage,
setUploadPhase,
setUploadFilenames: setUploadFileNames,
setHasLivePhotos,
setUploadProgressView,
@@ -486,7 +484,7 @@ export default function Uploader({
const preCollectionCreationAction = async () => {
props.onCloseCollectionSelector?.();
props.setShouldDisableDropzone(!uploadManager.shouldAllowNewUpload());
setUploadStage(UPLOAD_STAGES.START);
setUploadPhase("preparing");
setUploadProgressView(true);
};
@@ -802,7 +800,7 @@ export default function Uploader({
percentComplete={percentComplete}
uploadFileNames={uploadFileNames}
uploadCounter={uploadCounter}
uploadStage={uploadStage}
uploadPhase={uploadPhase}
inProgressUploads={inProgressUploads}
hasLivePhotos={hasLivePhotos}
retryFailed={retryFailed}

View File

@@ -15,7 +15,7 @@ import type { UploadItem } from "@/new/photos/services/upload/types";
import {
RANDOM_PERCENTAGE_PROGRESS_FOR_PUT,
UPLOAD_RESULT,
UPLOAD_STAGES,
type UploadPhase,
} from "@/new/photos/services/upload/types";
import { ensure } from "@/utils/ensure";
import { wait } from "@/utils/promise";
@@ -70,7 +70,7 @@ export type SegregatedFinishedUploads = Map<UPLOAD_RESULT, FileID[]>;
export interface ProgressUpdater {
setPercentComplete: React.Dispatch<React.SetStateAction<number>>;
setUploadCounter: React.Dispatch<React.SetStateAction<UploadCounter>>;
setUploadStage: React.Dispatch<React.SetStateAction<UPLOAD_STAGES>>;
setUploadPhase: (phase: UploadPhase) => void;
setInProgressUploads: React.Dispatch<
React.SetStateAction<InProgressUpload[]>
>;
@@ -132,7 +132,7 @@ class UIService {
private progressUpdater: ProgressUpdater;
// UPLOAD LEVEL STATES
private uploadStage: UPLOAD_STAGES = UPLOAD_STAGES.START;
private uploadPhase: UploadPhase = "preparing";
private filenames: Map<number, string> = new Map();
private hasLivePhoto: boolean = false;
private uploadProgressView: boolean = false;
@@ -146,7 +146,7 @@ class UIService {
init(progressUpdater: ProgressUpdater) {
this.progressUpdater = progressUpdater;
this.progressUpdater.setUploadStage(this.uploadStage);
this.progressUpdater.setUploadPhase(this.uploadPhase);
this.progressUpdater.setUploadFilenames(this.filenames);
this.progressUpdater.setHasLivePhotos(this.hasLivePhoto);
this.progressUpdater.setUploadProgressView(this.uploadProgressView);
@@ -184,9 +184,9 @@ class UIService {
this.updateProgressBarUI();
}
setUploadStage(stage: UPLOAD_STAGES) {
this.uploadStage = stage;
this.progressUpdater.setUploadStage(stage);
setUploadPhase(phase: UploadPhase) {
this.uploadPhase = phase;
this.progressUpdater.setUploadPhase(phase);
}
setFiles(files: { localID: number; fileName: string }[]) {
@@ -363,7 +363,7 @@ class UploadManager {
this.resetState();
this.uiService.reset();
uploadCancelService.reset();
this.uiService.setUploadStage(UPLOAD_STAGES.START);
this.uiService.setUploadPhase("preparing");
}
showUploadProgressDialog() {
@@ -411,10 +411,7 @@ class UploadManager {
splitMetadataAndMediaItems(namedItems);
if (metadataItems.length) {
this.uiService.setUploadStage(
UPLOAD_STAGES.READING_GOOGLE_METADATA_FILES,
);
this.uiService.setUploadPhase("readingMetadata");
await this.parseMetadataJSONFiles(metadataItems);
}
@@ -442,7 +439,7 @@ class UploadManager {
throw e;
}
} finally {
this.uiService.setUploadStage(UPLOAD_STAGES.FINISH);
this.uiService.setUploadPhase("done");
void globalThis.electron?.clearPendingUploads();
for (let i = 0; i < maxConcurrentUploads; i++) {
this.comlinkCryptoWorkers[i]?.terminate();
@@ -499,7 +496,7 @@ class UploadManager {
this.itemsToBeUploaded = [...this.itemsToBeUploaded, ...mediaItems];
this.uiService.reset(mediaItems.length);
await UploadService.setFileCount(mediaItems.length);
this.uiService.setUploadStage(UPLOAD_STAGES.UPLOADING);
this.uiService.setUploadPhase("uploading");
const uploadProcesses = [];
for (
@@ -653,7 +650,7 @@ class UploadManager {
public cancelRunningUpload() {
log.info("User cancelled running upload");
this.uiService.setUploadStage(UPLOAD_STAGES.CANCELLING);
this.uiService.setUploadPhase("cancelling");
uploadCancelService.requestUploadCancelation();
}

View File

@@ -58,14 +58,13 @@ export const toDataOrPathOrZipEntry = (desktopUploadItem: DesktopUploadItem) =>
export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random();
export enum UPLOAD_STAGES {
START,
READING_GOOGLE_METADATA_FILES,
EXTRACTING_METADATA,
UPLOADING,
CANCELLING,
FINISH,
}
export type UploadPhase =
| "preparing"
| "readingMetadata"
| "extractingMetadata"
| "uploading"
| "cancelling"
| "done";
export enum UPLOAD_RESULT {
FAILED,