diff --git a/web/apps/cast/src/services/render.ts b/web/apps/cast/src/services/render.ts index 18c4fa928f..672f95f269 100644 --- a/web/apps/cast/src/services/render.ts +++ b/web/apps/cast/src/services/render.ts @@ -9,6 +9,12 @@ import { FILE_TYPE } from "@/media/file-type"; import { isHEICExtension, isNonWebImageFileExtension } from "@/media/formats"; import { heicToJPEG } from "@/media/heic-convert"; import { decodeLivePhoto } from "@/media/live-photo"; +import type { + EncryptedEnteFile, + EnteFile, + FileMagicMetadata, + FilePublicMagicMetadata, +} from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; import { apiOrigin, customAPIOrigin } from "@/next/origins"; @@ -21,12 +27,6 @@ import HTTPService from "@ente/shared/network/HTTPService"; import type { AxiosResponse } from "axios"; import type { CastData } from "services/cast-data"; import { detectMediaMIMEType } from "services/detect-type"; -import type { - EncryptedEnteFile, - EnteFile, - FileMagicMetadata, - FilePublicMagicMetadata, -} from "types/file"; import { isChromecast } from "./chromecast"; /** diff --git a/web/apps/cast/src/types/file/index.ts b/web/apps/cast/src/types/file/index.ts index f294a54a18..c1bb5304a8 100644 --- a/web/apps/cast/src/types/file/index.ts +++ b/web/apps/cast/src/types/file/index.ts @@ -3,7 +3,7 @@ import type { EncryptedMagicMetadata, MagicMetadataCore, VISIBILITY_STATE, -} from "types/magicMetadata"; +} from "@/new/photos/types/magicMetadata"; export interface MetadataFileAttributes { encryptedData: string; diff --git a/web/apps/photos/src/components/Collections/CollectionCard.tsx b/web/apps/photos/src/components/Collections/CollectionCard.tsx index 9217f077fd..5bf247020e 100644 --- a/web/apps/photos/src/components/Collections/CollectionCard.tsx +++ b/web/apps/photos/src/components/Collections/CollectionCard.tsx @@ -1,10 +1,10 @@ +import { EnteFile } from "@/new/photos/types/file"; import { LoadingThumbnail, StaticThumbnail, } from "components/PlaceholderThumbnails"; import { useEffect, useState } from "react"; import downloadManager from "services/download"; -import { EnteFile } from "types/file"; export default function CollectionCard(props: { children?: any; diff --git a/web/apps/photos/src/components/Collections/CollectionOptions/index.tsx b/web/apps/photos/src/components/Collections/CollectionOptions/index.tsx index 61dcbc9e7e..5d03331918 100644 --- a/web/apps/photos/src/components/Collections/CollectionOptions/index.tsx +++ b/web/apps/photos/src/components/Collections/CollectionOptions/index.tsx @@ -1,3 +1,4 @@ +import { VISIBILITY_STATE } from "@/new/photos/types/magicMetadata"; import log from "@/next/log"; import { HorizontalFlex } from "@ente/shared/components/Container"; import OverflowMenu from "@ente/shared/components/OverflowMenu/menu"; @@ -18,7 +19,6 @@ import * as CollectionAPI from "services/collectionService"; import * as TrashService from "services/trashService"; import { Collection } from "types/collection"; import { SetFilesDownloadProgressAttributesCreator } from "types/gallery"; -import { VISIBILITY_STATE } from "types/magicMetadata"; import { changeCollectionOrder, changeCollectionSortOrder, diff --git a/web/apps/photos/src/components/ExportFinished.tsx b/web/apps/photos/src/components/ExportFinished.tsx index 43ba027578..24c142d75a 100644 --- a/web/apps/photos/src/components/ExportFinished.tsx +++ b/web/apps/photos/src/components/ExportFinished.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { SpaceBetweenFlex } from "@ente/shared/components/Container"; import { formatDateTime } from "@ente/shared/time/format"; import { @@ -9,7 +10,6 @@ import { } from "@mui/material"; import { t } from "i18next"; import { useState } from "react"; -import { EnteFile } from "types/file"; import { formatNumber } from "utils/number/format"; import ExportPendingList from "./ExportPendingList"; import LinkButton from "./pages/gallery/LinkButton"; diff --git a/web/apps/photos/src/components/ExportModal.tsx b/web/apps/photos/src/components/ExportModal.tsx index 0dcefbda6b..012244f734 100644 --- a/web/apps/photos/src/components/ExportModal.tsx +++ b/web/apps/photos/src/components/ExportModal.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import ChangeDirectoryOption from "@ente/shared/components/ChangeDirectoryOption"; import { @@ -24,7 +25,6 @@ import exportService, { selectAndPrepareExportDirectory, } from "services/export"; import { ExportProgress, ExportSettings } from "types/export"; -import { EnteFile } from "types/file"; import { getExportDirectoryDoesNotExistMessage } from "utils/ui"; import { DirectoryPath } from "./Directory"; import ExportFinished from "./ExportFinished"; diff --git a/web/apps/photos/src/components/ExportPendingList.tsx b/web/apps/photos/src/components/ExportPendingList.tsx index 93aa850787..88abf66b22 100644 --- a/web/apps/photos/src/components/ExportPendingList.tsx +++ b/web/apps/photos/src/components/ExportPendingList.tsx @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import { FlexWrapper } from "@ente/shared/components/Container"; import DialogBoxV2 from "@ente/shared/components/DialogBoxV2"; import { Box, styled } from "@mui/material"; import ItemList from "components/ItemList"; import { t } from "i18next"; -import { EnteFile } from "types/file"; import CollectionCard from "./Collections/CollectionCard"; import { ResultPreviewTile } from "./Collections/styledComponents"; diff --git a/web/apps/photos/src/components/FixCreationTime.tsx b/web/apps/photos/src/components/FixCreationTime.tsx index 757ca27376..1c060250ff 100644 --- a/web/apps/photos/src/components/FixCreationTime.tsx +++ b/web/apps/photos/src/components/FixCreationTime.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import DialogBox from "@ente/shared/components/DialogBox/"; import { Button, @@ -14,7 +15,6 @@ import { t } from "i18next"; import { GalleryContext } from "pages/gallery"; import React, { useContext, useEffect, useState } from "react"; import { updateCreationTimeWithExif } from "services/fix-exif"; -import { EnteFile } from "types/file"; import EnteDateTimePicker from "./EnteDateTimePicker"; export interface FixCreationTimeAttributes { diff --git a/web/apps/photos/src/components/PhotoFrame.tsx b/web/apps/photos/src/components/PhotoFrame.tsx index 89f1ce887e..6095a31765 100644 --- a/web/apps/photos/src/components/PhotoFrame.tsx +++ b/web/apps/photos/src/components/PhotoFrame.tsx @@ -1,4 +1,6 @@ import { FILE_TYPE } from "@/media/file-type"; +import type { LivePhotoSourceURL, SourceURLs } from "@/new/photos/types/file"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { PHOTOS_PAGES } from "@ente/shared/constants/pages"; import { CustomError } from "@ente/shared/error"; @@ -12,11 +14,7 @@ import PhotoSwipe from "photoswipe"; import { useContext, useEffect, useState } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import { Duplicate } from "services/deduplicationService"; -import DownloadManager, { - LivePhotoSourceURL, - SourceURLs, -} from "services/download"; -import { EnteFile } from "types/file"; +import DownloadManager from "services/download"; import { SelectedState, SetFilesDownloadProgressAttributesCreator, diff --git a/web/apps/photos/src/components/PhotoList/dedupe.tsx b/web/apps/photos/src/components/PhotoList/dedupe.tsx index 61b9958ef0..56a9638e3f 100644 --- a/web/apps/photos/src/components/PhotoList/dedupe.tsx +++ b/web/apps/photos/src/components/PhotoList/dedupe.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { FlexWrapper } from "@ente/shared/components/Container"; import { Box, styled } from "@mui/material"; import { @@ -18,7 +19,6 @@ import { areEqual, } from "react-window"; import { Duplicate } from "services/deduplicationService"; -import { EnteFile } from "types/file"; import { formattedByteSize } from "utils/units"; export enum ITEM_TYPE { diff --git a/web/apps/photos/src/components/PhotoList/index.tsx b/web/apps/photos/src/components/PhotoList/index.tsx index bfc06d8c78..85c6db57cb 100644 --- a/web/apps/photos/src/components/PhotoList/index.tsx +++ b/web/apps/photos/src/components/PhotoList/index.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { FlexWrapper } from "@ente/shared/components/Container"; import { formatDate } from "@ente/shared/time/format"; import { Box, Checkbox, Link, Typography, styled } from "@mui/material"; @@ -21,7 +22,6 @@ import { ListChildComponentProps, areEqual, } from "react-window"; -import { EnteFile } from "types/file"; import { handleSelectCreator } from "utils/photoFrame"; import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery"; import { formattedByteSize } from "utils/units"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx index 3a5dbb6bc2..2eddc5fd33 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCaption.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { FlexWrapper } from "@ente/shared/components/Container"; import Close from "@mui/icons-material/Close"; @@ -6,7 +7,6 @@ import { Box, IconButton, TextField } from "@mui/material"; import { Formik } from "formik"; import { t } from "i18next"; import { useState } from "react"; -import { EnteFile } from "types/file"; import { changeCaption, updateExistingFilePubMetadata } from "utils/file"; import * as Yup from "yup"; import { SmallLoadingSpinner } from "../styledComponents/SmallLoadingSpinner"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx index 9d5cad467c..85be6a3c1a 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderCreationTime.tsx @@ -1,10 +1,10 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { FlexWrapper } from "@ente/shared/components/Container"; import { formatDate, formatTime } from "@ente/shared/time/format"; import CalendarTodayIcon from "@mui/icons-material/CalendarToday"; import EnteDateTimePicker from "components/EnteDateTimePicker"; import { useState } from "react"; -import { EnteFile } from "types/file"; import { changeFileCreationTime, updateExistingFilePubMetadata, diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx index e9e27d55e8..caa9be2de4 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/RenderFileName.tsx @@ -1,4 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; import { FlexWrapper } from "@ente/shared/components/Container"; @@ -6,7 +7,6 @@ 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 { EnteFile } from "types/file"; import { changeFileName, updateExistingFilePubMetadata } from "utils/file"; import { formattedByteSize } from "utils/units"; import { FileNameEditDialog } from "./FileNameEditDialog"; diff --git a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx index 5a17f43d17..6fab590737 100644 --- a/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/FileInfo/index.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import CopyButton from "@ente/shared/components/CodeBlock/CopyButton"; import { FlexWrapper } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; @@ -18,7 +19,6 @@ import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; import { useContext, useEffect, useMemo, useState } from "react"; import { getEXIFLocation } from "services/exif"; -import { EnteFile } from "types/file"; import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery"; import { getMapDisableConfirmationDialog, diff --git a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx index 9bb27b4b2a..0d41aba55d 100644 --- a/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/ImageEditorOverlay/index.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; @@ -36,7 +37,6 @@ import { createContext, useContext, useEffect, useRef, useState } from "react"; import { getLocalCollections } from "services/collectionService"; import downloadManager from "services/download"; import uploadManager from "services/upload/uploadManager"; -import { EnteFile } from "types/file"; import { getEditorCloseConfirmationMessage } from "utils/ui"; import ColoursMenu from "./ColoursMenu"; import CropMenu, { cropRegionOfCanvas, getCropRegionArgs } from "./CropMenu"; diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index c7383efb13..db3d11b5c2 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import Photoswipe from "photoswipe"; import PhotoswipeUIDefault from "photoswipe/dist/photoswipe-ui-default"; @@ -6,7 +7,6 @@ import { addToFavorites, removeFromFavorites, } from "services/collectionService"; -import { EnteFile } from "types/file"; import { copyFileToClipboard, downloadSingleFile, @@ -16,6 +16,7 @@ import { import { FILE_TYPE } from "@/media/file-type"; import { isNonWebImageFileExtension } from "@/media/formats"; +import type { LoadedLivePhotoSourceURL } from "@/new/photos/types/file"; import { lowercaseExtension } from "@/next/file"; import { FlexWrapper } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; @@ -44,7 +45,7 @@ import isElectron from "is-electron"; import { AppContext } from "pages/_app"; import { GalleryContext } from "pages/gallery"; import { detectFileTypeInfo } from "services/detect-type"; -import downloadManager, { LoadedLivePhotoSourceURL } from "services/download"; +import downloadManager from "services/download"; import { getParsedExifData } from "services/exif"; import { trashFiles } from "services/fileService"; import { SetFilesDownloadProgressAttributesCreator } from "types/gallery"; diff --git a/web/apps/photos/src/components/Search/SearchBar/index.tsx b/web/apps/photos/src/components/Search/SearchBar/index.tsx index 5ba0462107..8d7612d4b5 100644 --- a/web/apps/photos/src/components/Search/SearchBar/index.tsx +++ b/web/apps/photos/src/components/Search/SearchBar/index.tsx @@ -1,7 +1,7 @@ import { Collection } from "types/collection"; import { SearchBarMobile } from "./searchBarMobile"; -import { EnteFile } from "types/file"; +import { EnteFile } from "@/new/photos/types/file"; import { UpdateSearch } from "types/search"; import SearchInput from "./searchInput"; import { SearchBarWrapper } from "./styledComponents"; diff --git a/web/apps/photos/src/components/Search/SearchBar/searchInput/index.tsx b/web/apps/photos/src/components/Search/SearchBar/searchInput/index.tsx index 62d4a1f434..d2fc70ee30 100644 --- a/web/apps/photos/src/components/Search/SearchBar/searchInput/index.tsx +++ b/web/apps/photos/src/components/Search/SearchBar/searchInput/index.tsx @@ -1,4 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import CloseIcon from "@mui/icons-material/Close"; import { IconButton } from "@mui/material"; import { t } from "i18next"; @@ -17,7 +18,6 @@ import { } from "services/searchService"; import { Collection } from "types/collection"; import { LocationTagData } from "types/entity"; -import { EnteFile } from "types/file"; import { ClipSearchScores, DateValue, diff --git a/web/apps/photos/src/components/ml/PeopleList.tsx b/web/apps/photos/src/components/ml/PeopleList.tsx index 38e70c3a8d..4e59588379 100644 --- a/web/apps/photos/src/components/ml/PeopleList.tsx +++ b/web/apps/photos/src/components/ml/PeopleList.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { blobCache } from "@/next/blob-cache"; import { Skeleton, styled } from "@mui/material"; import { Legend } from "components/PhotoViewer/styledComponents/Legend"; @@ -5,7 +6,6 @@ import { t } from "i18next"; import React, { useEffect, useState } from "react"; import { unidentifiedFaceIDs } from "services/face/indexer"; import type { Person } from "services/face/people"; -import { EnteFile } from "types/file"; const FaceChipContainer = styled("div")` display: flex; diff --git a/web/apps/photos/src/components/pages/gallery/Avatar.tsx b/web/apps/photos/src/components/pages/gallery/Avatar.tsx index caa9b8b782..12d61a34df 100644 --- a/web/apps/photos/src/components/pages/gallery/Avatar.tsx +++ b/web/apps/photos/src/components/pages/gallery/Avatar.tsx @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { styled } from "@mui/material"; import { useTheme } from "@mui/material/styles"; import { GalleryContext } from "pages/gallery"; import React, { useContext, useLayoutEffect, useState } from "react"; -import { EnteFile } from "types/file"; interface AvatarProps { file?: EnteFile; diff --git a/web/apps/photos/src/components/pages/gallery/Navbar.tsx b/web/apps/photos/src/components/pages/gallery/Navbar.tsx index 4a710faa81..08a52cf628 100644 --- a/web/apps/photos/src/components/pages/gallery/Navbar.tsx +++ b/web/apps/photos/src/components/pages/gallery/Navbar.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import { FlexWrapper, HorizontalFlex } from "@ente/shared/components/Container"; import SidebarToggler from "@ente/shared/components/Navbar/SidebarToggler"; import NavbarBase from "@ente/shared/components/Navbar/base"; @@ -9,7 +10,6 @@ import { t } from "i18next"; import { AppContext } from "pages/_app"; import React from "react"; import { Collection } from "types/collection"; -import { EnteFile } from "types/file"; import { UpdateSearch } from "types/search"; interface Iprops { diff --git a/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx b/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx index 8369b1e860..0b4c386c4b 100644 --- a/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx +++ b/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx @@ -1,4 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { Overlay } from "@ente/shared/components/Container"; import { CustomError } from "@ente/shared/error"; @@ -17,7 +18,6 @@ import { DeduplicateContext } from "pages/deduplicate"; import { GalleryContext } from "pages/gallery"; import React, { useContext, useEffect, useRef, useState } from "react"; import DownloadManager from "services/download"; -import { EnteFile } from "types/file"; import { shouldShowAvatar } from "utils/file"; import Avatar from "./Avatar"; diff --git a/web/apps/photos/src/pages/deduplicate/index.tsx b/web/apps/photos/src/pages/deduplicate/index.tsx index cbd297f78c..588df0a3dd 100644 --- a/web/apps/photos/src/pages/deduplicate/index.tsx +++ b/web/apps/photos/src/pages/deduplicate/index.tsx @@ -1,11 +1,11 @@ -import { t } from "i18next"; - +import { getLocalFiles } from "@/new/photos/services/files"; import PhotoFrame from "components/PhotoFrame"; import { ALL_SECTION } from "constants/collection"; +import { t } from "i18next"; import { AppContext } from "pages/_app"; import { createContext, useContext, useEffect, useState } from "react"; import { Duplicate, getDuplicates } from "services/deduplicationService"; -import { getLocalFiles, syncFiles, trashFiles } from "services/fileService"; +import { syncFiles, trashFiles } from "services/fileService"; import { SelectedState } from "types/gallery"; import { VerticallyCentered } from "@ente/shared/components/Container"; diff --git a/web/apps/photos/src/pages/gallery/index.tsx b/web/apps/photos/src/pages/gallery/index.tsx index 2b7a180137..360100c01c 100644 --- a/web/apps/photos/src/pages/gallery/index.tsx +++ b/web/apps/photos/src/pages/gallery/index.tsx @@ -1,6 +1,8 @@ import { WhatsNew } from "@/new/photos/components/WhatsNew"; import { shouldShowWhatsNew } from "@/new/photos/services/changelog"; import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags"; +import { getLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { CenteredFlex } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; @@ -90,13 +92,12 @@ import { import downloadManager from "services/download"; import { syncCLIPEmbeddings } from "services/embeddingService"; import { syncEntities } from "services/entityService"; -import { getLocalFiles, syncFiles } from "services/fileService"; +import { syncFiles } from "services/fileService"; import locationSearchService from "services/locationSearchService"; import { getLocalTrashedFiles, syncTrash } from "services/trashService"; import uploadManager from "services/upload/uploadManager"; import { isTokenValid, syncMapEnabled } from "services/userService"; import { Collection, CollectionSummaries } from "types/collection"; -import { EnteFile } from "types/file"; import { GalleryContextType, SelectedState, diff --git a/web/apps/photos/src/pages/shared-albums/index.tsx b/web/apps/photos/src/pages/shared-albums/index.tsx index 6962d7c450..2976ed1e88 100644 --- a/web/apps/photos/src/pages/shared-albums/index.tsx +++ b/web/apps/photos/src/pages/shared-albums/index.tsx @@ -1,3 +1,4 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { CenteredFlex, @@ -58,7 +59,6 @@ import { verifyPublicCollectionPassword, } from "services/publicCollectionService"; import { Collection } from "types/collection"; -import { EnteFile } from "types/file"; import { SelectedState, SetFilesDownloadProgressAttributes, diff --git a/web/apps/photos/src/services/clip-service.ts b/web/apps/photos/src/services/clip-service.ts index 915f9ae03e..f0de7c3127 100644 --- a/web/apps/photos/src/services/clip-service.ts +++ b/web/apps/photos/src/services/clip-service.ts @@ -1,4 +1,6 @@ import { FILE_TYPE } from "@/media/file-type"; +import { getAllLocalFiles, getLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import ComlinkCryptoWorker from "@ente/shared/crypto"; @@ -8,11 +10,9 @@ import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; import isElectron from "is-electron"; import PQueue from "p-queue"; import { Embedding } from "types/embedding"; -import { EnteFile } from "types/file"; import { getPersonalFiles } from "utils/file"; import downloadManager from "./download"; import { localCLIPEmbeddings, putEmbedding } from "./embeddingService"; -import { getAllLocalFiles, getLocalFiles } from "./fileService"; /** Status of CLIP indexing on the images in the user's local library. */ export interface CLIPIndexingStatus { diff --git a/web/apps/photos/src/services/collectionService.ts b/web/apps/photos/src/services/collectionService.ts index 485ea7cb76..17b9da68dc 100644 --- a/web/apps/photos/src/services/collectionService.ts +++ b/web/apps/photos/src/services/collectionService.ts @@ -1,10 +1,18 @@ +import { getLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; +import { + EncryptedMagicMetadata, + SUB_TYPE, + UpdateMagicMetadataRequest, + VISIBILITY_STATE, +} from "@/new/photos/types/magicMetadata"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; import ComlinkCryptoWorker from "@ente/shared/crypto"; import { CustomError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import localForage from "@ente/shared/storage/localForage"; -import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; +import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; import { getActualKey } from "@ente/shared/user"; import type { User } from "@ente/shared/user/types"; @@ -40,13 +48,6 @@ import { RemoveFromCollectionRequest, UpdatePublicURL, } from "types/collection"; -import { EnteFile } from "types/file"; -import { - EncryptedMagicMetadata, - SUB_TYPE, - UpdateMagicMetadataRequest, - VISIBILITY_STATE, -} from "types/magicMetadata"; import { FamilyData } from "types/user"; import { changeCollectionSubType, @@ -73,7 +74,6 @@ import { isPinnedCollection, updateMagicMetadata, } from "utils/magicMetadata"; -import { getLocalFiles } from "./fileService"; import { getPublicKey } from "./userService"; const COLLECTION_TABLE = "collections"; diff --git a/web/apps/photos/src/services/deduplicationService.ts b/web/apps/photos/src/services/deduplicationService.ts index b17d9f4f0b..d1edc4f642 100644 --- a/web/apps/photos/src/services/deduplicationService.ts +++ b/web/apps/photos/src/services/deduplicationService.ts @@ -1,11 +1,11 @@ import { hasFileHash } from "@/media/file"; import { FILE_TYPE } from "@/media/file-type"; import type { Metadata } from "@/media/types/file"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; import HTTPService from "@ente/shared/network/HTTPService"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; -import { EnteFile } from "types/file"; interface DuplicatesResponse { duplicates: Array<{ diff --git a/web/apps/photos/src/services/download/clients/photos.ts b/web/apps/photos/src/services/download/clients/photos.ts index ac88fa0324..3740061805 100644 --- a/web/apps/photos/src/services/download/clients/photos.ts +++ b/web/apps/photos/src/services/download/clients/photos.ts @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import { customAPIOrigin } from "@/next/origins"; import { CustomError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import { retryAsyncFunction } from "@ente/shared/utils"; import { DownloadClient } from "services/download"; -import { EnteFile } from "types/file"; export class PhotosDownloadClient implements DownloadClient { constructor( diff --git a/web/apps/photos/src/services/download/clients/publicAlbums.ts b/web/apps/photos/src/services/download/clients/publicAlbums.ts index 4a15407e59..9875c8d0fc 100644 --- a/web/apps/photos/src/services/download/clients/publicAlbums.ts +++ b/web/apps/photos/src/services/download/clients/publicAlbums.ts @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import { customAPIOrigin } from "@/next/origins"; import { CustomError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import { retryAsyncFunction } from "@ente/shared/utils"; import { DownloadClient } from "services/download"; -import { EnteFile } from "types/file"; export class PublicAlbumsDownloadClient implements DownloadClient { private token: string; diff --git a/web/apps/photos/src/services/download/index.ts b/web/apps/photos/src/services/download/index.ts index a080acd92e..179aa7cbc8 100644 --- a/web/apps/photos/src/services/download/index.ts +++ b/web/apps/photos/src/services/download/index.ts @@ -1,5 +1,10 @@ import { FILE_TYPE } from "@/media/file-type"; import { decodeLivePhoto } from "@/media/live-photo"; +import { + EnteFile, + type LivePhotoSourceURL, + type SourceURLs, +} from "@/new/photos/types/file"; import { blobCache, type BlobCache } from "@/next/blob-cache"; import log from "@/next/log"; import ComlinkCryptoWorker from "@ente/shared/crypto"; @@ -9,38 +14,10 @@ import { isPlaybackPossible } from "@ente/shared/media/video-playback"; import type { Remote } from "comlink"; import isElectron from "is-electron"; import * as ffmpeg from "services/ffmpeg"; -import { EnteFile } from "types/file"; import { getRenderableImage } from "utils/file"; import { PhotosDownloadClient } from "./clients/photos"; import { PublicAlbumsDownloadClient } from "./clients/publicAlbums"; -export type LivePhotoSourceURL = { - image: () => Promise; - video: () => Promise; -}; - -export type LoadedLivePhotoSourceURL = { - image: string; - video: string; -}; - -export type SourceURLs = { - url: string | LivePhotoSourceURL | LoadedLivePhotoSourceURL; - isOriginal: boolean; - isRenderable: boolean; - type: "normal" | "livePhoto"; - /** - * Best effort attempt at obtaining the MIME type. - * - * Known cases where it is missing: - * - * - Live photos (these have a different code path for obtaining the URL). - * - A video that is passes the isPlayable test in the browser. - * - */ - mimeType?: string; -}; - export type OnDownloadProgress = (event: { loaded: number; total: number; diff --git a/web/apps/photos/src/services/embeddingService.ts b/web/apps/photos/src/services/embeddingService.ts index f78d410042..2c91ca01c9 100644 --- a/web/apps/photos/src/services/embeddingService.ts +++ b/web/apps/photos/src/services/embeddingService.ts @@ -1,4 +1,6 @@ import type { EmbeddingModel } from "@/new/photos/services/embedding"; +import { getAllLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; import { inWorker } from "@/next/env"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; @@ -14,10 +16,8 @@ import type { GetEmbeddingDiffResponse, PutEmbeddingRequest, } from "types/embedding"; -import { EnteFile } from "types/file"; import { getLocalCollections } from "./collectionService"; import type { FaceIndex } from "./face/types"; -import { getAllLocalFiles } from "./fileService"; import { getLocalTrashedFiles } from "./trashService"; type FileML = FaceIndex & { diff --git a/web/apps/photos/src/services/export/index.ts b/web/apps/photos/src/services/export/index.ts index d54ae205ec..6acae01e28 100644 --- a/web/apps/photos/src/services/export/index.ts +++ b/web/apps/photos/src/services/export/index.ts @@ -1,6 +1,8 @@ import { FILE_TYPE } from "@/media/file-type"; import { decodeLivePhoto } from "@/media/live-photo"; import type { Metadata } from "@/media/types/file"; +import { getAllLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { wait } from "@/utils/promise"; @@ -22,7 +24,6 @@ import { ExportUIUpdaters, FileExportNames, } from "types/export"; -import { EnteFile } from "types/file"; import { constructCollectionNameMap, getCollectionUserFacingName, @@ -37,7 +38,6 @@ import { safeDirectoryName, safeFileName } from "utils/native-fs"; import { writeStream } from "utils/native-stream"; import { getAllLocalCollections } from "../collectionService"; import downloadManager from "../download"; -import { getAllLocalFiles } from "../fileService"; import { migrateExport } from "./migration"; /** Name of the JSON file in which we keep the state of the export. */ diff --git a/web/apps/photos/src/services/export/migration.ts b/web/apps/photos/src/services/export/migration.ts index 234427de83..f452a52642 100644 --- a/web/apps/photos/src/services/export/migration.ts +++ b/web/apps/photos/src/services/export/migration.ts @@ -1,5 +1,7 @@ import { FILE_TYPE } from "@/media/file-type"; import { decodeLivePhoto } from "@/media/live-photo"; +import { getAllLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import { nameAndExtension } from "@/next/file"; import log from "@/next/log"; @@ -8,7 +10,6 @@ import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; import type { User } from "@ente/shared/user/types"; import { getLocalCollections } from "services/collectionService"; import downloadManager from "services/download"; -import { getAllLocalFiles } from "services/fileService"; import { Collection } from "types/collection"; import { CollectionExportNames, @@ -20,7 +21,6 @@ import { ExportedCollectionPaths, FileExportNames, } from "types/export"; -import { EnteFile } from "types/file"; import { getNonEmptyPersonalCollections } from "utils/collection"; import { getIDBasedSortedFiles, diff --git a/web/apps/photos/src/services/face/f-index.ts b/web/apps/photos/src/services/face/f-index.ts index cdcc4fe919..584b733148 100644 --- a/web/apps/photos/src/services/face/f-index.ts +++ b/web/apps/photos/src/services/face/f-index.ts @@ -1,5 +1,6 @@ import { FILE_TYPE } from "@/media/file-type"; import { decodeLivePhoto } from "@/media/live-photo"; +import type { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { workerBridge } from "@/next/worker/worker-bridge"; import { Matrix } from "ml-matrix"; @@ -12,7 +13,6 @@ import { scale, translate, } from "transformation-matrix"; -import type { EnteFile } from "types/file"; import { getRenderableImage } from "utils/file"; import { saveFaceCrop } from "./crop"; import { diff --git a/web/apps/photos/src/services/face/face.worker.ts b/web/apps/photos/src/services/face/face.worker.ts index af0995951f..d74c235cc0 100644 --- a/web/apps/photos/src/services/face/face.worker.ts +++ b/web/apps/photos/src/services/face/face.worker.ts @@ -1,7 +1,7 @@ +import { EnteFile } from "@/new/photos/types/file"; import { expose } from "comlink"; import downloadManager from "services/download"; import mlService from "services/machineLearning/machineLearningService"; -import { EnteFile } from "types/file"; export class DedicatedMLWorker { public async closeLocalSyncContext() { diff --git a/web/apps/photos/src/services/face/indexer.ts b/web/apps/photos/src/services/face/indexer.ts index 5314a15e0b..c6cdc3295a 100644 --- a/web/apps/photos/src/services/face/indexer.ts +++ b/web/apps/photos/src/services/face/indexer.ts @@ -2,11 +2,11 @@ import { isBetaUser, isInternalUser, } from "@/new/photos/services/feature-flags"; +import { getAllLocalFiles } from "@/new/photos/services/files"; +import type { EnteFile } from "@/new/photos/types/file"; import { ComlinkWorker } from "@/next/worker/comlink-worker"; import { ensure } from "@/utils/ensure"; import type { Remote } from "comlink"; -import { getAllLocalFiles } from "services/fileService"; -import type { EnteFile } from "types/file"; import { faceIndex, indexableFileIDs, diff --git a/web/apps/photos/src/services/face/indexer.worker.ts b/web/apps/photos/src/services/face/indexer.worker.ts index 6cf1e5008f..8de8b61d16 100644 --- a/web/apps/photos/src/services/face/indexer.worker.ts +++ b/web/apps/photos/src/services/face/indexer.worker.ts @@ -1,5 +1,5 @@ +import type { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; -import type { EnteFile } from "types/file"; import { fileLogID } from "utils/file"; import { closeFaceDBConnectionsIfNeeded, diff --git a/web/apps/photos/src/services/face/mlWorkManager.ts b/web/apps/photos/src/services/face/mlWorkManager.ts index 1a89dc1575..d1d1dcbad8 100644 --- a/web/apps/photos/src/services/face/mlWorkManager.ts +++ b/web/apps/photos/src/services/face/mlWorkManager.ts @@ -1,4 +1,5 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { clientPackageNamePhotosDesktop } from "@/next/types/app"; @@ -8,7 +9,6 @@ import { getToken, getUserID } from "@ente/shared/storage/localStorage/helpers"; import debounce from "debounce"; import PQueue from "p-queue"; import type { DedicatedMLWorker } from "services/face/face.worker"; -import { EnteFile } from "types/file"; export type JobState = "Scheduled" | "Running" | "NotScheduled"; diff --git a/web/apps/photos/src/services/face/remote.ts b/web/apps/photos/src/services/face/remote.ts index 2fd50024da..2c4209ac28 100644 --- a/web/apps/photos/src/services/face/remote.ts +++ b/web/apps/photos/src/services/face/remote.ts @@ -1,7 +1,7 @@ +import type { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import ComlinkCryptoWorker from "@ente/shared/crypto"; import { putEmbedding } from "services/embeddingService"; -import type { EnteFile } from "types/file"; import type { FaceIndex } from "./types"; export const putFaceIndex = async ( diff --git a/web/apps/photos/src/services/fileService.ts b/web/apps/photos/src/services/fileService.ts index ebabc9dbfc..2e8621d693 100644 --- a/web/apps/photos/src/services/fileService.ts +++ b/web/apps/photos/src/services/fileService.ts @@ -1,21 +1,20 @@ -import log from "@/next/log"; -import { apiOrigin } from "@/next/origins"; -import ComlinkCryptoWorker from "@ente/shared/crypto"; -import { Events, eventBus } from "@ente/shared/events"; -import HTTPService from "@ente/shared/network/HTTPService"; -import localForage from "@ente/shared/storage/localForage"; -import { getToken } from "@ente/shared/storage/localStorage/helpers"; -import { REQUEST_BATCH_SIZE } from "constants/api"; -import { Collection } from "types/collection"; +import { getLocalFiles, setLocalFiles } from "@/new/photos/services/files"; import { EncryptedEnteFile, EnteFile, FileWithUpdatedMagicMetadata, FileWithUpdatedPublicMagicMetadata, TrashRequest, -} from "types/file"; +} from "@/new/photos/types/file"; +import { BulkUpdateMagicMetadataRequest } from "@/new/photos/types/magicMetadata"; +import log from "@/next/log"; +import { apiOrigin } from "@/next/origins"; +import ComlinkCryptoWorker from "@ente/shared/crypto"; +import HTTPService from "@ente/shared/network/HTTPService"; +import { getToken } from "@ente/shared/storage/localStorage/helpers"; +import { REQUEST_BATCH_SIZE } from "constants/api"; +import { Collection } from "types/collection"; import { SetFiles } from "types/gallery"; -import { BulkUpdateMagicMetadataRequest } from "types/magicMetadata"; import { batch } from "utils/common"; import { decryptFile, @@ -28,52 +27,6 @@ import { setCollectionLastSyncTime, } from "./collectionService"; -const FILES_TABLE = "files"; -const HIDDEN_FILES_TABLE = "hidden-files"; - -/** - * Return all files that we know about locally, both "normal" and "hidden". - */ -export const getAllLocalFiles = async () => - [].concat(await getLocalFiles("normal"), await getLocalFiles("hidden")); - -/** - * Return all files that we know about locally. By default it returns only - * "normal" (i.e. non-"hidden") files, but it can be passed the {@link type} - * "hidden" to get it to instead return hidden files that we know about locally. - */ -export const getLocalFiles = async (type: "normal" | "hidden" = "normal") => { - const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE; - const files: Array = - (await localForage.getItem(tableName)) || []; - return files; -}; - -const setLocalFiles = async (type: "normal" | "hidden", files: EnteFile[]) => { - try { - const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE; - await localForage.setItem(tableName, files); - try { - eventBus.emit(Events.LOCAL_FILES_UPDATED); - } catch (e) { - log.error("Error in localFileUpdated handlers", e); - } - } catch (e1) { - try { - const storageEstimate = await navigator.storage.estimate(); - log.error( - `failed to save files to indexedDB (storageEstimate was ${storageEstimate}`, - e1, - ); - log.info(`storage estimate ${JSON.stringify(storageEstimate)}`); - } catch (e2) { - log.error("failed to save files to indexedDB", e1); - log.error("failed to get storage stats", e2); - } - throw e1; - } -}; - export const syncFiles = async ( type: "normal" | "hidden", collections: Collection[], diff --git a/web/apps/photos/src/services/fix-exif.ts b/web/apps/photos/src/services/fix-exif.ts index f47e4c5ed0..a695f8d3a0 100644 --- a/web/apps/photos/src/services/fix-exif.ts +++ b/web/apps/photos/src/services/fix-exif.ts @@ -1,9 +1,9 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time"; import type { FixOption } from "components/FixCreationTime"; import { detectFileTypeInfo } from "services/detect-type"; -import { EnteFile } from "types/file"; import { changeFileCreationTime, updateExistingFilePubMetadata, diff --git a/web/apps/photos/src/services/machineLearning/machineLearningService.ts b/web/apps/photos/src/services/machineLearning/machineLearningService.ts index f28efe8b47..7dbadf9186 100644 --- a/web/apps/photos/src/services/machineLearning/machineLearningService.ts +++ b/web/apps/photos/src/services/machineLearning/machineLearningService.ts @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { CustomError, parseUploadErrorCodes } from "@ente/shared/error"; import PQueue from "p-queue"; import { syncAndGetFilesToIndex } from "services/face/indexer"; import { FaceIndexerWorker } from "services/face/indexer.worker"; -import { EnteFile } from "types/file"; const batchSize = 200; diff --git a/web/apps/photos/src/services/publicCollectionService.ts b/web/apps/photos/src/services/publicCollectionService.ts index 9dced45610..d33d89fc41 100644 --- a/web/apps/photos/src/services/publicCollectionService.ts +++ b/web/apps/photos/src/services/publicCollectionService.ts @@ -1,3 +1,4 @@ +import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; import ComlinkCryptoWorker from "@ente/shared/crypto"; @@ -5,7 +6,6 @@ import { CustomError, parseSharingErrorCodes } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import localForage from "@ente/shared/storage/localForage"; import { Collection, CollectionPublicMagicMetadata } from "types/collection"; -import { EncryptedEnteFile, EnteFile } from "types/file"; import { LocalSavedPublicCollectionFiles } from "types/publicCollection"; import { decryptFile, mergeMetadata, sortFiles } from "utils/file"; diff --git a/web/apps/photos/src/services/searchService.ts b/web/apps/photos/src/services/searchService.ts index 27786a2d3a..9fe1580e55 100644 --- a/web/apps/photos/src/services/searchService.ts +++ b/web/apps/photos/src/services/searchService.ts @@ -1,11 +1,11 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import * as chrono from "chrono-node"; import { t } from "i18next"; import type { Person } from "services/face/people"; import { Collection } from "types/collection"; import { EntityType, LocationTag, LocationTagData } from "types/entity"; -import { EnteFile } from "types/file"; import { ClipSearchScores, DateValue, diff --git a/web/apps/photos/src/services/trashService.ts b/web/apps/photos/src/services/trashService.ts index f367304550..cd5b2aa9b9 100644 --- a/web/apps/photos/src/services/trashService.ts +++ b/web/apps/photos/src/services/trashService.ts @@ -1,10 +1,10 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; import HTTPService from "@ente/shared/network/HTTPService"; import localForage from "@ente/shared/storage/localForage"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; import { Collection } from "types/collection"; -import { EnteFile } from "types/file"; import { SetFiles } from "types/gallery"; import { EncryptedTrashItem, Trash } from "types/trash"; import { decryptFile, mergeMetadata, sortTrashFiles } from "utils/file"; diff --git a/web/apps/photos/src/services/upload/publicUploadHttpClient.ts b/web/apps/photos/src/services/upload/publicUploadHttpClient.ts index 22ed45e2f3..e0f0bac3ea 100644 --- a/web/apps/photos/src/services/upload/publicUploadHttpClient.ts +++ b/web/apps/photos/src/services/upload/publicUploadHttpClient.ts @@ -1,8 +1,8 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { apiOrigin } from "@/next/origins"; import { CustomError, handleUploadError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; -import { EnteFile } from "types/file"; import { retryHTTPCall } from "./uploadHttpClient"; import { MultipartUploadURLs, UploadFile, UploadURL } from "./uploadService"; diff --git a/web/apps/photos/src/services/upload/uploadHttpClient.ts b/web/apps/photos/src/services/upload/uploadHttpClient.ts index 6841c0c1e8..67e52c2143 100644 --- a/web/apps/photos/src/services/upload/uploadHttpClient.ts +++ b/web/apps/photos/src/services/upload/uploadHttpClient.ts @@ -1,10 +1,10 @@ +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; import { apiOrigin, uploaderOrigin } from "@/next/origins"; import { wait } from "@/utils/promise"; import { CustomError, handleUploadError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; -import { EnteFile } from "types/file"; import { MultipartUploadURLs, UploadFile, UploadURL } from "./uploadService"; const MAX_URL_REQUESTS = 50; diff --git a/web/apps/photos/src/services/upload/uploadManager.ts b/web/apps/photos/src/services/upload/uploadManager.ts index 150b85ba69..0560fe8010 100644 --- a/web/apps/photos/src/services/upload/uploadManager.ts +++ b/web/apps/photos/src/services/upload/uploadManager.ts @@ -1,5 +1,7 @@ import { FILE_TYPE } from "@/media/file-type"; import { potentialFileTypeFromExtension } from "@/media/live-photo"; +import { getLocalFiles } from "@/new/photos/services/files"; +import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import { lowercaseExtension, nameAndExtension } from "@/next/file"; import log from "@/next/log"; @@ -26,10 +28,8 @@ import { import { getDisableCFUploadProxyFlag } from "services/userService"; import watcher from "services/watch"; import { Collection } from "types/collection"; -import { EncryptedEnteFile, EnteFile } from "types/file"; import { SetFiles } from "types/gallery"; import { decryptFile, getUserOwnedFiles, sortFiles } from "utils/file"; -import { getLocalFiles } from "../fileService"; import { getMetadataJSONMapKeyForJSON, tryParseTakeoutMetadataJSON, diff --git a/web/apps/photos/src/services/upload/uploadService.ts b/web/apps/photos/src/services/upload/uploadService.ts index 7161eb530c..66c0dcf8da 100644 --- a/web/apps/photos/src/services/upload/uploadService.ts +++ b/web/apps/photos/src/services/upload/uploadService.ts @@ -2,6 +2,15 @@ import { hasFileHash } from "@/media/file"; import { FILE_TYPE, type FileTypeInfo } from "@/media/file-type"; import { encodeLivePhoto } from "@/media/live-photo"; import type { Metadata } from "@/media/types/file"; +import { + EnteFile, + MetadataFileAttributes, + S3FileAttributes, + type EncryptedEnteFile, + type FilePublicMagicMetadata, + type FilePublicMagicMetadataProps, +} from "@/new/photos/types/file"; +import { EncryptedMagicMetadata } from "@/new/photos/types/magicMetadata"; import { ensureElectron } from "@/next/electron"; import { basename } from "@/next/file"; import log from "@/next/log"; @@ -24,15 +33,6 @@ import { PublicUploadProps, type LivePhotoAssets, } from "services/upload/uploadManager"; -import { - EnteFile, - MetadataFileAttributes, - S3FileAttributes, - type EncryptedEnteFile, - type FilePublicMagicMetadata, - type FilePublicMagicMetadataProps, -} from "types/file"; -import { EncryptedMagicMetadata } from "types/magicMetadata"; import type { ParsedExtractedMetadata } from "types/metadata"; import { getNonEmptyMagicMetadataProps, diff --git a/web/apps/photos/src/services/watch.ts b/web/apps/photos/src/services/watch.ts index 42ce245fa4..e9f7f33005 100644 --- a/web/apps/photos/src/services/watch.ts +++ b/web/apps/photos/src/services/watch.ts @@ -3,6 +3,8 @@ * watch folders functionality. */ +import { getLocalFiles } from "@/new/photos/services/files"; +import { EncryptedEnteFile } from "@/new/photos/types/file"; import { ensureElectron } from "@/next/electron"; import { basename, dirname } from "@/next/file"; import log from "@/next/log"; @@ -18,10 +20,8 @@ import uploadManager, { type UploadItemWithCollection, } from "services/upload/uploadManager"; import { Collection } from "types/collection"; -import { EncryptedEnteFile } from "types/file"; import { groupFilesBasedOnCollectionID } from "utils/file"; import { removeFromCollection } from "./collectionService"; -import { getLocalFiles } from "./fileService"; /** * Watch for file system folders and automatically update the corresponding Ente diff --git a/web/apps/photos/src/types/collection/index.ts b/web/apps/photos/src/types/collection/index.ts index 91b96281c7..1321451b2e 100644 --- a/web/apps/photos/src/types/collection/index.ts +++ b/web/apps/photos/src/types/collection/index.ts @@ -1,11 +1,11 @@ -import { CollectionSummaryType, CollectionType } from "constants/collection"; -import { EnteFile } from "types/file"; +import { EnteFile } from "@/new/photos/types/file"; import { EncryptedMagicMetadata, MagicMetadataCore, SUB_TYPE, VISIBILITY_STATE, -} from "types/magicMetadata"; +} from "@/new/photos/types/magicMetadata"; +import { CollectionSummaryType, CollectionType } from "constants/collection"; export enum COLLECTION_ROLE { VIEWER = "VIEWER", diff --git a/web/apps/photos/src/types/export/index.ts b/web/apps/photos/src/types/export/index.ts index 64ef249eda..6767c3e869 100644 --- a/web/apps/photos/src/types/export/index.ts +++ b/web/apps/photos/src/types/export/index.ts @@ -1,5 +1,5 @@ +import { EnteFile } from "@/new/photos/types/file"; import type { ExportStage } from "services/export"; -import { EnteFile } from "types/file"; export interface ExportProgress { success: number; diff --git a/web/apps/photos/src/types/gallery/index.ts b/web/apps/photos/src/types/gallery/index.ts index f69b6c24b6..1f95e78a19 100644 --- a/web/apps/photos/src/types/gallery/index.ts +++ b/web/apps/photos/src/types/gallery/index.ts @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import type { User } from "@ente/shared/user/types"; import { CollectionSelectorAttributes } from "components/Collections/CollectionSelector"; import { FilesDownloadProgressAttributes } from "components/FilesDownloadProgress"; import { TimeStampListItem } from "components/PhotoList"; import { Collection } from "types/collection"; -import { EnteFile } from "types/file"; export type SelectedState = { [k: number]: boolean; diff --git a/web/apps/photos/src/types/publicCollection/index.ts b/web/apps/photos/src/types/publicCollection/index.ts index 11ee4a2d12..95c5607584 100644 --- a/web/apps/photos/src/types/publicCollection/index.ts +++ b/web/apps/photos/src/types/publicCollection/index.ts @@ -1,6 +1,6 @@ +import { EnteFile } from "@/new/photos/types/file"; import { TimeStampListItem } from "components/PhotoList"; import { PublicURL } from "types/collection"; -import { EnteFile } from "types/file"; export interface PublicCollectionGalleryContextType { token: string; diff --git a/web/apps/photos/src/types/search/index.ts b/web/apps/photos/src/types/search/index.ts index adeb03d3aa..0e18d787ab 100644 --- a/web/apps/photos/src/types/search/index.ts +++ b/web/apps/photos/src/types/search/index.ts @@ -1,9 +1,9 @@ import { FILE_TYPE } from "@/media/file-type"; +import { EnteFile } from "@/new/photos/types/file"; import type { FaceIndexingStatus } from "services/face/indexer"; import type { Person } from "services/face/people"; import { City } from "services/locationSearchService"; import { LocationTagData } from "types/entity"; -import { EnteFile } from "types/file"; export enum SuggestionType { DATE = "DATE", diff --git a/web/apps/photos/src/types/trash/index.ts b/web/apps/photos/src/types/trash/index.ts index d7e231c1a9..df786029a1 100644 --- a/web/apps/photos/src/types/trash/index.ts +++ b/web/apps/photos/src/types/trash/index.ts @@ -1,4 +1,4 @@ -import { EncryptedEnteFile, EnteFile } from "types/file"; +import { EncryptedEnteFile, EnteFile } from "@/new/photos/types/file"; export interface TrashItem extends Omit { file: EnteFile; diff --git a/web/apps/photos/src/utils/collection/index.ts b/web/apps/photos/src/utils/collection/index.ts index 212cff7b1c..12fffe6bfa 100644 --- a/web/apps/photos/src/utils/collection/index.ts +++ b/web/apps/photos/src/utils/collection/index.ts @@ -1,3 +1,6 @@ +import { getAllLocalFiles, getLocalFiles } from "@/new/photos/services/files"; +import { EnteFile } from "@/new/photos/types/file"; +import { SUB_TYPE, VISIBILITY_STATE } from "@/new/photos/types/magicMetadata"; import { ensureElectron } from "@/next/electron"; import log from "@/next/log"; import { CustomError } from "@ente/shared/error"; @@ -30,7 +33,6 @@ import { updatePublicCollectionMagicMetadata, updateSharedCollectionMagicMetadata, } from "services/collectionService"; -import { getAllLocalFiles, getLocalFiles } from "services/fileService"; import { COLLECTION_ROLE, Collection, @@ -38,9 +40,7 @@ import { CollectionPublicMagicMetadataProps, CollectionSummaries, } from "types/collection"; -import { EnteFile } from "types/file"; import { SetFilesDownloadProgressAttributes } from "types/gallery"; -import { SUB_TYPE, VISIBILITY_STATE } from "types/magicMetadata"; import { downloadFilesWithProgress } from "utils/file"; import { isArchivedCollection, updateMagicMetadata } from "utils/magicMetadata"; import { safeDirectoryName } from "utils/native-fs"; diff --git a/web/apps/photos/src/utils/file/index.ts b/web/apps/photos/src/utils/file/index.ts index 5e2c60cee2..a6793a3386 100644 --- a/web/apps/photos/src/utils/file/index.ts +++ b/web/apps/photos/src/utils/file/index.ts @@ -2,6 +2,16 @@ import { FILE_TYPE } from "@/media/file-type"; import { isNonWebImageFileExtension } from "@/media/formats"; import { heicToJPEG } from "@/media/heic-convert"; import { decodeLivePhoto } from "@/media/live-photo"; +import { + EncryptedEnteFile, + EnteFile, + FileMagicMetadata, + FileMagicMetadataProps, + FilePublicMagicMetadata, + FilePublicMagicMetadataProps, + FileWithUpdatedMagicMetadata, +} from "@/new/photos/types/file"; +import { VISIBILITY_STATE } from "@/new/photos/types/magicMetadata"; import { lowercaseExtension } from "@/next/file"; import log from "@/next/log"; import { CustomErrorMessage, type Electron } from "@/next/types/ipc"; @@ -23,21 +33,11 @@ import { updateFileMagicMetadata, updateFilePublicMagicMetadata, } from "services/fileService"; -import { - EncryptedEnteFile, - EnteFile, - FileMagicMetadata, - FileMagicMetadataProps, - FilePublicMagicMetadata, - FilePublicMagicMetadataProps, - FileWithUpdatedMagicMetadata, -} from "types/file"; import { SelectedState, SetFilesDownloadProgressAttributes, SetFilesDownloadProgressAttributesCreator, } from "types/gallery"; -import { VISIBILITY_STATE } from "types/magicMetadata"; import { isArchivedFile, updateMagicMetadata } from "utils/magicMetadata"; import { safeFileName } from "utils/native-fs"; import { writeStream } from "utils/native-stream"; diff --git a/web/apps/photos/src/utils/magicMetadata/index.ts b/web/apps/photos/src/utils/magicMetadata/index.ts index cce41791e2..8d94a574f9 100644 --- a/web/apps/photos/src/utils/magicMetadata/index.ts +++ b/web/apps/photos/src/utils/magicMetadata/index.ts @@ -1,7 +1,10 @@ +import { EnteFile } from "@/new/photos/types/file"; +import { + MagicMetadataCore, + VISIBILITY_STATE, +} from "@/new/photos/types/magicMetadata"; import ComlinkCryptoWorker from "@ente/shared/crypto"; import { Collection } from "types/collection"; -import { EnteFile } from "types/file"; -import { MagicMetadataCore, VISIBILITY_STATE } from "types/magicMetadata"; export function isArchivedFile(item: EnteFile): boolean { if (!item || !item.magicMetadata || !item.magicMetadata.data) { diff --git a/web/apps/photos/src/utils/photoFrame/index.ts b/web/apps/photos/src/utils/photoFrame/index.ts index 93b680149f..8049d8ba01 100644 --- a/web/apps/photos/src/utils/photoFrame/index.ts +++ b/web/apps/photos/src/utils/photoFrame/index.ts @@ -1,7 +1,7 @@ import { FILE_TYPE } from "@/media/file-type"; +import type { LivePhotoSourceURL, SourceURLs } from "@/new/photos/types/file"; +import { EnteFile } from "@/new/photos/types/file"; import log from "@/next/log"; -import { LivePhotoSourceURL, SourceURLs } from "services/download"; -import { EnteFile } from "types/file"; import { SetSelectedState } from "types/gallery"; export async function playVideo(livePhotoVideo, livePhotoImage) { diff --git a/web/apps/photos/src/worker/search.worker.ts b/web/apps/photos/src/worker/search.worker.ts index 2667c0c850..f81aecfb96 100644 --- a/web/apps/photos/src/worker/search.worker.ts +++ b/web/apps/photos/src/worker/search.worker.ts @@ -1,9 +1,9 @@ +import { EnteFile } from "@/new/photos/types/file"; import * as Comlink from "comlink"; import { isInsideCity, isInsideLocationTag, } from "services/locationSearchService"; -import { EnteFile } from "types/file"; import { Search } from "types/search"; import { isSameDayAnyYear } from "utils/search"; diff --git a/web/apps/photos/tests/upload.test.ts b/web/apps/photos/tests/upload.test.ts index c4d76d5240..d839af637e 100644 --- a/web/apps/photos/tests/upload.test.ts +++ b/web/apps/photos/tests/upload.test.ts @@ -1,6 +1,6 @@ import { FILE_TYPE } from "@/media/file-type"; +import { getLocalFiles } from "@/new/photos/services/files"; import { getLocalCollections } from "services/collectionService"; -import { getLocalFiles } from "services/fileService"; import { tryToParseDateTime } from "services/upload/date"; import { MAX_FILE_NAME_LENGTH_GOOGLE_EXPORT, diff --git a/web/apps/photos/tsconfig.json b/web/apps/photos/tsconfig.json index cfe85e6d70..779ac7aa6c 100644 --- a/web/apps/photos/tsconfig.json +++ b/web/apps/photos/tsconfig.json @@ -22,7 +22,9 @@ "**/*.tsx", "**/*.js", "../../packages/shared/themes/mui-theme.d.ts", - "../../packages/next/global-electron.d.ts" + "../../packages/next/global-electron.d.ts", + "../../packages/new/photos/types/file.ts", + "../../packages/new/photos/types/magicMetadata.ts" ], "exclude": ["node_modules", "out", ".next", "thirdparty"] } diff --git a/web/packages/new/photos/services/embedding.ts b/web/packages/new/photos/services/embedding.ts index b6bf93b690..e20515e0a9 100644 --- a/web/packages/new/photos/services/embedding.ts +++ b/web/packages/new/photos/services/embedding.ts @@ -1,7 +1,9 @@ import { authenticatedRequestHeaders } from "@/next/http"; import { apiOrigin } from "@/next/origins"; import { nullToUndefined } from "@/utils/transform"; +// import ComlinkCryptoWorker from "@ente/shared/crypto"; import { z } from "zod"; +// import { getAllLocalFiles } from "./files"; /** * The embeddings that we (the current client) knows how to handle. @@ -79,18 +81,24 @@ type RemoteEmbedding = z.infer; */ export const syncRemoteFaceEmbeddings = async () => { let sinceTime = faceEmbeddingSyncTime(); + // const cryptoWorker = await ComlinkCryptoWorker.getInstance(); + // const files = await getAllLocalFiles(); + // TODO: eslint has fixed this spurious warning, but we're not on the latest // version yet, so add a disable. // https://github.com/eslint/eslint/pull/18286 /* eslint-disable no-constant-condition */ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { - const embeddings = await getEmbeddingsDiff( + const remoteEmbeddings = await getEmbeddingsDiff( "file-ml-clip-face", sinceTime, ); - if (embeddings.length == 0) break; - sinceTime = embeddings.reduce( + if (remoteEmbeddings.length == 0) break; + // const _embeddings = Promise.all( + // remoteEmbeddings.map(decryptFaceEmbedding), + // ); + sinceTime = remoteEmbeddings.reduce( (max, { updatedAt }) => Math.max(max, updatedAt), sinceTime, ); @@ -98,6 +106,22 @@ export const syncRemoteFaceEmbeddings = async () => { } }; +// const decryptFaceEmbedding = async (remoteEmbedding: RemoteEmbedding) => { +// const fileKey = fileIdToKeyMap.get(embedding.fileID); +// if (!fileKey) { +// throw Error(CustomError.FILE_NOT_FOUND); +// } +// const decryptedData = await worker.decryptMetadata( +// embedding.encryptedEmbedding, +// embedding.decryptionHeader, +// fileIdToKeyMap.get(embedding.fileID), +// ); +// return { +// ...decryptedData, +// updatedAt: embedding.updatedAt, +// } as unknown as FileML; +// }; + /** * The updatedAt of the most recent face {@link RemoteEmbedding} we've retrieved * and saved from remote, or 0. diff --git a/web/packages/new/photos/services/files.ts b/web/packages/new/photos/services/files.ts new file mode 100644 index 0000000000..d5a17b4e72 --- /dev/null +++ b/web/packages/new/photos/services/files.ts @@ -0,0 +1,38 @@ +import { type EnteFile } from "@/new/photos/types/file"; +import log from "@/next/log"; +import { Events, eventBus } from "@ente/shared/events"; +import localForage from "@ente/shared/storage/localForage"; + +const FILES_TABLE = "files"; +const HIDDEN_FILES_TABLE = "hidden-files"; + +/** + * Return all files that we know about locally, both "normal" and "hidden". + */ +export const getAllLocalFiles = async () => + (await getLocalFiles("normal")).concat(await getLocalFiles("hidden")); + +/** + * Return all files that we know about locally. By default it returns only + * "normal" (i.e. non-"hidden") files, but it can be passed the {@link type} + * "hidden" to get it to instead return hidden files that we know about locally. + */ +export const getLocalFiles = async (type: "normal" | "hidden" = "normal") => { + const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE; + const files: EnteFile[] = + (await localForage.getItem(tableName)) ?? []; + return files; +}; + +export const setLocalFiles = async ( + type: "normal" | "hidden", + files: EnteFile[], +) => { + const tableName = type === "normal" ? FILES_TABLE : HIDDEN_FILES_TABLE; + await localForage.setItem(tableName, files); + try { + eventBus.emit(Events.LOCAL_FILES_UPDATED); + } catch (e) { + log.error("Failed to save files", e); + } +}; diff --git a/web/apps/photos/src/types/file/index.ts b/web/packages/new/photos/types/file.ts similarity index 74% rename from web/apps/photos/src/types/file/index.ts rename to web/packages/new/photos/types/file.ts index c3d4cca440..1993ff9e8b 100644 --- a/web/apps/photos/src/types/file/index.ts +++ b/web/packages/new/photos/types/file.ts @@ -1,10 +1,9 @@ import type { Metadata } from "@/media/types/file"; -import { SourceURLs } from "services/download"; import { - EncryptedMagicMetadata, - MagicMetadataCore, VISIBILITY_STATE, -} from "types/magicMetadata"; + type EncryptedMagicMetadata, + type MagicMetadataCore, +} from "./magicMetadata"; export interface MetadataFileAttributes { encryptedData: string; @@ -63,6 +62,33 @@ export interface EnteFile isConverted?: boolean; } +export interface LivePhotoSourceURL { + image: () => Promise; + video: () => Promise; +} + +export interface LoadedLivePhotoSourceURL { + image: string; + video: string; +} + +export interface SourceURLs { + url: string | LivePhotoSourceURL | LoadedLivePhotoSourceURL; + isOriginal: boolean; + isRenderable: boolean; + type: "normal" | "livePhoto"; + /** + * Best effort attempt at obtaining the MIME type. + * + * Known cases where it is missing: + * + * - Live photos (these have a different code path for obtaining the URL). + * - A video that is passes the isPlayable test in the browser. + * + */ + mimeType?: string; +} + export interface TrashRequest { items: TrashRequestItems[]; } diff --git a/web/apps/photos/src/types/magicMetadata/index.ts b/web/packages/new/photos/types/magicMetadata.ts similarity index 100% rename from web/apps/photos/src/types/magicMetadata/index.ts rename to web/packages/new/photos/types/magicMetadata.ts