Ver código fonte

cleanup dead code

Abhinav 1 ano atrás
pai
commit
86d61060b7
78 arquivos alterados com 276 adições e 918 exclusões
  1. 1 1
      apps/photos/src/components/AuthenticateUserModal.tsx
  2. 2 2
      apps/photos/src/components/Collections/CollectionDownloadProgress.tsx
  3. 1 1
      apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx
  4. 1 1
      apps/photos/src/components/Collections/index.tsx
  5. 1 1
      apps/photos/src/components/FixLargeThumbnail.tsx
  6. 1 1
      apps/photos/src/components/MachineLearning/ImageViews.tsx
  7. 1 1
      apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx
  8. 3 3
      apps/photos/src/components/Sidebar/DebugSection.tsx
  9. 1 1
      apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx
  10. 3 3
      apps/photos/src/components/Sidebar/Preferences/index.tsx
  11. 1 1
      apps/photos/src/components/Sidebar/userDetailsSection.tsx
  12. 1 1
      apps/photos/src/components/TwoFactor/Modal/Manage.tsx
  13. 1 1
      apps/photos/src/components/TwoFactor/Modal/index.tsx
  14. 9 9
      apps/photos/src/components/Upload/Uploader.tsx
  15. 2 2
      apps/photos/src/components/WatchFolder/index.tsx
  16. 1 1
      apps/photos/src/components/pages/gallery/PlanSelector/card/index.tsx
  17. 3 3
      apps/photos/src/pages/_app.tsx
  18. 1 1
      apps/photos/src/pages/deduplicate/index.tsx
  19. 10 6
      apps/photos/src/pages/gallery/index.tsx
  20. 5 5
      apps/photos/src/pages/index.tsx
  21. 1 1
      apps/photos/src/pages/shared-albums/index.tsx
  22. 5 1
      apps/photos/src/services/billingService.ts
  23. 9 2
      apps/photos/src/services/cache/cacheStorageFactory.ts
  24. 18 20
      apps/photos/src/services/clipService.ts
  25. 3 3
      apps/photos/src/services/collectionService.ts
  26. 1 1
      apps/photos/src/services/downloadManager.ts
  27. 0 26
      apps/photos/src/services/electron/cache.ts
  28. 0 78
      apps/photos/src/services/electron/common.ts
  29. 0 27
      apps/photos/src/services/electron/ffmpeg.ts
  30. 0 48
      apps/photos/src/services/electron/fs.ts
  31. 0 42
      apps/photos/src/services/electron/safeStorage.tsx
  32. 0 36
      apps/photos/src/services/electron/update.ts
  33. 2 2
      apps/photos/src/services/embeddingService.ts
  34. 2 2
      apps/photos/src/services/entityService.ts
  35. 29 37
      apps/photos/src/services/export/index.ts
  36. 1 1
      apps/photos/src/services/export/migration.ts
  37. 11 2
      apps/photos/src/services/ffmpeg/ffmpegFactory.ts
  38. 2 2
      apps/photos/src/services/fileService.ts
  39. 5 20
      apps/photos/src/services/imageProcessor.ts
  40. 25 86
      apps/photos/src/services/importService.ts
  41. 2 2
      apps/photos/src/services/machineLearning/machineLearningFactory.ts
  42. 1 1
      apps/photos/src/services/machineLearning/mlWorkManager.ts
  43. 1 1
      apps/photos/src/services/migrateThumbnailService.ts
  44. 1 1
      apps/photos/src/services/publicCollectionDownloadManager.ts
  45. 2 2
      apps/photos/src/services/publicCollectionService.ts
  46. 1 1
      apps/photos/src/services/trashService.ts
  47. 4 3
      apps/photos/src/services/upload/thumbnailService.ts
  48. 2 2
      apps/photos/src/services/upload/uploadManager.ts
  49. 2 2
      apps/photos/src/services/userService.ts
  50. 1 1
      apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts
  51. 13 19
      apps/photos/src/services/watchFolder/watchFolderService.ts
  52. 3 3
      apps/photos/src/services/workerElectronCache/client.ts
  53. 0 100
      apps/photos/src/types/electron/index.ts
  54. 1 1
      apps/photos/src/utils/billing/index.ts
  55. 3 3
      apps/photos/src/utils/collection/index.ts
  56. 1 1
      apps/photos/src/utils/comlink/ComlinkConvertWorker.ts
  57. 0 25
      apps/photos/src/utils/comlink/ComlinkCryptoWorker.ts
  58. 1 1
      apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts
  59. 1 1
      apps/photos/src/utils/comlink/ComlinkMLWorker.ts
  60. 0 27
      apps/photos/src/utils/comlink/comlinkWorker.ts
  61. 1 1
      apps/photos/src/utils/common/apiUtil.ts
  62. 3 3
      apps/photos/src/utils/common/key.ts
  63. 6 5
      apps/photos/src/utils/crypto/index.ts
  64. 8 7
      apps/photos/src/utils/file/index.ts
  65. 1 1
      apps/photos/src/utils/machineLearning/faceCrop.ts
  66. 1 1
      apps/photos/src/utils/machineLearning/index.ts
  67. 1 1
      apps/photos/src/utils/magicMetadata/index.ts
  68. 0 48
      apps/photos/src/utils/storage/cache.ts
  69. 0 40
      apps/photos/src/utils/storage/index.ts
  70. 0 12
      apps/photos/src/utils/storage/localForage.ts
  71. 0 68
      apps/photos/src/utils/storage/localStorage.ts
  72. 1 1
      apps/photos/src/utils/storage/mlStorage.ts
  73. 0 32
      apps/photos/src/utils/storage/sessionStorage.ts
  74. 5 6
      apps/photos/src/utils/ui/index.tsx
  75. 1 1
      apps/photos/src/utils/user/family.ts
  76. 3 3
      apps/photos/src/utils/user/index.ts
  77. 39 6
      packages/shared/crypto/internal/crypto.worker.ts
  78. 3 3
      packages/shared/crypto/internal/libsodium.ts

+ 1 - 1
apps/photos/src/components/AuthenticateUserModal.tsx

