diff --git a/apps/photos/src/components/AuthenticateUserModal.tsx b/apps/photos/src/components/AuthenticateUserModal.tsx index a783dd415..09fb7a96f 100644 --- a/apps/photos/src/components/AuthenticateUserModal.tsx +++ b/apps/photos/src/components/AuthenticateUserModal.tsx @@ -1,6 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import { AppContext } from 'pages/_app'; import { KeyAttributes, User } from 'types/user'; import VerifyMasterPasswordForm, { diff --git a/apps/photos/src/components/Collections/CollectionDownloadProgress.tsx b/apps/photos/src/components/Collections/CollectionDownloadProgress.tsx index 4e326414f..7b91b35c6 100644 --- a/apps/photos/src/components/Collections/CollectionDownloadProgress.tsx +++ b/apps/photos/src/components/Collections/CollectionDownloadProgress.tsx @@ -4,7 +4,7 @@ import isElectron from 'is-electron'; import { AppContext } from 'pages/_app'; import { GalleryContext } from 'pages/gallery'; import { useContext } from 'react'; -import ElectronService from 'services/electron/common'; +import ElectronAPIs from '@ente/shared/electron'; export interface CollectionDownloadProgressAttributes { success: number; @@ -100,7 +100,7 @@ export const CollectionDownloadProgress: React.FC attr.collectionID === collectionID ); if (isElectron()) { - ElectronService.openDirectory(attributes.downloadDirPath); + ElectronAPIs.openDirectory(attributes.downloadDirPath); } else { if (attributes.isHidden) { galleryContext.openHiddenSection(() => { diff --git a/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx b/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx index b08e49a0b..ed165bdba 100644 --- a/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx +++ b/apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx @@ -4,7 +4,7 @@ import SingleInputForm, { } from '@ente/shared/components/SingleInputForm'; import React from 'react'; import { t } from 'i18next'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; export function PublicLinkSetPassword({ open, diff --git a/apps/photos/src/components/Collections/index.tsx b/apps/photos/src/components/Collections/index.tsx index 6e5ea11bd..6a3e6de0c 100644 --- a/apps/photos/src/components/Collections/index.tsx +++ b/apps/photos/src/components/Collections/index.tsx @@ -14,7 +14,7 @@ import { } from 'utils/collection'; import { useLocalState } from '@ente/shared/hooks/useLocalState'; import { sortCollectionSummaries } from 'services/collectionService'; -import { LS_KEYS } from 'utils/storage/localStorage'; +import { LS_KEYS } from '@ente/shared/storage/localStorage'; import { CollectionDownloadProgress, CollectionDownloadProgressAttributes, diff --git a/apps/photos/src/components/FixLargeThumbnail.tsx b/apps/photos/src/components/FixLargeThumbnail.tsx index 579439d27..6818ee668 100644 --- a/apps/photos/src/components/FixLargeThumbnail.tsx +++ b/apps/photos/src/components/FixLargeThumbnail.tsx @@ -6,7 +6,7 @@ import { getLargeThumbnailFiles, replaceThumbnail, } from 'services/migrateThumbnailService'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; import { logError } from '@ente/shared/sentry'; import { t } from 'i18next'; diff --git a/apps/photos/src/components/MachineLearning/ImageViews.tsx b/apps/photos/src/components/MachineLearning/ImageViews.tsx index 66930f952..f37963762 100644 --- a/apps/photos/src/components/MachineLearning/ImageViews.tsx +++ b/apps/photos/src/components/MachineLearning/ImageViews.tsx @@ -3,7 +3,7 @@ import { Skeleton, styled } from '@mui/material'; import { imageBitmapToBlob } from 'utils/image'; import { logError } from '@ente/shared/sentry'; -import { getBlobFromCache } from 'utils/storage/cache'; +import { getBlobFromCache } from '@ente/shared/storage/cacheStorage/helpers'; export const FaceCropsRow = styled('div')` & > img { diff --git a/apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx b/apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx index e14569975..19f4e20fb 100644 --- a/apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx +++ b/apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx @@ -1,7 +1,7 @@ export {}; // import React, { useState, useEffect, useContext, ChangeEvent } from 'react'; -// import { getData, LS_KEYS } from 'utils/storage/localStorage'; +// import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; // import { useRouter } from 'next/router'; // import { ComlinkWorker } from 'utils/comlink'; // import { AppContext } from 'pages/_app'; diff --git a/apps/photos/src/components/Sidebar/DebugSection.tsx b/apps/photos/src/components/Sidebar/DebugSection.tsx index e3e7597d9..d240076e8 100644 --- a/apps/photos/src/components/Sidebar/DebugSection.tsx +++ b/apps/photos/src/components/Sidebar/DebugSection.tsx @@ -7,7 +7,7 @@ import { t } from 'i18next'; import { addLogLine } from '@ente/shared/logging'; import { getDebugLogs } from '@ente/shared/logging/web'; import isElectron from 'is-electron'; -import ElectronService from 'services/electron/common'; +import ElectronAPIs from '@ente/shared/electron'; import Typography from '@mui/material/Typography'; import { isInternalUser } from 'utils/user'; import { testUpload } from '../../../tests/upload.test'; @@ -24,7 +24,7 @@ export default function DebugSection() { useEffect(() => { const main = async () => { if (isElectron()) { - const appVersion = await ElectronService.getAppVersion(); + const appVersion = await ElectronAPIs.getAppVersion(); setAppVersion(appVersion); } }; @@ -48,7 +48,7 @@ export default function DebugSection() { const downloadDebugLogs = () => { addLogLine('exporting logs'); if (isElectron()) { - ElectronService.openLogDirectory(); + ElectronAPIs.openLogDirectory(); } else { const logs = getDebugLogs(); diff --git a/apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx b/apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx index 95203c9d7..583912b33 100644 --- a/apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx +++ b/apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx @@ -4,7 +4,7 @@ import { useLocalState } from '@ente/shared/hooks/useLocalState'; import { t } from 'i18next'; import { useRouter } from 'next/router'; import { getBestPossibleUserLocale } from '@ente/shared/i18n/utils'; -import { LS_KEYS } from 'utils/storage/localStorage'; +import { LS_KEYS } from '@ente/shared/storage/localStorage'; const getLocaleDisplayName = (l: Language) => { switch (l) { diff --git a/apps/photos/src/components/Sidebar/Preferences/index.tsx b/apps/photos/src/components/Sidebar/Preferences/index.tsx index 87befc3a2..b3aa562dd 100644 --- a/apps/photos/src/components/Sidebar/Preferences/index.tsx +++ b/apps/photos/src/components/Sidebar/Preferences/index.tsx @@ -10,9 +10,9 @@ import AdvancedSettings from '../AdvancedSettings'; import MapSettings from '../MapSetting'; import { LanguageSelector } from './LanguageSelector'; import { EnteMenuItem } from 'components/Menu/EnteMenuItem'; -import { LS_KEYS } from 'utils/storage/localStorage'; +import { LS_KEYS } from '@ente/shared/storage/localStorage'; import { useLocalState } from '@ente/shared/hooks/useLocalState'; -import ElectronService from 'services/electron/common'; +import ElectronAPIs from '@ente/shared/electron'; import InMemoryStore, { MS_KEYS } from 'services/InMemoryStore'; import { logError } from '@ente/shared/sentry'; @@ -46,7 +46,7 @@ export default function Preferences({ open, onClose, onRootClose }) { const toggleOptOutOfCrashReports = async () => { try { if (isElectron()) { - await ElectronService.updateOptOutOfCrashReports( + await ElectronAPIs.updateOptOutOfCrashReports( !optOutOfCrashReports ); } diff --git a/apps/photos/src/components/Sidebar/userDetailsSection.tsx b/apps/photos/src/components/Sidebar/userDetailsSection.tsx index 4fb0559b2..cb552de57 100644 --- a/apps/photos/src/components/Sidebar/userDetailsSection.tsx +++ b/apps/photos/src/components/Sidebar/userDetailsSection.tsx @@ -2,7 +2,7 @@ import React, { useContext, useEffect, useMemo, useState } from 'react'; import SubscriptionCard from './SubscriptionCard'; import { getUserDetailsV2 } from 'services/userService'; import { UserDetails } from 'types/user'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; import { useLocalState } from '@ente/shared/hooks/useLocalState'; import Typography from '@mui/material/Typography'; import SubscriptionStatus from './SubscriptionStatus'; diff --git a/apps/photos/src/components/TwoFactor/Modal/Manage.tsx b/apps/photos/src/components/TwoFactor/Modal/Manage.tsx index 190734293..0464b8179 100644 --- a/apps/photos/src/components/TwoFactor/Modal/Manage.tsx +++ b/apps/photos/src/components/TwoFactor/Modal/Manage.tsx @@ -5,7 +5,7 @@ import { AppContext } from 'pages/_app'; import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages'; import router from 'next/router'; import { disableTwoFactor } from '@ente/accounts/api/user'; -import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; +import { setData, LS_KEYS, getData } from '@ente/shared/storage/localStorage'; import { Button, Grid } from '@mui/material'; interface Iprops { diff --git a/apps/photos/src/components/TwoFactor/Modal/index.tsx b/apps/photos/src/components/TwoFactor/Modal/index.tsx index 9ad1f3400..c343f53b5 100644 --- a/apps/photos/src/components/TwoFactor/Modal/index.tsx +++ b/apps/photos/src/components/TwoFactor/Modal/index.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { getTwoFactorStatus } from 'services/userService'; import { SetLoading } from 'types/gallery'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; import { t } from 'i18next'; import TwoFactorModalSetupSection from './Setup'; diff --git a/apps/photos/src/components/Upload/Uploader.tsx b/apps/photos/src/components/Upload/Uploader.tsx index 9bbb94794..7dc95a720 100644 --- a/apps/photos/src/components/Upload/Uploader.tsx +++ b/apps/photos/src/components/Upload/Uploader.tsx @@ -44,7 +44,6 @@ import { UPLOAD_STRATEGY, PICKED_UPLOAD_TYPE, } from 'constants/upload'; -import importService from 'services/importService'; import { getDownloadAppMessage, getRootLevelFileWithFolderNotAllowMessage, @@ -66,6 +65,7 @@ import { } from 'services/publicCollectionService'; import { UploadTypeSelectorIntent } from 'types/gallery'; import { getOrCreateAlbum } from 'utils/collection'; +import ElectronAPIs from '@ente/shared/electron'; const FIRST_ALBUM_NAME = 'My First Album'; @@ -179,7 +179,7 @@ export default function Uploader(props: Props) { setUploadProgressView(true); } - if (isElectron() && ImportService.checkAllElectronAPIsExists()) { + if (isElectron()) { ImportService.getPendingUploads().then( ({ files: electronFiles, collectionName, type }) => { addLogLine( @@ -234,7 +234,7 @@ export default function Uploader(props: Props) { for (const file of props.dragAndDropFiles) { if (file.name.endsWith('.zip')) { const zipFiles = - await importService.getElectronFilesFromGoogleZip( + await ElectronAPIs.getElectronFilesFromGoogleZip( (file as any).path ); addLogLine( @@ -529,13 +529,13 @@ export default function Uploader(props: Props) { ) { await ImportService.setToUploadCollection(collections); if (zipPaths.current) { - await ImportService.setToUploadFiles( + ElectronAPIs.setToUploadFiles( PICKED_UPLOAD_TYPE.ZIPS, zipPaths.current ); zipPaths.current = null; } - await ImportService.setToUploadFiles( + ElectronAPIs.setToUploadFiles( PICKED_UPLOAD_TYPE.FILES, filesWithCollectionToUploadIn.map( ({ file }) => (file as ElectronFile).path @@ -722,11 +722,11 @@ export default function Uploader(props: Props) { let files: ElectronFile[]; pickedUploadType.current = type; if (type === PICKED_UPLOAD_TYPE.FILES) { - files = await ImportService.showUploadFilesDialog(); + files = await ElectronAPIs.showUploadFilesDialog(); } else if (type === PICKED_UPLOAD_TYPE.FOLDERS) { - files = await ImportService.showUploadDirsDialog(); + files = await ElectronAPIs.showUploadDirsDialog(); } else { - const response = await ImportService.showUploadZipDialog(); + const response = await ElectronAPIs.showUploadZipDialog(); files = response.files; zipPaths.current = response.zipPaths; } @@ -755,7 +755,7 @@ export default function Uploader(props: Props) { }; const handleUpload = (type) => () => { - if (isElectron() && importService.checkAllElectronAPIsExists()) { + if (isElectron()) { handleDesktopUpload(type); } else { handleWebUpload(type); diff --git a/apps/photos/src/components/WatchFolder/index.tsx b/apps/photos/src/components/WatchFolder/index.tsx index fb7f2f38c..2d87c80b4 100644 --- a/apps/photos/src/components/WatchFolder/index.tsx +++ b/apps/photos/src/components/WatchFolder/index.tsx @@ -10,7 +10,7 @@ import DialogTitleWithCloseButton from '@ente/shared/components/DialogBox/TitleW import UploadStrategyChoiceModal from 'components/Upload/UploadStrategyChoiceModal'; import { UPLOAD_STRATEGY } from 'constants/upload'; import { getImportSuggestion } from 'utils/upload'; -import electronFSService from 'services/electron/fs'; +import ElectronAPIs from '@ente/shared/electron'; import { PICKED_UPLOAD_TYPE } from 'constants/upload'; interface Iprops { @@ -50,7 +50,7 @@ export default function WatchFolder({ open, onClose }: Iprops) { const addFolderForWatching = async (path: string) => { setInputFolderPath(path); - const files = await electronFSService.getDirFiles(path); + const files = await ElectronAPIs.getDirFiles(path); const analysisResult = getImportSuggestion( PICKED_UPLOAD_TYPE.FOLDERS, files diff --git a/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx b/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx index b1887cc6d..4528d5670 100644 --- a/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx +++ b/apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx @@ -20,7 +20,7 @@ import { logError } from '@ente/shared/sentry'; import { AppContext } from 'pages/_app'; import { Link, Stack } from '@mui/material'; import { useLocalState } from '@ente/shared/hooks/useLocalState'; -import { LS_KEYS } from 'utils/storage/localStorage'; +import { LS_KEYS } from '@ente/shared/storage/localStorage'; import { getLocalUserDetails } from 'utils/user'; import { PLAN_PERIOD } from 'constants/gallery'; import FreeSubscriptionPlanSelectorCard from './free'; diff --git a/apps/photos/src/pages/_app.tsx b/apps/photos/src/pages/_app.tsx index 50429a0bc..f1e4107d8 100644 --- a/apps/photos/src/pages/_app.tsx +++ b/apps/photos/src/pages/_app.tsx @@ -41,7 +41,7 @@ import { CustomError } from '@ente/shared/error'; import { addLogLine } from '@ente/shared/logging'; import { clearLogsIfLocalStorageLimitExceeded } from '@ente/shared/logging/web'; import isElectron from 'is-electron'; -import ElectronUpdateService from 'services/electron/update'; +import ElectronAPIs from '@ente/shared/electron'; import { getUpdateAvailableForDownloadMessage, getUpdateReadyToInstallMessage, @@ -52,7 +52,6 @@ import { SetNotificationAttributes, } from 'types/Notification'; import ArrowForward from '@mui/icons-material/ArrowForward'; -import { AppUpdateInfo } from 'types/electron'; import { CacheProvider } from '@emotion/react'; import { APP_TITLES, @@ -76,6 +75,7 @@ import { User } from '@ente/shared/user/types'; import { useLocalState } from '@ente/shared/hooks/useLocalState'; import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages'; import { getTheme } from '@ente/shared/themes'; +import { AppUpdateInfo } from '@ente/shared/electron/types'; const redirectMap = new Map([ [REDIRECTS.ROADMAP, getRoadmapRedirectURL], @@ -193,7 +193,7 @@ export default function App(props: EnteAppProps) { }); } }; - ElectronUpdateService.registerUpdateEventListener(showUpdateDialog); + ElectronAPIs.registerUpdateEventListener(showUpdateDialog); } }, []); diff --git a/apps/photos/src/pages/deduplicate/index.tsx b/apps/photos/src/pages/deduplicate/index.tsx index f4128bb27..8261aca80 100644 --- a/apps/photos/src/pages/deduplicate/index.tsx +++ b/apps/photos/src/pages/deduplicate/index.tsx @@ -22,7 +22,7 @@ import Router from 'next/router'; import DeduplicateOptions from 'components/pages/dedupe/SelectedFileOptions'; import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages'; import router from 'next/router'; -import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; +import { getKey, SESSION_KEYS } from '@ente/shared/storage/sessionStorage'; import { styled } from '@mui/material'; import { getLatestCollections } from 'services/collectionService'; import EnteSpinner from '@ente/shared/components/EnteSpinner'; diff --git a/apps/photos/src/pages/gallery/index.tsx b/apps/photos/src/pages/gallery/index.tsx index 38f878b1c..d04c82670 100644 --- a/apps/photos/src/pages/gallery/index.tsx +++ b/apps/photos/src/pages/gallery/index.tsx @@ -7,7 +7,11 @@ import { useState, } from 'react'; import { useRouter } from 'next/router'; -import { clearKeys, getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; +import { + clearKeys, + getKey, + SESSION_KEYS, +} from '@ente/shared/storage/sessionStorage'; import { getLocalFiles, syncFiles } from 'services/fileService'; import { styled, Typography } from '@mui/material'; import { @@ -32,7 +36,7 @@ import { justSignedUp, setIsFirstLogin, setJustSignedUp, -} from 'utils/storage'; +} from '@ente/shared/storage/localStorage/helpers'; import { isTokenValid, syncMapEnabled, @@ -103,11 +107,11 @@ import { ITEM_TYPE, TimeStampListItem } from 'components/PhotoList'; import UploadInputs from 'components/UploadSelectorInputs'; import useFileInput from '@ente/shared/hooks/useFileInput'; import { FamilyData, User } from 'types/user'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import { CenteredFlex } from 'components/Container'; import { checkConnectivity } from 'utils/common'; import { SYNC_INTERVAL_IN_MICROSECONDS } from 'constants/gallery'; -import ElectronService from 'services/electron/common'; +import ElectronAPIs from '@ente/shared/electron'; import uploadManager from 'services/upload/uploadManager'; import { getToken } from 'utils/common/key'; import ExportModal from 'components/ExportModal'; @@ -337,14 +341,14 @@ export default function Gallery() { syncInterval.current = setInterval(() => { syncWithRemote(false, true); }, SYNC_INTERVAL_IN_MICROSECONDS); - ElectronService.registerForegroundEventListener(() => { + ElectronAPIs.registerForegroundEventListener(() => { syncWithRemote(false, true); }); }; main(); return () => { clearInterval(syncInterval.current); - ElectronService.registerForegroundEventListener(() => {}); + ElectronAPIs.registerForegroundEventListener(() => {}); ClipService.removeOnFileUploadListener(); }; }, []); diff --git a/apps/photos/src/pages/index.tsx b/apps/photos/src/pages/index.tsx index 25fbbd191..7ffa53239 100644 --- a/apps/photos/src/pages/index.tsx +++ b/apps/photos/src/pages/index.tsx @@ -4,19 +4,19 @@ import { styled, Button, Typography, TypographyProps } from '@mui/material'; import { AppContext } from './_app'; import Login from '@ente/accounts/components/Login'; import { useRouter } from 'next/router'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import SignUp from '@ente/accounts/components/SignUp'; import EnteSpinner from '@ente/shared/components/EnteSpinner'; import { t } from 'i18next'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { logError } from '@ente/shared/sentry'; import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages'; import { EnteLogo } from '@ente/shared/components/EnteLogo'; import isElectron from 'is-electron'; -import safeStorageService from 'services/electron/safeStorage'; +import ElectronAPIs from '@ente/shared/electron'; import { saveKeyInSessionStore } from 'utils/crypto'; -import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; +import { getKey, SESSION_KEYS } from '@ente/shared/storage/sessionStorage'; import { getAlbumsURL } from 'utils/common/apiUtil'; import { Trans } from 'react-i18next'; import { APPS } from '@ente/shared/apps/constants'; @@ -132,7 +132,7 @@ export default function LandingPage() { const user = getData(LS_KEYS.USER); let key = getKey(SESSION_KEYS.ENCRYPTION_KEY); if (!key && isElectron()) { - key = await safeStorageService.getEncryptionKey(); + key = await ElectronAPIs.getEncryptionKey(); if (key) { await saveKeyInSessionStore( SESSION_KEYS.ENCRYPTION_KEY, diff --git a/apps/photos/src/pages/shared-albums/index.tsx b/apps/photos/src/pages/shared-albums/index.tsx index e72defbb1..e701d1fa7 100644 --- a/apps/photos/src/pages/shared-albums/index.tsx +++ b/apps/photos/src/pages/shared-albums/index.tsx @@ -51,7 +51,7 @@ import { logoutUser } from '@ente/accounts/services/user'; import UploadButton from 'components/Upload/UploadButton'; import bs58 from 'bs58'; import AddPhotoAlternateOutlined from '@mui/icons-material/AddPhotoAlternateOutlined'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { UploadTypeSelectorIntent } from 'types/gallery'; import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined'; import MoreHoriz from '@mui/icons-material/MoreHoriz'; diff --git a/apps/photos/src/services/billingService.ts b/apps/photos/src/services/billingService.ts index 992a956e6..e9f876e82 100644 --- a/apps/photos/src/services/billingService.ts +++ b/apps/photos/src/services/billingService.ts @@ -1,6 +1,10 @@ import { getEndpoint, getPaymentsURL } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; -import { setData, LS_KEYS, removeData } from 'utils/storage/localStorage'; +import { + setData, + LS_KEYS, + removeData, +} from '@ente/shared/storage/localStorage'; import HTTPService from './HTTPService'; import { logError } from '@ente/shared/sentry'; import { getPaymentToken } from './userService'; diff --git a/apps/photos/src/services/cache/cacheStorageFactory.ts b/apps/photos/src/services/cache/cacheStorageFactory.ts index bb0b8abb5..569206d56 100644 --- a/apps/photos/src/services/cache/cacheStorageFactory.ts +++ b/apps/photos/src/services/cache/cacheStorageFactory.ts @@ -1,5 +1,5 @@ import { LimitedCacheStorage } from 'types/cache/index'; -import { ElectronCacheStorage } from 'services/electron/cache'; +import ElectronAPIs from '@ente/shared/electron'; import { runningInElectron, runningInWorker } from 'utils/common'; import { WorkerElectronCacheStorageService } from 'services/workerElectronCache/service'; @@ -14,7 +14,14 @@ class cacheStorageFactory { } return this.workerElectronCacheStorageServiceInstance; } else { - return ElectronCacheStorage; + return { + open(cacheName) { + return ElectronAPIs.openDiskCache(cacheName); + }, + delete(cacheName) { + return ElectronAPIs.deleteDiskCache(cacheName); + }, + }; } } else { return transformBrowserCacheStorageToLimitedCacheStorage(caches); diff --git a/apps/photos/src/services/clipService.ts b/apps/photos/src/services/clipService.ts index 20e62c036..2034d5cce 100644 --- a/apps/photos/src/services/clipService.ts +++ b/apps/photos/src/services/clipService.ts @@ -1,24 +1,24 @@ -import { EnteFile } from 'types/file'; import { putEmbedding, getLatestEmbeddings, getLocalEmbeddings, } from './embeddingService'; import { getAllLocalFiles, getLocalFiles } from './fileService'; -import { ElectronAPIs } from 'types/electron'; import downloadManager from './downloadManager'; -import { getToken } from 'utils/common/key'; -import { Embedding, Model } from 'types/embedding'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; import { logError } from '@ente/shared/sentry'; import { addLogLine } from '@ente/shared/logging'; -import { CustomError } from 'utils/error'; -import { LS_KEYS, getData } from 'utils/storage/localStorage'; -import { getPersonalFiles } from 'utils/file'; import isElectron from 'is-electron'; import { Events, eventBus } from './events'; import PQueue from 'p-queue'; +import { EnteFile } from 'types/file'; +import ElectronAPIs from '@ente/shared/electron'; +import { CustomError } from '@ente/shared/error'; +import { LS_KEYS, getData } from '@ente/shared/storage/localStorage'; +import { getPersonalFiles } from 'utils/file'; import { FILE_TYPE } from 'constants/file'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; +import { Embedding, Model } from 'types/embedding'; +import { getToken } from '@ente/shared/storage/localStorage/helpers'; const CLIP_EMBEDDING_LENGTH = 512; @@ -28,22 +28,20 @@ export interface ClipExtractionStatus { } class ClipServiceImpl { - private electronAPIs: ElectronAPIs; - private embeddingExtractionInProgress: AbortController = null; + private embeddingExtractionInProgress: AbortController | null = null; private reRunNeeded = false; private clipExtractionStatus: ClipExtractionStatus = { pending: 0, indexed: 0, }; - private onUpdateHandler: (status: ClipExtractionStatus) => void = null; + private onUpdateHandler: ((status: ClipExtractionStatus) => void) | null = + null; private liveEmbeddingExtractionQueue: PQueue; - private onFileUploadedHandler: (arg: { - enteFile: EnteFile; - localFile: globalThis.File; - }) => void = null; + private onFileUploadedHandler: + | ((arg: { enteFile: EnteFile; localFile: globalThis.File }) => void) + | null = null; constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; this.liveEmbeddingExtractionQueue = new PQueue({ concurrency: 1, }); @@ -104,7 +102,7 @@ class ClipServiceImpl { if (!isElectron()) { return false; } - const platform = await this.electronAPIs.getPlatform(); + const platform = await ElectronAPIs.getPlatform(); return platform !== 'windows'; }; @@ -150,7 +148,7 @@ class ClipServiceImpl { getTextEmbedding = async (text: string): Promise => { try { - return this.electronAPIs.computeTextEmbedding(text); + return ElectronAPIs.computeTextEmbedding(text); } catch (e) { logError(e, 'failed to compute text embedding'); throw e; @@ -249,7 +247,7 @@ class ClipServiceImpl { const file = await localFile .arrayBuffer() .then((buffer) => new Uint8Array(buffer)); - const embedding = await this.electronAPIs.computeImageEmbedding(file); + const embedding = await ElectronAPIs.computeImageEmbedding(file); return embedding; }; @@ -297,7 +295,7 @@ class ClipServiceImpl { } else { thumb = await downloadManager.downloadThumb(token, file); } - const embedding = await this.electronAPIs.computeImageEmbedding(thumb); + const embedding = await ElectronAPIs.computeImageEmbedding(thumb); return embedding; }; diff --git a/apps/photos/src/services/collectionService.ts b/apps/photos/src/services/collectionService.ts index 01b7ebd97..46ee68ea8 100644 --- a/apps/photos/src/services/collectionService.ts +++ b/apps/photos/src/services/collectionService.ts @@ -1,6 +1,6 @@ import { getEndpoint } from 'utils/common/apiUtil'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; -import localForage from 'utils/storage/localForage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; +import localForage from '@ente/shared/storage/localForage'; import { getActualKey, getToken } from 'utils/common/key'; import { getPublicKey } from './userService'; @@ -64,7 +64,7 @@ import { isDefaultHiddenCollection, getHiddenCollections, } from 'utils/collection'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { getLocalFiles } from './fileService'; import { REQUEST_BATCH_SIZE } from 'constants/api'; import { batch } from 'utils/common'; diff --git a/apps/photos/src/services/downloadManager.ts b/apps/photos/src/services/downloadManager.ts index e8ce700b8..806df52f3 100644 --- a/apps/photos/src/services/downloadManager.ts +++ b/apps/photos/src/services/downloadManager.ts @@ -11,7 +11,7 @@ import { EnteFile } from 'types/file'; import { logError } from '@ente/shared/sentry'; import { FILE_TYPE } from 'constants/file'; import { CustomError } from 'utils/error'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { CacheStorageService } from './cache/cacheStorageService'; import { CACHES } from 'constants/cache'; import { Remote } from 'comlink'; diff --git a/apps/photos/src/services/electron/cache.ts b/apps/photos/src/services/electron/cache.ts deleted file mode 100644 index 46e1aefa8..000000000 --- a/apps/photos/src/services/electron/cache.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { LimitedCache, LimitedCacheStorage } from 'types/cache'; -import { ElectronAPIs } from 'types/electron'; - -class ElectronCacheStorageService implements LimitedCacheStorage { - private electronAPIs: ElectronAPIs; - private allElectronAPIsExist: boolean = false; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - this.allElectronAPIsExist = !!this.electronAPIs?.openDiskCache; - } - - async open(cacheName: string): Promise { - if (this.allElectronAPIsExist) { - return await this.electronAPIs.openDiskCache(cacheName); - } - } - - async delete(cacheName: string): Promise { - if (this.allElectronAPIsExist) { - return await this.electronAPIs.deleteDiskCache(cacheName); - } - } -} - -export const ElectronCacheStorage = new ElectronCacheStorageService(); diff --git a/apps/photos/src/services/electron/common.ts b/apps/photos/src/services/electron/common.ts deleted file mode 100644 index 2ed24b3dd..000000000 --- a/apps/photos/src/services/electron/common.ts +++ /dev/null @@ -1,78 +0,0 @@ -import isElectron from 'is-electron'; -import { ElectronAPIs } from 'types/electron'; - -class ElectronService { - private electronAPIs: ElectronAPIs; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - - checkIsBundledApp() { - return isElectron() && !!this.electronAPIs?.openDiskCache; - } - - logToDisk(msg: string) { - if (this.electronAPIs?.logToDisk) { - this.electronAPIs.logToDisk(msg); - } - } - - openLogDirectory() { - if (this.electronAPIs?.openLogDirectory) { - this.electronAPIs.openLogDirectory(); - } - } - - getSentryUserID() { - if (this.electronAPIs?.getSentryUserID) { - return this.electronAPIs.getSentryUserID(); - } - } - getAppVersion() { - if (this.electronAPIs?.getAppVersion) { - return this.electronAPIs.getAppVersion(); - } - } - logRendererProcessMemoryUsage(message: string) { - if (this.electronAPIs?.logRendererProcessMemoryUsage) { - return this.electronAPIs.logRendererProcessMemoryUsage(message); - } - } - registerForegroundEventListener(onForeground: () => void) { - if (this.electronAPIs?.registerForegroundEventListener) { - this.electronAPIs.registerForegroundEventListener(onForeground); - } - } - - checkExistsAndCreateDir(dirPath: string) { - if (this.electronAPIs?.checkExistsAndCreateDir) { - this.electronAPIs.checkExistsAndCreateDir(dirPath); - } - } - - openDirectory(dirPath: string) { - if (this.electronAPIs?.openDirectory) { - this.electronAPIs.openDirectory(dirPath); - } - } - - selectDirectory() { - if (this.electronAPIs?.selectDirectory) { - return this.electronAPIs.selectDirectory(); - } - } - - updateOptOutOfCrashReports(optOut: boolean) { - if (this.electronAPIs?.updateOptOutOfCrashReports) { - return this.electronAPIs.updateOptOutOfCrashReports(optOut); - } - } - getPlatform() { - if (this.electronAPIs?.getPlatform) { - return this.electronAPIs.getPlatform(); - } - } -} - -export default new ElectronService(); diff --git a/apps/photos/src/services/electron/ffmpeg.ts b/apps/photos/src/services/electron/ffmpeg.ts deleted file mode 100644 index f45a575b9..000000000 --- a/apps/photos/src/services/electron/ffmpeg.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IFFmpeg } from 'services/ffmpeg/ffmpegFactory'; -import { ElectronAPIs } from 'types/electron'; -import { ElectronFile } from 'types/upload'; - -export class ElectronFFmpeg implements IFFmpeg { - private electronAPIs: ElectronAPIs; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - - async run( - cmd: string[], - inputFile: ElectronFile | File, - outputFilename: string, - dontTimeout?: boolean - ) { - if (this.electronAPIs?.runFFmpegCmd) { - return this.electronAPIs.runFFmpegCmd( - cmd, - inputFile, - outputFilename, - dontTimeout - ); - } - } -} diff --git a/apps/photos/src/services/electron/fs.ts b/apps/photos/src/services/electron/fs.ts deleted file mode 100644 index 27be0f701..000000000 --- a/apps/photos/src/services/electron/fs.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ElectronAPIs } from 'types/electron'; -import { logError } from '@ente/shared/sentry'; - -class ElectronFSService { - private electronAPIs: ElectronAPIs; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - - getDirFiles(dirPath: string) { - if (this.electronAPIs.getDirFiles) { - return this.electronAPIs.getDirFiles(dirPath); - } - } - - async isFolder(folderPath: string) { - try { - const isFolder = await this.electronAPIs.isFolder(folderPath); - return isFolder; - } catch (e) { - logError(e, 'error while checking if is Folder'); - } - } - - async saveMediaFile( - filePath: string, - fileStream: ReadableStream - ) { - try { - await this.electronAPIs.saveStreamToDisk(filePath, fileStream); - } catch (e) { - logError(e, 'error while saving media file'); - throw e; - } - } - - deleteFile(filePath: string) { - try { - this.electronAPIs.deleteFile(filePath); - } catch (e) { - logError(e, 'error while deleting file'); - throw e; - } - } -} - -export default new ElectronFSService(); diff --git a/apps/photos/src/services/electron/safeStorage.tsx b/apps/photos/src/services/electron/safeStorage.tsx deleted file mode 100644 index de4f1e9ef..000000000 --- a/apps/photos/src/services/electron/safeStorage.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { ElectronAPIs } from 'types/electron'; -import { logError } from '@ente/shared/sentry'; - -class SafeStorageService { - private electronAPIs: ElectronAPIs; - private allElectronAPIsExist: boolean = false; - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - this.allElectronAPIsExist = !!this.electronAPIs?.getEncryptionKey; - } - - async getEncryptionKey() { - try { - if (this.allElectronAPIsExist) { - return (await this.electronAPIs.getEncryptionKey()) as string; - } - } catch (e) { - logError(e, 'getEncryptionKey failed'); - } - } - - async setEncryptionKey(encryptionKey: string) { - try { - if (this.allElectronAPIsExist) { - return await this.electronAPIs.setEncryptionKey(encryptionKey); - } - } catch (e) { - logError(e, 'setEncryptionKey failed'); - } - } - - async clearElectronStore() { - try { - if (this.allElectronAPIsExist) { - return this.electronAPIs.clearElectronStore(); - } - } catch (e) { - logError(e, 'clearElectronStore failed'); - } - } -} -export default new SafeStorageService(); diff --git a/apps/photos/src/services/electron/update.ts b/apps/photos/src/services/electron/update.ts deleted file mode 100644 index 52641264a..000000000 --- a/apps/photos/src/services/electron/update.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { AppUpdateInfo, ElectronAPIs } from 'types/electron'; - -class ElectronUpdateService { - private electronAPIs: ElectronAPIs; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - - registerUpdateEventListener( - showUpdateDialog: (updateInfo: AppUpdateInfo) => void - ) { - if (this.electronAPIs?.registerUpdateEventListener) { - this.electronAPIs.registerUpdateEventListener(showUpdateDialog); - } - } - - updateAndRestart() { - if (this.electronAPIs?.updateAndRestart) { - this.electronAPIs.updateAndRestart(); - } - } - - skipAppUpdate(version: string) { - if (this.electronAPIs?.skipAppUpdate) { - this.electronAPIs.skipAppUpdate(version); - } - } - muteUpdateNotification(version: string) { - if (this.electronAPIs?.muteUpdateNotification) { - this.electronAPIs.muteUpdateNotification(version); - } - } -} - -export default new ElectronUpdateService(); diff --git a/apps/photos/src/services/embeddingService.ts b/apps/photos/src/services/embeddingService.ts index f0a770b5a..26424cde3 100644 --- a/apps/photos/src/services/embeddingService.ts +++ b/apps/photos/src/services/embeddingService.ts @@ -4,11 +4,11 @@ import { GetEmbeddingDiffResponse, PutEmbeddingRequest, } from 'types/embedding'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { getEndpoint } from 'utils/common/apiUtil'; import { addLogLine } from '@ente/shared/logging'; import { logError } from '@ente/shared/sentry'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { getAllLocalFiles } from './fileService'; import HTTPService from './HTTPService'; import { getToken } from 'utils/common/key'; diff --git a/apps/photos/src/services/entityService.ts b/apps/photos/src/services/entityService.ts index aee8c664f..9dd078fdf 100644 --- a/apps/photos/src/services/entityService.ts +++ b/apps/photos/src/services/entityService.ts @@ -1,9 +1,9 @@ import { getToken } from 'utils/common/key'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import HTTPService from './HTTPService'; import { getEndpoint } from 'utils/common/apiUtil'; import { logError } from '@ente/shared/sentry'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { getActualKey } from 'utils/common/key'; import { EntityType, diff --git a/apps/photos/src/services/export/index.ts b/apps/photos/src/services/export/index.ts index 779d44140..fc3142e50 100644 --- a/apps/photos/src/services/export/index.ts +++ b/apps/photos/src/services/export/index.ts @@ -23,7 +23,7 @@ import { getCollectionIDFromFileUID, } from 'utils/export'; import { logError } from '@ente/shared/sentry'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; import { getAllLocalCollections } from '../collectionService'; import downloadManager from '../downloadManager'; import { getAllLocalFiles } from '../fileService'; @@ -51,7 +51,6 @@ import { import { User } from 'types/user'; import { FILE_TYPE } from 'constants/file'; import { ExportStage } from 'constants/export'; -import { ElectronAPIs } from 'types/electron'; import { CustomError } from 'utils/error'; import { addLogLine } from '@ente/shared/logging'; import { eventBus, Events } from '../events'; @@ -61,7 +60,7 @@ import { getNonEmptyPersonalCollections, } from 'utils/collection'; import { migrateExport } from './migration'; -import ElectronFSService from '../electron/fs'; +import ElectronAPIs from '@ente/shared/electron'; const EXPORT_RECORD_FILE_NAME = 'export_status.json'; @@ -76,7 +75,6 @@ export const NULL_EXPORT_RECORD: ExportRecord = { }; class ExportService { - private electronAPIs: ElectronAPIs; private exportSettings: ExportSettings; private exportInProgress: RequestCanceller = null; private reRunNeeded = false; @@ -95,10 +93,6 @@ class ExportService { failed: 0, }; - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - getExportSettings(): ExportSettings { try { if (this.exportSettings) { @@ -166,12 +160,12 @@ class ExportService { async changeExportDirectory() { try { - const newRootDir = await this.electronAPIs.selectDirectory(); + const newRootDir = await ElectronAPIs.selectDirectory(); if (!newRootDir) { throw Error(CustomError.SELECT_FOLDER_ABORTED); } const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`; - await this.electronAPIs.checkExistsAndCreateDir(newExportDir); + await ElectronAPIs.checkExistsAndCreateDir(newExportDir); return newExportDir; } catch (e) { if (e.message !== CustomError.SELECT_FOLDER_ABORTED) { @@ -183,7 +177,7 @@ class ExportService { async openExportDirectory(exportFolder: string) { try { - await this.electronAPIs.openDirectory(exportFolder); + await ElectronAPIs.openDirectory(exportFolder); } catch (e) { logError(e, 'openExportDirectory failed'); } @@ -529,7 +523,7 @@ class ExportService { newCollectionExportName ); try { - await this.electronAPIs.rename( + await ElectronAPIs.rename( oldCollectionExportPath, newCollectionExportPath ); @@ -614,13 +608,11 @@ class ExportService { ); try { // delete the collection metadata folder - await this.electronAPIs.deleteFolder( + await ElectronAPIs.deleteFolder( getMetadataFolderExportPath(collectionExportPath) ); // delete the collection folder - await this.electronAPIs.deleteFolder( - collectionExportPath - ); + await ElectronAPIs.deleteFolder(collectionExportPath); } catch (e) { await this.addCollectionExportedRecord( exportFolder, @@ -703,10 +695,10 @@ class ExportService { exportDir, collectionExportName ); - await this.electronAPIs.checkExistsAndCreateDir( + await ElectronAPIs.checkExistsAndCreateDir( collectionExportPath ); - await this.electronAPIs.checkExistsAndCreateDir( + await ElectronAPIs.checkExistsAndCreateDir( getMetadataFolderExportPath(collectionExportPath) ); await this.downloadAndSave( @@ -786,7 +778,7 @@ class ExportService { `moving image file ${imageExportPath} to trash folder` ); if (this.exists(imageExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( imageExportPath, getTrashedFileExportPath( exportDir, @@ -799,7 +791,7 @@ class ExportService { getMetadataFileExportPath(imageExportPath); if (this.exists(imageMetadataFileExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( imageMetadataFileExportPath, getTrashedFileExportPath( exportDir, @@ -816,7 +808,7 @@ class ExportService { `moving video file ${videoExportPath} to trash folder` ); if (this.exists(videoExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( videoExportPath, getTrashedFileExportPath( exportDir, @@ -827,7 +819,7 @@ class ExportService { const videoMetadataFileExportPath = getMetadataFileExportPath(videoExportPath); if (this.exists(videoMetadataFileExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( videoMetadataFileExportPath, getTrashedFileExportPath( exportDir, @@ -848,7 +840,7 @@ class ExportService { `moving file ${fileExportPath} to ${trashedFilePath} trash folder` ); if (this.exists(fileExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( fileExportPath, trashedFilePath ); @@ -856,7 +848,7 @@ class ExportService { const metadataFileExportPath = getMetadataFileExportPath(fileExportPath); if (this.exists(metadataFileExportPath)) { - await this.electronAPIs.moveFile( + await ElectronAPIs.moveFile( metadataFileExportPath, getTrashedFileExportPath( exportDir, @@ -995,7 +987,7 @@ class ExportService { try { const exportRecord = await this.getExportRecord(folder); const newRecord: ExportRecord = { ...exportRecord, ...newData }; - await this.electronAPIs.saveFileToDisk( + await ElectronAPIs.saveFileToDisk( `${folder}/${EXPORT_RECORD_FILE_NAME}`, JSON.stringify(newRecord, null, 2) ); @@ -1016,7 +1008,7 @@ class ExportService { if (!this.exists(exportRecordJSONPath)) { return this.createEmptyExportRecord(exportRecordJSONPath); } - const recordFile = await this.electronAPIs.readTextFile( + const recordFile = await ElectronAPIs.readTextFile( exportRecordJSONPath ); try { @@ -1054,8 +1046,8 @@ class ExportService { exportFolder, collectionExportName ); - await this.electronAPIs.checkExistsAndCreateDir(collectionExportPath); - await this.electronAPIs.checkExistsAndCreateDir( + await ElectronAPIs.checkExistsAndCreateDir(collectionExportPath); + await ElectronAPIs.checkExistsAndCreateDir( getMetadataFolderExportPath(collectionExportPath) ); @@ -1102,7 +1094,7 @@ class ExportService { fileExportName, file ); - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(collectionExportPath, fileExportName), updatedFileStream ); @@ -1150,7 +1142,7 @@ class ExportService { imageExportName, file ); - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(collectionExportPath, imageExportName), imageStream ); @@ -1162,12 +1154,12 @@ class ExportService { file ); try { - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(collectionExportPath, videoExportName), videoStream ); } catch (e) { - ElectronFSService.deleteFile( + ElectronAPIs.deleteFile( getFileExportPath(collectionExportPath, imageExportName) ); throw e; @@ -1183,7 +1175,7 @@ class ExportService { fileExportName: string, file: EnteFile ) { - await this.electronAPIs.saveFileToDisk( + await ElectronAPIs.saveFileToDisk( getFileMetadataExportPath(collectionExportPath, fileExportName), getGoogleLikeMetadataFile(fileExportName, file) ); @@ -1194,15 +1186,15 @@ class ExportService { }; exists = (path: string) => { - return this.electronAPIs.exists(path); + return ElectronAPIs.exists(path); }; rename = (oldPath: string, newPath: string) => { - return this.electronAPIs.rename(oldPath, newPath); + return ElectronAPIs.rename(oldPath, newPath); }; checkExistsAndCreateDir = (path: string) => { - return this.electronAPIs.checkExistsAndCreateDir(path); + return ElectronAPIs.checkExistsAndCreateDir(path); }; exportFolderExists = (exportFolder: string) => { @@ -1224,7 +1216,7 @@ class ExportService { private createEmptyExportRecord = async (exportRecordJSONPath: string) => { const exportRecord: ExportRecord = NULL_EXPORT_RECORD; - await this.electronAPIs.saveFileToDisk( + await ElectronAPIs.saveFileToDisk( exportRecordJSONPath, JSON.stringify(exportRecord, null, 2) ); diff --git a/apps/photos/src/services/export/migration.ts b/apps/photos/src/services/export/migration.ts index 9815df124..ca224d9f9 100644 --- a/apps/photos/src/services/export/migration.ts +++ b/apps/photos/src/services/export/migration.ts @@ -26,7 +26,7 @@ import { } from 'utils/file'; import { addLocalLog, addLogLine } from '@ente/shared/logging'; import { logError } from '@ente/shared/sentry'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import exportService from './index'; import { Collection } from 'types/collection'; import { diff --git a/apps/photos/src/services/ffmpeg/ffmpegFactory.ts b/apps/photos/src/services/ffmpeg/ffmpegFactory.ts index 790c711fd..1fa408c11 100644 --- a/apps/photos/src/services/ffmpeg/ffmpegFactory.ts +++ b/apps/photos/src/services/ffmpeg/ffmpegFactory.ts @@ -1,5 +1,5 @@ +import ElectronAPIs from '@ente/shared/electron'; import isElectron from 'is-electron'; -import { ElectronFFmpeg } from 'services/electron/ffmpeg'; import { ElectronFile } from 'types/upload'; import ComlinkFFmpegWorker from 'utils/comlink/ComlinkFFmpegWorker'; @@ -17,7 +17,16 @@ class FFmpegFactory { async getFFmpegClient() { if (!this.client) { if (isElectron()) { - this.client = new ElectronFFmpeg(); + this.client = { + run(cmd, inputFile, outputFilename, dontTimeout) { + return ElectronAPIs.runFFmpegCmd( + cmd, + inputFile, + outputFilename, + dontTimeout + ); + }, + }; } else { this.client = await ComlinkFFmpegWorker.getInstance(); } diff --git a/apps/photos/src/services/fileService.ts b/apps/photos/src/services/fileService.ts index 0726841fa..1e804172c 100644 --- a/apps/photos/src/services/fileService.ts +++ b/apps/photos/src/services/fileService.ts @@ -1,5 +1,5 @@ import { getEndpoint } from 'utils/common/apiUtil'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { getToken } from 'utils/common/key'; import { Collection } from 'types/collection'; @@ -22,7 +22,7 @@ import { import { SetFiles } from 'types/gallery'; import { BulkUpdateMagicMetadataRequest } from 'types/magicMetadata'; import { addLogLine } from '@ente/shared/logging'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { getCollectionLastSyncTime, setCollectionLastSyncTime, diff --git a/apps/photos/src/services/electron/imageProcessor.ts b/apps/photos/src/services/imageProcessor.ts similarity index 75% rename from apps/photos/src/services/electron/imageProcessor.ts rename to apps/photos/src/services/imageProcessor.ts index c5719cf44..84b78d901 100644 --- a/apps/photos/src/services/electron/imageProcessor.ts +++ b/apps/photos/src/services/imageProcessor.ts @@ -1,28 +1,16 @@ -import { ElectronAPIs } from 'types/electron'; +import ElectronAPIs from '@ente/shared/electron'; +import { addLogLine } from '@ente/shared/logging'; +import { logError } from '@ente/shared/sentry'; import { ElectronFile } from 'types/upload'; import { CustomError } from 'utils/error'; import { convertBytesToHumanReadable } from 'utils/file/size'; -import { addLogLine } from '@ente/shared/logging'; -import { logError } from '@ente/shared/sentry'; class ElectronImageProcessorService { - private electronAPIs: ElectronAPIs; - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - } - - generateImageThumbnailAPIExists() { - return !!this.electronAPIs?.generateImageThumbnail; - } - async convertToJPEG(fileBlob: Blob, filename: string): Promise { try { - if (!this.electronAPIs?.convertToJPEG) { - throw new Error('convertToJPEG API not available'); - } const startTime = Date.now(); const inputFileData = new Uint8Array(await fileBlob.arrayBuffer()); - const convertedFileData = await this.electronAPIs.convertToJPEG( + const convertedFileData = await ElectronAPIs.convertToJPEG( inputFileData, filename ); @@ -51,11 +39,8 @@ class ElectronImageProcessorService { maxSize: number ): Promise { try { - if (!this.electronAPIs?.generateImageThumbnail) { - throw new Error('generateImageThumbnail API not available'); - } const startTime = Date.now(); - const thumb = await this.electronAPIs.generateImageThumbnail( + const thumb = await ElectronAPIs.generateImageThumbnail( inputFile, maxDimension, maxSize diff --git a/apps/photos/src/services/importService.ts b/apps/photos/src/services/importService.ts index f14289250..328aec4bb 100644 --- a/apps/photos/src/services/importService.ts +++ b/apps/photos/src/services/importService.ts @@ -1,8 +1,8 @@ import { PICKED_UPLOAD_TYPE } from 'constants/upload'; import { Collection } from 'types/collection'; -import { ElectronAPIs } from 'types/electron'; import { ElectronFile, FileWithCollection } from 'types/upload'; import { logError } from '@ente/shared/sentry'; +import ElectronAPIs from '@ente/shared/electron'; interface PendingUploads { files: ElectronFile[]; @@ -10,53 +10,12 @@ interface PendingUploads { type: PICKED_UPLOAD_TYPE; } -interface selectZipResult { - files: ElectronFile[]; - zipPaths: string[]; -} class ImportService { - electronAPIs: ElectronAPIs; - private allElectronAPIsExist: boolean = false; - - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - this.allElectronAPIsExist = !!this.electronAPIs?.getPendingUploads; - } - - async getElectronFilesFromGoogleZip( - zipPath: string - ): Promise { - if (this.allElectronAPIsExist) { - return this.electronAPIs.getElectronFilesFromGoogleZip(zipPath); - } - } - - checkAllElectronAPIsExists = () => this.allElectronAPIsExist; - - async showUploadFilesDialog(): Promise { - if (this.allElectronAPIsExist) { - return this.electronAPIs.showUploadFilesDialog(); - } - } - - async showUploadDirsDialog(): Promise { - if (this.allElectronAPIsExist) { - return this.electronAPIs.showUploadDirsDialog(); - } - } - - async showUploadZipDialog(): Promise { - if (this.allElectronAPIsExist) { - return this.electronAPIs.showUploadZipDialog(); - } - } async getPendingUploads(): Promise { try { - if (this.allElectronAPIsExist) { - const pendingUploads = - (await this.electronAPIs.getPendingUploads()) as PendingUploads; - return pendingUploads; - } + const pendingUploads = + (await ElectronAPIs.getPendingUploads()) as PendingUploads; + return pendingUploads; } catch (e) { if (e?.message?.includes('ENOENT: no such file or directory')) { // ignore @@ -68,9 +27,8 @@ class ImportService { } async setToUploadCollection(collections: Collection[]) { - if (this.allElectronAPIsExist) { - let collectionName: string = null; - /* collection being one suggest one of two things + let collectionName: string = null; + /* collection being one suggest one of two things 1. Either the user has upload to a single existing collection 2. Created a new single collection to upload to may have had multiple folder, but chose to upload @@ -79,52 +37,33 @@ class ImportService { helps the info of user choosing this options and on next upload we can directly start uploading to this collection */ - if (collections.length === 1) { - collectionName = collections[0].name; - } - this.electronAPIs.setToUploadCollection(collectionName); - } - } - - async setToUploadFiles( - type: PICKED_UPLOAD_TYPE.FILES | PICKED_UPLOAD_TYPE.ZIPS, - filePaths: string[] - ) { - if (this.allElectronAPIsExist) { - this.electronAPIs.setToUploadFiles(type, filePaths); + if (collections.length === 1) { + collectionName = collections[0].name; } + ElectronAPIs.setToUploadCollection(collectionName); } updatePendingUploads(files: FileWithCollection[]) { - if (this.allElectronAPIsExist) { - const filePaths = []; - for (const fileWithCollection of files) { - if (fileWithCollection.isLivePhoto) { - filePaths.push( - ( - fileWithCollection.livePhotoAssets - .image as ElectronFile - ).path, - ( - fileWithCollection.livePhotoAssets - .video as ElectronFile - ).path - ); - } else { - filePaths.push( - (fileWithCollection.file as ElectronFile).path - ); - } + const filePaths = []; + for (const fileWithCollection of files) { + if (fileWithCollection.isLivePhoto) { + filePaths.push( + (fileWithCollection.livePhotoAssets.image as ElectronFile) + .path, + (fileWithCollection.livePhotoAssets.video as ElectronFile) + .path + ); + } else { + filePaths.push((fileWithCollection.file as ElectronFile).path); } - this.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, filePaths); } + ElectronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, filePaths); } + cancelRemainingUploads() { - if (this.allElectronAPIsExist) { - this.electronAPIs.setToUploadCollection(null); - this.electronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.ZIPS, []); - this.electronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, []); - } + ElectronAPIs.setToUploadCollection(null); + ElectronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.ZIPS, []); + ElectronAPIs.setToUploadFiles(PICKED_UPLOAD_TYPE.FILES, []); } } diff --git a/apps/photos/src/services/machineLearning/machineLearningFactory.ts b/apps/photos/src/services/machineLearning/machineLearningFactory.ts index 67e7f9859..65ad9c5cb 100644 --- a/apps/photos/src/services/machineLearning/machineLearningFactory.ts +++ b/apps/photos/src/services/machineLearning/machineLearningFactory.ts @@ -30,8 +30,8 @@ import mobileFaceNetEmbeddingService from './mobileFaceNetEmbeddingService'; import dbscanClusteringService from './dbscanClusteringService'; import ssdMobileNetV2Service from './ssdMobileNetV2Service'; import imageSceneService from './imageSceneService'; -import { getDedicatedCryptoWorker } from 'utils/comlink/ComlinkCryptoWorker'; -import { ComlinkWorker } from 'utils/comlink/comlinkWorker'; +import { getDedicatedCryptoWorker } from '@ente/shared/crypto'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; import { DedicatedCryptoWorker } from 'worker/crypto.worker'; import { addLogLine } from '@ente/shared/logging'; diff --git a/apps/photos/src/services/machineLearning/mlWorkManager.ts b/apps/photos/src/services/machineLearning/mlWorkManager.ts index 834a7cf8b..b529555d5 100644 --- a/apps/photos/src/services/machineLearning/mlWorkManager.ts +++ b/apps/photos/src/services/machineLearning/mlWorkManager.ts @@ -9,7 +9,7 @@ import { getMLSyncJobConfig } from 'utils/machineLearning/config'; import { logError } from '@ente/shared/sentry'; import mlIDbStorage from 'utils/storage/mlIDbStorage'; import { MLSyncJobResult, MLSyncJob } from './mlSyncJob'; -import { ComlinkWorker } from 'utils/comlink/comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; import { DedicatedMLWorker } from 'worker/ml.worker'; import { getDedicatedMLWorker } from 'utils/comlink/ComlinkMLWorker'; import { addLogLine } from '@ente/shared/logging'; diff --git a/apps/photos/src/services/migrateThumbnailService.ts b/apps/photos/src/services/migrateThumbnailService.ts index dce5025d0..ed4f27c83 100644 --- a/apps/photos/src/services/migrateThumbnailService.ts +++ b/apps/photos/src/services/migrateThumbnailService.ts @@ -13,7 +13,7 @@ import { UploadURL } from 'types/upload'; import { S3FileAttributes } from 'types/file'; import { Remote } from 'comlink'; import { DedicatedCryptoWorker } from 'worker/crypto.worker'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; const ENDPOINT = getEndpoint(); const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB diff --git a/apps/photos/src/services/publicCollectionDownloadManager.ts b/apps/photos/src/services/publicCollectionDownloadManager.ts index db77ed314..b1537aeb6 100644 --- a/apps/photos/src/services/publicCollectionDownloadManager.ts +++ b/apps/photos/src/services/publicCollectionDownloadManager.ts @@ -13,7 +13,7 @@ import { EnteFile } from 'types/file'; import { logError } from '@ente/shared/sentry'; import { FILE_TYPE } from 'constants/file'; import { CustomError } from 'utils/error'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { CACHES } from 'constants/cache'; import { CacheStorageService } from './cache/cacheStorageService'; import { LimitedCache } from 'types/cache'; diff --git a/apps/photos/src/services/publicCollectionService.ts b/apps/photos/src/services/publicCollectionService.ts index 947a2663d..f4aad91a3 100644 --- a/apps/photos/src/services/publicCollectionService.ts +++ b/apps/photos/src/services/publicCollectionService.ts @@ -1,5 +1,5 @@ import { getEndpoint } from 'utils/common/apiUtil'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { Collection, CollectionPublicMagicMetadata } from 'types/collection'; import HTTPService from './HTTPService'; import { logError } from '@ente/shared/sentry'; @@ -12,7 +12,7 @@ import { } from 'types/publicCollection'; import { REPORT_REASON } from 'constants/publicCollection'; import { CustomError, parseSharingErrorCodes } from 'utils/error'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; const ENDPOINT = getEndpoint(); const PUBLIC_COLLECTION_FILES_TABLE = 'public-collection-files'; diff --git a/apps/photos/src/services/trashService.ts b/apps/photos/src/services/trashService.ts index ed26156a7..f79dd8d81 100644 --- a/apps/photos/src/services/trashService.ts +++ b/apps/photos/src/services/trashService.ts @@ -4,7 +4,7 @@ import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { decryptFile, sortTrashFiles } from 'utils/file'; import { logError } from '@ente/shared/sentry'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { getCollection } from './collectionService'; import HTTPService from './HTTPService'; diff --git a/apps/photos/src/services/upload/thumbnailService.ts b/apps/photos/src/services/upload/thumbnailService.ts index 44ef5bb39..a63be2b88 100644 --- a/apps/photos/src/services/upload/thumbnailService.ts +++ b/apps/photos/src/services/upload/thumbnailService.ts @@ -3,7 +3,7 @@ import { CustomError, errorWithContext } from 'utils/error'; import { logError } from '@ente/shared/sentry'; import { BLACK_THUMBNAIL_BASE64 } from 'constants/upload'; import * as FFmpegService from 'services/ffmpeg/ffmpegService'; -import ElectronImageProcessorService from 'services/electron/imageProcessor'; +import ElectronAPIs from '@ente/shared/electron'; import { convertBytesToHumanReadable } from 'utils/file/size'; import { ElectronFile, FileTypeInfo } from 'types/upload'; import { getUint8ArrayView } from '../readerService'; @@ -11,6 +11,7 @@ import { addLogLine } from '@ente/shared/logging'; import { getFileNameSize } from '@ente/shared/logging/web'; import HeicConversionService from 'services/heicConversionService'; import { isFileHEIC } from 'utils/file'; +import isElectron from 'is-electron'; const MAX_THUMBNAIL_DIMENSION = 720; const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10; @@ -83,9 +84,9 @@ async function generateImageThumbnail( file: File | ElectronFile, fileTypeInfo: FileTypeInfo ) { - if (ElectronImageProcessorService.generateImageThumbnailAPIExists()) { + if (isElectron()) { try { - return await ElectronImageProcessorService.generateImageThumbnail( + return await ElectronAPIs.generateImageThumbnail( file, MAX_THUMBNAIL_DIMENSION, MAX_THUMBNAIL_SIZE diff --git a/apps/photos/src/services/upload/uploadManager.ts b/apps/photos/src/services/upload/uploadManager.ts index dd686236f..e27b0b5a4 100644 --- a/apps/photos/src/services/upload/uploadManager.ts +++ b/apps/photos/src/services/upload/uploadManager.ts @@ -31,13 +31,13 @@ import watchFolderService from 'services/watchFolder/watchFolderService'; import { ProgressUpdater } from 'types/upload/ui'; import uploadCancelService from './uploadCancelService'; import { DedicatedCryptoWorker } from 'worker/crypto.worker'; -import { ComlinkWorker } from 'utils/comlink/comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; import { Remote } from 'comlink'; import { getLocalPublicFiles, getPublicCollectionUID, } from 'services/publicCollectionService'; -import { getDedicatedCryptoWorker } from 'utils/comlink/ComlinkCryptoWorker'; +import { getDedicatedCryptoWorker } from '@ente/shared/crypto'; import { getDisableCFUploadProxyFlag } from 'services/userService'; const MAX_CONCURRENT_UPLOADS = 4; diff --git a/apps/photos/src/services/userService.ts b/apps/photos/src/services/userService.ts index e4612b358..34b90f361 100644 --- a/apps/photos/src/services/userService.ts +++ b/apps/photos/src/services/userService.ts @@ -4,7 +4,7 @@ import { isDevDeployment, } from 'utils/common/apiUtil'; import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; -import localForage from 'utils/storage/localForage'; +import localForage from '@ente/shared/storage/localForage'; import { getToken } from 'utils/common/key'; import HTTPService from './HTTPService'; import { getRecoveryKey } from 'utils/crypto'; @@ -18,7 +18,7 @@ import { import { ApiError } from 'utils/error'; import { getLocalFamilyData, isPartOfFamily } from 'utils/user/family'; import { AxiosResponse, HttpStatusCode } from 'axios'; -import { setLocalMapEnabled } from 'utils/storage'; +import { setLocalMapEnabled } from '@ente/shared/storage/localStorage/helpers'; import { putAttributes } from '@ente/accounts/api/user'; import { logoutUser } from '@ente/accounts/services/user'; diff --git a/apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts b/apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts index 64c839111..f9ce49c50 100644 --- a/apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts +++ b/apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts @@ -4,7 +4,7 @@ import { retryAsyncFunction } from 'utils/network'; import { logError } from '@ente/shared/sentry'; import { addLogLine } from '@ente/shared/logging'; import { DedicatedConvertWorker } from 'worker/convert.worker'; -import { ComlinkWorker } from 'utils/comlink/comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; import { convertBytesToHumanReadable } from 'utils/file/size'; import { getDedicatedConvertWorker } from 'utils/comlink/ComlinkConvertWorker'; diff --git a/apps/photos/src/services/watchFolder/watchFolderService.ts b/apps/photos/src/services/watchFolder/watchFolderService.ts index 6064bda31..a66aca3a4 100644 --- a/apps/photos/src/services/watchFolder/watchFolderService.ts +++ b/apps/photos/src/services/watchFolder/watchFolderService.ts @@ -9,7 +9,6 @@ import { WatchMapping, WatchMappingSyncedFile, } from 'types/watchFolder'; -import { ElectronAPIs } from 'types/electron'; import debounce from 'debounce-promise'; import { diskFileAddedCallback, @@ -22,9 +21,9 @@ import uploadManager from 'services/upload/uploadManager'; import { addLocalLog, addLogLine } from '@ente/shared/logging'; import { getValidFilesToUpload } from 'utils/watch'; import { groupFilesBasedOnCollectionID } from 'utils/file'; +import ElectronAPIs from '@ente/shared/electron'; class watchFolderService { - private electronAPIs: ElectronAPIs; private allElectronAPIsExist: boolean = false; private eventQueue: EventQueueItem[] = []; private currentEvent: EventQueueItem; @@ -40,11 +39,6 @@ class watchFolderService { private syncWithRemote: () => void; private setWatchFolderServiceIsRunning: (isRunning: boolean) => void; - constructor() { - this.electronAPIs = globalThis['ElectronAPIs']; - this.allElectronAPIsExist = !!this.electronAPIs?.getWatchMappings; - } - isUploadRunning() { return this.uploadRunning; } @@ -88,7 +82,7 @@ class watchFolderService { for (const mapping of mappings) { const filesOnDisk: ElectronFile[] = - await this.electronAPIs.getDirFiles(mapping.folderPath); + await ElectronAPIs.getDirFiles(mapping.folderPath); this.uploadDiffOfFiles(mapping, filesOnDisk); this.trashDiffOfFiles(mapping, filesOnDisk); @@ -155,11 +149,11 @@ class watchFolderService { ): Promise { const notDeletedMappings = []; for (const mapping of mappings) { - const mappingExists = await this.electronAPIs.isFolder( + const mappingExists = await ElectronAPIs.isFolder( mapping.folderPath ); if (!mappingExists) { - this.electronAPIs.removeWatchMapping(mapping.folderPath); + ElectronAPIs.removeWatchMapping(mapping.folderPath); } else { notDeletedMappings.push(mapping); } @@ -178,7 +172,7 @@ class watchFolderService { private setupWatcherFunctions() { if (this.allElectronAPIsExist) { - this.electronAPIs.registerWatcherFunctions( + ElectronAPIs.registerWatcherFunctions( diskFileAddedCallback, diskFileRemovedCallback, diskFolderRemovedCallback @@ -193,7 +187,7 @@ class watchFolderService { ) { if (this.allElectronAPIsExist) { try { - await this.electronAPIs.addWatchMapping( + await ElectronAPIs.addWatchMapping( rootFolderName, folderPath, uploadStrategy @@ -208,7 +202,7 @@ class watchFolderService { async removeWatchMapping(folderPath: string) { if (this.allElectronAPIsExist) { try { - await this.electronAPIs.removeWatchMapping(folderPath); + await ElectronAPIs.removeWatchMapping(folderPath); } catch (e) { logError(e, 'error while removing watch mapping'); } @@ -218,7 +212,7 @@ class watchFolderService { getWatchMappings(): WatchMapping[] { if (this.allElectronAPIsExist) { try { - return this.electronAPIs.getWatchMappings() ?? []; + return ElectronAPIs.getWatchMappings() ?? []; } catch (e) { logError(e, 'error while getting watch mappings'); return []; @@ -395,7 +389,7 @@ class watchFolderService { ...this.currentlySyncedMapping.syncedFiles, ...syncedFiles, ]; - this.electronAPIs.updateWatchMappingSyncedFiles( + ElectronAPIs.updateWatchMappingSyncedFiles( this.currentlySyncedMapping.folderPath, this.currentlySyncedMapping.syncedFiles ); @@ -405,7 +399,7 @@ class watchFolderService { ...this.currentlySyncedMapping.ignoredFiles, ...ignoredFiles, ]; - this.electronAPIs.updateWatchMappingIgnoredFiles( + ElectronAPIs.updateWatchMappingIgnoredFiles( this.currentlySyncedMapping.folderPath, this.currentlySyncedMapping.ignoredFiles ); @@ -521,7 +515,7 @@ class watchFolderService { this.currentlySyncedMapping.syncedFiles.filter( (file) => !filePathsToRemove.has(file.path) ); - this.electronAPIs.updateWatchMappingSyncedFiles( + ElectronAPIs.updateWatchMappingSyncedFiles( this.currentlySyncedMapping.folderPath, this.currentlySyncedMapping.syncedFiles ); @@ -613,7 +607,7 @@ class watchFolderService { async selectFolder(): Promise { try { - const folderPath = await this.electronAPIs.selectDirectory(); + const folderPath = await ElectronAPIs.selectDirectory(); return folderPath; } catch (e) { logError(e, 'error while selecting folder'); @@ -641,7 +635,7 @@ class watchFolderService { async isFolder(folderPath: string) { try { - const isFolder = await this.electronAPIs.isFolder(folderPath); + const isFolder = await ElectronAPIs.isFolder(folderPath); return isFolder; } catch (e) { logError(e, 'error while checking if folder exists'); diff --git a/apps/photos/src/services/workerElectronCache/client.ts b/apps/photos/src/services/workerElectronCache/client.ts index 48b2ac80b..a4ca1cc32 100644 --- a/apps/photos/src/services/workerElectronCache/client.ts +++ b/apps/photos/src/services/workerElectronCache/client.ts @@ -1,4 +1,4 @@ -import { ElectronCacheStorage } from 'services/electron/cache'; +import ElectronAPIs from '@ente/shared/electron'; import * as Comlink from 'comlink'; import { LimitedCache, @@ -14,7 +14,7 @@ export class WorkerElectronCacheStorageClient implements ProxiedLimitedCacheStorage { async open(cacheName: string) { - const cache = await ElectronCacheStorage.open(cacheName); + const cache = await ElectronAPIs.openDiskCache(cacheName); return Comlink.proxy({ match: Comlink.proxy(transformMatch(cache.match.bind(cache))), put: Comlink.proxy(transformPut(cache.put.bind(cache))), @@ -23,7 +23,7 @@ export class WorkerElectronCacheStorageClient } async delete(cacheName: string) { - return await ElectronCacheStorage.delete(cacheName); + return await ElectronAPIs.deleteDiskCache(cacheName); } } diff --git a/apps/photos/src/types/electron/index.ts b/apps/photos/src/types/electron/index.ts deleted file mode 100644 index 02a903d6f..000000000 --- a/apps/photos/src/types/electron/index.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { LimitedCache } from 'types/cache'; -import { ElectronFile } from 'types/upload'; -import { WatchMapping } from 'types/watchFolder'; - -export interface AppUpdateInfo { - autoUpdatable: boolean; - version: string; -} - -export interface ElectronAPIs { - exists: (path: string) => boolean; - checkExistsAndCreateDir: (dirPath: string) => Promise; - saveStreamToDisk: ( - path: string, - fileStream: ReadableStream - ) => Promise; - saveFileToDisk: (path: string, file: any) => Promise; - selectDirectory: () => Promise; - sendNotification: (content: string) => void; - readTextFile: (path: string) => Promise; - showUploadFilesDialog: () => Promise; - showUploadDirsDialog: () => Promise; - getPendingUploads: () => Promise<{ - files: ElectronFile[]; - collectionName: string; - type: string; - }>; - setToUploadFiles: (type: string, filePaths: string[]) => void; - showUploadZipDialog: () => Promise<{ - zipPaths: string[]; - files: ElectronFile[]; - }>; - getElectronFilesFromGoogleZip: ( - filePath: string - ) => Promise; - setToUploadCollection: (collectionName: string) => void; - getDirFiles: (dirPath: string) => Promise; - getWatchMappings: () => WatchMapping[]; - updateWatchMappingSyncedFiles: ( - folderPath: string, - files: WatchMapping['syncedFiles'] - ) => void; - updateWatchMappingIgnoredFiles: ( - folderPath: string, - files: WatchMapping['ignoredFiles'] - ) => void; - addWatchMapping: ( - collectionName: string, - folderPath: string, - uploadStrategy: number - ) => Promise; - removeWatchMapping: (folderPath: string) => Promise; - registerWatcherFunctions: ( - addFile: (file: ElectronFile) => Promise, - removeFile: (path: string) => Promise, - removeFolder: (folderPath: string) => Promise - ) => void; - isFolder: (dirPath: string) => Promise; - clearElectronStore: () => void; - setEncryptionKey: (encryptionKey: string) => Promise; - getEncryptionKey: () => Promise; - openDiskCache: (cacheName: string) => Promise; - deleteDiskCache: (cacheName: string) => Promise; - logToDisk: (msg: string) => void; - convertToJPEG: ( - fileData: Uint8Array, - filename: string - ) => Promise; - openLogDirectory: () => void; - registerUpdateEventListener: ( - showUpdateDialog: (updateInfo: AppUpdateInfo) => void - ) => void; - updateAndRestart: () => void; - skipAppUpdate: (version: string) => void; - getSentryUserID: () => Promise; - getAppVersion: () => Promise; - runFFmpegCmd: ( - cmd: string[], - inputFile: File | ElectronFile, - outputFileName: string, - dontTimeout?: boolean - ) => Promise; - muteUpdateNotification: (version: string) => void; - generateImageThumbnail: ( - inputFile: File | ElectronFile, - maxDimension: number, - maxSize: number - ) => Promise; - logRendererProcessMemoryUsage: (message: string) => Promise; - registerForegroundEventListener: (onForeground: () => void) => void; - openDirectory: (dirPath: string) => Promise; - moveFile: (oldPath: string, newPath: string) => Promise; - deleteFolder: (path: string) => Promise; - deleteFile: (path: string) => void; - rename: (oldPath: string, newPath: string) => Promise; - updateOptOutOfCrashReports: (optOut: boolean) => Promise; - computeImageEmbedding: (imageData: Uint8Array) => Promise; - computeTextEmbedding: (text: string) => Promise; - getPlatform: () => Promise<'mac' | 'windows' | 'linux'>; -} diff --git a/apps/photos/src/utils/billing/index.ts b/apps/photos/src/utils/billing/index.ts index 30373da29..cdb0a4ed0 100644 --- a/apps/photos/src/utils/billing/index.ts +++ b/apps/photos/src/utils/billing/index.ts @@ -4,7 +4,7 @@ import billingService from 'services/billingService'; import { Plan, Subscription } from 'types/billing'; import { NextRouter } from 'next/router'; import { SetLoading } from 'types/gallery'; -import { getData, LS_KEYS } from '../storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import { logError } from '@ente/shared/sentry'; import { SetDialogBoxAttributes } from 'types/dialogBox'; import { openLink } from 'utils/common'; diff --git a/apps/photos/src/utils/collection/index.ts b/apps/photos/src/utils/collection/index.ts index 27b705c41..7ba83a187 100644 --- a/apps/photos/src/utils/collection/index.ts +++ b/apps/photos/src/utils/collection/index.ts @@ -17,7 +17,7 @@ import { getAllLocalFiles, getLocalFiles } from 'services/fileService'; import { EnteFile } from 'types/file'; import { CustomError } from 'utils/error'; import { User } from 'types/user'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import { logError } from '@ente/shared/sentry'; import { COLLECTION_ROLE, @@ -45,7 +45,7 @@ import bs58 from 'bs58'; import { t } from 'i18next'; import isElectron from 'is-electron'; import { SetCollectionDownloadProgressAttributes } from 'types/gallery'; -import ElectronService from 'services/electron/common'; +import ElectronAPIs from '@ente/shared/electron'; import { getCollectionExportPath, getUniqueCollectionExportName, @@ -186,7 +186,7 @@ async function downloadCollectionFiles( downloadDirPath: null, }; if (isElectron()) { - const selectedDir = await ElectronService.selectDirectory(); + const selectedDir = await ElectronAPIs.selectDirectory(); if (!selectedDir) { return; } diff --git a/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts b/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts index c5a436728..ac1e3dc90 100644 --- a/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts +++ b/apps/photos/src/utils/comlink/ComlinkConvertWorker.ts @@ -1,7 +1,7 @@ import { Remote } from 'comlink'; import { runningInBrowser } from 'utils/common'; import { DedicatedConvertWorker } from 'worker/convert.worker'; -import { ComlinkWorker } from './comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; class ComlinkConvertWorker { private comlinkWorkerInstance: Remote; diff --git a/apps/photos/src/utils/comlink/ComlinkCryptoWorker.ts b/apps/photos/src/utils/comlink/ComlinkCryptoWorker.ts deleted file mode 100644 index 2410d469a..000000000 --- a/apps/photos/src/utils/comlink/ComlinkCryptoWorker.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Remote } from 'comlink'; -import { DedicatedCryptoWorker } from 'worker/crypto.worker'; -import { ComlinkWorker } from './comlinkWorker'; - -class ComlinkCryptoWorker { - private comlinkWorkerInstance: Promise>; - - async getInstance() { - if (!this.comlinkWorkerInstance) { - const comlinkWorker = getDedicatedCryptoWorker(); - this.comlinkWorkerInstance = comlinkWorker.remote; - } - return this.comlinkWorkerInstance; - } -} - -export const getDedicatedCryptoWorker = () => { - const cryptoComlinkWorker = new ComlinkWorker( - 'ente-crypto-worker', - new Worker(new URL('worker/crypto.worker.ts', import.meta.url)) - ); - return cryptoComlinkWorker; -}; - -export default new ComlinkCryptoWorker(); diff --git a/apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts b/apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts index efc71bf99..3593c2931 100644 --- a/apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts +++ b/apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts @@ -1,6 +1,6 @@ import { Remote } from 'comlink'; import { DedicatedFFmpegWorker } from 'worker/ffmpeg.worker'; -import { ComlinkWorker } from './comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; class ComlinkFFmpegWorker { private comlinkWorkerInstance: Promise>; diff --git a/apps/photos/src/utils/comlink/ComlinkMLWorker.ts b/apps/photos/src/utils/comlink/ComlinkMLWorker.ts index 6eed2a8b9..0931792fd 100644 --- a/apps/photos/src/utils/comlink/ComlinkMLWorker.ts +++ b/apps/photos/src/utils/comlink/ComlinkMLWorker.ts @@ -1,6 +1,6 @@ import { runningInBrowser } from 'utils/common'; import { DedicatedMLWorker } from 'worker/ml.worker'; -import { ComlinkWorker } from './comlinkWorker'; +import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker'; export const getDedicatedMLWorker = (name: string) => { if (runningInBrowser()) { diff --git a/apps/photos/src/utils/comlink/comlinkWorker.ts b/apps/photos/src/utils/comlink/comlinkWorker.ts deleted file mode 100644 index 7b4935800..000000000 --- a/apps/photos/src/utils/comlink/comlinkWorker.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { expose, Remote, wrap } from 'comlink'; -import { WorkerElectronCacheStorageClient } from 'services/workerElectronCache/client'; -import { addLocalLog } from '@ente/shared/logging'; - -export class ComlinkWorker InstanceType> { - public remote: Promise>>; - private worker: Worker; - private name: string; - - constructor(name: string, worker: Worker) { - this.name = name; - this.worker = worker; - - this.worker.onerror = (errorEvent) => { - console.error('Got error event from worker', errorEvent); - }; - addLocalLog(() => `Initiated ${this.name}`); - const comlink = wrap(this.worker); - this.remote = new comlink() as Promise>>; - expose(WorkerElectronCacheStorageClient, this.worker); - } - - public terminate() { - this.worker.terminate(); - addLocalLog(() => `Terminated ${this.name}`); - } -} diff --git a/apps/photos/src/utils/common/apiUtil.ts b/apps/photos/src/utils/common/apiUtil.ts index 169521737..6d9ef81c0 100644 --- a/apps/photos/src/utils/common/apiUtil.ts +++ b/apps/photos/src/utils/common/apiUtil.ts @@ -1,4 +1,4 @@ -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; export const getEndpoint = () => { let endpoint = getData(LS_KEYS.API_ENDPOINT); diff --git a/apps/photos/src/utils/common/key.ts b/apps/photos/src/utils/common/key.ts index 02aa22c9d..74e6a7a74 100644 --- a/apps/photos/src/utils/common/key.ts +++ b/apps/photos/src/utils/common/key.ts @@ -1,7 +1,7 @@ import { B64EncryptionResult } from 'types/crypto'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; -import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; +import { getKey, SESSION_KEYS } from '@ente/shared/storage/sessionStorage'; import { CustomError } from '../error'; export const getActualKey = async () => { diff --git a/apps/photos/src/utils/crypto/index.ts b/apps/photos/src/utils/crypto/index.ts index c816bd93b..31b1e9396 100644 --- a/apps/photos/src/utils/crypto/index.ts +++ b/apps/photos/src/utils/crypto/index.ts @@ -1,12 +1,13 @@ import { KeyAttributes, SRPSetupAttributes } from 'types/user'; -import { SESSION_KEYS, setKey } from 'utils/storage/sessionStorage'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; +import { SESSION_KEYS, setKey } from '@ente/shared/storage/sessionStorage'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; import { getActualKey, getToken } from 'utils/common/key'; import { setRecoveryKey } from '@ente/accounts/api/user'; import { logError } from '@ente/shared/sentry'; import isElectron from 'is-electron'; -import safeStorageService from 'services/electron/safeStorage'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ElectronAPIs from '@ente/shared/electron'; + +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { PasswordStrength } from 'constants/crypto'; import zxcvbn from 'zxcvbn'; import { SRP, SrpClient } from 'fast-srp-hap'; @@ -125,7 +126,7 @@ export const saveKeyInSessionStore = async ( !fromDesktop && keyType === SESSION_KEYS.ENCRYPTION_KEY ) { - safeStorageService.setEncryptionKey(key); + ElectronAPIs.setEncryptionKey(key); } }; diff --git a/apps/photos/src/utils/file/index.ts b/apps/photos/src/utils/file/index.ts index 17fcd10fc..1cc030f2e 100644 --- a/apps/photos/src/utils/file/index.ts +++ b/apps/photos/src/utils/file/index.ts @@ -13,7 +13,7 @@ import { getFileType } from 'services/typeDetectionService'; import DownloadManager from 'services/downloadManager'; import { logError } from '@ente/shared/sentry'; import { User } from 'types/user'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; import { updateFileCreationDateInEXIF } from 'services/upload/exifService'; import { TYPE_JPEG, @@ -33,7 +33,7 @@ import { isArchivedFile, updateMagicMetadata } from 'utils/magicMetadata'; import { addLocalLog, addLogLine } from '@ente/shared/logging'; import { CustomError } from 'utils/error'; import { convertBytesToHumanReadable } from './size'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; import { deleteFromTrash, trashFiles, @@ -41,13 +41,14 @@ import { updateFilePublicMagicMetadata, } from 'services/fileService'; import isElectron from 'is-electron'; -import imageProcessor from 'services/electron/imageProcessor'; import { isPlaybackPossible } from 'utils/photoFrame'; import { FileTypeInfo } from 'types/upload'; import { moveToHiddenCollection } from 'services/collectionService'; -import ElectronFSService from 'services/electron/fs'; +import ElectronFSService from '@ente/shared/electron'; import { getFileExportPath, getUniqueFileExportName } from 'utils/export'; +import imageProcessor from 'services/imageProcessor'; +import ElectronAPIs from '@ente/shared/electron'; const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000; @@ -712,7 +713,7 @@ export async function downloadFileDesktop( livePhoto.imageNameTitle ); const imageStream = generateStreamFromArrayBuffer(livePhoto.image); - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(downloadPath, imageExportName), imageStream ); @@ -722,7 +723,7 @@ export async function downloadFileDesktop( livePhoto.videoNameTitle ); const videoStream = generateStreamFromArrayBuffer(livePhoto.video); - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(downloadPath, videoExportName), videoStream ); @@ -737,7 +738,7 @@ export async function downloadFileDesktop( downloadPath, file.metadata.title ); - await ElectronFSService.saveMediaFile( + await ElectronAPIs.saveStreamToDisk( getFileExportPath(downloadPath, fileExportName), updatedFileStream ); diff --git a/apps/photos/src/utils/machineLearning/faceCrop.ts b/apps/photos/src/utils/machineLearning/faceCrop.ts index c9217e9f1..2e4d4bdc8 100644 --- a/apps/photos/src/utils/machineLearning/faceCrop.ts +++ b/apps/photos/src/utils/machineLearning/faceCrop.ts @@ -13,7 +13,7 @@ import { } from 'types/machineLearning'; import { cropWithRotation, imageBitmapToBlob } from 'utils/image'; import { addLogLine } from '@ente/shared/logging'; -import { getBlobFromCache } from 'utils/storage/cache'; +import { getBlobFromCache } from '@ente/shared/storage/cacheStorage/helpers'; import { enlargeBox } from '.'; import { Box } from '../../../thirdparty/face-api/classes'; import { getAlignedFaceBox } from './faceAlign'; diff --git a/apps/photos/src/utils/machineLearning/index.ts b/apps/photos/src/utils/machineLearning/index.ts index e63f26651..c18514b39 100644 --- a/apps/photos/src/utils/machineLearning/index.ts +++ b/apps/photos/src/utils/machineLearning/index.ts @@ -24,7 +24,7 @@ import { // import { mlFilesStore, mlPeopleStore } from 'utils/storage/mlStorage'; import { getRenderableImage } from 'utils/file'; import { imageBitmapToBlob } from 'utils/image'; -import { cached } from 'utils/storage/cache'; +import { cached } from '@ente/shared/storage/cacheStorage/helpers'; import mlIDbStorage from 'utils/storage/mlIDbStorage'; import { Box, Point } from '../../../thirdparty/face-api/classes'; import { diff --git a/apps/photos/src/utils/magicMetadata/index.ts b/apps/photos/src/utils/magicMetadata/index.ts index a650d0a82..7ed18f1c0 100644 --- a/apps/photos/src/utils/magicMetadata/index.ts +++ b/apps/photos/src/utils/magicMetadata/index.ts @@ -1,7 +1,7 @@ import { Collection } from 'types/collection'; import { EnteFile } from 'types/file'; import { MagicMetadataCore, VISIBILITY_STATE } from 'types/magicMetadata'; -import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker'; +import ComlinkCryptoWorker from '@ente/shared/crypto'; export function isArchivedFile(item: EnteFile): boolean { if (!item || !item.magicMetadata || !item.magicMetadata.data) { diff --git a/apps/photos/src/utils/storage/cache.ts b/apps/photos/src/utils/storage/cache.ts deleted file mode 100644 index 7894e0775..000000000 --- a/apps/photos/src/utils/storage/cache.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { CACHES } from 'constants/cache'; -import { CacheStorageService } from 'services/cache/cacheStorageService'; -import { logError } from '@ente/shared/sentry'; - -export async function cached( - cacheName: string, - id: string, - get: () => Promise -): Promise { - const cache = await CacheStorageService.open(cacheName); - const cacheResponse = await cache.match(id); - - let result: Blob; - if (cacheResponse) { - result = await cacheResponse.blob(); - } else { - result = await get(); - - try { - await cache.put(id, new Response(result)); - } catch (e) { - // TODO: handle storage full exception. - console.error('Error while storing file to cache: ', id); - } - } - - return result; -} - -export async function getBlobFromCache( - cacheName: string, - url: string -): Promise { - const cache = await CacheStorageService.open(cacheName); - const response = await cache.match(url); - - return response.blob(); -} - -export async function deleteAllCache() { - try { - await CacheStorageService.delete(CACHES.THUMBS); - await CacheStorageService.delete(CACHES.FACE_CROPS); - await CacheStorageService.delete(CACHES.FILES); - } catch (e) { - logError(e, 'deleteAllCache failed'); // log and ignore - } -} diff --git a/apps/photos/src/utils/storage/index.ts b/apps/photos/src/utils/storage/index.ts deleted file mode 100644 index d159f8215..000000000 --- a/apps/photos/src/utils/storage/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Language } from '@ente/shared/i18n/locale'; -import { getData, LS_KEYS, setData } from './localStorage'; - -export const isFirstLogin = () => - getData(LS_KEYS.IS_FIRST_LOGIN)?.status ?? false; - -export function setIsFirstLogin(status) { - setData(LS_KEYS.IS_FIRST_LOGIN, { status }); -} - -export const justSignedUp = () => - getData(LS_KEYS.JUST_SIGNED_UP)?.status ?? false; - -export function setJustSignedUp(status) { - setData(LS_KEYS.JUST_SIGNED_UP, { status }); -} - -export function getLivePhotoInfoShownCount() { - return getData(LS_KEYS.LIVE_PHOTO_INFO_SHOWN_COUNT)?.count ?? 0; -} - -export function setLivePhotoInfoShownCount(count) { - setData(LS_KEYS.LIVE_PHOTO_INFO_SHOWN_COUNT, { count }); -} - -export function getUserLocale(): Language { - return getData(LS_KEYS.LOCALE)?.value; -} - -export function getLocalMapEnabled(): boolean { - return getData(LS_KEYS.MAP_ENABLED)?.value ?? false; -} - -export function setLocalMapEnabled(value: boolean) { - setData(LS_KEYS.MAP_ENABLED, { value }); -} - -export function getHasOptedOutOfCrashReports(): boolean { - return getData(LS_KEYS.OPT_OUT_OF_CRASH_REPORTS)?.value ?? false; -} diff --git a/apps/photos/src/utils/storage/localForage.ts b/apps/photos/src/utils/storage/localForage.ts deleted file mode 100644 index b807318a6..000000000 --- a/apps/photos/src/utils/storage/localForage.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { runningInBrowser } from 'utils/common'; - -import localForage from 'localforage'; - -if (runningInBrowser()) { - localForage.config({ - name: 'ente-files', - version: 1.0, - storeName: 'files', - }); -} -export default localForage; diff --git a/apps/photos/src/utils/storage/localStorage.ts b/apps/photos/src/utils/storage/localStorage.ts deleted file mode 100644 index d9a61e992..000000000 --- a/apps/photos/src/utils/storage/localStorage.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { logError } from '@ente/shared/sentry'; - -export enum LS_KEYS { - USER = 'user', - SESSION = 'session', - KEY_ATTRIBUTES = 'keyAttributes', - ORIGINAL_KEY_ATTRIBUTES = 'originalKeyAttributes', - SUBSCRIPTION = 'subscription', - FAMILY_DATA = 'familyData', - PLANS = 'plans', - IS_FIRST_LOGIN = 'isFirstLogin', - JUST_SIGNED_UP = 'justSignedUp', - SHOW_BACK_BUTTON = 'showBackButton', - EXPORT = 'export', - AnonymizedUserID = 'anonymizedUserID', - THUMBNAIL_FIX_STATE = 'thumbnailFixState', - LIVE_PHOTO_INFO_SHOWN_COUNT = 'livePhotoInfoShownCount', - LOGS = 'logs', - USER_DETAILS = 'userDetails', - COLLECTION_SORT_BY = 'collectionSortBy', - THEME = 'theme', - WAIT_TIME = 'waitTime', - API_ENDPOINT = 'apiEndpoint', - LOCALE = 'locale', - MAP_ENABLED = 'mapEnabled', - SRP_SETUP_ATTRIBUTES = 'srpSetupAttributes', - SRP_ATTRIBUTES = 'srpAttributes', - OPT_OUT_OF_CRASH_REPORTS = 'optOutOfCrashReports', - CF_PROXY_DISABLED = 'cfProxyDisabled', -} - -export const setData = (key: LS_KEYS, value: object) => { - if (typeof localStorage === 'undefined') { - return null; - } - localStorage.setItem(key, JSON.stringify(value)); -}; - -export const removeData = (key: LS_KEYS) => { - if (typeof localStorage === 'undefined') { - return null; - } - localStorage.removeItem(key); -}; - -export const getData = (key: LS_KEYS) => { - try { - if ( - typeof localStorage === 'undefined' || - typeof key === 'undefined' || - typeof localStorage.getItem(key) === 'undefined' || - localStorage.getItem(key) === 'undefined' - ) { - return null; - } - const data = localStorage.getItem(key); - return data && JSON.parse(data); - } catch (e) { - logError(e, 'Failed to Parse JSON for key ' + key); - } -}; - -export const clearData = () => { - if (typeof localStorage === 'undefined') { - return null; - } - localStorage.clear(); -}; diff --git a/apps/photos/src/utils/storage/mlStorage.ts b/apps/photos/src/utils/storage/mlStorage.ts index 60ef01a87..ea0807cee 100644 --- a/apps/photos/src/utils/storage/mlStorage.ts +++ b/apps/photos/src/utils/storage/mlStorage.ts @@ -1,3 +1,4 @@ +import localForage from 'localforage'; import { EnteFile } from 'types/file'; import { Face, @@ -5,7 +6,6 @@ import { MLIndex, MLSyncContext, } from 'types/machineLearning'; -import localForage from './localForage'; export const mlFilesStore = localForage.createInstance({ driver: localForage.INDEXEDDB, diff --git a/apps/photos/src/utils/storage/sessionStorage.ts b/apps/photos/src/utils/storage/sessionStorage.ts deleted file mode 100644 index bad871f76..000000000 --- a/apps/photos/src/utils/storage/sessionStorage.ts +++ /dev/null @@ -1,32 +0,0 @@ -export enum SESSION_KEYS { - ENCRYPTION_KEY = 'encryptionKey', - KEY_ENCRYPTION_KEY = 'keyEncryptionKey', -} - -export const setKey = (key: SESSION_KEYS, value: object) => { - if (typeof sessionStorage === 'undefined') { - return null; - } - sessionStorage.setItem(key, JSON.stringify(value)); -}; - -export const getKey = (key: SESSION_KEYS) => { - if (typeof sessionStorage === 'undefined') { - return null; - } - return JSON.parse(sessionStorage.getItem(key)); -}; - -export const removeKey = (key: SESSION_KEYS) => { - if (typeof sessionStorage === 'undefined') { - return null; - } - sessionStorage.removeItem(key); -}; - -export const clearKeys = () => { - if (typeof sessionStorage === 'undefined') { - return null; - } - sessionStorage.clear(); -}; diff --git a/apps/photos/src/utils/ui/index.tsx b/apps/photos/src/utils/ui/index.tsx index f8cb17579..cd36f0286 100644 --- a/apps/photos/src/utils/ui/index.tsx +++ b/apps/photos/src/utils/ui/index.tsx @@ -3,14 +3,14 @@ import { DialogBoxAttributes } from 'types/dialogBox'; import { downloadApp } from 'utils/common'; import { t } from 'i18next'; -import ElectronUpdateService from 'services/electron/update'; -import { AppUpdateInfo } from 'types/electron'; +import ElectronAPIs from '@ente/shared/electron'; import InfoOutlined from '@mui/icons-material/InfoRounded'; import { Trans } from 'react-i18next'; import { Subscription } from 'types/billing'; import { logoutUser } from '@ente/accounts/services/user'; import { Link } from '@mui/material'; import { OPEN_STREET_MAP_LINK } from 'components/Sidebar/EnableMap'; +import { AppUpdateInfo } from '@ente/shared/electron/types'; export const getDownloadAppMessage = (): DialogBoxAttributes => { return { title: t('DOWNLOAD_APP'), @@ -58,15 +58,14 @@ export const getUpdateReadyToInstallMessage = ( title: t('UPDATE_AVAILABLE'), content: t('UPDATE_INSTALLABLE_MESSAGE'), proceed: { - action: () => ElectronUpdateService.updateAndRestart(), + action: () => ElectronAPIs.updateAndRestart(), text: t('INSTALL_NOW'), variant: 'accent', }, close: { text: t('INSTALL_ON_NEXT_LAUNCH'), variant: 'secondary', - action: () => - ElectronUpdateService.muteUpdateNotification(updateInfo.version), + action: () => ElectronAPIs.muteUpdateNotification(updateInfo.version), }, }); @@ -79,7 +78,7 @@ export const getUpdateAvailableForDownloadMessage = ( close: { text: t('IGNORE_THIS_VERSION'), variant: 'secondary', - action: () => ElectronUpdateService.skipAppUpdate(updateInfo.version), + action: () => ElectronAPIs.skipAppUpdate(updateInfo.version), }, proceed: { action: downloadApp, diff --git a/apps/photos/src/utils/user/family.ts b/apps/photos/src/utils/user/family.ts index c02ee2d30..cb0c1691e 100644 --- a/apps/photos/src/utils/user/family.ts +++ b/apps/photos/src/utils/user/family.ts @@ -1,6 +1,6 @@ import { FamilyData, FamilyMember, User } from 'types/user'; import { logError } from '@ente/shared/sentry'; -import { getData, LS_KEYS } from 'utils/storage/localStorage'; +import { getData, LS_KEYS } from '@ente/shared/storage/localStorage'; export function getLocalFamilyData(): FamilyData { return getData(LS_KEYS.FAMILY_DATA); diff --git a/apps/photos/src/utils/user/index.ts b/apps/photos/src/utils/user/index.ts index 6ccf9c86d..35b2a3edb 100644 --- a/apps/photos/src/utils/user/index.ts +++ b/apps/photos/src/utils/user/index.ts @@ -1,7 +1,7 @@ import isElectron from 'is-electron'; import { UserDetails } from 'types/user'; -import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; -import ElectronService from 'services/electron/common'; +import { getData, LS_KEYS, setData } from '@ente/shared/storage/localStorage'; +import ElectronAPIs from '@ente/shared/electron'; import { Buffer } from 'buffer'; export function makeID(length) { @@ -19,7 +19,7 @@ export function makeID(length) { export async function getSentryUserID() { if (isElectron()) { - return await ElectronService.getSentryUserID(); + return await ElectronAPIs.getSentryUserID(); } else { let anonymizeUserID = getData(LS_KEYS.AnonymizedUserID)?.id; if (!anonymizeUserID) { diff --git a/packages/shared/crypto/internal/crypto.worker.ts b/packages/shared/crypto/internal/crypto.worker.ts index 3dbacbd0a..784c6e4ef 100644 --- a/packages/shared/crypto/internal/crypto.worker.ts +++ b/packages/shared/crypto/internal/crypto.worker.ts @@ -1,7 +1,9 @@ import * as Comlink from 'comlink'; import { StateAddress } from 'libsodium-wrappers'; -import * as libsodium from './libsodium'; +import * as libsodium from '@ente/shared/crypto/internal/libsodium'; +const textDecoder = new TextDecoder(); +const textEncoder = new TextEncoder(); export class DedicatedCryptoWorker { async decryptMetadata( encryptedMetadata: string, @@ -13,7 +15,7 @@ export class DedicatedCryptoWorker { await libsodium.fromB64(header), key ); - return JSON.parse(new TextDecoder().decode(encodedMetadata)); + return JSON.parse(textDecoder.decode(encodedMetadata)); } async decryptThumbnail( @@ -24,14 +26,27 @@ export class DedicatedCryptoWorker { return libsodium.decryptChaChaOneShot(fileData, header, key); } + async decryptEmbedding( + encryptedEmbedding: string, + header: string, + key: string + ) { + const encodedEmbedding = await libsodium.decryptChaChaOneShot( + await libsodium.fromB64(encryptedEmbedding), + await libsodium.fromB64(header), + key + ); + return Float32Array.from( + JSON.parse(textDecoder.decode(encodedEmbedding)) + ); + } + async decryptFile(fileData: Uint8Array, header: Uint8Array, key: string) { return libsodium.decryptChaCha(fileData, header, key); } async encryptMetadata(metadata: Object, key: string) { - const encodedMetadata = new TextEncoder().encode( - JSON.stringify(metadata) - ); + const encodedMetadata = textEncoder.encode(JSON.stringify(metadata)); const { file: encryptedMetadata } = await libsodium.encryptChaChaOneShot(encodedMetadata, key); @@ -49,6 +64,24 @@ export class DedicatedCryptoWorker { return libsodium.encryptChaChaOneShot(fileData, key); } + async encryptEmbedding(embedding: Float32Array, key: string) { + const encodedEmbedding = textEncoder.encode( + JSON.stringify(Array.from(embedding)) + ); + const { file: encryptEmbedding } = await libsodium.encryptChaChaOneShot( + encodedEmbedding, + key + ); + const { encryptedData, ...other } = encryptEmbedding; + return { + file: { + encryptedData: await libsodium.toB64(encryptedData), + ...other, + }, + key, + }; + } + async encryptFile(fileData: Uint8Array) { return libsodium.encryptChaCha(fileData); } @@ -179,4 +212,4 @@ export class DedicatedCryptoWorker { } } -Comlink.expose(DedicatedCryptoWorker); +Comlink.expose(DedicatedCryptoWorker, self); diff --git a/packages/shared/crypto/internal/libsodium.ts b/packages/shared/crypto/internal/libsodium.ts index de7e2f9c7..958a2af0b 100644 --- a/packages/shared/crypto/internal/libsodium.ts +++ b/packages/shared/crypto/internal/libsodium.ts @@ -1,7 +1,7 @@ import sodium, { StateAddress } from 'libsodium-wrappers'; -import { ENCRYPTION_CHUNK_SIZE } from '../constants'; -import { B64EncryptionResult } from '../types'; -import { CustomError } from '@ente/shared/error'; +import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; +import { B64EncryptionResult } from 'types/crypto'; +import { CustomError } from 'utils/error'; export async function decryptChaChaOneShot( data: Uint8Array,