Browse Source

Switch to prettier defaults

This is unfortunately a huge diff, but now is as good as ever to do this pending chore.

- Move to prettier (v3) defaults. The only thing we tweak is the tabWidth (the
  default is 2, we change it to 4).

- Use the prettier plugin to sort imports.

We were not changing the defaults of prettier much anyway, the main thing that
has changed is the switching from the overridden single quotes to the default
double quotes.
Manav Rathi 1 year ago
parent
commit
c1bf193211
100 changed files with 1317 additions and 1265 deletions
  1. 0 3
      .github/.prettierrc.json
  2. 1 3
      .prettierrc.json
  3. 4 4
      apps/accounts/.eslintrc.js
  4. 1 1
      apps/accounts/next.config.js
  5. 2 2
      apps/accounts/sentry.client.config.ts
  6. 32 30
      apps/accounts/src/pages/_app.tsx
  7. 1 1
      apps/accounts/src/pages/_document.tsx
  8. 13 13
      apps/accounts/src/pages/account-handoff.tsx
  9. 5 5
      apps/accounts/src/pages/credentials/index.tsx
  10. 5 5
      apps/accounts/src/pages/generate/index.tsx
  11. 3 3
      apps/accounts/src/pages/index.tsx
  12. 5 5
      apps/accounts/src/pages/login/index.tsx
  13. 21 18
      apps/accounts/src/pages/passkeys/DeletePasskeyModal.tsx
  14. 24 23
      apps/accounts/src/pages/passkeys/ManagePasskeyDrawer.tsx
  15. 6 6
      apps/accounts/src/pages/passkeys/PasskeyListItem.tsx
  16. 5 5
      apps/accounts/src/pages/passkeys/PasskeysList.tsx
  17. 13 12
      apps/accounts/src/pages/passkeys/RenamePasskeyModal.tsx
  18. 1 1
      apps/accounts/src/pages/passkeys/finish.tsx
  19. 60 53
      apps/accounts/src/pages/passkeys/flow/index.tsx
  20. 35 33
      apps/accounts/src/pages/passkeys/index.tsx
  21. 5 5
      apps/accounts/src/pages/recover/index.tsx
  22. 5 5
      apps/accounts/src/pages/signup/index.tsx
  23. 5 5
      apps/accounts/src/pages/two-factor/recover/index.tsx
  24. 5 5
      apps/accounts/src/pages/two-factor/setup/index.tsx
  25. 5 5
      apps/accounts/src/pages/two-factor/verify/index.tsx
  26. 5 5
      apps/accounts/src/pages/verify/index.tsx
  27. 30 30
      apps/accounts/src/services/passkeysService.ts
  28. 12 12
      apps/accounts/src/styles/global.css
  29. 4 4
      apps/auth/.eslintrc.js
  30. 1 1
      apps/auth/next.config.js
  31. 2 2
      apps/auth/sentry.client.config.ts
  32. 10 9
      apps/auth/src/components/AuthFooter.tsx
  33. 19 17
      apps/auth/src/components/Navbar.tsx
  34. 86 76
      apps/auth/src/components/OTPDisplay.tsx
  35. 4 4
      apps/auth/src/components/TimerProgress.tsx
  36. 5 5
      apps/auth/src/pages/404.tsx
  37. 55 53
      apps/auth/src/pages/_app.tsx
  38. 1 1
      apps/auth/src/pages/_document.tsx
  39. 5 5
      apps/auth/src/pages/_error.tsx
  40. 45 42
      apps/auth/src/pages/auth/index.tsx
  41. 5 5
      apps/auth/src/pages/change-email/index.tsx
  42. 5 5
      apps/auth/src/pages/change-password/index.tsx
  43. 5 5
      apps/auth/src/pages/credentials/index.tsx
  44. 5 5
      apps/auth/src/pages/generate/index.tsx
  45. 3 3
      apps/auth/src/pages/index.tsx
  46. 5 5
      apps/auth/src/pages/login/index.tsx
  47. 5 5
      apps/auth/src/pages/recover/index.tsx
  48. 5 5
      apps/auth/src/pages/signup/index.tsx
  49. 5 5
      apps/auth/src/pages/two-factor/recover/index.tsx
  50. 5 5
      apps/auth/src/pages/two-factor/setup/index.tsx
  51. 5 5
      apps/auth/src/pages/two-factor/verify/index.tsx
  52. 5 5
      apps/auth/src/pages/verify/index.tsx
  53. 24 24
      apps/auth/src/services/index.ts
  54. 50 50
      apps/auth/src/types/code.ts
  55. 4 4
      apps/cast/.eslintrc.js
  56. 1 1
      apps/cast/next.config.js
  57. 2 2
      apps/cast/sentry.client.config.ts
  58. 5 4
      apps/cast/src/components/FilledCircleCheck/index.tsx
  59. 39 35
      apps/cast/src/components/LargeType.tsx
  60. 21 17
      apps/cast/src/components/PairedSuccessfullyOverlay.tsx
  61. 25 23
      apps/cast/src/components/Theatre/PhotoAuditorium.tsx
  62. 14 12
      apps/cast/src/components/Theatre/VideoAuditorium.tsx
  63. 2 2
      apps/cast/src/components/Theatre/index.tsx
  64. 6 6
      apps/cast/src/components/TimerBar.tsx
  65. 11 11
      apps/cast/src/constants/apps.ts
  66. 3 3
      apps/cast/src/constants/cache.ts
  67. 20 20
      apps/cast/src/constants/collection.ts
  68. 3 3
      apps/cast/src/constants/ffmpeg.ts
  69. 25 25
      apps/cast/src/constants/file.ts
  70. 2 2
      apps/cast/src/constants/gallery.ts
  71. 16 16
      apps/cast/src/constants/pages.ts
  72. 54 54
      apps/cast/src/constants/upload.ts
  73. 9 9
      apps/cast/src/constants/urls.ts
  74. 9 8
      apps/cast/src/pages/_app.tsx
  75. 11 9
      apps/cast/src/pages/_document.tsx
  76. 67 60
      apps/cast/src/pages/index.tsx
  77. 24 24
      apps/cast/src/pages/slideshow.tsx
  78. 3 3
      apps/cast/src/services/InMemoryStore.ts
  79. 2 2
      apps/cast/src/services/cache/cacheStorageFactory.ts
  80. 6 6
      apps/cast/src/services/cache/cacheStorageService.ts
  81. 44 44
      apps/cast/src/services/cast/castService.ts
  82. 38 38
      apps/cast/src/services/castDownloadManager.ts
  83. 4 4
      apps/cast/src/services/events.ts
  84. 3 3
      apps/cast/src/services/ffmpeg/ffmpegFactory.ts
  85. 10 10
      apps/cast/src/services/ffmpeg/ffmpegService.ts
  86. 3 3
      apps/cast/src/services/heicConversionService.ts
  87. 12 12
      apps/cast/src/services/livePhotoService.ts
  88. 3 3
      apps/cast/src/services/queueProcessor.ts
  89. 14 14
      apps/cast/src/services/readerService.ts
  90. 19 19
      apps/cast/src/services/typeDetectionService.ts
  91. 26 26
      apps/cast/src/services/wasm/ffmpeg.ts
  92. 3 3
      apps/cast/src/services/wasmHeicConverter/wasmHEICConverterClient.ts
  93. 24 24
      apps/cast/src/services/wasmHeicConverter/wasmHEICConverterService.ts
  94. 14 14
      apps/cast/src/types/collection/index.ts
  95. 7 7
      apps/cast/src/types/file/index.ts
  96. 3 3
      apps/cast/src/types/gallery/index.ts
  97. 9 9
      apps/cast/src/types/upload/index.ts
  98. 1 1
      apps/cast/src/types/upload/ui.ts
  99. 12 12
      apps/cast/src/utils/collection/index.ts
  100. 6 6
      apps/cast/src/utils/comlink/ComlinkConvertWorker.ts

+ 0 - 3
.github/.prettierrc.json

@@ -1,3 +0,0 @@
-{
-    "tabWidth": 4
-}

+ 1 - 3
.prettierrc.json

@@ -1,6 +1,4 @@
 {
 {
     "tabWidth": 4,
     "tabWidth": 4,
-    "trailingComma": "es5",
-    "singleQuote": true,
-    "bracketSameLine": true
+    "plugins": ["prettier-plugin-organize-imports"]
 }
 }

+ 4 - 4
apps/accounts/.eslintrc.js

@@ -3,11 +3,11 @@ module.exports = {
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // packaged as a submodule.
     // packaged as a submodule.
     root: true,
     root: true,
-    extends: ['@ente/eslint-config'],
-    parser: '@typescript-eslint/parser',
+    extends: ["@ente/eslint-config"],
+    parser: "@typescript-eslint/parser",
     parserOptions: {
     parserOptions: {
         tsconfigRootDir: __dirname,
         tsconfigRootDir: __dirname,
-        project: './tsconfig.json',
+        project: "./tsconfig.json",
     },
     },
-    ignorePatterns: ['.eslintrc.js', 'out'],
+    ignorePatterns: [".eslintrc.js", "out"],
 };
 };

+ 1 - 1
apps/accounts/next.config.js