@@ -1,6 +1,6 @@
 import React, { useContext, useEffect, useState } from 'react';
 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 { AppContext } from 'pages/_app';
 import { KeyAttributes, User } from 'types/user';
 import { KeyAttributes, User } from 'types/user';
 import VerifyMasterPasswordForm, {
 import VerifyMasterPasswordForm, {

+ 2 - 2
apps/photos/src/components/Collections/CollectionDownloadProgress.tsx

@@ -4,7 +4,7 @@ import isElectron from 'is-electron';
 import { AppContext } from 'pages/_app';
 import { AppContext } from 'pages/_app';
 import { GalleryContext } from 'pages/gallery';
 import { GalleryContext } from 'pages/gallery';
 import { useContext } from 'react';
 import { useContext } from 'react';
-import ElectronService from 'services/electron/common';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 export interface CollectionDownloadProgressAttributes {
 export interface CollectionDownloadProgressAttributes {
     success: number;
     success: number;
@@ -100,7 +100,7 @@ export const CollectionDownloadProgress: React.FC<CollectionDownloadProgressProp
                 (attr) => attr.collectionID === collectionID
                 (attr) => attr.collectionID === collectionID
             );
             );
             if (isElectron()) {
             if (isElectron()) {
-                ElectronService.openDirectory(attributes.downloadDirPath);
+                ElectronAPIs.openDirectory(attributes.downloadDirPath);
             } else {
             } else {
                 if (attributes.isHidden) {
                 if (attributes.isHidden) {
                     galleryContext.openHiddenSection(() => {
                     galleryContext.openHiddenSection(() => {

+ 1 - 1
apps/photos/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/setPassword.tsx

@@ -4,7 +4,7 @@ import SingleInputForm, {
 } from '@ente/shared/components/SingleInputForm';
 } from '@ente/shared/components/SingleInputForm';
 import React from 'react';
 import React from 'react';
 import { t } from 'i18next';
 import { t } from 'i18next';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 
 
 export function PublicLinkSetPassword({
 export function PublicLinkSetPassword({
     open,
     open,

+ 1 - 1
apps/photos/src/components/Collections/index.tsx

@@ -14,7 +14,7 @@ import {
 } from 'utils/collection';
 } from 'utils/collection';
 import { useLocalState } from '@ente/shared/hooks/useLocalState';
 import { useLocalState } from '@ente/shared/hooks/useLocalState';
 import { sortCollectionSummaries } from 'services/collectionService';
 import { sortCollectionSummaries } from 'services/collectionService';
-import { LS_KEYS } from 'utils/storage/localStorage';
+import { LS_KEYS } from '@ente/shared/storage/localStorage';
 import {
 import {
     CollectionDownloadProgress,
     CollectionDownloadProgress,
     CollectionDownloadProgressAttributes,
     CollectionDownloadProgressAttributes,

+ 1 - 1
apps/photos/src/components/FixLargeThumbnail.tsx

@@ -6,7 +6,7 @@ import {
     getLargeThumbnailFiles,
     getLargeThumbnailFiles,
     replaceThumbnail,
     replaceThumbnail,
 } from 'services/migrateThumbnailService';
 } 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 { logError } from '@ente/shared/sentry';
 import { t } from 'i18next';
 import { t } from 'i18next';
 
 

+ 1 - 1
apps/photos/src/components/MachineLearning/ImageViews.tsx

@@ -3,7 +3,7 @@ import { Skeleton, styled } from '@mui/material';
 
 
 import { imageBitmapToBlob } from 'utils/image';
 import { imageBitmapToBlob } from 'utils/image';
 import { logError } from '@ente/shared/sentry';
 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')`
 export const FaceCropsRow = styled('div')`
     & > img {
     & > img {

+ 1 - 1
apps/photos/src/components/MachineLearning/MlDebug-disabled.tsx

@@ -1,7 +1,7 @@
 export {};
 export {};
 
 
 // import React, { useState, useEffect, useContext, ChangeEvent } from 'react';
 // 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 { useRouter } from 'next/router';
 // import { ComlinkWorker } from 'utils/comlink';
 // import { ComlinkWorker } from 'utils/comlink';
 // import { AppContext } from 'pages/_app';
 // import { AppContext } from 'pages/_app';

+ 3 - 3
apps/photos/src/components/Sidebar/DebugSection.tsx

@@ -7,7 +7,7 @@ import { t } from 'i18next';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 import { getDebugLogs } from '@ente/shared/logging/web';
 import { getDebugLogs } from '@ente/shared/logging/web';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
-import ElectronService from 'services/electron/common';
+import ElectronAPIs from '@ente/shared/electron';
 import Typography from '@mui/material/Typography';
 import Typography from '@mui/material/Typography';
 import { isInternalUser } from 'utils/user';
 import { isInternalUser } from 'utils/user';
 import { testUpload } from '../../../tests/upload.test';
 import { testUpload } from '../../../tests/upload.test';
@@ -24,7 +24,7 @@ export default function DebugSection() {
     useEffect(() => {
     useEffect(() => {
         const main = async () => {
         const main = async () => {
             if (isElectron()) {
             if (isElectron()) {
-                const appVersion = await ElectronService.getAppVersion();
+                const appVersion = await ElectronAPIs.getAppVersion();
                 setAppVersion(appVersion);
                 setAppVersion(appVersion);
             }
             }
         };
         };
@@ -48,7 +48,7 @@ export default function DebugSection() {
     const downloadDebugLogs = () => {
     const downloadDebugLogs = () => {
         addLogLine('exporting logs');
         addLogLine('exporting logs');
         if (isElectron()) {
         if (isElectron()) {
-            ElectronService.openLogDirectory();
+            ElectronAPIs.openLogDirectory();
         } else {
         } else {
             const logs = getDebugLogs();
             const logs = getDebugLogs();
 
 

+ 1 - 1
apps/photos/src/components/Sidebar/Preferences/LanguageSelector.tsx

@@ -4,7 +4,7 @@ import { useLocalState } from '@ente/shared/hooks/useLocalState';
 import { t } from 'i18next';
 import { t } from 'i18next';
 import { useRouter } from 'next/router';
 import { useRouter } from 'next/router';
 import { getBestPossibleUserLocale } from '@ente/shared/i18n/utils';
 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) => {
 const getLocaleDisplayName = (l: Language) => {
     switch (l) {
     switch (l) {

+ 3 - 3
apps/photos/src/components/Sidebar/Preferences/index.tsx

@@ -10,9 +10,9 @@ import AdvancedSettings from '../AdvancedSettings';
 import MapSettings from '../MapSetting';
 import MapSettings from '../MapSetting';
 import { LanguageSelector } from './LanguageSelector';
 import { LanguageSelector } from './LanguageSelector';
 import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
 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 { 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 InMemoryStore, { MS_KEYS } from 'services/InMemoryStore';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 
 
@@ -46,7 +46,7 @@ export default function Preferences({ open, onClose, onRootClose }) {
     const toggleOptOutOfCrashReports = async () => {
     const toggleOptOutOfCrashReports = async () => {
         try {
         try {
             if (isElectron()) {
             if (isElectron()) {
-                await ElectronService.updateOptOutOfCrashReports(
+                await ElectronAPIs.updateOptOutOfCrashReports(
                     !optOutOfCrashReports
                     !optOutOfCrashReports
                 );
                 );
             }
             }

+ 1 - 1
apps/photos/src/components/Sidebar/userDetailsSection.tsx

@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useMemo, useState } from 'react';
 import SubscriptionCard from './SubscriptionCard';
 import SubscriptionCard from './SubscriptionCard';
 import { getUserDetailsV2 } from 'services/userService';
 import { getUserDetailsV2 } from 'services/userService';
 import { UserDetails } from 'types/user';
 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 { useLocalState } from '@ente/shared/hooks/useLocalState';
 import Typography from '@mui/material/Typography';
 import Typography from '@mui/material/Typography';
 import SubscriptionStatus from './SubscriptionStatus';
 import SubscriptionStatus from './SubscriptionStatus';

+ 1 - 1
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 { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import router from 'next/router';
 import router from 'next/router';
 import { disableTwoFactor } from '@ente/accounts/api/user';
 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';
 import { Button, Grid } from '@mui/material';
 
 
 interface Iprops {
 interface Iprops {

+ 1 - 1
apps/photos/src/components/TwoFactor/Modal/index.tsx

@@ -1,7 +1,7 @@
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import { getTwoFactorStatus } from 'services/userService';
 import { getTwoFactorStatus } from 'services/userService';
 import { SetLoading } from 'types/gallery';
 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 { t } from 'i18next';
 
 
 import TwoFactorModalSetupSection from './Setup';
 import TwoFactorModalSetupSection from './Setup';

+ 9 - 9
apps/photos/src/components/Upload/Uploader.tsx

@@ -44,7 +44,6 @@ import {
     UPLOAD_STRATEGY,
     UPLOAD_STRATEGY,
     PICKED_UPLOAD_TYPE,
     PICKED_UPLOAD_TYPE,
 } from 'constants/upload';
 } from 'constants/upload';
-import importService from 'services/importService';
 import {
 import {
     getDownloadAppMessage,
     getDownloadAppMessage,
     getRootLevelFileWithFolderNotAllowMessage,
     getRootLevelFileWithFolderNotAllowMessage,
@@ -66,6 +65,7 @@ import {
 } from 'services/publicCollectionService';
 } from 'services/publicCollectionService';
 import { UploadTypeSelectorIntent } from 'types/gallery';
 import { UploadTypeSelectorIntent } from 'types/gallery';
 import { getOrCreateAlbum } from 'utils/collection';
 import { getOrCreateAlbum } from 'utils/collection';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 const FIRST_ALBUM_NAME = 'My First Album';
 const FIRST_ALBUM_NAME = 'My First Album';
 
 
@@ -179,7 +179,7 @@ export default function Uploader(props: Props) {
             setUploadProgressView(true);
             setUploadProgressView(true);
         }
         }
 
 
-        if (isElectron() && ImportService.checkAllElectronAPIsExists()) {
+        if (isElectron()) {
             ImportService.getPendingUploads().then(
             ImportService.getPendingUploads().then(
                 ({ files: electronFiles, collectionName, type }) => {
                 ({ files: electronFiles, collectionName, type }) => {
                     addLogLine(
                     addLogLine(
@@ -234,7 +234,7 @@ export default function Uploader(props: Props) {
                         for (const file of props.dragAndDropFiles) {
                         for (const file of props.dragAndDropFiles) {
                             if (file.name.endsWith('.zip')) {
                             if (file.name.endsWith('.zip')) {
                                 const zipFiles =
                                 const zipFiles =
-                                    await importService.getElectronFilesFromGoogleZip(
+                                    await ElectronAPIs.getElectronFilesFromGoogleZip(
                                         (file as any).path
                                         (file as any).path
                                     );
                                     );
                                 addLogLine(
                                 addLogLine(
@@ -529,13 +529,13 @@ export default function Uploader(props: Props) {
             ) {
             ) {
                 await ImportService.setToUploadCollection(collections);
                 await ImportService.setToUploadCollection(collections);
                 if (zipPaths.current) {
                 if (zipPaths.current) {
-                    await ImportService.setToUploadFiles(
+                    ElectronAPIs.setToUploadFiles(
                         PICKED_UPLOAD_TYPE.ZIPS,
                         PICKED_UPLOAD_TYPE.ZIPS,
                         zipPaths.current
                         zipPaths.current
                     );
                     );
                     zipPaths.current = null;
                     zipPaths.current = null;
                 }
                 }
-                await ImportService.setToUploadFiles(
+                ElectronAPIs.setToUploadFiles(
                     PICKED_UPLOAD_TYPE.FILES,
                     PICKED_UPLOAD_TYPE.FILES,
                     filesWithCollectionToUploadIn.map(
                     filesWithCollectionToUploadIn.map(
                         ({ file }) => (file as ElectronFile).path
                         ({ file }) => (file as ElectronFile).path
@@ -722,11 +722,11 @@ export default function Uploader(props: Props) {
         let files: ElectronFile[];
         let files: ElectronFile[];
         pickedUploadType.current = type;
         pickedUploadType.current = type;
         if (type === PICKED_UPLOAD_TYPE.FILES) {
         if (type === PICKED_UPLOAD_TYPE.FILES) {
-            files = await ImportService.showUploadFilesDialog();
+            files = await ElectronAPIs.showUploadFilesDialog();
         } else if (type === PICKED_UPLOAD_TYPE.FOLDERS) {
         } else if (type === PICKED_UPLOAD_TYPE.FOLDERS) {
-            files = await ImportService.showUploadDirsDialog();
+            files = await ElectronAPIs.showUploadDirsDialog();
         } else {
         } else {
-            const response = await ImportService.showUploadZipDialog();
+            const response = await ElectronAPIs.showUploadZipDialog();
             files = response.files;
             files = response.files;
             zipPaths.current = response.zipPaths;
             zipPaths.current = response.zipPaths;
         }
         }
@@ -755,7 +755,7 @@ export default function Uploader(props: Props) {
     };
     };
 
 
     const handleUpload = (type) => () => {
     const handleUpload = (type) => () => {
-        if (isElectron() && importService.checkAllElectronAPIsExists()) {
+        if (isElectron()) {
             handleDesktopUpload(type);
             handleDesktopUpload(type);
         } else {
         } else {
             handleWebUpload(type);
             handleWebUpload(type);

+ 2 - 2
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 UploadStrategyChoiceModal from 'components/Upload/UploadStrategyChoiceModal';
 import { UPLOAD_STRATEGY } from 'constants/upload';
 import { UPLOAD_STRATEGY } from 'constants/upload';
 import { getImportSuggestion } from 'utils/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';
 import { PICKED_UPLOAD_TYPE } from 'constants/upload';
 
 
 interface Iprops {
 interface Iprops {
@@ -50,7 +50,7 @@ export default function WatchFolder({ open, onClose }: Iprops) {
 
 
     const addFolderForWatching = async (path: string) => {
     const addFolderForWatching = async (path: string) => {
         setInputFolderPath(path);
         setInputFolderPath(path);
-        const files = await electronFSService.getDirFiles(path);
+        const files = await ElectronAPIs.getDirFiles(path);
         const analysisResult = getImportSuggestion(
         const analysisResult = getImportSuggestion(
             PICKED_UPLOAD_TYPE.FOLDERS,
             PICKED_UPLOAD_TYPE.FOLDERS,
             files
             files

+ 1 - 1
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 { AppContext } from 'pages/_app';
 import { Link, Stack } from '@mui/material';
 import { Link, Stack } from '@mui/material';
 import { useLocalState } from '@ente/shared/hooks/useLocalState';
 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 { getLocalUserDetails } from 'utils/user';
 import { PLAN_PERIOD } from 'constants/gallery';
 import { PLAN_PERIOD } from 'constants/gallery';
 import FreeSubscriptionPlanSelectorCard from './free';
 import FreeSubscriptionPlanSelectorCard from './free';

+ 3 - 3
apps/photos/src/pages/_app.tsx

@@ -41,7 +41,7 @@ import { CustomError } from '@ente/shared/error';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 import { clearLogsIfLocalStorageLimitExceeded } from '@ente/shared/logging/web';
 import { clearLogsIfLocalStorageLimitExceeded } from '@ente/shared/logging/web';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
-import ElectronUpdateService from 'services/electron/update';
+import ElectronAPIs from '@ente/shared/electron';
 import {
 import {
     getUpdateAvailableForDownloadMessage,
     getUpdateAvailableForDownloadMessage,
     getUpdateReadyToInstallMessage,
     getUpdateReadyToInstallMessage,
@@ -52,7 +52,6 @@ import {
     SetNotificationAttributes,
     SetNotificationAttributes,
 } from 'types/Notification';
 } from 'types/Notification';
 import ArrowForward from '@mui/icons-material/ArrowForward';
 import ArrowForward from '@mui/icons-material/ArrowForward';
-import { AppUpdateInfo } from 'types/electron';
 import { CacheProvider } from '@emotion/react';
 import { CacheProvider } from '@emotion/react';
 import {
 import {
     APP_TITLES,
     APP_TITLES,
@@ -76,6 +75,7 @@ import { User } from '@ente/shared/user/types';
 import { useLocalState } from '@ente/shared/hooks/useLocalState';
 import { useLocalState } from '@ente/shared/hooks/useLocalState';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import { getTheme } from '@ente/shared/themes';
 import { getTheme } from '@ente/shared/themes';
+import { AppUpdateInfo } from '@ente/shared/electron/types';
 
 
 const redirectMap = new Map([
 const redirectMap = new Map([
     [REDIRECTS.ROADMAP, getRoadmapRedirectURL],
     [REDIRECTS.ROADMAP, getRoadmapRedirectURL],
@@ -193,7 +193,7 @@ export default function App(props: EnteAppProps) {
                     });
                     });
                 }
                 }
             };
             };
-            ElectronUpdateService.registerUpdateEventListener(showUpdateDialog);
+            ElectronAPIs.registerUpdateEventListener(showUpdateDialog);
         }
         }
     }, []);
     }, []);
 
 

+ 1 - 1
apps/photos/src/pages/deduplicate/index.tsx

@@ -22,7 +22,7 @@ import Router from 'next/router';
 import DeduplicateOptions from 'components/pages/dedupe/SelectedFileOptions';
 import DeduplicateOptions from 'components/pages/dedupe/SelectedFileOptions';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import router from 'next/router';
 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 { styled } from '@mui/material';
 import { getLatestCollections } from 'services/collectionService';
 import { getLatestCollections } from 'services/collectionService';
 import EnteSpinner from '@ente/shared/components/EnteSpinner';
 import EnteSpinner from '@ente/shared/components/EnteSpinner';

+ 10 - 6
apps/photos/src/pages/gallery/index.tsx

@@ -7,7 +7,11 @@ import {
     useState,
     useState,
 } from 'react';
 } from 'react';
 import { useRouter } from 'next/router';
 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 { getLocalFiles, syncFiles } from 'services/fileService';
 import { styled, Typography } from '@mui/material';
 import { styled, Typography } from '@mui/material';
 import {
 import {
@@ -32,7 +36,7 @@ import {
     justSignedUp,
     justSignedUp,
     setIsFirstLogin,
     setIsFirstLogin,
     setJustSignedUp,
     setJustSignedUp,
-} from 'utils/storage';
+} from '@ente/shared/storage/localStorage/helpers';
 import {
 import {
     isTokenValid,
     isTokenValid,
     syncMapEnabled,
     syncMapEnabled,
@@ -103,11 +107,11 @@ import { ITEM_TYPE, TimeStampListItem } from 'components/PhotoList';
 import UploadInputs from 'components/UploadSelectorInputs';
 import UploadInputs from 'components/UploadSelectorInputs';
 import useFileInput from '@ente/shared/hooks/useFileInput';
 import useFileInput from '@ente/shared/hooks/useFileInput';
 import { FamilyData, User } from 'types/user';
 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 { CenteredFlex } from 'components/Container';
 import { checkConnectivity } from 'utils/common';
 import { checkConnectivity } from 'utils/common';
 import { SYNC_INTERVAL_IN_MICROSECONDS } from 'constants/gallery';
 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 uploadManager from 'services/upload/uploadManager';
 import { getToken } from 'utils/common/key';
 import { getToken } from 'utils/common/key';
 import ExportModal from 'components/ExportModal';
 import ExportModal from 'components/ExportModal';
@@ -337,14 +341,14 @@ export default function Gallery() {
             syncInterval.current = setInterval(() => {
             syncInterval.current = setInterval(() => {
                 syncWithRemote(false, true);
                 syncWithRemote(false, true);
             }, SYNC_INTERVAL_IN_MICROSECONDS);
             }, SYNC_INTERVAL_IN_MICROSECONDS);
-            ElectronService.registerForegroundEventListener(() => {
+            ElectronAPIs.registerForegroundEventListener(() => {
                 syncWithRemote(false, true);
                 syncWithRemote(false, true);
             });
             });
         };
         };
         main();
         main();
         return () => {
         return () => {
             clearInterval(syncInterval.current);
             clearInterval(syncInterval.current);
-            ElectronService.registerForegroundEventListener(() => {});
+            ElectronAPIs.registerForegroundEventListener(() => {});
             ClipService.removeOnFileUploadListener();
             ClipService.removeOnFileUploadListener();
         };
         };
     }, []);
     }, []);

+ 5 - 5
apps/photos/src/pages/index.tsx

@@ -4,19 +4,19 @@ import { styled, Button, Typography, TypographyProps } from '@mui/material';
 import { AppContext } from './_app';
 import { AppContext } from './_app';
 import Login from '@ente/accounts/components/Login';
 import Login from '@ente/accounts/components/Login';
 import { useRouter } from 'next/router';
 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 SignUp from '@ente/accounts/components/SignUp';
 import EnteSpinner from '@ente/shared/components/EnteSpinner';
 import EnteSpinner from '@ente/shared/components/EnteSpinner';
 import { t } from 'i18next';
 import { t } from 'i18next';
 
 
-import localForage from 'utils/storage/localForage';
+import localForage from '@ente/shared/storage/localForage';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
 import { EnteLogo } from '@ente/shared/components/EnteLogo';
 import { EnteLogo } from '@ente/shared/components/EnteLogo';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
-import safeStorageService from 'services/electron/safeStorage';
+import ElectronAPIs from '@ente/shared/electron';
 import { saveKeyInSessionStore } from 'utils/crypto';
 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 { getAlbumsURL } from 'utils/common/apiUtil';
 import { Trans } from 'react-i18next';
 import { Trans } from 'react-i18next';
 import { APPS } from '@ente/shared/apps/constants';
 import { APPS } from '@ente/shared/apps/constants';
@@ -132,7 +132,7 @@ export default function LandingPage() {
         const user = getData(LS_KEYS.USER);
         const user = getData(LS_KEYS.USER);
         let key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
         let key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
         if (!key && isElectron()) {
         if (!key && isElectron()) {
-            key = await safeStorageService.getEncryptionKey();
+            key = await ElectronAPIs.getEncryptionKey();
             if (key) {
             if (key) {
                 await saveKeyInSessionStore(
                 await saveKeyInSessionStore(
                     SESSION_KEYS.ENCRYPTION_KEY,
                     SESSION_KEYS.ENCRYPTION_KEY,

+ 1 - 1
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 UploadButton from 'components/Upload/UploadButton';
 import bs58 from 'bs58';
 import bs58 from 'bs58';
 import AddPhotoAlternateOutlined from '@mui/icons-material/AddPhotoAlternateOutlined';
 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 { UploadTypeSelectorIntent } from 'types/gallery';
 import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';
 import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';
 import MoreHoriz from '@mui/icons-material/MoreHoriz';
 import MoreHoriz from '@mui/icons-material/MoreHoriz';

+ 5 - 1
apps/photos/src/services/billingService.ts

@@ -1,6 +1,10 @@
 import { getEndpoint, getPaymentsURL } from 'utils/common/apiUtil';
 import { getEndpoint, getPaymentsURL } from 'utils/common/apiUtil';
 import { getToken } from 'utils/common/key';
 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 HTTPService from './HTTPService';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { getPaymentToken } from './userService';
 import { getPaymentToken } from './userService';

+ 9 - 2
apps/photos/src/services/cache/cacheStorageFactory.ts

@@ -1,5 +1,5 @@
 import { LimitedCacheStorage } from 'types/cache/index';
 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 { runningInElectron, runningInWorker } from 'utils/common';
 import { WorkerElectronCacheStorageService } from 'services/workerElectronCache/service';
 import { WorkerElectronCacheStorageService } from 'services/workerElectronCache/service';
 
 
@@ -14,7 +14,14 @@ class cacheStorageFactory {
                 }
                 }
                 return this.workerElectronCacheStorageServiceInstance;
                 return this.workerElectronCacheStorageServiceInstance;
             } else {
             } else {
-                return ElectronCacheStorage;
+                return {
+                    open(cacheName) {
+                        return ElectronAPIs.openDiskCache(cacheName);
+                    },
+                    delete(cacheName) {
+                        return ElectronAPIs.deleteDiskCache(cacheName);
+                    },
+                };
             }
             }
         } else {
         } else {
             return transformBrowserCacheStorageToLimitedCacheStorage(caches);
             return transformBrowserCacheStorageToLimitedCacheStorage(caches);

+ 18 - 20
apps/photos/src/services/clipService.ts

@@ -1,24 +1,24 @@
-import { EnteFile } from 'types/file';
 import {
 import {
     putEmbedding,
     putEmbedding,
     getLatestEmbeddings,
     getLatestEmbeddings,
     getLocalEmbeddings,
     getLocalEmbeddings,
 } from './embeddingService';
 } from './embeddingService';
 import { getAllLocalFiles, getLocalFiles } from './fileService';
 import { getAllLocalFiles, getLocalFiles } from './fileService';
-import { ElectronAPIs } from 'types/electron';
 import downloadManager from './downloadManager';
 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 { logError } from '@ente/shared/sentry';
 import { addLogLine } from '@ente/shared/logging';
 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 isElectron from 'is-electron';
 import { Events, eventBus } from './events';
 import { Events, eventBus } from './events';
 import PQueue from 'p-queue';
 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 { 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;
 const CLIP_EMBEDDING_LENGTH = 512;
 
 
@@ -28,22 +28,20 @@ export interface ClipExtractionStatus {
 }
 }
 
 
 class ClipServiceImpl {
 class ClipServiceImpl {
-    private electronAPIs: ElectronAPIs;
-    private embeddingExtractionInProgress: AbortController = null;
+    private embeddingExtractionInProgress: AbortController | null = null;
     private reRunNeeded = false;
     private reRunNeeded = false;
     private clipExtractionStatus: ClipExtractionStatus = {
     private clipExtractionStatus: ClipExtractionStatus = {
         pending: 0,
         pending: 0,
         indexed: 0,
         indexed: 0,
     };
     };
-    private onUpdateHandler: (status: ClipExtractionStatus) => void = null;
+    private onUpdateHandler: ((status: ClipExtractionStatus) => void) | null =
+        null;
     private liveEmbeddingExtractionQueue: PQueue;
     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() {
     constructor() {
-        this.electronAPIs = globalThis['ElectronAPIs'];
         this.liveEmbeddingExtractionQueue = new PQueue({
         this.liveEmbeddingExtractionQueue = new PQueue({
             concurrency: 1,
             concurrency: 1,
         });
         });
@@ -104,7 +102,7 @@ class ClipServiceImpl {
         if (!isElectron()) {
         if (!isElectron()) {
             return false;
             return false;
         }
         }
-        const platform = await this.electronAPIs.getPlatform();
+        const platform = await ElectronAPIs.getPlatform();
         return platform !== 'windows';
         return platform !== 'windows';
     };
     };
 
 
@@ -150,7 +148,7 @@ class ClipServiceImpl {
 
 
     getTextEmbedding = async (text: string): Promise<Float32Array> => {
     getTextEmbedding = async (text: string): Promise<Float32Array> => {
         try {
         try {
-            return this.electronAPIs.computeTextEmbedding(text);
+            return ElectronAPIs.computeTextEmbedding(text);
         } catch (e) {
         } catch (e) {
             logError(e, 'failed to compute text embedding');
             logError(e, 'failed to compute text embedding');
             throw e;
             throw e;
@@ -249,7 +247,7 @@ class ClipServiceImpl {
         const file = await localFile
         const file = await localFile
             .arrayBuffer()
             .arrayBuffer()
             .then((buffer) => new Uint8Array(buffer));
             .then((buffer) => new Uint8Array(buffer));
-        const embedding = await this.electronAPIs.computeImageEmbedding(file);
+        const embedding = await ElectronAPIs.computeImageEmbedding(file);
         return embedding;
         return embedding;
     };
     };
 
 
@@ -297,7 +295,7 @@ class ClipServiceImpl {
         } else {
         } else {
             thumb = await downloadManager.downloadThumb(token, file);
             thumb = await downloadManager.downloadThumb(token, file);
         }
         }
-        const embedding = await this.electronAPIs.computeImageEmbedding(thumb);
+        const embedding = await ElectronAPIs.computeImageEmbedding(thumb);
         return embedding;
         return embedding;
     };
     };
 
 

+ 3 - 3
apps/photos/src/services/collectionService.ts

@@ -1,6 +1,6 @@
 import { getEndpoint } from 'utils/common/apiUtil';
 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 { getActualKey, getToken } from 'utils/common/key';
 import { getPublicKey } from './userService';
 import { getPublicKey } from './userService';
@@ -64,7 +64,7 @@ import {
     isDefaultHiddenCollection,
     isDefaultHiddenCollection,
     getHiddenCollections,
     getHiddenCollections,
 } from 'utils/collection';
 } from 'utils/collection';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import { getLocalFiles } from './fileService';
 import { getLocalFiles } from './fileService';
 import { REQUEST_BATCH_SIZE } from 'constants/api';
 import { REQUEST_BATCH_SIZE } from 'constants/api';
 import { batch } from 'utils/common';
 import { batch } from 'utils/common';

+ 1 - 1
apps/photos/src/services/downloadManager.ts

@@ -11,7 +11,7 @@ import { EnteFile } from 'types/file';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { FILE_TYPE } from 'constants/file';
 import { FILE_TYPE } from 'constants/file';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import { CacheStorageService } from './cache/cacheStorageService';
 import { CacheStorageService } from './cache/cacheStorageService';
 import { CACHES } from 'constants/cache';
 import { CACHES } from 'constants/cache';
 import { Remote } from 'comlink';
 import { Remote } from 'comlink';

+ 0 - 26
apps/photos/src/services/electron/cache.ts

@@ -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<LimitedCache> {
-        if (this.allElectronAPIsExist) {
-            return await this.electronAPIs.openDiskCache(cacheName);
-        }
-    }
-
-    async delete(cacheName: string): Promise<boolean> {
-        if (this.allElectronAPIsExist) {
-            return await this.electronAPIs.deleteDiskCache(cacheName);
-        }
-    }
-}
-
-export const ElectronCacheStorage = new ElectronCacheStorageService();

+ 0 - 78
apps/photos/src/services/electron/common.ts

@@ -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();

+ 0 - 27
apps/photos/src/services/electron/ffmpeg.ts

@@ -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
-            );
-        }
-    }
-}

+ 0 - 48
apps/photos/src/services/electron/fs.ts

@@ -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<Uint8Array>
-    ) {
-        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();

+ 0 - 42
apps/photos/src/services/electron/safeStorage.tsx

@@ -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();

+ 0 - 36
apps/photos/src/services/electron/update.ts

@@ -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();

+ 2 - 2
apps/photos/src/services/embeddingService.ts

@@ -4,11 +4,11 @@ import {
     GetEmbeddingDiffResponse,
     GetEmbeddingDiffResponse,
     PutEmbeddingRequest,
     PutEmbeddingRequest,
 } from 'types/embedding';
 } from 'types/embedding';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import { getEndpoint } from 'utils/common/apiUtil';
 import { getEndpoint } from 'utils/common/apiUtil';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
-import localForage from 'utils/storage/localForage';
+import localForage from '@ente/shared/storage/localForage';
 import { getAllLocalFiles } from './fileService';
 import { getAllLocalFiles } from './fileService';
 import HTTPService from './HTTPService';
 import HTTPService from './HTTPService';
 import { getToken } from 'utils/common/key';
 import { getToken } from 'utils/common/key';

+ 2 - 2
apps/photos/src/services/entityService.ts

@@ -1,9 +1,9 @@
 import { getToken } from 'utils/common/key';
 import { getToken } from 'utils/common/key';
-import localForage from 'utils/storage/localForage';
+import localForage from '@ente/shared/storage/localForage';
 import HTTPService from './HTTPService';
 import HTTPService from './HTTPService';
 import { getEndpoint } from 'utils/common/apiUtil';
 import { getEndpoint } from 'utils/common/apiUtil';
 import { logError } from '@ente/shared/sentry';
 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 { getActualKey } from 'utils/common/key';
 import {
 import {
     EntityType,
     EntityType,

+ 29 - 37
apps/photos/src/services/export/index.ts

@@ -23,7 +23,7 @@ import {
     getCollectionIDFromFileUID,
     getCollectionIDFromFileUID,
 } from 'utils/export';
 } from 'utils/export';
 import { logError } from '@ente/shared/sentry';
 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 { getAllLocalCollections } from '../collectionService';
 import downloadManager from '../downloadManager';
 import downloadManager from '../downloadManager';
 import { getAllLocalFiles } from '../fileService';
 import { getAllLocalFiles } from '../fileService';
@@ -51,7 +51,6 @@ import {
 import { User } from 'types/user';
 import { User } from 'types/user';
 import { FILE_TYPE } from 'constants/file';
 import { FILE_TYPE } from 'constants/file';
 import { ExportStage } from 'constants/export';
 import { ExportStage } from 'constants/export';
-import { ElectronAPIs } from 'types/electron';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 import { eventBus, Events } from '../events';
 import { eventBus, Events } from '../events';
@@ -61,7 +60,7 @@ import {
     getNonEmptyPersonalCollections,
     getNonEmptyPersonalCollections,
 } from 'utils/collection';
 } from 'utils/collection';
 import { migrateExport } from './migration';
 import { migrateExport } from './migration';
-import ElectronFSService from '../electron/fs';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 const EXPORT_RECORD_FILE_NAME = 'export_status.json';
 const EXPORT_RECORD_FILE_NAME = 'export_status.json';
 
 
@@ -76,7 +75,6 @@ export const NULL_EXPORT_RECORD: ExportRecord = {
 };
 };
 
 
 class ExportService {
 class ExportService {
-    private electronAPIs: ElectronAPIs;
     private exportSettings: ExportSettings;
     private exportSettings: ExportSettings;
     private exportInProgress: RequestCanceller = null;
     private exportInProgress: RequestCanceller = null;
     private reRunNeeded = false;
     private reRunNeeded = false;
@@ -95,10 +93,6 @@ class ExportService {
         failed: 0,
         failed: 0,
     };
     };
 
 
-    constructor() {
-        this.electronAPIs = globalThis['ElectronAPIs'];
-    }
-
     getExportSettings(): ExportSettings {
     getExportSettings(): ExportSettings {
         try {
         try {
             if (this.exportSettings) {
             if (this.exportSettings) {
@@ -166,12 +160,12 @@ class ExportService {
 
 
     async changeExportDirectory() {
     async changeExportDirectory() {
         try {
         try {
-            const newRootDir = await this.electronAPIs.selectDirectory();
+            const newRootDir = await ElectronAPIs.selectDirectory();
             if (!newRootDir) {
             if (!newRootDir) {
                 throw Error(CustomError.SELECT_FOLDER_ABORTED);
                 throw Error(CustomError.SELECT_FOLDER_ABORTED);
             }
             }
             const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`;
             const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`;
-            await this.electronAPIs.checkExistsAndCreateDir(newExportDir);
+            await ElectronAPIs.checkExistsAndCreateDir(newExportDir);
             return newExportDir;
             return newExportDir;
         } catch (e) {
         } catch (e) {
             if (e.message !== CustomError.SELECT_FOLDER_ABORTED) {
             if (e.message !== CustomError.SELECT_FOLDER_ABORTED) {
@@ -183,7 +177,7 @@ class ExportService {
 
 
     async openExportDirectory(exportFolder: string) {
     async openExportDirectory(exportFolder: string) {
         try {
         try {
-            await this.electronAPIs.openDirectory(exportFolder);
+            await ElectronAPIs.openDirectory(exportFolder);
         } catch (e) {
         } catch (e) {
             logError(e, 'openExportDirectory failed');
             logError(e, 'openExportDirectory failed');
         }
         }
@@ -529,7 +523,7 @@ class ExportService {
                         newCollectionExportName
                         newCollectionExportName
                     );
                     );
                     try {
                     try {
-                        await this.electronAPIs.rename(
+                        await ElectronAPIs.rename(
                             oldCollectionExportPath,
                             oldCollectionExportPath,
                             newCollectionExportPath
                             newCollectionExportPath
                         );
                         );
@@ -614,13 +608,11 @@ class ExportService {
                     );
                     );
                     try {
                     try {
                         // delete the collection metadata folder
                         // delete the collection metadata folder
-                        await this.electronAPIs.deleteFolder(
+                        await ElectronAPIs.deleteFolder(
                             getMetadataFolderExportPath(collectionExportPath)
                             getMetadataFolderExportPath(collectionExportPath)
                         );
                         );
                         // delete the collection folder
                         // delete the collection folder
-                        await this.electronAPIs.deleteFolder(
-                            collectionExportPath
-                        );
+                        await ElectronAPIs.deleteFolder(collectionExportPath);
                     } catch (e) {
                     } catch (e) {
                         await this.addCollectionExportedRecord(
                         await this.addCollectionExportedRecord(
                             exportFolder,
                             exportFolder,
@@ -703,10 +695,10 @@ class ExportService {
                         exportDir,
                         exportDir,
                         collectionExportName
                         collectionExportName
                     );
                     );
-                    await this.electronAPIs.checkExistsAndCreateDir(
+                    await ElectronAPIs.checkExistsAndCreateDir(
                         collectionExportPath
                         collectionExportPath
                     );
                     );
-                    await this.electronAPIs.checkExistsAndCreateDir(
+                    await ElectronAPIs.checkExistsAndCreateDir(
                         getMetadataFolderExportPath(collectionExportPath)
                         getMetadataFolderExportPath(collectionExportPath)
                     );
                     );
                     await this.downloadAndSave(
                     await this.downloadAndSave(
@@ -786,7 +778,7 @@ class ExportService {
                                 `moving image file ${imageExportPath} to trash folder`
                                 `moving image file ${imageExportPath} to trash folder`
                             );
                             );
                             if (this.exists(imageExportPath)) {
                             if (this.exists(imageExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     imageExportPath,
                                     imageExportPath,
                                     getTrashedFileExportPath(
                                     getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -799,7 +791,7 @@ class ExportService {
                                 getMetadataFileExportPath(imageExportPath);
                                 getMetadataFileExportPath(imageExportPath);
 
 
                             if (this.exists(imageMetadataFileExportPath)) {
                             if (this.exists(imageMetadataFileExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     imageMetadataFileExportPath,
                                     imageMetadataFileExportPath,
                                     getTrashedFileExportPath(
                                     getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -816,7 +808,7 @@ class ExportService {
                                 `moving video file ${videoExportPath} to trash folder`
                                 `moving video file ${videoExportPath} to trash folder`
                             );
                             );
                             if (this.exists(videoExportPath)) {
                             if (this.exists(videoExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     videoExportPath,
                                     videoExportPath,
                                     getTrashedFileExportPath(
                                     getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -827,7 +819,7 @@ class ExportService {
                             const videoMetadataFileExportPath =
                             const videoMetadataFileExportPath =
                                 getMetadataFileExportPath(videoExportPath);
                                 getMetadataFileExportPath(videoExportPath);
                             if (this.exists(videoMetadataFileExportPath)) {
                             if (this.exists(videoMetadataFileExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     videoMetadataFileExportPath,
                                     videoMetadataFileExportPath,
                                     getTrashedFileExportPath(
                                     getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -848,7 +840,7 @@ class ExportService {
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`
                                 `moving file ${fileExportPath} to ${trashedFilePath} trash folder`
                             );
                             );
                             if (this.exists(fileExportPath)) {
                             if (this.exists(fileExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     fileExportPath,
                                     fileExportPath,
                                     trashedFilePath
                                     trashedFilePath
                                 );
                                 );
@@ -856,7 +848,7 @@ class ExportService {
                             const metadataFileExportPath =
                             const metadataFileExportPath =
                                 getMetadataFileExportPath(fileExportPath);
                                 getMetadataFileExportPath(fileExportPath);
                             if (this.exists(metadataFileExportPath)) {
                             if (this.exists(metadataFileExportPath)) {
-                                await this.electronAPIs.moveFile(
+                                await ElectronAPIs.moveFile(
                                     metadataFileExportPath,
                                     metadataFileExportPath,
                                     getTrashedFileExportPath(
                                     getTrashedFileExportPath(
                                         exportDir,
                                         exportDir,
@@ -995,7 +987,7 @@ class ExportService {
         try {
         try {
             const exportRecord = await this.getExportRecord(folder);
             const exportRecord = await this.getExportRecord(folder);
             const newRecord: ExportRecord = { ...exportRecord, ...newData };
             const newRecord: ExportRecord = { ...exportRecord, ...newData };
-            await this.electronAPIs.saveFileToDisk(
+            await ElectronAPIs.saveFileToDisk(
                 `${folder}/${EXPORT_RECORD_FILE_NAME}`,
                 `${folder}/${EXPORT_RECORD_FILE_NAME}`,
                 JSON.stringify(newRecord, null, 2)
                 JSON.stringify(newRecord, null, 2)
             );
             );
@@ -1016,7 +1008,7 @@ class ExportService {
             if (!this.exists(exportRecordJSONPath)) {
             if (!this.exists(exportRecordJSONPath)) {
                 return this.createEmptyExportRecord(exportRecordJSONPath);
                 return this.createEmptyExportRecord(exportRecordJSONPath);
             }
             }
-            const recordFile = await this.electronAPIs.readTextFile(
+            const recordFile = await ElectronAPIs.readTextFile(
                 exportRecordJSONPath
                 exportRecordJSONPath
             );
             );
             try {
             try {
@@ -1054,8 +1046,8 @@ class ExportService {
             exportFolder,
             exportFolder,
             collectionExportName
             collectionExportName
         );
         );
-        await this.electronAPIs.checkExistsAndCreateDir(collectionExportPath);
-        await this.electronAPIs.checkExistsAndCreateDir(
+        await ElectronAPIs.checkExistsAndCreateDir(collectionExportPath);
+        await ElectronAPIs.checkExistsAndCreateDir(
             getMetadataFolderExportPath(collectionExportPath)
             getMetadataFolderExportPath(collectionExportPath)
         );
         );
 
 
@@ -1102,7 +1094,7 @@ class ExportService {
                         fileExportName,
                         fileExportName,
                         file
                         file
                     );
                     );
-                    await ElectronFSService.saveMediaFile(
+                    await ElectronAPIs.saveStreamToDisk(
                         getFileExportPath(collectionExportPath, fileExportName),
                         getFileExportPath(collectionExportPath, fileExportName),
                         updatedFileStream
                         updatedFileStream
                     );
                     );
@@ -1150,7 +1142,7 @@ class ExportService {
                 imageExportName,
                 imageExportName,
                 file
                 file
             );
             );
-            await ElectronFSService.saveMediaFile(
+            await ElectronAPIs.saveStreamToDisk(
                 getFileExportPath(collectionExportPath, imageExportName),
                 getFileExportPath(collectionExportPath, imageExportName),
                 imageStream
                 imageStream
             );
             );
@@ -1162,12 +1154,12 @@ class ExportService {
                 file
                 file
             );
             );
             try {
             try {
-                await ElectronFSService.saveMediaFile(
+                await ElectronAPIs.saveStreamToDisk(
                     getFileExportPath(collectionExportPath, videoExportName),
                     getFileExportPath(collectionExportPath, videoExportName),
                     videoStream
                     videoStream
                 );
                 );
             } catch (e) {
             } catch (e) {
-                ElectronFSService.deleteFile(
+                ElectronAPIs.deleteFile(
                     getFileExportPath(collectionExportPath, imageExportName)
                     getFileExportPath(collectionExportPath, imageExportName)
                 );
                 );
                 throw e;
                 throw e;
@@ -1183,7 +1175,7 @@ class ExportService {
         fileExportName: string,
         fileExportName: string,
         file: EnteFile
         file: EnteFile
     ) {
     ) {
-        await this.electronAPIs.saveFileToDisk(
+        await ElectronAPIs.saveFileToDisk(
             getFileMetadataExportPath(collectionExportPath, fileExportName),
             getFileMetadataExportPath(collectionExportPath, fileExportName),
             getGoogleLikeMetadataFile(fileExportName, file)
             getGoogleLikeMetadataFile(fileExportName, file)
         );
         );
@@ -1194,15 +1186,15 @@ class ExportService {
     };
     };
 
 
     exists = (path: string) => {
     exists = (path: string) => {
-        return this.electronAPIs.exists(path);
+        return ElectronAPIs.exists(path);
     };
     };
 
 
     rename = (oldPath: string, newPath: string) => {
     rename = (oldPath: string, newPath: string) => {
-        return this.electronAPIs.rename(oldPath, newPath);
+        return ElectronAPIs.rename(oldPath, newPath);
     };
     };
 
 
     checkExistsAndCreateDir = (path: string) => {
     checkExistsAndCreateDir = (path: string) => {
-        return this.electronAPIs.checkExistsAndCreateDir(path);
+        return ElectronAPIs.checkExistsAndCreateDir(path);
     };
     };
 
 
     exportFolderExists = (exportFolder: string) => {
     exportFolderExists = (exportFolder: string) => {
@@ -1224,7 +1216,7 @@ class ExportService {
 
 
     private createEmptyExportRecord = async (exportRecordJSONPath: string) => {
     private createEmptyExportRecord = async (exportRecordJSONPath: string) => {
         const exportRecord: ExportRecord = NULL_EXPORT_RECORD;
         const exportRecord: ExportRecord = NULL_EXPORT_RECORD;
-        await this.electronAPIs.saveFileToDisk(
+        await ElectronAPIs.saveFileToDisk(
             exportRecordJSONPath,
             exportRecordJSONPath,
             JSON.stringify(exportRecord, null, 2)
             JSON.stringify(exportRecord, null, 2)
         );
         );

+ 1 - 1
apps/photos/src/services/export/migration.ts

@@ -26,7 +26,7 @@ import {
 } from 'utils/file';
 } from 'utils/file';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { logError } from '@ente/shared/sentry';
 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 exportService from './index';
 import { Collection } from 'types/collection';
 import { Collection } from 'types/collection';
 import {
 import {

+ 11 - 2
apps/photos/src/services/ffmpeg/ffmpegFactory.ts

@@ -1,5 +1,5 @@
+import ElectronAPIs from '@ente/shared/electron';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
-import { ElectronFFmpeg } from 'services/electron/ffmpeg';
 import { ElectronFile } from 'types/upload';
 import { ElectronFile } from 'types/upload';
 import ComlinkFFmpegWorker from 'utils/comlink/ComlinkFFmpegWorker';
 import ComlinkFFmpegWorker from 'utils/comlink/ComlinkFFmpegWorker';
 
 
@@ -17,7 +17,16 @@ class FFmpegFactory {
     async getFFmpegClient() {
     async getFFmpegClient() {
         if (!this.client) {
         if (!this.client) {
             if (isElectron()) {
             if (isElectron()) {
-                this.client = new ElectronFFmpeg();
+                this.client = {
+                    run(cmd, inputFile, outputFilename, dontTimeout) {
+                        return ElectronAPIs.runFFmpegCmd(
+                            cmd,
+                            inputFile,
+                            outputFilename,
+                            dontTimeout
+                        );
+                    },
+                };
             } else {
             } else {
                 this.client = await ComlinkFFmpegWorker.getInstance();
                 this.client = await ComlinkFFmpegWorker.getInstance();
             }
             }

+ 2 - 2
apps/photos/src/services/fileService.ts

@@ -1,5 +1,5 @@
 import { getEndpoint } from 'utils/common/apiUtil';
 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 { getToken } from 'utils/common/key';
 import { Collection } from 'types/collection';
 import { Collection } from 'types/collection';
@@ -22,7 +22,7 @@ import {
 import { SetFiles } from 'types/gallery';
 import { SetFiles } from 'types/gallery';
 import { BulkUpdateMagicMetadataRequest } from 'types/magicMetadata';
 import { BulkUpdateMagicMetadataRequest } from 'types/magicMetadata';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import {
 import {
     getCollectionLastSyncTime,
     getCollectionLastSyncTime,
     setCollectionLastSyncTime,
     setCollectionLastSyncTime,

+ 5 - 20
apps/photos/src/services/electron/imageProcessor.ts → 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 { ElectronFile } from 'types/upload';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
 import { convertBytesToHumanReadable } from 'utils/file/size';
 import { convertBytesToHumanReadable } from 'utils/file/size';
-import { addLogLine } from '@ente/shared/logging';
-import { logError } from '@ente/shared/sentry';
 
 
 class ElectronImageProcessorService {
 class ElectronImageProcessorService {
-    private electronAPIs: ElectronAPIs;
-    constructor() {
-        this.electronAPIs = globalThis['ElectronAPIs'];
-    }
-
-    generateImageThumbnailAPIExists() {
-        return !!this.electronAPIs?.generateImageThumbnail;
-    }
-
     async convertToJPEG(fileBlob: Blob, filename: string): Promise<Blob> {
     async convertToJPEG(fileBlob: Blob, filename: string): Promise<Blob> {
         try {
         try {
-            if (!this.electronAPIs?.convertToJPEG) {
-                throw new Error('convertToJPEG API not available');
-            }
             const startTime = Date.now();
             const startTime = Date.now();
             const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
             const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
-            const convertedFileData = await this.electronAPIs.convertToJPEG(
+            const convertedFileData = await ElectronAPIs.convertToJPEG(
                 inputFileData,
                 inputFileData,
                 filename
                 filename
             );
             );
@@ -51,11 +39,8 @@ class ElectronImageProcessorService {
         maxSize: number
         maxSize: number
     ): Promise<Uint8Array> {
     ): Promise<Uint8Array> {
         try {
         try {
-            if (!this.electronAPIs?.generateImageThumbnail) {
-                throw new Error('generateImageThumbnail API not available');
-            }
             const startTime = Date.now();
             const startTime = Date.now();
-            const thumb = await this.electronAPIs.generateImageThumbnail(
+            const thumb = await ElectronAPIs.generateImageThumbnail(
                 inputFile,
                 inputFile,
                 maxDimension,
                 maxDimension,
                 maxSize
                 maxSize

+ 25 - 86
apps/photos/src/services/importService.ts

@@ -1,8 +1,8 @@
 import { PICKED_UPLOAD_TYPE } from 'constants/upload';
 import { PICKED_UPLOAD_TYPE } from 'constants/upload';
 import { Collection } from 'types/collection';
 import { Collection } from 'types/collection';
-import { ElectronAPIs } from 'types/electron';
 import { ElectronFile, FileWithCollection } from 'types/upload';
 import { ElectronFile, FileWithCollection } from 'types/upload';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 interface PendingUploads {
 interface PendingUploads {
     files: ElectronFile[];
     files: ElectronFile[];
@@ -10,53 +10,12 @@ interface PendingUploads {
     type: PICKED_UPLOAD_TYPE;
     type: PICKED_UPLOAD_TYPE;
 }
 }
 
 
-interface selectZipResult {
-    files: ElectronFile[];
-    zipPaths: string[];
-}
 class ImportService {
 class ImportService {
-    electronAPIs: ElectronAPIs;
-    private allElectronAPIsExist: boolean = false;
-
-    constructor() {
-        this.electronAPIs = globalThis['ElectronAPIs'];
-        this.allElectronAPIsExist = !!this.electronAPIs?.getPendingUploads;
-    }
-
-    async getElectronFilesFromGoogleZip(
-        zipPath: string
-    ): Promise<ElectronFile[]> {
-        if (this.allElectronAPIsExist) {
-            return this.electronAPIs.getElectronFilesFromGoogleZip(zipPath);
-        }
-    }
-
-    checkAllElectronAPIsExists = () => this.allElectronAPIsExist;
-
-    async showUploadFilesDialog(): Promise<ElectronFile[]> {
-        if (this.allElectronAPIsExist) {
-            return this.electronAPIs.showUploadFilesDialog();
-        }
-    }
-
-    async showUploadDirsDialog(): Promise<ElectronFile[]> {
-        if (this.allElectronAPIsExist) {
-            return this.electronAPIs.showUploadDirsDialog();
-        }
-    }
-
-    async showUploadZipDialog(): Promise<selectZipResult> {
-        if (this.allElectronAPIsExist) {
-            return this.electronAPIs.showUploadZipDialog();
-        }
-    }
     async getPendingUploads(): Promise<PendingUploads> {
     async getPendingUploads(): Promise<PendingUploads> {
         try {
         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) {
         } catch (e) {
             if (e?.message?.includes('ENOENT: no such file or directory')) {
             if (e?.message?.includes('ENOENT: no such file or directory')) {
                 // ignore
                 // ignore
@@ -68,9 +27,8 @@ class ImportService {
     }
     }
 
 
     async setToUploadCollection(collections: Collection[]) {
     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
                 1. Either the user has upload to a single existing collection
                 2. Created a new single collection to upload to 
                 2. Created a new single collection to upload to 
                     may have had multiple folder, but chose to upload
                     may have had multiple folder, but chose to upload
@@ -79,52 +37,33 @@ class ImportService {
                 helps the info of user choosing this options
                 helps the info of user choosing this options
                 and on next upload we can directly start uploading to this collection 
                 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[]) {
     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() {
     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, []);
     }
     }
 }
 }
 
 

+ 2 - 2
apps/photos/src/services/machineLearning/machineLearningFactory.ts

@@ -30,8 +30,8 @@ import mobileFaceNetEmbeddingService from './mobileFaceNetEmbeddingService';
 import dbscanClusteringService from './dbscanClusteringService';
 import dbscanClusteringService from './dbscanClusteringService';
 import ssdMobileNetV2Service from './ssdMobileNetV2Service';
 import ssdMobileNetV2Service from './ssdMobileNetV2Service';
 import imageSceneService from './imageSceneService';
 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 { DedicatedCryptoWorker } from 'worker/crypto.worker';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 
 

+ 1 - 1
apps/photos/src/services/machineLearning/mlWorkManager.ts

@@ -9,7 +9,7 @@ import { getMLSyncJobConfig } from 'utils/machineLearning/config';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import mlIDbStorage from 'utils/storage/mlIDbStorage';
 import mlIDbStorage from 'utils/storage/mlIDbStorage';
 import { MLSyncJobResult, MLSyncJob } from './mlSyncJob';
 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 { DedicatedMLWorker } from 'worker/ml.worker';
 import { getDedicatedMLWorker } from 'utils/comlink/ComlinkMLWorker';
 import { getDedicatedMLWorker } from 'utils/comlink/ComlinkMLWorker';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';

+ 1 - 1
apps/photos/src/services/migrateThumbnailService.ts

@@ -13,7 +13,7 @@ import { UploadURL } from 'types/upload';
 import { S3FileAttributes } from 'types/file';
 import { S3FileAttributes } from 'types/file';
 import { Remote } from 'comlink';
 import { Remote } from 'comlink';
 import { DedicatedCryptoWorker } from 'worker/crypto.worker';
 import { DedicatedCryptoWorker } from 'worker/crypto.worker';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 
 
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
 const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB
 const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB

+ 1 - 1
apps/photos/src/services/publicCollectionDownloadManager.ts

@@ -13,7 +13,7 @@ import { EnteFile } from 'types/file';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { FILE_TYPE } from 'constants/file';
 import { FILE_TYPE } from 'constants/file';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import { CACHES } from 'constants/cache';
 import { CACHES } from 'constants/cache';
 import { CacheStorageService } from './cache/cacheStorageService';
 import { CacheStorageService } from './cache/cacheStorageService';
 import { LimitedCache } from 'types/cache';
 import { LimitedCache } from 'types/cache';

+ 2 - 2
apps/photos/src/services/publicCollectionService.ts

@@ -1,5 +1,5 @@
 import { getEndpoint } from 'utils/common/apiUtil';
 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 { Collection, CollectionPublicMagicMetadata } from 'types/collection';
 import HTTPService from './HTTPService';
 import HTTPService from './HTTPService';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
@@ -12,7 +12,7 @@ import {
 } from 'types/publicCollection';
 } from 'types/publicCollection';
 import { REPORT_REASON } from 'constants/publicCollection';
 import { REPORT_REASON } from 'constants/publicCollection';
 import { CustomError, parseSharingErrorCodes } from 'utils/error';
 import { CustomError, parseSharingErrorCodes } from 'utils/error';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 
 
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
 const PUBLIC_COLLECTION_FILES_TABLE = 'public-collection-files';
 const PUBLIC_COLLECTION_FILES_TABLE = 'public-collection-files';

+ 1 - 1
apps/photos/src/services/trashService.ts

@@ -4,7 +4,7 @@ import { getEndpoint } from 'utils/common/apiUtil';
 import { getToken } from 'utils/common/key';
 import { getToken } from 'utils/common/key';
 import { decryptFile, sortTrashFiles } from 'utils/file';
 import { decryptFile, sortTrashFiles } from 'utils/file';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
-import localForage from 'utils/storage/localForage';
+import localForage from '@ente/shared/storage/localForage';
 import { getCollection } from './collectionService';
 import { getCollection } from './collectionService';
 
 
 import HTTPService from './HTTPService';
 import HTTPService from './HTTPService';

+ 4 - 3
apps/photos/src/services/upload/thumbnailService.ts

@@ -3,7 +3,7 @@ import { CustomError, errorWithContext } from 'utils/error';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { BLACK_THUMBNAIL_BASE64 } from 'constants/upload';
 import { BLACK_THUMBNAIL_BASE64 } from 'constants/upload';
 import * as FFmpegService from 'services/ffmpeg/ffmpegService';
 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 { convertBytesToHumanReadable } from 'utils/file/size';
 import { ElectronFile, FileTypeInfo } from 'types/upload';
 import { ElectronFile, FileTypeInfo } from 'types/upload';
 import { getUint8ArrayView } from '../readerService';
 import { getUint8ArrayView } from '../readerService';
@@ -11,6 +11,7 @@ import { addLogLine } from '@ente/shared/logging';
 import { getFileNameSize } from '@ente/shared/logging/web';
 import { getFileNameSize } from '@ente/shared/logging/web';
 import HeicConversionService from 'services/heicConversionService';
 import HeicConversionService from 'services/heicConversionService';
 import { isFileHEIC } from 'utils/file';
 import { isFileHEIC } from 'utils/file';
+import isElectron from 'is-electron';
 
 
 const MAX_THUMBNAIL_DIMENSION = 720;
 const MAX_THUMBNAIL_DIMENSION = 720;
 const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10;
 const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10;
@@ -83,9 +84,9 @@ async function generateImageThumbnail(
     file: File | ElectronFile,
     file: File | ElectronFile,
     fileTypeInfo: FileTypeInfo
     fileTypeInfo: FileTypeInfo
 ) {
 ) {
-    if (ElectronImageProcessorService.generateImageThumbnailAPIExists()) {
+    if (isElectron()) {
         try {
         try {
-            return await ElectronImageProcessorService.generateImageThumbnail(
+            return await ElectronAPIs.generateImageThumbnail(
                 file,
                 file,
                 MAX_THUMBNAIL_DIMENSION,
                 MAX_THUMBNAIL_DIMENSION,
                 MAX_THUMBNAIL_SIZE
                 MAX_THUMBNAIL_SIZE

+ 2 - 2
apps/photos/src/services/upload/uploadManager.ts

@@ -31,13 +31,13 @@ import watchFolderService from 'services/watchFolder/watchFolderService';
 import { ProgressUpdater } from 'types/upload/ui';
 import { ProgressUpdater } from 'types/upload/ui';
 import uploadCancelService from './uploadCancelService';
 import uploadCancelService from './uploadCancelService';
 import { DedicatedCryptoWorker } from 'worker/crypto.worker';
 import { DedicatedCryptoWorker } from 'worker/crypto.worker';
-import { ComlinkWorker } from 'utils/comlink/comlinkWorker';
+import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker';
 import { Remote } from 'comlink';
 import { Remote } from 'comlink';
 import {
 import {
     getLocalPublicFiles,
     getLocalPublicFiles,
     getPublicCollectionUID,
     getPublicCollectionUID,
 } from 'services/publicCollectionService';
 } from 'services/publicCollectionService';
-import { getDedicatedCryptoWorker } from 'utils/comlink/ComlinkCryptoWorker';
+import { getDedicatedCryptoWorker } from '@ente/shared/crypto';
 import { getDisableCFUploadProxyFlag } from 'services/userService';
 import { getDisableCFUploadProxyFlag } from 'services/userService';
 
 
 const MAX_CONCURRENT_UPLOADS = 4;
 const MAX_CONCURRENT_UPLOADS = 4;

+ 2 - 2
apps/photos/src/services/userService.ts

@@ -4,7 +4,7 @@ import {
     isDevDeployment,
     isDevDeployment,
 } from 'utils/common/apiUtil';
 } from 'utils/common/apiUtil';
 import { getData, LS_KEYS } from '@ente/shared/storage/localStorage';
 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 { getToken } from 'utils/common/key';
 import HTTPService from './HTTPService';
 import HTTPService from './HTTPService';
 import { getRecoveryKey } from 'utils/crypto';
 import { getRecoveryKey } from 'utils/crypto';
@@ -18,7 +18,7 @@ import {
 import { ApiError } from 'utils/error';
 import { ApiError } from 'utils/error';
 import { getLocalFamilyData, isPartOfFamily } from 'utils/user/family';
 import { getLocalFamilyData, isPartOfFamily } from 'utils/user/family';
 import { AxiosResponse, HttpStatusCode } from 'axios';
 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 { putAttributes } from '@ente/accounts/api/user';
 import { logoutUser } from '@ente/accounts/services/user';
 import { logoutUser } from '@ente/accounts/services/user';
 
 

+ 1 - 1
apps/photos/src/services/wasmHeicConverter/wasmHEICConverterService.ts

@@ -4,7 +4,7 @@ import { retryAsyncFunction } from 'utils/network';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
 import { DedicatedConvertWorker } from 'worker/convert.worker';
 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 { convertBytesToHumanReadable } from 'utils/file/size';
 import { getDedicatedConvertWorker } from 'utils/comlink/ComlinkConvertWorker';
 import { getDedicatedConvertWorker } from 'utils/comlink/ComlinkConvertWorker';
 
 

+ 13 - 19
apps/photos/src/services/watchFolder/watchFolderService.ts

@@ -9,7 +9,6 @@ import {
     WatchMapping,
     WatchMapping,
     WatchMappingSyncedFile,
     WatchMappingSyncedFile,
 } from 'types/watchFolder';
 } from 'types/watchFolder';
-import { ElectronAPIs } from 'types/electron';
 import debounce from 'debounce-promise';
 import debounce from 'debounce-promise';
 import {
 import {
     diskFileAddedCallback,
     diskFileAddedCallback,
@@ -22,9 +21,9 @@ import uploadManager from 'services/upload/uploadManager';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { getValidFilesToUpload } from 'utils/watch';
 import { getValidFilesToUpload } from 'utils/watch';
 import { groupFilesBasedOnCollectionID } from 'utils/file';
 import { groupFilesBasedOnCollectionID } from 'utils/file';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 class watchFolderService {
 class watchFolderService {
-    private electronAPIs: ElectronAPIs;
     private allElectronAPIsExist: boolean = false;
     private allElectronAPIsExist: boolean = false;
     private eventQueue: EventQueueItem[] = [];
     private eventQueue: EventQueueItem[] = [];
     private currentEvent: EventQueueItem;
     private currentEvent: EventQueueItem;
@@ -40,11 +39,6 @@ class watchFolderService {
     private syncWithRemote: () => void;
     private syncWithRemote: () => void;
     private setWatchFolderServiceIsRunning: (isRunning: boolean) => void;
     private setWatchFolderServiceIsRunning: (isRunning: boolean) => void;
 
 
-    constructor() {
-        this.electronAPIs = globalThis['ElectronAPIs'];
-        this.allElectronAPIsExist = !!this.electronAPIs?.getWatchMappings;
-    }
-
     isUploadRunning() {
     isUploadRunning() {
         return this.uploadRunning;
         return this.uploadRunning;
     }
     }
@@ -88,7 +82,7 @@ class watchFolderService {
 
 
             for (const mapping of mappings) {
             for (const mapping of mappings) {
                 const filesOnDisk: ElectronFile[] =
                 const filesOnDisk: ElectronFile[] =
-                    await this.electronAPIs.getDirFiles(mapping.folderPath);
+                    await ElectronAPIs.getDirFiles(mapping.folderPath);
 
 
                 this.uploadDiffOfFiles(mapping, filesOnDisk);
                 this.uploadDiffOfFiles(mapping, filesOnDisk);
                 this.trashDiffOfFiles(mapping, filesOnDisk);
                 this.trashDiffOfFiles(mapping, filesOnDisk);
@@ -155,11 +149,11 @@ class watchFolderService {
     ): Promise<WatchMapping[]> {
     ): Promise<WatchMapping[]> {
         const notDeletedMappings = [];
         const notDeletedMappings = [];
         for (const mapping of mappings) {
         for (const mapping of mappings) {
-            const mappingExists = await this.electronAPIs.isFolder(
+            const mappingExists = await ElectronAPIs.isFolder(
                 mapping.folderPath
                 mapping.folderPath
             );
             );
             if (!mappingExists) {
             if (!mappingExists) {
-                this.electronAPIs.removeWatchMapping(mapping.folderPath);
+                ElectronAPIs.removeWatchMapping(mapping.folderPath);
             } else {
             } else {
                 notDeletedMappings.push(mapping);
                 notDeletedMappings.push(mapping);
             }
             }
@@ -178,7 +172,7 @@ class watchFolderService {
 
 
     private setupWatcherFunctions() {
     private setupWatcherFunctions() {
         if (this.allElectronAPIsExist) {
         if (this.allElectronAPIsExist) {
-            this.electronAPIs.registerWatcherFunctions(
+            ElectronAPIs.registerWatcherFunctions(
                 diskFileAddedCallback,
                 diskFileAddedCallback,
                 diskFileRemovedCallback,
                 diskFileRemovedCallback,
                 diskFolderRemovedCallback
                 diskFolderRemovedCallback
@@ -193,7 +187,7 @@ class watchFolderService {
     ) {
     ) {
         if (this.allElectronAPIsExist) {
         if (this.allElectronAPIsExist) {
             try {
             try {
-                await this.electronAPIs.addWatchMapping(
+                await ElectronAPIs.addWatchMapping(
                     rootFolderName,
                     rootFolderName,
                     folderPath,
                     folderPath,
                     uploadStrategy
                     uploadStrategy
@@ -208,7 +202,7 @@ class watchFolderService {
     async removeWatchMapping(folderPath: string) {
     async removeWatchMapping(folderPath: string) {
         if (this.allElectronAPIsExist) {
         if (this.allElectronAPIsExist) {
             try {
             try {
-                await this.electronAPIs.removeWatchMapping(folderPath);
+                await ElectronAPIs.removeWatchMapping(folderPath);
             } catch (e) {
             } catch (e) {
                 logError(e, 'error while removing watch mapping');
                 logError(e, 'error while removing watch mapping');
             }
             }
@@ -218,7 +212,7 @@ class watchFolderService {
     getWatchMappings(): WatchMapping[] {
     getWatchMappings(): WatchMapping[] {
         if (this.allElectronAPIsExist) {
         if (this.allElectronAPIsExist) {
             try {
             try {
-                return this.electronAPIs.getWatchMappings() ?? [];
+                return ElectronAPIs.getWatchMappings() ?? [];
             } catch (e) {
             } catch (e) {
                 logError(e, 'error while getting watch mappings');
                 logError(e, 'error while getting watch mappings');
                 return [];
                 return [];
@@ -395,7 +389,7 @@ class watchFolderService {
                         ...this.currentlySyncedMapping.syncedFiles,
                         ...this.currentlySyncedMapping.syncedFiles,
                         ...syncedFiles,
                         ...syncedFiles,
                     ];
                     ];
-                    this.electronAPIs.updateWatchMappingSyncedFiles(
+                    ElectronAPIs.updateWatchMappingSyncedFiles(
                         this.currentlySyncedMapping.folderPath,
                         this.currentlySyncedMapping.folderPath,
                         this.currentlySyncedMapping.syncedFiles
                         this.currentlySyncedMapping.syncedFiles
                     );
                     );
@@ -405,7 +399,7 @@ class watchFolderService {
                         ...this.currentlySyncedMapping.ignoredFiles,
                         ...this.currentlySyncedMapping.ignoredFiles,
                         ...ignoredFiles,
                         ...ignoredFiles,
                     ];
                     ];
-                    this.electronAPIs.updateWatchMappingIgnoredFiles(
+                    ElectronAPIs.updateWatchMappingIgnoredFiles(
                         this.currentlySyncedMapping.folderPath,
                         this.currentlySyncedMapping.folderPath,
                         this.currentlySyncedMapping.ignoredFiles
                         this.currentlySyncedMapping.ignoredFiles
                     );
                     );
@@ -521,7 +515,7 @@ class watchFolderService {
                 this.currentlySyncedMapping.syncedFiles.filter(
                 this.currentlySyncedMapping.syncedFiles.filter(
                     (file) => !filePathsToRemove.has(file.path)
                     (file) => !filePathsToRemove.has(file.path)
                 );
                 );
-            this.electronAPIs.updateWatchMappingSyncedFiles(
+            ElectronAPIs.updateWatchMappingSyncedFiles(
                 this.currentlySyncedMapping.folderPath,
                 this.currentlySyncedMapping.folderPath,
                 this.currentlySyncedMapping.syncedFiles
                 this.currentlySyncedMapping.syncedFiles
             );
             );
@@ -613,7 +607,7 @@ class watchFolderService {
 
 
     async selectFolder(): Promise<string> {
     async selectFolder(): Promise<string> {
         try {
         try {
-            const folderPath = await this.electronAPIs.selectDirectory();
+            const folderPath = await ElectronAPIs.selectDirectory();
             return folderPath;
             return folderPath;
         } catch (e) {
         } catch (e) {
             logError(e, 'error while selecting folder');
             logError(e, 'error while selecting folder');
@@ -641,7 +635,7 @@ class watchFolderService {
 
 
     async isFolder(folderPath: string) {
     async isFolder(folderPath: string) {
         try {
         try {
-            const isFolder = await this.electronAPIs.isFolder(folderPath);
+            const isFolder = await ElectronAPIs.isFolder(folderPath);
             return isFolder;
             return isFolder;
         } catch (e) {
         } catch (e) {
             logError(e, 'error while checking if folder exists');
             logError(e, 'error while checking if folder exists');

+ 3 - 3
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 * as Comlink from 'comlink';
 import {
 import {
     LimitedCache,
     LimitedCache,
@@ -14,7 +14,7 @@ export class WorkerElectronCacheStorageClient
     implements ProxiedLimitedCacheStorage
     implements ProxiedLimitedCacheStorage
 {
 {
     async open(cacheName: string) {
     async open(cacheName: string) {
-        const cache = await ElectronCacheStorage.open(cacheName);
+        const cache = await ElectronAPIs.openDiskCache(cacheName);
         return Comlink.proxy({
         return Comlink.proxy({
             match: Comlink.proxy(transformMatch(cache.match.bind(cache))),
             match: Comlink.proxy(transformMatch(cache.match.bind(cache))),
             put: Comlink.proxy(transformPut(cache.put.bind(cache))),
             put: Comlink.proxy(transformPut(cache.put.bind(cache))),
@@ -23,7 +23,7 @@ export class WorkerElectronCacheStorageClient
     }
     }
 
 
     async delete(cacheName: string) {
     async delete(cacheName: string) {
-        return await ElectronCacheStorage.delete(cacheName);
+        return await ElectronAPIs.deleteDiskCache(cacheName);
     }
     }
 }
 }
 
 

+ 0 - 100
apps/photos/src/types/electron/index.ts

@@ -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<void>;
-    saveStreamToDisk: (
-        path: string,
-        fileStream: ReadableStream<any>
-    ) => Promise<void>;
-    saveFileToDisk: (path: string, file: any) => Promise<void>;
-    selectDirectory: () => Promise<string>;
-    sendNotification: (content: string) => void;
-    readTextFile: (path: string) => Promise<string>;
-    showUploadFilesDialog: () => Promise<ElectronFile[]>;
-    showUploadDirsDialog: () => Promise<ElectronFile[]>;
-    getPendingUploads: () => Promise<{
-        files: ElectronFile[];
-        collectionName: string;
-        type: string;
-    }>;
-    setToUploadFiles: (type: string, filePaths: string[]) => void;
-    showUploadZipDialog: () => Promise<{
-        zipPaths: string[];
-        files: ElectronFile[];
-    }>;
-    getElectronFilesFromGoogleZip: (
-        filePath: string
-    ) => Promise<ElectronFile[]>;
-    setToUploadCollection: (collectionName: string) => void;
-    getDirFiles: (dirPath: string) => Promise<ElectronFile[]>;
-    getWatchMappings: () => WatchMapping[];
-    updateWatchMappingSyncedFiles: (
-        folderPath: string,
-        files: WatchMapping['syncedFiles']
-    ) => void;
-    updateWatchMappingIgnoredFiles: (
-        folderPath: string,
-        files: WatchMapping['ignoredFiles']
-    ) => void;
-    addWatchMapping: (
-        collectionName: string,
-        folderPath: string,
-        uploadStrategy: number
-    ) => Promise<void>;
-    removeWatchMapping: (folderPath: string) => Promise<void>;
-    registerWatcherFunctions: (
-        addFile: (file: ElectronFile) => Promise<void>,
-        removeFile: (path: string) => Promise<void>,
-        removeFolder: (folderPath: string) => Promise<void>
-    ) => void;
-    isFolder: (dirPath: string) => Promise<boolean>;
-    clearElectronStore: () => void;
-    setEncryptionKey: (encryptionKey: string) => Promise<void>;
-    getEncryptionKey: () => Promise<string>;
-    openDiskCache: (cacheName: string) => Promise<LimitedCache>;
-    deleteDiskCache: (cacheName: string) => Promise<boolean>;
-    logToDisk: (msg: string) => void;
-    convertToJPEG: (
-        fileData: Uint8Array,
-        filename: string
-    ) => Promise<Uint8Array>;
-    openLogDirectory: () => void;
-    registerUpdateEventListener: (
-        showUpdateDialog: (updateInfo: AppUpdateInfo) => void
-    ) => void;
-    updateAndRestart: () => void;
-    skipAppUpdate: (version: string) => void;
-    getSentryUserID: () => Promise<string>;
-    getAppVersion: () => Promise<string>;
-    runFFmpegCmd: (
-        cmd: string[],
-        inputFile: File | ElectronFile,
-        outputFileName: string,
-        dontTimeout?: boolean
-    ) => Promise<File>;
-    muteUpdateNotification: (version: string) => void;
-    generateImageThumbnail: (
-        inputFile: File | ElectronFile,
-        maxDimension: number,
-        maxSize: number
-    ) => Promise<Uint8Array>;
-    logRendererProcessMemoryUsage: (message: string) => Promise<void>;
-    registerForegroundEventListener: (onForeground: () => void) => void;
-    openDirectory: (dirPath: string) => Promise<void>;
-    moveFile: (oldPath: string, newPath: string) => Promise<void>;
-    deleteFolder: (path: string) => Promise<void>;
-    deleteFile: (path: string) => void;
-    rename: (oldPath: string, newPath: string) => Promise<void>;
-    updateOptOutOfCrashReports: (optOut: boolean) => Promise<void>;
-    computeImageEmbedding: (imageData: Uint8Array) => Promise<Float32Array>;
-    computeTextEmbedding: (text: string) => Promise<Float32Array>;
-    getPlatform: () => Promise<'mac' | 'windows' | 'linux'>;
-}

+ 1 - 1
apps/photos/src/utils/billing/index.ts

@@ -4,7 +4,7 @@ import billingService from 'services/billingService';
 import { Plan, Subscription } from 'types/billing';
 import { Plan, Subscription } from 'types/billing';
 import { NextRouter } from 'next/router';
 import { NextRouter } from 'next/router';
 import { SetLoading } from 'types/gallery';
 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 { logError } from '@ente/shared/sentry';
 import { SetDialogBoxAttributes } from 'types/dialogBox';
 import { SetDialogBoxAttributes } from 'types/dialogBox';
 import { openLink } from 'utils/common';
 import { openLink } from 'utils/common';

+ 3 - 3
apps/photos/src/utils/collection/index.ts

@@ -17,7 +17,7 @@ import { getAllLocalFiles, getLocalFiles } from 'services/fileService';
 import { EnteFile } from 'types/file';
 import { EnteFile } from 'types/file';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
 import { User } from 'types/user';
 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 { logError } from '@ente/shared/sentry';
 import {
 import {
     COLLECTION_ROLE,
     COLLECTION_ROLE,
@@ -45,7 +45,7 @@ import bs58 from 'bs58';
 import { t } from 'i18next';
 import { t } from 'i18next';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
 import { SetCollectionDownloadProgressAttributes } from 'types/gallery';
 import { SetCollectionDownloadProgressAttributes } from 'types/gallery';
-import ElectronService from 'services/electron/common';
+import ElectronAPIs from '@ente/shared/electron';
 import {
 import {
     getCollectionExportPath,
     getCollectionExportPath,
     getUniqueCollectionExportName,
     getUniqueCollectionExportName,
@@ -186,7 +186,7 @@ async function downloadCollectionFiles(
         downloadDirPath: null,
         downloadDirPath: null,
     };
     };
     if (isElectron()) {
     if (isElectron()) {
-        const selectedDir = await ElectronService.selectDirectory();
+        const selectedDir = await ElectronAPIs.selectDirectory();
         if (!selectedDir) {
         if (!selectedDir) {
             return;
             return;
         }
         }

+ 1 - 1
apps/photos/src/utils/comlink/ComlinkConvertWorker.ts

@@ -1,7 +1,7 @@
 import { Remote } from 'comlink';
 import { Remote } from 'comlink';
 import { runningInBrowser } from 'utils/common';
 import { runningInBrowser } from 'utils/common';
 import { DedicatedConvertWorker } from 'worker/convert.worker';
 import { DedicatedConvertWorker } from 'worker/convert.worker';
-import { ComlinkWorker } from './comlinkWorker';
+import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker';
 
 
 class ComlinkConvertWorker {
 class ComlinkConvertWorker {
     private comlinkWorkerInstance: Remote<DedicatedConvertWorker>;
     private comlinkWorkerInstance: Remote<DedicatedConvertWorker>;

+ 0 - 25
apps/photos/src/utils/comlink/ComlinkCryptoWorker.ts

@@ -1,25 +0,0 @@
-import { Remote } from 'comlink';
-import { DedicatedCryptoWorker } from 'worker/crypto.worker';
-import { ComlinkWorker } from './comlinkWorker';
-
-class ComlinkCryptoWorker {
-    private comlinkWorkerInstance: Promise<Remote<DedicatedCryptoWorker>>;
-
-    async getInstance() {
-        if (!this.comlinkWorkerInstance) {
-            const comlinkWorker = getDedicatedCryptoWorker();
-            this.comlinkWorkerInstance = comlinkWorker.remote;
-        }
-        return this.comlinkWorkerInstance;
-    }
-}
-
-export const getDedicatedCryptoWorker = () => {
-    const cryptoComlinkWorker = new ComlinkWorker<typeof DedicatedCryptoWorker>(
-        'ente-crypto-worker',
-        new Worker(new URL('worker/crypto.worker.ts', import.meta.url))
-    );
-    return cryptoComlinkWorker;
-};
-
-export default new ComlinkCryptoWorker();

+ 1 - 1
apps/photos/src/utils/comlink/ComlinkFFmpegWorker.ts

@@ -1,6 +1,6 @@
 import { Remote } from 'comlink';
 import { Remote } from 'comlink';
 import { DedicatedFFmpegWorker } from 'worker/ffmpeg.worker';
 import { DedicatedFFmpegWorker } from 'worker/ffmpeg.worker';
-import { ComlinkWorker } from './comlinkWorker';
+import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker';
 
 
 class ComlinkFFmpegWorker {
 class ComlinkFFmpegWorker {
     private comlinkWorkerInstance: Promise<Remote<DedicatedFFmpegWorker>>;
     private comlinkWorkerInstance: Promise<Remote<DedicatedFFmpegWorker>>;

+ 1 - 1
apps/photos/src/utils/comlink/ComlinkMLWorker.ts

@@ -1,6 +1,6 @@
 import { runningInBrowser } from 'utils/common';
 import { runningInBrowser } from 'utils/common';
 import { DedicatedMLWorker } from 'worker/ml.worker';
 import { DedicatedMLWorker } from 'worker/ml.worker';
-import { ComlinkWorker } from './comlinkWorker';
+import { ComlinkWorker } from '@ente/shared/worker/comlinkWorker';
 
 
 export const getDedicatedMLWorker = (name: string) => {
 export const getDedicatedMLWorker = (name: string) => {
     if (runningInBrowser()) {
     if (runningInBrowser()) {

+ 0 - 27
apps/photos/src/utils/comlink/comlinkWorker.ts

@@ -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<T extends new () => InstanceType<T>> {
-    public remote: Promise<Remote<InstanceType<T>>>;
-    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<T>(this.worker);
-        this.remote = new comlink() as Promise<Remote<InstanceType<T>>>;
-        expose(WorkerElectronCacheStorageClient, this.worker);
-    }
-
-    public terminate() {
-        this.worker.terminate();
-        addLocalLog(() => `Terminated ${this.name}`);
-    }
-}

+ 1 - 1
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 = () => {
 export const getEndpoint = () => {
     let endpoint = getData(LS_KEYS.API_ENDPOINT);
     let endpoint = getData(LS_KEYS.API_ENDPOINT);

+ 3 - 3
apps/photos/src/utils/common/key.ts

@@ -1,7 +1,7 @@
 import { B64EncryptionResult } from 'types/crypto';
 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';
 import { CustomError } from '../error';
 
 
 export const getActualKey = async () => {
 export const getActualKey = async () => {

+ 6 - 5
apps/photos/src/utils/crypto/index.ts

@@ -1,12 +1,13 @@
 import { KeyAttributes, SRPSetupAttributes } from 'types/user';
 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 { getActualKey, getToken } from 'utils/common/key';
 import { setRecoveryKey } from '@ente/accounts/api/user';
 import { setRecoveryKey } from '@ente/accounts/api/user';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import isElectron from 'is-electron';
 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 { PasswordStrength } from 'constants/crypto';
 import zxcvbn from 'zxcvbn';
 import zxcvbn from 'zxcvbn';
 import { SRP, SrpClient } from 'fast-srp-hap';
 import { SRP, SrpClient } from 'fast-srp-hap';
@@ -125,7 +126,7 @@ export const saveKeyInSessionStore = async (
         !fromDesktop &&
         !fromDesktop &&
         keyType === SESSION_KEYS.ENCRYPTION_KEY
         keyType === SESSION_KEYS.ENCRYPTION_KEY
     ) {
     ) {
-        safeStorageService.setEncryptionKey(key);
+        ElectronAPIs.setEncryptionKey(key);
     }
     }
 };
 };
 
 

+ 8 - 7
apps/photos/src/utils/file/index.ts

@@ -13,7 +13,7 @@ import { getFileType } from 'services/typeDetectionService';
 import DownloadManager from 'services/downloadManager';
 import DownloadManager from 'services/downloadManager';
 import { logError } from '@ente/shared/sentry';
 import { logError } from '@ente/shared/sentry';
 import { User } from 'types/user';
 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 { updateFileCreationDateInEXIF } from 'services/upload/exifService';
 import {
 import {
     TYPE_JPEG,
     TYPE_JPEG,
@@ -33,7 +33,7 @@ import { isArchivedFile, updateMagicMetadata } from 'utils/magicMetadata';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { addLocalLog, addLogLine } from '@ente/shared/logging';
 import { CustomError } from 'utils/error';
 import { CustomError } from 'utils/error';
 import { convertBytesToHumanReadable } from './size';
 import { convertBytesToHumanReadable } from './size';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import ComlinkCryptoWorker from '@ente/shared/crypto';
 import {
 import {
     deleteFromTrash,
     deleteFromTrash,
     trashFiles,
     trashFiles,
@@ -41,13 +41,14 @@ import {
     updateFilePublicMagicMetadata,
     updateFilePublicMagicMetadata,
 } from 'services/fileService';
 } from 'services/fileService';
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
-import imageProcessor from 'services/electron/imageProcessor';
 import { isPlaybackPossible } from 'utils/photoFrame';
 import { isPlaybackPossible } from 'utils/photoFrame';
 import { FileTypeInfo } from 'types/upload';
 import { FileTypeInfo } from 'types/upload';
 import { moveToHiddenCollection } from 'services/collectionService';
 import { moveToHiddenCollection } from 'services/collectionService';
 
 
-import ElectronFSService from 'services/electron/fs';
+import ElectronFSService from '@ente/shared/electron';
 import { getFileExportPath, getUniqueFileExportName } from 'utils/export';
 import { getFileExportPath, getUniqueFileExportName } from 'utils/export';
+import imageProcessor from 'services/imageProcessor';
+import ElectronAPIs from '@ente/shared/electron';
 
 
 const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
 const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
 
 
@@ -712,7 +713,7 @@ export async function downloadFileDesktop(
             livePhoto.imageNameTitle
             livePhoto.imageNameTitle
         );
         );
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
-        await ElectronFSService.saveMediaFile(
+        await ElectronAPIs.saveStreamToDisk(
             getFileExportPath(downloadPath, imageExportName),
             getFileExportPath(downloadPath, imageExportName),
             imageStream
             imageStream
         );
         );
@@ -722,7 +723,7 @@ export async function downloadFileDesktop(
                 livePhoto.videoNameTitle
                 livePhoto.videoNameTitle
             );
             );
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
-            await ElectronFSService.saveMediaFile(
+            await ElectronAPIs.saveStreamToDisk(
                 getFileExportPath(downloadPath, videoExportName),
                 getFileExportPath(downloadPath, videoExportName),
                 videoStream
                 videoStream
             );
             );
@@ -737,7 +738,7 @@ export async function downloadFileDesktop(
             downloadPath,
             downloadPath,
             file.metadata.title
             file.metadata.title
         );
         );
-        await ElectronFSService.saveMediaFile(
+        await ElectronAPIs.saveStreamToDisk(
             getFileExportPath(downloadPath, fileExportName),
             getFileExportPath(downloadPath, fileExportName),
             updatedFileStream
             updatedFileStream
         );
         );

+ 1 - 1
apps/photos/src/utils/machineLearning/faceCrop.ts

@@ -13,7 +13,7 @@ import {
 } from 'types/machineLearning';
 } from 'types/machineLearning';
 import { cropWithRotation, imageBitmapToBlob } from 'utils/image';
 import { cropWithRotation, imageBitmapToBlob } from 'utils/image';
 import { addLogLine } from '@ente/shared/logging';
 import { addLogLine } from '@ente/shared/logging';
-import { getBlobFromCache } from 'utils/storage/cache';
+import { getBlobFromCache } from '@ente/shared/storage/cacheStorage/helpers';
 import { enlargeBox } from '.';
 import { enlargeBox } from '.';
 import { Box } from '../../../thirdparty/face-api/classes';
 import { Box } from '../../../thirdparty/face-api/classes';
 import { getAlignedFaceBox } from './faceAlign';
 import { getAlignedFaceBox } from './faceAlign';

+ 1 - 1
apps/photos/src/utils/machineLearning/index.ts

@@ -24,7 +24,7 @@ import {
 // import { mlFilesStore, mlPeopleStore } from 'utils/storage/mlStorage';
 // import { mlFilesStore, mlPeopleStore } from 'utils/storage/mlStorage';
 import { getRenderableImage } from 'utils/file';
 import { getRenderableImage } from 'utils/file';
 import { imageBitmapToBlob } from 'utils/image';
 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 mlIDbStorage from 'utils/storage/mlIDbStorage';
 import { Box, Point } from '../../../thirdparty/face-api/classes';
 import { Box, Point } from '../../../thirdparty/face-api/classes';
 import {
 import {

+ 1 - 1
apps/photos/src/utils/magicMetadata/index.ts

@@ -1,7 +1,7 @@
 import { Collection } from 'types/collection';
 import { Collection } from 'types/collection';
 import { EnteFile } from 'types/file';
 import { EnteFile } from 'types/file';
 import { MagicMetadataCore, VISIBILITY_STATE } from 'types/magicMetadata';
 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 {
 export function isArchivedFile(item: EnteFile): boolean {
     if (!item || !item.magicMetadata || !item.magicMetadata.data) {
     if (!item || !item.magicMetadata || !item.magicMetadata.data) {

+ 0 - 48
apps/photos/src/utils/storage/cache.ts

@@ -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<Blob>
-): Promise<Blob> {
-    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<Blob> {
-    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
-    }
-}

+ 0 - 40
apps/photos/src/utils/storage/index.ts

@@ -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;
-}

+ 0 - 12
apps/photos/src/utils/storage/localForage.ts

@@ -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;

+ 0 - 68
apps/photos/src/utils/storage/localStorage.ts

@@ -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();
-};

+ 1 - 1
apps/photos/src/utils/storage/mlStorage.ts

@@ -1,3 +1,4 @@
+import localForage from 'localforage';
 import { EnteFile } from 'types/file';
 import { EnteFile } from 'types/file';
 import {
 import {
     Face,
     Face,
@@ -5,7 +6,6 @@ import {
     MLIndex,
     MLIndex,
     MLSyncContext,
     MLSyncContext,
 } from 'types/machineLearning';
 } from 'types/machineLearning';
-import localForage from './localForage';
 
 
 export const mlFilesStore = localForage.createInstance({
 export const mlFilesStore = localForage.createInstance({
     driver: localForage.INDEXEDDB,
     driver: localForage.INDEXEDDB,

+ 0 - 32
apps/photos/src/utils/storage/sessionStorage.ts

@@ -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();
-};

+ 5 - 6
apps/photos/src/utils/ui/index.tsx

@@ -3,14 +3,14 @@ import { DialogBoxAttributes } from 'types/dialogBox';
 import { downloadApp } from 'utils/common';
 import { downloadApp } from 'utils/common';
 import { t } from 'i18next';
 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 InfoOutlined from '@mui/icons-material/InfoRounded';
 import { Trans } from 'react-i18next';
 import { Trans } from 'react-i18next';
 import { Subscription } from 'types/billing';
 import { Subscription } from 'types/billing';
 import { logoutUser } from '@ente/accounts/services/user';
 import { logoutUser } from '@ente/accounts/services/user';
 import { Link } from '@mui/material';
 import { Link } from '@mui/material';
 import { OPEN_STREET_MAP_LINK } from 'components/Sidebar/EnableMap';
 import { OPEN_STREET_MAP_LINK } from 'components/Sidebar/EnableMap';
+import { AppUpdateInfo } from '@ente/shared/electron/types';
 export const getDownloadAppMessage = (): DialogBoxAttributes => {
 export const getDownloadAppMessage = (): DialogBoxAttributes => {
     return {
     return {
         title: t('DOWNLOAD_APP'),
         title: t('DOWNLOAD_APP'),
@@ -58,15 +58,14 @@ export const getUpdateReadyToInstallMessage = (
     title: t('UPDATE_AVAILABLE'),
     title: t('UPDATE_AVAILABLE'),
     content: t('UPDATE_INSTALLABLE_MESSAGE'),
     content: t('UPDATE_INSTALLABLE_MESSAGE'),
     proceed: {
     proceed: {
-        action: () => ElectronUpdateService.updateAndRestart(),
+        action: () => ElectronAPIs.updateAndRestart(),
         text: t('INSTALL_NOW'),
         text: t('INSTALL_NOW'),
         variant: 'accent',
         variant: 'accent',
     },
     },
     close: {
     close: {
         text: t('INSTALL_ON_NEXT_LAUNCH'),
         text: t('INSTALL_ON_NEXT_LAUNCH'),
         variant: 'secondary',
         variant: 'secondary',
-        action: () =>
-            ElectronUpdateService.muteUpdateNotification(updateInfo.version),
+        action: () => ElectronAPIs.muteUpdateNotification(updateInfo.version),
     },
     },
 });
 });
 
 
@@ -79,7 +78,7 @@ export const getUpdateAvailableForDownloadMessage = (
     close: {
     close: {
         text: t('IGNORE_THIS_VERSION'),
         text: t('IGNORE_THIS_VERSION'),
         variant: 'secondary',
         variant: 'secondary',
-        action: () => ElectronUpdateService.skipAppUpdate(updateInfo.version),
+        action: () => ElectronAPIs.skipAppUpdate(updateInfo.version),
     },
     },
     proceed: {
     proceed: {
         action: downloadApp,
         action: downloadApp,

+ 1 - 1
apps/photos/src/utils/user/family.ts

@@ -1,6 +1,6 @@
 import { FamilyData, FamilyMember, User } from 'types/user';
 import { FamilyData, FamilyMember, User } from 'types/user';
 import { logError } from '@ente/shared/sentry';
 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 {
 export function getLocalFamilyData(): FamilyData {
     return getData(LS_KEYS.FAMILY_DATA);
     return getData(LS_KEYS.FAMILY_DATA);

+ 3 - 3
apps/photos/src/utils/user/index.ts

@@ -1,7 +1,7 @@
 import isElectron from 'is-electron';
 import isElectron from 'is-electron';
 import { UserDetails } from 'types/user';
 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';
 import { Buffer } from 'buffer';
 
 
 export function makeID(length) {
 export function makeID(length) {
@@ -19,7 +19,7 @@ export function makeID(length) {
 
 
 export async function getSentryUserID() {
 export async function getSentryUserID() {
     if (isElectron()) {
     if (isElectron()) {
-        return await ElectronService.getSentryUserID();
+        return await ElectronAPIs.getSentryUserID();
     } else {
     } else {
         let anonymizeUserID = getData(LS_KEYS.AnonymizedUserID)?.id;
         let anonymizeUserID = getData(LS_KEYS.AnonymizedUserID)?.id;
         if (!anonymizeUserID) {
         if (!anonymizeUserID) {

+ 39 - 6
packages/shared/crypto/internal/crypto.worker.ts

@@ -1,7 +1,9 @@
 import * as Comlink from 'comlink';
 import * as Comlink from 'comlink';
 import { StateAddress } from 'libsodium-wrappers';
 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 {
 export class DedicatedCryptoWorker {
     async decryptMetadata(
     async decryptMetadata(
         encryptedMetadata: string,
         encryptedMetadata: string,
@@ -13,7 +15,7 @@ export class DedicatedCryptoWorker {
             await libsodium.fromB64(header),
             await libsodium.fromB64(header),
             key
             key
         );
         );
-        return JSON.parse(new TextDecoder().decode(encodedMetadata));
+        return JSON.parse(textDecoder.decode(encodedMetadata));
     }
     }
 
 
     async decryptThumbnail(
     async decryptThumbnail(
@@ -24,14 +26,27 @@ export class DedicatedCryptoWorker {
         return libsodium.decryptChaChaOneShot(fileData, header, key);
         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) {
     async decryptFile(fileData: Uint8Array, header: Uint8Array, key: string) {
         return libsodium.decryptChaCha(fileData, header, key);
         return libsodium.decryptChaCha(fileData, header, key);
     }
     }
 
 
     async encryptMetadata(metadata: Object, key: string) {
     async encryptMetadata(metadata: Object, key: string) {
-        const encodedMetadata = new TextEncoder().encode(
-            JSON.stringify(metadata)
-        );
+        const encodedMetadata = textEncoder.encode(JSON.stringify(metadata));
 
 
         const { file: encryptedMetadata } =
         const { file: encryptedMetadata } =
             await libsodium.encryptChaChaOneShot(encodedMetadata, key);
             await libsodium.encryptChaChaOneShot(encodedMetadata, key);
@@ -49,6 +64,24 @@ export class DedicatedCryptoWorker {
         return libsodium.encryptChaChaOneShot(fileData, key);
         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) {
     async encryptFile(fileData: Uint8Array) {
         return libsodium.encryptChaCha(fileData);
         return libsodium.encryptChaCha(fileData);
     }
     }
@@ -179,4 +212,4 @@ export class DedicatedCryptoWorker {
     }
     }
 }
 }
 
 
-Comlink.expose(DedicatedCryptoWorker);
+Comlink.expose(DedicatedCryptoWorker, self);

+ 3 - 3
packages/shared/crypto/internal/libsodium.ts

@@ -1,7 +1,7 @@
 import sodium, { StateAddress } from 'libsodium-wrappers';
 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(
 export async function decryptChaChaOneShot(
     data: Uint8Array,
     data: Uint8Array,