From e87096aba5f2fa65adcb1d2d2f00b67443a79a30 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 09:51:40 +0530 Subject: [PATCH 01/25] Split --- web/apps/photos/package.json | 1 + web/apps/photos/src/pages/shared-albums.tsx | 2 +- web/apps/photos/src/services/logout.ts | 2 +- web/apps/photos/src/services/upload/uploadManager.ts | 2 +- web/packages/gallery/.eslintrc.js | 3 +++ web/packages/gallery/README.md | 12 ++++++++++++ web/packages/gallery/package.json | 6 ++++++ web/packages/gallery/tsconfig.json | 4 ++++ web/packages/{media => gallery}/upload.ts | 0 web/packages/new/photos/services/settings.ts | 2 +- 10 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 web/packages/gallery/.eslintrc.js create mode 100644 web/packages/gallery/README.md create mode 100644 web/packages/gallery/package.json create mode 100644 web/packages/gallery/tsconfig.json rename web/packages/{media => gallery}/upload.ts (100%) diff --git a/web/apps/photos/package.json b/web/apps/photos/package.json index 1bfcec9104..ad2f3323d2 100644 --- a/web/apps/photos/package.json +++ b/web/apps/photos/package.json @@ -5,6 +5,7 @@ "dependencies": { "@/accounts": "*", "@/base": "*", + "@/gallery": "*", "@/media": "*", "@/new": "*", "@ente/eslint-config": "*", diff --git a/web/apps/photos/src/pages/shared-albums.tsx b/web/apps/photos/src/pages/shared-albums.tsx index 8dea594d65..3556c57a34 100644 --- a/web/apps/photos/src/pages/shared-albums.tsx +++ b/web/apps/photos/src/pages/shared-albums.tsx @@ -7,7 +7,7 @@ import { useIsSmallWidth, useIsTouchscreen } from "@/base/hooks"; import log from "@/base/log"; import type { Collection } from "@/media/collection"; import { type EnteFile, mergeMetadata } from "@/media/file"; -import { updateShouldDisableCFUploadProxy } from "@/media/upload"; +import { updateShouldDisableCFUploadProxy } from "@/gallery/upload"; import { GalleryItemsHeaderAdapter, GalleryItemsSummary, diff --git a/web/apps/photos/src/services/logout.ts b/web/apps/photos/src/services/logout.ts index ab4b91200a..5349914fb1 100644 --- a/web/apps/photos/src/services/logout.ts +++ b/web/apps/photos/src/services/logout.ts @@ -1,6 +1,6 @@ import { accountLogout } from "@/accounts/services/logout"; import log from "@/base/log"; -import { resetUploadState } from "@/media/upload"; +import { resetUploadState } from "@/gallery/upload"; import DownloadManager from "@/new/photos/services/download"; import { logoutML, terminateMLWorker } from "@/new/photos/services/ml"; import { logoutSearch } from "@/new/photos/services/search"; diff --git a/web/apps/photos/src/services/upload/uploadManager.ts b/web/apps/photos/src/services/upload/uploadManager.ts index 35bf5da1fb..2171d079a9 100644 --- a/web/apps/photos/src/services/upload/uploadManager.ts +++ b/web/apps/photos/src/services/upload/uploadManager.ts @@ -8,7 +8,7 @@ import type { Collection } from "@/media/collection"; import { EncryptedEnteFile, EnteFile } from "@/media/file"; import { FileType } from "@/media/file-type"; import { potentialFileTypeFromExtension } from "@/media/live-photo"; -import { shouldDisableCFUploadProxy } from "@/media/upload"; +import { shouldDisableCFUploadProxy } from "@/gallery/upload"; import { getLocalFiles } from "@/new/photos/services/files"; import { indexNewUpload } from "@/new/photos/services/ml"; import type { UploadItem } from "@/new/photos/services/upload/types"; diff --git a/web/packages/gallery/.eslintrc.js b/web/packages/gallery/.eslintrc.js new file mode 100644 index 0000000000..348075cd4f --- /dev/null +++ b/web/packages/gallery/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@/build-config/eslintrc-next"], +}; diff --git a/web/packages/gallery/README.md b/web/packages/gallery/README.md new file mode 100644 index 0000000000..49cddae88d --- /dev/null +++ b/web/packages/gallery/README.md @@ -0,0 +1,12 @@ +## @/gallery + +A package for sharing code between our apps that show media (photos, videos) in +a gallery like view. + +Specifically, this is the intersection of code required by both the photos and +public albums apps. + +### Packaging + +This (internal) package exports a React TypeScript library. We rely on the +importing project to transpile and bundle it. diff --git a/web/packages/gallery/package.json b/web/packages/gallery/package.json new file mode 100644 index 0000000000..4281b87fd9 --- /dev/null +++ b/web/packages/gallery/package.json @@ -0,0 +1,6 @@ +{ + "name": "@/gallery", + "version": "0.0.0", + "private": true, + "dependencies": {} +} diff --git a/web/packages/gallery/tsconfig.json b/web/packages/gallery/tsconfig.json new file mode 100644 index 0000000000..b39c0995b0 --- /dev/null +++ b/web/packages/gallery/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@/build-config/tsconfig-next.json", + "include": ["."] +} diff --git a/web/packages/media/upload.ts b/web/packages/gallery/upload.ts similarity index 100% rename from web/packages/media/upload.ts rename to web/packages/gallery/upload.ts diff --git a/web/packages/new/photos/services/settings.ts b/web/packages/new/photos/services/settings.ts index 063fb378e0..92a6a2d149 100644 --- a/web/packages/new/photos/services/settings.ts +++ b/web/packages/new/photos/services/settings.ts @@ -6,7 +6,7 @@ import { localUser } from "@/base/local-user"; import log from "@/base/log"; -import { updateShouldDisableCFUploadProxy } from "@/media/upload"; +import { updateShouldDisableCFUploadProxy } from "@/gallery/upload"; import { nullToUndefined } from "@/utils/transform"; import { z } from "zod"; import { fetchFeatureFlags, updateRemoteFlag } from "./remote-store"; From 2bb4be423feb2ff8061b96320e8659d1bff11ea1 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 09:59:59 +0530 Subject: [PATCH 02/25] Inline --- .../src/components/PhotoViewer/index.tsx | 38 +++++++++++++++++-- .../CircularProgressWithLabel.tsx | 32 ---------------- 2 files changed, 34 insertions(+), 36 deletions(-) delete mode 100644 web/apps/photos/src/components/PhotoViewer/styledComponents/CircularProgressWithLabel.tsx diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index 366a377545..c87a12cd74 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -3,13 +3,13 @@ import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; import { lowercaseExtension } from "@/base/file"; import log from "@/base/log"; import type { LoadedLivePhotoSourceURL } from "@/media/file"; -import { type EnteFile, fileLogID } from "@/media/file"; +import { fileLogID, type EnteFile } from "@/media/file"; import { FileType } from "@/media/file-type"; import { isHEICExtension, needsJPEGConversion } from "@/media/formats"; import downloadManager from "@/new/photos/services/download"; import { extractRawExif, parseExif } from "@/new/photos/services/exif"; import { AppContext } from "@/new/photos/types/context"; -import { FlexWrapper } from "@ente/shared/components/Container"; +import { FlexWrapper, Overlay } from "@ente/shared/components/Container"; import AlbumOutlined from "@mui/icons-material/AlbumOutlined"; import ChevronLeft from "@mui/icons-material/ChevronLeft"; import ChevronRight from "@mui/icons-material/ChevronRight"; @@ -25,7 +25,14 @@ import FullscreenOutlinedIcon from "@mui/icons-material/FullscreenOutlined"; import InfoIcon from "@mui/icons-material/InfoOutlined"; import ReplayIcon from "@mui/icons-material/Replay"; import ZoomInOutlinedIcon from "@mui/icons-material/ZoomInOutlined"; -import { Box, Button, styled } from "@mui/material"; +import { + Box, + Button, + CircularProgress, + styled, + Typography, + type CircularProgressProps, +} from "@mui/material"; import { t } from "i18next"; import isElectron from "is-electron"; import { GalleryContext } from "pages/gallery"; @@ -48,7 +55,6 @@ import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery"; import { getTrashFileMessage } from "utils/ui"; import { FileInfo, type FileInfoExif, type FileInfoProps } from "./FileInfo"; import ImageEditorOverlay from "./ImageEditorOverlay"; -import CircularProgressWithLabel from "./styledComponents/CircularProgressWithLabel"; import { ConversionFailedNotification } from "./styledComponents/ConversionFailedNotification"; import { LivePhotoBtnContainer } from "./styledComponents/LivePhotoBtn"; @@ -983,3 +989,27 @@ function PhotoViewer(props: PhotoViewerProps) { } export default PhotoViewer; + +function CircularProgressWithLabel( + props: CircularProgressProps & { value: number }, +) { + return ( + <> + + + {`${Math.round(props.value)}%`} + + + ); +} diff --git a/web/apps/photos/src/components/PhotoViewer/styledComponents/CircularProgressWithLabel.tsx b/web/apps/photos/src/components/PhotoViewer/styledComponents/CircularProgressWithLabel.tsx deleted file mode 100644 index 9556a3a855..0000000000 --- a/web/apps/photos/src/components/PhotoViewer/styledComponents/CircularProgressWithLabel.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Overlay } from "@ente/shared/components/Container"; -import { - CircularProgress, - Typography, - type CircularProgressProps, -} from "@mui/material"; - -function CircularProgressWithLabel( - props: CircularProgressProps & { value: number }, -) { - return ( - <> - - - {`${Math.round(props.value)}%`} - - - ); -} - -export default CircularProgressWithLabel; From 542cb16e1a91de765d039d3fa17b13bde9dfc76a Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:00:57 +0530 Subject: [PATCH 03/25] Inline --- .../src/components/PhotoViewer/index.tsx | 27 ++++++++++++++++- .../ConversionFailedNotification.tsx | 29 ------------------- 2 files changed, 26 insertions(+), 30 deletions(-) delete mode 100644 web/apps/photos/src/components/PhotoViewer/styledComponents/ConversionFailedNotification.tsx diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index c87a12cd74..d34aaef17a 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -33,6 +33,7 @@ import { Typography, type CircularProgressProps, } from "@mui/material"; +import Notification from "components/Notification"; import { t } from "i18next"; import isElectron from "is-electron"; import { GalleryContext } from "pages/gallery"; @@ -55,7 +56,6 @@ import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery"; import { getTrashFileMessage } from "utils/ui"; import { FileInfo, type FileInfoExif, type FileInfoProps } from "./FileInfo"; import ImageEditorOverlay from "./ImageEditorOverlay"; -import { ConversionFailedNotification } from "./styledComponents/ConversionFailedNotification"; import { LivePhotoBtnContainer } from "./styledComponents/LivePhotoBtn"; interface PhotoswipeFullscreenAPI { @@ -1013,3 +1013,28 @@ function CircularProgressWithLabel( ); } + +interface ConversionFailedNotificationProps { + open: boolean; + onClose: () => void; + onClick: () => void; +} + +const ConversionFailedNotification: React.FC< + ConversionFailedNotificationProps +> = ({ open, onClose, onClick }) => { + return ( + + ); +}; diff --git a/web/apps/photos/src/components/PhotoViewer/styledComponents/ConversionFailedNotification.tsx b/web/apps/photos/src/components/PhotoViewer/styledComponents/ConversionFailedNotification.tsx deleted file mode 100644 index fe504d1805..0000000000 --- a/web/apps/photos/src/components/PhotoViewer/styledComponents/ConversionFailedNotification.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import Notification from "components/Notification"; -import { t } from "i18next"; - -interface Iprops { - open: boolean; - onClose: () => void; - onClick: () => void; -} - -export const ConversionFailedNotification = ({ - open, - onClose, - onClick, -}: Iprops) => { - return ( - - ); -}; From 079154198b0f1f1b6a29ab0aac594045bec7a402 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:01:41 +0530 Subject: [PATCH 04/25] Inline --- web/apps/photos/src/components/PhotoViewer/index.tsx | 10 +++++++++- .../PhotoViewer/styledComponents/LivePhotoBtn.tsx | 9 --------- 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 web/apps/photos/src/components/PhotoViewer/styledComponents/LivePhotoBtn.tsx diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index d34aaef17a..e13c49f8ea 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -29,6 +29,7 @@ import { Box, Button, CircularProgress, + Paper, styled, Typography, type CircularProgressProps, @@ -56,7 +57,6 @@ import { PublicCollectionGalleryContext } from "utils/publicCollectionGallery"; import { getTrashFileMessage } from "utils/ui"; import { FileInfo, type FileInfoExif, type FileInfoProps } from "./FileInfo"; import ImageEditorOverlay from "./ImageEditorOverlay"; -import { LivePhotoBtnContainer } from "./styledComponents/LivePhotoBtn"; interface PhotoswipeFullscreenAPI { enter: () => void; @@ -1038,3 +1038,11 @@ const ConversionFailedNotification: React.FC< /> ); }; + +const LivePhotoBtnContainer = styled(Paper)` + border-radius: 4px; + position: absolute; + bottom: 10vh; + right: 6vh; + z-index: 10; +`; diff --git a/web/apps/photos/src/components/PhotoViewer/styledComponents/LivePhotoBtn.tsx b/web/apps/photos/src/components/PhotoViewer/styledComponents/LivePhotoBtn.tsx deleted file mode 100644 index 00b8979d5a..0000000000 --- a/web/apps/photos/src/components/PhotoViewer/styledComponents/LivePhotoBtn.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Paper, styled } from "@mui/material"; - -export const LivePhotoBtnContainer = styled(Paper)` - border-radius: 4px; - position: absolute; - bottom: 10vh; - right: 6vh; - z-index: 10; -`; From 22b0d47e0a26b70ca001e98668fb6f0eec9dfe3f Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:06:44 +0530 Subject: [PATCH 05/25] Unused --- .../src/components/PhotoViewer/styledComponents/Pre.tsx | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 web/apps/photos/src/components/PhotoViewer/styledComponents/Pre.tsx diff --git a/web/apps/photos/src/components/PhotoViewer/styledComponents/Pre.tsx b/web/apps/photos/src/components/PhotoViewer/styledComponents/Pre.tsx deleted file mode 100644 index b088ec9f83..0000000000 --- a/web/apps/photos/src/components/PhotoViewer/styledComponents/Pre.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { styled } from "@mui/material"; -export const Pre = styled("pre")` - color: #aaa; - padding: 7px 15px; -`; From ce80a002eadce5a6c8056779f1438ede8603b0ac Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:09:21 +0530 Subject: [PATCH 06/25] Inline --- .../family/usageSection/index.tsx | 22 +++++++++++++++++-- .../family/usageSection/legend.tsx | 18 --------------- 2 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/legend.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx index 4c0b1904f2..91181d98bf 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx @@ -1,7 +1,10 @@ -import { SpaceBetweenFlex } from "@ente/shared/components/Container"; +import { + FlexWrapper, + SpaceBetweenFlex, +} from "@ente/shared/components/Container"; import { Box, Stack, Typography } from "@mui/material"; import { t } from "i18next"; -import { Legend } from "./legend"; +import { LegendIndicator } from "../../../styledComponents"; import { FamilyUsageProgressBar } from "./progressBar"; interface Iprops { @@ -40,3 +43,18 @@ export function FamilyUsageSection({ ); } + +interface LegendProps { + label: string; + color: string; +} +function Legend({ label, color }: LegendProps) { + return ( + + + + {label} + + + ); +} diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/legend.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/legend.tsx deleted file mode 100644 index 6caaa2374d..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/legend.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { FlexWrapper } from "@ente/shared/components/Container"; -import { Typography } from "@mui/material"; -import { LegendIndicator } from "../../../styledComponents"; - -interface Iprops { - label: string; - color: string; -} -export function Legend({ label, color }: Iprops) { - return ( - - - - {label} - - - ); -} From d50c577a2f1a8f6b4923f4bd763c1fb3e0265045 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:10:07 +0530 Subject: [PATCH 07/25] Inline --- .../family/usageSection/index.tsx | 37 ++++++++++++++++++- .../family/usageSection/progressBar.tsx | 34 ----------------- 2 files changed, 35 insertions(+), 36 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/progressBar.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx index 91181d98bf..84ee5b0f69 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx @@ -4,8 +4,7 @@ import { } from "@ente/shared/components/Container"; import { Box, Stack, Typography } from "@mui/material"; import { t } from "i18next"; -import { LegendIndicator } from "../../../styledComponents"; -import { FamilyUsageProgressBar } from "./progressBar"; +import { LegendIndicator, Progressbar } from "../../../styledComponents"; interface Iprops { userUsage: number; @@ -44,10 +43,44 @@ export function FamilyUsageSection({ ); } +interface FamilyUsageProgressBarProps { + userUsage: number; + totalUsage: number; + totalStorage: number; +} + +function FamilyUsageProgressBar({ + userUsage, + totalUsage, + totalStorage, +}: FamilyUsageProgressBarProps) { + return ( + + + + + ); +} + interface LegendProps { label: string; color: string; } + function Legend({ label, color }: LegendProps) { return ( diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/progressBar.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/progressBar.tsx deleted file mode 100644 index ab28b5b8f1..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/progressBar.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Box } from "@mui/material"; -import { Progressbar } from "../../../styledComponents"; -interface Iprops { - userUsage: number; - totalUsage: number; - totalStorage: number; -} - -export function FamilyUsageProgressBar({ - userUsage, - totalUsage, - totalStorage, -}: Iprops) { - return ( - - - - - ); -} From e7b7b3c1cc5b7b9b8f2c3660161923a9bc998809 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:13:11 +0530 Subject: [PATCH 08/25] Inline --- .../contentOverlay/individual/index.tsx | 53 +++++++++++++++++-- .../individual/usageSection.tsx | 42 --------------- 2 files changed, 50 insertions(+), 45 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/usageSection.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx index 9bdc3292c1..6e8f1e354d 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx @@ -1,12 +1,19 @@ +import { formattedStorageByteSize } from "@/new/photos/utils/units"; +import { SpaceBetweenFlex } from "@ente/shared/components/Container"; +import { Box, Typography } from "@mui/material"; +import { t } from "i18next"; import { UserDetails } from "types/user"; import StorageSection from "../storageSection"; -import { IndividualUsageSection } from "./usageSection"; -interface Iprops { +import { Progressbar } from "../../styledComponents"; + +interface IndividualSubscriptionCardContentProps { userDetails: UserDetails; } -export function IndividualSubscriptionCardContent({ userDetails }: Iprops) { +export const IndividualSubscriptionCardContent: React.FC< + IndividualSubscriptionCardContentProps +> = ({ userDetails }) => { const totalStorage = userDetails.subscription.storage + (userDetails.storageBonus ?? 0); return ( @@ -19,4 +26,44 @@ export function IndividualSubscriptionCardContent({ userDetails }: Iprops) { /> ); +}; + +interface IndividualUsageSectionProps { + usage: number; + fileCount: number; + storage: number; } +const IndividualUsageSection: React.FC = ({ + usage, + storage, + fileCount, +}) => { + // [Note: Fallback translation for languages with multiple plurals] + // + // Languages like Polish and Arabian have multiple plural forms, and + // currently i18n falls back to the base language translation instead of the + // "_other" form if all the plural forms are not listed out. + // + // As a workaround, name the _other form as the unprefixed name. That is, + // instead of calling the most general plural form as foo_count_other, call + // it foo_count (To keep our heads straight, we adopt the convention that + // all such pluralizable strings use the _count suffix, but that's not a + // requirement from the library). + return ( + + + + {`${formattedStorageByteSize( + storage - usage, + )} ${t("FREE")}`} + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/usageSection.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/usageSection.tsx deleted file mode 100644 index 857ac9c633..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/usageSection.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { formattedStorageByteSize } from "@/new/photos/utils/units"; -import { SpaceBetweenFlex } from "@ente/shared/components/Container"; -import { Box, Typography } from "@mui/material"; -import { t } from "i18next"; - -import { Progressbar } from "../../styledComponents"; - -interface Iprops { - usage: number; - fileCount: number; - storage: number; -} -export function IndividualUsageSection({ usage, storage, fileCount }: Iprops) { - // [Note: Fallback translation for languages with multiple plurals] - // - // Languages like Polish and Arabian have multiple plural forms, and - // currently i18n falls back to the base language translation instead of the - // "_other" form if all the plural forms are not listed out. - // - // As a workaround, name the _other form as the unprefixed name. That is, - // instead of calling the most general plural form as foo_count_other, call - // it foo_count (To keep our heads straight, we adopt the convention that - // all such pluralizable strings use the _count suffix, but that's not a - // requirement from the library). - return ( - - - - {`${formattedStorageByteSize( - storage - usage, - )} ${t("FREE")}`} - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -} From 058e1579415dc545861d974ba09089553defbcd9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:15:10 +0530 Subject: [PATCH 09/25] Inline --- .../SubscriptionCard/contentOverlay/index.tsx | 74 ++++++++++++++++++- .../contentOverlay/individual/index.tsx | 69 ----------------- 2 files changed, 71 insertions(+), 72 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx index 238058534c..58b374ae6f 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx @@ -1,14 +1,20 @@ +import { formattedStorageByteSize } from "@/new/photos/utils/units"; import { Overlay, SpaceBetweenFlex } from "@ente/shared/components/Container"; +import { Box, Typography } from "@mui/material"; +import { t } from "i18next"; import { UserDetails } from "types/user"; import { hasNonAdminFamilyMembers } from "utils/user/family"; +import { Progressbar } from "../styledComponents"; import { FamilySubscriptionCardContent } from "./family"; -import { IndividualSubscriptionCardContent } from "./individual"; +import StorageSection from "./storageSection"; -interface Iprops { +interface SubscriptionCardContentOverlayPprops { userDetails: UserDetails; } -export function SubscriptionCardContentOverlay({ userDetails }: Iprops) { +export const SubscriptionCardContentOverlay: React.FC< + SubscriptionCardContentOverlayPprops +> = ({ userDetails }) => { return ( ); +}; + +interface IndividualSubscriptionCardContentProps { + userDetails: UserDetails; } + +const IndividualSubscriptionCardContent: React.FC< + IndividualSubscriptionCardContentProps +> = ({ userDetails }) => { + const totalStorage = + userDetails.subscription.storage + (userDetails.storageBonus ?? 0); + return ( + <> + + + + ); +}; + +interface IndividualUsageSectionProps { + usage: number; + fileCount: number; + storage: number; +} + +const IndividualUsageSection: React.FC = ({ + usage, + storage, + fileCount, +}) => { + // [Note: Fallback translation for languages with multiple plurals] + // + // Languages like Polish and Arabian have multiple plural forms, and + // currently i18n falls back to the base language translation instead of the + // "_other" form if all the plural forms are not listed out. + // + // As a workaround, name the _other form as the unprefixed name. That is, + // instead of calling the most general plural form as foo_count_other, call + // it foo_count (To keep our heads straight, we adopt the convention that + // all such pluralizable strings use the _count suffix, but that's not a + // requirement from the library). + return ( + + + + {`${formattedStorageByteSize( + storage - usage, + )} ${t("FREE")}`} + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx index 6e8f1e354d..e69de29bb2 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx @@ -1,69 +0,0 @@ -import { formattedStorageByteSize } from "@/new/photos/utils/units"; -import { SpaceBetweenFlex } from "@ente/shared/components/Container"; -import { Box, Typography } from "@mui/material"; -import { t } from "i18next"; -import { UserDetails } from "types/user"; -import StorageSection from "../storageSection"; - -import { Progressbar } from "../../styledComponents"; - -interface IndividualSubscriptionCardContentProps { - userDetails: UserDetails; -} - -export const IndividualSubscriptionCardContent: React.FC< - IndividualSubscriptionCardContentProps -> = ({ userDetails }) => { - const totalStorage = - userDetails.subscription.storage + (userDetails.storageBonus ?? 0); - return ( - <> - - - - ); -}; - -interface IndividualUsageSectionProps { - usage: number; - fileCount: number; - storage: number; -} -const IndividualUsageSection: React.FC = ({ - usage, - storage, - fileCount, -}) => { - // [Note: Fallback translation for languages with multiple plurals] - // - // Languages like Polish and Arabian have multiple plural forms, and - // currently i18n falls back to the base language translation instead of the - // "_other" form if all the plural forms are not listed out. - // - // As a workaround, name the _other form as the unprefixed name. That is, - // instead of calling the most general plural form as foo_count_other, call - // it foo_count (To keep our heads straight, we adopt the convention that - // all such pluralizable strings use the _count suffix, but that's not a - // requirement from the library). - return ( - - - - {`${formattedStorageByteSize( - storage - usage, - )} ${t("FREE")}`} - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -}; From 2ee6e7edc433c98834c21d36259a7f9416174173 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:17:37 +0530 Subject: [PATCH 10/25] Inline --- .../contentOverlay/family/index.tsx | 102 +++++++++++++++++- .../family/usageSection/index.tsx | 93 ---------------- .../contentOverlay/individual/index.tsx | 0 3 files changed, 99 insertions(+), 96 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx index 77776745dc..ea437ef4b6 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx @@ -1,13 +1,23 @@ +import { + FlexWrapper, + SpaceBetweenFlex, +} from "@ente/shared/components/Container"; +import { Box, Stack, Typography } from "@mui/material"; +import { t } from "i18next"; +import type React from "react"; import { useMemo } from "react"; import { UserDetails } from "types/user"; import { isPartOfFamily } from "utils/user/family"; +import { LegendIndicator, Progressbar } from "../../styledComponents"; import StorageSection from "../storageSection"; -import { FamilyUsageSection } from "./usageSection"; -interface Iprops { +interface FamilySubscriptionCardContentProps { userDetails: UserDetails; } -export function FamilySubscriptionCardContent({ userDetails }: Iprops) { + +export const FamilySubscriptionCardContent: React.FC< + FamilySubscriptionCardContentProps +> = ({ userDetails }) => { const totalUsage = useMemo(() => { if (isPartOfFamily(userDetails.familyData)) { return userDetails.familyData.members.reduce( @@ -32,4 +42,90 @@ export function FamilySubscriptionCardContent({ userDetails }: Iprops) { /> ); +}; + +interface FamilyUsageSectionProps { + userUsage: number; + totalUsage: number; + fileCount: number; + totalStorage: number; } + +const FamilyUsageSection: React.FC = ({ + userUsage, + totalUsage, + fileCount, + totalStorage, +}) => { + return ( + + + + + + + + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; + +interface FamilyUsageProgressBarProps { + userUsage: number; + totalUsage: number; + totalStorage: number; +} + +const FamilyUsageProgressBar: React.FC = ({ + userUsage, + totalUsage, + totalStorage, +}) => { + return ( + + + + + ); +}; + +interface LegendProps { + label: string; + color: string; +} + +const Legend: React.FC = ({ label, color }) => { + return ( + + + + {label} + + + ); +}; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx deleted file mode 100644 index 84ee5b0f69..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/usageSection/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { - FlexWrapper, - SpaceBetweenFlex, -} from "@ente/shared/components/Container"; -import { Box, Stack, Typography } from "@mui/material"; -import { t } from "i18next"; -import { LegendIndicator, Progressbar } from "../../../styledComponents"; - -interface Iprops { - userUsage: number; - totalUsage: number; - fileCount: number; - totalStorage: number; -} - -export function FamilyUsageSection({ - userUsage, - totalUsage, - fileCount, - totalStorage, -}: Iprops) { - return ( - - - - - - - - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -} - -interface FamilyUsageProgressBarProps { - userUsage: number; - totalUsage: number; - totalStorage: number; -} - -function FamilyUsageProgressBar({ - userUsage, - totalUsage, - totalStorage, -}: FamilyUsageProgressBarProps) { - return ( - - - - - ); -} - -interface LegendProps { - label: string; - color: string; -} - -function Legend({ label, color }: LegendProps) { - return ( - - - - {label} - - - ); -} diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/individual/index.tsx deleted file mode 100644 index e69de29bb2..0000000000 From 499763edacf3c4135e265df8e8b32dfb9496f889 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:21:06 +0530 Subject: [PATCH 11/25] Inline --- .../contentOverlay/family/index.tsx | 131 ----------------- .../SubscriptionCard/contentOverlay/index.tsx | 134 +++++++++++++++++- 2 files changed, 129 insertions(+), 136 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx deleted file mode 100644 index ea437ef4b6..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/family/index.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { - FlexWrapper, - SpaceBetweenFlex, -} from "@ente/shared/components/Container"; -import { Box, Stack, Typography } from "@mui/material"; -import { t } from "i18next"; -import type React from "react"; -import { useMemo } from "react"; -import { UserDetails } from "types/user"; -import { isPartOfFamily } from "utils/user/family"; -import { LegendIndicator, Progressbar } from "../../styledComponents"; -import StorageSection from "../storageSection"; - -interface FamilySubscriptionCardContentProps { - userDetails: UserDetails; -} - -export const FamilySubscriptionCardContent: React.FC< - FamilySubscriptionCardContentProps -> = ({ userDetails }) => { - const totalUsage = useMemo(() => { - if (isPartOfFamily(userDetails.familyData)) { - return userDetails.familyData.members.reduce( - (sum, currentMember) => sum + currentMember.usage, - 0, - ); - } else { - return userDetails.usage; - } - }, [userDetails]); - const totalStorage = - userDetails.familyData.storage + (userDetails.storageBonus ?? 0); - - return ( - <> - - - - ); -}; - -interface FamilyUsageSectionProps { - userUsage: number; - totalUsage: number; - fileCount: number; - totalStorage: number; -} - -const FamilyUsageSection: React.FC = ({ - userUsage, - totalUsage, - fileCount, - totalStorage, -}) => { - return ( - - - - - - - - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -}; - -interface FamilyUsageProgressBarProps { - userUsage: number; - totalUsage: number; - totalStorage: number; -} - -const FamilyUsageProgressBar: React.FC = ({ - userUsage, - totalUsage, - totalStorage, -}) => { - return ( - - - - - ); -}; - -interface LegendProps { - label: string; - color: string; -} - -const Legend: React.FC = ({ label, color }) => { - return ( - - - - {label} - - - ); -}; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx index 58b374ae6f..687ba37896 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx @@ -1,11 +1,16 @@ import { formattedStorageByteSize } from "@/new/photos/utils/units"; -import { Overlay, SpaceBetweenFlex } from "@ente/shared/components/Container"; -import { Box, Typography } from "@mui/material"; +import { + FlexWrapper, + Overlay, + SpaceBetweenFlex, +} from "@ente/shared/components/Container"; +import { Box, Stack, Typography } from "@mui/material"; import { t } from "i18next"; +import type React from "react"; +import { useMemo } from "react"; import { UserDetails } from "types/user"; -import { hasNonAdminFamilyMembers } from "utils/user/family"; -import { Progressbar } from "../styledComponents"; -import { FamilySubscriptionCardContent } from "./family"; +import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; +import { LegendIndicator, Progressbar } from "../styledComponents"; import StorageSection from "./storageSection"; interface SubscriptionCardContentOverlayPprops { @@ -95,3 +100,122 @@ const IndividualUsageSection: React.FC = ({ ); }; + +interface FamilySubscriptionCardContentProps { + userDetails: UserDetails; +} + +const FamilySubscriptionCardContent: React.FC< + FamilySubscriptionCardContentProps +> = ({ userDetails }) => { + const totalUsage = useMemo(() => { + if (isPartOfFamily(userDetails.familyData)) { + return userDetails.familyData.members.reduce( + (sum, currentMember) => sum + currentMember.usage, + 0, + ); + } else { + return userDetails.usage; + } + }, [userDetails]); + const totalStorage = + userDetails.familyData.storage + (userDetails.storageBonus ?? 0); + + return ( + <> + + + + ); +}; + +interface FamilyUsageSectionProps { + userUsage: number; + totalUsage: number; + fileCount: number; + totalStorage: number; +} + +const FamilyUsageSection: React.FC = ({ + userUsage, + totalUsage, + fileCount, + totalStorage, +}) => { + return ( + + + + + + + + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; + +interface FamilyUsageProgressBarProps { + userUsage: number; + totalUsage: number; + totalStorage: number; +} + +const FamilyUsageProgressBar: React.FC = ({ + userUsage, + totalUsage, + totalStorage, +}) => { + return ( + + + + + ); +}; + +interface LegendProps { + label: string; + color: string; +} + +const Legend: React.FC = ({ label, color }) => { + return ( + + + + {label} + + + ); +}; From f3c4ca932de22a091b34e338e338b811cc0ddea9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:23:19 +0530 Subject: [PATCH 12/25] Inline --- .../SubscriptionCard/contentOverlay/index.tsx | 52 +++++++++++++++++-- .../contentOverlay/storageSection.tsx | 48 ----------------- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx index 687ba37896..a84f6b98ad 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx @@ -1,17 +1,16 @@ -import { formattedStorageByteSize } from "@/new/photos/utils/units"; +import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; import { FlexWrapper, Overlay, SpaceBetweenFlex, } from "@ente/shared/components/Container"; -import { Box, Stack, Typography } from "@mui/material"; +import { Box, Stack, Typography, styled } from "@mui/material"; import { t } from "i18next"; import type React from "react"; import { useMemo } from "react"; import { UserDetails } from "types/user"; import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; import { LegendIndicator, Progressbar } from "../styledComponents"; -import StorageSection from "./storageSection"; interface SubscriptionCardContentOverlayPprops { userDetails: UserDetails; @@ -60,6 +59,53 @@ const IndividualSubscriptionCardContent: React.FC< ); }; +const MobileSmallBox = styled(Box)` + display: none; + @media (max-width: 359px) { + display: block; + } +`; + +const DefaultBox = styled(Box)` + display: none; + @media (min-width: 360px) { + display: block; + } +`; + +interface StorageSectionProps { + usage: number; + storage: number; +} + +const StorageSection: React.FC = ({ usage, storage }) => { + return ( + + + {t("STORAGE")} + + + + {`${formattedStorageByteSize(usage, { round: true })} ${t( + "OF", + )} ${formattedStorageByteSize(storage)} ${t("USED")}`} + + + + + {`${bytesInGB(usage)} / ${bytesInGB(storage)} ${t("storage_unit.gb")} ${t("USED")}`} + + + + ); +}; + interface IndividualUsageSectionProps { usage: number; fileCount: number; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx index 4ad0ed2149..e69de29bb2 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx @@ -1,48 +0,0 @@ -import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; -import { Box, Typography, styled } from "@mui/material"; -import { t } from "i18next"; - -const MobileSmallBox = styled(Box)` - display: none; - @media (max-width: 359px) { - display: block; - } -`; - -const DefaultBox = styled(Box)` - display: none; - @media (min-width: 360px) { - display: block; - } -`; -interface Iprops { - usage: number; - storage: number; -} -export default function StorageSection({ usage, storage }: Iprops) { - return ( - - - {t("STORAGE")} - - - - {`${formattedStorageByteSize(usage, { round: true })} ${t( - "OF", - )} ${formattedStorageByteSize(storage)} ${t("USED")}`} - - - - - {`${bytesInGB(usage)} / ${bytesInGB(storage)} ${t("storage_unit.gb")} ${t("USED")}`} - - - - ); -} From 0087be4938b21ac822d6ebd0eec0381ba8423470 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:26:45 +0530 Subject: [PATCH 13/25] Inline --- .../SubscriptionCard/contentOverlay/index.tsx | 267 ---------------- .../contentOverlay/storageSection.tsx | 0 .../Sidebar/SubscriptionCard/index.tsx | 291 +++++++++++++++++- 3 files changed, 278 insertions(+), 280 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx index a84f6b98ad..e69de29bb2 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx @@ -1,267 +0,0 @@ -import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; -import { - FlexWrapper, - Overlay, - SpaceBetweenFlex, -} from "@ente/shared/components/Container"; -import { Box, Stack, Typography, styled } from "@mui/material"; -import { t } from "i18next"; -import type React from "react"; -import { useMemo } from "react"; -import { UserDetails } from "types/user"; -import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; -import { LegendIndicator, Progressbar } from "../styledComponents"; - -interface SubscriptionCardContentOverlayPprops { - userDetails: UserDetails; -} - -export const SubscriptionCardContentOverlay: React.FC< - SubscriptionCardContentOverlayPprops -> = ({ userDetails }) => { - return ( - - - {hasNonAdminFamilyMembers(userDetails.familyData) ? ( - - ) : ( - - )} - - - ); -}; - -interface IndividualSubscriptionCardContentProps { - userDetails: UserDetails; -} - -const IndividualSubscriptionCardContent: React.FC< - IndividualSubscriptionCardContentProps -> = ({ userDetails }) => { - const totalStorage = - userDetails.subscription.storage + (userDetails.storageBonus ?? 0); - return ( - <> - - - - ); -}; - -const MobileSmallBox = styled(Box)` - display: none; - @media (max-width: 359px) { - display: block; - } -`; - -const DefaultBox = styled(Box)` - display: none; - @media (min-width: 360px) { - display: block; - } -`; - -interface StorageSectionProps { - usage: number; - storage: number; -} - -const StorageSection: React.FC = ({ usage, storage }) => { - return ( - - - {t("STORAGE")} - - - - {`${formattedStorageByteSize(usage, { round: true })} ${t( - "OF", - )} ${formattedStorageByteSize(storage)} ${t("USED")}`} - - - - - {`${bytesInGB(usage)} / ${bytesInGB(storage)} ${t("storage_unit.gb")} ${t("USED")}`} - - - - ); -}; - -interface IndividualUsageSectionProps { - usage: number; - fileCount: number; - storage: number; -} - -const IndividualUsageSection: React.FC = ({ - usage, - storage, - fileCount, -}) => { - // [Note: Fallback translation for languages with multiple plurals] - // - // Languages like Polish and Arabian have multiple plural forms, and - // currently i18n falls back to the base language translation instead of the - // "_other" form if all the plural forms are not listed out. - // - // As a workaround, name the _other form as the unprefixed name. That is, - // instead of calling the most general plural form as foo_count_other, call - // it foo_count (To keep our heads straight, we adopt the convention that - // all such pluralizable strings use the _count suffix, but that's not a - // requirement from the library). - return ( - - - - {`${formattedStorageByteSize( - storage - usage, - )} ${t("FREE")}`} - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -}; - -interface FamilySubscriptionCardContentProps { - userDetails: UserDetails; -} - -const FamilySubscriptionCardContent: React.FC< - FamilySubscriptionCardContentProps -> = ({ userDetails }) => { - const totalUsage = useMemo(() => { - if (isPartOfFamily(userDetails.familyData)) { - return userDetails.familyData.members.reduce( - (sum, currentMember) => sum + currentMember.usage, - 0, - ); - } else { - return userDetails.usage; - } - }, [userDetails]); - const totalStorage = - userDetails.familyData.storage + (userDetails.storageBonus ?? 0); - - return ( - <> - - - - ); -}; - -interface FamilyUsageSectionProps { - userUsage: number; - totalUsage: number; - fileCount: number; - totalStorage: number; -} - -const FamilyUsageSection: React.FC = ({ - userUsage, - totalUsage, - fileCount, - totalStorage, -}) => { - return ( - - - - - - - - - {t("photos_count", { count: fileCount ?? 0 })} - - - - ); -}; - -interface FamilyUsageProgressBarProps { - userUsage: number; - totalUsage: number; - totalStorage: number; -} - -const FamilyUsageProgressBar: React.FC = ({ - userUsage, - totalUsage, - totalStorage, -}) => { - return ( - - - - - ); -}; - -interface LegendProps { - label: string; - color: string; -} - -const Legend: React.FC = ({ label, color }) => { - return ( - - - - {label} - - - ); -}; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/storageSection.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx index 514c43df81..6c7dadb531 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx @@ -1,23 +1,34 @@ -import { FlexWrapper, Overlay } from "@ente/shared/components/Container"; +import type { ButtonishProps } from "@/new/photos/components/mui"; +import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; +import { + FlexWrapper, + Overlay, + SpaceBetweenFlex, +} from "@ente/shared/components/Container"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; -import { Box, Skeleton } from "@mui/material"; -import { UserDetails } from "types/user"; -import { SubscriptionCardContentOverlay } from "./contentOverlay"; +import { Box, Skeleton, Stack, Typography, styled } from "@mui/material"; +import { t } from "i18next"; +import type React from "react"; +import { useMemo } from "react"; +import type { UserDetails } from "types/user"; +import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; +import { LegendIndicator, Progressbar } from "./styledComponents"; -const SUBSCRIPTION_CARD_SIZE = 152; - -interface Iprops { +interface SubscriptionCardProps { userDetails: UserDetails; onClick: () => void; } -export default function SubscriptionCard({ userDetails, onClick }: Iprops) { +export const SubscriptionCard: React.FC = ({ + userDetails, + onClick, +}) => { if (!userDetails) { return ( ); @@ -30,9 +41,9 @@ export default function SubscriptionCard({ userDetails, onClick }: Iprops) { ); -} +}; -function BackgroundOverlay() { +const BackgroundOverlay: React.FC = () => { return ( ); -} +}; -function ClickOverlay({ onClick }) { +const ClickOverlay: React.FC = ({ onClick }) => { return ( ); +}; + +interface SubscriptionCardContentOverlayProps { + userDetails: UserDetails; } + +export const SubscriptionCardContentOverlay: React.FC< + SubscriptionCardContentOverlayProps +> = ({ userDetails }) => { + return ( + + + {hasNonAdminFamilyMembers(userDetails.familyData) ? ( + + ) : ( + + )} + + + ); +}; + +interface IndividualSubscriptionCardContentProps { + userDetails: UserDetails; +} + +const IndividualSubscriptionCardContent: React.FC< + IndividualSubscriptionCardContentProps +> = ({ userDetails }) => { + const totalStorage = + userDetails.subscription.storage + (userDetails.storageBonus ?? 0); + return ( + <> + + + + ); +}; + +const MobileSmallBox = styled(Box)` + display: none; + @media (max-width: 359px) { + display: block; + } +`; + +const DefaultBox = styled(Box)` + display: none; + @media (min-width: 360px) { + display: block; + } +`; + +interface StorageSectionProps { + usage: number; + storage: number; +} + +const StorageSection: React.FC = ({ usage, storage }) => { + return ( + + + {t("STORAGE")} + + + + {`${formattedStorageByteSize(usage, { round: true })} ${t( + "OF", + )} ${formattedStorageByteSize(storage)} ${t("USED")}`} + + + + + {`${bytesInGB(usage)} / ${bytesInGB(storage)} ${t("storage_unit.gb")} ${t("USED")}`} + + + + ); +}; + +interface IndividualUsageSectionProps { + usage: number; + fileCount: number; + storage: number; +} + +const IndividualUsageSection: React.FC = ({ + usage, + storage, + fileCount, +}) => { + // [Note: Fallback translation for languages with multiple plurals] + // + // Languages like Polish and Arabian have multiple plural forms, and + // currently i18n falls back to the base language translation instead of the + // "_other" form if all the plural forms are not listed out. + // + // As a workaround, name the _other form as the unprefixed name. That is, + // instead of calling the most general plural form as foo_count_other, call + // it foo_count (To keep our heads straight, we adopt the convention that + // all such pluralizable strings use the _count suffix, but that's not a + // requirement from the library). + return ( + + + + {`${formattedStorageByteSize( + storage - usage, + )} ${t("FREE")}`} + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; + +interface FamilySubscriptionCardContentProps { + userDetails: UserDetails; +} + +const FamilySubscriptionCardContent: React.FC< + FamilySubscriptionCardContentProps +> = ({ userDetails }) => { + const totalUsage = useMemo(() => { + if (isPartOfFamily(userDetails.familyData)) { + return userDetails.familyData.members.reduce( + (sum, currentMember) => sum + currentMember.usage, + 0, + ); + } else { + return userDetails.usage; + } + }, [userDetails]); + const totalStorage = + userDetails.familyData.storage + (userDetails.storageBonus ?? 0); + + return ( + <> + + + + ); +}; + +interface FamilyUsageSectionProps { + userUsage: number; + totalUsage: number; + fileCount: number; + totalStorage: number; +} + +const FamilyUsageSection: React.FC = ({ + userUsage, + totalUsage, + fileCount, + totalStorage, +}) => { + return ( + + + + + + + + + {t("photos_count", { count: fileCount ?? 0 })} + + + + ); +}; + +interface FamilyUsageProgressBarProps { + userUsage: number; + totalUsage: number; + totalStorage: number; +} + +const FamilyUsageProgressBar: React.FC = ({ + userUsage, + totalUsage, + totalStorage, +}) => { + return ( + + + + + ); +}; + +interface LegendProps { + label: string; + color: string; +} + +const Legend: React.FC = ({ label, color }) => { + return ( + + + + {label} + + + ); +}; From 8ac01c96a3f740c370e38ce1a7f39052f71b59c9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:28:55 +0530 Subject: [PATCH 14/25] Inline --- .../SubscriptionCard/contentOverlay/index.tsx | 0 .../Sidebar/SubscriptionCard/index.tsx | 36 +++++++++++++++++-- .../SubscriptionCard/styledComponents.tsx | 27 -------------- 3 files changed, 34 insertions(+), 29 deletions(-) delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx delete mode 100644 web/apps/photos/src/components/Sidebar/SubscriptionCard/styledComponents.tsx diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/contentOverlay/index.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx index 6c7dadb531..922d5bce91 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx @@ -6,13 +6,20 @@ import { SpaceBetweenFlex, } from "@ente/shared/components/Container"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; -import { Box, Skeleton, Stack, Typography, styled } from "@mui/material"; +import CircleIcon from "@mui/icons-material/Circle"; +import { + Box, + LinearProgress, + Skeleton, + Stack, + Typography, + styled, +} from "@mui/material"; import { t } from "i18next"; import type React from "react"; import { useMemo } from "react"; import type { UserDetails } from "types/user"; import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; -import { LegendIndicator, Progressbar } from "./styledComponents"; interface SubscriptionCardProps { userDetails: UserDetails; @@ -322,3 +329,28 @@ const Legend: React.FC = ({ label, color }) => { ); }; + +const Progressbar = styled(LinearProgress)(() => ({ + ".MuiLinearProgress-bar": { + borderRadius: "2px", + }, + borderRadius: "2px", + backgroundColor: "rgba(255, 255, 255, 0.2)", +})); + +Progressbar.defaultProps = { + variant: "determinate", +}; + +const DotSeparator = styled(CircleIcon)` + font-size: 4px; + margin: 0 ${({ theme }) => theme.spacing(1)}; + color: inherit; +`; + +const LegendIndicator = styled(DotSeparator)` + font-size: 8.71px; + margin: 0; + margin-right: 4px; + color: inherit; +`; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/styledComponents.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard/styledComponents.tsx deleted file mode 100644 index 90bea72ce7..0000000000 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard/styledComponents.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import CircleIcon from "@mui/icons-material/Circle"; -import { LinearProgress, styled } from "@mui/material"; - -export const Progressbar = styled(LinearProgress)(() => ({ - ".MuiLinearProgress-bar": { - borderRadius: "2px", - }, - borderRadius: "2px", - backgroundColor: "rgba(255, 255, 255, 0.2)", -})); - -Progressbar.defaultProps = { - variant: "determinate", -}; - -const DotSeparator = styled(CircleIcon)` - font-size: 4px; - margin: 0 ${({ theme }) => theme.spacing(1)}; - color: inherit; -`; - -export const LegendIndicator = styled(DotSeparator)` - font-size: 8.71px; - margin: 0; - margin-right: 4px; - color: inherit; -`; From 0464e31393c0d7b9e9c8449777d7267ae1720dc2 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:30:32 +0530 Subject: [PATCH 15/25] Move --- .../{SubscriptionCard/index.tsx => SubscriptionCard.tsx} | 0 web/apps/photos/src/components/Sidebar/index.tsx | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename web/apps/photos/src/components/Sidebar/{SubscriptionCard/index.tsx => SubscriptionCard.tsx} (100%) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx similarity index 100% rename from web/apps/photos/src/components/Sidebar/SubscriptionCard/index.tsx rename to web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 922e6a2148..6150c4f750 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -81,13 +81,14 @@ import { isFamilyAdmin, isPartOfFamily } from "utils/user/family"; import { testUpload } from "../../../tests/upload.test"; import { MemberSubscriptionManage } from "../MemberSubscriptionManage"; import { Preferences } from "./Preferences"; -import SubscriptionCard from "./SubscriptionCard"; +import { SubscriptionCard } from "./SubscriptionCard"; interface Iprops { collectionSummaries: CollectionSummaries; sidebarView: boolean; closeSidebar: () => void; } + export default function Sidebar({ collectionSummaries, sidebarView, From e07bf90f7ae73aaf520d110e39932bf9510b8cd6 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:41:25 +0530 Subject: [PATCH 16/25] Remove deprecated defaultProps --- .../src/components/Sidebar/SubscriptionCard.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index 922d5bce91..514d6126fd 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -194,7 +194,10 @@ const IndividualUsageSection: React.FC = ({ // requirement from the library). return ( - + = ({ }) => { return ( - - = ({ label, color }) => { ); }; -const Progressbar = styled(LinearProgress)(() => ({ +const ProgressBar = styled(LinearProgress)(() => ({ ".MuiLinearProgress-bar": { borderRadius: "2px", }, @@ -338,10 +343,6 @@ const Progressbar = styled(LinearProgress)(() => ({ backgroundColor: "rgba(255, 255, 255, 0.2)", })); -Progressbar.defaultProps = { - variant: "determinate", -}; - const DotSeparator = styled(CircleIcon)` font-size: 4px; margin: 0 ${({ theme }) => theme.spacing(1)}; From c7b9a350346341785ed6b32e724f534415cc2605 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:49:11 +0530 Subject: [PATCH 17/25] Conv --- web/apps/photos/src/pages/gallery.tsx | 12 ++++++------ web/apps/photos/src/utils/ui/index.tsx | 14 -------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 9b5c433337..082cac72c3 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -1,3 +1,4 @@ +import { sessionExpiredDialogAttributes } from "@/accounts/components/LoginComponents"; import { stashRedirect } from "@/accounts/services/redirect"; import { NavbarBase } from "@/base/components/Navbar"; import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; @@ -129,7 +130,6 @@ import { handleCollectionOps, } from "utils/collection"; import { FILE_OPS_TYPE, getSelectedFiles, handleFileOps } from "utils/file"; -import { getSessionExpiredMessage } from "utils/ui"; import { getLocalFamilyData } from "utils/user/family"; const defaultGalleryContext: GalleryContextType = { @@ -228,6 +228,7 @@ export default function Gallery() { showLoadingBar, hideLoadingBar, setDialogMessage, + showMiniDialog, logout, ...appContext } = useAppContext(); @@ -548,9 +549,8 @@ export default function Gallery() { }; }, [selectAll, clearSelection]); - const showSessionExpiredMessage = () => { - setDialogMessage(getSessionExpiredMessage(logout)); - }; + const showSessionExpiredDialog = () => + showMiniDialog(sessionExpiredDialogAttributes(logout)); const syncWithRemote = async (force = false, silent = false) => { if (!navigator.onLine) return; @@ -609,7 +609,7 @@ export default function Gallery() { } catch (e) { switch (e.message) { case CustomError.SESSION_EXPIRED: - showSessionExpiredMessage(); + showSessionExpiredDialog(); break; case CustomError.KEY_MISSING: clearKeys(); @@ -1026,6 +1026,7 @@ export default function Gallery() { isFirstUpload={areOnlySystemCollections( collectionSummaries, )} + showSessionExpiredMessage={showSessionExpiredDialog} {...{ dragAndDropFiles, openFileSelector, @@ -1036,7 +1037,6 @@ export default function Gallery() { fileSelectorZipFiles, uploadTypeSelectorIntent, uploadTypeSelectorView, - showSessionExpiredMessage, }} /> ), }); - -export const getSessionExpiredMessage = ( - action: () => void, -): DialogBoxAttributes => ({ - title: t("session_expired"), - content: t("session_expired_message"), - - nonClosable: true, - proceed: { - text: t("login"), - action, - variant: "accent", - }, -}); From 59e9e26d064523a2b50f628b7833f01861d8bfaf Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 10:53:13 +0530 Subject: [PATCH 18/25] Flatten --- .../photos/src/components/Sidebar/SubscriptionCard.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index 514d6126fd..91d632bbf1 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -343,15 +343,9 @@ const ProgressBar = styled(LinearProgress)(() => ({ backgroundColor: "rgba(255, 255, 255, 0.2)", })); -const DotSeparator = styled(CircleIcon)` - font-size: 4px; - margin: 0 ${({ theme }) => theme.spacing(1)}; - color: inherit; -`; - -const LegendIndicator = styled(DotSeparator)` +const LegendIndicator = styled(CircleIcon)` font-size: 8.71px; margin: 0; - margin-right: 4px; + margin-inline-end: 4px; color: inherit; `; From 339cdeaa5593145f64d9b00209733eaf3e021fed Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:03:14 +0530 Subject: [PATCH 19/25] Tweak --- .../components/Sidebar/SubscriptionCard.tsx | 101 ++++++++++-------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index 91d632bbf1..82f37eead0 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -14,6 +14,7 @@ import { Stack, Typography, styled, + type LinearProgressProps, } from "@mui/material"; import { t } from "i18next"; import type React from "react"; @@ -194,10 +195,7 @@ const IndividualUsageSection: React.FC = ({ // requirement from the library). return ( - + = ({ }) => { return ( - = ({ ); }; -interface FamilyUsageProgressBarProps { +interface FamilyUsageBarProps { userUsage: number; totalUsage: number; totalStorage: number; } -const FamilyUsageProgressBar: React.FC = ({ +const FamilyUsageBar: React.FC = ({ userUsage, totalUsage, totalStorage, -}) => { - return ( - - - - - ); +}) => ( + + + + +); + +type UsageBarProps = Pick & { + used: number; + total: number; }; -interface LegendProps { - label: string; - color: string; -} +const UsageBar: React.FC = ({ used, total, sx }) => ( + +); -const Legend: React.FC = ({ label, color }) => { - return ( - - - - {label} - - - ); -}; - -const ProgressBar = styled(LinearProgress)(() => ({ +const UsageBar_ = styled(LinearProgress)(() => ({ ".MuiLinearProgress-bar": { borderRadius: "2px", }, @@ -343,7 +336,21 @@ const ProgressBar = styled(LinearProgress)(() => ({ backgroundColor: "rgba(255, 255, 255, 0.2)", })); -const LegendIndicator = styled(CircleIcon)` +interface LegendProps { + label: string; + color: string; +} + +const Legend: React.FC = ({ label, color }) => ( + + + + {label} + + +); + +const LegendDot = styled(CircleIcon)` font-size: 8.71px; margin: 0; margin-inline-end: 4px; From b03effff3e9bde3d3a5795ec0032bc33d6cfd372 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:09:30 +0530 Subject: [PATCH 20/25] Tweak --- .../components/Sidebar/SubscriptionCard.tsx | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index 82f37eead0..8da968f22b 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -1,10 +1,6 @@ import type { ButtonishProps } from "@/new/photos/components/mui"; import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; -import { - FlexWrapper, - Overlay, - SpaceBetweenFlex, -} from "@ente/shared/components/Container"; +import { Overlay, SpaceBetweenFlex } from "@ente/shared/components/Container"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import CircleIcon from "@mui/icons-material/Circle"; import { @@ -63,19 +59,19 @@ const BackgroundOverlay: React.FC = () => { ); }; -const ClickOverlay: React.FC = ({ onClick }) => { - return ( - - - - - - ); -}; +const ClickOverlay: React.FC = ({ onClick }) => ( + + + +); interface SubscriptionCardContentOverlayProps { userDetails: UserDetails; From bbc7d63250383117e5b8f248f7014b29f232fe7a Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:12:30 +0530 Subject: [PATCH 21/25] Move --- web/apps/accounts/src/pages/_app.tsx | 2 +- web/apps/auth/src/pages/_app.tsx | 2 +- web/apps/photos/src/components/PhotoViewer/index.tsx | 3 ++- .../src/components/Sidebar/SubscriptionCard.tsx | 3 ++- .../src/components/pages/gallery/PreviewCard.tsx | 2 +- web/apps/photos/src/pages/_app.tsx | 2 +- web/packages/base/components/mui/Container.tsx | 12 ++++++++++++ .../new/photos/components/PlaceholderThumbnails.tsx | 2 +- .../new/photos/components/gallery/BarImpl.tsx | 2 +- web/packages/shared/components/Container.tsx | 7 ------- 10 files changed, 22 insertions(+), 15 deletions(-) diff --git a/web/apps/accounts/src/pages/_app.tsx b/web/apps/accounts/src/pages/_app.tsx index e52d4abc28..3b425cb965 100644 --- a/web/apps/accounts/src/pages/_app.tsx +++ b/web/apps/accounts/src/pages/_app.tsx @@ -2,12 +2,12 @@ import { staticAppTitle } from "@/base/app"; import { CustomHead } from "@/base/components/Head"; import { AttributedMiniDialog } from "@/base/components/MiniDialog"; import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; +import { Overlay } from "@/base/components/mui/Container"; import { AppNavbar } from "@/base/components/Navbar"; import { useAttributedMiniDialog } from "@/base/components/utils/dialog"; import { setupI18n } from "@/base/i18n"; import { disableDiskLogs } from "@/base/log"; import { logUnhandledErrorsAndRejections } from "@/base/log-web"; -import { Overlay } from "@ente/shared/components/Container"; import { getTheme } from "@ente/shared/themes"; import { THEME_COLOR } from "@ente/shared/themes/constants"; import { CssBaseline } from "@mui/material"; diff --git a/web/apps/auth/src/pages/_app.tsx b/web/apps/auth/src/pages/_app.tsx index 5557ace23d..b8cb12239d 100644 --- a/web/apps/auth/src/pages/_app.tsx +++ b/web/apps/auth/src/pages/_app.tsx @@ -4,6 +4,7 @@ import { clientPackageName, staticAppTitle } from "@/base/app"; import { CustomHead } from "@/base/components/Head"; import { AttributedMiniDialog } from "@/base/components/MiniDialog"; import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; +import { Overlay } from "@/base/components/mui/Container"; import { AppNavbar } from "@/base/components/Navbar"; import { genericErrorDialogAttributes, @@ -15,7 +16,6 @@ import { logUnhandledErrorsAndRejections, } from "@/base/log-web"; import { ensure } from "@/utils/ensure"; -import { Overlay } from "@ente/shared/components/Container"; import { MessageContainer } from "@ente/shared/components/MessageContainer"; import { useLocalState } from "@ente/shared/hooks/useLocalState"; import HTTPService from "@ente/shared/network/HTTPService"; diff --git a/web/apps/photos/src/components/PhotoViewer/index.tsx b/web/apps/photos/src/components/PhotoViewer/index.tsx index e13c49f8ea..d1ee5f59de 100644 --- a/web/apps/photos/src/components/PhotoViewer/index.tsx +++ b/web/apps/photos/src/components/PhotoViewer/index.tsx @@ -1,5 +1,6 @@ import { isDesktop } from "@/base/app"; import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; +import { Overlay } from "@/base/components/mui/Container"; import { lowercaseExtension } from "@/base/file"; import log from "@/base/log"; import type { LoadedLivePhotoSourceURL } from "@/media/file"; @@ -9,7 +10,7 @@ import { isHEICExtension, needsJPEGConversion } from "@/media/formats"; import downloadManager from "@/new/photos/services/download"; import { extractRawExif, parseExif } from "@/new/photos/services/exif"; import { AppContext } from "@/new/photos/types/context"; -import { FlexWrapper, Overlay } from "@ente/shared/components/Container"; +import { FlexWrapper } from "@ente/shared/components/Container"; import AlbumOutlined from "@mui/icons-material/AlbumOutlined"; import ChevronLeft from "@mui/icons-material/ChevronLeft"; import ChevronRight from "@mui/icons-material/ChevronRight"; diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index 8da968f22b..cd121608ce 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -1,6 +1,7 @@ +import { Overlay } from "@/base/components/mui/Container"; import type { ButtonishProps } from "@/new/photos/components/mui"; import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; -import { Overlay, SpaceBetweenFlex } from "@ente/shared/components/Container"; +import { SpaceBetweenFlex } from "@ente/shared/components/Container"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import CircleIcon from "@mui/icons-material/Circle"; import { diff --git a/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx b/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx index 0f66a27ed6..64a44ff335 100644 --- a/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx +++ b/web/apps/photos/src/components/pages/gallery/PreviewCard.tsx @@ -1,3 +1,4 @@ +import { Overlay } from "@/base/components/mui/Container"; import log from "@/base/log"; import { EnteFile } from "@/media/file"; import { FileType } from "@/media/file-type"; @@ -11,7 +12,6 @@ import { } from "@/new/photos/components/PlaceholderThumbnails"; import { TRASH_SECTION } from "@/new/photos/services/collection"; import DownloadManager from "@/new/photos/services/download"; -import { Overlay } from "@ente/shared/components/Container"; import { CustomError } from "@ente/shared/error"; import useLongPress from "@ente/shared/hooks/useLongPress"; import AlbumOutlined from "@mui/icons-material/AlbumOutlined"; diff --git a/web/apps/photos/src/pages/_app.tsx b/web/apps/photos/src/pages/_app.tsx index 361a0be901..7a1582b8e4 100644 --- a/web/apps/photos/src/pages/_app.tsx +++ b/web/apps/photos/src/pages/_app.tsx @@ -2,6 +2,7 @@ import { clientPackageName, staticAppTitle } from "@/base/app"; import { CustomHead } from "@/base/components/Head"; import { AttributedMiniDialog } from "@/base/components/MiniDialog"; import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator"; +import { Overlay } from "@/base/components/mui/Container"; import { AppNavbar } from "@/base/components/Navbar"; import { genericErrorDialogAttributes, @@ -24,7 +25,6 @@ import DownloadManager from "@/new/photos/services/download"; import { runMigrations } from "@/new/photos/services/migrations"; import { initML, isMLSupported } from "@/new/photos/services/ml"; import { AppContext } from "@/new/photos/types/context"; -import { Overlay } from "@ente/shared/components/Container"; import DialogBox from "@ente/shared/components/DialogBox"; import { DialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; import { MessageContainer } from "@ente/shared/components/MessageContainer"; diff --git a/web/packages/base/components/mui/Container.tsx b/web/packages/base/components/mui/Container.tsx index d985fc033a..abaa0e2dce 100644 --- a/web/packages/base/components/mui/Container.tsx +++ b/web/packages/base/components/mui/Container.tsx @@ -24,3 +24,15 @@ export const CenteredBox = styled("div")` justify-content: center; align-items: center; `; + +/** + * An absolute positioned div that fills the entire nearest relatively + * positioned ancestor. + */ +export const Overlay = styled("div")` + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; +`; diff --git a/web/packages/new/photos/components/PlaceholderThumbnails.tsx b/web/packages/new/photos/components/PlaceholderThumbnails.tsx index 0fcab06569..d6fab83a28 100644 --- a/web/packages/new/photos/components/PlaceholderThumbnails.tsx +++ b/web/packages/new/photos/components/PlaceholderThumbnails.tsx @@ -1,5 +1,5 @@ +import { Overlay } from "@/base/components/mui/Container"; import { FileType } from "@/media/file-type"; -import { Overlay } from "@ente/shared/components/Container"; import PhotoOutlined from "@mui/icons-material/PhotoOutlined"; import PlayCircleOutlineOutlined from "@mui/icons-material/PlayCircleOutlineOutlined"; import { styled } from "@mui/material"; diff --git a/web/packages/new/photos/components/gallery/BarImpl.tsx b/web/packages/new/photos/components/gallery/BarImpl.tsx index 6821b622b0..29c9d7987c 100644 --- a/web/packages/new/photos/components/gallery/BarImpl.tsx +++ b/web/packages/new/photos/components/gallery/BarImpl.tsx @@ -1,3 +1,4 @@ +import { Overlay } from "@/base/components/mui/Container"; import { useIsSmallWidth } from "@/base/hooks"; import { CollectionsSortOptions } from "@/new/photos/components/CollectionsSortOptions"; import { FilledIconButton } from "@/new/photos/components/mui"; @@ -18,7 +19,6 @@ import type { } from "@/new/photos/services/collection/ui"; import type { Person } from "@/new/photos/services/ml/people"; import { ensure } from "@/utils/ensure"; -import { Overlay } from "@ente/shared/components/Container"; import ArchiveIcon from "@mui/icons-material/Archive"; import ExpandMore from "@mui/icons-material/ExpandMore"; import Favorite from "@mui/icons-material/FavoriteRounded"; diff --git a/web/packages/shared/components/Container.tsx b/web/packages/shared/components/Container.tsx index 9a1eb9666e..3472e2c5b4 100644 --- a/web/packages/shared/components/Container.tsx +++ b/web/packages/shared/components/Container.tsx @@ -32,13 +32,6 @@ export const FluidContainer = styled(FlexWrapper)` flex: 1; `; -export const Overlay = styled(Box)` - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; -`; export const HorizontalFlex = styled(Box)({ display: "flex", From 25f6ad893db2adaac8596f2e45959a1405dd498b Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:13:50 +0530 Subject: [PATCH 22/25] Fix lints --- web/apps/photos/src/pages/shared-albums.tsx | 2 +- web/apps/photos/src/services/upload/uploadManager.ts | 2 +- web/packages/gallery/tsconfig.json | 2 +- web/packages/shared/components/Container.tsx | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/web/apps/photos/src/pages/shared-albums.tsx b/web/apps/photos/src/pages/shared-albums.tsx index 3556c57a34..3bc2f51229 100644 --- a/web/apps/photos/src/pages/shared-albums.tsx +++ b/web/apps/photos/src/pages/shared-albums.tsx @@ -5,9 +5,9 @@ import { NavbarBase, SelectionBar } from "@/base/components/Navbar"; import { sharedCryptoWorker } from "@/base/crypto"; import { useIsSmallWidth, useIsTouchscreen } from "@/base/hooks"; import log from "@/base/log"; +import { updateShouldDisableCFUploadProxy } from "@/gallery/upload"; import type { Collection } from "@/media/collection"; import { type EnteFile, mergeMetadata } from "@/media/file"; -import { updateShouldDisableCFUploadProxy } from "@/gallery/upload"; import { GalleryItemsHeaderAdapter, GalleryItemsSummary, diff --git a/web/apps/photos/src/services/upload/uploadManager.ts b/web/apps/photos/src/services/upload/uploadManager.ts index 2171d079a9..c3989ee91f 100644 --- a/web/apps/photos/src/services/upload/uploadManager.ts +++ b/web/apps/photos/src/services/upload/uploadManager.ts @@ -4,11 +4,11 @@ import { lowercaseExtension, nameAndExtension } from "@/base/file"; import log from "@/base/log"; import type { Electron } from "@/base/types/ipc"; import { ComlinkWorker } from "@/base/worker/comlink-worker"; +import { shouldDisableCFUploadProxy } from "@/gallery/upload"; import type { Collection } from "@/media/collection"; import { EncryptedEnteFile, EnteFile } from "@/media/file"; import { FileType } from "@/media/file-type"; import { potentialFileTypeFromExtension } from "@/media/live-photo"; -import { shouldDisableCFUploadProxy } from "@/gallery/upload"; import { getLocalFiles } from "@/new/photos/services/files"; import { indexNewUpload } from "@/new/photos/services/ml"; import type { UploadItem } from "@/new/photos/services/upload/types"; diff --git a/web/packages/gallery/tsconfig.json b/web/packages/gallery/tsconfig.json index b39c0995b0..b2a1203623 100644 --- a/web/packages/gallery/tsconfig.json +++ b/web/packages/gallery/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "@/build-config/tsconfig-next.json", - "include": ["."] + "include": [".", "../../packages/base/global-electron.d.ts"] } diff --git a/web/packages/shared/components/Container.tsx b/web/packages/shared/components/Container.tsx index 3472e2c5b4..7852439cb4 100644 --- a/web/packages/shared/components/Container.tsx +++ b/web/packages/shared/components/Container.tsx @@ -32,7 +32,6 @@ export const FluidContainer = styled(FlexWrapper)` flex: 1; `; - export const HorizontalFlex = styled(Box)({ display: "flex", }); From 6830ace1cef024cd2675f7147c9f3fd5e2723315 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:16:11 +0530 Subject: [PATCH 23/25] Inline --- .../photos/src/components/pages/gallery/PlanSelector.tsx | 8 ++++++-- web/apps/photos/src/utils/user/index.ts | 6 ------ 2 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 web/apps/photos/src/utils/user/index.ts diff --git a/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx b/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx index 3e840eaa03..7aee04f44d 100644 --- a/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx +++ b/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx @@ -8,6 +8,7 @@ import { FluidContainer, SpaceBetweenFlex, } from "@ente/shared/components/Container"; +import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; import ArrowForward from "@mui/icons-material/ArrowForward"; import ChevronRight from "@mui/icons-material/ChevronRight"; import Close from "@mui/icons-material/Close"; @@ -34,7 +35,7 @@ import billingService, { type PlansResponse } from "services/billingService"; import { getFamilyPortalRedirectURL } from "services/userService"; import { Plan, PLAN_PERIOD, Subscription } from "types/billing"; import { SetLoading } from "types/gallery"; -import { BonusData } from "types/user"; +import { BonusData, UserDetails } from "types/user"; import { activateSubscription, cancelSubscription, @@ -52,7 +53,6 @@ import { updatePaymentMethod, updateSubscription, } from "utils/billing"; -import { getLocalUserDetails } from "utils/user"; import { getTotalFamilyUsage, isPartOfFamily } from "utils/user/family"; interface PlanSelectorProps { @@ -796,3 +796,7 @@ const ManageSubscriptionButton = ({ children, ...props }: ButtonProps) => ( {children} ); + +function getLocalUserDetails(): UserDetails { + return getData(LS_KEYS.USER_DETAILS)?.value; +} diff --git a/web/apps/photos/src/utils/user/index.ts b/web/apps/photos/src/utils/user/index.ts deleted file mode 100644 index 7404fb5887..0000000000 --- a/web/apps/photos/src/utils/user/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; -import { UserDetails } from "types/user"; - -export function getLocalUserDetails(): UserDetails { - return getData(LS_KEYS.USER_DETAILS)?.value; -} From e267dc6bc983c1b09307622706aef597652e9308 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:22:45 +0530 Subject: [PATCH 24/25] Move --- .../components/MemberSubscriptionManage.tsx | 2 +- .../components/Sidebar/SubscriptionCard.tsx | 5 +- .../photos/src/components/Sidebar/index.tsx | 2 +- .../components/pages/gallery/PlanSelector.tsx | 5 +- web/apps/photos/src/pages/gallery.tsx | 2 +- web/apps/photos/src/services/userService.ts | 2 +- web/apps/photos/src/utils/billing/index.ts | 5 +- web/apps/photos/src/utils/user/family.ts | 43 ---------------- web/packages/new/photos/services/user.ts | 49 +++++++++++++++++++ 9 files changed, 65 insertions(+), 50 deletions(-) delete mode 100644 web/apps/photos/src/utils/user/family.ts diff --git a/web/apps/photos/src/components/MemberSubscriptionManage.tsx b/web/apps/photos/src/components/MemberSubscriptionManage.tsx index 5fec26cbdf..62be7e4473 100644 --- a/web/apps/photos/src/components/MemberSubscriptionManage.tsx +++ b/web/apps/photos/src/components/MemberSubscriptionManage.tsx @@ -1,4 +1,5 @@ import { useIsSmallWidth } from "@/base/hooks"; +import { getFamilyPlanAdmin } from "@/new/photos/services/user"; import { AppContext } from "@/new/photos/types/context"; import { FlexWrapper, @@ -9,7 +10,6 @@ import { Box, Button, Dialog, DialogContent, Typography } from "@mui/material"; import { t } from "i18next"; import { useContext } from "react"; import billingService from "services/billingService"; -import { getFamilyPlanAdmin } from "utils/user/family"; export function MemberSubscriptionManage({ open, userDetails, onClose }) { const { setDialogMessage } = useContext(AppContext); diff --git a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx index cd121608ce..090b4c949f 100644 --- a/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx +++ b/web/apps/photos/src/components/Sidebar/SubscriptionCard.tsx @@ -1,5 +1,9 @@ import { Overlay } from "@/base/components/mui/Container"; import type { ButtonishProps } from "@/new/photos/components/mui"; +import { + hasNonAdminFamilyMembers, + isPartOfFamily, +} from "@/new/photos/services/user"; import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; import { SpaceBetweenFlex } from "@ente/shared/components/Container"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; @@ -17,7 +21,6 @@ import { t } from "i18next"; import type React from "react"; import { useMemo } from "react"; import type { UserDetails } from "types/user"; -import { hasNonAdminFamilyMembers, isPartOfFamily } from "utils/user/family"; interface SubscriptionCardProps { userDetails: UserDetails; diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 6150c4f750..3ad8b186e8 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -77,7 +77,7 @@ import { isSubscriptionCancelled, isSubscriptionPastDue, } from "utils/billing"; -import { isFamilyAdmin, isPartOfFamily } from "utils/user/family"; +import { isFamilyAdmin, isPartOfFamily } from "@/new/photos/services/user"; import { testUpload } from "../../../tests/upload.test"; import { MemberSubscriptionManage } from "../MemberSubscriptionManage"; import { Preferences } from "./Preferences"; diff --git a/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx b/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx index 7aee04f44d..a64a302e46 100644 --- a/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx +++ b/web/apps/photos/src/components/pages/gallery/PlanSelector.tsx @@ -1,5 +1,9 @@ import { genericRetriableErrorDialogAttributes } from "@/base/components/utils/dialog"; import log from "@/base/log"; +import { + getTotalFamilyUsage, + isPartOfFamily, +} from "@/new/photos/services/user"; import { AppContext } from "@/new/photos/types/context"; import { bytesInGB, formattedStorageByteSize } from "@/new/photos/utils/units"; import { openURL } from "@/new/photos/utils/web"; @@ -53,7 +57,6 @@ import { updatePaymentMethod, updateSubscription, } from "utils/billing"; -import { getTotalFamilyUsage, isPartOfFamily } from "utils/user/family"; interface PlanSelectorProps { modalView: boolean; diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 082cac72c3..ff039f7a67 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -45,6 +45,7 @@ import { } from "@/new/photos/services/search"; import type { SearchOption } from "@/new/photos/services/search/types"; import { initSettings } from "@/new/photos/services/settings"; +import { getLocalFamilyData } from "@/new/photos/services/user"; import { useAppContext } from "@/new/photos/types/context"; import { splitByPredicate } from "@/utils/array"; import { ensure } from "@/utils/ensure"; @@ -130,7 +131,6 @@ import { handleCollectionOps, } from "utils/collection"; import { FILE_OPS_TYPE, getSelectedFiles, handleFileOps } from "utils/file"; -import { getLocalFamilyData } from "utils/user/family"; const defaultGalleryContext: GalleryContextType = { showPlanSelectorModal: () => null, diff --git a/web/apps/photos/src/services/userService.ts b/web/apps/photos/src/services/userService.ts index f6fb67ea3a..171ebf7d2e 100644 --- a/web/apps/photos/src/services/userService.ts +++ b/web/apps/photos/src/services/userService.ts @@ -1,13 +1,13 @@ import { putAttributes } from "@/accounts/api/user"; import log from "@/base/log"; import { apiURL, familyAppOrigin } from "@/base/origins"; +import { getLocalFamilyData, isPartOfFamily } from "@/new/photos/services/user"; import { ApiError } from "@ente/shared/error"; import HTTPService from "@ente/shared/network/HTTPService"; import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; import { getToken } from "@ente/shared/storage/localStorage/helpers"; import { HttpStatusCode } from "axios"; import { DeleteChallengeResponse, UserDetails } from "types/user"; -import { getLocalFamilyData, isPartOfFamily } from "utils/user/family"; const HAS_SET_KEYS = "hasSetKeys"; diff --git a/web/apps/photos/src/utils/billing/index.ts b/web/apps/photos/src/utils/billing/index.ts index a1ff2c7b56..84d6b0c457 100644 --- a/web/apps/photos/src/utils/billing/index.ts +++ b/web/apps/photos/src/utils/billing/index.ts @@ -1,4 +1,8 @@ import log from "@/base/log"; +import { + getTotalFamilyUsage, + isPartOfFamily, +} from "@/new/photos/services/user"; import { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types"; import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; import { t } from "i18next"; @@ -8,7 +12,6 @@ import { Plan, Subscription } from "types/billing"; import { SetLoading } from "types/gallery"; import { BonusData, UserDetails } from "types/user"; import { getSubscriptionPurchaseSuccessMessage } from "utils/ui"; -import { getTotalFamilyUsage, isPartOfFamily } from "utils/user/family"; const PAYMENT_PROVIDER_STRIPE = "stripe"; const FREE_PLAN = "free"; diff --git a/web/apps/photos/src/utils/user/family.ts b/web/apps/photos/src/utils/user/family.ts deleted file mode 100644 index 0456976cc2..0000000000 --- a/web/apps/photos/src/utils/user/family.ts +++ /dev/null @@ -1,43 +0,0 @@ -import log from "@/base/log"; -import type { FamilyData, FamilyMember } from "@/new/photos/services/user"; -import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; -import type { User } from "@ente/shared/user/types"; - -export function getLocalFamilyData(): FamilyData { - return getData(LS_KEYS.FAMILY_DATA); -} - -// isPartOfFamily return true if the current user is part of some family plan -export function isPartOfFamily(familyData: FamilyData): boolean { - return Boolean( - familyData && familyData.members && familyData.members.length > 0, - ); -} - -// hasNonAdminFamilyMembers return true if the admin user has members in his family -export function hasNonAdminFamilyMembers(familyData: FamilyData): boolean { - return Boolean(isPartOfFamily(familyData) && familyData.members.length > 1); -} - -export function isFamilyAdmin(familyData: FamilyData): boolean { - const familyAdmin: FamilyMember = getFamilyPlanAdmin(familyData); - const user: User = getData(LS_KEYS.USER); - return familyAdmin.email === user.email; -} - -export function getFamilyPlanAdmin(familyData: FamilyData): FamilyMember { - if (isPartOfFamily(familyData)) { - return familyData.members.find((x) => x.isAdmin); - } else { - log.error( - "invalid getFamilyPlanAdmin call - verify user is part of family plan before calling this method", - ); - } -} - -export function getTotalFamilyUsage(familyData: FamilyData): number { - return familyData.members.reduce( - (sum, currentMember) => sum + currentMember.usage, - 0, - ); -} diff --git a/web/packages/new/photos/services/user.ts b/web/packages/new/photos/services/user.ts index 58bd087e74..5c20573cab 100644 --- a/web/packages/new/photos/services/user.ts +++ b/web/packages/new/photos/services/user.ts @@ -1,5 +1,8 @@ import { authenticatedRequestHeaders, ensureOk } from "@/base/http"; +import log from "@/base/log"; import { apiURL } from "@/base/origins"; +import { LS_KEYS, getData } from "@ente/shared/storage/localStorage"; +import type { User } from "@ente/shared/user/types"; import { z } from "zod"; export interface FamilyMember { @@ -15,6 +18,52 @@ export interface FamilyData { members: FamilyMember[]; } +export function getLocalFamilyData(): FamilyData { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return getData(LS_KEYS.FAMILY_DATA); +} + +// isPartOfFamily return true if the current user is part of some family plan +export function isPartOfFamily(familyData: FamilyData): boolean { + return Boolean( + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain, @typescript-eslint/no-unnecessary-condition + familyData && familyData.members && familyData.members.length > 0, + ); +} + +// hasNonAdminFamilyMembers return true if the admin user has members in his family +export function hasNonAdminFamilyMembers(familyData: FamilyData): boolean { + return Boolean(isPartOfFamily(familyData) && familyData.members.length > 1); +} + +export function isFamilyAdmin(familyData: FamilyData): boolean { + const familyAdmin: FamilyMember = getFamilyPlanAdmin(familyData); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const user: User = getData(LS_KEYS.USER); + return familyAdmin.email === user.email; +} + +export function getFamilyPlanAdmin(familyData: FamilyData): FamilyMember { + if (isPartOfFamily(familyData)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return familyData.members.find((x) => x.isAdmin)!; + } else { + log.error( + "invalid getFamilyPlanAdmin call - verify user is part of family plan before calling this method", + ); + throw new Error( + "invalid getFamilyPlanAdmin call - verify user is part of family plan before calling this method", + ); + } +} + +export function getTotalFamilyUsage(familyData: FamilyData): number { + return familyData.members.reduce( + (sum, currentMember) => sum + currentMember.usage, + 0, + ); +} + /** * Fetch the two-factor status (whether or not it is enabled) from remote. */ From 91b4ef2915e2510f5b871af07e2e3e0a1db79edd Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 6 Nov 2024 11:33:14 +0530 Subject: [PATCH 25/25] LF --- web/apps/photos/src/components/Sidebar/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 3ad8b186e8..425c7d291e 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -18,6 +18,7 @@ import { } from "@/new/photos/services/collection"; import type { CollectionSummaries } from "@/new/photos/services/collection/ui"; import { isInternalUser } from "@/new/photos/services/settings"; +import { isFamilyAdmin, isPartOfFamily } from "@/new/photos/services/user"; import { AppContext, useAppContext } from "@/new/photos/types/context"; import { initiateEmail, openURL } from "@/new/photos/utils/web"; import { SpaceBetweenFlex } from "@ente/shared/components/Container"; @@ -77,7 +78,6 @@ import { isSubscriptionCancelled, isSubscriptionPastDue, } from "utils/billing"; -import { isFamilyAdmin, isPartOfFamily } from "@/new/photos/services/user"; import { testUpload } from "../../../tests/upload.test"; import { MemberSubscriptionManage } from "../MemberSubscriptionManage"; import { Preferences } from "./Preferences";