Merge remote-tracking branch 'origin/main' into stream-queue-fix
This commit is contained in:
@@ -391,7 +391,7 @@ export const PhotoViewer: React.FC<PhotoViewerProps> = ({
|
||||
const extension = lowercaseExtension(file.metadata.title);
|
||||
// Assume it is supported.
|
||||
let isSupported = true;
|
||||
if (needsJPEGConversion(extension)) {
|
||||
if (extension && needsJPEGConversion(extension)) {
|
||||
// See if the file is on the whitelist of extensions that we know
|
||||
// will not be directly renderable.
|
||||
if (!isDesktop) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import { type EnteFile } from "@/media/file";
|
||||
import {
|
||||
fileCreationPhotoDate,
|
||||
fileLocation,
|
||||
filePublicMagicMetadata,
|
||||
updateRemotePublicMagicMetadata,
|
||||
type ParsedMetadataDate,
|
||||
} from "@/media/file-metadata";
|
||||
@@ -62,7 +63,6 @@ import { FlexWrapper } from "@ente/shared/components/Container";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
import { getPublicMagicMetadataSync } from "@ente/shared/file-metadata";
|
||||
import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
|
||||
import CameraOutlinedIcon from "@mui/icons-material/CameraOutlined";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
@@ -669,8 +669,10 @@ const CreationTime: React.FC<CreationTimeProps> = ({
|
||||
const openEditMode = () => setIsInEditMode(true);
|
||||
const closeEditMode = () => setIsInEditMode(false);
|
||||
|
||||
const publicMagicMetadata = getPublicMagicMetadataSync(file);
|
||||
const originalDate = fileCreationPhotoDate(file, publicMagicMetadata);
|
||||
const originalDate = fileCreationPhotoDate(
|
||||
file,
|
||||
filePublicMagicMetadata(file),
|
||||
);
|
||||
|
||||
const saveEdits = async (pickedTime: ParsedMetadataDate) => {
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,11 @@ import { decryptMetadataJSON, encryptMetadataJSON } from "@/base/crypto";
|
||||
import { authenticatedRequestHeaders, ensureOk } from "@/base/http";
|
||||
import { apiURL } from "@/base/origins";
|
||||
import { type Location } from "@/base/types";
|
||||
import { type EnteFile, type FilePublicMagicMetadata } from "@/media/file";
|
||||
import {
|
||||
fileLogID,
|
||||
type EnteFile,
|
||||
type FilePublicMagicMetadata,
|
||||
} from "@/media/file";
|
||||
import { nullToUndefined } from "@/utils/transform";
|
||||
import { z } from "zod";
|
||||
import { mergeMetadata1 } from "./file";
|
||||
@@ -290,6 +294,27 @@ const PublicMagicMetadata = z
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
/**
|
||||
* Return the public magic metadata for an {@link EnteFile}.
|
||||
*
|
||||
* We are not expected to be in a scenario where the file gets to the UI without
|
||||
* having its public magic metadata decrypted, so this function is a sanity
|
||||
* check and should be a no-op in usually. It'll throw if it finds its
|
||||
* assumptions broken. Once the types have been refactored this entire
|
||||
* check/cast shouldn't be needed, and this should become a trivial accessor.
|
||||
*/
|
||||
export const filePublicMagicMetadata = (file: EnteFile) => {
|
||||
if (!file.pubMagicMetadata) return undefined;
|
||||
if (typeof file.pubMagicMetadata.data == "string") {
|
||||
throw new Error(
|
||||
`Public magic metadata for ${fileLogID(file)} had not been decrypted even when the file reached the UI layer`,
|
||||
);
|
||||
}
|
||||
// This cast is unavoidable in the current setup. We need to refactor the
|
||||
// types so that this cast in not needed.
|
||||
return file.pubMagicMetadata.data as PublicMagicMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the hash of the file by reading it from its metadata.
|
||||
*
|
||||
|
||||
@@ -2,8 +2,7 @@ import { assertionFailed } from "@/base/assert";
|
||||
import { newID } from "@/base/id";
|
||||
import { ensureLocalUser } from "@/base/local-user";
|
||||
import type { EnteFile } from "@/media/file";
|
||||
import { metadataHash } from "@/media/file-metadata";
|
||||
import { getPublicMagicMetadataSync } from "@ente/shared/file-metadata";
|
||||
import { filePublicMagicMetadata, metadataHash } from "@/media/file-metadata";
|
||||
import {
|
||||
addToCollection,
|
||||
createCollectionNameByID,
|
||||
@@ -310,7 +309,7 @@ const duplicateGroupItemToRetain = (duplicateGroup: DuplicateGroup) => {
|
||||
const itemsWithCaption: DuplicateGroup["items"] = [];
|
||||
const itemsWithOtherEdits: DuplicateGroup["items"] = [];
|
||||
for (const item of duplicateGroup.items) {
|
||||
const pubMM = getPublicMagicMetadataSync(item.file);
|
||||
const pubMM = filePublicMagicMetadata(item.file);
|
||||
if (!pubMM) continue;
|
||||
if (pubMM.caption) itemsWithCaption.push(item);
|
||||
if (pubMM.editedName ?? pubMM.editedTime)
|
||||
|
||||
@@ -3,9 +3,12 @@ import { logUnhandledErrorsAndRejectionsInWorker } from "@/base/log-web";
|
||||
import type { Location } from "@/base/types";
|
||||
import type { Collection } from "@/media/collection";
|
||||
import type { EnteFile } from "@/media/file";
|
||||
import { fileCreationPhotoDate, fileLocation } from "@/media/file-metadata";
|
||||
import {
|
||||
fileCreationPhotoDate,
|
||||
fileLocation,
|
||||
filePublicMagicMetadata,
|
||||
} from "@/media/file-metadata";
|
||||
import { nullToUndefined } from "@/utils/transform";
|
||||
import { getPublicMagicMetadataSync } from "@ente/shared/file-metadata";
|
||||
import type { Component } from "chrono-node";
|
||||
import * as chrono from "chrono-node";
|
||||
import { expose } from "comlink";
|
||||
@@ -383,7 +386,7 @@ const isMatchingFile = (file: EnteFile, suggestion: SearchSuggestion) => {
|
||||
case "date":
|
||||
return isDateComponentsMatch(
|
||||
suggestion.dateComponents,
|
||||
fileCreationPhotoDate(file, getPublicMagicMetadataSync(file)),
|
||||
fileCreationPhotoDate(file, filePublicMagicMetadata(file)),
|
||||
);
|
||||
|
||||
case "location": {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { isDevBuild } from "@/base/env";
|
||||
import { type EnteFile, fileLogID } from "@/media/file";
|
||||
import {
|
||||
decryptPublicMagicMetadata,
|
||||
type PublicMagicMetadata,
|
||||
} from "@/media/file-metadata";
|
||||
|
||||
/**
|
||||
* On-demand decrypt the public magic metadata for an {@link EnteFile} for code
|
||||
* running synchronously.
|
||||
*
|
||||
* It both modifies the given file object, and also returns the decrypted
|
||||
* metadata.
|
||||
*
|
||||
* We are not expected to be in a scenario where the file gets to the UI without
|
||||
* having its public magic metadata decrypted, so this function is a sanity
|
||||
* check and should be a no-op in usually. On debug builds it'll throw if it
|
||||
* finds its assumptions broken.
|
||||
*/
|
||||
export const getPublicMagicMetadataSync = (file: EnteFile) => {
|
||||
if (!file.pubMagicMetadata) return undefined;
|
||||
if (typeof file.pubMagicMetadata.data == "string") {
|
||||
if (isDevBuild)
|
||||
throw new Error(
|
||||
`Public magic metadata for ${fileLogID(file)} had not been decrypted even when the file reached the UI layer`,
|
||||
);
|
||||
decryptPublicMagicMetadata(file);
|
||||
}
|
||||
// This cast is unavoidable in the current setup. We need to refactor the
|
||||
// types so that this cast in not needed.
|
||||
return file.pubMagicMetadata.data as PublicMagicMetadata;
|
||||
};
|
||||
Reference in New Issue
Block a user