From 9ced976c424b6462f6f7dcffa8981926734ec0b0 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 3 Jun 2022 11:44:47 +0530 Subject: [PATCH 1/6] update collectionSummary structure --- .../AllCollections/CollectionCard.tsx | 6 +- .../Collections/AllCollections/content.tsx | 2 +- .../Collections/AllCollections/index.tsx | 2 +- src/components/Collections/CollectionInfo.tsx | 64 +++------- .../Collections/CollectionInfoWithOptions.tsx | 32 +++++ src/components/Collections/index.tsx | 4 +- .../pages/gallery/CollectionSelector.tsx | 8 +- src/pages/gallery/index.tsx | 18 +-- src/pages/shared-albums/index.tsx | 28 ++--- src/services/collectionService.ts | 112 ++++++++---------- src/types/collection/index.ts | 28 +++-- src/utils/file/index.ts | 11 +- 12 files changed, 146 insertions(+), 169 deletions(-) create mode 100644 src/components/Collections/CollectionInfoWithOptions.tsx diff --git a/src/components/Collections/AllCollections/CollectionCard.tsx b/src/components/Collections/AllCollections/CollectionCard.tsx index 45681a6ad..3cbdfb71a 100644 --- a/src/components/Collections/AllCollections/CollectionCard.tsx +++ b/src/components/Collections/AllCollections/CollectionCard.tsx @@ -19,9 +19,7 @@ export default function AllCollectionCard({ - onCollectionClick(collectionSummary.collectionAttributes.id) - }> + onClick={() => onCollectionClick(collectionSummary.attributes.id)}>
- {collectionSummary.collectionAttributes.name} + {collectionSummary.name} ))} diff --git a/src/components/Collections/AllCollections/index.tsx b/src/components/Collections/AllCollections/index.tsx index 8edfd18e0..e76ea8479 100644 --- a/src/components/Collections/AllCollections/index.tsx +++ b/src/components/Collections/AllCollections/index.tsx @@ -35,7 +35,7 @@ export default function AllCollections(props: Iprops) { () => sortCollectionSummaries( [...collectionSummaries.values()].filter( - (x) => x.collectionAttributes.type !== CollectionType.system + (x) => x.type !== CollectionType.system ), collectionSortBy ), diff --git a/src/components/Collections/CollectionInfo.tsx b/src/components/Collections/CollectionInfo.tsx index 6fdf1ba9b..ccbdbf6b7 100644 --- a/src/components/Collections/CollectionInfo.tsx +++ b/src/components/Collections/CollectionInfo.tsx @@ -1,50 +1,24 @@ -import React from 'react'; import { Typography } from '@mui/material'; +import React from 'react'; import constants from 'utils/strings/constants'; -import { Collection, CollectionSummary } from 'types/collection'; -import { PaddedSpaceBetweenFlex } from 'components/Collections/styledComponents'; -import CollectionOptions from 'components/Collections/CollectionOptions'; -import { SetCollectionNamerAttributes } from 'components/Collections/CollectionNamer'; -import { ARCHIVE_SECTION, TRASH_SECTION } from 'constants/collection'; - -interface Iprops { - activeCollection: Collection; - collectionSummary: CollectionSummary; - setCollectionNamerAttributes: SetCollectionNamerAttributes; - showCollectionShareModal: () => void; - redirectToAll: () => void; -} -export default function collectionInfo(props: Iprops) { - if (!props.collectionSummary) { - return <>; - } - const { - collectionSummary: { collectionAttributes, fileCount }, - } = props; - +export function CollectionInfo({ name, fileCount }) { return ( - -
- - {collectionAttributes.name} - - - {constants.PHOTO_COUNT(fileCount)} - -
- {collectionAttributes.id !== ARCHIVE_SECTION && - collectionAttributes.id !== TRASH_SECTION && ( - - )} -
+
+ + {name} + + + {constants.PHOTO_COUNT(fileCount)} + +
); } diff --git a/src/components/Collections/CollectionInfoWithOptions.tsx b/src/components/Collections/CollectionInfoWithOptions.tsx new file mode 100644 index 000000000..0da4c9a93 --- /dev/null +++ b/src/components/Collections/CollectionInfoWithOptions.tsx @@ -0,0 +1,32 @@ +import { CollectionInfo } from './CollectionInfo'; +import React from 'react'; +import { Collection, CollectionSummary } from 'types/collection'; +import { PaddedSpaceBetweenFlex } from 'components/Collections/styledComponents'; +import CollectionOptions from 'components/Collections/CollectionOptions'; +import { SetCollectionNamerAttributes } from 'components/Collections/CollectionNamer'; +import { CollectionType } from 'constants/collection'; + +interface Iprops { + activeCollection: Collection; + collectionSummary: CollectionSummary; + setCollectionNamerAttributes: SetCollectionNamerAttributes; + showCollectionShareModal: () => void; + redirectToAll: () => void; +} +export default function collectionInfoWithOptions({ + collectionSummary, + ...props +}: Iprops) { + if (!collectionSummary) { + return <>; + } + + const { name, type, fileCount } = collectionSummary; + + return ( + + + {type !== CollectionType.system && } + + ); +} diff --git a/src/components/Collections/index.tsx b/src/components/Collections/index.tsx index c254d5d46..6bc57df73 100644 --- a/src/components/Collections/index.tsx +++ b/src/components/Collections/index.tsx @@ -2,7 +2,7 @@ import { Collection, CollectionSummaries } from 'types/collection'; import CollectionBar from 'components/Collections/CollectionBar'; import React, { useEffect, useRef, useState } from 'react'; import AllCollections from 'components/Collections/AllCollections'; -import CollectionInfo from 'components/Collections/CollectionInfo'; +import CollectionInfoWithOptions from 'components/Collections/CollectionInfoWithOptions'; import { ALL_SECTION } from 'constants/collection'; import CollectionShare from 'components/Collections/CollectionShare'; import { SetCollectionNamerAttributes } from 'components/Collections/CollectionNamer'; @@ -60,7 +60,7 @@ export default function Collections(props: Iprops) { setActiveCollection={setActiveCollectionID} /> - + ({ type, attributes: collectionAttributes }) => collectionAttributes.id !== attributes.fromCollection && collectionAttributes.ownerID === user?.id && - collectionAttributes.type !== CollectionType.favorites && - collectionAttributes.type !== CollectionType.system + type !== CollectionType.favorites && + type !== CollectionType.system ); if (personalCollectionsOtherThanFrom.length === 0) { props.onClose(); @@ -96,7 +96,7 @@ function CollectionSelector({ collectionTile={CollectionSelectorTile} onCollectionClick={handleCollectionClick} collectionSummary={collectionSummary} - key={collectionSummary.collectionAttributes.id} + key={collectionSummary.attributes.id} /> ))} diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index 551d11bcc..e183655a4 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -17,7 +17,6 @@ import { import styled from 'styled-components'; import { syncCollections, - getCollectionsAndTheirLatestFile, getFavItemIds, getLocalCollections, getNonEmptyCollections, @@ -91,11 +90,7 @@ import DeleteBtn from 'components/DeleteBtn'; import FixCreationTime, { FixCreationTimeAttributes, } from 'components/FixCreationTime'; -import { - Collection, - CollectionAndItsLatestFile, - CollectionSummaries, -} from 'types/collection'; +import { Collection, CollectionSummaries } from 'types/collection'; import { EnteFile } from 'types/file'; import { GalleryContextType, @@ -145,8 +140,7 @@ export const GalleryContext = createContext( export default function Gallery() { const router = useRouter(); const [collections, setCollections] = useState([]); - const [collectionsAndTheirLatestFile, setCollectionsAndTheirLatestFile] = - useState([]); + const [files, setFiles] = useState(null); const [favItemIds, setFavItemIds] = useState>(); const [bannerMessage, setBannerMessage] = useState( @@ -349,11 +343,7 @@ export default function Gallery() { const nonEmptyCollections = getNonEmptyCollections(collections, files); setCollections(nonEmptyCollections); - const collectionsAndTheirLatestFile = getCollectionsAndTheirLatestFile( - nonEmptyCollections, - files - ); - setCollectionsAndTheirLatestFile(collectionsAndTheirLatestFile); + const collectionSummaries = getCollectionSummaries( nonEmptyCollections, files @@ -672,7 +662,7 @@ export default function Gallery() { setUploadInProgress={setUploadInProgress} fileRejections={fileRejections} setFiles={setFiles} - isFirstUpload={collectionsAndTheirLatestFile?.length === 0} + isFirstUpload={collectionSummaries.size === 0} electronFiles={electronFiles} setElectronFiles={setElectronFiles} uploadTypeSelectorView={uploadTypeSelectorView} diff --git a/src/pages/shared-albums/index.tsx b/src/pages/shared-albums/index.tsx index 0ad69e8ef..39eb4bfdd 100644 --- a/src/pages/shared-albums/index.tsx +++ b/src/pages/shared-albums/index.tsx @@ -13,7 +13,7 @@ import { syncPublicFiles, verifyPublicCollectionPassword, } from 'services/publicCollectionService'; -import { Collection, CollectionSummaries } from 'types/collection'; +import { Collection } from 'types/collection'; import { EnteFile } from 'types/file'; import { mergeMetadata, sortFiles } from 'utils/file'; import { AppContext } from 'pages/_app'; @@ -33,6 +33,8 @@ import SingleInputForm from 'components/SingleInputForm'; import { Card } from 'react-bootstrap'; import { logError } from 'utils/sentry'; import SharedAlbumNavbar from 'components/pages/sharedAlbum/Navbar'; +import { CollectionInfo } from 'components/Collections/CollectionInfo'; +import { PaddedSpaceBetweenFlex } from 'components/Collections/styledComponents'; const Loader = () => ( @@ -59,8 +61,6 @@ export default function PublicCollectionGallery() { const router = useRouter(); const [isPasswordProtected, setIsPasswordProtected] = useState(false); - const [collectionSummaries, setCollectionSummaries] = - useState(new Map()); useEffect(() => { const currentURL = new URL(window.location.href); @@ -133,7 +133,7 @@ export default function PublicCollectionGallery() { collection?.publicURLs?.[0]?.passwordEnabled; setIsPasswordProtected(isPasswordProtected); setErrorMessage(null); - let files = []; + // remove outdated password, sharer has disabled the password if (!isPasswordProtected && passwordJWTToken.current) { passwordJWTToken.current = null; @@ -144,7 +144,7 @@ export default function PublicCollectionGallery() { (isPasswordProtected && passwordJWTToken.current) ) { try { - files = await syncPublicFiles( + await syncPublicFiles( token.current, passwordJWTToken.current, collection, @@ -162,18 +162,6 @@ export default function PublicCollectionGallery() { if (isPasswordProtected && !passwordJWTToken.current) { await removePublicFiles(collectionUID); } - collectionSummaries.set(collection.id, { - collectionAttributes: { - name: collection.name, - type: collection.type, - id: collection.id, - updationTime: collection.updationTime, - ownerID: collection.owner.id, - }, - latestFile: files[0], - fileCount: files.length, - }); - setCollectionSummaries(collectionSummaries); } catch (e) { const parsedError = parseSharingErrorCodes(e); if ( @@ -293,6 +281,12 @@ export default function PublicCollectionGallery() { openReportForm, }}> + + + { +): CollectionLatestFile => { const latestFile = new Map(); files.forEach((file) => { - if (!latestFile.has(file.collectionID)) { - latestFile.set(file.collectionID, file); + const collectionID = getFileCollectionID(file); + if (!latestFile.has(collectionID)) { + latestFile.set(collectionID, file); } }); - const collectionsAndTheirLatestFile: CollectionAndItsLatestFile[] = []; - - for (const collection of collections) { - collectionsAndTheirLatestFile.push({ - collection, - file: latestFile.get(collection.id), - }); - } - return collectionsAndTheirLatestFile; + return latestFile; }; export const getFavItemIds = async ( @@ -711,6 +704,18 @@ export const getNonEmptyCollections = ( ); }; +export function getFileCollectionID(file: EnteFile) { + let collectionID: number; + if (file.isTrashed) { + collectionID = TRASH_SECTION; + } else if (IsArchived(file)) { + collectionID = ARCHIVE_SECTION; + } else { + collectionID = file.collectionID; + } + return collectionID; +} + export function sortCollectionSummaries( collectionSummaries: CollectionSummary[], sortBy: COLLECTION_SORT_BY @@ -730,13 +735,10 @@ export function sortCollectionSummaries( ); case COLLECTION_SORT_BY.UPDATION_TIME_DESCENDING: return ( - b.collectionAttributes.updationTime - - a.collectionAttributes.updationTime + b.attributes.updationTime - a.attributes.updationTime ); case COLLECTION_SORT_BY.NAME: - return a.collectionAttributes.name.localeCompare( - b.collectionAttributes.name - ); + return a.name.localeCompare(b.name); } }) ); @@ -753,9 +755,9 @@ function compareCollectionsLatestFile(first: EnteFile, second: EnteFile) { function moveFavCollectionToFront(collectionSummaries: CollectionSummary[]) { return collectionSummaries.sort((a, b) => - a.collectionAttributes.type === CollectionType.favorites + a.type === CollectionType.favorites ? -1 - : b.collectionAttributes.type === CollectionType.favorites + : b.type === CollectionType.favorites ? 1 : 0 ); @@ -766,39 +768,35 @@ export function getCollectionSummaries( files: EnteFile[] ): CollectionSummaries { const collectionSummaries: CollectionSummaries = new Map(); - const collectionAndTheirLatestFile = getCollectionsAndTheirLatestFile( - collections, - files - ); - const collectionAndTheirLatestFileMap = new Map(); - for (const collectionAndItsLatestFile of collectionAndTheirLatestFile) { - collectionAndTheirLatestFileMap.set( - collectionAndItsLatestFile.collection.id, - collectionAndItsLatestFile.file - ); - } + const collectionsLatestFile = getCollectionsLatestFile(files); const collectionFilesCount = getCollectionsFileCount(files); for (const collection of collections) { collectionSummaries.set(collection.id, { - collectionAttributes: { - id: collection.id, - name: collection.name, - type: collection.type, + name: collection.name, + type: collection.type, + latestFile: collectionsLatestFile.get(collection.id), + fileCount: collectionFilesCount.get(collection.id) ?? 0, + attributes: { updationTime: collection.updationTime, ownerID: collection.owner.id, + id: collection.id, }, - latestFile: collectionAndTheirLatestFileMap.get(collection.id), - fileCount: collectionFilesCount.get(collection.id) ?? 0, }); } collectionSummaries.set( ARCHIVE_SECTION, - getArchivedCollectionSummaries(collectionFilesCount) + getArchivedCollectionSummaries( + collectionFilesCount, + collectionsLatestFile + ) ); collectionSummaries.set( TRASH_SECTION, - getTrashedCollectionSummaries(collectionFilesCount) + getTrashedCollectionSummaries( + collectionFilesCount, + collectionsLatestFile + ) ); return collectionSummaries; } @@ -813,33 +811,27 @@ function getCollectionsFileCount(files: EnteFile[]): CollectionFilesCount { } function getArchivedCollectionSummaries( - collectionFilesCount: CollectionFilesCount + collectionFilesCount: CollectionFilesCount, + collectionsLatestFile: CollectionLatestFile ) { return { - collectionAttributes: { - id: ARCHIVE_SECTION, - name: constants.ARCHIVE, - type: CollectionType.system, - updationTime: 0, - ownerID: 0, - }, - latestFile: null, + name: constants.ARCHIVE, + type: CollectionType.system, + latestFile: collectionsLatestFile.get(ARCHIVE_SECTION), fileCount: collectionFilesCount.get(ARCHIVE_SECTION) ?? 0, + attributes: { id: TRASH_SECTION }, } as CollectionSummary; } function getTrashedCollectionSummaries( - collectionFilesCount: CollectionFilesCount -) { + collectionFilesCount: CollectionFilesCount, + collectionsLatestFile: CollectionLatestFile +): CollectionSummary { return { - collectionAttributes: { - id: TRASH_SECTION, - name: constants.TRASH, - type: CollectionType.system, - updationTime: 0, - ownerID: 0, - }, - latestFile: null, + name: constants.TRASH, + type: CollectionType.system, + latestFile: collectionsLatestFile.get(TRASH_SECTION), fileCount: collectionFilesCount.get(TRASH_SECTION) ?? 0, + attributes: { id: TRASH_SECTION }, }; } diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 0bc4c9345..4ae91b0b2 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -73,10 +73,7 @@ export interface collectionAttributes { pathDecryptionNonce?: string; } -export interface CollectionAndItsLatestFile { - collection: Collection; - file: EnteFile; -} +export type CollectionLatestFile = Map; export interface RemoveFromCollectionRequest { collectionID: number; @@ -92,16 +89,23 @@ export interface CollectionMagicMetadata data: CollectionMagicMetadataProps; } export interface CollectionSummary { - collectionAttributes: { - id: number; - name: string; - type: CollectionType; - ownerID: number; - updationTime: number; - }; - latestFile: EnteFile; + name: string; + type: CollectionType; + latestFile?: EnteFile; fileCount: number; + attributes?: { + id?: number; + ownerID?: number; + updationTime?: number; + }; } export type CollectionSummaries = Map; export type CollectionFilesCount = Map; + +export interface CollectionInfo { + id: number; + name: string; + fileCount: number; + type: CollectionType; +} diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 1166bfcea..acfe5d6d9 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -25,7 +25,7 @@ import HEICConverter from 'services/heicConverter/heicConverterService'; import ffmpegService from 'services/ffmpeg/ffmpegService'; import { NEW_FILE_MAGIC_METADATA, VISIBILITY_STATE } from 'types/magicMetadata'; import { IsArchived, updateMagicMetadataProps } from 'utils/magicMetadata'; -import { ARCHIVE_SECTION, TRASH_SECTION } from 'constants/collection'; +import { getFileCollectionID } from 'services/collectionService'; export function downloadAsFile(filename: string, content: string) { const file = new Blob([content], { type: 'text/plain', @@ -142,14 +142,7 @@ export function isFileHEIC(mimeType: string) { export function sortFilesIntoCollections(files: EnteFile[]) { const collectionWiseFiles = new Map(); for (const file of files) { - let collectionID: number; - if (file.isTrashed) { - collectionID = TRASH_SECTION; - } else if (IsArchived(file)) { - collectionID = ARCHIVE_SECTION; - } else { - collectionID = file.collectionID; - } + const collectionID = getFileCollectionID(file); if (!collectionWiseFiles.has(collectionID)) { collectionWiseFiles.set(collectionID, []); } From 5274b32e84c13c7bd3ffcd8f60735757e264abbb Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 3 Jun 2022 13:01:10 +0530 Subject: [PATCH 2/6] update collection bar navigation button to scroll button and abstract body padding into seperate component --- ...{NavigationButton.tsx => ScrollButton.tsx} | 10 ++---- .../Collections/CollectionBar/index.tsx | 32 ++++++++++--------- .../Collections/CollectionInfoWithOptions.tsx | 15 ++++++--- .../Collections/styledComponents.ts | 18 +++-------- src/components/Container.ts | 8 +++++ src/components/PhotoList.tsx | 11 +++---- src/hooks/useComponentScroll.tsx | 6 +++- src/pages/shared-albums/index.tsx | 7 ++-- 8 files changed, 55 insertions(+), 52 deletions(-) rename src/components/Collections/CollectionBar/{NavigationButton.tsx => ScrollButton.tsx} (87%) diff --git a/src/components/Collections/CollectionBar/NavigationButton.tsx b/src/components/Collections/CollectionBar/ScrollButton.tsx similarity index 87% rename from src/components/Collections/CollectionBar/NavigationButton.tsx rename to src/components/Collections/CollectionBar/ScrollButton.tsx index effd16a8d..6054f09a0 100644 --- a/src/components/Collections/CollectionBar/NavigationButton.tsx +++ b/src/components/Collections/CollectionBar/ScrollButton.tsx @@ -1,11 +1,7 @@ import React from 'react'; import styled, { css } from 'styled-components'; import NavigateNextIcon from '@mui/icons-material/NavigateNext'; - -export enum SCROLL_DIRECTION { - LEFT = -1, - RIGHT = +1, -} +import { SCROLL_DIRECTION } from 'hooks/useComponentScroll'; const Wrapper = styled.button<{ direction: SCROLL_DIRECTION }>` position: absolute; @@ -43,9 +39,9 @@ const Wrapper = styled.button<{ direction: SCROLL_DIRECTION }>` } `; -const NavigationButton = ({ scrollDirection, ...rest }) => ( +const ScrollButton = ({ scrollDirection, ...rest }) => ( ); -export default NavigationButton; +export default ScrollButton; diff --git a/src/components/Collections/CollectionBar/index.tsx b/src/components/Collections/CollectionBar/index.tsx index 88b1904bf..85134ed9c 100644 --- a/src/components/Collections/CollectionBar/index.tsx +++ b/src/components/Collections/CollectionBar/index.tsx @@ -1,6 +1,4 @@ -import NavigationButton, { - SCROLL_DIRECTION, -} from 'components/Collections/CollectionBar/NavigationButton'; +import ScrollButton from 'components/Collections/CollectionBar/ScrollButton'; import React, { useEffect } from 'react'; import { Collection, CollectionSummaries } from 'types/collection'; import constants from 'utils/strings/constants'; @@ -10,12 +8,13 @@ import { Hider, CollectionBarWrapper, ScrollContainer, - PaddedSpaceBetweenFlex, + CollectionSectionWrapper, } from 'components/Collections/styledComponents'; import CollectionCardWithActiveIndicator from 'components/Collections/CollectionBar/CollectionCardWithActiveIndicator'; -import useComponentScroll from 'hooks/useComponentScroll'; +import useComponentScroll, { SCROLL_DIRECTION } from 'hooks/useComponentScroll'; import useWindowSize from 'hooks/useWindowSize'; import LinkButton from 'components/pages/gallery/LinkButton'; +import { SpaceBetweenFlex } from 'components/Container'; interface IProps { collections: Collection[]; @@ -66,17 +65,20 @@ export default function CollectionBar(props: IProps) { return ( - - {constants.ALBUMS} - {hasScrollBar && ( - - {constants.VIEW_ALL_ALBUMS} - - )} - + + + {constants.ALBUMS} + {hasScrollBar && ( + + {constants.VIEW_ALL_ALBUMS} + + )} + + + {!onFarLeft && ( - @@ -102,7 +104,7 @@ export default function CollectionBar(props: IProps) { ))} {!onFarRight && ( - diff --git a/src/components/Collections/CollectionInfoWithOptions.tsx b/src/components/Collections/CollectionInfoWithOptions.tsx index 0da4c9a93..95c3c82ad 100644 --- a/src/components/Collections/CollectionInfoWithOptions.tsx +++ b/src/components/Collections/CollectionInfoWithOptions.tsx @@ -1,10 +1,11 @@ import { CollectionInfo } from './CollectionInfo'; import React from 'react'; import { Collection, CollectionSummary } from 'types/collection'; -import { PaddedSpaceBetweenFlex } from 'components/Collections/styledComponents'; +import { CollectionSectionWrapper } from 'components/Collections/styledComponents'; import CollectionOptions from 'components/Collections/CollectionOptions'; import { SetCollectionNamerAttributes } from 'components/Collections/CollectionNamer'; import { CollectionType } from 'constants/collection'; +import { SpaceBetweenFlex } from 'components/Container'; interface Iprops { activeCollection: Collection; @@ -24,9 +25,13 @@ export default function collectionInfoWithOptions({ const { name, type, fileCount } = collectionSummary; return ( - - - {type !== CollectionType.system && } - + + + + {type !== CollectionType.system && ( + + )} + + ); } diff --git a/src/components/Collections/styledComponents.ts b/src/components/Collections/styledComponents.ts index 063aab4e4..77e0a1859 100644 --- a/src/components/Collections/styledComponents.ts +++ b/src/components/Collections/styledComponents.ts @@ -1,28 +1,19 @@ -import { SpaceBetweenFlex } from 'components/Container'; -import { IMAGE_CONTAINER_MAX_WIDTH } from 'constants/gallery'; +import { PaddedContainer } from 'components/Container'; import styled from 'styled-components'; -export const CollectionBarWrapper = styled.div` +export const CollectionBarWrapper = styled(PaddedContainer)` display: flex; position: relative; overflow: hidden; height: 86px; width: 100%; margin: 10px auto; - padding: 0 24px; - @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * 4}px) { - padding: 0 4px; - } border-bottom: 1px solid ${({ theme }) => theme.palette.grey.A200}; `; -export const PaddedSpaceBetweenFlex = styled(SpaceBetweenFlex)` +export const CollectionSectionWrapper = styled(PaddedContainer)` margin-bottom: 8px; margin-top: 16px; - padding: 0 24px; - @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * 4}px) { - padding: 0 4px; - } `; export const ScrollContainer = styled.div` @@ -66,8 +57,7 @@ export const ActiveIndicator = styled.div` `; export const Hider = styled.div<{ hide: boolean }>` - opacity: ${(props) => (props.hide ? '0' : '100')}; - height: ${(props) => (props.hide ? '0' : 'auto')}; + display: ${(props) => (props.hide ? 'none' : 'block')}; `; export const AllCollectionTile = styled(CollectionTile)` diff --git a/src/components/Container.ts b/src/components/Container.ts index 813bff177..c6016873e 100644 --- a/src/components/Container.ts +++ b/src/components/Container.ts @@ -1,6 +1,7 @@ import { Box } from '@mui/material'; import styled from 'styled-components'; import { default as MuiStyled } from '@mui/styled-engine'; +import { IMAGE_CONTAINER_MAX_WIDTH } from 'constants/gallery'; const VerticallyCentered = MuiStyled(Box)` flex: 1; @@ -90,3 +91,10 @@ export const InvertedIconButton = styled(IconButton)` background-color: ${({ theme }) => theme.palette.primary.main}; } `; + +export const PaddedContainer = styled(Box)` + padding: 0 24px; + @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * 4}px) { + padding: 0 4px; + } +`; diff --git a/src/components/PhotoList.tsx b/src/components/PhotoList.tsx index 5f8ebec7c..a4dbc1a87 100644 --- a/src/components/PhotoList.tsx +++ b/src/components/PhotoList.tsx @@ -17,6 +17,7 @@ import { ENTE_WEBSITE_LINK } from 'constants/urls'; import { getVariantColor, ButtonVariant } from './pages/gallery/LinkButton'; import { convertBytesToHumanReadable } from 'utils/billing'; import { DeduplicateContext } from 'pages/deduplicate'; +import { PaddedContainer } from './Container'; const A_DAY = 24 * 60 * 60 * 1000; const NO_OF_PAGES = 2; @@ -65,19 +66,17 @@ const getTemplateColumns = (columns: number, groups?: number[]): string => { } }; -const ListContainer = styled.div<{ columns: number; groups?: number[] }>` +const ListContainer = styled(PaddedContainer)<{ + columns: number; + groups?: number[]; +}>` user-select: none; display: grid; grid-template-columns: ${({ columns, groups }) => getTemplateColumns(columns, groups)}; grid-column-gap: ${GAP_BTW_TILES}px; - padding: 0 24px; width: 100%; color: #fff; - - @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * 4}px) { - padding: 0 4px; - } `; const DateContainer = styled.div<{ span: number }>` diff --git a/src/hooks/useComponentScroll.tsx b/src/hooks/useComponentScroll.tsx index 4b7e033f0..def91e5f0 100644 --- a/src/hooks/useComponentScroll.tsx +++ b/src/hooks/useComponentScroll.tsx @@ -1,6 +1,10 @@ -import { SCROLL_DIRECTION } from 'components/Collections/CollectionBar/NavigationButton'; import { useRef, useState, useEffect } from 'react'; +export enum SCROLL_DIRECTION { + LEFT = -1, + RIGHT = +1, +} + export default function useComponentScroll({ dependencies, }: { diff --git a/src/pages/shared-albums/index.tsx b/src/pages/shared-albums/index.tsx index 39eb4bfdd..44fab4e54 100644 --- a/src/pages/shared-albums/index.tsx +++ b/src/pages/shared-albums/index.tsx @@ -34,7 +34,7 @@ import { Card } from 'react-bootstrap'; import { logError } from 'utils/sentry'; import SharedAlbumNavbar from 'components/pages/sharedAlbum/Navbar'; import { CollectionInfo } from 'components/Collections/CollectionInfo'; -import { PaddedSpaceBetweenFlex } from 'components/Collections/styledComponents'; +import { CollectionSectionWrapper } from 'components/Collections/styledComponents'; const Loader = () => ( @@ -281,12 +281,12 @@ export default function PublicCollectionGallery() { openReportForm, }}> - + - + null} isInSearchMode={false} search={{}} - setSearchStats={() => null} deleted={[]} activeCollection={ALL_SECTION} isSharedCollection From ed54ede6d76093f8180306280da3b7a32906ea08 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 3 Jun 2022 13:33:50 +0530 Subject: [PATCH 3/6] fix collection latest file missing --- src/services/collectionService.ts | 45 +++++++++++++------------------ src/types/collection/index.ts | 2 +- src/utils/file/index.ts | 20 +++++++++----- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index 4fc80b292..bfb35f769 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -13,7 +13,7 @@ import { CustomError } from 'utils/error'; import { sortFiles, sortFilesIntoCollections } from 'utils/file'; import { Collection, - CollectionLatestFile, + CollectionLatestFiles, AddToCollectionRequest, MoveToCollectionRequest, EncryptedFileKey, @@ -205,18 +205,23 @@ export const getCollection = async ( } }; -export const getCollectionsLatestFile = ( +export const getCollectionLatestFiles = ( files: EnteFile[] -): CollectionLatestFile => { - const latestFile = new Map(); +): CollectionLatestFiles => { + const latestFiles = new Map(); files.forEach((file) => { - const collectionID = getFileCollectionID(file); - if (!latestFile.has(collectionID)) { - latestFile.set(collectionID, file); + if (!latestFiles.has(file.collectionID)) { + latestFiles.set(file.collectionID, file); + } + if (!latestFiles.has(ARCHIVE_SECTION) && IsArchived(file)) { + latestFiles.set(ARCHIVE_SECTION, file); + } + if (!latestFiles.has(TRASH_SECTION) && file.isTrashed) { + latestFiles.set(TRASH_SECTION, file); } }); - return latestFile; + return latestFiles; }; export const getFavItemIds = async ( @@ -704,18 +709,6 @@ export const getNonEmptyCollections = ( ); }; -export function getFileCollectionID(file: EnteFile) { - let collectionID: number; - if (file.isTrashed) { - collectionID = TRASH_SECTION; - } else if (IsArchived(file)) { - collectionID = ARCHIVE_SECTION; - } else { - collectionID = file.collectionID; - } - return collectionID; -} - export function sortCollectionSummaries( collectionSummaries: CollectionSummary[], sortBy: COLLECTION_SORT_BY @@ -768,14 +761,14 @@ export function getCollectionSummaries( files: EnteFile[] ): CollectionSummaries { const collectionSummaries: CollectionSummaries = new Map(); - const collectionsLatestFile = getCollectionsLatestFile(files); + const collectionLatestFiles = getCollectionLatestFiles(files); const collectionFilesCount = getCollectionsFileCount(files); for (const collection of collections) { collectionSummaries.set(collection.id, { name: collection.name, type: collection.type, - latestFile: collectionsLatestFile.get(collection.id), + latestFile: collectionLatestFiles.get(collection.id), fileCount: collectionFilesCount.get(collection.id) ?? 0, attributes: { updationTime: collection.updationTime, @@ -788,14 +781,14 @@ export function getCollectionSummaries( ARCHIVE_SECTION, getArchivedCollectionSummaries( collectionFilesCount, - collectionsLatestFile + collectionLatestFiles ) ); collectionSummaries.set( TRASH_SECTION, getTrashedCollectionSummaries( collectionFilesCount, - collectionsLatestFile + collectionLatestFiles ) ); return collectionSummaries; @@ -812,7 +805,7 @@ function getCollectionsFileCount(files: EnteFile[]): CollectionFilesCount { function getArchivedCollectionSummaries( collectionFilesCount: CollectionFilesCount, - collectionsLatestFile: CollectionLatestFile + collectionsLatestFile: CollectionLatestFiles ) { return { name: constants.ARCHIVE, @@ -825,7 +818,7 @@ function getArchivedCollectionSummaries( function getTrashedCollectionSummaries( collectionFilesCount: CollectionFilesCount, - collectionsLatestFile: CollectionLatestFile + collectionsLatestFile: CollectionLatestFiles ): CollectionSummary { return { name: constants.TRASH, diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 4ae91b0b2..0bf5c6b67 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -73,7 +73,7 @@ export interface collectionAttributes { pathDecryptionNonce?: string; } -export type CollectionLatestFile = Map; +export type CollectionLatestFiles = Map; export interface RemoveFromCollectionRequest { collectionID: number; diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index acfe5d6d9..5dca0f254 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -25,7 +25,7 @@ import HEICConverter from 'services/heicConverter/heicConverterService'; import ffmpegService from 'services/ffmpeg/ffmpegService'; import { NEW_FILE_MAGIC_METADATA, VISIBILITY_STATE } from 'types/magicMetadata'; import { IsArchived, updateMagicMetadataProps } from 'utils/magicMetadata'; -import { getFileCollectionID } from 'services/collectionService'; +import { ARCHIVE_SECTION, TRASH_SECTION } from 'constants/collection'; export function downloadAsFile(filename: string, content: string) { const file = new Blob([content], { type: 'text/plain', @@ -140,14 +140,22 @@ export function isFileHEIC(mimeType: string) { } export function sortFilesIntoCollections(files: EnteFile[]) { - const collectionWiseFiles = new Map(); + const collectionWiseFiles = new Map([ + [ARCHIVE_SECTION, []], + [TRASH_SECTION, []], + ]); for (const file of files) { - const collectionID = getFileCollectionID(file); - if (!collectionWiseFiles.has(collectionID)) { - collectionWiseFiles.set(collectionID, []); + if (!collectionWiseFiles.has(file.collectionID)) { + collectionWiseFiles.set(file.collectionID, []); } - collectionWiseFiles.get(collectionID).push(file); + collectionWiseFiles.get(file.collectionID).push(file); + if (IsArchived(file)) { + collectionWiseFiles.get(ARCHIVE_SECTION).push(file); + } + if (file.isTrashed) { + collectionWiseFiles.get(TRASH_SECTION).push(file); + } } return collectionWiseFiles; } From 594c9ad5df2e343adf2fd44ef85f2703d2afed15 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 3 Jun 2022 13:42:42 +0530 Subject: [PATCH 4/6] sort collection bar collection summaries --- .../Collections/CollectionBar/index.tsx | 29 ++++++++++++------- .../Collections/CollectionInfoWithOptions.tsx | 7 +++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/Collections/CollectionBar/index.tsx b/src/components/Collections/CollectionBar/index.tsx index 85134ed9c..3dcaefe0e 100644 --- a/src/components/Collections/CollectionBar/index.tsx +++ b/src/components/Collections/CollectionBar/index.tsx @@ -1,8 +1,8 @@ import ScrollButton from 'components/Collections/CollectionBar/ScrollButton'; -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { Collection, CollectionSummaries } from 'types/collection'; import constants from 'utils/strings/constants'; -import { ALL_SECTION } from 'constants/collection'; +import { ALL_SECTION, COLLECTION_SORT_BY } from 'constants/collection'; import { Typography } from '@mui/material'; import { Hider, @@ -15,6 +15,7 @@ import useComponentScroll, { SCROLL_DIRECTION } from 'hooks/useComponentScroll'; import useWindowSize from 'hooks/useWindowSize'; import LinkButton from 'components/pages/gallery/LinkButton'; import { SpaceBetweenFlex } from 'components/Container'; +import { sortCollectionSummaries } from 'services/collectionService'; interface IProps { collections: Collection[]; @@ -34,7 +35,17 @@ export default function CollectionBar(props: IProps) { showAllCollections, } = props; + const sortedCollectionSummary = useMemo( + () => + sortCollectionSummaries( + [...collectionSummaries.values()], + COLLECTION_SORT_BY.UPDATION_TIME_DESCENDING + ), + [collectionSummaries] + ); + const windowSize = useWindowSize(); + const { componentRef, scrollComponent, @@ -90,15 +101,13 @@ export default function CollectionBar(props: IProps) { onClick={clickHandler(ALL_SECTION)}> {constants.ALL_SECTION_NAME} - {collections.map((item) => ( + {sortedCollectionSummary.map((item) => ( + key={item.attributes.id} + latestFile={item.latestFile} + ref={collectionChipsRef[item.attributes.id]} + active={activeCollection === item.attributes.id} + onClick={clickHandler(item.attributes.id)}> {item.name} ))} diff --git a/src/components/Collections/CollectionInfoWithOptions.tsx b/src/components/Collections/CollectionInfoWithOptions.tsx index 95c3c82ad..3b84807e4 100644 --- a/src/components/Collections/CollectionInfoWithOptions.tsx +++ b/src/components/Collections/CollectionInfoWithOptions.tsx @@ -28,9 +28,10 @@ export default function collectionInfoWithOptions({ - {type !== CollectionType.system && ( - - )} + {type !== CollectionType.system && + type !== CollectionType.favorites && ( + + )} ); From 7848f2046623300377d675666a70426a06220e24 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 3 Jun 2022 13:46:00 +0530 Subject: [PATCH 5/6] remove collections props from collection bar --- src/components/Collections/CollectionBar/index.tsx | 13 ++++++------- src/components/Collections/index.tsx | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/Collections/CollectionBar/index.tsx b/src/components/Collections/CollectionBar/index.tsx index 3dcaefe0e..4598cbfdc 100644 --- a/src/components/Collections/CollectionBar/index.tsx +++ b/src/components/Collections/CollectionBar/index.tsx @@ -1,6 +1,6 @@ import ScrollButton from 'components/Collections/CollectionBar/ScrollButton'; import React, { useEffect, useMemo } from 'react'; -import { Collection, CollectionSummaries } from 'types/collection'; +import { CollectionSummaries } from 'types/collection'; import constants from 'utils/strings/constants'; import { ALL_SECTION, COLLECTION_SORT_BY } from 'constants/collection'; import { Typography } from '@mui/material'; @@ -18,7 +18,6 @@ import { SpaceBetweenFlex } from 'components/Container'; import { sortCollectionSummaries } from 'services/collectionService'; interface IProps { - collections: Collection[]; activeCollection?: number; setActiveCollection: (id?: number) => void; isInSearchMode: boolean; @@ -29,7 +28,7 @@ interface IProps { export default function CollectionBar(props: IProps) { const { activeCollection, - collections, + setActiveCollection, collectionSummaries, showAllCollections, @@ -53,12 +52,12 @@ export default function CollectionBar(props: IProps) { onFarLeft, onFarRight, } = useComponentScroll({ - dependencies: [windowSize, collections], + dependencies: [windowSize, collectionSummaries], }); - const collectionChipsRef = props.collections.reduce( - (refMap, collection) => { - refMap[collection.id] = React.createRef(); + const collectionChipsRef = sortedCollectionSummary.reduce( + (refMap, collectionSummary) => { + refMap[collectionSummary.attributes.id] = React.createRef(); return refMap; }, {} diff --git a/src/components/Collections/index.tsx b/src/components/Collections/index.tsx index 6bc57df73..ba181c81a 100644 --- a/src/components/Collections/index.tsx +++ b/src/components/Collections/index.tsx @@ -45,7 +45,6 @@ export default function Collections(props: Iprops) { return ( <> Date: Fri, 3 Jun 2022 14:06:40 +0530 Subject: [PATCH 6/6] move id to root of collectionSummary --- .../Collections/AllCollections/CollectionCard.tsx | 2 +- src/components/Collections/AllCollections/content.tsx | 2 +- src/components/Collections/CollectionBar/index.tsx | 10 +++++----- src/components/pages/gallery/CollectionSelector.tsx | 6 +++--- src/services/collectionService.ts | 6 +++--- src/types/collection/index.ts | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/Collections/AllCollections/CollectionCard.tsx b/src/components/Collections/AllCollections/CollectionCard.tsx index 3cbdfb71a..f2dea1879 100644 --- a/src/components/Collections/AllCollections/CollectionCard.tsx +++ b/src/components/Collections/AllCollections/CollectionCard.tsx @@ -19,7 +19,7 @@ export default function AllCollectionCard({ onCollectionClick(collectionSummary.attributes.id)}> + onClick={() => onCollectionClick(collectionSummary.id)}>
))} diff --git a/src/components/Collections/CollectionBar/index.tsx b/src/components/Collections/CollectionBar/index.tsx index 4598cbfdc..72d2cc53f 100644 --- a/src/components/Collections/CollectionBar/index.tsx +++ b/src/components/Collections/CollectionBar/index.tsx @@ -57,7 +57,7 @@ export default function CollectionBar(props: IProps) { const collectionChipsRef = sortedCollectionSummary.reduce( (refMap, collectionSummary) => { - refMap[collectionSummary.attributes.id] = React.createRef(); + refMap[collectionSummary.id] = React.createRef(); return refMap; }, {} @@ -102,11 +102,11 @@ export default function CollectionBar(props: IProps) { {sortedCollectionSummary.map((item) => ( + ref={collectionChipsRef[item.id]} + active={activeCollection === item.id} + onClick={clickHandler(item.id)}> {item.name} ))} diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index a1029d45c..14d36157f 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -49,8 +49,8 @@ function CollectionSelector({ const personalCollectionsOtherThanFrom = [ ...collectionSummaries.values(), ]?.filter( - ({ type, attributes: collectionAttributes }) => - collectionAttributes.id !== attributes.fromCollection && + ({ type, id, attributes: collectionAttributes }) => + id !== attributes.fromCollection && collectionAttributes.ownerID === user?.id && type !== CollectionType.favorites && type !== CollectionType.system @@ -96,7 +96,7 @@ function CollectionSelector({ collectionTile={CollectionSelectorTile} onCollectionClick={handleCollectionClick} collectionSummary={collectionSummary} - key={collectionSummary.attributes.id} + key={collectionSummary.id} /> ))} diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index bfb35f769..c7aa4d9a4 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -766,6 +766,7 @@ export function getCollectionSummaries( for (const collection of collections) { collectionSummaries.set(collection.id, { + id: collection.id, name: collection.name, type: collection.type, latestFile: collectionLatestFiles.get(collection.id), @@ -773,7 +774,6 @@ export function getCollectionSummaries( attributes: { updationTime: collection.updationTime, ownerID: collection.owner.id, - id: collection.id, }, }); } @@ -808,11 +808,11 @@ function getArchivedCollectionSummaries( collectionsLatestFile: CollectionLatestFiles ) { return { + id: TRASH_SECTION, name: constants.ARCHIVE, type: CollectionType.system, latestFile: collectionsLatestFile.get(ARCHIVE_SECTION), fileCount: collectionFilesCount.get(ARCHIVE_SECTION) ?? 0, - attributes: { id: TRASH_SECTION }, } as CollectionSummary; } @@ -821,10 +821,10 @@ function getTrashedCollectionSummaries( collectionsLatestFile: CollectionLatestFiles ): CollectionSummary { return { + id: TRASH_SECTION, name: constants.TRASH, type: CollectionType.system, latestFile: collectionsLatestFile.get(TRASH_SECTION), fileCount: collectionFilesCount.get(TRASH_SECTION) ?? 0, - attributes: { id: TRASH_SECTION }, }; } diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 0bf5c6b67..478991af8 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -89,12 +89,12 @@ export interface CollectionMagicMetadata data: CollectionMagicMetadataProps; } export interface CollectionSummary { + id: number; name: string; type: CollectionType; latestFile?: EnteFile; fileCount: number; attributes?: { - id?: number; ownerID?: number; updationTime?: number; };