@@ -1,4 +1,4 @@
-const nextConfigBase = require('@/next/next.config.base.js');
+const nextConfigBase = require("@/next/next.config.base.js");
 
 
 module.exports = {
 module.exports = {
     ...nextConfigBase,
     ...nextConfigBase,

+ 2 - 2
apps/accounts/sentry.client.config.ts

@@ -1,3 +1,3 @@
-import { initSentry } from '@ente/shared/sentry/config/sentry.config.base';
+import { initSentry } from "@ente/shared/sentry/config/sentry.config.base";
 
 
-initSentry('https://0f7214c7feb9b1dd2fed5db09b42fa1b@sentry.ente.io/5');
+initSentry("https://0f7214c7feb9b1dd2fed5db09b42fa1b@sentry.ente.io/5");

+ 32 - 30
apps/accounts/src/pages/_app.tsx

@@ -1,27 +1,27 @@
-import { CacheProvider } from '@emotion/react';
-import { APPS, APP_TITLES } from '@ente/shared/apps/constants';
-import { EnteAppProps } from '@ente/shared/apps/types';
-import { Overlay } from '@ente/shared/components/Container';
-import DialogBoxV2 from '@ente/shared/components/DialogBoxV2';
+import { setupI18n } from "@/ui/i18n";
+import { CacheProvider } from "@emotion/react";
+import { APPS, APP_TITLES } from "@ente/shared/apps/constants";
+import { EnteAppProps } from "@ente/shared/apps/types";
+import { Overlay } from "@ente/shared/components/Container";
+import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import {
 import {
     DialogBoxAttributesV2,
     DialogBoxAttributesV2,
     SetDialogBoxAttributesV2,
     SetDialogBoxAttributesV2,
-} from '@ente/shared/components/DialogBoxV2/types';
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import AppNavbar from '@ente/shared/components/Navbar/app';
-import { useLocalState } from '@ente/shared/hooks/useLocalState';
-import { setupI18n } from '@/ui/i18n';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { LS_KEYS, getData } from '@ente/shared/storage/localStorage';
-import { getTheme } from '@ente/shared/themes';
-import { THEME_COLOR } from '@ente/shared/themes/constants';
-import createEmotionCache from '@ente/shared/themes/createEmotionCache';
-import { CssBaseline, useMediaQuery } from '@mui/material';
-import { ThemeProvider } from '@mui/material/styles';
-import Head from 'next/head';
-import { useRouter } from 'next/router';
-import { createContext, useEffect, useState } from 'react';
-import 'styles/global.css';
+} from "@ente/shared/components/DialogBoxV2/types";
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import AppNavbar from "@ente/shared/components/Navbar/app";
+import { useLocalState } from "@ente/shared/hooks/useLocalState";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
+import { getTheme } from "@ente/shared/themes";
+import { THEME_COLOR } from "@ente/shared/themes/constants";
+import createEmotionCache from "@ente/shared/themes/createEmotionCache";
+import { CssBaseline, useMediaQuery } from "@mui/material";
+import { ThemeProvider } from "@mui/material/styles";
+import Head from "next/head";
+import { useRouter } from "next/router";
+import { createContext, useEffect, useState } from "react";
+import "styles/global.css";
 
 
 interface AppContextProps {
 interface AppContextProps {
     isMobile: boolean;
     isMobile: boolean;
@@ -50,7 +50,7 @@ export default function App(props: EnteAppProps) {
 
 
     const showNavBar = (show: boolean) => setShowNavBar(show);
     const showNavBar = (show: boolean) => setShowNavBar(show);
 
 
-    const isMobile = useMediaQuery('(max-width:428px)');
+    const isMobile = useMediaQuery("(max-width:428px)");
 
 
     const router = useRouter();
     const router = useRouter();
 
 
@@ -70,14 +70,14 @@ export default function App(props: EnteAppProps) {
         const pkg = getData(LS_KEYS.CLIENT_PACKAGE);
         const pkg = getData(LS_KEYS.CLIENT_PACKAGE);
         if (!pkg) return;
         if (!pkg) return;
         HTTPService.setHeaders({
         HTTPService.setHeaders({
-            'X-Client-Package': pkg.name,
+            "X-Client-Package": pkg.name,
         });
         });
     };
     };
 
 
     useEffect(() => {
     useEffect(() => {
-        router.events.on('routeChangeComplete', setupPackageName);
+        router.events.on("routeChangeComplete", setupPackageName);
         return () => {
         return () => {
-            router.events.off('routeChangeComplete', setupPackageName);
+            router.events.off("routeChangeComplete", setupPackageName);
         };
         };
     }, [router.events]);
     }, [router.events]);
 
 
@@ -111,17 +111,19 @@ export default function App(props: EnteAppProps) {
                         showNavBar,
                         showNavBar,
                         setDialogBoxAttributesV2:
                         setDialogBoxAttributesV2:
                             setDialogBoxAttributesV2 as any,
                             setDialogBoxAttributesV2 as any,
-                    }}>
+                    }}
+                >
                     {!isI18nReady && (
                     {!isI18nReady && (
                         <Overlay
                         <Overlay
                             sx={(theme) => ({
                             sx={(theme) => ({
-                                display: 'flex',
-                                justifyContent: 'center',
-                                alignItems: 'center',
+                                display: "flex",
+                                justifyContent: "center",
+                                alignItems: "center",
                                 zIndex: 2000,
                                 zIndex: 2000,
                                 backgroundColor: (theme as any).colors
                                 backgroundColor: (theme as any).colors
                                     .background.base,
                                     .background.base,
-                            })}>
+                            })}
+                        >
                             <EnteSpinner />
                             <EnteSpinner />
                         </Overlay>
                         </Overlay>
                     )}
                     )}

+ 1 - 1
apps/accounts/src/pages/_document.tsx

@@ -1,6 +1,6 @@
 import DocumentPage, {
 import DocumentPage, {
     EnteDocumentProps,
     EnteDocumentProps,
-} from '@ente/shared/next/pages/_document';
+} from "@ente/shared/next/pages/_document";
 
 
 export default function Document(props: EnteDocumentProps) {
 export default function Document(props: EnteDocumentProps) {
     return <DocumentPage {...props} />;
     return <DocumentPage {...props} />;

+ 13 - 13
apps/accounts/src/pages/account-handoff.tsx

@@ -1,11 +1,11 @@
-import { VerticallyCentered } from '@ente/shared/components/Container';
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import { ACCOUNTS_PAGES } from '@ente/shared/constants/pages';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { logError } from '@ente/shared/sentry';
-import { LS_KEYS, getData, setData } from '@ente/shared/storage/localStorage';
-import { useRouter } from 'next/router';
-import { useEffect } from 'react';
+import { VerticallyCentered } from "@ente/shared/components/Container";
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { logError } from "@ente/shared/sentry";
+import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
+import { useRouter } from "next/router";
+import { useEffect } from "react";
 
 
 const AccountHandoff = () => {
 const AccountHandoff = () => {
     const router = useRouter();
     const router = useRouter();
@@ -16,26 +16,26 @@ const AccountHandoff = () => {
 
 
             router.push(ACCOUNTS_PAGES.PASSKEYS);
             router.push(ACCOUNTS_PAGES.PASSKEYS);
         } catch (e) {
         } catch (e) {
-            logError(e, 'Failed to deserialize and set passed user data');
+            logError(e, "Failed to deserialize and set passed user data");
             router.push(ACCOUNTS_PAGES.LOGIN);
             router.push(ACCOUNTS_PAGES.LOGIN);
         }
         }
     };
     };
 
 
     const getClientPackageName = () => {
     const getClientPackageName = () => {
         const urlParams = new URLSearchParams(window.location.search);
         const urlParams = new URLSearchParams(window.location.search);
-        const pkg = urlParams.get('package');
+        const pkg = urlParams.get("package");
         if (!pkg) return;
         if (!pkg) return;
         setData(LS_KEYS.CLIENT_PACKAGE, { name: pkg });
         setData(LS_KEYS.CLIENT_PACKAGE, { name: pkg });
         HTTPService.setHeaders({
         HTTPService.setHeaders({
-            'X-Client-Package': pkg,
+            "X-Client-Package": pkg,
         });
         });
     };
     };
 
 
     const extractAccountsToken = () => {
     const extractAccountsToken = () => {
         const urlParams = new URLSearchParams(window.location.search);
         const urlParams = new URLSearchParams(window.location.search);
-        const token = urlParams.get('token');
+        const token = urlParams.get("token");
         if (!token) {
         if (!token) {
-            throw new Error('token not found');
+            throw new Error("token not found");
         }
         }
 
 
         const user = getData(LS_KEYS.USER) || {};
         const user = getData(LS_KEYS.USER) || {};

+ 5 - 5
apps/accounts/src/pages/credentials/index.tsx

@@ -1,8 +1,8 @@
-import CredentialPage from '@ente/accounts/pages/credentials';
-import { useRouter } from 'next/router';
-import { AppContext } from '../_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import CredentialPage from "@ente/accounts/pages/credentials";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { useContext } from "react";
+import { AppContext } from "../_app";
 
 
 export default function Credential() {
 export default function Credential() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/generate/index.tsx

@@ -1,8 +1,8 @@
-import GeneratePage from '@ente/accounts/pages/generate';
-import { APPS } from '@ente/shared/apps/constants';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
+import GeneratePage from "@ente/accounts/pages/generate";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Generate() {
 export default function Generate() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 3 - 3
apps/accounts/src/pages/index.tsx

@@ -1,11 +1,11 @@
-import { useRouter } from 'next/router';
-import { useEffect } from 'react';
+import { useRouter } from "next/router";
+import { useEffect } from "react";
 
 
 const Index = () => {
 const Index = () => {
     const router = useRouter();
     const router = useRouter();
 
 
     useEffect(() => {
     useEffect(() => {
-        router.push('/login');
+        router.push("/login");
     }, []);
     }, []);
     return <></>;
     return <></>;
 };
 };

+ 5 - 5
apps/accounts/src/pages/login/index.tsx

@@ -1,8 +1,8 @@
-import LoginPage from '@ente/accounts/pages/login';
-import { useRouter } from 'next/router';
-import { AppContext } from '../_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import LoginPage from "@ente/accounts/pages/login";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { useContext } from "react";
+import { AppContext } from "../_app";
 
 
 export default function Login() {
 export default function Login() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 21 - 18
apps/accounts/src/pages/passkeys/DeletePasskeyModal.tsx

@@ -1,11 +1,11 @@
-import DialogBoxV2 from '@ente/shared/components/DialogBoxV2';
-import EnteButton from '@ente/shared/components/EnteButton';
-import { Button, Stack, Typography } from '@mui/material';
-import { AppContext } from 'pages/_app';
-import { useContext, useState } from 'react';
-import { deletePasskey } from 'services/passkeysService';
-import { PasskeysContext } from '.';
-import { t } from 'i18next';
+import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
+import EnteButton from "@ente/shared/components/EnteButton";
+import { Button, Stack, Typography } from "@mui/material";
+import { t } from "i18next";
+import { AppContext } from "pages/_app";
+import { useContext, useState } from "react";
+import { deletePasskey } from "services/passkeysService";
+import { PasskeysContext } from ".";
 
 
 interface IProps {
 interface IProps {
     open: boolean;
     open: boolean;
@@ -41,27 +41,30 @@ const DeletePasskeyModal = (props: IProps) => {
             onClose={props.onClose}
             onClose={props.onClose}
             fullScreen={isMobile}
             fullScreen={isMobile}
             attributes={{
             attributes={{
-                title: t('DELETE_PASSKEY'),
+                title: t("DELETE_PASSKEY"),
                 secondary: {
                 secondary: {
                     action: props.onClose,
                     action: props.onClose,
-                    text: t('CANCEL'),
+                    text: t("CANCEL"),
                 },
                 },
-            }}>
-            <Stack spacing={'8px'}>
-                <Typography>{t('DELETE_PASSKEY_CONFIRMATION')}</Typography>
+            }}
+        >
+            <Stack spacing={"8px"}>
+                <Typography>{t("DELETE_PASSKEY_CONFIRMATION")}</Typography>
                 <EnteButton
                 <EnteButton
                     type="submit"
                     type="submit"
                     size="large"
                     size="large"
                     color="critical"
                     color="critical"
                     loading={loading}
                     loading={loading}
-                    onClick={doDelete}>
-                    {t('DELETE')}
+                    onClick={doDelete}
+                >
+                    {t("DELETE")}
                 </EnteButton>
                 </EnteButton>
                 <Button
                 <Button
                     size="large"
                     size="large"
-                    color={'secondary'}
-                    onClick={props.onClose}>
-                    {t('CANCEL')}
+                    color={"secondary"}
+                    onClick={props.onClose}
+                >
+                    {t("CANCEL")}
                 </Button>
                 </Button>
             </Stack>
             </Stack>
         </DialogBoxV2>
         </DialogBoxV2>

+ 24 - 23
apps/accounts/src/pages/passkeys/ManagePasskeyDrawer.tsx

@@ -1,19 +1,19 @@
-import { EnteDrawer } from '@ente/shared/components/EnteDrawer';
-import { PasskeysContext } from '.';
-import { Stack } from '@mui/material';
-import Titlebar from '@ente/shared/components/Titlebar';
-import { MenuItemGroup } from '@ente/shared/components/Menu/MenuItemGroup';
-import { EnteMenuItem } from '@ente/shared/components/Menu/EnteMenuItem';
-import { useContext, useState } from 'react';
-import EditIcon from '@mui/icons-material/Edit';
-import DeleteIcon from '@mui/icons-material/Delete';
-import MenuItemDivider from '@ente/shared/components/Menu/MenuItemDivider';
-import DeletePasskeyModal from './DeletePasskeyModal';
-import RenamePasskeyModal from './RenamePasskeyModal';
-import InfoItem from '@ente/shared/components/Info/InfoItem';
-import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
-import { formatDateTimeFull } from '@ente/shared/time/format';
-import { t } from 'i18next';
+import { EnteDrawer } from "@ente/shared/components/EnteDrawer";
+import InfoItem from "@ente/shared/components/Info/InfoItem";
+import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem";
+import MenuItemDivider from "@ente/shared/components/Menu/MenuItemDivider";
+import { MenuItemGroup } from "@ente/shared/components/Menu/MenuItemGroup";
+import Titlebar from "@ente/shared/components/Titlebar";
+import { formatDateTimeFull } from "@ente/shared/time/format";
+import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
+import DeleteIcon from "@mui/icons-material/Delete";
+import EditIcon from "@mui/icons-material/Edit";
+import { Stack } from "@mui/material";
+import { t } from "i18next";
+import { useContext, useState } from "react";
+import { PasskeysContext } from ".";
+import DeletePasskeyModal from "./DeletePasskeyModal";
+import RenamePasskeyModal from "./RenamePasskeyModal";
 
 
 interface IProps {
 interface IProps {
     open: boolean;
     open: boolean;
@@ -33,10 +33,11 @@ const ManagePasskeyDrawer = (props: IProps) => {
                 open={props.open}
                 open={props.open}
                 onClose={() => {
                 onClose={() => {
                     setShowPasskeyDrawer(false);
                     setShowPasskeyDrawer(false);
-                }}>
+                }}
+            >
                 {selectedPasskey && (
                 {selectedPasskey && (
                     <>
                     <>
-                        <Stack spacing={'4px'} py={'12px'}>
+                        <Stack spacing={"4px"} py={"12px"}>
                             <Titlebar
                             <Titlebar
                                 onClose={() => {
                                 onClose={() => {
                                     setShowPasskeyDrawer(false);
                                     setShowPasskeyDrawer(false);
@@ -48,11 +49,11 @@ const ManagePasskeyDrawer = (props: IProps) => {
                             />
                             />
                             <InfoItem
                             <InfoItem
                                 icon={<CalendarTodayIcon />}
                                 icon={<CalendarTodayIcon />}
-                                title={t('CREATED_AT')}
+                                title={t("CREATED_AT")}
                                 caption={
                                 caption={
                                     `${formatDateTimeFull(
                                     `${formatDateTimeFull(
-                                        selectedPasskey.createdAt / 1000
-                                    )}` || ''
+                                        selectedPasskey.createdAt / 1000,
+                                    )}` || ""
                                 }
                                 }
                                 loading={!selectedPasskey}
                                 loading={!selectedPasskey}
                                 hideEditOption
                                 hideEditOption
@@ -63,7 +64,7 @@ const ManagePasskeyDrawer = (props: IProps) => {
                                         setShowRenamePasskeyModal(true);
                                         setShowRenamePasskeyModal(true);
                                     }}
                                     }}
                                     startIcon={<EditIcon />}
                                     startIcon={<EditIcon />}
-                                    label={'Rename Passkey'}
+                                    label={"Rename Passkey"}
                                 />
                                 />
                                 <MenuItemDivider />
                                 <MenuItemDivider />
                                 <EnteMenuItem
                                 <EnteMenuItem
@@ -71,7 +72,7 @@ const ManagePasskeyDrawer = (props: IProps) => {
                                         setShowDeletePasskeyModal(true);
                                         setShowDeletePasskeyModal(true);
                                     }}
                                     }}
                                     startIcon={<DeleteIcon />}
                                     startIcon={<DeleteIcon />}
-                                    label={'Delete Passkey'}
+                                    label={"Delete Passkey"}
                                     color="critical"
                                     color="critical"
                                 />
                                 />
                             </MenuItemGroup>
                             </MenuItemGroup>

+ 6 - 6
apps/accounts/src/pages/passkeys/PasskeyListItem.tsx

@@ -1,9 +1,9 @@
-import { EnteMenuItem } from '@ente/shared/components/Menu/EnteMenuItem';
-import { Passkey } from 'types/passkey';
-import ChevronRightIcon from '@mui/icons-material/ChevronRight';
-import { useContext } from 'react';
-import { PasskeysContext } from '.';
-import KeyIcon from '@mui/icons-material/Key';
+import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem";
+import ChevronRightIcon from "@mui/icons-material/ChevronRight";
+import KeyIcon from "@mui/icons-material/Key";
+import { useContext } from "react";
+import { Passkey } from "types/passkey";
+import { PasskeysContext } from ".";
 
 
 interface IProps {
 interface IProps {
     passkey: Passkey;
     passkey: Passkey;

+ 5 - 5
apps/accounts/src/pages/passkeys/PasskeysList.tsx

@@ -1,8 +1,8 @@
-import { MenuItemGroup } from '@ente/shared/components/Menu/MenuItemGroup';
-import { Passkey } from 'types/passkey';
-import PasskeyListItem from './PasskeyListItem';
-import MenuItemDivider from '@ente/shared/components/Menu/MenuItemDivider';
-import { Fragment } from 'react';
+import MenuItemDivider from "@ente/shared/components/Menu/MenuItemDivider";
+import { MenuItemGroup } from "@ente/shared/components/Menu/MenuItemGroup";
+import { Fragment } from "react";
+import { Passkey } from "types/passkey";
+import PasskeyListItem from "./PasskeyListItem";
 
 
 interface IProps {
 interface IProps {
     passkeys: Passkey[];
     passkeys: Passkey[];

+ 13 - 12
apps/accounts/src/pages/passkeys/RenamePasskeyModal.tsx

@@ -1,10 +1,10 @@
-import DialogBoxV2 from '@ente/shared/components/DialogBoxV2';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { PasskeysContext } from '.';
-import SingleInputForm from '@ente/shared/components/SingleInputForm';
-import { t } from 'i18next';
-import { renamePasskey } from 'services/passkeysService';
+import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
+import SingleInputForm from "@ente/shared/components/SingleInputForm";
+import { t } from "i18next";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
+import { renamePasskey } from "services/passkeysService";
+import { PasskeysContext } from ".";
 
 
 interface IProps {
 interface IProps {
     open: boolean;
     open: boolean;
@@ -34,17 +34,18 @@ const RenamePasskeyModal = (props: IProps) => {
             onClose={props.onClose}
             onClose={props.onClose}
             fullScreen={isMobile}
             fullScreen={isMobile}
             attributes={{
             attributes={{
-                title: t('RENAME_PASSKEY'),
+                title: t("RENAME_PASSKEY"),
                 secondary: {
                 secondary: {
                     action: props.onClose,
                     action: props.onClose,
-                    text: t('CANCEL'),
+                    text: t("CANCEL"),
                 },
                 },
-            }}>
+            }}
+        >
             <SingleInputForm
             <SingleInputForm
                 initialValue={selectedPasskey?.friendlyName}
                 initialValue={selectedPasskey?.friendlyName}
                 callback={onSubmit}
                 callback={onSubmit}
-                placeholder={t('ENTER_PASSKEY_NAME')}
-                buttonText={t('RENAME')}
+                placeholder={t("ENTER_PASSKEY_NAME")}
+                buttonText={t("RENAME")}
                 fieldType="text"
                 fieldType="text"
                 secondaryButtonAction={props.onClose}
                 secondaryButtonAction={props.onClose}
                 submitButtonProps={{ sx: { mt: 1, mb: 2 } }}
                 submitButtonProps={{ sx: { mt: 1, mb: 2 } }}

+ 1 - 1
apps/accounts/src/pages/passkeys/finish.tsx

@@ -1,4 +1,4 @@
-import PasskeysFinishPage from '@ente/accounts/pages/passkeys/finish';
+import PasskeysFinishPage from "@ente/accounts/pages/passkeys/finish";
 const PasskeysFinish = () => {
 const PasskeysFinish = () => {
     return <PasskeysFinishPage />;
     return <PasskeysFinishPage />;
 };
 };

+ 60 - 53
apps/accounts/src/pages/passkeys/flow/index.tsx

@@ -1,25 +1,25 @@
-import { APPS, CLIENT_PACKAGE_NAMES } from '@ente/shared/apps/constants';
+import { APPS, CLIENT_PACKAGE_NAMES } from "@ente/shared/apps/constants";
 import {
 import {
     CenteredFlex,
     CenteredFlex,
     VerticallyCentered,
     VerticallyCentered,
-} from '@ente/shared/components/Container';
-import EnteButton from '@ente/shared/components/EnteButton';
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import FormPaper from '@ente/shared/components/Form/FormPaper';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { logError } from '@ente/shared/sentry';
-import { LS_KEYS, setData } from '@ente/shared/storage/localStorage';
-import InfoIcon from '@mui/icons-material/Info';
-import { Box, Typography } from '@mui/material';
-import { t } from 'i18next';
-import _sodium from 'libsodium-wrappers';
-import Image from 'next/image';
-import { useEffect, useState } from 'react';
+} from "@ente/shared/components/Container";
+import EnteButton from "@ente/shared/components/EnteButton";
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import FormPaper from "@ente/shared/components/Form/FormPaper";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { logError } from "@ente/shared/sentry";
+import { LS_KEYS, setData } from "@ente/shared/storage/localStorage";
+import InfoIcon from "@mui/icons-material/Info";
+import { Box, Typography } from "@mui/material";
+import { t } from "i18next";
+import _sodium from "libsodium-wrappers";
+import Image from "next/image";
+import { useEffect, useState } from "react";
 import {
 import {
     BeginPasskeyAuthenticationResponse,
     BeginPasskeyAuthenticationResponse,
     beginPasskeyAuthentication,
     beginPasskeyAuthentication,
     finishPasskeyAuthentication,
     finishPasskeyAuthentication,
-} from 'services/passkeysService';
+} from "services/passkeysService";
 
 
 const PasskeysFlow = () => {
 const PasskeysFlow = () => {
     const [errored, setErrored] = useState(false);
     const [errored, setErrored] = useState(false);
@@ -32,18 +32,18 @@ const PasskeysFlow = () => {
         const searchParams = new URLSearchParams(window.location.search);
         const searchParams = new URLSearchParams(window.location.search);
 
 
         // get redirect from the query params
         // get redirect from the query params
-        const redirect = searchParams.get('redirect') as string;
+        const redirect = searchParams.get("redirect") as string;
 
 
         const redirectURL = new URL(redirect);
         const redirectURL = new URL(redirect);
-        if (process.env.NEXT_PUBLIC_DISABLE_REDIRECT_CHECK !== 'true') {
+        if (process.env.NEXT_PUBLIC_DISABLE_REDIRECT_CHECK !== "true") {
             if (
             if (
-                redirect !== '' &&
+                redirect !== "" &&
                 !(
                 !(
-                    redirectURL.host.endsWith('.ente.io') ||
-                    redirectURL.host.endsWith('bada-frame.pages.dev')
+                    redirectURL.host.endsWith(".ente.io") ||
+                    redirectURL.host.endsWith("bada-frame.pages.dev")
                 ) &&
                 ) &&
-                redirectURL.protocol !== 'ente:' &&
-                redirectURL.protocol !== 'enteauth:'
+                redirectURL.protocol !== "ente:" &&
+                redirectURL.protocol !== "enteauth:"
             ) {
             ) {
                 setInvalidInfo(true);
                 setInvalidInfo(true);
                 setLoading(false);
                 setLoading(false);
@@ -52,19 +52,19 @@ const PasskeysFlow = () => {
         }
         }
 
 
         let pkg = CLIENT_PACKAGE_NAMES.get(APPS.PHOTOS);
         let pkg = CLIENT_PACKAGE_NAMES.get(APPS.PHOTOS);
-        if (redirectURL.protocol === 'enteauth:') {
+        if (redirectURL.protocol === "enteauth:") {
             pkg = CLIENT_PACKAGE_NAMES.get(APPS.AUTH);
             pkg = CLIENT_PACKAGE_NAMES.get(APPS.AUTH);
-        } else if (redirectURL.hostname.startsWith('accounts')) {
+        } else if (redirectURL.hostname.startsWith("accounts")) {
             pkg = CLIENT_PACKAGE_NAMES.get(APPS.ACCOUNTS);
             pkg = CLIENT_PACKAGE_NAMES.get(APPS.ACCOUNTS);
         }
         }
 
 
         setData(LS_KEYS.CLIENT_PACKAGE, { name: pkg });
         setData(LS_KEYS.CLIENT_PACKAGE, { name: pkg });
         HTTPService.setHeaders({
         HTTPService.setHeaders({
-            'X-Client-Package': pkg,
+            "X-Client-Package": pkg,
         });
         });
 
 
         // get passkeySessionID from the query params
         // get passkeySessionID from the query params
-        const passkeySessionID = searchParams.get('passkeySessionID') as string;
+        const passkeySessionID = searchParams.get("passkeySessionID") as string;
 
 
         setLoading(true);
         setLoading(true);
 
 
@@ -100,7 +100,7 @@ const PasskeysFlow = () => {
 
 
         if (!credential) {
         if (!credential) {
             if (!isWebAuthnSupported()) {
             if (!isWebAuthnSupported()) {
-                alert('WebAuthn is not supported in this browser');
+                alert("WebAuthn is not supported in this browser");
             }
             }
             setErrored(true);
             setErrored(true);
             return;
             return;
@@ -114,7 +114,7 @@ const PasskeysFlow = () => {
             finishData = await finishAuthentication(
             finishData = await finishAuthentication(
                 credential,
                 credential,
                 passkeySessionID,
                 passkeySessionID,
-                beginData.ceremonySessionID
+                beginData.ceremonySessionID,
             );
             );
         } catch (e) {
         } catch (e) {
             logError(e, "Couldn't finish passkey authentication");
             logError(e, "Couldn't finish passkey authentication");
@@ -142,28 +142,28 @@ const PasskeysFlow = () => {
 
 
     const getCredential = async (
     const getCredential = async (
         publicKey: any,
         publicKey: any,
-        timeoutMillis: number = 60000 // Default timeout of 60 seconds
+        timeoutMillis: number = 60000, // Default timeout of 60 seconds
     ): Promise<Credential | null> => {
     ): Promise<Credential | null> => {
         publicKey.challenge = _sodium.from_base64(
         publicKey.challenge = _sodium.from_base64(
             publicKey.challenge,
             publicKey.challenge,
-            _sodium.base64_variants.URLSAFE_NO_PADDING
+            _sodium.base64_variants.URLSAFE_NO_PADDING,
         );
         );
         publicKey.allowCredentials?.forEach(function (listItem: any) {
         publicKey.allowCredentials?.forEach(function (listItem: any) {
             listItem.id = _sodium.from_base64(
             listItem.id = _sodium.from_base64(
                 listItem.id,
                 listItem.id,
-                _sodium.base64_variants.URLSAFE_NO_PADDING
+                _sodium.base64_variants.URLSAFE_NO_PADDING,
             );
             );
             // note: we are orverwriting the transports array with all possible values.
             // note: we are orverwriting the transports array with all possible values.
             // This is because the browser will only prompt the user for the transport that is available.
             // This is because the browser will only prompt the user for the transport that is available.
             // Warning: In case of invalid transport value, the webauthn will fail on Safari & iOS browsers
             // Warning: In case of invalid transport value, the webauthn will fail on Safari & iOS browsers
-            listItem.transports = ['usb', 'nfc', 'ble', 'internal'];
+            listItem.transports = ["usb", "nfc", "ble", "internal"];
         });
         });
         publicKey.timeout = timeoutMillis;
         publicKey.timeout = timeoutMillis;
         const publicKeyCredentialCreationOptions: CredentialRequestOptions = {
         const publicKeyCredentialCreationOptions: CredentialRequestOptions = {
             publicKey: publicKey,
             publicKey: publicKey,
         };
         };
         const credential = await navigator.credentials.get(
         const credential = await navigator.credentials.get(
-            publicKeyCredentialCreationOptions
+            publicKeyCredentialCreationOptions,
         );
         );
         return credential;
         return credential;
     };
     };
@@ -171,12 +171,12 @@ const PasskeysFlow = () => {
     const finishAuthentication = async (
     const finishAuthentication = async (
         credential: Credential,
         credential: Credential,
         sessionId: string,
         sessionId: string,
-        ceremonySessionId: string
+        ceremonySessionId: string,
     ) => {
     ) => {
         const data = await finishPasskeyAuthentication(
         const data = await finishPasskeyAuthentication(
             credential,
             credential,
             sessionId,
             sessionId,
-            ceremonySessionId
+            ceremonySessionId,
         );
         );
         return data;
         return data;
     };
     };
@@ -199,18 +199,20 @@ const PasskeysFlow = () => {
                 display="flex"
                 display="flex"
                 justifyContent="center"
                 justifyContent="center"
                 alignItems="center"
                 alignItems="center"
-                height="100%">
+                height="100%"
+            >
                 <Box maxWidth="30rem">
                 <Box maxWidth="30rem">
                     <FormPaper
                     <FormPaper
                         style={{
                         style={{
-                            padding: '1rem',
-                        }}>
+                            padding: "1rem",
+                        }}
+                    >
                         <InfoIcon />
                         <InfoIcon />
                         <Typography fontWeight="bold" variant="h1">
                         <Typography fontWeight="bold" variant="h1">
-                            {t('PASSKEY_LOGIN_FAILED')}
+                            {t("PASSKEY_LOGIN_FAILED")}
                         </Typography>
                         </Typography>
                         <Typography marginTop="1rem">
                         <Typography marginTop="1rem">
-                            {t('PASSKEY_LOGIN_URL_INVALID')}
+                            {t("PASSKEY_LOGIN_URL_INVALID")}
                         </Typography>
                         </Typography>
                     </FormPaper>
                     </FormPaper>
                 </Box>
                 </Box>
@@ -224,18 +226,20 @@ const PasskeysFlow = () => {
                 display="flex"
                 display="flex"
                 justifyContent="center"
                 justifyContent="center"
                 alignItems="center"
                 alignItems="center"
-                height="100%">
+                height="100%"
+            >
                 <Box maxWidth="30rem">
                 <Box maxWidth="30rem">
                     <FormPaper
                     <FormPaper
                         style={{
                         style={{
-                            padding: '1rem',
-                        }}>
+                            padding: "1rem",
+                        }}
+                    >
                         <InfoIcon />
                         <InfoIcon />
                         <Typography fontWeight="bold" variant="h1">
                         <Typography fontWeight="bold" variant="h1">
-                            {t('PASSKEY_LOGIN_FAILED')}
+                            {t("PASSKEY_LOGIN_FAILED")}
                         </Typography>
                         </Typography>
                         <Typography marginTop="1rem">
                         <Typography marginTop="1rem">
-                            {t('PASSKEY_LOGIN_ERRORED')}
+                            {t("PASSKEY_LOGIN_ERRORED")}
                         </Typography>
                         </Typography>
                         <EnteButton
                         <EnteButton
                             onClick={() => {
                             onClick={() => {
@@ -244,12 +248,13 @@ const PasskeysFlow = () => {
                             }}
                             }}
                             fullWidth
                             fullWidth
                             style={{
                             style={{
-                                marginTop: '1rem',
+                                marginTop: "1rem",
                             }}
                             }}
                             color="primary"
                             color="primary"
                             type="button"
                             type="button"
-                            variant="contained">
-                            {t('TRY_AGAIN')}
+                            variant="contained"
+                        >
+                            {t("TRY_AGAIN")}
                         </EnteButton>
                         </EnteButton>
                     </FormPaper>
                     </FormPaper>
                 </Box>
                 </Box>
@@ -263,18 +268,20 @@ const PasskeysFlow = () => {
                 display="flex"
                 display="flex"
                 justifyContent="center"
                 justifyContent="center"
                 alignItems="center"
                 alignItems="center"
-                height="100%">
+                height="100%"
+            >
                 <Box maxWidth="30rem">
                 <Box maxWidth="30rem">
                     <FormPaper
                     <FormPaper
                         style={{
                         style={{
-                            padding: '1rem',
-                        }}>
+                            padding: "1rem",
+                        }}
+                    >
                         <InfoIcon />
                         <InfoIcon />
                         <Typography fontWeight="bold" variant="h1">
                         <Typography fontWeight="bold" variant="h1">
-                            {t('LOGIN_WITH_PASSKEY')}
+                            {t("LOGIN_WITH_PASSKEY")}
                         </Typography>
                         </Typography>
                         <Typography marginTop="1rem">
                         <Typography marginTop="1rem">
-                            {t('PASSKEY_FOLLOW_THE_STEPS_FROM_YOUR_BROWSER')}
+                            {t("PASSKEY_FOLLOW_THE_STEPS_FROM_YOUR_BROWSER")}
                         </Typography>
                         </Typography>
                         <CenteredFlex marginTop="1rem">
                         <CenteredFlex marginTop="1rem">
                             <Image
                             <Image

+ 35 - 33
apps/accounts/src/pages/passkeys/index.tsx

@@ -1,14 +1,14 @@
-import { CenteredFlex } from '@ente/shared/components/Container';
-import FormPaper from '@ente/shared/components/Form/FormPaper';
-import SingleInputForm from '@ente/shared/components/SingleInputForm';
-import { ACCOUNTS_PAGES } from '@ente/shared/constants/pages';
-import { logError } from '@ente/shared/sentry';
-import { getToken } from '@ente/shared/storage/localStorage/helpers';
-import { Box, Typography } from '@mui/material';
-import { t } from 'i18next';
-import _sodium from 'libsodium-wrappers';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
+import { CenteredFlex } from "@ente/shared/components/Container";
+import FormPaper from "@ente/shared/components/Form/FormPaper";
+import SingleInputForm from "@ente/shared/components/SingleInputForm";
+import { ACCOUNTS_PAGES } from "@ente/shared/constants/pages";
+import { logError } from "@ente/shared/sentry";
+import { getToken } from "@ente/shared/storage/localStorage/helpers";
+import { Box, Typography } from "@mui/material";
+import { t } from "i18next";
+import _sodium from "libsodium-wrappers";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
 import {
 import {
     Dispatch,
     Dispatch,
     SetStateAction,
     SetStateAction,
@@ -16,15 +16,15 @@ import {
     useContext,
     useContext,
     useEffect,
     useEffect,
     useState,
     useState,
-} from 'react';
-import { Passkey } from 'types/passkey';
+} from "react";
+import { Passkey } from "types/passkey";
 import {
 import {
     finishPasskeyRegistration,
     finishPasskeyRegistration,
     getPasskeyRegistrationOptions,
     getPasskeyRegistrationOptions,
     getPasskeys,
     getPasskeys,
-} from '../../services/passkeysService';
-import ManagePasskeyDrawer from './ManagePasskeyDrawer';
-import PasskeysList from './PasskeysList';
+} from "../../services/passkeysService";
+import ManagePasskeyDrawer from "./ManagePasskeyDrawer";
+import PasskeysList from "./PasskeysList";
 
 
 export const PasskeysContext = createContext(
 export const PasskeysContext = createContext(
     {} as {
     {} as {
@@ -32,14 +32,14 @@ export const PasskeysContext = createContext(
         setSelectedPasskey: Dispatch<SetStateAction<Passkey | null>>;
         setSelectedPasskey: Dispatch<SetStateAction<Passkey | null>>;
         setShowPasskeyDrawer: Dispatch<SetStateAction<boolean>>;
         setShowPasskeyDrawer: Dispatch<SetStateAction<boolean>>;
         refreshPasskeys: () => void;
         refreshPasskeys: () => void;
-    }
+    },
 );
 );
 
 
 const Passkeys = () => {
 const Passkeys = () => {
     const { showNavBar } = useContext(AppContext);
     const { showNavBar } = useContext(AppContext);
 
 
     const [selectedPasskey, setSelectedPasskey] = useState<Passkey | null>(
     const [selectedPasskey, setSelectedPasskey] = useState<Passkey | null>(
-        null
+        null,
     );
     );
 
 
     const [showPasskeyDrawer, setShowPasskeyDrawer] = useState(false);
     const [showPasskeyDrawer, setShowPasskeyDrawer] = useState(false);
@@ -69,7 +69,7 @@ const Passkeys = () => {
     const handleSubmit = async (
     const handleSubmit = async (
         inputValue: string,
         inputValue: string,
         setFieldError: (errorMessage: string) => void,
         setFieldError: (errorMessage: string) => void,
-        resetForm: (nextState?: unknown) => void
+        resetForm: (nextState?: unknown) => void,
     ) => {
     ) => {
         let response: {
         let response: {
             options: {
             options: {
@@ -81,7 +81,7 @@ const Passkeys = () => {
         try {
         try {
             response = await getPasskeyRegistrationOptions();
             response = await getPasskeyRegistrationOptions();
         } catch {
         } catch {
-            setFieldError('Failed to begin registration');
+            setFieldError("Failed to begin registration");
             return;
             return;
         }
         }
 
 
@@ -90,12 +90,12 @@ const Passkeys = () => {
         options.publicKey.challenge = _sodium.from_base64(
         options.publicKey.challenge = _sodium.from_base64(
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             // @ts-ignore
-            options.publicKey.challenge
+            options.publicKey.challenge,
         );
         );
         options.publicKey.user.id = _sodium.from_base64(
         options.publicKey.user.id = _sodium.from_base64(
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             // @ts-ignore
-            options.publicKey.user.id
+            options.publicKey.user.id,
         );
         );
 
 
         // create new credential
         // create new credential
@@ -104,8 +104,8 @@ const Passkeys = () => {
         try {
         try {
             newCredential = await navigator.credentials.create(options);
             newCredential = await navigator.credentials.create(options);
         } catch (e) {
         } catch (e) {
-            logError(e, 'Error creating credential');
-            setFieldError('Failed to create credential');
+            logError(e, "Error creating credential");
+            setFieldError("Failed to create credential");
             return;
             return;
         }
         }
 
 
@@ -113,10 +113,10 @@ const Passkeys = () => {
             await finishPasskeyRegistration(
             await finishPasskeyRegistration(
                 inputValue,
                 inputValue,
                 newCredential,
                 newCredential,
-                response.sessionID
+                response.sessionID,
             );
             );
         } catch {
         } catch {
-            setFieldError('Failed to finish registration');
+            setFieldError("Failed to finish registration");
             return;
             return;
         }
         }
 
 
@@ -132,21 +132,23 @@ const Passkeys = () => {
                     setSelectedPasskey,
                     setSelectedPasskey,
                     setShowPasskeyDrawer,
                     setShowPasskeyDrawer,
                     refreshPasskeys: init,
                     refreshPasskeys: init,
-                }}>
+                }}
+            >
                 <CenteredFlex>
                 <CenteredFlex>
                     <Box maxWidth="20rem">
                     <Box maxWidth="20rem">
                         <Box marginBottom="1rem">
                         <Box marginBottom="1rem">
-                            <Typography>{t('PASSKEYS_DESCRIPTION')}</Typography>
+                            <Typography>{t("PASSKEYS_DESCRIPTION")}</Typography>
                         </Box>
                         </Box>
                         <FormPaper
                         <FormPaper
                             style={{
                             style={{
-                                padding: '1rem',
-                            }}>
+                                padding: "1rem",
+                            }}
+                        >
                             <SingleInputForm
                             <SingleInputForm
                                 fieldType="text"
                                 fieldType="text"
-                                placeholder={t('ENTER_PASSKEY_NAME')}
-                                buttonText={t('ADD_PASSKEY')}
-                                initialValue={''}
+                                placeholder={t("ENTER_PASSKEY_NAME")}
+                                buttonText={t("ADD_PASSKEY")}
+                                initialValue={""}
                                 callback={handleSubmit}
                                 callback={handleSubmit}
                                 submitButtonProps={{
                                 submitButtonProps={{
                                     sx: {
                                     sx: {

+ 5 - 5
apps/accounts/src/pages/recover/index.tsx

@@ -1,8 +1,8 @@
-import RecoverPage from '@ente/accounts/pages/recover';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import RecoverPage from "@ente/accounts/pages/recover";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Recover() {
 export default function Recover() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/signup/index.tsx

@@ -1,8 +1,8 @@
-import SignupPage from '@ente/accounts/pages/signup';
-import { APPS } from '@ente/shared/apps/constants';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
+import SignupPage from "@ente/accounts/pages/signup";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Sigup() {
 export default function Sigup() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/two-factor/recover/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorRecoverPage from '@ente/accounts/pages/two-factor/recover';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorRecoverPage from "@ente/accounts/pages/two-factor/recover";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorRecover() {
 export default function TwoFactorRecover() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/two-factor/setup/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorSetupPage from '@ente/accounts/pages/two-factor/setup';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorSetupPage from "@ente/accounts/pages/two-factor/setup";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorSetup() {
 export default function TwoFactorSetup() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/two-factor/verify/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorVerifyPage from '@ente/accounts/pages/two-factor/verify';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorVerifyPage from "@ente/accounts/pages/two-factor/verify";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorVerify() {
 export default function TwoFactorVerify() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/accounts/src/pages/verify/index.tsx

@@ -1,8 +1,8 @@
-import VerifyPage from '@ente/accounts/pages/verify';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import VerifyPage from "@ente/accounts/pages/verify";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Verify() {
 export default function Verify() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 30 - 30
apps/accounts/src/services/passkeysService.ts

@@ -1,8 +1,8 @@
-import HTTPService from '@ente/shared/network/HTTPService';
-import { getEndpoint } from '@ente/shared/network/api';
-import { logError } from '@ente/shared/sentry';
-import { getToken } from '@ente/shared/storage/localStorage/helpers';
-import _sodium from 'libsodium-wrappers';
+import HTTPService from "@ente/shared/network/HTTPService";
+import { getEndpoint } from "@ente/shared/network/api";
+import { logError } from "@ente/shared/sentry";
+import { getToken } from "@ente/shared/storage/localStorage/helpers";
+import _sodium from "libsodium-wrappers";
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
 
 
 export const getPasskeys = async () => {
 export const getPasskeys = async () => {
@@ -12,11 +12,11 @@ export const getPasskeys = async () => {
         const response = await HTTPService.get(
         const response = await HTTPService.get(
             `${ENDPOINT}/passkeys`,
             `${ENDPOINT}/passkeys`,
             {},
             {},
-            { 'X-Auth-Token': token }
+            { "X-Auth-Token": token },
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'get passkeys failed');
+        logError(e, "get passkeys failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -29,11 +29,11 @@ export const renamePasskey = async (id: string, name: string) => {
             `${ENDPOINT}/passkeys/${id}`,
             `${ENDPOINT}/passkeys/${id}`,
             {},
             {},
             { friendlyName: name },
             { friendlyName: name },
-            { 'X-Auth-Token': token }
+            { "X-Auth-Token": token },
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'rename passkey failed');
+        logError(e, "rename passkey failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -46,11 +46,11 @@ export const deletePasskey = async (id: string) => {
             `${ENDPOINT}/passkeys/${id}`,
             `${ENDPOINT}/passkeys/${id}`,
             {},
             {},
             {},
             {},
-            { 'X-Auth-Token': token }
+            { "X-Auth-Token": token },
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'delete passkey failed');
+        logError(e, "delete passkey failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -63,12 +63,12 @@ export const getPasskeyRegistrationOptions = async () => {
             `${ENDPOINT}/passkeys/registration/begin`,
             `${ENDPOINT}/passkeys/registration/begin`,
             {},
             {},
             {
             {
-                'X-Auth-Token': token,
-            }
+                "X-Auth-Token": token,
+            },
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'get passkey registration options failed');
+        logError(e, "get passkey registration options failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -76,20 +76,20 @@ export const getPasskeyRegistrationOptions = async () => {
 export const finishPasskeyRegistration = async (
 export const finishPasskeyRegistration = async (
     friendlyName: string,
     friendlyName: string,
     credential: Credential,
     credential: Credential,
-    sessionId: string
+    sessionId: string,
 ) => {
 ) => {
     try {
     try {
         const attestationObjectB64 = _sodium.to_base64(
         const attestationObjectB64 = _sodium.to_base64(
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             // @ts-ignore
             new Uint8Array(credential.response.attestationObject),
             new Uint8Array(credential.response.attestationObject),
-            _sodium.base64_variants.URLSAFE_NO_PADDING
+            _sodium.base64_variants.URLSAFE_NO_PADDING,
         );
         );
         const clientDataJSONB64 = _sodium.to_base64(
         const clientDataJSONB64 = _sodium.to_base64(
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
             // @ts-ignore
             // @ts-ignore
             new Uint8Array(credential.response.clientDataJSON),
             new Uint8Array(credential.response.clientDataJSON),
-            _sodium.base64_variants.URLSAFE_NO_PADDING
+            _sodium.base64_variants.URLSAFE_NO_PADDING,
         );
         );
 
 
         const token = getToken();
         const token = getToken();
@@ -111,12 +111,12 @@ export const finishPasskeyRegistration = async (
                 sessionID: sessionId,
                 sessionID: sessionId,
             },
             },
             {
             {
-                'X-Auth-Token': token,
-            }
+                "X-Auth-Token": token,
+            },
         );
         );
         return await response.data;
         return await response.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'finish passkey registration failed');
+        logError(e, "finish passkey registration failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -130,19 +130,19 @@ interface Options {
 }
 }
 
 
 export const beginPasskeyAuthentication = async (
 export const beginPasskeyAuthentication = async (
-    sessionId: string
+    sessionId: string,
 ): Promise<BeginPasskeyAuthenticationResponse> => {
 ): Promise<BeginPasskeyAuthenticationResponse> => {
     try {
     try {
         const data = await HTTPService.post(
         const data = await HTTPService.post(
             `${ENDPOINT}/users/two-factor/passkeys/begin`,
             `${ENDPOINT}/users/two-factor/passkeys/begin`,
             {
             {
                 sessionID: sessionId,
                 sessionID: sessionId,
-            }
+            },
         );
         );
 
 
         return data.data;
         return data.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'begin passkey authentication failed');
+        logError(e, "begin passkey authentication failed");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -150,7 +150,7 @@ export const beginPasskeyAuthentication = async (
 export const finishPasskeyAuthentication = async (
 export const finishPasskeyAuthentication = async (
     credential: Credential,
     credential: Credential,
     sessionId: string,
     sessionId: string,
-    ceremonySessionId: string
+    ceremonySessionId: string,
 ) => {
 ) => {
     try {
     try {
         const data = await HTTPService.post(
         const data = await HTTPService.post(
@@ -164,37 +164,37 @@ export const finishPasskeyAuthentication = async (
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // @ts-ignore
                         // @ts-ignore
                         new Uint8Array(credential.response.authenticatorData),
                         new Uint8Array(credential.response.authenticatorData),
-                        _sodium.base64_variants.URLSAFE_NO_PADDING
+                        _sodium.base64_variants.URLSAFE_NO_PADDING,
                     ),
                     ),
                     clientDataJSON: _sodium.to_base64(
                     clientDataJSON: _sodium.to_base64(
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // @ts-ignore
                         // @ts-ignore
                         new Uint8Array(credential.response.clientDataJSON),
                         new Uint8Array(credential.response.clientDataJSON),
-                        _sodium.base64_variants.URLSAFE_NO_PADDING
+                        _sodium.base64_variants.URLSAFE_NO_PADDING,
                     ),
                     ),
                     signature: _sodium.to_base64(
                     signature: _sodium.to_base64(
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // @ts-ignore
                         // @ts-ignore
                         new Uint8Array(credential.response.signature),
                         new Uint8Array(credential.response.signature),
-                        _sodium.base64_variants.URLSAFE_NO_PADDING
+                        _sodium.base64_variants.URLSAFE_NO_PADDING,
                     ),
                     ),
                     userHandle: _sodium.to_base64(
                     userHandle: _sodium.to_base64(
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                         // @ts-ignore
                         // @ts-ignore
                         new Uint8Array(credential.response.userHandle),
                         new Uint8Array(credential.response.userHandle),
-                        _sodium.base64_variants.URLSAFE_NO_PADDING
+                        _sodium.base64_variants.URLSAFE_NO_PADDING,
                     ),
                     ),
                 },
                 },
             },
             },
             {
             {
                 sessionID: sessionId,
                 sessionID: sessionId,
                 ceremonySessionID: ceremonySessionId,
                 ceremonySessionID: ceremonySessionId,
-            }
+            },
         );
         );
 
 
         return data.data;
         return data.data;
     } catch (e) {
     } catch (e) {
-        logError(e, 'finish passkey authentication failed');
+        logError(e, "finish passkey authentication failed");
         throw e;
         throw e;
     }
     }
 };
 };

+ 12 - 12
apps/accounts/src/styles/global.css

@@ -1,39 +1,39 @@
 /* inter-regular - latin */
 /* inter-regular - latin */
 @font-face {
 @font-face {
-    font-family: 'Inter';
+    font-family: "Inter";
     font-style: normal;
     font-style: normal;
     font-weight: 400;
     font-weight: 400;
     src:
     src:
-        local(''),
-        url('/fonts/inter-v11-latin-500.woff2') format('woff2'),
+        local(""),
+        url("/fonts/inter-v11-latin-500.woff2") format("woff2"),
         /* Chrome 26+, Opera 23+, Firefox 39+ */
         /* Chrome 26+, Opera 23+, Firefox 39+ */
-            url('/fonts/inter-v11-latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+            url("/fonts/inter-v11-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
     font-display: swap; /*https://web.dev/font-display/?utm_source=lighthouse&utm_medium=devtools#how-to-avoid-showing-invisible-text*/
     font-display: swap; /*https://web.dev/font-display/?utm_source=lighthouse&utm_medium=devtools#how-to-avoid-showing-invisible-text*/
 }
 }
 
 
 /* inter-600 - latin */
 /* inter-600 - latin */
 @font-face {
 @font-face {
-    font-family: 'Inter';
+    font-family: "Inter";
     font-style: normal;
     font-style: normal;
     font-weight: 700;
     font-weight: 700;
     src:
     src:
-        local(''),
-        url('/fonts/inter-v11-latin-600.woff2') format('woff2'),
+        local(""),
+        url("/fonts/inter-v11-latin-600.woff2") format("woff2"),
         /* Chrome 26+, Opera 23+, Firefox 39+ */
         /* Chrome 26+, Opera 23+, Firefox 39+ */
-            url('/fonts/inter-v11-latin-600.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+            url("/fonts/inter-v11-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
     font-display: swap;
     font-display: swap;
 }
 }
 
 
 /* inter-800 - latin */
 /* inter-800 - latin */
 @font-face {
 @font-face {
-    font-family: 'Inter';
+    font-family: "Inter";
     font-style: normal;
     font-style: normal;
     font-weight: 900;
     font-weight: 900;
     src:
     src:
-        local(''),
-        url('/fonts/inter-v11-latin-800.woff2') format('woff2'),
+        local(""),
+        url("/fonts/inter-v11-latin-800.woff2") format("woff2"),
         /* Chrome 26+, Opera 23+, Firefox 39+ */
         /* Chrome 26+, Opera 23+, Firefox 39+ */
-            url('/fonts/inter-v11-latin-800.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+            url("/fonts/inter-v11-latin-800.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
     font-display: swap;
     font-display: swap;
 }
 }
 
 

+ 4 - 4
apps/auth/.eslintrc.js

@@ -3,11 +3,11 @@ module.exports = {
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // packaged as a submodule.
     // packaged as a submodule.
     root: true,
     root: true,
-    extends: ['@ente/eslint-config'],
-    parser: '@typescript-eslint/parser',
+    extends: ["@ente/eslint-config"],
+    parser: "@typescript-eslint/parser",
     parserOptions: {
     parserOptions: {
         tsconfigRootDir: __dirname,
         tsconfigRootDir: __dirname,
-        project: './tsconfig.json',
+        project: "./tsconfig.json",
     },
     },
-    ignorePatterns: ['.eslintrc.js', 'out'],
+    ignorePatterns: [".eslintrc.js", "out"],
 };
 };

+ 1 - 1
apps/auth/next.config.js

@@ -1,3 +1,3 @@
-const nextConfigBase = require('@/next/next.config.base.js');
+const nextConfigBase = require("@/next/next.config.base.js");
 
 
 module.exports = nextConfigBase;
 module.exports = nextConfigBase;

+ 2 - 2
apps/auth/sentry.client.config.ts

@@ -1,3 +1,3 @@
-import { initSentry } from '@ente/shared/sentry/config/sentry.config.base';
+import { initSentry } from "@ente/shared/sentry/config/sentry.config.base";
 
 
-initSentry('https://5d344112b570b1a368b6f5c1d0bb798b@sentry.ente.io/8');
+initSentry("https://5d344112b570b1a368b6f5c1d0bb798b@sentry.ente.io/8");

+ 10 - 9
apps/auth/src/components/AuthFooter.tsx

@@ -1,18 +1,19 @@
-import { Button } from '@mui/material';
-import { t } from 'i18next';
+import { Button } from "@mui/material";
+import { t } from "i18next";
 
 
 export const AuthFooter = () => {
 export const AuthFooter = () => {
     return (
     return (
         <div
         <div
             style={{
             style={{
-                display: 'flex',
-                flexDirection: 'column',
-                alignItems: 'center',
-                justifyContent: 'center',
-            }}>
-            <p>{t('AUTH_DOWNLOAD_MOBILE_APP')}</p>
+                display: "flex",
+                flexDirection: "column",
+                alignItems: "center",
+                justifyContent: "center",
+            }}
+        >
+            <p>{t("AUTH_DOWNLOAD_MOBILE_APP")}</p>
             <a href="https://github.com/ente-io/auth#-download" download>
             <a href="https://github.com/ente-io/auth#-download" download>
-                <Button color="accent">{t('DOWNLOAD')}</Button>
+                <Button color="accent">{t("DOWNLOAD")}</Button>
             </a>
             </a>
         </div>
         </div>
     );
     );

+ 19 - 17
apps/auth/src/components/Navbar.tsx

@@ -1,31 +1,33 @@
-import { HorizontalFlex } from '@ente/shared/components/Container';
-import NavbarBase from '@ente/shared/components/Navbar/base';
-import React from 'react';
-import { t } from 'i18next';
-import { logoutUser } from '@ente/accounts/services/user';
-import { EnteLogo } from '@ente/shared/components/EnteLogo';
-import OverflowMenu from '@ente/shared/components/OverflowMenu/menu';
-import { OverflowMenuOption } from '@ente/shared/components/OverflowMenu/option';
-import MoreHoriz from '@mui/icons-material/MoreHoriz';
-import LogoutOutlined from '@mui/icons-material/LogoutOutlined';
-import { AppContext } from 'pages/_app';
+import { logoutUser } from "@ente/accounts/services/user";
+import { HorizontalFlex } from "@ente/shared/components/Container";
+import { EnteLogo } from "@ente/shared/components/EnteLogo";
+import NavbarBase from "@ente/shared/components/Navbar/base";
+import OverflowMenu from "@ente/shared/components/OverflowMenu/menu";
+import { OverflowMenuOption } from "@ente/shared/components/OverflowMenu/option";
+import LogoutOutlined from "@mui/icons-material/LogoutOutlined";
+import MoreHoriz from "@mui/icons-material/MoreHoriz";
+import { t } from "i18next";
+import { AppContext } from "pages/_app";
+import React from "react";
 
 
 export default function AuthNavbar() {
 export default function AuthNavbar() {
     const { isMobile } = React.useContext(AppContext);
     const { isMobile } = React.useContext(AppContext);
     return (
     return (
         <NavbarBase isMobile={isMobile}>
         <NavbarBase isMobile={isMobile}>
-            <HorizontalFlex flex={1} justifyContent={'center'}>
+            <HorizontalFlex flex={1} justifyContent={"center"}>
                 <EnteLogo />
                 <EnteLogo />
             </HorizontalFlex>
             </HorizontalFlex>
-            <HorizontalFlex position={'absolute'} right="24px">
+            <HorizontalFlex position={"absolute"} right="24px">
                 <OverflowMenu
                 <OverflowMenu
-                    ariaControls={'auth-options'}
-                    triggerButtonIcon={<MoreHoriz />}>
+                    ariaControls={"auth-options"}
+                    triggerButtonIcon={<MoreHoriz />}
+                >
                     <OverflowMenuOption
                     <OverflowMenuOption
                         color="critical"
                         color="critical"
                         startIcon={<LogoutOutlined />}
                         startIcon={<LogoutOutlined />}
-                        onClick={logoutUser}>
-                        {t('LOGOUT')}
+                        onClick={logoutUser}
+                    >
+                        {t("LOGOUT")}
                     </OverflowMenuOption>
                     </OverflowMenuOption>
                 </OverflowMenu>
                 </OverflowMenu>
             </HorizontalFlex>
             </HorizontalFlex>

+ 86 - 76
apps/auth/src/components/OTPDisplay.tsx

@@ -1,98 +1,107 @@
-import React, { useState, useEffect } from 'react';
-import { TOTP, HOTP } from 'otpauth';
-import { Code } from 'types/code';
-import TimerProgress from './TimerProgress';
-import { t } from 'i18next';
-import { ButtonBase, Snackbar } from '@mui/material';
+import { ButtonBase, Snackbar } from "@mui/material";
+import { t } from "i18next";
+import { HOTP, TOTP } from "otpauth";
+import { useEffect, useState } from "react";
+import { Code } from "types/code";
+import TimerProgress from "./TimerProgress";
 
 
 const TOTPDisplay = ({ issuer, account, code, nextCode, period }) => {
 const TOTPDisplay = ({ issuer, account, code, nextCode, period }) => {
     return (
     return (
         <div
         <div
             style={{
             style={{
-                backgroundColor: 'rgba(40, 40, 40, 0.6)',
-                borderRadius: '4px',
-                overflow: 'hidden',
-            }}>
+                backgroundColor: "rgba(40, 40, 40, 0.6)",
+                borderRadius: "4px",
+                overflow: "hidden",
+            }}
+        >
             <TimerProgress period={period ?? Code.defaultPeriod} />
             <TimerProgress period={period ?? Code.defaultPeriod} />
             <div
             <div
                 style={{
                 style={{
-                    padding: '12px 20px 0px 20px',
-                    display: 'flex',
-                    alignItems: 'flex-start',
-                    minWidth: '320px',
-                    minHeight: '120px',
-                    justifyContent: 'space-between',
-                }}>
+                    padding: "12px 20px 0px 20px",
+                    display: "flex",
+                    alignItems: "flex-start",
+                    minWidth: "320px",
+                    minHeight: "120px",
+                    justifyContent: "space-between",
+                }}
+            >
                 <div
                 <div
                     style={{
                     style={{
-                        display: 'flex',
-                        flexDirection: 'column',
-                        alignItems: 'flex-start',
-                        minWidth: '200px',
-                    }}>
+                        display: "flex",
+                        flexDirection: "column",
+                        alignItems: "flex-start",
+                        minWidth: "200px",
+                    }}
+                >
                     <p
                     <p
                         style={{
                         style={{
-                            fontWeight: 'bold',
-                            margin: '0px',
-                            fontSize: '14px',
-                            textAlign: 'left',
-                        }}>
+                            fontWeight: "bold",
+                            margin: "0px",
+                            fontSize: "14px",
+                            textAlign: "left",
+                        }}
+                    >
                         {issuer}
                         {issuer}
                     </p>
                     </p>
                     <p
                     <p
                         style={{
                         style={{
-                            marginTop: '0px',
-                            marginBottom: '8px',
-                            textAlign: 'left',
-                            fontSize: '12px',
-                            maxWidth: '200px',
-                            minHeight: '16px',
-                            color: 'grey',
-                        }}>
+                            marginTop: "0px",
+                            marginBottom: "8px",
+                            textAlign: "left",
+                            fontSize: "12px",
+                            maxWidth: "200px",
+                            minHeight: "16px",
+                            color: "grey",
+                        }}
+                    >
                         {account}
                         {account}
                     </p>
                     </p>
                     <p
                     <p
                         style={{
                         style={{
-                            margin: '0px',
-                            marginBottom: '1rem',
-                            fontSize: '24px',
-                            fontWeight: 'bold',
-                            textAlign: 'left',
-                        }}>
+                            margin: "0px",
+                            marginBottom: "1rem",
+                            fontSize: "24px",
+                            fontWeight: "bold",
+                            textAlign: "left",
+                        }}
+                    >
                         {code}
                         {code}
                     </p>
                     </p>
                 </div>
                 </div>
                 <div style={{ flex: 1 }} />
                 <div style={{ flex: 1 }} />
                 <div
                 <div
                     style={{
                     style={{
-                        display: 'flex',
-                        flexDirection: 'column',
-                        alignItems: 'flex-end',
-                        minWidth: '120px',
-                        textAlign: 'right',
-                        marginTop: 'auto',
-                        marginBottom: '1rem',
-                    }}>
+                        display: "flex",
+                        flexDirection: "column",
+                        alignItems: "flex-end",
+                        minWidth: "120px",
+                        textAlign: "right",
+                        marginTop: "auto",
+                        marginBottom: "1rem",
+                    }}
+                >
                     <p
                     <p
                         style={{
                         style={{
-                            fontWeight: 'bold',
-                            marginBottom: '0px',
-                            fontSize: '10px',
-                            marginTop: 'auto',
-                            textAlign: 'right',
-                            color: 'grey',
-                        }}>
-                        {t('AUTH_NEXT')}
+                            fontWeight: "bold",
+                            marginBottom: "0px",
+                            fontSize: "10px",
+                            marginTop: "auto",
+                            textAlign: "right",
+                            color: "grey",
+                        }}
+                    >
+                        {t("AUTH_NEXT")}
                     </p>
                     </p>
                     <p
                     <p
                         style={{
                         style={{
-                            fontSize: '14px',
-                            fontWeight: 'bold',
-                            marginBottom: '0px',
-                            marginTop: 'auto',
-                            textAlign: 'right',
-                            color: 'grey',
-                        }}>
+                            fontSize: "14px",
+                            fontWeight: "bold",
+                            marginBottom: "0px",
+                            marginTop: "auto",
+                            textAlign: "right",
+                            color: "grey",
+                        }}
+                    >
                         {nextCode}
                         {nextCode}
                     </p>
                     </p>
                 </div>
                 </div>
@@ -111,7 +120,7 @@ function BadCodeInfo({ codeInfo, codeErr }) {
             <div>
             <div>
                 {showRawData ? (
                 {showRawData ? (
                     <div onClick={() => setShowRawData(false)}>
                     <div onClick={() => setShowRawData(false)}>
-                        {codeInfo.rawData ?? 'no raw data'}
+                        {codeInfo.rawData ?? "no raw data"}
                     </div>
                     </div>
                 ) : (
                 ) : (
                     <div onClick={() => setShowRawData(true)}>Show rawData</div>
                     <div onClick={() => setShowRawData(true)}>Show rawData</div>
@@ -127,15 +136,15 @@ interface OTPDisplayProps {
 
 
 const OTPDisplay = (props: OTPDisplayProps) => {
 const OTPDisplay = (props: OTPDisplayProps) => {
     const { codeInfo } = props;
     const { codeInfo } = props;
-    const [code, setCode] = useState('');
-    const [nextCode, setNextCode] = useState('');
-    const [codeErr, setCodeErr] = useState('');
+    const [code, setCode] = useState("");
+    const [nextCode, setNextCode] = useState("");
+    const [codeErr, setCodeErr] = useState("");
     const [hasCopied, setHasCopied] = useState(false);
     const [hasCopied, setHasCopied] = useState(false);
 
 
     const generateCodes = () => {
     const generateCodes = () => {
         try {
         try {
             const currentTime = new Date().getTime();
             const currentTime = new Date().getTime();
-            if (codeInfo.type.toLowerCase() === 'totp') {
+            if (codeInfo.type.toLowerCase() === "totp") {
                 const totp = new TOTP({
                 const totp = new TOTP({
                     secret: codeInfo.secret,
                     secret: codeInfo.secret,
                     algorithm: codeInfo.algorithm ?? Code.defaultAlgo,
                     algorithm: codeInfo.algorithm ?? Code.defaultAlgo,
@@ -146,9 +155,9 @@ const OTPDisplay = (props: OTPDisplayProps) => {
                 setNextCode(
                 setNextCode(
                     totp.generate({
                     totp.generate({
                         timestamp: currentTime + codeInfo.period * 1000,
                         timestamp: currentTime + codeInfo.period * 1000,
-                    })
+                    }),
                 );
                 );
-            } else if (codeInfo.type.toLowerCase() === 'hotp') {
+            } else if (codeInfo.type.toLowerCase() === "hotp") {
                 const hotp = new HOTP({
                 const hotp = new HOTP({
                     secret: codeInfo.secret,
                     secret: codeInfo.secret,
                     counter: 0,
                     counter: 0,
@@ -184,8 +193,8 @@ const OTPDisplay = (props: OTPDisplayProps) => {
             // we need to call generateCodes() once before the interval loop
             // we need to call generateCodes() once before the interval loop
             // to set the initial code and nextCode
             // to set the initial code and nextCode
             generateCodes();
             generateCodes();
-            codeType.toLowerCase() === 'totp' ||
-            codeType.toLowerCase() === 'hotp'
+            codeType.toLowerCase() === "totp" ||
+            codeType.toLowerCase() === "hotp"
                 ? setInterval(() => {
                 ? setInterval(() => {
                       generateCodes();
                       generateCodes();
                   }, codePeriodInMs)
                   }, codePeriodInMs)
@@ -198,13 +207,14 @@ const OTPDisplay = (props: OTPDisplayProps) => {
     }, [codeInfo]);
     }, [codeInfo]);
 
 
     return (
     return (
-        <div style={{ padding: '8px' }}>
-            {codeErr === '' ? (
+        <div style={{ padding: "8px" }}>
+            {codeErr === "" ? (
                 <ButtonBase
                 <ButtonBase
                     component="div"
                     component="div"
                     onClick={() => {
                     onClick={() => {
                         copyCode();
                         copyCode();
-                    }}>
+                    }}
+                >
                     <TOTPDisplay
                     <TOTPDisplay
                         period={codeInfo.period}
                         period={codeInfo.period}
                         issuer={codeInfo.issuer}
                         issuer={codeInfo.issuer}

+ 4 - 4
apps/auth/src/components/TimerProgress.tsx

@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import { useEffect, useState } from "react";
 
 
 const TimerProgress = ({ period }) => {
 const TimerProgress = ({ period }) => {
     const [progress, setProgress] = useState(0);
     const [progress, setProgress] = useState(0);
@@ -24,14 +24,14 @@ const TimerProgress = ({ period }) => {
         return () => clearInterval(ticker);
         return () => clearInterval(ticker);
     }, []);
     }, []);
 
 
-    const color = progress > 0.4 ? 'green' : 'orange';
+    const color = progress > 0.4 ? "green" : "orange";
 
 
     return (
     return (
         <div
         <div
             style={{
             style={{
-                borderTopLeftRadius: '3px',
+                borderTopLeftRadius: "3px",
                 width: `${progress * 100}%`,
                 width: `${progress * 100}%`,
-                height: '3px',
+                height: "3px",
                 backgroundColor: color,
                 backgroundColor: color,
             }}
             }}
         />
         />

+ 5 - 5
apps/auth/src/pages/404.tsx

@@ -1,8 +1,8 @@
-import NotFoundPage from '@ente/shared/next/pages/404';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import { APPS } from "@ente/shared/apps/constants";
+import NotFoundPage from "@ente/shared/next/pages/404";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function NotFound() {
 export default function NotFound() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 55 - 53
apps/auth/src/pages/_app.tsx

@@ -1,42 +1,42 @@
-import React, { createContext, useEffect, useRef, useState } from 'react';
-import AppNavbar from '@ente/shared/components/Navbar/app';
-import { t } from 'i18next';
-
-import { useRouter } from 'next/router';
-import { Overlay } from '@ente/shared/components/Container';
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import { LS_KEYS } from '@ente/shared/storage/localStorage';
-import HTTPService from '@ente/shared/network/HTTPService';
-import Head from 'next/head';
-import LoadingBar from 'react-top-loading-bar';
-import DialogBoxV2 from '@ente/shared/components/DialogBoxV2';
-import { ThemeProvider } from '@mui/material/styles';
-import { MessageContainer } from '@ente/shared/components/MessageContainer';
-import { CssBaseline, useMediaQuery } from '@mui/material';
+import AppNavbar from "@ente/shared/components/Navbar/app";
+import { t } from "i18next";
+import { createContext, useEffect, useRef, useState } from "react";
+
+import { Overlay } from "@ente/shared/components/Container";
+import DialogBoxV2 from "@ente/shared/components/DialogBoxV2";
 import {
 import {
     DialogBoxAttributesV2,
     DialogBoxAttributesV2,
     SetDialogBoxAttributesV2,
     SetDialogBoxAttributesV2,
-} from '@ente/shared/components/DialogBoxV2/types';
+} from "@ente/shared/components/DialogBoxV2/types";
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import { MessageContainer } from "@ente/shared/components/MessageContainer";
 import {
 import {
     clearLogsIfLocalStorageLimitExceeded,
     clearLogsIfLocalStorageLimitExceeded,
     logStartupMessage,
     logStartupMessage,
-} from '@ente/shared/logging/web';
-
-import { CacheProvider } from '@emotion/react';
+} from "@ente/shared/logging/web";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { LS_KEYS } from "@ente/shared/storage/localStorage";
+import { CssBaseline, useMediaQuery } from "@mui/material";
+import { ThemeProvider } from "@mui/material/styles";
+import Head from "next/head";
+import { useRouter } from "next/router";
+import LoadingBar from "react-top-loading-bar";
+
+import { setupI18n } from "@/ui/i18n";
+import { CacheProvider } from "@emotion/react";
 import {
 import {
     APP_TITLES,
     APP_TITLES,
     APPS,
     APPS,
     CLIENT_PACKAGE_NAMES,
     CLIENT_PACKAGE_NAMES,
-} from '@ente/shared/apps/constants';
-import { EnteAppProps } from '@ente/shared/apps/types';
-import createEmotionCache from '@ente/shared/themes/createEmotionCache';
-import { THEME_COLOR } from '@ente/shared/themes/constants';
-import { SetTheme } from '@ente/shared/themes/types';
-import { setupI18n } from '@/ui/i18n';
-import { useLocalState } from '@ente/shared/hooks/useLocalState';
-import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
-import { getTheme } from '@ente/shared/themes';
-import '../../public/css/global.css';
+} from "@ente/shared/apps/constants";
+import { EnteAppProps } from "@ente/shared/apps/types";
+import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
+import { useLocalState } from "@ente/shared/hooks/useLocalState";
+import { getTheme } from "@ente/shared/themes";
+import { THEME_COLOR } from "@ente/shared/themes/constants";
+import createEmotionCache from "@ente/shared/themes/createEmotionCache";
+import { SetTheme } from "@ente/shared/themes/types";
+import "../../public/css/global.css";
 
 
 type AppContextType = {
 type AppContextType = {
     showNavBar: (show: boolean) => void;
     showNavBar: (show: boolean) => void;
@@ -64,7 +64,7 @@ export default function App(props: EnteAppProps) {
     const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
     const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
     const [loading, setLoading] = useState(false);
     const [loading, setLoading] = useState(false);
     const [offline, setOffline] = useState(
     const [offline, setOffline] = useState(
-        typeof window !== 'undefined' && !window.navigator.onLine
+        typeof window !== "undefined" && !window.navigator.onLine,
     );
     );
     const [showNavbar, setShowNavBar] = useState(false);
     const [showNavbar, setShowNavBar] = useState(false);
     const isLoadingBarRunning = useRef(false);
     const isLoadingBarRunning = useRef(false);
@@ -72,10 +72,10 @@ export default function App(props: EnteAppProps) {
     const [dialogBoxAttributeV2, setDialogBoxAttributesV2] =
     const [dialogBoxAttributeV2, setDialogBoxAttributesV2] =
         useState<DialogBoxAttributesV2>();
         useState<DialogBoxAttributesV2>();
     const [dialogBoxV2View, setDialogBoxV2View] = useState(false);
     const [dialogBoxV2View, setDialogBoxV2View] = useState(false);
-    const isMobile = useMediaQuery('(max-width:428px)');
+    const isMobile = useMediaQuery("(max-width:428px)");
     const [themeColor, setThemeColor] = useLocalState(
     const [themeColor, setThemeColor] = useLocalState(
         LS_KEYS.THEME,
         LS_KEYS.THEME,
-        THEME_COLOR.DARK
+        THEME_COLOR.DARK,
     );
     );
 
 
     useEffect(() => {
     useEffect(() => {
@@ -83,7 +83,7 @@ export default function App(props: EnteAppProps) {
         setupI18n().finally(() => setIsI18nReady(true));
         setupI18n().finally(() => setIsI18nReady(true));
         // set client package name in headers
         // set client package name in headers
         HTTPService.setHeaders({
         HTTPService.setHeaders({
-            'X-Client-Package': CLIENT_PACKAGE_NAMES.get(APPS.AUTH),
+            "X-Client-Package": CLIENT_PACKAGE_NAMES.get(APPS.AUTH),
         });
         });
         // setup logging
         // setup logging
         clearLogsIfLocalStorageLimitExceeded();
         clearLogsIfLocalStorageLimitExceeded();
@@ -96,31 +96,31 @@ export default function App(props: EnteAppProps) {
     useEffect(() => {
     useEffect(() => {
         if (isI18nReady) {
         if (isI18nReady) {
             console.log(
             console.log(
-                `%c${t('CONSOLE_WARNING_STOP')}`,
-                'color: red; font-size: 52px;'
+                `%c${t("CONSOLE_WARNING_STOP")}`,
+                "color: red; font-size: 52px;",
             );
             );
-            console.log(`%c${t('CONSOLE_WARNING_DESC')}`, 'font-size: 20px;');
+            console.log(`%c${t("CONSOLE_WARNING_DESC")}`, "font-size: 20px;");
         }
         }
     }, [isI18nReady]);
     }, [isI18nReady]);
 
 
     useEffect(() => {
     useEffect(() => {
-        router.events.on('routeChangeStart', (url: string) => {
-            const newPathname = url.split('?')[0] as PAGES;
+        router.events.on("routeChangeStart", (url: string) => {
+            const newPathname = url.split("?")[0] as PAGES;
             if (window.location.pathname !== newPathname) {
             if (window.location.pathname !== newPathname) {
                 setLoading(true);
                 setLoading(true);
             }
             }
         });
         });
 
 
-        router.events.on('routeChangeComplete', () => {
+        router.events.on("routeChangeComplete", () => {
             setLoading(false);
             setLoading(false);
         });
         });
 
 
-        window.addEventListener('online', setUserOnline);
-        window.addEventListener('offline', setUserOffline);
+        window.addEventListener("online", setUserOnline);
+        window.addEventListener("offline", setUserOffline);
 
 
         return () => {
         return () => {
-            window.removeEventListener('online', setUserOnline);
-            window.removeEventListener('offline', setUserOffline);
+            window.removeEventListener("online", setUserOnline);
+            window.removeEventListener("offline", setUserOffline);
         };
         };
     }, []);
     }, []);
 
 
@@ -145,9 +145,9 @@ export default function App(props: EnteAppProps) {
 
 
     const somethingWentWrong = () =>
     const somethingWentWrong = () =>
         setDialogBoxAttributesV2({
         setDialogBoxAttributesV2({
-            title: t('ERROR'),
-            close: { variant: 'critical' },
-            content: t('UNKNOWN_ERROR'),
+            title: t("ERROR"),
+            close: { variant: "critical" },
+            content: t("UNKNOWN_ERROR"),
         });
         });
 
 
     return (
     return (
@@ -155,7 +155,7 @@ export default function App(props: EnteAppProps) {
             <Head>
             <Head>
                 <title>
                 <title>
                     {isI18nReady
                     {isI18nReady
-                        ? t('TITLE', { context: APPS.AUTH })
+                        ? t("TITLE", { context: APPS.AUTH })
                         : APP_TITLES.get(APPS.AUTH)}
                         : APP_TITLES.get(APPS.AUTH)}
                 </title>
                 </title>
                 <meta
                 <meta
@@ -168,7 +168,7 @@ export default function App(props: EnteAppProps) {
                 <CssBaseline enableColorScheme />
                 <CssBaseline enableColorScheme />
                 {showNavbar && <AppNavbar isMobile={isMobile} />}
                 {showNavbar && <AppNavbar isMobile={isMobile} />}
                 <MessageContainer>
                 <MessageContainer>
-                    {offline && t('OFFLINE_MSG')}
+                    {offline && t("OFFLINE_MSG")}
                 </MessageContainer>
                 </MessageContainer>
 
 
                 <LoadingBar color="#51cd7c" ref={loadingBar} />
                 <LoadingBar color="#51cd7c" ref={loadingBar} />
@@ -190,16 +190,18 @@ export default function App(props: EnteAppProps) {
                         setThemeColor,
                         setThemeColor,
                         somethingWentWrong,
                         somethingWentWrong,
                         setDialogBoxAttributesV2,
                         setDialogBoxAttributesV2,
-                    }}>
+                    }}
+                >
                     {(loading || !isI18nReady) && (
                     {(loading || !isI18nReady) && (
                         <Overlay
                         <Overlay
                             sx={(theme) => ({
                             sx={(theme) => ({
-                                display: 'flex',
-                                justifyContent: 'center',
-                                alignItems: 'center',
+                                display: "flex",
+                                justifyContent: "center",
+                                alignItems: "center",
                                 zIndex: 2000,
                                 zIndex: 2000,
                                 backgroundColor: theme.colors.background.base,
                                 backgroundColor: theme.colors.background.base,
-                            })}>
+                            })}
+                        >
                             <EnteSpinner />
                             <EnteSpinner />
                         </Overlay>
                         </Overlay>
                     )}
                     )}

+ 1 - 1
apps/auth/src/pages/_document.tsx

@@ -1,6 +1,6 @@
 import DocumentPage, {
 import DocumentPage, {
     EnteDocumentProps,
     EnteDocumentProps,
-} from '@ente/shared/next/pages/_document';
+} from "@ente/shared/next/pages/_document";
 
 
 export default function Document(props: EnteDocumentProps) {
 export default function Document(props: EnteDocumentProps) {
     return <DocumentPage {...props} />;
     return <DocumentPage {...props} />;

+ 5 - 5
apps/auth/src/pages/_error.tsx

@@ -1,8 +1,8 @@
-import ErrorPage from '@ente/shared/next/pages/_error';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import { APPS } from "@ente/shared/apps/constants";
+import ErrorPage from "@ente/shared/next/pages/_error";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Error() {
 export default function Error() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 45 - 42
apps/auth/src/pages/auth/index.tsx

@@ -1,24 +1,24 @@
-import React, { useContext, useEffect, useState } from 'react';
-import OTPDisplay from 'components/OTPDisplay';
-import { getAuthCodes } from 'services';
-import { CustomError } from '@ente/shared/error';
-import { AUTH_PAGES as PAGES } from '@ente/shared/constants/pages';
-import { useRouter } from 'next/router';
-import { AuthFooter } from 'components/AuthFooter';
-import { AppContext } from 'pages/_app';
-import { TextField } from '@mui/material';
-import AuthNavbar from 'components/Navbar';
-import { t } from 'i18next';
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import { VerticallyCentered } from '@ente/shared/components/Container';
-import InMemoryStore, { MS_KEYS } from '@ente/shared/storage/InMemoryStore';
+import { VerticallyCentered } from "@ente/shared/components/Container";
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import { AUTH_PAGES as PAGES } from "@ente/shared/constants/pages";
+import { CustomError } from "@ente/shared/error";
+import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
+import { TextField } from "@mui/material";
+import { AuthFooter } from "components/AuthFooter";
+import AuthNavbar from "components/Navbar";
+import OTPDisplay from "components/OTPDisplay";
+import { t } from "i18next";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext, useEffect, useState } from "react";
+import { getAuthCodes } from "services";
 
 
 const AuthenticatorCodesPage = () => {
 const AuthenticatorCodesPage = () => {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);
     const router = useRouter();
     const router = useRouter();
     const [codes, setCodes] = useState([]);
     const [codes, setCodes] = useState([]);
     const [hasFetched, setHasFetched] = useState(false);
     const [hasFetched, setHasFetched] = useState(false);
-    const [searchTerm, setSearchTerm] = useState('');
+    const [searchTerm, setSearchTerm] = useState("");
 
 
     useEffect(() => {
     useEffect(() => {
         const fetchCodes = async () => {
         const fetchCodes = async () => {
@@ -41,12 +41,12 @@ const AuthenticatorCodesPage = () => {
 
 
     const filteredCodes = codes.filter(
     const filteredCodes = codes.filter(
         (secret) =>
         (secret) =>
-            (secret.issuer ?? '')
+            (secret.issuer ?? "")
                 .toLowerCase()
                 .toLowerCase()
                 .includes(searchTerm.toLowerCase()) ||
                 .includes(searchTerm.toLowerCase()) ||
-            (secret.account ?? '')
+            (secret.account ?? "")
                 .toLowerCase()
                 .toLowerCase()
-                .includes(searchTerm.toLowerCase())
+                .includes(searchTerm.toLowerCase()),
     );
     );
 
 
     if (!hasFetched) {
     if (!hasFetched) {
@@ -64,47 +64,50 @@ const AuthenticatorCodesPage = () => {
             <AuthNavbar />
             <AuthNavbar />
             <div
             <div
                 style={{
                 style={{
-                    maxWidth: '800px',
-                    display: 'flex',
-                    flexDirection: 'column',
-                    alignItems: 'center',
-                    justifyContent: 'center',
-                    margin: '0 auto',
-                }}>
-                <div style={{ marginBottom: '1rem' }} />
+                    maxWidth: "800px",
+                    display: "flex",
+                    flexDirection: "column",
+                    alignItems: "center",
+                    justifyContent: "center",
+                    margin: "0 auto",
+                }}
+            >
+                <div style={{ marginBottom: "1rem" }} />
                 {filteredCodes.length === 0 && searchTerm.length === 0 ? (
                 {filteredCodes.length === 0 && searchTerm.length === 0 ? (
                     <></>
                     <></>
                 ) : (
                 ) : (
                     <TextField
                     <TextField
                         id="search"
                         id="search"
                         name="search"
                         name="search"
-                        label={t('SEARCH')}
+                        label={t("SEARCH")}
                         onChange={(e) => setSearchTerm(e.target.value)}
                         onChange={(e) => setSearchTerm(e.target.value)}
                         variant="filled"
                         variant="filled"
-                        style={{ width: '350px' }}
+                        style={{ width: "350px" }}
                         value={searchTerm}
                         value={searchTerm}
                         autoFocus
                         autoFocus
                     />
                     />
                 )}
                 )}
 
 
-                <div style={{ marginBottom: '1rem' }} />
+                <div style={{ marginBottom: "1rem" }} />
                 <div
                 <div
                     style={{
                     style={{
-                        display: 'flex',
-                        flexDirection: 'row',
-                        flexWrap: 'wrap',
-                        justifyContent: 'center',
-                    }}>
+                        display: "flex",
+                        flexDirection: "row",
+                        flexWrap: "wrap",
+                        justifyContent: "center",
+                    }}
+                >
                     {filteredCodes.length === 0 ? (
                     {filteredCodes.length === 0 ? (
                         <div
                         <div
                             style={{
                             style={{
-                                alignItems: 'center',
-                                display: 'flex',
-                                textAlign: 'center',
-                                marginTop: '32px',
-                            }}>
+                                alignItems: "center",
+                                display: "flex",
+                                textAlign: "center",
+                                marginTop: "32px",
+                            }}
+                        >
                             {searchTerm.length !== 0 ? (
                             {searchTerm.length !== 0 ? (
-                                <p>{t('NO_RESULTS')}</p>
+                                <p>{t("NO_RESULTS")}</p>
                             ) : (
                             ) : (
                                 <div />
                                 <div />
                             )}
                             )}
@@ -115,9 +118,9 @@ const AuthenticatorCodesPage = () => {
                         ))
                         ))
                     )}
                     )}
                 </div>
                 </div>
-                <div style={{ marginBottom: '2rem' }} />
+                <div style={{ marginBottom: "2rem" }} />
                 <AuthFooter />
                 <AuthFooter />
-                <div style={{ marginBottom: '4rem' }} />
+                <div style={{ marginBottom: "4rem" }} />
             </div>
             </div>
             <style jsx>{`
             <style jsx>{`
                 @media (min-width: 800px) {
                 @media (min-width: 800px) {

+ 5 - 5
apps/auth/src/pages/change-email/index.tsx

@@ -1,8 +1,8 @@
-import ChangeEmailPage from '@ente/accounts/pages/change-email';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import ChangeEmailPage from "@ente/accounts/pages/change-email";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function ChangeEmail() {
 export default function ChangeEmail() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/change-password/index.tsx

@@ -1,8 +1,8 @@
-import ChangePasswordPage from '@ente/accounts/pages/change-password';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import ChangePasswordPage from "@ente/accounts/pages/change-password";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function ChangePassword() {
 export default function ChangePassword() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/credentials/index.tsx

@@ -1,8 +1,8 @@
-import CredentialPage from '@ente/accounts/pages/credentials';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import CredentialPage from "@ente/accounts/pages/credentials";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Credential() {
 export default function Credential() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/generate/index.tsx

@@ -1,8 +1,8 @@
-import GeneratePage from '@ente/accounts/pages/generate';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import GeneratePage from "@ente/accounts/pages/generate";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Generate() {
 export default function Generate() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 3 - 3
apps/auth/src/pages/index.tsx

@@ -1,6 +1,6 @@
-import { PHOTOS_PAGES as PAGES } from '@ente/shared/constants/pages';
-import { useRouter } from 'next/router';
-import { useEffect } from 'react';
+import { PHOTOS_PAGES as PAGES } from "@ente/shared/constants/pages";
+import { useRouter } from "next/router";
+import { useEffect } from "react";
 
 
 const IndexPage = () => {
 const IndexPage = () => {
     const router = useRouter();
     const router = useRouter();

+ 5 - 5
apps/auth/src/pages/login/index.tsx

@@ -1,8 +1,8 @@
-import LoginPage from '@ente/accounts/pages/login';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import LoginPage from "@ente/accounts/pages/login";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Login() {
 export default function Login() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/recover/index.tsx

@@ -1,8 +1,8 @@
-import RecoverPage from '@ente/accounts/pages/recover';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import RecoverPage from "@ente/accounts/pages/recover";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Recover() {
 export default function Recover() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/signup/index.tsx

@@ -1,8 +1,8 @@
-import SignupPage from '@ente/accounts/pages/signup';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import SignupPage from "@ente/accounts/pages/signup";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Sigup() {
 export default function Sigup() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/two-factor/recover/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorRecoverPage from '@ente/accounts/pages/two-factor/recover';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorRecoverPage from "@ente/accounts/pages/two-factor/recover";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorRecover() {
 export default function TwoFactorRecover() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/two-factor/setup/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorSetupPage from '@ente/accounts/pages/two-factor/setup';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorSetupPage from "@ente/accounts/pages/two-factor/setup";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorSetup() {
 export default function TwoFactorSetup() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/two-factor/verify/index.tsx

@@ -1,8 +1,8 @@
-import TwoFactorVerifyPage from '@ente/accounts/pages/two-factor/verify';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import TwoFactorVerifyPage from "@ente/accounts/pages/two-factor/verify";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function TwoFactorVerify() {
 export default function TwoFactorVerify() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 5 - 5
apps/auth/src/pages/verify/index.tsx

@@ -1,8 +1,8 @@
-import VerifyPage from '@ente/accounts/pages/verify';
-import { useRouter } from 'next/router';
-import { AppContext } from 'pages/_app';
-import { useContext } from 'react';
-import { APPS } from '@ente/shared/apps/constants';
+import VerifyPage from "@ente/accounts/pages/verify";
+import { APPS } from "@ente/shared/apps/constants";
+import { useRouter } from "next/router";
+import { AppContext } from "pages/_app";
+import { useContext } from "react";
 
 
 export default function Verify() {
 export default function Verify() {
     const appContext = useContext(AppContext);
     const appContext = useContext(AppContext);

+ 24 - 24
apps/auth/src/services/index.ts

@@ -1,13 +1,13 @@
-import { HttpStatusCode } from 'axios';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { AuthEntity, AuthKey } from 'types/api';
-import { Code } from 'types/code';
-import ComlinkCryptoWorker from '@ente/shared/crypto';
-import { getEndpoint } from '@ente/shared/network/api';
-import { getActualKey } from '@ente/shared/user';
-import { getToken } from '@ente/shared/storage/localStorage/helpers';
-import { ApiError, CustomError } from '@ente/shared/error';
-import { logError } from '@ente/shared/sentry';
+import ComlinkCryptoWorker from "@ente/shared/crypto";
+import { ApiError, CustomError } from "@ente/shared/error";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { getEndpoint } from "@ente/shared/network/api";
+import { logError } from "@ente/shared/sentry";
+import { getToken } from "@ente/shared/storage/localStorage/helpers";
+import { getActualKey } from "@ente/shared/user";
+import { HttpStatusCode } from "axios";
+import { AuthEntity, AuthKey } from "types/api";
+import { Code } from "types/code";
 
 
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
 export const getAuthCodes = async (): Promise<Code[]> => {
 export const getAuthCodes = async (): Promise<Code[]> => {
@@ -18,7 +18,7 @@ export const getAuthCodes = async (): Promise<Code[]> => {
         const authenticatorKey = await cryptoWorker.decryptB64(
         const authenticatorKey = await cryptoWorker.decryptB64(
             authKeyData.encryptedKey,
             authKeyData.encryptedKey,
             authKeyData.header,
             authKeyData.header,
-            masterKey
+            masterKey,
         );
         );
         // always fetch all data from server for now
         // always fetch all data from server for now
         const authEntity: AuthEntity[] = await getDiff(0);
         const authEntity: AuthEntity[] = await getDiff(0);
@@ -31,21 +31,21 @@ export const getAuthCodes = async (): Promise<Code[]> => {
                             await cryptoWorker.decryptMetadata(
                             await cryptoWorker.decryptMetadata(
                                 entity.encryptedData,
                                 entity.encryptedData,
                                 entity.header,
                                 entity.header,
-                                authenticatorKey
+                                authenticatorKey,
                             );
                             );
                         return Code.fromRawData(entity.id, decryptedCode);
                         return Code.fromRawData(entity.id, decryptedCode);
                     } catch (e) {
                     } catch (e) {
                         logError(
                         logError(
-                            Error('failed to parse code'),
-                            'codeId = ' + entity.id
+                            Error("failed to parse code"),
+                            "codeId = " + entity.id,
                         );
                         );
                         return null;
                         return null;
                     }
                     }
-                })
+                }),
         );
         );
         // Remove null and undefined values
         // Remove null and undefined values
         const filteredAuthCodes = authCodes.filter(
         const filteredAuthCodes = authCodes.filter(
-            (f) => f !== null && f !== undefined
+            (f) => f !== null && f !== undefined,
         );
         );
         filteredAuthCodes.sort((a, b) => {
         filteredAuthCodes.sort((a, b) => {
             if (a.issuer && b.issuer) {
             if (a.issuer && b.issuer) {
@@ -62,7 +62,7 @@ export const getAuthCodes = async (): Promise<Code[]> => {
         return filteredAuthCodes;
         return filteredAuthCodes;
     } catch (e) {
     } catch (e) {
         if (e.message !== CustomError.AUTH_KEY_NOT_FOUND) {
         if (e.message !== CustomError.AUTH_KEY_NOT_FOUND) {
-            logError(e, 'get authenticator entities failed');
+            logError(e, "get authenticator entities failed");
         }
         }
         throw e;
         throw e;
     }
     }
@@ -74,8 +74,8 @@ export const getAuthKey = async (): Promise<AuthKey> => {
             `${ENDPOINT}/authenticator/key`,
             `${ENDPOINT}/authenticator/key`,
             {},
             {},
             {
             {
-                'X-Auth-Token': getToken(),
-            }
+                "X-Auth-Token": getToken(),
+            },
         );
         );
         return resp.data;
         return resp.data;
     } catch (e) {
     } catch (e) {
@@ -85,7 +85,7 @@ export const getAuthKey = async (): Promise<AuthKey> => {
         ) {
         ) {
             throw Error(CustomError.AUTH_KEY_NOT_FOUND);
             throw Error(CustomError.AUTH_KEY_NOT_FOUND);
         } else {
         } else {
-            logError(e, 'Get key failed');
+            logError(e, "Get key failed");
             throw e;
             throw e;
         }
         }
     }
     }
@@ -94,7 +94,7 @@ export const getAuthKey = async (): Promise<AuthKey> => {
 // return a promise which resolves to list of AuthEnitity
 // return a promise which resolves to list of AuthEnitity
 export const getDiff = async (
 export const getDiff = async (
     sinceTime: number,
     sinceTime: number,
-    limit = 2500
+    limit = 2500,
 ): Promise<AuthEntity[]> => {
 ): Promise<AuthEntity[]> => {
     try {
     try {
         const resp = await HTTPService.get(
         const resp = await HTTPService.get(
@@ -104,12 +104,12 @@ export const getDiff = async (
                 limit,
                 limit,
             },
             },
             {
             {
-                'X-Auth-Token': getToken(),
-            }
+                "X-Auth-Token": getToken(),
+            },
         );
         );
         return resp.data.diff;
         return resp.data.diff;
     } catch (e) {
     } catch (e) {
-        logError(e, 'Get diff failed');
+        logError(e, "Get diff failed");
         throw e;
         throw e;
     }
     }
 };
 };

+ 50 - 50
apps/auth/src/types/code.ts

@@ -1,18 +1,18 @@
-import { URI } from 'vscode-uri';
+import { URI } from "vscode-uri";
 
 
-type Type = 'totp' | 'TOTP' | 'hotp' | 'HOTP';
+type Type = "totp" | "TOTP" | "hotp" | "HOTP";
 
 
 type AlgorithmType =
 type AlgorithmType =
-    | 'sha1'
-    | 'SHA1'
-    | 'sha256'
-    | 'SHA256'
-    | 'sha512'
-    | 'SHA512';
+    | "sha1"
+    | "SHA1"
+    | "sha256"
+    | "SHA256"
+    | "sha512"
+    | "SHA512";
 
 
 export class Code {
 export class Code {
     static readonly defaultDigits = 6;
     static readonly defaultDigits = 6;
-    static readonly defaultAlgo = 'sha1';
+    static readonly defaultAlgo = "sha1";
     static readonly defaultPeriod = 30;
     static readonly defaultPeriod = 30;
 
 
     // id for the corresponding auth entity
     // id for the corresponding auth entity
@@ -35,7 +35,7 @@ export class Code {
         algorithm: AlgorithmType,
         algorithm: AlgorithmType,
         type: Type,
         type: Type,
         rawData?: string,
         rawData?: string,
-        id?: string
+        id?: string,
     ) {
     ) {
         this.account = account;
         this.account = account;
         this.issuer = issuer;
         this.issuer = issuer;
@@ -50,36 +50,36 @@ export class Code {
 
 
     static fromRawData(id: string, rawData: string): Code {
     static fromRawData(id: string, rawData: string): Code {
         let santizedRawData = rawData
         let santizedRawData = rawData
-            .replace(/\+/g, '%2B')
-            .replace(/:/g, '%3A')
-            .replaceAll('\r', '');
+            .replace(/\+/g, "%2B")
+            .replace(/:/g, "%3A")
+            .replaceAll("\r", "");
         if (santizedRawData.startsWith('"')) {
         if (santizedRawData.startsWith('"')) {
             santizedRawData = santizedRawData.substring(1);
             santizedRawData = santizedRawData.substring(1);
         }
         }
         if (santizedRawData.endsWith('"')) {
         if (santizedRawData.endsWith('"')) {
             santizedRawData = santizedRawData.substring(
             santizedRawData = santizedRawData.substring(
                 0,
                 0,
-                santizedRawData.length - 1
+                santizedRawData.length - 1,
             );
             );
         }
         }
 
 
         const uriParams = {};
         const uriParams = {};
         const searchParamsString =
         const searchParamsString =
-            decodeURIComponent(santizedRawData).split('?')[1];
-        searchParamsString.split('&').forEach((pair) => {
-            const [key, value] = pair.split('=');
+            decodeURIComponent(santizedRawData).split("?")[1];
+        searchParamsString.split("&").forEach((pair) => {
+            const [key, value] = pair.split("=");
             uriParams[key] = value;
             uriParams[key] = value;
         });
         });
 
 
         const uri = URI.parse(santizedRawData);
         const uri = URI.parse(santizedRawData);
         let uriPath = decodeURIComponent(uri.path);
         let uriPath = decodeURIComponent(uri.path);
         if (
         if (
-            uriPath.startsWith('/otpauth://') ||
-            uriPath.startsWith('otpauth://')
+            uriPath.startsWith("/otpauth://") ||
+            uriPath.startsWith("otpauth://")
         ) {
         ) {
-            uriPath = uriPath.split('otpauth://')[1];
-        } else if (uriPath.startsWith('otpauth%3A//')) {
-            uriPath = uriPath.split('otpauth%3A//')[1];
+            uriPath = uriPath.split("otpauth://")[1];
+        } else if (uriPath.startsWith("otpauth%3A//")) {
+            uriPath = uriPath.split("otpauth%3A//")[1];
         }
         }
 
 
         return new Code(
         return new Code(
@@ -91,54 +91,54 @@ export class Code {
             Code._getAlgorithm(uriParams),
             Code._getAlgorithm(uriParams),
             Code._getType(uriPath),
             Code._getType(uriPath),
             rawData,
             rawData,
-            id
+            id,
         );
         );
     }
     }
 
 
     private static _getAccount(uriPath: string): string {
     private static _getAccount(uriPath: string): string {
         try {
         try {
             const path = decodeURIComponent(uriPath);
             const path = decodeURIComponent(uriPath);
-            if (path.includes(':')) {
-                return path.split(':')[1];
-            } else if (path.includes('/')) {
-                return path.split('/')[1];
+            if (path.includes(":")) {
+                return path.split(":")[1];
+            } else if (path.includes("/")) {
+                return path.split("/")[1];
             }
             }
         } catch (e) {
         } catch (e) {
-            return '';
+            return "";
         }
         }
     }
     }
 
 
     private static _getIssuer(
     private static _getIssuer(
         uriPath: string,
         uriPath: string,
-        uriParams: { get?: any }
+        uriParams: { get?: any },
     ): string {
     ): string {
         try {
         try {
-            if (uriParams['issuer'] !== undefined) {
-                let issuer = uriParams['issuer'];
+            if (uriParams["issuer"] !== undefined) {
+                let issuer = uriParams["issuer"];
                 // This is to handle bug in the ente auth app
                 // This is to handle bug in the ente auth app
-                if (issuer.endsWith('period')) {
+                if (issuer.endsWith("period")) {
                     issuer = issuer.substring(0, issuer.length - 6);
                     issuer = issuer.substring(0, issuer.length - 6);
                 }
                 }
                 return issuer;
                 return issuer;
             }
             }
             let path = decodeURIComponent(uriPath);
             let path = decodeURIComponent(uriPath);
-            if (path.startsWith('totp/') || path.startsWith('hotp/')) {
+            if (path.startsWith("totp/") || path.startsWith("hotp/")) {
                 path = path.substring(5);
                 path = path.substring(5);
             }
             }
-            if (path.includes(':')) {
-                return path.split(':')[0];
-            } else if (path.includes('-')) {
-                return path.split('-')[0];
+            if (path.includes(":")) {
+                return path.split(":")[0];
+            } else if (path.includes("-")) {
+                return path.split("-")[0];
             }
             }
             return path;
             return path;
         } catch (e) {
         } catch (e) {
-            return '';
+            return "";
         }
         }
     }
     }
 
 
     private static _getDigits(uriParams): number {
     private static _getDigits(uriParams): number {
         try {
         try {
-            return parseInt(uriParams['digits'], 10) || Code.defaultDigits;
+            return parseInt(uriParams["digits"], 10) || Code.defaultDigits;
         } catch (e) {
         } catch (e) {
             return Code.defaultDigits;
             return Code.defaultDigits;
         }
         }
@@ -146,7 +146,7 @@ export class Code {
 
 
     private static _getPeriod(uriParams): number {
     private static _getPeriod(uriParams): number {
         try {
         try {
-            return parseInt(uriParams['period'], 10) || Code.defaultPeriod;
+            return parseInt(uriParams["period"], 10) || Code.defaultPeriod;
         } catch (e) {
         } catch (e) {
             return Code.defaultPeriod;
             return Code.defaultPeriod;
         }
         }
@@ -154,29 +154,29 @@ export class Code {
 
 
     private static _getAlgorithm(uriParams): AlgorithmType {
     private static _getAlgorithm(uriParams): AlgorithmType {
         try {
         try {
-            const algorithm = uriParams['algorithm'].toLowerCase();
-            if (algorithm === 'sha256') {
+            const algorithm = uriParams["algorithm"].toLowerCase();
+            if (algorithm === "sha256") {
                 return algorithm;
                 return algorithm;
-            } else if (algorithm === 'sha512') {
+            } else if (algorithm === "sha512") {
                 return algorithm;
                 return algorithm;
             }
             }
         } catch (e) {
         } catch (e) {
             // nothing
             // nothing
         }
         }
-        return 'sha1';
+        return "sha1";
     }
     }
 
 
     private static _getType(uriPath: string): Type {
     private static _getType(uriPath: string): Type {
-        const oauthType = uriPath.split('/')[0].substring(0);
-        if (oauthType.toLowerCase() === 'totp') {
-            return 'totp';
-        } else if (oauthType.toLowerCase() === 'hotp') {
-            return 'hotp';
+        const oauthType = uriPath.split("/")[0].substring(0);
+        if (oauthType.toLowerCase() === "totp") {
+            return "totp";
+        } else if (oauthType.toLowerCase() === "hotp") {
+            return "hotp";
         }
         }
         throw new Error(`Unsupported format with host ${oauthType}`);
         throw new Error(`Unsupported format with host ${oauthType}`);
     }
     }
 
 
     static getSanitizedSecret(uriParams): string {
     static getSanitizedSecret(uriParams): string {
-        return uriParams['secret'].replace(/ /g, '').toUpperCase();
+        return uriParams["secret"].replace(/ /g, "").toUpperCase();
     }
     }
 }
 }

+ 4 - 4
apps/cast/.eslintrc.js

@@ -3,11 +3,11 @@ module.exports = {
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // This is required here to ensure desktop picks the right eslint config, where this app is
     // packaged as a submodule.
     // packaged as a submodule.
     root: true,
     root: true,
-    extends: ['@ente/eslint-config'],
-    parser: '@typescript-eslint/parser',
+    extends: ["@ente/eslint-config"],
+    parser: "@typescript-eslint/parser",
     parserOptions: {
     parserOptions: {
         tsconfigRootDir: __dirname,
         tsconfigRootDir: __dirname,
-        project: './tsconfig.json',
+        project: "./tsconfig.json",
     },
     },
-    ignorePatterns: ['.eslintrc.js', 'out'],
+    ignorePatterns: [".eslintrc.js", "out"],
 };
 };

+ 1 - 1
apps/cast/next.config.js

@@ -1,3 +1,3 @@
-const nextConfigBase = require('@/next/next.config.base.js');
+const nextConfigBase = require("@/next/next.config.base.js");
 
 
 module.exports = nextConfigBase;
 module.exports = nextConfigBase;

+ 2 - 2
apps/cast/sentry.client.config.ts

@@ -1,3 +1,3 @@
-import { initSentry } from '@ente/shared/sentry/config/sentry.config.base';
+import { initSentry } from "@ente/shared/sentry/config/sentry.config.base";
 
 
-initSentry('https://0f7214c7feb9b1dd2fed5db09b42fa1b@sentry.ente.io/5');
+initSentry("https://0f7214c7feb9b1dd2fed5db09b42fa1b@sentry.ente.io/5");

+ 5 - 4
apps/cast/src/components/FilledCircleCheck/index.tsx

@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react';
-import styles from './FilledCircleCheck.module.scss'; // Import our CSS module
+import { useEffect, useState } from "react";
+import styles from "./FilledCircleCheck.module.scss"; // Import our CSS module
 
 
 const FilledCircleCheck = () => {
 const FilledCircleCheck = () => {
     const [animate, setAnimate] = useState(false);
     const [animate, setAnimate] = useState(false);
@@ -9,11 +9,12 @@ const FilledCircleCheck = () => {
     }, []);
     }, []);
 
 
     return (
     return (
-        <div className={`${styles.circle} ${animate ? styles.animate : ''}`}>
+        <div className={`${styles.circle} ${animate ? styles.animate : ""}`}>
             <svg
             <svg
                 className={styles.checkmark}
                 className={styles.checkmark}
                 xmlns="http://www.w3.org/2000/svg"
                 xmlns="http://www.w3.org/2000/svg"
-                viewBox="0 0 52 52">
+                viewBox="0 0 52 52"
+            >
                 <circle
                 <circle
                     className={styles.checkmark__circle}
                     className={styles.checkmark__circle}
                     cx="26"
                     cx="26"

+ 39 - 35
apps/cast/src/components/LargeType.tsx

@@ -1,58 +1,62 @@
 const colourPool = [
 const colourPool = [
-    '#87CEFA', // Light Blue
-    '#90EE90', // Light Green
-    '#F08080', // Light Coral
-    '#FFFFE0', // Light Yellow
-    '#FFB6C1', // Light Pink
-    '#E0FFFF', // Light Cyan
-    '#FAFAD2', // Light Goldenrod
-    '#87CEFA', // Light Sky Blue
-    '#D3D3D3', // Light Gray
-    '#B0C4DE', // Light Steel Blue
-    '#FFA07A', // Light Salmon
-    '#20B2AA', // Light Sea Green
-    '#778899', // Light Slate Gray
-    '#AFEEEE', // Light Turquoise
-    '#7A58C1', // Light Violet
-    '#FFA500', // Light Orange
-    '#A0522D', // Light Brown
-    '#9370DB', // Light Purple
-    '#008080', // Light Teal
-    '#808000', // Light Olive
+    "#87CEFA", // Light Blue
+    "#90EE90", // Light Green
+    "#F08080", // Light Coral
+    "#FFFFE0", // Light Yellow
+    "#FFB6C1", // Light Pink
+    "#E0FFFF", // Light Cyan
+    "#FAFAD2", // Light Goldenrod
+    "#87CEFA", // Light Sky Blue
+    "#D3D3D3", // Light Gray
+    "#B0C4DE", // Light Steel Blue
+    "#FFA07A", // Light Salmon
+    "#20B2AA", // Light Sea Green
+    "#778899", // Light Slate Gray
+    "#AFEEEE", // Light Turquoise
+    "#7A58C1", // Light Violet
+    "#FFA500", // Light Orange
+    "#A0522D", // Light Brown
+    "#9370DB", // Light Purple
+    "#008080", // Light Teal
+    "#808000", // Light Olive
 ];
 ];
 
 
 export default function LargeType({ chars }: { chars: string[] }) {
 export default function LargeType({ chars }: { chars: string[] }) {
     return (
     return (
         <table
         <table
             style={{
             style={{
-                fontSize: '4rem',
-                fontWeight: 'bold',
-                fontFamily: 'monospace',
-                display: 'flex',
-                position: 'relative',
-            }}>
+                fontSize: "4rem",
+                fontWeight: "bold",
+                fontFamily: "monospace",
+                display: "flex",
+                position: "relative",
+            }}
+        >
             {chars.map((char, i) => (
             {chars.map((char, i) => (
                 <tr
                 <tr
                     key={i}
                     key={i}
                     style={{
                     style={{
-                        display: 'flex',
-                        flexDirection: 'column',
-                        alignItems: 'center',
-                        padding: '0.5rem',
+                        display: "flex",
+                        flexDirection: "column",
+                        alignItems: "center",
+                        padding: "0.5rem",
                         // alternating background
                         // alternating background
-                        backgroundColor: i % 2 === 0 ? '#2e2e2e' : '#5e5e5e',
-                    }}>
+                        backgroundColor: i % 2 === 0 ? "#2e2e2e" : "#5e5e5e",
+                    }}
+                >
                     <span
                     <span
                         style={{
                         style={{
                             color: colourPool[i % colourPool.length],
                             color: colourPool[i % colourPool.length],
                             lineHeight: 1.2,
                             lineHeight: 1.2,
-                        }}>
+                        }}
+                    >
                         {char}
                         {char}
                     </span>
                     </span>
                     <span
                     <span
                         style={{
                         style={{
-                            fontSize: '1rem',
-                        }}>
+                            fontSize: "1rem",
+                        }}
+                    >
                         {i + 1}
                         {i + 1}
                     </span>
                     </span>
                 </tr>
                 </tr>

+ 21 - 17
apps/cast/src/components/PairedSuccessfullyOverlay.tsx

@@ -1,38 +1,42 @@
-import FilledCircleCheck from './FilledCircleCheck';
+import FilledCircleCheck from "./FilledCircleCheck";
 
 
 export default function PairedSuccessfullyOverlay() {
 export default function PairedSuccessfullyOverlay() {
     return (
     return (
         <div
         <div
             style={{
             style={{
-                position: 'fixed',
+                position: "fixed",
                 top: 0,
                 top: 0,
                 right: 0,
                 right: 0,
-                height: '100%',
-                width: '100%',
-                display: 'flex',
-                justifyContent: 'center',
-                alignItems: 'center',
+                height: "100%",
+                width: "100%",
+                display: "flex",
+                justifyContent: "center",
+                alignItems: "center",
                 zIndex: 100,
                 zIndex: 100,
-                backgroundColor: 'black',
-            }}>
+                backgroundColor: "black",
+            }}
+        >
             <div
             <div
                 style={{
                 style={{
-                    display: 'flex',
-                    alignItems: 'center',
-                    flexDirection: 'column',
-                    textAlign: 'center',
-                }}>
+                    display: "flex",
+                    alignItems: "center",
+                    flexDirection: "column",
+                    textAlign: "center",
+                }}
+            >
                 <FilledCircleCheck />
                 <FilledCircleCheck />
                 <h2
                 <h2
                     style={{
                     style={{
                         marginBottom: 0,
                         marginBottom: 0,
-                    }}>
+                    }}
+                >
                     Pairing Complete
                     Pairing Complete
                 </h2>
                 </h2>
                 <p
                 <p
                     style={{
                     style={{
-                        lineHeight: '1.5rem',
-                    }}>
+                        lineHeight: "1.5rem",
+                    }}
+                >
                     We're preparing your album.
                     We're preparing your album.
                     <br /> This should only take a few seconds.
                     <br /> This should only take a few seconds.
                 </p>
                 </p>

+ 25 - 23
apps/cast/src/components/Theatre/PhotoAuditorium.tsx

@@ -1,5 +1,5 @@
-import { SlideshowContext } from 'pages/slideshow';
-import { useContext, useEffect, useState } from 'react';
+import { SlideshowContext } from "pages/slideshow";
+import { useContext, useEffect, useState } from "react";
 
 
 export default function PhotoAuditorium({
 export default function PhotoAuditorium({
     url,
     url,
@@ -49,38 +49,40 @@ export default function PhotoAuditorium({
     return (
     return (
         <div
         <div
             style={{
             style={{
-                width: '100vw',
-                height: '100vh',
+                width: "100vw",
+                height: "100vh",
                 backgroundImage: `url(${url})`,
                 backgroundImage: `url(${url})`,
-                backgroundSize: 'cover',
-                backgroundPosition: 'center',
-                backgroundRepeat: 'no-repeat',
-                backgroundBlendMode: 'multiply',
-                backgroundColor: 'rgba(0, 0, 0, 0.5)',
-            }}>
+                backgroundSize: "cover",
+                backgroundPosition: "center",
+                backgroundRepeat: "no-repeat",
+                backgroundBlendMode: "multiply",
+                backgroundColor: "rgba(0, 0, 0, 0.5)",
+            }}
+        >
             <div
             <div
                 style={{
                 style={{
-                    height: '100%',
-                    width: '100%',
-                    display: 'flex',
-                    justifyContent: 'center',
-                    alignItems: 'center',
-                    backdropFilter: 'blur(10px)',
-                }}>
+                    height: "100%",
+                    width: "100%",
+                    display: "flex",
+                    justifyContent: "center",
+                    alignItems: "center",
+                    backdropFilter: "blur(10px)",
+                }}
+            >
                 <img
                 <img
                     src={url}
                     src={url}
                     style={{
                     style={{
-                        maxWidth: '100%',
-                        maxHeight: '100%',
-                        display: showPreloadedNextSlide ? 'none' : 'block',
+                        maxWidth: "100%",
+                        maxHeight: "100%",
+                        display: showPreloadedNextSlide ? "none" : "block",
                     }}
                     }}
                 />
                 />
                 <img
                 <img
                     src={nextSlideUrl}
                     src={nextSlideUrl}
                     style={{
                     style={{
-                        maxWidth: '100%',
-                        maxHeight: '100%',
-                        display: showPreloadedNextSlide ? 'block' : 'none',
+                        maxWidth: "100%",
+                        maxHeight: "100%",
+                        display: showPreloadedNextSlide ? "block" : "none",
                     }}
                     }}
                     onLoad={() => {
                     onLoad={() => {
                         setNextSlidePrerendered(true);
                         setNextSlidePrerendered(true);

+ 14 - 12
apps/cast/src/components/Theatre/VideoAuditorium.tsx

@@ -1,6 +1,6 @@
-import mime from 'mime-types';
-import { SlideshowContext } from 'pages/slideshow';
-import { useContext, useEffect, useRef } from 'react';
+import mime from "mime-types";
+import { SlideshowContext } from "pages/slideshow";
+import { useContext, useEffect, useRef } from "react";
 
 
 export default function VideoAuditorium({
 export default function VideoAuditorium({
     name,
     name,
@@ -30,22 +30,24 @@ export default function VideoAuditorium({
     return (
     return (
         <div
         <div
             style={{
             style={{
-                width: '100vw',
-                height: '100vh',
-                display: 'flex',
-                justifyContent: 'center',
-                alignItems: 'center',
-            }}>
+                width: "100vw",
+                height: "100vh",
+                display: "flex",
+                justifyContent: "center",
+                alignItems: "center",
+            }}
+        >
             <video
             <video
                 ref={videoRef}
                 ref={videoRef}
                 autoPlay
                 autoPlay
                 controls
                 controls
                 style={{
                 style={{
-                    maxWidth: '100vw',
-                    maxHeight: '100vh',
+                    maxWidth: "100vw",
+                    maxHeight: "100vh",
                 }}
                 }}
                 onError={showNextSlide}
                 onError={showNextSlide}
-                onEnded={showNextSlide}>
+                onEnded={showNextSlide}
+            >
                 <source src={url} type={mime.lookup(name)} />
                 <source src={url} type={mime.lookup(name)} />
             </video>
             </video>
         </div>
         </div>

+ 2 - 2
apps/cast/src/components/Theatre/index.tsx

@@ -1,5 +1,5 @@
-import { FILE_TYPE } from 'constants/file';
-import PhotoAuditorium from './PhotoAuditorium';
+import { FILE_TYPE } from "constants/file";
+import PhotoAuditorium from "./PhotoAuditorium";
 // import VideoAuditorium from './VideoAuditorium';
 // import VideoAuditorium from './VideoAuditorium';
 
 
 interface fileProp {
 interface fileProp {

+ 6 - 6
apps/cast/src/components/TimerBar.tsx

@@ -1,9 +1,9 @@
-import { useEffect, useState } from 'react';
+import { useEffect, useState } from "react";
 
 
 export default function TimerBar({ percentage }: { percentage: number }) {
 export default function TimerBar({ percentage }: { percentage: number }) {
-    const okColor = '#75C157';
-    const warningColor = '#FFC000';
-    const lateColor = '#FF0000';
+    const okColor = "#75C157";
+    const warningColor = "#FFC000";
+    const lateColor = "#FF0000";
 
 
     const [backgroundColor, setBackgroundColor] = useState(okColor);
     const [backgroundColor, setBackgroundColor] = useState(okColor);
 
 
@@ -21,9 +21,9 @@ export default function TimerBar({ percentage }: { percentage: number }) {
         <div
         <div
             style={{
             style={{
                 width: `${percentage}%`, // Set the width based on the time left
                 width: `${percentage}%`, // Set the width based on the time left
-                height: '10px', // Same as the border thickness
+                height: "10px", // Same as the border thickness
                 backgroundColor, // The color of the moving border
                 backgroundColor, // The color of the moving border
-                transition: 'width 1s linear', // Smooth transition for the width change
+                transition: "width 1s linear", // Smooth transition for the width change
             }}
             }}
         />
         />
     );
     );

+ 11 - 11
apps/cast/src/constants/apps.ts

@@ -1,11 +1,11 @@
-import { getAlbumsURL } from '@ente/shared/network/api';
-import { runningInBrowser } from '@ente/shared/platform';
-import { PAGES } from 'constants/pages';
+import { getAlbumsURL } from "@ente/shared/network/api";
+import { runningInBrowser } from "@ente/shared/platform";
+import { PAGES } from "constants/pages";
 
 
 export enum APPS {
 export enum APPS {
-    PHOTOS = 'PHOTOS',
-    AUTH = 'AUTH',
-    ALBUMS = 'ALBUMS',
+    PHOTOS = "PHOTOS",
+    AUTH = "AUTH",
+    ALBUMS = "ALBUMS",
 }
 }
 
 
 export const ALLOWED_APP_PAGES = new Map([
 export const ALLOWED_APP_PAGES = new Map([
@@ -29,9 +29,9 @@ export const ALLOWED_APP_PAGES = new Map([
 ]);
 ]);
 
 
 export const CLIENT_PACKAGE_NAMES = new Map([
 export const CLIENT_PACKAGE_NAMES = new Map([
-    [APPS.ALBUMS, 'io.ente.albums.web'],
-    [APPS.PHOTOS, 'io.ente.photos.web'],
-    [APPS.AUTH, 'io.ente.auth.web'],
+    [APPS.ALBUMS, "io.ente.albums.web"],
+    [APPS.PHOTOS, "io.ente.photos.web"],
+    [APPS.AUTH, "io.ente.auth.web"],
 ]);
 ]);
 
 
 export const getAppNameAndTitle = () => {
 export const getAppNameAndTitle = () => {
@@ -41,9 +41,9 @@ export const getAppNameAndTitle = () => {
     const currentURL = new URL(window.location.href);
     const currentURL = new URL(window.location.href);
     const albumsURL = new URL(getAlbumsURL());
     const albumsURL = new URL(getAlbumsURL());
     if (currentURL.origin === albumsURL.origin) {
     if (currentURL.origin === albumsURL.origin) {
-        return { name: APPS.ALBUMS, title: 'ente Photos' };
+        return { name: APPS.ALBUMS, title: "ente Photos" };
     } else {
     } else {
-        return { name: APPS.PHOTOS, title: 'ente Photos' };
+        return { name: APPS.PHOTOS, title: "ente Photos" };
     }
     }
 };
 };
 
 

+ 3 - 3
apps/cast/src/constants/cache.ts

@@ -1,5 +1,5 @@
 export enum CACHES {
 export enum CACHES {
-    THUMBS = 'thumbs',
-    FACE_CROPS = 'face-crops',
-    FILES = 'files',
+    THUMBS = "thumbs",
+    FACE_CROPS = "face-crops",
+    FILES = "files",
 }
 }

+ 20 - 20
apps/cast/src/constants/collection.ts

@@ -3,31 +3,31 @@ export const TRASH_SECTION = -2;
 export const DUMMY_UNCATEGORIZED_COLLECTION = -3;
 export const DUMMY_UNCATEGORIZED_COLLECTION = -3;
 export const HIDDEN_ITEMS_SECTION = -4;
 export const HIDDEN_ITEMS_SECTION = -4;
 export const ALL_SECTION = 0;
 export const ALL_SECTION = 0;
-export const DEFAULT_HIDDEN_COLLECTION_USER_FACING_NAME = 'Hidden';
+export const DEFAULT_HIDDEN_COLLECTION_USER_FACING_NAME = "Hidden";
 
 
 export enum CollectionType {
 export enum CollectionType {
-    folder = 'folder',
-    favorites = 'favorites',
-    album = 'album',
-    uncategorized = 'uncategorized',
+    folder = "folder",
+    favorites = "favorites",
+    album = "album",
+    uncategorized = "uncategorized",
 }
 }
 
 
 export enum CollectionSummaryType {
 export enum CollectionSummaryType {
-    folder = 'folder',
-    favorites = 'favorites',
-    album = 'album',
-    archive = 'archive',
-    trash = 'trash',
-    uncategorized = 'uncategorized',
-    all = 'all',
-    outgoingShare = 'outgoingShare',
-    incomingShareViewer = 'incomingShareViewer',
-    incomingShareCollaborator = 'incomingShareCollaborator',
-    sharedOnlyViaLink = 'sharedOnlyViaLink',
-    archived = 'archived',
-    defaultHidden = 'defaultHidden',
-    hiddenItems = 'hiddenItems',
-    pinned = 'pinned',
+    folder = "folder",
+    favorites = "favorites",
+    album = "album",
+    archive = "archive",
+    trash = "trash",
+    uncategorized = "uncategorized",
+    all = "all",
+    outgoingShare = "outgoingShare",
+    incomingShareViewer = "incomingShareViewer",
+    incomingShareCollaborator = "incomingShareCollaborator",
+    sharedOnlyViaLink = "sharedOnlyViaLink",
+    archived = "archived",
+    defaultHidden = "defaultHidden",
+    hiddenItems = "hiddenItems",
+    pinned = "pinned",
 }
 }
 export enum COLLECTION_LIST_SORT_BY {
 export enum COLLECTION_LIST_SORT_BY {
     NAME,
     NAME,

+ 3 - 3
apps/cast/src/constants/ffmpeg.ts

@@ -1,3 +1,3 @@
-export const INPUT_PATH_PLACEHOLDER = 'INPUT';
-export const FFMPEG_PLACEHOLDER = 'FFMPEG';
-export const OUTPUT_PATH_PLACEHOLDER = 'OUTPUT';
+export const INPUT_PATH_PLACEHOLDER = "INPUT";
+export const FFMPEG_PLACEHOLDER = "FFMPEG";
+export const OUTPUT_PATH_PLACEHOLDER = "OUTPUT";

+ 25 - 25
apps/cast/src/constants/file.ts

@@ -4,10 +4,10 @@ export const MAX_EDITED_CREATION_TIME = new Date();
 export const MAX_EDITED_FILE_NAME_LENGTH = 100;
 export const MAX_EDITED_FILE_NAME_LENGTH = 100;
 export const MAX_CAPTION_SIZE = 5000;
 export const MAX_CAPTION_SIZE = 5000;
 
 
-export const TYPE_HEIC = 'heic';
-export const TYPE_HEIF = 'heif';
-export const TYPE_JPEG = 'jpeg';
-export const TYPE_JPG = 'jpg';
+export const TYPE_HEIC = "heic";
+export const TYPE_HEIF = "heif";
+export const TYPE_JPEG = "jpeg";
+export const TYPE_JPG = "jpg";
 
 
 export enum FILE_TYPE {
 export enum FILE_TYPE {
     IMAGE,
     IMAGE,
@@ -17,27 +17,27 @@ export enum FILE_TYPE {
 }
 }
 
 
 export const RAW_FORMATS = [
 export const RAW_FORMATS = [
-    'heic',
-    'rw2',
-    'tiff',
-    'arw',
-    'cr3',
-    'cr2',
-    'raf',
-    'nef',
-    'psd',
-    'dng',
-    'tif',
+    "heic",
+    "rw2",
+    "tiff",
+    "arw",
+    "cr3",
+    "cr2",
+    "raf",
+    "nef",
+    "psd",
+    "dng",
+    "tif",
 ];
 ];
 export const SUPPORTED_RAW_FORMATS = [
 export const SUPPORTED_RAW_FORMATS = [
-    'heic',
-    'rw2',
-    'tiff',
-    'arw',
-    'cr3',
-    'cr2',
-    'nef',
-    'psd',
-    'dng',
-    'tif',
+    "heic",
+    "rw2",
+    "tiff",
+    "arw",
+    "cr3",
+    "cr2",
+    "nef",
+    "psd",
+    "dng",
+    "tif",
 ];
 ];

+ 2 - 2
apps/cast/src/constants/gallery.ts

@@ -8,8 +8,8 @@ export const SPACE_BTW_DATES = 44;
 export const SPACE_BTW_DATES_TO_IMAGE_CONTAINER_WIDTH_RATIO = 0.244;
 export const SPACE_BTW_DATES_TO_IMAGE_CONTAINER_WIDTH_RATIO = 0.244;
 
 
 export enum PLAN_PERIOD {
 export enum PLAN_PERIOD {
-    MONTH = 'month',
-    YEAR = 'year',
+    MONTH = "month",
+    YEAR = "year",
 }
 }
 
 
 export const SYNC_INTERVAL_IN_MICROSECONDS = 1000 * 60 * 5; // 5 minutes
 export const SYNC_INTERVAL_IN_MICROSECONDS = 1000 * 60 * 5; // 5 minutes

+ 16 - 16
apps/cast/src/constants/pages.ts

@@ -1,20 +1,20 @@
 export enum PAGES {
 export enum PAGES {
-    CHANGE_EMAIL = '/change-email',
-    CHANGE_PASSWORD = '/change-password',
-    CREDENTIALS = '/credentials',
-    GALLERY = '/gallery',
-    GENERATE = '/generate',
-    LOGIN = '/login',
-    RECOVER = '/recover',
-    SIGNUP = '/signup',
-    TWO_FACTOR_SETUP = '/two-factor/setup',
-    TWO_FACTOR_VERIFY = '/two-factor/verify',
-    TWO_FACTOR_RECOVER = '/two-factor/recover',
-    VERIFY = '/verify',
-    ROOT = '/',
-    SHARED_ALBUMS = '/shared-albums',
+    CHANGE_EMAIL = "/change-email",
+    CHANGE_PASSWORD = "/change-password",
+    CREDENTIALS = "/credentials",
+    GALLERY = "/gallery",
+    GENERATE = "/generate",
+    LOGIN = "/login",
+    RECOVER = "/recover",
+    SIGNUP = "/signup",
+    TWO_FACTOR_SETUP = "/two-factor/setup",
+    TWO_FACTOR_VERIFY = "/two-factor/verify",
+    TWO_FACTOR_RECOVER = "/two-factor/recover",
+    VERIFY = "/verify",
+    ROOT = "/",
+    SHARED_ALBUMS = "/shared-albums",
     // ML_DEBUG = '/ml-debug',
     // ML_DEBUG = '/ml-debug',
-    DEDUPLICATE = '/deduplicate',
+    DEDUPLICATE = "/deduplicate",
     // AUTH page is used to show (auth)enticator codes
     // AUTH page is used to show (auth)enticator codes
-    AUTH = '/auth',
+    AUTH = "/auth",
 }
 }

+ 54 - 54
apps/cast/src/constants/upload.ts

@@ -1,52 +1,52 @@
-import { ENCRYPTION_CHUNK_SIZE } from '@ente/shared/crypto/constants';
-import { FILE_TYPE } from 'constants/file';
+import { ENCRYPTION_CHUNK_SIZE } from "@ente/shared/crypto/constants";
+import { FILE_TYPE } from "constants/file";
 import {
 import {
     FileTypeInfo,
     FileTypeInfo,
     ImportSuggestion,
     ImportSuggestion,
     Location,
     Location,
     ParsedExtractedMetadata,
     ParsedExtractedMetadata,
-} from 'types/upload';
+} from "types/upload";
 
 
 // list of format that were missed by type-detection for some files.
 // list of format that were missed by type-detection for some files.
 export const WHITELISTED_FILE_FORMATS: FileTypeInfo[] = [
 export const WHITELISTED_FILE_FORMATS: FileTypeInfo[] = [
-    { fileType: FILE_TYPE.IMAGE, exactType: 'jpeg', mimeType: 'image/jpeg' },
-    { fileType: FILE_TYPE.IMAGE, exactType: 'jpg', mimeType: 'image/jpeg' },
-    { fileType: FILE_TYPE.VIDEO, exactType: 'webm', mimeType: 'video/webm' },
-    { fileType: FILE_TYPE.VIDEO, exactType: 'mod', mimeType: 'video/mpeg' },
-    { fileType: FILE_TYPE.VIDEO, exactType: 'mp4', mimeType: 'video/mp4' },
-    { fileType: FILE_TYPE.IMAGE, exactType: 'gif', mimeType: 'image/gif' },
-    { fileType: FILE_TYPE.VIDEO, exactType: 'dv', mimeType: 'video/x-dv' },
+    { fileType: FILE_TYPE.IMAGE, exactType: "jpeg", mimeType: "image/jpeg" },
+    { fileType: FILE_TYPE.IMAGE, exactType: "jpg", mimeType: "image/jpeg" },
+    { fileType: FILE_TYPE.VIDEO, exactType: "webm", mimeType: "video/webm" },
+    { fileType: FILE_TYPE.VIDEO, exactType: "mod", mimeType: "video/mpeg" },
+    { fileType: FILE_TYPE.VIDEO, exactType: "mp4", mimeType: "video/mp4" },
+    { fileType: FILE_TYPE.IMAGE, exactType: "gif", mimeType: "image/gif" },
+    { fileType: FILE_TYPE.VIDEO, exactType: "dv", mimeType: "video/x-dv" },
     {
     {
         fileType: FILE_TYPE.VIDEO,
         fileType: FILE_TYPE.VIDEO,
-        exactType: 'wmv',
-        mimeType: 'video/x-ms-asf',
+        exactType: "wmv",
+        mimeType: "video/x-ms-asf",
     },
     },
     {
     {
         fileType: FILE_TYPE.VIDEO,
         fileType: FILE_TYPE.VIDEO,
-        exactType: 'hevc',
-        mimeType: 'video/hevc',
+        exactType: "hevc",
+        mimeType: "video/hevc",
     },
     },
     {
     {
         fileType: FILE_TYPE.IMAGE,
         fileType: FILE_TYPE.IMAGE,
-        exactType: 'raf',
-        mimeType: 'image/x-fuji-raf',
+        exactType: "raf",
+        mimeType: "image/x-fuji-raf",
     },
     },
     {
     {
         fileType: FILE_TYPE.IMAGE,
         fileType: FILE_TYPE.IMAGE,
-        exactType: 'orf',
-        mimeType: 'image/x-olympus-orf',
+        exactType: "orf",
+        mimeType: "image/x-olympus-orf",
     },
     },
 
 
     {
     {
         fileType: FILE_TYPE.IMAGE,
         fileType: FILE_TYPE.IMAGE,
-        exactType: 'crw',
-        mimeType: 'image/x-canon-crw',
+        exactType: "crw",
+        mimeType: "image/x-canon-crw",
     },
     },
 ];
 ];
 
 
-export const KNOWN_NON_MEDIA_FORMATS = ['xmp', 'html', 'txt'];
+export const KNOWN_NON_MEDIA_FORMATS = ["xmp", "html", "txt"];
 
 
-export const EXIFLESS_FORMATS = ['gif', 'bmp'];
+export const EXIFLESS_FORMATS = ["gif", "bmp"];
 
 
 // this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part.
 // this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part.
 export const MULTIPART_PART_SIZE = 20 * 1024 * 1024;
 export const MULTIPART_PART_SIZE = 20 * 1024 * 1024;
@@ -54,7 +54,7 @@ export const MULTIPART_PART_SIZE = 20 * 1024 * 1024;
 export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE;
 export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE;
 
 
 export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor(
 export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor(
-    MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE
+    MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE,
 );
 );
 
 
 export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random();
 export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random();
@@ -88,9 +88,9 @@ export enum UPLOAD_RESULT {
 }
 }
 
 
 export enum PICKED_UPLOAD_TYPE {
 export enum PICKED_UPLOAD_TYPE {
-    FILES = 'files',
-    FOLDERS = 'folders',
-    ZIPS = 'zips',
+    FILES = "files",
+    FOLDERS = "folders",
+    ZIPS = "zips",
 }
 }
 
 
 export const MAX_FILE_SIZE_SUPPORTED = 4 * 1024 * 1024 * 1024; // 4 GB
 export const MAX_FILE_SIZE_SUPPORTED = 4 * 1024 * 1024 * 1024; // 4 GB
@@ -107,36 +107,36 @@ export const NULL_EXTRACTED_METADATA: ParsedExtractedMetadata = {
 export const A_SEC_IN_MICROSECONDS = 1e6;
 export const A_SEC_IN_MICROSECONDS = 1e6;
 
 
 export const DEFAULT_IMPORT_SUGGESTION: ImportSuggestion = {
 export const DEFAULT_IMPORT_SUGGESTION: ImportSuggestion = {
-    rootFolderName: '',
+    rootFolderName: "",
     hasNestedFolders: false,
     hasNestedFolders: false,
     hasRootLevelFileWithFolder: false,
     hasRootLevelFileWithFolder: false,
 };
 };
 
 
 export const BLACK_THUMBNAIL_BASE64 =
 export const BLACK_THUMBNAIL_BASE64 =
-    '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEB' +
-    'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQ' +
-    'EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARC' +
-    'ACWASwDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF' +
-    'BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk' +
-    '6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztL' +
-    'W2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAA' +
-    'AAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVY' +
-    'nLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImK' +
-    'kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oAD' +
-    'AMBAAIRAxEAPwD/AD/6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA' +
-    'CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg' +
-    'AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC' +
-    'gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo' +
-    'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg' +
-    'AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg' +
-    'AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA' +
-    'CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA' +
-    'CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA' +
-    'KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg' +
-    'AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo' +
-    'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA' +
-    'CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK' +
-    'ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA' +
-    'KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo' +
-    'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo' +
-    'AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD/9k=';
+    "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEB" +
+    "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQ" +
+    "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARC" +
+    "ACWASwDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF" +
+    "BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk" +
+    "6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztL" +
+    "W2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAA" +
+    "AAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVY" +
+    "nLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImK" +
+    "kpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oAD" +
+    "AMBAAIRAxEAPwD/AD/6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA" +
+    "CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg" +
+    "AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC" +
+    "gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo" +
+    "AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg" +
+    "AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg" +
+    "AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA" +
+    "CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA" +
+    "CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA" +
+    "KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg" +
+    "AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo" +
+    "AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA" +
+    "CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK" +
+    "ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA" +
+    "KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo" +
+    "AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo" +
+    "AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD/9k=";

+ 9 - 9
apps/cast/src/constants/urls.ts

@@ -1,19 +1,19 @@
-export const ENTE_WEBSITE_LINK = 'https://ente.io';
+export const ENTE_WEBSITE_LINK = "https://ente.io";
 
 
-export const ML_BLOG_LINK = 'https://ente.io/blog/desktop-ml-beta';
+export const ML_BLOG_LINK = "https://ente.io/blog/desktop-ml-beta";
 
 
 export const FACE_SEARCH_PRIVACY_POLICY_LINK =
 export const FACE_SEARCH_PRIVACY_POLICY_LINK =
-    'https://ente.io/privacy#8-biometric-information-privacy-policy';
+    "https://ente.io/privacy#8-biometric-information-privacy-policy";
 
 
-export const SUPPORT_EMAIL = 'support@ente.io';
+export const SUPPORT_EMAIL = "support@ente.io";
 
 
-export const APP_DOWNLOAD_URL = 'https://ente.io/download/desktop';
+export const APP_DOWNLOAD_URL = "https://ente.io/download/desktop";
 
 
-export const FEEDBACK_EMAIL = 'feedback@ente.io';
+export const FEEDBACK_EMAIL = "feedback@ente.io";
 
 
-export const DELETE_ACCOUNT_EMAIL = 'account-deletion@ente.io';
+export const DELETE_ACCOUNT_EMAIL = "account-deletion@ente.io";
 
 
-export const WEB_ROADMAP_URL = 'https://github.com/ente-io/photos-web/issues';
+export const WEB_ROADMAP_URL = "https://github.com/ente-io/photos-web/issues";
 
 
 export const DESKTOP_ROADMAP_URL =
 export const DESKTOP_ROADMAP_URL =
-    'https://github.com/ente-io/photos-desktop/issues';
+    "https://github.com/ente-io/photos-desktop/issues";

+ 9 - 8
apps/cast/src/pages/_app.tsx

@@ -1,9 +1,9 @@
-import type { AppProps } from 'next/app';
-import 'styles/global.css';
-import { ThemeProvider, CssBaseline } from '@mui/material';
-import { getTheme } from '@ente/shared/themes';
-import { THEME_COLOR } from '@ente/shared/themes/constants';
-import { APPS } from '@ente/shared/apps/constants';
+import { APPS } from "@ente/shared/apps/constants";
+import { getTheme } from "@ente/shared/themes";
+import { THEME_COLOR } from "@ente/shared/themes/constants";
+import { CssBaseline, ThemeProvider } from "@mui/material";
+import type { AppProps } from "next/app";
+import "styles/global.css";
 
 
 export default function App({ Component, pageProps }: AppProps) {
 export default function App({ Component, pageProps }: AppProps) {
     return (
     return (
@@ -12,8 +12,9 @@ export default function App({ Component, pageProps }: AppProps) {
 
 
             <main
             <main
                 style={{
                 style={{
-                    display: 'contents',
-                }}>
+                    display: "contents",
+                }}
+            >
                 <Component {...pageProps} />
                 <Component {...pageProps} />
             </main>
             </main>
         </ThemeProvider>
         </ThemeProvider>

+ 11 - 9
apps/cast/src/pages/_document.tsx

@@ -1,22 +1,24 @@
-import { Html, Head, Main, NextScript } from 'next/document';
+import { Head, Html, Main, NextScript } from "next/document";
 
 
 export default function Document() {
 export default function Document() {
     return (
     return (
         <Html
         <Html
             lang="en"
             lang="en"
             style={{
             style={{
-                height: '100%',
-                width: '100%',
-            }}>
+                height: "100%",
+                width: "100%",
+            }}
+        >
             <Head />
             <Head />
             <body
             <body
                 style={{
                 style={{
-                    height: '100%',
-                    width: '100%',
+                    height: "100%",
+                    width: "100%",
                     margin: 0,
                     margin: 0,
-                    backgroundColor: 'black',
-                    color: 'white',
-                }}>
+                    backgroundColor: "black",
+                    color: "white",
+                }}
+            >
                 <Main />
                 <Main />
                 <NextScript />
                 <NextScript />
             </body>
             </body>

+ 67 - 60
apps/cast/src/pages/index.tsx

@@ -1,13 +1,13 @@
-import EnteSpinner from '@ente/shared/components/EnteSpinner';
-import { boxSealOpen, toB64 } from '@ente/shared/crypto/internal/libsodium';
-import { useCastReceiver } from '@ente/shared/hooks/useCastReceiver';
-import { addLogLine } from '@ente/shared/logging';
-import castGateway from '@ente/shared/network/cast';
-import LargeType from 'components/LargeType';
-import _sodium from 'libsodium-wrappers';
-import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
-import { storeCastData } from 'services/cast/castService';
+import EnteSpinner from "@ente/shared/components/EnteSpinner";
+import { boxSealOpen, toB64 } from "@ente/shared/crypto/internal/libsodium";
+import { useCastReceiver } from "@ente/shared/hooks/useCastReceiver";
+import { addLogLine } from "@ente/shared/logging";
+import castGateway from "@ente/shared/network/cast";
+import LargeType from "components/LargeType";
+import _sodium from "libsodium-wrappers";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import { storeCastData } from "services/cast/castService";
 
 
 // Function to generate cryptographically secure digits
 // Function to generate cryptographically secure digits
 const generateSecureData = (length: number): Uint8Array => {
 const generateSecureData = (length: number): Uint8Array => {
@@ -21,7 +21,7 @@ const generateSecureData = (length: number): Uint8Array => {
 };
 };
 
 
 const convertDataToDecimalString = (data: Uint8Array): string => {
 const convertDataToDecimalString = (data: Uint8Array): string => {
-    let decimalString = '';
+    let decimalString = "";
     for (let i = 0; i < data.length; i++) {
     for (let i = 0; i < data.length; i++) {
         decimalString += data[i].toString(); // No need to pad, as each value is a single digit
         decimalString += data[i].toString(); // No need to pad, as each value is a single digit
     }
     }
@@ -30,8 +30,8 @@ const convertDataToDecimalString = (data: Uint8Array): string => {
 
 
 export default function PairingMode() {
 export default function PairingMode() {
     const [digits, setDigits] = useState<string[]>([]);
     const [digits, setDigits] = useState<string[]>([]);
-    const [publicKeyB64, setPublicKeyB64] = useState('');
-    const [privateKeyB64, setPrivateKeyB64] = useState('');
+    const [publicKeyB64, setPublicKeyB64] = useState("");
+    const [privateKeyB64, setPrivateKeyB64] = useState("");
     const [codePending, setCodePending] = useState(true);
     const [codePending, setCodePending] = useState(true);
     const [isCastReady, setIsCastReady] = useState(false);
     const [isCastReady, setIsCastReady] = useState(false);
 
 
@@ -49,18 +49,18 @@ export default function PairingMode() {
         try {
         try {
             const options = new cast.framework.CastReceiverOptions();
             const options = new cast.framework.CastReceiverOptions();
             options.customNamespaces = Object.assign({});
             options.customNamespaces = Object.assign({});
-            options.customNamespaces['urn:x-cast:pair-request'] =
+            options.customNamespaces["urn:x-cast:pair-request"] =
                 cast.framework.system.MessageType.JSON;
                 cast.framework.system.MessageType.JSON;
 
 
             options.disableIdleTimeout = true;
             options.disableIdleTimeout = true;
 
 
             context.addCustomMessageListener(
             context.addCustomMessageListener(
-                'urn:x-cast:pair-request',
-                messageReceiveHandler
+                "urn:x-cast:pair-request",
+                messageReceiveHandler,
             );
             );
             context.start(options);
             context.start(options);
         } catch (e) {
         } catch (e) {
-            addLogLine(e, 'failed to create cast context');
+            addLogLine(e, "failed to create cast context");
         }
         }
         setIsCastReady(true);
         setIsCastReady(true);
         return () => {
         return () => {
@@ -74,17 +74,17 @@ export default function PairingMode() {
         data: any;
         data: any;
     }) => {
     }) => {
         cast.framework.CastReceiverContext.getInstance().sendCustomMessage(
         cast.framework.CastReceiverContext.getInstance().sendCustomMessage(
-            'urn:x-cast:pair-request',
+            "urn:x-cast:pair-request",
             message.senderId,
             message.senderId,
             {
             {
-                code: digits.join(''),
-            }
+                code: digits.join(""),
+            },
         );
         );
     };
     };
 
 
     const init = async () => {
     const init = async () => {
         const data = generateSecureData(6);
         const data = generateSecureData(6);
-        setDigits(convertDataToDecimalString(data).split(''));
+        setDigits(convertDataToDecimalString(data).split(""));
         const keypair = await generateKeyPair();
         const keypair = await generateKeyPair();
         setPublicKeyB64(await toB64(keypair.publicKey));
         setPublicKeyB64(await toB64(keypair.publicKey));
         setPrivateKeyB64(await toB64(keypair.privateKey));
         setPrivateKeyB64(await toB64(keypair.privateKey));
@@ -105,10 +105,10 @@ export default function PairingMode() {
         // see if we were acknowledged on the client.
         // see if we were acknowledged on the client.
         // the client will send us the encrypted payload using our public key that we advertised.
         // the client will send us the encrypted payload using our public key that we advertised.
         // then, we can decrypt this and store all the necessary info locally so we can play the collection slideshow.
         // then, we can decrypt this and store all the necessary info locally so we can play the collection slideshow.
-        let devicePayload = '';
+        let devicePayload = "";
         try {
         try {
             const encDastData = await castGateway.getCastData(
             const encDastData = await castGateway.getCastData(
-                `${digits.join('')}`
+                `${digits.join("")}`,
             );
             );
             if (!encDastData) return;
             if (!encDastData) return;
             devicePayload = encDastData;
             devicePayload = encDastData;
@@ -121,7 +121,7 @@ export default function PairingMode() {
         const decryptedPayload = await boxSealOpen(
         const decryptedPayload = await boxSealOpen(
             devicePayload,
             devicePayload,
             publicKeyB64,
             publicKeyB64,
-            privateKeyB64
+            privateKeyB64,
         );
         );
 
 
         const decryptedPayloadObj = JSON.parse(atob(decryptedPayload));
         const decryptedPayloadObj = JSON.parse(atob(decryptedPayload));
@@ -133,8 +133,8 @@ export default function PairingMode() {
         // hey client, we exist!
         // hey client, we exist!
         try {
         try {
             await castGateway.registerDevice(
             await castGateway.registerDevice(
-                `${digits.join('')}`,
-                publicKeyB64
+                `${digits.join("")}`,
+                publicKeyB64,
             );
             );
             setCodePending(false);
             setCodePending(false);
         } catch (e) {
         } catch (e) {
@@ -155,7 +155,7 @@ export default function PairingMode() {
             const data = await pollForCastData();
             const data = await pollForCastData();
             if (!data) return;
             if (!data) return;
             storeCastData(data);
             storeCastData(data);
-            await router.push('/slideshow');
+            await router.push("/slideshow");
         }, 1000);
         }, 1000);
 
 
         return () => {
         return () => {
@@ -172,30 +172,34 @@ export default function PairingMode() {
         <>
         <>
             <div
             <div
                 style={{
                 style={{
-                    height: '100%',
-                    display: 'flex',
-                    justifyContent: 'center',
-                    alignItems: 'center',
-                }}>
+                    height: "100%",
+                    display: "flex",
+                    justifyContent: "center",
+                    alignItems: "center",
+                }}
+            >
                 <div
                 <div
                     style={{
                     style={{
-                        textAlign: 'center',
-                        display: 'flex',
-                        flexDirection: 'column',
-                        alignItems: 'center',
-                    }}>
+                        textAlign: "center",
+                        display: "flex",
+                        flexDirection: "column",
+                        alignItems: "center",
+                    }}
+                >
                     <img width={150} src="/images/ente.svg" />
                     <img width={150} src="/images/ente.svg" />
                     <h1
                     <h1
                         style={{
                         style={{
-                            fontWeight: 'normal',
-                        }}>
+                            fontWeight: "normal",
+                        }}
+                    >
                         Enter this code on <b>ente</b> to pair this TV
                         Enter this code on <b>ente</b> to pair this TV
                     </h1>
                     </h1>
                     <div
                     <div
                         style={{
                         style={{
-                            borderRadius: '10px',
-                            overflow: 'hidden',
-                        }}>
+                            borderRadius: "10px",
+                            overflow: "hidden",
+                        }}
+                    >
                         {codePending ? (
                         {codePending ? (
                             <EnteSpinner />
                             <EnteSpinner />
                         ) : (
                         ) : (
@@ -206,33 +210,36 @@ export default function PairingMode() {
                     </div>
                     </div>
                     <p
                     <p
                         style={{
                         style={{
-                            fontSize: '1.2rem',
-                        }}>
-                        Visit{' '}
+                            fontSize: "1.2rem",
+                        }}
+                    >
+                        Visit{" "}
                         <a
                         <a
                             style={{
                             style={{
-                                textDecoration: 'none',
-                                color: '#87CEFA',
-                                fontWeight: 'bold',
+                                textDecoration: "none",
+                                color: "#87CEFA",
+                                fontWeight: "bold",
                             }}
                             }}
                             href="https://ente.io/cast"
                             href="https://ente.io/cast"
-                            target="_blank">
+                            target="_blank"
+                        >
                             ente.io/cast
                             ente.io/cast
-                        </a>{' '}
+                        </a>{" "}
                         for help
                         for help
                     </p>
                     </p>
                     <div
                     <div
                         style={{
                         style={{
-                            position: 'fixed',
-                            bottom: '20px',
-                            right: '20px',
-                            backgroundColor: 'white',
-                            display: 'flex',
-                            justifyContent: 'center',
-                            alignItems: 'center',
-                            padding: '10px',
-                            borderRadius: '10px',
-                        }}>
+                            position: "fixed",
+                            bottom: "20px",
+                            right: "20px",
+                            backgroundColor: "white",
+                            display: "flex",
+                            justifyContent: "center",
+                            alignItems: "center",
+                            padding: "10px",
+                            borderRadius: "10px",
+                        }}
+                    >
                         <img src="/images/help-qrcode.webp" />
                         <img src="/images/help-qrcode.webp" />
                     </div>
                     </div>
                 </div>
                 </div>

+ 24 - 24
apps/cast/src/pages/slideshow.tsx

@@ -1,17 +1,17 @@
-import { logError } from '@ente/shared/sentry';
-import PairedSuccessfullyOverlay from 'components/PairedSuccessfullyOverlay';
-import Theatre from 'components/Theatre';
-import { FILE_TYPE } from 'constants/file';
-import { useRouter } from 'next/router';
-import { createContext, useEffect, useState } from 'react';
+import { logError } from "@ente/shared/sentry";
+import PairedSuccessfullyOverlay from "components/PairedSuccessfullyOverlay";
+import Theatre from "components/Theatre";
+import { FILE_TYPE } from "constants/file";
+import { useRouter } from "next/router";
+import { createContext, useEffect, useState } from "react";
 import {
 import {
     getCastCollection,
     getCastCollection,
     getLocalFiles,
     getLocalFiles,
     syncPublicFiles,
     syncPublicFiles,
-} from 'services/cast/castService';
-import { Collection } from 'types/collection';
-import { EnteFile } from 'types/file';
-import { getPreviewableImage, isRawFileFromFileName } from 'utils/file';
+} from "services/cast/castService";
+import { Collection } from "types/collection";
+import { EnteFile } from "types/file";
+import { getPreviewableImage, isRawFileFromFileName } from "utils/file";
 
 
 export const SlideshowContext = createContext<{
 export const SlideshowContext = createContext<{
     showNextSlide: () => void;
     showNextSlide: () => void;
@@ -23,24 +23,24 @@ export default function Slideshow() {
     const [collectionFiles, setCollectionFiles] = useState<EnteFile[]>([]);
     const [collectionFiles, setCollectionFiles] = useState<EnteFile[]>([]);
 
 
     const [currentFile, setCurrentFile] = useState<EnteFile | undefined>(
     const [currentFile, setCurrentFile] = useState<EnteFile | undefined>(
-        undefined
+        undefined,
     );
     );
     const [nextFile, setNextFile] = useState<EnteFile | undefined>(undefined);
     const [nextFile, setNextFile] = useState<EnteFile | undefined>(undefined);
 
 
     const [loading, setLoading] = useState(true);
     const [loading, setLoading] = useState(true);
-    const [castToken, setCastToken] = useState<string>('');
+    const [castToken, setCastToken] = useState<string>("");
     const [castCollection, setCastCollection] = useState<
     const [castCollection, setCastCollection] = useState<
         Collection | undefined
         Collection | undefined
     >(undefined);
     >(undefined);
 
 
     const syncCastFiles = async (token: string) => {
     const syncCastFiles = async (token: string) => {
         try {
         try {
-            const castToken = window.localStorage.getItem('castToken');
+            const castToken = window.localStorage.getItem("castToken");
             const requestedCollectionKey =
             const requestedCollectionKey =
-                window.localStorage.getItem('collectionKey');
+                window.localStorage.getItem("collectionKey");
             const collection = await getCastCollection(
             const collection = await getCastCollection(
                 castToken,
                 castToken,
-                requestedCollectionKey
+                requestedCollectionKey,
             );
             );
             if (
             if (
                 castCollection === undefined ||
                 castCollection === undefined ||
@@ -50,22 +50,22 @@ export default function Slideshow() {
                 await syncPublicFiles(token, collection, () => {});
                 await syncPublicFiles(token, collection, () => {});
                 const files = await getLocalFiles(String(collection.id));
                 const files = await getLocalFiles(String(collection.id));
                 setCollectionFiles(
                 setCollectionFiles(
-                    files.filter((file) => isFileEligibleForCast(file))
+                    files.filter((file) => isFileEligibleForCast(file)),
                 );
                 );
             }
             }
         } catch (e) {
         } catch (e) {
-            logError(e, 'error during sync');
-            router.push('/');
+            logError(e, "error during sync");
+            router.push("/");
         }
         }
     };
     };
 
 
     const init = async () => {
     const init = async () => {
         try {
         try {
-            const castToken = window.localStorage.getItem('castToken');
+            const castToken = window.localStorage.getItem("castToken");
             setCastToken(castToken);
             setCastToken(castToken);
         } catch (e) {
         } catch (e) {
-            logError(e, 'error during sync');
-            router.push('/');
+            logError(e, "error during sync");
+            router.push("/");
         }
         }
     };
     };
 
 
@@ -115,7 +115,7 @@ export default function Slideshow() {
 
 
     const showNextSlide = () => {
     const showNextSlide = () => {
         const currentIndex = collectionFiles.findIndex(
         const currentIndex = collectionFiles.findIndex(
-            (file) => file.id === currentFile?.id
+            (file) => file.id === currentFile?.id,
         );
         );
 
 
         const nextIndex = (currentIndex + 1) % collectionFiles.length;
         const nextIndex = (currentIndex + 1) % collectionFiles.length;
@@ -128,7 +128,7 @@ export default function Slideshow() {
         setNextFile(nextNextFile);
         setNextFile(nextNextFile);
     };
     };
 
 
-    const [renderableFileURL, setRenderableFileURL] = useState<string>('');
+    const [renderableFileURL, setRenderableFileURL] = useState<string>("");
 
 
     const getRenderableFileURL = async () => {
     const getRenderableFileURL = async () => {
         if (!currentFile) return;
         if (!currentFile) return;
@@ -143,7 +143,7 @@ export default function Slideshow() {
         try {
         try {
             const blob = await getPreviewableImage(
             const blob = await getPreviewableImage(
                 currentFile as EnteFile,
                 currentFile as EnteFile,
-                castToken
+                castToken,
             );
             );
 
 
             const url = URL.createObjectURL(blob);
             const url = URL.createObjectURL(blob);

+ 3 - 3
apps/cast/src/services/InMemoryStore.ts

@@ -1,7 +1,7 @@
 export enum MS_KEYS {
 export enum MS_KEYS {
-    OPT_OUT_OF_CRASH_REPORTS = 'optOutOfCrashReports',
-    SRP_CONFIGURE_IN_PROGRESS = 'srpConfigureInProgress',
-    REDIRECT_URL = 'redirectUrl',
+    OPT_OUT_OF_CRASH_REPORTS = "optOutOfCrashReports",
+    SRP_CONFIGURE_IN_PROGRESS = "srpConfigureInProgress",
+    REDIRECT_URL = "redirectUrl",
 }
 }
 
 
 type StoreType = Map<Partial<MS_KEYS>, any>;
 type StoreType = Map<Partial<MS_KEYS>, any>;

+ 2 - 2
apps/cast/src/services/cache/cacheStorageFactory.ts

@@ -1,4 +1,4 @@
-import { LimitedCacheStorage } from 'types/cache/index';
+import { LimitedCacheStorage } from "types/cache/index";
 // import { ElectronCacheStorage } from 'services/electron/cache';
 // import { ElectronCacheStorage } from 'services/electron/cache';
 // import { runningInElectron, runningInWorker } from 'utils/common';
 // import { runningInElectron, runningInWorker } from 'utils/common';
 // import { WorkerElectronCacheStorageService } from 'services/workerElectronCache/service';
 // import { WorkerElectronCacheStorageService } from 'services/workerElectronCache/service';
@@ -25,7 +25,7 @@ class cacheStorageFactory {
 export const CacheStorageFactory = new cacheStorageFactory();
 export const CacheStorageFactory = new cacheStorageFactory();
 
 
 function transformBrowserCacheStorageToLimitedCacheStorage(
 function transformBrowserCacheStorageToLimitedCacheStorage(
-    caches: CacheStorage
+    caches: CacheStorage,
 ): LimitedCacheStorage {
 ): LimitedCacheStorage {
     return {
     return {
         async open(cacheName) {
         async open(cacheName) {

+ 6 - 6
apps/cast/src/services/cache/cacheStorageService.ts

@@ -1,8 +1,8 @@
-import { logError } from '@ente/shared/sentry';
-import { CacheStorageFactory } from './cacheStorageFactory';
+import { logError } from "@ente/shared/sentry";
+import { CacheStorageFactory } from "./cacheStorageFactory";
 
 
-const SecurityError = 'SecurityError';
-const INSECURE_OPERATION = 'The operation is insecure.';
+const SecurityError = "SecurityError";
+const INSECURE_OPERATION = "The operation is insecure.";
 async function openCache(cacheName: string) {
 async function openCache(cacheName: string) {
     try {
     try {
         return await CacheStorageFactory.getCacheStorage().open(cacheName);
         return await CacheStorageFactory.getCacheStorage().open(cacheName);
@@ -12,7 +12,7 @@ async function openCache(cacheName: string) {
             // no-op
             // no-op
         } else {
         } else {
             // log and ignore, we don't want to break the caller flow, when cache is not available
             // log and ignore, we don't want to break the caller flow, when cache is not available
-            logError(e, 'openCache failed');
+            logError(e, "openCache failed");
         }
         }
     }
     }
 }
 }
@@ -25,7 +25,7 @@ async function deleteCache(cacheName: string) {
             // no-op
             // no-op
         } else {
         } else {
             // log and ignore, we don't want to break the caller flow, when cache is not available
             // log and ignore, we don't want to break the caller flow, when cache is not available
-            logError(e, 'deleteCache failed');
+            logError(e, "deleteCache failed");
         }
         }
     }
     }
 }
 }

+ 44 - 44
apps/cast/src/services/cast/castService.ts

@@ -1,51 +1,51 @@
-import { getEndpoint } from '@ente/shared/network/api';
-import localForage from '@ente/shared/storage/localForage';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { logError } from '@ente/shared/sentry';
-import { CustomError, parseSharingErrorCodes } from '@ente/shared/error';
-import ComlinkCryptoWorker from '@ente/shared/crypto';
+import ComlinkCryptoWorker from "@ente/shared/crypto";
+import { CustomError, parseSharingErrorCodes } from "@ente/shared/error";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { getEndpoint } from "@ente/shared/network/api";
+import { logError } from "@ente/shared/sentry";
+import localForage from "@ente/shared/storage/localForage";
 
 
-import { Collection, CollectionPublicMagicMetadata } from 'types/collection';
-import { EncryptedEnteFile, EnteFile } from 'types/file';
-import { decryptFile, mergeMetadata, sortFiles } from 'utils/file';
+import { Collection, CollectionPublicMagicMetadata } from "types/collection";
+import { EncryptedEnteFile, EnteFile } from "types/file";
+import { decryptFile, mergeMetadata, sortFiles } from "utils/file";
 
 
 export interface SavedCollectionFiles {
 export interface SavedCollectionFiles {
     collectionLocalID: string;
     collectionLocalID: string;
     files: EnteFile[];
     files: EnteFile[];
 }
 }
 const ENDPOINT = getEndpoint();
 const ENDPOINT = getEndpoint();
-const COLLECTION_FILES_TABLE = 'collection-files';
-const COLLECTIONS_TABLE = 'collections';
+const COLLECTION_FILES_TABLE = "collection-files";
+const COLLECTIONS_TABLE = "collections";
 
 
 const getLastSyncKey = (collectionUID: string) => `${collectionUID}-time`;
 const getLastSyncKey = (collectionUID: string) => `${collectionUID}-time`;
 
 
 export const getLocalFiles = async (
 export const getLocalFiles = async (
-    collectionUID: string
+    collectionUID: string,
 ): Promise<EnteFile[]> => {
 ): Promise<EnteFile[]> => {
     const localSavedcollectionFiles =
     const localSavedcollectionFiles =
         (await localForage.getItem<SavedCollectionFiles[]>(
         (await localForage.getItem<SavedCollectionFiles[]>(
-            COLLECTION_FILES_TABLE
+            COLLECTION_FILES_TABLE,
         )) || [];
         )) || [];
     const matchedCollection = localSavedcollectionFiles.find(
     const matchedCollection = localSavedcollectionFiles.find(
-        (item) => item.collectionLocalID === collectionUID
+        (item) => item.collectionLocalID === collectionUID,
     );
     );
     return matchedCollection?.files || [];
     return matchedCollection?.files || [];
 };
 };
 
 
 const savecollectionFiles = async (
 const savecollectionFiles = async (
     collectionUID: string,
     collectionUID: string,
-    files: EnteFile[]
+    files: EnteFile[],
 ) => {
 ) => {
     const collectionFiles =
     const collectionFiles =
         (await localForage.getItem<SavedCollectionFiles[]>(
         (await localForage.getItem<SavedCollectionFiles[]>(
-            COLLECTION_FILES_TABLE
+            COLLECTION_FILES_TABLE,
         )) || [];
         )) || [];
     await localForage.setItem(
     await localForage.setItem(
         COLLECTION_FILES_TABLE,
         COLLECTION_FILES_TABLE,
         dedupeCollectionFiles([
         dedupeCollectionFiles([
             { collectionLocalID: collectionUID, files },
             { collectionLocalID: collectionUID, files },
             ...collectionFiles,
             ...collectionFiles,
-        ])
+        ]),
     );
     );
 };
 };
 
 
@@ -55,7 +55,7 @@ export const getLocalCollections = async (collectionKey: string) => {
     const collection =
     const collection =
         localCollections.find(
         localCollections.find(
             (localSavedPublicCollection) =>
             (localSavedPublicCollection) =>
-                localSavedPublicCollection.key === collectionKey
+                localSavedPublicCollection.key === collectionKey,
         ) || null;
         ) || null;
     return collection;
     return collection;
 };
 };
@@ -65,7 +65,7 @@ const saveCollection = async (collection: Collection) => {
         (await localForage.getItem<Collection[]>(COLLECTIONS_TABLE)) ?? [];
         (await localForage.getItem<Collection[]>(COLLECTIONS_TABLE)) ?? [];
     await localForage.setItem(
     await localForage.setItem(
         COLLECTIONS_TABLE,
         COLLECTIONS_TABLE,
-        dedupeCollections([collection, ...collections])
+        dedupeCollections([collection, ...collections]),
     );
     );
 };
 };
 
 
@@ -105,7 +105,7 @@ const updateSyncTime = async (collectionUID: string, time: number) =>
 export const syncPublicFiles = async (
 export const syncPublicFiles = async (
     token: string,
     token: string,
     collection: Collection,
     collection: Collection,
-    setPublicFiles: (files: EnteFile[]) => void
+    setPublicFiles: (files: EnteFile[]) => void,
 ) => {
 ) => {
     try {
     try {
         let files: EnteFile[] = [];
         let files: EnteFile[] = [];
@@ -123,7 +123,7 @@ export const syncPublicFiles = async (
                 collection,
                 collection,
                 lastSyncTime,
                 lastSyncTime,
                 files,
                 files,
-                setPublicFiles
+                setPublicFiles,
             );
             );
 
 
             files = [...files, ...fetchedFiles];
             files = [...files, ...fetchedFiles];
@@ -150,14 +150,14 @@ export const syncPublicFiles = async (
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
             setPublicFiles([...sortFiles(mergeMetadata(files), sortAsc)]);
         } catch (e) {
         } catch (e) {
             const parsedError = parseSharingErrorCodes(e);
             const parsedError = parseSharingErrorCodes(e);
-            logError(e, 'failed to sync shared collection files');
+            logError(e, "failed to sync shared collection files");
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
             if (parsedError.message === CustomError.TOKEN_EXPIRED) {
                 throw e;
                 throw e;
             }
             }
         }
         }
         return [...sortFiles(mergeMetadata(files), sortAsc)];
         return [...sortFiles(mergeMetadata(files), sortAsc)];
     } catch (e) {
     } catch (e) {
-        logError(e, 'failed to get local  or sync shared collection files');
+        logError(e, "failed to get local  or sync shared collection files");
         throw e;
         throw e;
     }
     }
 };
 };
@@ -167,7 +167,7 @@ const fetchFiles = async (
     collection: Collection,
     collection: Collection,
     sinceTime: number,
     sinceTime: number,
     files: EnteFile[],
     files: EnteFile[],
-    setPublicFiles: (files: EnteFile[]) => void
+    setPublicFiles: (files: EnteFile[]) => void,
 ): Promise<EnteFile[]> => {
 ): Promise<EnteFile[]> => {
     try {
     try {
         let decryptedFiles: EnteFile[] = [];
         let decryptedFiles: EnteFile[] = [];
@@ -184,9 +184,9 @@ const fetchFiles = async (
                     sinceTime: time,
                     sinceTime: time,
                 },
                 },
                 {
                 {
-                    'Cache-Control': 'no-cache',
-                    'X-Cast-Access-Token': castToken,
-                }
+                    "Cache-Control": "no-cache",
+                    "X-Cast-Access-Token": castToken,
+                },
             );
             );
             decryptedFiles = [
             decryptedFiles = [
                 ...decryptedFiles,
                 ...decryptedFiles,
@@ -197,7 +197,7 @@ const fetchFiles = async (
                         } else {
                         } else {
                             return file;
                             return file;
                         }
                         }
-                    }) as Promise<EnteFile>[]
+                    }) as Promise<EnteFile>[],
                 )),
                 )),
             ];
             ];
 
 
@@ -208,28 +208,28 @@ const fetchFiles = async (
                 sortFiles(
                 sortFiles(
                     mergeMetadata(
                     mergeMetadata(
                         [...(files || []), ...decryptedFiles].filter(
                         [...(files || []), ...decryptedFiles].filter(
-                            (item) => !item.isDeleted
-                        )
+                            (item) => !item.isDeleted,
+                        ),
                     ),
                     ),
-                    sortAsc
-                )
+                    sortAsc,
+                ),
             );
             );
         } while (resp.data.hasMore);
         } while (resp.data.hasMore);
         return decryptedFiles;
         return decryptedFiles;
     } catch (e) {
     } catch (e) {
-        logError(e, 'Get cast files failed');
+        logError(e, "Get cast files failed");
         throw e;
         throw e;
     }
     }
 };
 };
 
 
 export const getCastCollection = async (
 export const getCastCollection = async (
     castToken: string,
     castToken: string,
-    collectionKey: string
+    collectionKey: string,
 ): Promise<Collection> => {
 ): Promise<Collection> => {
     try {
     try {
         const resp = await HTTPService.get(`${ENDPOINT}/cast/info`, null, {
         const resp = await HTTPService.get(`${ENDPOINT}/cast/info`, null, {
-            'Cache-Control': 'no-cache',
-            'X-Cast-Access-Token': castToken,
+            "Cache-Control": "no-cache",
+            "X-Cast-Access-Token": castToken,
         });
         });
         const fetchedCollection = resp.data.collection;
         const fetchedCollection = resp.data.collection;
 
 
@@ -240,7 +240,7 @@ export const getCastCollection = async (
             (await cryptoWorker.decryptToUTF8(
             (await cryptoWorker.decryptToUTF8(
                 fetchedCollection.encryptedName,
                 fetchedCollection.encryptedName,
                 fetchedCollection.nameDecryptionNonce,
                 fetchedCollection.nameDecryptionNonce,
-                collectionKey
+                collectionKey,
             )));
             )));
 
 
         let collectionPublicMagicMetadata: CollectionPublicMagicMetadata;
         let collectionPublicMagicMetadata: CollectionPublicMagicMetadata;
@@ -250,7 +250,7 @@ export const getCastCollection = async (
                 data: await cryptoWorker.decryptMetadata(
                 data: await cryptoWorker.decryptMetadata(
                     fetchedCollection.pubMagicMetadata.data,
                     fetchedCollection.pubMagicMetadata.data,
                     fetchedCollection.pubMagicMetadata.header,
                     fetchedCollection.pubMagicMetadata.header,
-                    collectionKey
+                    collectionKey,
                 ),
                 ),
             };
             };
         }
         }
@@ -264,20 +264,20 @@ export const getCastCollection = async (
         await saveCollection(collection);
         await saveCollection(collection);
         return collection;
         return collection;
     } catch (e) {
     } catch (e) {
-        logError(e, 'failed to get cast collection');
+        logError(e, "failed to get cast collection");
         throw e;
         throw e;
     }
     }
 };
 };
 
 
 export const removeCollection = async (
 export const removeCollection = async (
     collectionUID: string,
     collectionUID: string,
-    collectionKey: string
+    collectionKey: string,
 ) => {
 ) => {
     const collections =
     const collections =
         (await localForage.getItem<Collection[]>(COLLECTIONS_TABLE)) || [];
         (await localForage.getItem<Collection[]>(COLLECTIONS_TABLE)) || [];
     await localForage.setItem(
     await localForage.setItem(
         COLLECTIONS_TABLE,
         COLLECTIONS_TABLE,
-        collections.filter((collection) => collection.key !== collectionKey)
+        collections.filter((collection) => collection.key !== collectionKey),
     );
     );
     await removeCollectionFiles(collectionUID);
     await removeCollectionFiles(collectionUID);
 };
 };
@@ -286,14 +286,14 @@ export const removeCollectionFiles = async (collectionUID: string) => {
     await localForage.removeItem(getLastSyncKey(collectionUID));
     await localForage.removeItem(getLastSyncKey(collectionUID));
     const collectionFiles =
     const collectionFiles =
         (await localForage.getItem<SavedCollectionFiles[]>(
         (await localForage.getItem<SavedCollectionFiles[]>(
-            COLLECTION_FILES_TABLE
+            COLLECTION_FILES_TABLE,
         )) ?? [];
         )) ?? [];
     await localForage.setItem(
     await localForage.setItem(
         COLLECTION_FILES_TABLE,
         COLLECTION_FILES_TABLE,
         collectionFiles.filter(
         collectionFiles.filter(
             (collectionFiles) =>
             (collectionFiles) =>
-                collectionFiles.collectionLocalID !== collectionUID
-        )
+                collectionFiles.collectionLocalID !== collectionUID,
+        ),
     );
     );
 };
 };
 
 

+ 38 - 38
apps/cast/src/services/castDownloadManager.ts

@@ -1,19 +1,19 @@
+import { EnteFile } from "types/file";
 import {
 import {
+    createTypedObjectURL,
     generateStreamFromArrayBuffer,
     generateStreamFromArrayBuffer,
     getRenderableFileURL,
     getRenderableFileURL,
-    createTypedObjectURL,
-} from 'utils/file';
-import { EnteFile } from 'types/file';
+} from "utils/file";
 
 
-import { FILE_TYPE } from 'constants/file';
-import { CustomError } from '@ente/shared/error';
-import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
-import { CACHES } from 'constants/cache';
-import { CacheStorageService } from './cache/cacheStorageService';
-import { LimitedCache } from 'types/cache';
-import { getCastFileURL, getCastThumbnailURL } from '@ente/shared/network/api';
-import HTTPService from '@ente/shared/network/HTTPService';
-import { logError } from '@ente/shared/sentry';
+import { CustomError } from "@ente/shared/error";
+import HTTPService from "@ente/shared/network/HTTPService";
+import { getCastFileURL, getCastThumbnailURL } from "@ente/shared/network/api";
+import { logError } from "@ente/shared/sentry";
+import { CACHES } from "constants/cache";
+import { FILE_TYPE } from "constants/file";
+import { LimitedCache } from "types/cache";
+import ComlinkCryptoWorker from "utils/comlink/ComlinkCryptoWorker";
+import { CacheStorageService } from "./cache/cacheStorageService";
 
 
 class CastDownloadManager {
 class CastDownloadManager {
     private fileObjectURLPromise = new Map<
     private fileObjectURLPromise = new Map<
@@ -33,7 +33,7 @@ class CastDownloadManager {
     private async getThumbnailCache() {
     private async getThumbnailCache() {
         try {
         try {
             const thumbnailCache = await CacheStorageService.open(
             const thumbnailCache = await CacheStorageService.open(
-                CACHES.THUMBS
+                CACHES.THUMBS,
             );
             );
             return thumbnailCache;
             return thumbnailCache;
         } catch (e) {
         } catch (e) {
@@ -44,14 +44,14 @@ class CastDownloadManager {
 
 
     public async getCachedThumbnail(
     public async getCachedThumbnail(
         file: EnteFile,
         file: EnteFile,
-        thumbnailCache?: LimitedCache
+        thumbnailCache?: LimitedCache,
     ) {
     ) {
         try {
         try {
             if (!thumbnailCache) {
             if (!thumbnailCache) {
                 thumbnailCache = await this.getThumbnailCache();
                 thumbnailCache = await this.getThumbnailCache();
             }
             }
             const cacheResp: Response = await thumbnailCache?.match(
             const cacheResp: Response = await thumbnailCache?.match(
-                file.id.toString()
+                file.id.toString(),
             );
             );
 
 
             if (cacheResp) {
             if (cacheResp) {
@@ -59,7 +59,7 @@ class CastDownloadManager {
             }
             }
             return null;
             return null;
         } catch (e) {
         } catch (e) {
-            logError(e, 'failed to get cached thumbnail');
+            logError(e, "failed to get cached thumbnail");
             throw e;
             throw e;
         }
         }
     }
     }
@@ -71,7 +71,7 @@ class CastDownloadManager {
                     const thumbnailCache = await this.getThumbnailCache();
                     const thumbnailCache = await this.getThumbnailCache();
                     const cachedThumb = await this.getCachedThumbnail(
                     const cachedThumb = await this.getCachedThumbnail(
                         file,
                         file,
-                        thumbnailCache
+                        thumbnailCache,
                     );
                     );
                     if (cachedThumb) {
                     if (cachedThumb) {
                         return cachedThumb;
                         return cachedThumb;
@@ -82,7 +82,7 @@ class CastDownloadManager {
                     try {
                     try {
                         await thumbnailCache?.put(
                         await thumbnailCache?.put(
                             file.id.toString(),
                             file.id.toString(),
-                            new Response(thumbBlob)
+                            new Response(thumbBlob),
                         );
                         );
                     } catch (e) {
                     } catch (e) {
                         // TODO: handle storage full exception.
                         // TODO: handle storage full exception.
@@ -95,7 +95,7 @@ class CastDownloadManager {
             return await this.thumbnailObjectURLPromise.get(file.id);
             return await this.thumbnailObjectURLPromise.get(file.id);
         } catch (e) {
         } catch (e) {
             this.thumbnailObjectURLPromise.delete(file.id);
             this.thumbnailObjectURLPromise.delete(file.id);
-            logError(e, 'get castDownloadManager preview Failed');
+            logError(e, "get castDownloadManager preview Failed");
             throw e;
             throw e;
         }
         }
     }
     }
@@ -105,18 +105,18 @@ class CastDownloadManager {
             getCastThumbnailURL(file.id),
             getCastThumbnailURL(file.id),
             null,
             null,
             {
             {
-                'X-Cast-Access-Token': castToken,
+                "X-Cast-Access-Token": castToken,
             },
             },
-            { responseType: 'arraybuffer' }
+            { responseType: "arraybuffer" },
         );
         );
-        if (typeof resp.data === 'undefined') {
+        if (typeof resp.data === "undefined") {
             throw Error(CustomError.REQUEST_FAILED);
             throw Error(CustomError.REQUEST_FAILED);
         }
         }
         const cryptoWorker = await ComlinkCryptoWorker.getInstance();
         const cryptoWorker = await ComlinkCryptoWorker.getInstance();
         const decrypted = await cryptoWorker.decryptThumbnail(
         const decrypted = await cryptoWorker.decryptThumbnail(
             new Uint8Array(resp.data),
             new Uint8Array(resp.data),
             await cryptoWorker.fromB64(file.thumbnail.decryptionHeader),
             await cryptoWorker.fromB64(file.thumbnail.decryptionHeader),
-            file.key
+            file.key,
         );
         );
         return decrypted;
         return decrypted;
     };
     };
@@ -132,7 +132,7 @@ class CastDownloadManager {
                 } else {
                 } else {
                     const fileURL = await createTypedObjectURL(
                     const fileURL = await createTypedObjectURL(
                         fileBlob,
                         fileBlob,
-                        file.metadata.title
+                        file.metadata.title,
                     );
                     );
                     return { converted: [fileURL], original: [fileURL] };
                     return { converted: [fileURL], original: [fileURL] };
                 }
                 }
@@ -145,7 +145,7 @@ class CastDownloadManager {
             return fileURLs;
             return fileURLs;
         } catch (e) {
         } catch (e) {
             this.fileObjectURLPromise.delete(fileKey);
             this.fileObjectURLPromise.delete(fileKey);
-            logError(e, 'castDownloadManager failed to get file');
+            logError(e, "castDownloadManager failed to get file");
             throw e;
             throw e;
         }
         }
     };
     };
@@ -166,40 +166,40 @@ class CastDownloadManager {
                 getCastFileURL(file.id),
                 getCastFileURL(file.id),
                 null,
                 null,
                 {
                 {
-                    'X-Cast-Access-Token': castToken,
+                    "X-Cast-Access-Token": castToken,
                 },
                 },
-                { responseType: 'arraybuffer' }
+                { responseType: "arraybuffer" },
             );
             );
-            if (typeof resp.data === 'undefined') {
+            if (typeof resp.data === "undefined") {
                 throw Error(CustomError.REQUEST_FAILED);
                 throw Error(CustomError.REQUEST_FAILED);
             }
             }
             const decrypted = await cryptoWorker.decryptFile(
             const decrypted = await cryptoWorker.decryptFile(
                 new Uint8Array(resp.data),
                 new Uint8Array(resp.data),
                 await cryptoWorker.fromB64(file.file.decryptionHeader),
                 await cryptoWorker.fromB64(file.file.decryptionHeader),
-                file.key
+                file.key,
             );
             );
             return generateStreamFromArrayBuffer(decrypted);
             return generateStreamFromArrayBuffer(decrypted);
         }
         }
         const resp = await fetch(getCastFileURL(file.id), {
         const resp = await fetch(getCastFileURL(file.id), {
             headers: {
             headers: {
-                'X-Cast-Access-Token': castToken,
+                "X-Cast-Access-Token": castToken,
             },
             },
         });
         });
         const reader = resp.body.getReader();
         const reader = resp.body.getReader();
 
 
-        const contentLength = +resp.headers.get('Content-Length');
+        const contentLength = +resp.headers.get("Content-Length");
         let downloadedBytes = 0;
         let downloadedBytes = 0;
 
 
         const stream = new ReadableStream({
         const stream = new ReadableStream({
             async start(controller) {
             async start(controller) {
                 const decryptionHeader = await cryptoWorker.fromB64(
                 const decryptionHeader = await cryptoWorker.fromB64(
-                    file.file.decryptionHeader
+                    file.file.decryptionHeader,
                 );
                 );
                 const fileKey = await cryptoWorker.fromB64(file.key);
                 const fileKey = await cryptoWorker.fromB64(file.key);
                 const { pullState, decryptionChunkSize } =
                 const { pullState, decryptionChunkSize } =
                     await cryptoWorker.initChunkDecryption(
                     await cryptoWorker.initChunkDecryption(
                         decryptionHeader,
                         decryptionHeader,
-                        fileKey
+                        fileKey,
                     );
                     );
                 let data = new Uint8Array();
                 let data = new Uint8Array();
                 // The following function handles each data chunk
                 // The following function handles each data chunk
@@ -214,19 +214,19 @@ class CastDownloadManager {
                                 total: contentLength,
                                 total: contentLength,
                             });
                             });
                             const buffer = new Uint8Array(
                             const buffer = new Uint8Array(
-                                data.byteLength + value.byteLength
+                                data.byteLength + value.byteLength,
                             );
                             );
                             buffer.set(new Uint8Array(data), 0);
                             buffer.set(new Uint8Array(data), 0);
                             buffer.set(new Uint8Array(value), data.byteLength);
                             buffer.set(new Uint8Array(value), data.byteLength);
                             if (buffer.length > decryptionChunkSize) {
                             if (buffer.length > decryptionChunkSize) {
                                 const fileData = buffer.slice(
                                 const fileData = buffer.slice(
                                     0,
                                     0,
-                                    decryptionChunkSize
+                                    decryptionChunkSize,
                                 );
                                 );
                                 const { decryptedData } =
                                 const { decryptedData } =
                                     await cryptoWorker.decryptFileChunk(
                                     await cryptoWorker.decryptFileChunk(
                                         fileData,
                                         fileData,
-                                        pullState
+                                        pullState,
                                     );
                                     );
                                 controller.enqueue(decryptedData);
                                 controller.enqueue(decryptedData);
                                 data = buffer.slice(decryptionChunkSize);
                                 data = buffer.slice(decryptionChunkSize);
@@ -239,7 +239,7 @@ class CastDownloadManager {
                                 const { decryptedData } =
                                 const { decryptedData } =
                                     await cryptoWorker.decryptFileChunk(
                                     await cryptoWorker.decryptFileChunk(
                                         data,
                                         data,
-                                        pullState
+                                        pullState,
                                     );
                                     );
                                 controller.enqueue(decryptedData);
                                 controller.enqueue(decryptedData);
                                 data = null;
                                 data = null;
@@ -262,7 +262,7 @@ class CastDownloadManager {
             } else {
             } else {
                 this.fileDownloadProgress.set(
                 this.fileDownloadProgress.set(
                     fileID,
                     fileID,
-                    Math.round((event.loaded * 100) / event.total)
+                    Math.round((event.loaded * 100) / event.total),
                 );
                 );
             }
             }
             this.progressUpdater(new Map(this.fileDownloadProgress));
             this.progressUpdater(new Map(this.fileDownloadProgress));

+ 4 - 4
apps/cast/src/services/events.ts

@@ -1,12 +1,12 @@
-import { EventEmitter } from 'eventemitter3';
+import { EventEmitter } from "eventemitter3";
 
 
 // When registering event handlers,
 // When registering event handlers,
 // handle errors to avoid unhandled rejection or propagation to emit call
 // handle errors to avoid unhandled rejection or propagation to emit call
 
 
 export enum Events {
 export enum Events {
-    LOGOUT = 'logout',
-    FILE_UPLOADED = 'fileUploaded',
-    LOCAL_FILES_UPDATED = 'localFilesUpdated',
+    LOGOUT = "logout",
+    FILE_UPLOADED = "fileUploaded",
+    LOCAL_FILES_UPDATED = "localFilesUpdated",
 }
 }
 
 
 export const eventBus = new EventEmitter<Events>();
 export const eventBus = new EventEmitter<Events>();

+ 3 - 3
apps/cast/src/services/ffmpeg/ffmpegFactory.ts

@@ -1,14 +1,14 @@
 // import isElectron from 'is-electron';
 // import isElectron from 'is-electron';
 // import { ElectronFFmpeg } from 'services/electron/ffmpeg';
 // import { ElectronFFmpeg } from 'services/electron/ffmpeg';
-import { ElectronFile } from 'types/upload';
-import ComlinkFFmpegWorker from 'utils/comlink/ComlinkFFmpegWorker';
+import { ElectronFile } from "types/upload";
+import ComlinkFFmpegWorker from "utils/comlink/ComlinkFFmpegWorker";
 
 
 export interface IFFmpeg {
 export interface IFFmpeg {
     run: (
     run: (
         cmd: string[],
         cmd: string[],
         inputFile: File | ElectronFile,
         inputFile: File | ElectronFile,
         outputFilename: string,
         outputFilename: string,
-        dontTimeout?: boolean
+        dontTimeout?: boolean,
     ) => Promise<File | ElectronFile>;
     ) => Promise<File | ElectronFile>;
 }
 }
 
 

+ 10 - 10
apps/cast/src/services/ffmpeg/ffmpegService.ts

@@ -1,11 +1,11 @@
+import { logError } from "@ente/shared/sentry";
 import {
 import {
     FFMPEG_PLACEHOLDER,
     FFMPEG_PLACEHOLDER,
     INPUT_PATH_PLACEHOLDER,
     INPUT_PATH_PLACEHOLDER,
     OUTPUT_PATH_PLACEHOLDER,
     OUTPUT_PATH_PLACEHOLDER,
-} from 'constants/ffmpeg';
-import { ElectronFile } from 'types/upload';
-import ffmpegFactory from './ffmpegFactory';
-import { logError } from '@ente/shared/sentry';
+} from "constants/ffmpeg";
+import { ElectronFile } from "types/upload";
+import ffmpegFactory from "./ffmpegFactory";
 
 
 export async function convertToMP4(file: File | ElectronFile) {
 export async function convertToMP4(file: File | ElectronFile) {
     try {
     try {
@@ -13,18 +13,18 @@ export async function convertToMP4(file: File | ElectronFile) {
         return await ffmpegClient.run(
         return await ffmpegClient.run(
             [
             [
                 FFMPEG_PLACEHOLDER,
                 FFMPEG_PLACEHOLDER,
-                '-i',
+                "-i",
                 INPUT_PATH_PLACEHOLDER,
                 INPUT_PATH_PLACEHOLDER,
-                '-preset',
-                'ultrafast',
+                "-preset",
+                "ultrafast",
                 OUTPUT_PATH_PLACEHOLDER,
                 OUTPUT_PATH_PLACEHOLDER,
             ],
             ],
             file,
             file,
-            'output.mp4',
-            true
+            "output.mp4",
+            true,
         );
         );
     } catch (e) {
     } catch (e) {
-        logError(e, 'ffmpeg convertToMP4 failed');
+        logError(e, "ffmpeg convertToMP4 failed");
         throw e;
         throw e;
     }
     }
 }
 }

+ 3 - 3
apps/cast/src/services/heicConversionService.ts

@@ -1,12 +1,12 @@
-import { logError } from '@ente/shared/sentry';
-import WasmHEICConverterService from './wasmHeicConverter/wasmHEICConverterService';
+import { logError } from "@ente/shared/sentry";
+import WasmHEICConverterService from "./wasmHeicConverter/wasmHEICConverterService";
 
 
 class HeicConversionService {
 class HeicConversionService {
     async convert(heicFileData: Blob): Promise<Blob> {
     async convert(heicFileData: Blob): Promise<Blob> {
         try {
         try {
             return await WasmHEICConverterService.convert(heicFileData);
             return await WasmHEICConverterService.convert(heicFileData);
         } catch (e) {
         } catch (e) {
-            logError(e, 'failed to convert heic file');
+            logError(e, "failed to convert heic file");
             throw e;
             throw e;
         }
         }
     }
     }

+ 12 - 12
apps/cast/src/services/livePhotoService.ts

@@ -1,9 +1,9 @@
-import JSZip from 'jszip';
-import { EnteFile } from 'types/file';
+import JSZip from "jszip";
+import { EnteFile } from "types/file";
 import {
 import {
     getFileExtensionWithDot,
     getFileExtensionWithDot,
     getFileNameWithoutExtension,
     getFileNameWithoutExtension,
-} from 'utils/file';
+} from "utils/file";
 
 
 class LivePhoto {
 class LivePhoto {
     image: Uint8Array;
     image: Uint8Array;
@@ -18,14 +18,14 @@ export const decodeLivePhoto = async (file: EnteFile, zipBlob: Blob) => {
 
 
     const livePhoto = new LivePhoto();
     const livePhoto = new LivePhoto();
     for (const zipFilename in zip.files) {
     for (const zipFilename in zip.files) {
-        if (zipFilename.startsWith('image')) {
+        if (zipFilename.startsWith("image")) {
             livePhoto.imageNameTitle =
             livePhoto.imageNameTitle =
                 originalName + getFileExtensionWithDot(zipFilename);
                 originalName + getFileExtensionWithDot(zipFilename);
-            livePhoto.image = await zip.files[zipFilename].async('uint8array');
-        } else if (zipFilename.startsWith('video')) {
+            livePhoto.image = await zip.files[zipFilename].async("uint8array");
+        } else if (zipFilename.startsWith("video")) {
             livePhoto.videoNameTitle =
             livePhoto.videoNameTitle =
                 originalName + getFileExtensionWithDot(zipFilename);
                 originalName + getFileExtensionWithDot(zipFilename);
-            livePhoto.video = await zip.files[zipFilename].async('uint8array');
+            livePhoto.video = await zip.files[zipFilename].async("uint8array");
         }
         }
     }
     }
     return livePhoto;
     return livePhoto;
@@ -34,12 +34,12 @@ export const decodeLivePhoto = async (file: EnteFile, zipBlob: Blob) => {
 export const encodeLivePhoto = async (livePhoto: LivePhoto) => {
 export const encodeLivePhoto = async (livePhoto: LivePhoto) => {
     const zip = new JSZip();
     const zip = new JSZip();
     zip.file(
     zip.file(
-        'image' + getFileExtensionWithDot(livePhoto.imageNameTitle),
-        livePhoto.image
+        "image" + getFileExtensionWithDot(livePhoto.imageNameTitle),
+        livePhoto.image,
     );
     );
     zip.file(
     zip.file(
-        'video' + getFileExtensionWithDot(livePhoto.videoNameTitle),
-        livePhoto.video
+        "video" + getFileExtensionWithDot(livePhoto.videoNameTitle),
+        livePhoto.video,
     );
     );
-    return await zip.generateAsync({ type: 'uint8array' });
+    return await zip.generateAsync({ type: "uint8array" });
 };
 };

+ 3 - 3
apps/cast/src/services/queueProcessor.ts

@@ -1,4 +1,4 @@
-import { CustomError } from '@ente/shared/error';
+import { CustomError } from "@ente/shared/error";
 
 
 interface RequestQueueItem {
 interface RequestQueueItem {
     request: (canceller?: RequestCanceller) => Promise<any>;
     request: (canceller?: RequestCanceller) => Promise<any>;
@@ -28,11 +28,11 @@ export default class QueueProcessor<T> {
 
 
     constructor(
     constructor(
         private maxParallelProcesses: number,
         private maxParallelProcesses: number,
-        private processingStrategy = PROCESSING_STRATEGY.FIFO
+        private processingStrategy = PROCESSING_STRATEGY.FIFO,
     ) {}
     ) {}
 
 
     public queueUpRequest(
     public queueUpRequest(
-        request: (canceller?: RequestCanceller) => Promise<T>
+        request: (canceller?: RequestCanceller) => Promise<T>,
     ) {
     ) {
         const isCanceled: CancellationStatus = { status: false };
         const isCanceled: CancellationStatus = { status: false };
         const canceller: RequestCanceller = {
         const canceller: RequestCanceller = {

+ 14 - 14
apps/cast/src/services/readerService.ts

@@ -1,14 +1,14 @@
-import { logError } from '@ente/shared/sentry';
-import { convertBytesToHumanReadable } from '@ente/shared/utils/size';
-import { ElectronFile } from 'types/upload';
+import { logError } from "@ente/shared/sentry";
+import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
+import { ElectronFile } from "types/upload";
 
 
 export async function getUint8ArrayView(
 export async function getUint8ArrayView(
-    file: Blob | ElectronFile
+    file: Blob | ElectronFile,
 ): Promise<Uint8Array> {
 ): Promise<Uint8Array> {
     try {
     try {
         return new Uint8Array(await file.arrayBuffer());
         return new Uint8Array(await file.arrayBuffer());
     } catch (e) {
     } catch (e) {
-        logError(e, 'reading file blob failed', {
+        logError(e, "reading file blob failed", {
             fileSize: convertBytesToHumanReadable(file.size),
             fileSize: convertBytesToHumanReadable(file.size),
         });
         });
         throw e;
         throw e;
@@ -37,7 +37,7 @@ export function getFileStream(file: File, chunkSize: number) {
 
 
 export async function getElectronFileStream(
 export async function getElectronFileStream(
     file: ElectronFile,
     file: ElectronFile,
-    chunkSize: number
+    chunkSize: number,
 ) {
 ) {
     const chunkCount = Math.ceil(file.size / chunkSize);
     const chunkCount = Math.ceil(file.size / chunkSize);
     return {
     return {
@@ -61,29 +61,29 @@ async function* fileChunkReaderMaker(file: File, chunkSize: number) {
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 async function getUint8ArrayViewOld(
 async function getUint8ArrayViewOld(
     reader: FileReader,
     reader: FileReader,
-    file: Blob
+    file: Blob,
 ): Promise<Uint8Array> {
 ): Promise<Uint8Array> {
     return await new Promise((resolve, reject) => {
     return await new Promise((resolve, reject) => {
         reader.onabort = () =>
         reader.onabort = () =>
             reject(
             reject(
                 Error(
                 Error(
                     `file reading was aborted, file size= ${convertBytesToHumanReadable(
                     `file reading was aborted, file size= ${convertBytesToHumanReadable(
-                        file.size
-                    )}`
-                )
+                        file.size,
+                    )}`,
+                ),
             );
             );
         reader.onerror = () =>
         reader.onerror = () =>
             reject(
             reject(
                 Error(
                 Error(
                     `file reading has failed, file size= ${convertBytesToHumanReadable(
                     `file reading has failed, file size= ${convertBytesToHumanReadable(
-                        file.size
-                    )} , reason= ${reader.error}`
-                )
+                        file.size,
+                    )} , reason= ${reader.error}`,
+                ),
             );
             );
         reader.onload = () => {
         reader.onload = () => {
             // Do whatever you want with the file contents
             // Do whatever you want with the file contents
             const result =
             const result =
-                typeof reader.result === 'string'
+                typeof reader.result === "string"
                     ? new TextEncoder().encode(reader.result)
                     ? new TextEncoder().encode(reader.result)
                     : new Uint8Array(reader.result);
                     : new Uint8Array(reader.result);
             resolve(result);
             resolve(result);

+ 19 - 19
apps/cast/src/services/typeDetectionService.ts

@@ -1,26 +1,26 @@
-import { FILE_TYPE } from 'constants/file';
-import { ElectronFile, FileTypeInfo } from 'types/upload';
+import { CustomError } from "@ente/shared/error";
+import { logError } from "@ente/shared/sentry";
+import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
+import { FILE_TYPE } from "constants/file";
 import {
 import {
-    WHITELISTED_FILE_FORMATS,
     KNOWN_NON_MEDIA_FORMATS,
     KNOWN_NON_MEDIA_FORMATS,
-} from 'constants/upload';
-import { CustomError } from '@ente/shared/error';
-import { getFileExtension } from 'utils/file';
-import { logError } from '@ente/shared/sentry';
-import { getUint8ArrayView } from './readerService';
-import FileType, { FileTypeResult } from 'file-type';
-import { convertBytesToHumanReadable } from '@ente/shared/utils/size';
+    WHITELISTED_FILE_FORMATS,
+} from "constants/upload";
+import FileType, { FileTypeResult } from "file-type";
+import { ElectronFile, FileTypeInfo } from "types/upload";
+import { getFileExtension } from "utils/file";
+import { getUint8ArrayView } from "./readerService";
 
 
 function getFileSize(file: File | ElectronFile) {
 function getFileSize(file: File | ElectronFile) {
     return file.size;
     return file.size;
 }
 }
 
 
-const TYPE_VIDEO = 'video';
-const TYPE_IMAGE = 'image';
+const TYPE_VIDEO = "video";
+const TYPE_IMAGE = "image";
 const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100;
 const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100;
 
 
 export async function getFileType(
 export async function getFileType(
-    receivedFile: File | ElectronFile
+    receivedFile: File | ElectronFile,
 ): Promise<FileTypeInfo> {
 ): Promise<FileTypeInfo> {
     try {
     try {
         let fileType: FILE_TYPE;
         let fileType: FILE_TYPE;
@@ -32,7 +32,7 @@ export async function getFileType(
             typeResult = await extractElectronFileType(receivedFile);
             typeResult = await extractElectronFileType(receivedFile);
         }
         }
 
 
-        const mimTypeParts: string[] = typeResult.mime?.split('/');
+        const mimTypeParts: string[] = typeResult.mime?.split("/");
 
 
         if (mimTypeParts?.length !== 2) {
         if (mimTypeParts?.length !== 2) {
             throw Error(CustomError.INVALID_MIME_TYPE(typeResult.mime));
             throw Error(CustomError.INVALID_MIME_TYPE(typeResult.mime));
@@ -56,7 +56,7 @@ export async function getFileType(
         const fileFormat = getFileExtension(receivedFile.name);
         const fileFormat = getFileExtension(receivedFile.name);
         const fileSize = convertBytesToHumanReadable(getFileSize(receivedFile));
         const fileSize = convertBytesToHumanReadable(getFileSize(receivedFile));
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
         const whiteListedFormat = WHITELISTED_FILE_FORMATS.find(
-            (a) => a.exactType === fileFormat
+            (a) => a.exactType === fileFormat,
         );
         );
         if (whiteListedFormat) {
         if (whiteListedFormat) {
             return whiteListedFormat;
             return whiteListedFormat;
@@ -65,13 +65,13 @@ export async function getFileType(
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
         if (e.message === CustomError.NON_MEDIA_FILE) {
         if (e.message === CustomError.NON_MEDIA_FILE) {
-            logError(e, 'unsupported file format', {
+            logError(e, "unsupported file format", {
                 fileFormat,
                 fileFormat,
                 fileSize,
                 fileSize,
             });
             });
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
             throw Error(CustomError.UNSUPPORTED_FILE_FORMAT);
         }
         }
-        logError(e, 'type detection failed', {
+        logError(e, "type detection failed", {
             fileFormat,
             fileFormat,
             fileSize,
             fileSize,
         });
         });
@@ -96,11 +96,11 @@ async function extractElectronFileType(file: ElectronFile) {
 async function getFileTypeFromBuffer(buffer: Uint8Array) {
 async function getFileTypeFromBuffer(buffer: Uint8Array) {
     const result = await FileType.fromBuffer(buffer);
     const result = await FileType.fromBuffer(buffer);
     if (!result?.mime) {
     if (!result?.mime) {
-        let logableInfo = '';
+        let logableInfo = "";
         try {
         try {
             logableInfo = `result: ${JSON.stringify(result)}`;
             logableInfo = `result: ${JSON.stringify(result)}`;
         } catch (e) {
         } catch (e) {
-            logableInfo = 'failed to stringify result';
+            logableInfo = "failed to stringify result";
         }
         }
         throw Error(`mimetype missing from file type result - ${logableInfo}`);
         throw Error(`mimetype missing from file type result - ${logableInfo}`);
     }
     }

+ 26 - 26
apps/cast/src/services/wasm/ffmpeg.ts

@@ -1,14 +1,14 @@
-import { promiseWithTimeout } from '@ente/shared/promise';
-import { createFFmpeg, FFmpeg } from 'ffmpeg-wasm';
-import QueueProcessor from 'services/queueProcessor';
-import { getUint8ArrayView } from 'services/readerService';
-import { logError } from '@ente/shared/sentry';
-import { generateTempName } from 'utils/temp';
-import { addLogLine } from '@ente/shared/logging';
+import { addLogLine } from "@ente/shared/logging";
+import { promiseWithTimeout } from "@ente/shared/promise";
+import { logError } from "@ente/shared/sentry";
+import { createFFmpeg, FFmpeg } from "ffmpeg-wasm";
+import QueueProcessor from "services/queueProcessor";
+import { getUint8ArrayView } from "services/readerService";
+import { generateTempName } from "utils/temp";
 
 
-const INPUT_PATH_PLACEHOLDER = 'INPUT';
-const FFMPEG_PLACEHOLDER = 'FFMPEG';
-const OUTPUT_PATH_PLACEHOLDER = 'OUTPUT';
+const INPUT_PATH_PLACEHOLDER = "INPUT";
+const FFMPEG_PLACEHOLDER = "FFMPEG";
+const OUTPUT_PATH_PLACEHOLDER = "OUTPUT";
 
 
 const FFMPEG_EXECUTION_WAIT_TIME = 30 * 1000;
 const FFMPEG_EXECUTION_WAIT_TIME = 30 * 1000;
 
 
@@ -19,7 +19,7 @@ export class WasmFFmpeg {
 
 
     constructor() {
     constructor() {
         this.ffmpeg = createFFmpeg({
         this.ffmpeg = createFFmpeg({
-            corePath: '/js/ffmpeg/ffmpeg-core.js',
+            corePath: "/js/ffmpeg/ffmpeg-core.js",
             mt: false,
             mt: false,
         });
         });
 
 
@@ -36,7 +36,7 @@ export class WasmFFmpeg {
         cmd: string[],
         cmd: string[],
         inputFile: File,
         inputFile: File,
         outputFileName: string,
         outputFileName: string,
-        dontTimeout = false
+        dontTimeout = false,
     ) {
     ) {
         const response = this.ffmpegTaskQueue.queueUpRequest(() => {
         const response = this.ffmpegTaskQueue.queueUpRequest(() => {
             if (dontTimeout) {
             if (dontTimeout) {
@@ -44,14 +44,14 @@ export class WasmFFmpeg {
             } else {
             } else {
                 return promiseWithTimeout<File>(
                 return promiseWithTimeout<File>(
                     this.execute(cmd, inputFile, outputFileName),
                     this.execute(cmd, inputFile, outputFileName),
-                    FFMPEG_EXECUTION_WAIT_TIME
+                    FFMPEG_EXECUTION_WAIT_TIME,
                 );
                 );
             }
             }
         });
         });
         try {
         try {
             return await response.promise;
             return await response.promise;
         } catch (e) {
         } catch (e) {
-            logError(e, 'ffmpeg run failed');
+            logError(e, "ffmpeg run failed");
             throw e;
             throw e;
         }
         }
     }
     }
@@ -59,25 +59,25 @@ export class WasmFFmpeg {
     private async execute(
     private async execute(
         cmd: string[],
         cmd: string[],
         inputFile: File,
         inputFile: File,
-        outputFileName: string
+        outputFileName: string,
     ) {
     ) {
         let tempInputFilePath: string;
         let tempInputFilePath: string;
         let tempOutputFilePath: string;
         let tempOutputFilePath: string;
         try {
         try {
             await this.ready;
             await this.ready;
             const extension = getFileExtension(inputFile.name);
             const extension = getFileExtension(inputFile.name);
-            const tempNameSuffix = extension ? `input.${extension}` : 'input';
+            const tempNameSuffix = extension ? `input.${extension}` : "input";
             tempInputFilePath = `${generateTempName(10, tempNameSuffix)}`;
             tempInputFilePath = `${generateTempName(10, tempNameSuffix)}`;
             this.ffmpeg.FS(
             this.ffmpeg.FS(
-                'writeFile',
+                "writeFile",
                 tempInputFilePath,
                 tempInputFilePath,
-                await getUint8ArrayView(inputFile)
+                await getUint8ArrayView(inputFile),
             );
             );
             tempOutputFilePath = `${generateTempName(10, outputFileName)}`;
             tempOutputFilePath = `${generateTempName(10, outputFileName)}`;
 
 
             cmd = cmd.map((cmdPart) => {
             cmd = cmd.map((cmdPart) => {
                 if (cmdPart === FFMPEG_PLACEHOLDER) {
                 if (cmdPart === FFMPEG_PLACEHOLDER) {
-                    return '';
+                    return "";
                 } else if (cmdPart === INPUT_PATH_PLACEHOLDER) {
                 } else if (cmdPart === INPUT_PATH_PLACEHOLDER) {
                     return tempInputFilePath;
                     return tempInputFilePath;
                 } else if (cmdPart === OUTPUT_PATH_PLACEHOLDER) {
                 } else if (cmdPart === OUTPUT_PATH_PLACEHOLDER) {
@@ -89,26 +89,26 @@ export class WasmFFmpeg {
             addLogLine(`${cmd}`);
             addLogLine(`${cmd}`);
             await this.ffmpeg.run(...cmd);
             await this.ffmpeg.run(...cmd);
             return new File(
             return new File(
-                [this.ffmpeg.FS('readFile', tempOutputFilePath)],
-                outputFileName
+                [this.ffmpeg.FS("readFile", tempOutputFilePath)],
+                outputFileName,
             );
             );
         } finally {
         } finally {
             try {
             try {
-                this.ffmpeg.FS('unlink', tempInputFilePath);
+                this.ffmpeg.FS("unlink", tempInputFilePath);
             } catch (e) {
             } catch (e) {
-                logError(e, 'unlink input file failed');
+                logError(e, "unlink input file failed");
             }
             }
             try {
             try {
-                this.ffmpeg.FS('unlink', tempOutputFilePath);
+                this.ffmpeg.FS("unlink", tempOutputFilePath);
             } catch (e) {
             } catch (e) {
-                logError(e, 'unlink output file failed');
+                logError(e, "unlink output file failed");
             }
             }
         }
         }
     }
     }
 }
 }
 
 
 function getFileExtension(filename: string) {
 function getFileExtension(filename: string) {
-    const lastDotPosition = filename.lastIndexOf('.');
+    const lastDotPosition = filename.lastIndexOf(".");
     if (lastDotPosition === -1) return null;
     if (lastDotPosition === -1) return null;
     else {
     else {
         return filename.slice(lastDotPosition + 1);
         return filename.slice(lastDotPosition + 1);

+ 3 - 3
apps/cast/src/services/wasmHeicConverter/wasmHEICConverterClient.ts

@@ -1,9 +1,9 @@
-import * as HeicConvert from 'heic-convert';
-import { getUint8ArrayView } from 'services/readerService';
+import * as HeicConvert from "heic-convert";
+import { getUint8ArrayView } from "services/readerService";
 
 
 export async function convertHEIC(
 export async function convertHEIC(
     fileBlob: Blob,
     fileBlob: Blob,
-    format: string
+    format: string,
 ): Promise<Blob> {
 ): Promise<Blob> {
     const filedata = await getUint8ArrayView(fileBlob);
     const filedata = await getUint8ArrayView(fileBlob);
     const result = await HeicConvert({ buffer: filedata, format });
     const result = await HeicConvert({ buffer: filedata, format });

+ 24 - 24
apps/cast/src/services/wasmHeicConverter/wasmHEICConverterService.ts

@@ -1,23 +1,23 @@
-import QueueProcessor from 'services/queueProcessor';
-import { retryAsyncFunction } from 'utils/network';
-import { DedicatedConvertWorker } from 'worker/convert.worker';
-import { ComlinkWorker } from 'utils/comlink/comlinkWorker';
-import { getDedicatedConvertWorker } from 'utils/comlink/ComlinkConvertWorker';
-import { logError } from '@ente/shared/sentry';
-import { addLogLine } from '@ente/shared/logging';
-import { convertBytesToHumanReadable } from '@ente/shared/utils/size';
-import { CustomError } from '@ente/shared/error';
+import { CustomError } from "@ente/shared/error";
+import { addLogLine } from "@ente/shared/logging";
+import { logError } from "@ente/shared/sentry";
+import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
+import QueueProcessor from "services/queueProcessor";
+import { getDedicatedConvertWorker } from "utils/comlink/ComlinkConvertWorker";
+import { ComlinkWorker } from "utils/comlink/comlinkWorker";
+import { retryAsyncFunction } from "utils/network";
+import { DedicatedConvertWorker } from "worker/convert.worker";
 
 
 const WORKER_POOL_SIZE = 2;
 const WORKER_POOL_SIZE = 2;
 const MAX_CONVERSION_IN_PARALLEL = 1;
 const MAX_CONVERSION_IN_PARALLEL = 1;
 const WAIT_TIME_BEFORE_NEXT_ATTEMPT_IN_MICROSECONDS = [100, 100];
 const WAIT_TIME_BEFORE_NEXT_ATTEMPT_IN_MICROSECONDS = [100, 100];
 const WAIT_TIME_IN_MICROSECONDS = 30 * 1000;
 const WAIT_TIME_IN_MICROSECONDS = 30 * 1000;
 const BREATH_TIME_IN_MICROSECONDS = 1000;
 const BREATH_TIME_IN_MICROSECONDS = 1000;
-const CONVERT_FORMAT = 'JPEG';
+const CONVERT_FORMAT = "JPEG";
 
 
 class HEICConverter {
 class HEICConverter {
     private convertProcessor = new QueueProcessor<Blob>(
     private convertProcessor = new QueueProcessor<Blob>(
-        MAX_CONVERSION_IN_PARALLEL
+        MAX_CONVERSION_IN_PARALLEL,
     );
     );
     private workerPool: ComlinkWorker<typeof DedicatedConvertWorker>[] = [];
     private workerPool: ComlinkWorker<typeof DedicatedConvertWorker>[] = [];
     private ready: Promise<void>;
     private ready: Promise<void>;
@@ -43,22 +43,22 @@ class HEICConverter {
                             const main = async () => {
                             const main = async () => {
                                 try {
                                 try {
                                     const timeout = setTimeout(() => {
                                     const timeout = setTimeout(() => {
-                                        reject(Error('wait time exceeded'));
+                                        reject(Error("wait time exceeded"));
                                     }, WAIT_TIME_IN_MICROSECONDS);
                                     }, WAIT_TIME_IN_MICROSECONDS);
                                     const startTime = Date.now();
                                     const startTime = Date.now();
                                     const convertedHEIC =
                                     const convertedHEIC =
                                         await worker.convertHEIC(
                                         await worker.convertHEIC(
                                             fileBlob,
                                             fileBlob,
-                                            CONVERT_FORMAT
+                                            CONVERT_FORMAT,
                                         );
                                         );
                                     addLogLine(
                                     addLogLine(
                                         `originalFileSize:${convertBytesToHumanReadable(
                                         `originalFileSize:${convertBytesToHumanReadable(
-                                            fileBlob?.size
+                                            fileBlob?.size,
                                         )},convertedFileSize:${convertBytesToHumanReadable(
                                         )},convertedFileSize:${convertBytesToHumanReadable(
-                                            convertedHEIC?.size
+                                            convertedHEIC?.size,
                                         )},  heic conversion time: ${
                                         )},  heic conversion time: ${
                                             Date.now() - startTime
                                             Date.now() - startTime
-                                        }ms `
+                                        }ms `,
                                     );
                                     );
                                     clearTimeout(timeout);
                                     clearTimeout(timeout);
                                     resolve(convertedHEIC);
                                     resolve(convertedHEIC);
@@ -67,37 +67,37 @@ class HEICConverter {
                                 }
                                 }
                             };
                             };
                             main();
                             main();
-                        }
+                        },
                     );
                     );
                     if (!convertedHEIC || convertedHEIC?.size === 0) {
                     if (!convertedHEIC || convertedHEIC?.size === 0) {
                         logError(
                         logError(
                             Error(`converted heic fileSize is Zero`),
                             Error(`converted heic fileSize is Zero`),
-                            'converted heic fileSize is Zero',
+                            "converted heic fileSize is Zero",
                             {
                             {
                                 originalFileSize: convertBytesToHumanReadable(
                                 originalFileSize: convertBytesToHumanReadable(
-                                    fileBlob?.size ?? 0
+                                    fileBlob?.size ?? 0,
                                 ),
                                 ),
                                 convertedFileSize: convertBytesToHumanReadable(
                                 convertedFileSize: convertBytesToHumanReadable(
-                                    convertedHEIC?.size ?? 0
+                                    convertedHEIC?.size ?? 0,
                                 ),
                                 ),
-                            }
+                            },
                         );
                         );
                     }
                     }
                     await new Promise((resolve) => {
                     await new Promise((resolve) => {
                         setTimeout(
                         setTimeout(
                             () => resolve(null),
                             () => resolve(null),
-                            BREATH_TIME_IN_MICROSECONDS
+                            BREATH_TIME_IN_MICROSECONDS,
                         );
                         );
                     });
                     });
                     this.workerPool.push(convertWorker);
                     this.workerPool.push(convertWorker);
                     return convertedHEIC;
                     return convertedHEIC;
                 } catch (e) {
                 } catch (e) {
-                    logError(e, 'heic conversion failed');
+                    logError(e, "heic conversion failed");
                     convertWorker.terminate();
                     convertWorker.terminate();
                     this.workerPool.push(getDedicatedConvertWorker());
                     this.workerPool.push(getDedicatedConvertWorker());
                     throw e;
                     throw e;
                 }
                 }
-            }, WAIT_TIME_BEFORE_NEXT_ATTEMPT_IN_MICROSECONDS)
+            }, WAIT_TIME_BEFORE_NEXT_ATTEMPT_IN_MICROSECONDS),
         );
         );
         try {
         try {
             return await response.promise;
             return await response.promise;

+ 14 - 14
apps/cast/src/types/collection/index.ts

@@ -1,17 +1,17 @@
-import { EnteFile } from 'types/file';
-import { CollectionSummaryType, CollectionType } from 'constants/collection';
+import { CollectionSummaryType, CollectionType } from "constants/collection";
+import { EnteFile } from "types/file";
 import {
 import {
     EncryptedMagicMetadata,
     EncryptedMagicMetadata,
     MagicMetadataCore,
     MagicMetadataCore,
     SUB_TYPE,
     SUB_TYPE,
     VISIBILITY_STATE,
     VISIBILITY_STATE,
-} from 'types/magicMetadata';
+} from "types/magicMetadata";
 
 
 export enum COLLECTION_ROLE {
 export enum COLLECTION_ROLE {
-    VIEWER = 'VIEWER',
-    OWNER = 'OWNER',
-    COLLABORATOR = 'COLLABORATOR',
-    UNKNOWN = 'UNKNOWN',
+    VIEWER = "VIEWER",
+    OWNER = "OWNER",
+    COLLABORATOR = "COLLABORATOR",
+    UNKNOWN = "UNKNOWN",
 }
 }
 
 
 export interface CollectionUser {
 export interface CollectionUser {
@@ -43,13 +43,13 @@ export interface EncryptedCollection {
 export interface Collection
 export interface Collection
     extends Omit<
     extends Omit<
         EncryptedCollection,
         EncryptedCollection,
-        | 'encryptedKey'
-        | 'keyDecryptionNonce'
-        | 'encryptedName'
-        | 'nameDecryptionNonce'
-        | 'magicMetadata'
-        | 'pubMagicMetadata'
-        | 'sharedMagicMetadata'
+        | "encryptedKey"
+        | "keyDecryptionNonce"
+        | "encryptedName"
+        | "nameDecryptionNonce"
+        | "magicMetadata"
+        | "pubMagicMetadata"
+        | "sharedMagicMetadata"
     > {
     > {
     key: string;
     key: string;
     name: string;
     name: string;

+ 7 - 7
apps/cast/src/types/file/index.ts

@@ -2,8 +2,8 @@ import {
     EncryptedMagicMetadata,
     EncryptedMagicMetadata,
     MagicMetadataCore,
     MagicMetadataCore,
     VISIBILITY_STATE,
     VISIBILITY_STATE,
-} from 'types/magicMetadata';
-import { Metadata } from 'types/upload';
+} from "types/magicMetadata";
+import { Metadata } from "types/upload";
 
 
 export interface MetadataFileAttributes {
 export interface MetadataFileAttributes {
     encryptedData: string;
     encryptedData: string;
@@ -38,11 +38,11 @@ export interface EncryptedEnteFile {
 export interface EnteFile
 export interface EnteFile
     extends Omit<
     extends Omit<
         EncryptedEnteFile,
         EncryptedEnteFile,
-        | 'metadata'
-        | 'pubMagicMetadata'
-        | 'magicMetadata'
-        | 'encryptedKey'
-        | 'keyDecryptionNonce'
+        | "metadata"
+        | "pubMagicMetadata"
+        | "magicMetadata"
+        | "encryptedKey"
+        | "keyDecryptionNonce"
     > {
     > {
     metadata: Metadata;
     metadata: Metadata;
     magicMetadata: FileMagicMetadata;
     magicMetadata: FileMagicMetadata;

+ 3 - 3
apps/cast/src/types/gallery/index.ts

@@ -1,9 +1,9 @@
 // import { CollectionDownloadProgressAttributes } from 'components/Collections/CollectionDownloadProgress';
 // import { CollectionDownloadProgressAttributes } from 'components/Collections/CollectionDownloadProgress';
 // import { CollectionSelectorAttributes } from 'components/Collections/CollectionSelector';
 // import { CollectionSelectorAttributes } from 'components/Collections/CollectionSelector';
 // import { TimeStampListItem } from 'components/PhotoList';
 // import { TimeStampListItem } from 'components/PhotoList';
-import { User } from '@ente/shared/user/types';
-import { Collection } from 'types/collection';
-import { EnteFile } from 'types/file';
+import { User } from "@ente/shared/user/types";
+import { Collection } from "types/collection";
+import { EnteFile } from "types/file";
 
 
 export type SelectedState = {
 export type SelectedState = {
     [k: number]: boolean;
     [k: number]: boolean;

+ 9 - 9
apps/cast/src/types/upload/index.ts

@@ -1,16 +1,16 @@
 import {
 import {
     B64EncryptionResult,
     B64EncryptionResult,
     LocalFileAttributes,
     LocalFileAttributes,
-} from '@ente/shared/crypto/types';
-import { FILE_TYPE } from 'constants/file';
-import { Collection } from 'types/collection';
+} from "@ente/shared/crypto/types";
+import { FILE_TYPE } from "constants/file";
+import { Collection } from "types/collection";
 import {
 import {
-    MetadataFileAttributes,
-    S3FileAttributes,
     FilePublicMagicMetadata,
     FilePublicMagicMetadata,
     FilePublicMagicMetadataProps,
     FilePublicMagicMetadataProps,
-} from 'types/file';
-import { EncryptedMagicMetadata } from 'types/magicMetadata';
+    MetadataFileAttributes,
+    S3FileAttributes,
+} from "types/file";
+import { EncryptedMagicMetadata } from "types/magicMetadata";
 
 
 export interface DataStream {
 export interface DataStream {
     stream: ReadableStream<Uint8Array>;
     stream: ReadableStream<Uint8Array>;
@@ -18,7 +18,7 @@ export interface DataStream {
 }
 }
 
 
 export function isDataStream(object: any): object is DataStream {
 export function isDataStream(object: any): object is DataStream {
-    return 'stream' in object;
+    return "stream" in object;
 }
 }
 
 
 export type Logger = (message: string) => void;
 export type Logger = (message: string) => void;
@@ -114,7 +114,7 @@ export interface FileInMemory {
 }
 }
 
 
 export interface FileWithMetadata
 export interface FileWithMetadata
-    extends Omit<FileInMemory, 'hasStaticThumbnail'> {
+    extends Omit<FileInMemory, "hasStaticThumbnail"> {
     metadata: Metadata;
     metadata: Metadata;
     localID: number;
     localID: number;
     pubMagicMetadata: FilePublicMagicMetadata;
     pubMagicMetadata: FilePublicMagicMetadata;

+ 1 - 1
apps/cast/src/types/upload/ui.ts

@@ -1,4 +1,4 @@
-import { UPLOAD_RESULT, UPLOAD_STAGES } from 'constants/upload';
+import { UPLOAD_RESULT, UPLOAD_STAGES } from "constants/upload";
 
 
 export type FileID = number;
 export type FileID = number;
 export type FileName = string;
 export type FileName = string;

+ 12 - 12
apps/cast/src/utils/collection/index.ts

@@ -1,13 +1,13 @@
-import { COLLECTION_ROLE, Collection } from 'types/collection';
+import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
+import { User } from "@ente/shared/user/types";
 import {
 import {
     CollectionSummaryType,
     CollectionSummaryType,
     CollectionType,
     CollectionType,
     HIDE_FROM_COLLECTION_BAR_TYPES,
     HIDE_FROM_COLLECTION_BAR_TYPES,
     OPTIONS_NOT_HAVING_COLLECTION_TYPES,
     OPTIONS_NOT_HAVING_COLLECTION_TYPES,
-} from 'constants/collection';
-import { SUB_TYPE, VISIBILITY_STATE } from 'types/magicMetadata';
-import { User } from '@ente/shared/user/types';
-import { getData, LS_KEYS } from '@ente/shared/storage/localStorage';
+} from "constants/collection";
+import { COLLECTION_ROLE, Collection } from "types/collection";
+import { SUB_TYPE, VISIBILITY_STATE } from "types/magicMetadata";
 
 
 export enum COLLECTION_OPS_TYPE {
 export enum COLLECTION_OPS_TYPE {
     ADD,
     ADD,
@@ -19,7 +19,7 @@ export enum COLLECTION_OPS_TYPE {
 
 
 export function getSelectedCollection(
 export function getSelectedCollection(
     collectionID: number,
     collectionID: number,
-    collections: Collection[]
+    collections: Collection[],
 ) {
 ) {
     return collections.find((collection) => collection.id === collectionID);
     return collections.find((collection) => collection.id === collectionID);
 }
 }
@@ -64,7 +64,7 @@ export const shouldBeShownOnCollectionBar = (type: CollectionSummaryType) => {
 export const getUserOwnedCollections = (collections: Collection[]) => {
 export const getUserOwnedCollections = (collections: Collection[]) => {
     const user: User = getData(LS_KEYS.USER);
     const user: User = getData(LS_KEYS.USER);
     if (!user?.id) {
     if (!user?.id) {
-        throw Error('user missing');
+        throw Error("user missing");
     }
     }
     return collections.filter((collection) => collection.owner.id === user.id);
     return collections.filter((collection) => collection.owner.id === user.id);
 };
 };
@@ -103,7 +103,7 @@ export function isSharedOnlyViaLink(collection: Collection) {
 export function isValidMoveTarget(
 export function isValidMoveTarget(
     sourceCollectionID: number,
     sourceCollectionID: number,
     targetCollection: Collection,
     targetCollection: Collection,
-    user: User
+    user: User,
 ) {
 ) {
     return (
     return (
         sourceCollectionID !== targetCollection.id &&
         sourceCollectionID !== targetCollection.id &&
@@ -116,7 +116,7 @@ export function isValidMoveTarget(
 export function isValidReplacementAlbum(
 export function isValidReplacementAlbum(
     collection: Collection,
     collection: Collection,
     user: User,
     user: User,
-    wantedCollectionName: string
+    wantedCollectionName: string,
 ) {
 ) {
     return (
     return (
         collection.name === wantedCollectionName &&
         collection.name === wantedCollectionName &&
@@ -129,15 +129,15 @@ export function isValidReplacementAlbum(
 }
 }
 
 
 export function getCollectionNameMap(
 export function getCollectionNameMap(
-    collections: Collection[]
+    collections: Collection[],
 ): Map<number, string> {
 ): Map<number, string> {
     return new Map<number, string>(
     return new Map<number, string>(
-        collections.map((collection) => [collection.id, collection.name])
+        collections.map((collection) => [collection.id, collection.name]),
     );
     );
 }
 }
 
 
 export function getNonHiddenCollections(
 export function getNonHiddenCollections(
-    collections: Collection[]
+    collections: Collection[],
 ): Collection[] {
 ): Collection[] {
     return collections.filter((collection) => !isHiddenCollection(collection));
     return collections.filter((collection) => !isHiddenCollection(collection));
 }
 }

+ 6 - 6
apps/cast/src/utils/comlink/ComlinkConvertWorker.ts

@@ -1,7 +1,7 @@
-import { Remote } from 'comlink';
-import { DedicatedConvertWorker } from 'worker/convert.worker';
-import { ComlinkWorker } from './comlinkWorker';
-import { runningInBrowser } from '@ente/shared/platform';
+import { runningInBrowser } from "@ente/shared/platform";
+import { Remote } from "comlink";
+import { DedicatedConvertWorker } from "worker/convert.worker";
+import { ComlinkWorker } from "./comlinkWorker";
 
 
 class ComlinkConvertWorker {
 class ComlinkConvertWorker {
     private comlinkWorkerInstance: Remote<DedicatedConvertWorker>;
     private comlinkWorkerInstance: Remote<DedicatedConvertWorker>;
@@ -20,8 +20,8 @@ export const getDedicatedConvertWorker = () => {
         const cryptoComlinkWorker = new ComlinkWorker<
         const cryptoComlinkWorker = new ComlinkWorker<
             typeof DedicatedConvertWorker
             typeof DedicatedConvertWorker
         >(
         >(
-            'ente-convert-worker',
-            new Worker(new URL('worker/convert.worker.ts', import.meta.url))
+            "ente-convert-worker",
+            new Worker(new URL("worker/convert.worker.ts", import.meta.url)),
         );
         );
         return cryptoComlinkWorker;
         return cryptoComlinkWorker;
     }
     }

Some files were not shown because too many files changed in this diff