diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx
deleted file mode 100644
index c047fa18cc..0000000000
--- a/web/apps/photos/src/components/PhotoViewer/FileInfo/ExifData.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { Titlebar } from "@/base/components/Titlebar";
-import CopyButton from "@ente/shared/components/CodeBlock/CopyButton";
-import { formatDateTimeFull } from "@ente/shared/time/format";
-import { Box, Stack, styled, Typography } from "@mui/material";
-import { t } from "i18next";
-import React from "react";
-import { FileInfoSidebar } from ".";
-
-const ExifItem = styled(Box)`
- padding-left: 8px;
- padding-right: 8px;
- display: flex;
- flex-direction: column;
- gap: 4px;
-`;
-
-function parseExifValue(value: any) {
- switch (typeof value) {
- case "string":
- case "number":
- return value;
- default:
- if (value instanceof Date) {
- return formatDateTimeFull(value);
- }
- try {
- return JSON.stringify(Array.from(value));
- } catch (e) {
- return null;
- }
- }
-}
-export function ExifData(props: {
- exif: any;
- open: boolean;
- onClose: () => void;
- filename: string;
- onInfoClose: () => void;
-}) {
- const { exif, open, onClose, filename, onInfoClose } = props;
-
- if (!exif) {
- return <>>;
- }
- const handleRootClose = () => {
- onClose();
- onInfoClose();
- };
-
- return (
-
-
- }
- />
-
- {[...Object.entries(exif)]
- .sort((a, b) => a[0].localeCompare(b[0]))
- .map(([key, value]) =>
- value ? (
-
-
- {key}
-
-
- {parseExifValue(value)}
-
-
- ) : (
-
- ),
- )}
-
-
- );
-}
diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx
deleted file mode 100644
index e9443c84c1..0000000000
--- a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { nameAndExtension } from "@/base/file";
-import log from "@/base/log";
-import { FILE_TYPE } from "@/media/file-type";
-import { EnteFile } from "@/new/photos/types/file";
-import { formattedByteSize } from "@/new/photos/utils/units";
-import { FlexWrapper } from "@ente/shared/components/Container";
-import PhotoOutlined from "@mui/icons-material/PhotoOutlined";
-import VideocamOutlined from "@mui/icons-material/VideocamOutlined";
-import Box from "@mui/material/Box";
-import { useEffect, useState } from "react";
-import { changeFileName, updateExistingFilePubMetadata } from "utils/file";
-import { FileNameEditDialog } from "./FileNameEditDialog";
-import InfoItem from "./InfoItem";
-
-const getFileTitle = (filename, extension) => {
- if (extension) {
- return filename + "." + extension;
- } else {
- return filename;
- }
-};
-
-const getCaption = (file: EnteFile, parsedExifData) => {
- const megaPixels = parsedExifData?.["megaPixels"];
- const resolution = parsedExifData?.["resolution"];
- const fileSize = file.info?.fileSize;
-
- const captionParts = [];
- if (megaPixels) {
- captionParts.push(megaPixels);
- }
- if (resolution) {
- captionParts.push(resolution);
- }
- if (fileSize) {
- captionParts.push(formattedByteSize(fileSize));
- }
- return (
-
- {captionParts.map((caption) => (
- {caption}
- ))}
-
- );
-};
-
-export function RenderFileName({
- parsedExifData,
- shouldDisableEdits,
- file,
- scheduleUpdate,
-}: {
- parsedExifData: Record;
- shouldDisableEdits: boolean;
- file: EnteFile;
- scheduleUpdate: () => void;
-}) {
- const [isInEditMode, setIsInEditMode] = useState(false);
- const openEditMode = () => setIsInEditMode(true);
- const closeEditMode = () => setIsInEditMode(false);
- const [filename, setFilename] = useState();
- const [extension, setExtension] = useState();
-
- useEffect(() => {
- const [filename, extension] = nameAndExtension(file.metadata.title);
- setFilename(filename);
- setExtension(extension);
- }, [file]);
-
- const saveEdits = async (newFilename: string) => {
- try {
- if (file) {
- if (filename === newFilename) {
- closeEditMode();
- return;
- }
- setFilename(newFilename);
- const newTitle = getFileTitle(newFilename, extension);
- const updatedFile = await changeFileName(file, newTitle);
- updateExistingFilePubMetadata(file, updatedFile);
- scheduleUpdate();
- }
- } catch (e) {
- log.error("failed to update file name", e);
- throw e;
- }
- };
-
- return (
- <>
-
- ) : (
-
- )
- }
- title={getFileTitle(filename, extension)}
- caption={getCaption(file, parsedExifData)}
- openEditor={openEditMode}
- hideEditOption={shouldDisableEdits || isInEditMode}
- />
-
- >
- );
-}
diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx
index 453f56bf33..84af0f5f4d 100644
--- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx
+++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx
@@ -1,9 +1,13 @@
import { EnteDrawer } from "@/base/components/EnteDrawer";
import { Titlebar } from "@/base/components/Titlebar";
+import { nameAndExtension } from "@/base/file";
+import log from "@/base/log";
+import { FILE_TYPE } from "@/media/file-type";
import { UnidentifiedFaces } from "@/new/photos/components/PeopleList";
-import type { RawExifTags } from "@/new/photos/services/exif";
+import type { ParsedExif, RawExifTags } from "@/new/photos/services/exif";
import { isMLEnabled } from "@/new/photos/services/ml";
import { EnteFile } from "@/new/photos/types/file";
+import { formattedByteSize } from "@/new/photos/utils/units";
import CopyButton from "@ente/shared/components/CodeBlock/CopyButton";
import { FlexWrapper } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
@@ -12,7 +16,9 @@ import BackupOutlined from "@mui/icons-material/BackupOutlined";
import CameraOutlined from "@mui/icons-material/CameraOutlined";
import FolderOutlined from "@mui/icons-material/FolderOutlined";
import LocationOnOutlined from "@mui/icons-material/LocationOnOutlined";
+import PhotoOutlined from "@mui/icons-material/PhotoOutlined";
import TextSnippetOutlined from "@mui/icons-material/TextSnippetOutlined";
+import VideocamOutlined from "@mui/icons-material/VideocamOutlined";
import { Box, DialogProps, Link, Stack, styled } from "@mui/material";
import { Chip } from "components/Chip";
import LinkButton from "components/pages/gallery/LinkButton";
@@ -20,33 +26,29 @@ import { t } from "i18next";
import { AppContext } from "pages/_app";
import { GalleryContext } from "pages/gallery";
import React, { useContext, useEffect, useMemo, useState } from "react";
+import { changeFileName, updateExistingFilePubMetadata } from "utils/file";
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
import {
getMapDisableConfirmationDialog,
getMapEnableConfirmationDialog,
} from "utils/ui";
import { ExifData } from "./ExifData";
+import { FileNameEditDialog } from "./FileNameEditDialog";
import InfoItem from "./InfoItem";
import MapBox from "./MapBox";
import { RenderCaption } from "./RenderCaption";
import { RenderCreationTime } from "./RenderCreationTime";
-import { RenderFileName } from "./RenderFileName";
-
-export const FileInfoSidebar = styled((props: DialogProps) => (
-
-))({
- zIndex: 1501,
- "& .MuiPaper-root": {
- padding: 8,
- },
-});
+export interface FileInfoExif {
+ tags: RawExifTags;
+ parsed: ParsedExif;
+}
interface FileInfoProps {
shouldDisableEdits?: boolean;
showInfo: boolean;
handleCloseInfo: () => void;
file: EnteFile;
- rawExif: RawExifTags | undefined;
+ exif: FileInfoExif | undefined;
scheduleUpdate: () => void;
refreshPhotoswipe: () => void;
fileToCollectionsMap?: Map;
@@ -55,33 +57,12 @@ interface FileInfoProps {
closePhotoViewer: () => void;
}
-function BasicDeviceCamera({
- parsedExifData,
-}: {
- parsedExifData: Record;
-}) {
- return (
-
- {parsedExifData["fNumber"]}
- {parsedExifData["exposureTime"]}
- {parsedExifData["ISO"]}
-
- );
-}
-
-function getOpenStreetMapLink(location: {
- latitude: number;
- longitude: number;
-}) {
- return `https://www.openstreetmap.org/?mlat=${location.latitude}&mlon=${location.longitude}#map=15/${location.latitude}/${location.longitude}`;
-}
-
export const FileInfo: React.FC = ({
shouldDisableEdits,
showInfo,
handleCloseInfo,
file,
- rawExif,
+ exif,
scheduleUpdate,
refreshPhotoswipe,
fileToCollectionsMap,
@@ -95,11 +76,10 @@ export const FileInfo: React.FC = ({
PublicCollectionGalleryContext,
);
- const [parsedExifData, setParsedExifData] = useState>();
- const [showExif, setShowExif] = useState(false);
-
- const openExif = () => setShowExif(true);
- const closeExif = () => setShowExif(false);
+ const [parsedExif, setParsedExif] = useState<
+ ParsedFileInfoExif | undefined
+ >();
+ const [openRawExif, setOpenRawExif] = useState(false);
const location = useMemo(() => {
if (file && file.metadata) {
@@ -113,48 +93,12 @@ export const FileInfo: React.FC = ({
};
}
}
- return null;
+ return exif.parsed.location;
}, [file]);
useEffect(() => {
- setParsedExifData(parseInfoExif(rawExif));
-
- if (!exif) {
- setParsedExifData({});
- return;
- }
- const parsedExifData = {};
- if (exif["fNumber"]) {
- parsedExifData["fNumber"] = `f/${Math.ceil(exif["FNumber"])}`;
- } else if (exif["ApertureValue"] && exif["FocalLength"]) {
- parsedExifData["fNumber"] = `f/${Math.ceil(
- exif["FocalLength"] / exif["ApertureValue"],
- )}`;
- }
- const imageWidth = exif["ImageWidth"] ?? exif["ExifImageWidth"];
- const imageHeight = exif["ImageHeight"] ?? exif["ExifImageHeight"];
- if (imageWidth && imageHeight) {
- parsedExifData["resolution"] = `${imageWidth} x ${imageHeight}`;
- const megaPixels = Math.round((imageWidth * imageHeight) / 1000000);
- if (megaPixels) {
- parsedExifData["megaPixels"] = `${Math.round(
- (imageWidth * imageHeight) / 1000000,
- )}MP`;
- }
- }
- if (exif["Make"] && exif["Model"]) {
- parsedExifData["takenOnDevice"] =
- `${exif["Make"]} ${exif["Model"]}`;
- }
- if (exif["ExposureTime"]) {
- parsedExifData["exposureTime"] = `1/${
- 1 / parseFloat(exif["ExposureTime"])
- }`;
- }
- if (exif["ISO"]) {
- parsedExifData["ISO"] = `ISO${exif["ISO"]}`;
- }
- }, [rawExif]);
+ setParsedExif(exif ? parseFileInfoExif(exif) : undefined);
+ }, [exif]);
if (!file) {
return <>>;
@@ -272,7 +216,7 @@ export const FileInfo: React.FC = ({
) : exif !== null ? (
setOpenRawExif(true)}
sx={{
textDecoration: "none",
color: "text.muted",
@@ -329,9 +273,9 @@ export const FileInfo: React.FC = ({
)}
setOpenRawExif(false)}
onInfoClose={handleCloseInfo}
filename={file.metadata.title}
/>
@@ -339,54 +283,276 @@ export const FileInfo: React.FC = ({
);
};
-interface ParsedInfoExif {
+/**
+ * Some immediate fields of interest, in the form that we want to display on the
+ * info panel for a file.
+ */
+type ParsedFileInfoExif = FileInfoExif & {
resolution?: string;
megaPixels?: string;
takenOnDevice?: string;
fNumber?: string;
exposureTime?: string;
iso?: string;
-}
+};
-/**
- * Extract some immediate fields of interest and in the form that we want to
- * display on the info panel for a file.
- */
-const parseInfoExif = (rawExif: RawExifTags | undefined): ParsedInfoExif => {
- const parsed = {};
- if (!rawExif) return {};
+const parseFileInfoExif = (fileInfoExif: FileInfoExif): ParsedFileInfoExif => {
+ const parsed: ParsedFileInfoExif = { ...fileInfoExif };
-
- if (rawExif.exif)
- if (exif["fNumber"]) {
- parsedExifData["fNumber"] = `f/${Math.ceil(exif["FNumber"])}`;
- } else if (exif["ApertureValue"] && exif["FocalLength"]) {
- parsedExifData["fNumber"] = `f/${Math.ceil(
- exif["FocalLength"] / exif["ApertureValue"],
- )}`;
+ const { width, height } = fileInfoExif.parsed;
+ if (width && height) {
+ parsed.resolution = `${width} x ${height}`;
+ const mp = Math.round((width * height) / 1000000);
+ if (mp) parsed.megaPixels = `${mp}MP`;
}
- const imageWidth = exif["ImageWidth"] ?? exif["ExifImageWidth"];
- const imageHeight = exif["ImageHeight"] ?? exif["ExifImageHeight"];
- if (imageWidth && imageHeight) {
- parsedExifData["resolution"] = `${imageWidth} x ${imageHeight}`;
- const megaPixels = Math.round((imageWidth * imageHeight) / 1000000);
- if (megaPixels) {
- parsedExifData["megaPixels"] = `${Math.round(
- (imageWidth * imageHeight) / 1000000,
- )}MP`;
+
+ const { tags } = fileInfoExif;
+ const { exif } = tags;
+
+ if (exif) {
+ if (exif.Make && exif.Model) {
+ parsed["takenOnDevice"] =
+ `${exif.Make.description} ${exif.Model.description}`;
+ }
+
+ if (exif.FNumber) {
+ parsed.fNumber = `f/${Math.ceil(exif.FNumber.value)}`;
+ } else if (exif.FocalLength && exif.ApertureValue) {
+ parsed.fNumber = `f/${Math.ceil(
+ exif.FocalLength.value / exif.ApertureValue.value,
+ )}`;
+ }
+
+ if (exif.ExposureTime) {
+ parsed["exposureTime"] = `1/${1 / exif.ExposureTime.value}`;
+ }
+
+ if (exif.ISOSpeedRatings) {
+ const iso = exif.ISOSpeedRatings;
+ const n = Array.isArray(iso) ? (iso[0] ?? 0) / (iso[1] ?? 1) : iso;
+ parsed.iso = `ISO${n}`;
}
}
- if (exif["Make"] && exif["Model"]) {
- parsedExifData["takenOnDevice"] =
- `${exif["Make"]} ${exif["Model"]}`;
+ return parsed;
+};
+
+const FileInfoSidebar = styled((props: DialogProps) => (
+
+))({
+ zIndex: 1501,
+ "& .MuiPaper-root": {
+ padding: 8,
+ },
+});
+
+function RenderFileName({
+ parsedExifData,
+ shouldDisableEdits,
+ file,
+ scheduleUpdate,
+}: {
+ parsedExifData: Record;
+ shouldDisableEdits: boolean;
+ file: EnteFile;
+ scheduleUpdate: () => void;
+}) {
+ const [isInEditMode, setIsInEditMode] = useState(false);
+ const openEditMode = () => setIsInEditMode(true);
+ const closeEditMode = () => setIsInEditMode(false);
+ const [filename, setFilename] = useState();
+ const [extension, setExtension] = useState();
+
+ useEffect(() => {
+ const [filename, extension] = nameAndExtension(file.metadata.title);
+ setFilename(filename);
+ setExtension(extension);
+ }, [file]);
+
+ const saveEdits = async (newFilename: string) => {
+ try {
+ if (file) {
+ if (filename === newFilename) {
+ closeEditMode();
+ return;
+ }
+ setFilename(newFilename);
+ const newTitle = getFileTitle(newFilename, extension);
+ const updatedFile = await changeFileName(file, newTitle);
+ updateExistingFilePubMetadata(file, updatedFile);
+ scheduleUpdate();
+ }
+ } catch (e) {
+ log.error("failed to update file name", e);
+ throw e;
+ }
+ };
+
+ return (
+ <>
+
+ ) : (
+
+ )
+ }
+ title={getFileTitle(filename, extension)}
+ caption={getCaption(file, parsedExifData)}
+ openEditor={openEditMode}
+ hideEditOption={shouldDisableEdits || isInEditMode}
+ />
+
+ >
+ );
+}
+
+const getFileTitle = (filename, extension) => {
+ if (extension) {
+ return filename + "." + extension;
+ } else {
+ return filename;
}
- if (exif["ExposureTime"]) {
- parsedExifData["exposureTime"] = `1/${
- 1 / parseFloat(exif["ExposureTime"])
- }`;
+};
+
+const getCaption = (file: EnteFile, parsedExifData) => {
+ const megaPixels = parsedExifData?.["megaPixels"];
+ const resolution = parsedExifData?.["resolution"];
+ const fileSize = file.info?.fileSize;
+
+ const captionParts = [];
+ if (megaPixels) {
+ captionParts.push(megaPixels);
}
- if (exif["ISO"]) {
- parsedExifData["ISO"] = `ISO${exif["ISO"]}`;
+ if (resolution) {
+ captionParts.push(resolution);
}
- setParsedExifData(parsedExifData);
-}, [exif]);
+ if (fileSize) {
+ captionParts.push(formattedByteSize(fileSize));
+ }
+ return (
+
+ {captionParts.map((caption) => (
+ {caption}
+ ))}
+
+ );
+};
+
+function BasicDeviceCamera({
+ parsedExifData,
+}: {
+ parsedExifData: Record;
+}) {
+ return (
+
+ {parsedExifData["fNumber"]}
+ {parsedExifData["exposureTime"]}
+ {parsedExifData["ISO"]}
+
+ );
+}
+
+function getOpenStreetMapLink(location: {
+ latitude: number;
+ longitude: number;
+}) {
+ return `https://www.openstreetmap.org/?mlat=${location.latitude}&mlon=${location.longitude}#map=15/${location.latitude}/${location.longitude}`;
+}
+
+import { formatDateTimeFull } from "@ente/shared/time/format";
+import { Typography } from "@mui/material";
+import { FileInfoSidebar } from ".";
+
+const ExifItem = styled(Box)`
+ padding-left: 8px;
+ padding-right: 8px;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+`;
+
+function parseExifValue(value: any) {
+ switch (typeof value) {
+ case "string":
+ case "number":
+ return value;
+ default:
+ if (value instanceof Date) {
+ return formatDateTimeFull(value);
+ }
+ try {
+ return JSON.stringify(Array.from(value));
+ } catch (e) {
+ return null;
+ }
+ }
+}
+export function ExifData(props: {
+ exif: any;
+ open: boolean;
+ onClose: () => void;
+ filename: string;
+ onInfoClose: () => void;
+}) {
+ const { exif, open, onClose, filename, onInfoClose } = props;
+
+ if (!exif) {
+ return <>>;
+ }
+ const handleRootClose = () => {
+ onClose();
+ onInfoClose();
+ };
+
+ return (
+
+
+ }
+ />
+
+ {[...Object.entries(exif)]
+ .sort((a, b) => a[0].localeCompare(b[0]))
+ .map(([key, value]) =>
+ value ? (
+
+
+ {key}
+
+
+ {parseExifValue(value)}
+
+
+ ) : (
+
+ ),
+ )}
+
+
+ );
+}
diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx
index 768daf46f4..4d623992aa 100644
--- a/web/apps/photos/src/components/PhotoViewer/index.tsx
+++ b/web/apps/photos/src/components/PhotoViewer/index.tsx
@@ -18,7 +18,7 @@ import { lowercaseExtension } from "@/base/file";
import { FILE_TYPE } from "@/media/file-type";
import { isHEICExtension, needsJPEGConversion } from "@/media/formats";
import downloadManager from "@/new/photos/services/download";
-import { extractRawExif, type RawExifTags } from "@/new/photos/services/exif";
+import { extractRawExif, parseExif } from "@/new/photos/services/exif";
import type { LoadedLivePhotoSourceURL } from "@/new/photos/types/file";
import { FlexWrapper } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
@@ -52,7 +52,7 @@ import { isClipboardItemPresent } from "utils/common";
import { pauseVideo, playVideo } from "utils/photoFrame";
import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery";
import { getTrashFileMessage } from "utils/ui";
-import { FileInfo } from "./FileInfo";
+import { FileInfo, type FileInfoExif } from "./FileInfo";
import ImageEditorOverlay from "./ImageEditorOverlay";
import CircularProgressWithLabel from "./styledComponents/CircularProgressWithLabel";
import { ConversionFailedNotification } from "./styledComponents/ConversionFailedNotification";
@@ -107,11 +107,11 @@ function PhotoViewer(props: Iprops) {
useState>();
const [isFav, setIsFav] = useState(false);
const [showInfo, setShowInfo] = useState(false);
- const [rawExif, setRawExif] = useState<{
+ const [exif, setExif] = useState<{
key: string;
- value: RawExifTags;
+ value: FileInfoExif | undefined;
}>();
- const rawExifCopy = useRef(null);
+ const exifCopy = useRef(null);
const [livePhotoBtnOptions, setLivePhotoBtnOptions] = useState(
defaultLivePhotoDefaultOptions,
);
@@ -290,8 +290,8 @@ function PhotoViewer(props: Iprops) {
}, [photoSwipe?.currItem, isOpen, isSourceLoaded]);
useEffect(() => {
- rawExifCopy.current = rawExif;
- }, [rawExif]);
+ exifCopy.current = exif;
+ }, [exif]);
function updateFavButton(file: EnteFile) {
setIsFav(isInFav(file));
@@ -306,14 +306,14 @@ function PhotoViewer(props: Iprops) {
function updateExif(file: EnteFile) {
if (file.metadata.fileType === FILE_TYPE.VIDEO) {
- setRawExif({ key: file.src, value: null });
+ setExif({ key: file.src, value: undefined });
return;
}
if (!file.isSourceLoaded || file.conversionFailed) {
return;
}
- if (!file || !rawExifCopy?.current?.value === null) {
+ if (!file || !exifCopy?.current?.value) {
return;
}
const key =
@@ -321,10 +321,10 @@ function PhotoViewer(props: Iprops) {
? file.src
: (file.srcURLs.url as LoadedLivePhotoSourceURL).image;
- if (rawExifCopy?.current?.key === key) {
+ if (exifCopy?.current?.key === key) {
return;
}
- setRawExif({ key, value: undefined });
+ setExif({ key, value: undefined });
checkExifAvailable(file);
}
@@ -584,40 +584,32 @@ function PhotoViewer(props: Iprops) {
}
};
- const checkExifAvailable = async (file: EnteFile) => {
+ const checkExifAvailable = async (enteFile: EnteFile) => {
try {
- if (exifExtractionInProgress.current === file.src) {
+ if (exifExtractionInProgress.current === enteFile.src) {
return;
}
try {
- exifExtractionInProgress.current = file.src;
- let fileObject: File;
- if (file.metadata.fileType === FILE_TYPE.IMAGE) {
- fileObject = await getFileFromURL(
- file.src as string,
- file.metadata.title,
- );
- } else {
- const url = (file.srcURLs.url as LoadedLivePhotoSourceURL)
- .image;
- fileObject = await getFileFromURL(url, file.metadata.title);
- }
- const rawExif = await extractRawExif(fileObject);
- // TODO: Exif
- // if (await wipNewLib()) {
- // const newLib = await extractExif(fileObject);
- // cmpNewLib(file.metadata, newLib);
- // }
- if (exifExtractionInProgress.current === file.src) {
- setRawExif({ key: file.src, value: rawExif });
+ exifExtractionInProgress.current = enteFile.src;
+ const file = await getFileFromURL(
+ enteFile.metadata.fileType === FILE_TYPE.IMAGE
+ ? (enteFile.src as string)
+ : (enteFile.srcURLs.url as LoadedLivePhotoSourceURL)
+ .image,
+ enteFile.metadata.title,
+ );
+ const tags = await extractRawExif(file);
+ const parsed = parseExif(tags);
+ if (exifExtractionInProgress.current === enteFile.src) {
+ setExif({ key: enteFile.src, value: { tags, parsed } });
}
} finally {
exifExtractionInProgress.current = null;
}
} catch (e) {
- setRawExif({ key: file.src, value: null });
+ setExif({ key: enteFile.src, value: undefined });
log.error(
- `checkExifAvailable failed for file ${file.metadata.title}`,
+ `checkExifAvailable failed for file ${enteFile.metadata.title}`,
e,
);
}
@@ -946,7 +938,7 @@ function PhotoViewer(props: Iprops) {
showInfo={showInfo}
handleCloseInfo={handleCloseInfo}
file={photoSwipe?.currItem as EnteFile}
- rawExif={rawExif?.value}
+ exif={exif?.value}
scheduleUpdate={scheduleUpdate}
refreshPhotoswipe={refreshPhotoswipe}
fileToCollectionsMap={props.fileToCollectionsMap}
diff --git a/web/packages/new/photos/services/exif.ts b/web/packages/new/photos/services/exif.ts
index 9dd4612adb..1066fb260d 100644
--- a/web/packages/new/photos/services/exif.ts
+++ b/web/packages/new/photos/services/exif.ts
@@ -34,7 +34,7 @@ export const cmpNewLib = (
* be attached to an {@link EnteFile} allows us to perform operations using
* these attributes without needing to re-download the original image.
*/
-interface ParsedExif {
+export interface ParsedExif {
/** The width of the image, in pixels. */
width?: number;
/** The height of the image, in pixels. */