This commit is contained in:
Manav Rathi
2024-08-02 13:55:12 +05:30
parent 967149c04b
commit 4335df1634
3 changed files with 76 additions and 79 deletions

View File

@@ -1,6 +1,9 @@
import type { ParsedMetadataDate } from "@/media/file-metadata";
import { PhotoDateTimePicker } from "@/new/photos/components/PhotoDateTimePicker";
import { updateCreationTimeWithExif } from "@/new/photos/services/fix-exif";
import {
updateDateTimeOfEnteFiles,
type FixOption,
} from "@/new/photos/services/fix-exif";
import { EnteFile } from "@/new/photos/types/file";
import DialogBox from "@ente/shared/components/DialogBox/";
import {
@@ -22,13 +25,8 @@ export interface FixCreationTimeAttributes {
files: EnteFile[];
}
type Step = "running" | "completed" | "completed-with-errors";
export type FixOption =
| "date-time-original"
| "date-time-digitized"
| "metadata-date"
| "custom-time";
/** The current state of the fixing process. */
type Status = "running" | "completed" | "completed-with-errors";
interface FormValues {
option: FixOption;
@@ -38,13 +36,16 @@ interface FormValues {
interface FixCreationTimeProps {
isOpen: boolean;
show: () => void;
hide: () => void;
attributes: FixCreationTimeAttributes;
}
const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
const [step, setStep] = useState<Step | undefined>();
const FixCreationTime: React.FC<FixCreationTimeProps> = ({
isOpen,
hide,
attributes,
}) => {
const [status, setStatus] = useState<Status | undefined>();
const [progressTracker, setProgressTracker] = useState({
current: 0,
total: 0,
@@ -54,39 +55,37 @@ const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
useEffect(() => {
// TODO (MR): Not sure why this is needed
if (props.attributes && props.isOpen && step !== "running") {
setStep(undefined);
}
}, [props.isOpen]);
if (attributes && isOpen && status !== "running") setStatus(undefined);
}, [isOpen]);
const onSubmit = async (values: FormValues) => {
console.log({ values });
setStep("running");
const completedWithErrors = await updateCreationTimeWithExif(
props.attributes.files,
setStatus("running");
const completedWithErrors = await updateDateTimeOfEnteFiles(
attributes.files,
values.option,
values.customDate,
setProgressTracker,
);
setStep(completedWithErrors ? "completed-with-errors" : "completed");
setStatus(completedWithErrors ? "completed-with-errors" : "completed");
await galleryContext.syncWithRemote();
};
const title =
step === "running"
status == "running"
? t("FIX_CREATION_TIME_IN_PROGRESS")
: t("FIX_CREATION_TIME");
const message = messageForStep(step);
const message = messageForStatus(status);
if (!props.attributes) {
if (!attributes) {
return <></>;
}
return (
<DialogBox
open={props.isOpen}
onClose={props.hide}
open={isOpen}
onClose={hide}
attributes={{ title, nonClosable: true }}
>
<div
@@ -94,16 +93,12 @@ const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
marginBottom: "10px",
display: "flex",
flexDirection: "column",
...(step === "running" ? { alignItems: "center" } : {}),
...(status == "running" ? { alignItems: "center" } : {}),
}}
>
{message && <div>{message}</div>}
{step === "running" && (
<FixCreationTimeRunning {...{ progressTracker }} />
)}
<OptionsForm {...{ step, onSubmit }} hide={props.hide} />
{status === "running" && <Progress {...{ progressTracker }} />}
<OptionsForm {...{ step: status, onSubmit }} hide={hide} />
</div>
</DialogBox>
);
@@ -111,7 +106,7 @@ const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
export default FixCreationTime;
const messageForStep = (step?: Step) => {
const messageForStatus = (step?: Status) => {
switch (step) {
case undefined:
return undefined;
@@ -124,9 +119,38 @@ const messageForStep = (step?: Step) => {
}
};
const Progress = ({ progressTracker }) => {
const progress = Math.round(
(progressTracker.current * 100) / progressTracker.total,
);
return (
<>
<div style={{ marginBottom: "10px" }}>
<ComfySpan>
{" "}
{progressTracker.current} / {progressTracker.total}{" "}
</ComfySpan>{" "}
<span style={{ marginLeft: "10px" }}>
{" "}
{t("CREATION_TIME_UPDATED")}
</span>
</div>
<div
style={{
width: "100%",
marginTop: "10px",
marginBottom: "20px",
}}
>
<LinearProgress variant="determinate" value={progress} />
</div>
</>
);
};
interface OptionsFormProps {
step?: Step;
onSubmit: (values: FormValues) => void | Promise<any>;
step?: Status;
onSubmit: (values: FormValues) => Promise<void>;
hide: () => void;
}
@@ -168,18 +192,15 @@ const OptionsForm: React.FC<OptionsFormProps> = ({ step, onSubmit, hide }) => {
label={t("METADATA_DATE")}
/>
<FormControlLabel
value={"custom-time"}
value={"custom"}
control={<Radio size="small" />}
label={t("CUSTOM_TIME")}
/>
</RadioGroup>
{values.option === "custom-time" && (
{values.option == "custom" && (
<PhotoDateTimePicker
onAccept={(customDate) =>
setValues({
option: "custom-time",
customDate,
})
setValues({ option: "custom", customDate })
}
/>
)}
@@ -193,7 +214,7 @@ const OptionsForm: React.FC<OptionsFormProps> = ({ step, onSubmit, hide }) => {
const Footer = ({ step, startFix, ...props }) => {
return (
step !== "running" && (
step != "running" && (
<div
style={{
width: "100%",
@@ -202,7 +223,7 @@ const Footer = ({ step, startFix, ...props }) => {
justifyContent: "space-around",
}}
>
{(step === undefined || step === "completed-with-errors") && (
{(!step || step == "completed-with-errors") && (
<Button
color="secondary"
size="large"
@@ -213,12 +234,12 @@ const Footer = ({ step, startFix, ...props }) => {
{t("cancel")}
</Button>
)}
{step === "completed" && (
{step == "completed" && (
<Button color="primary" size="large" onClick={props.hide}>
{t("CLOSE")}
</Button>
)}
{(step === undefined || step === "completed-with-errors") && (
{(!step || step == "completed-with-errors") && (
<>
<div style={{ width: "30px" }} />
@@ -231,32 +252,3 @@ const Footer = ({ step, startFix, ...props }) => {
)
);
};
const FixCreationTimeRunning = ({ progressTracker }) => {
const progress = Math.round(
(progressTracker.current * 100) / progressTracker.total,
);
return (
<>
<div style={{ marginBottom: "10px" }}>
<ComfySpan>
{" "}
{progressTracker.current} / {progressTracker.total}{" "}
</ComfySpan>{" "}
<span style={{ marginLeft: "10px" }}>
{" "}
{t("CREATION_TIME_UPDATED")}
</span>
</div>
<div
style={{
width: "100%",
marginTop: "10px",
marginBottom: "20px",
}}
>
<LinearProgress variant="determinate" value={progress} />
</div>
</>
);
};

View File

@@ -1066,7 +1066,6 @@ export default function Gallery() {
<FixCreationTime
isOpen={fixCreationTimeView}
hide={() => setFixCreationTimeView(false)}
show={() => setFixCreationTimeView(true)}
attributes={fixCreationTimeAttributes}
/>
<GalleryNavbar

View File

@@ -1,11 +1,11 @@
import log from "@/base/log";
import type { ParsedMetadataDate } from "@/media/file-metadata";
import { FileType } from "@/media/file-type";
import downloadManager from "@/new/photos/services/download";
import { EnteFile } from "@/new/photos/types/file";
import type { EnteFile } from "@/new/photos/types/file";
import { detectFileTypeInfo } from "@/new/photos/utils/detect-type";
import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
import { getParsedExifData } from "@ente/shared/utils/exif-old";
import type { FixOption } from "components/FixCreationTime";
import {
changeFileCreationTime,
updateExistingFilePubMetadata,
@@ -26,10 +26,16 @@ export type SetProgressTracker = React.Dispatch<
}>
>;
export async function updateCreationTimeWithExif(
export type FixOption =
| "date-time-original"
| "date-time-digitized"
| "metadata-date"
| "custom";
export async function updateDateTimeOfEnteFiles(
filesToBeUpdated: EnteFile[],
fixOption: FixOption,
customTime: Date,
customDate: ParsedMetadataDate,
setProgressTracker: SetProgressTracker,
) {
let completedWithError = false;
@@ -42,7 +48,7 @@ export async function updateCreationTimeWithExif(
try {
let correctCreationTime: number;
if (fixOption === "custom-time") {
correctCreationTime = customTime.getTime() * 1000;
correctCreationTime = customDate.getTime() * 1000;
} else {
if (file.metadata.fileType !== FileType.image) {
continue;