commit
20efc76a8d
|
@ -57,6 +57,7 @@ export const Value = styled.div<{ width?: string }>`
|
|||
`;
|
||||
|
||||
export const FlexWrapper = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
|
|
20
src/components/icons/SortIcon.tsx
Normal file
20
src/components/icons/SortIcon.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function SortIcon(props) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={props.height}
|
||||
viewBox={props.viewBox}
|
||||
width={props.width}>
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
SortIcon.defaultProps = {
|
||||
height: 24,
|
||||
width: 24,
|
||||
viewBox: '0 0 24 24',
|
||||
};
|
20
src/components/icons/TickIcon.tsx
Normal file
20
src/components/icons/TickIcon.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function TickIcon(props) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={props.height}
|
||||
viewBox={props.viewBox}
|
||||
width={props.width}
|
||||
fill="currentColor">
|
||||
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
TickIcon.defaultProps = {
|
||||
height: 28,
|
||||
width: 20,
|
||||
viewBox: '0 0 24 24',
|
||||
};
|
|
@ -9,7 +9,7 @@ import {
|
|||
import { getSelectedCollection } from 'utils/collection';
|
||||
import constants from 'utils/strings/constants';
|
||||
import { SetCollectionNamerAttributes } from './CollectionNamer';
|
||||
import LinkButton from './LinkButton';
|
||||
import LinkButton, { ButtonVariant, LinkButtonProps } from './LinkButton';
|
||||
|
||||
interface Props {
|
||||
syncWithRemote: () => Promise<void>;
|
||||
|
@ -21,6 +21,28 @@ interface Props {
|
|||
showCollectionShareModal: () => void;
|
||||
redirectToAll: () => void;
|
||||
}
|
||||
|
||||
export const MenuLink = ({ children, ...props }: LinkButtonProps) => (
|
||||
<LinkButton
|
||||
style={{ fontSize: '14px', fontWeight: 700, padding: '8px 1em' }}
|
||||
{...props}>
|
||||
{children}
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
export const MenuItem = (props: { children: any }) => (
|
||||
<ListGroup.Item
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: '#282828',
|
||||
padding: 0,
|
||||
}}>
|
||||
{props.children}
|
||||
</ListGroup.Item>
|
||||
);
|
||||
|
||||
const CollectionOptions = (props: Props) => {
|
||||
const collectionRename = async (
|
||||
selectedCollection: Collection,
|
||||
|
@ -75,23 +97,6 @@ const CollectionOptions = (props: Props) => {
|
|||
});
|
||||
};
|
||||
|
||||
const MenuLink = (props) => (
|
||||
<LinkButton
|
||||
style={{ fontSize: '14px', fontWeight: 700, padding: '8px 1em' }}
|
||||
{...props}>
|
||||
{props.children}
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
const MenuItem = (props) => (
|
||||
<ListGroup.Item
|
||||
style={{
|
||||
background: '#282828',
|
||||
padding: 0,
|
||||
}}>
|
||||
{props.children}
|
||||
</ListGroup.Item>
|
||||
);
|
||||
return (
|
||||
<Popover id="collection-options" style={{ borderRadius: '10px' }}>
|
||||
<Popover.Content style={{ padding: 0, border: 'none' }}>
|
||||
|
@ -108,7 +113,7 @@ const CollectionOptions = (props: Props) => {
|
|||
</MenuItem>
|
||||
<MenuItem>
|
||||
<MenuLink
|
||||
variant="danger"
|
||||
variant={ButtonVariant.danger}
|
||||
onClick={confirmDeleteCollection}>
|
||||
{constants.DELETE}
|
||||
</MenuLink>
|
||||
|
|
|
@ -7,6 +7,8 @@ import {
|
|||
} from 'services/collectionService';
|
||||
import AddCollectionButton from './AddCollectionButton';
|
||||
import PreviewCard from './PreviewCard';
|
||||
import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
||||
import { User } from 'services/userService';
|
||||
|
||||
export const CollectionIcon = styled.div`
|
||||
width: 200px;
|
||||
|
@ -53,14 +55,18 @@ function CollectionSelector({
|
|||
if (!attributes) {
|
||||
return;
|
||||
}
|
||||
const collectionsOtherThanFrom = collectionsAndTheirLatestFile?.filter(
|
||||
(item) => !(item.collection.id === attributes.fromCollection)
|
||||
);
|
||||
if (collectionsOtherThanFrom.length === 0) {
|
||||
const user: User = getData(LS_KEYS.USER);
|
||||
const personalCollectionsOtherThanFrom =
|
||||
collectionsAndTheirLatestFile?.filter(
|
||||
(item) =>
|
||||
item.collection.id !== attributes.fromCollection &&
|
||||
item.collection.owner.id === user?.id
|
||||
);
|
||||
if (personalCollectionsOtherThanFrom.length === 0) {
|
||||
props.onHide();
|
||||
attributes.showNextModal();
|
||||
} else {
|
||||
setCollectionToShow(collectionsOtherThanFrom);
|
||||
setCollectionToShow(personalCollectionsOtherThanFrom);
|
||||
}
|
||||
}, [props.show]);
|
||||
|
||||
|
|
31
src/components/pages/gallery/CollectionSort.tsx
Normal file
31
src/components/pages/gallery/CollectionSort.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { IconButton } from 'components/Container';
|
||||
import SortIcon from 'components/icons/SortIcon';
|
||||
import React from 'react';
|
||||
import { OverlayTrigger } from 'react-bootstrap';
|
||||
import { COLLECTION_SORT_BY } from 'services/collectionService';
|
||||
import constants from 'utils/strings/constants';
|
||||
import CollectionSortOptions from './CollectionSortOptions';
|
||||
import { IconWithMessage } from './SelectedFileOptions';
|
||||
|
||||
interface Props {
|
||||
setCollectionSortBy: (sortBy: COLLECTION_SORT_BY) => void;
|
||||
activeSortBy: COLLECTION_SORT_BY;
|
||||
}
|
||||
export default function CollectionSort(props: Props) {
|
||||
const collectionSortOptions = CollectionSortOptions(props);
|
||||
return (
|
||||
<OverlayTrigger
|
||||
rootClose
|
||||
trigger="click"
|
||||
placement="bottom"
|
||||
overlay={collectionSortOptions}>
|
||||
<div>
|
||||
<IconWithMessage message={constants.SORT}>
|
||||
<IconButton style={{ color: '#fff' }}>
|
||||
<SortIcon />
|
||||
</IconButton>
|
||||
</IconWithMessage>
|
||||
</div>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
}
|
69
src/components/pages/gallery/CollectionSortOptions.tsx
Normal file
69
src/components/pages/gallery/CollectionSortOptions.tsx
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { Label, Value } from 'components/Container';
|
||||
import TickIcon from 'components/icons/TickIcon';
|
||||
import React from 'react';
|
||||
import { ListGroup, Popover, Row } from 'react-bootstrap';
|
||||
import { COLLECTION_SORT_BY } from 'services/collectionService';
|
||||
import styled from 'styled-components';
|
||||
import constants from 'utils/strings/constants';
|
||||
import { MenuItem, MenuLink } from './CollectionOptions';
|
||||
|
||||
interface OptionProps {
|
||||
activeSortBy: COLLECTION_SORT_BY;
|
||||
setCollectionSortBy: (sortBy: COLLECTION_SORT_BY) => void;
|
||||
}
|
||||
|
||||
const TickWrapper = styled.span`
|
||||
color: #aaa;
|
||||
margin-left: 5px;
|
||||
`;
|
||||
|
||||
const SortByOptionCreator =
|
||||
({ setCollectionSortBy, activeSortBy }: OptionProps) =>
|
||||
(props: { sortBy: COLLECTION_SORT_BY; children: any }) =>
|
||||
(
|
||||
<MenuItem>
|
||||
<Row>
|
||||
<Label width="20px">
|
||||
{activeSortBy === props.sortBy && (
|
||||
<TickWrapper>
|
||||
<TickIcon />
|
||||
</TickWrapper>
|
||||
)}
|
||||
</Label>
|
||||
<Value width="165px">
|
||||
<MenuLink
|
||||
onClick={() => setCollectionSortBy(props.sortBy)}
|
||||
variant={
|
||||
activeSortBy === props.sortBy && 'success'
|
||||
}>
|
||||
{props.children}
|
||||
</MenuLink>
|
||||
</Value>
|
||||
</Row>
|
||||
</MenuItem>
|
||||
);
|
||||
|
||||
const CollectionSortOptions = (props: OptionProps) => {
|
||||
const SortByOption = SortByOptionCreator(props);
|
||||
|
||||
return (
|
||||
<Popover id="collection-sort-options" style={{ borderRadius: '10px' }}>
|
||||
<Popover.Content
|
||||
style={{ padding: 0, border: 'none', width: '185px' }}>
|
||||
<ListGroup style={{ borderRadius: '8px' }}>
|
||||
<SortByOption sortBy={COLLECTION_SORT_BY.LATEST_FILE}>
|
||||
{constants.SORT_BY_LATEST_PHOTO}
|
||||
</SortByOption>
|
||||
<SortByOption sortBy={COLLECTION_SORT_BY.MODIFICATION_TIME}>
|
||||
{constants.SORT_BY_MODIFICATION_TIME}
|
||||
</SortByOption>
|
||||
<SortByOption sortBy={COLLECTION_SORT_BY.NAME}>
|
||||
{constants.SORT_BY_COLLECTION_NAME}
|
||||
</SortByOption>
|
||||
</ListGroup>
|
||||
</Popover.Content>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollectionSortOptions;
|
|
@ -5,7 +5,13 @@ import NavigationButton, {
|
|||
} from 'components/NavigationButton';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
|
||||
import { Collection, CollectionType } from 'services/collectionService';
|
||||
import {
|
||||
Collection,
|
||||
CollectionAndItsLatestFile,
|
||||
CollectionType,
|
||||
COLLECTION_SORT_BY,
|
||||
sortCollections,
|
||||
} from 'services/collectionService';
|
||||
import { User } from 'services/userService';
|
||||
import styled from 'styled-components';
|
||||
import { IMAGE_CONTAINER_MAX_WIDTH } from 'types';
|
||||
|
@ -14,6 +20,7 @@ import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
|||
import constants from 'utils/strings/constants';
|
||||
import { SetCollectionNamerAttributes } from './CollectionNamer';
|
||||
import CollectionOptions from './CollectionOptions';
|
||||
import CollectionSort from './CollectionSort';
|
||||
import OptionIcon, { OptionIconWrapper } from './OptionIcon';
|
||||
|
||||
export const ARCHIVE_SECTION = -1;
|
||||
|
@ -21,6 +28,7 @@ export const ALL_SECTION = 0;
|
|||
|
||||
interface CollectionProps {
|
||||
collections: Collection[];
|
||||
collectionAndTheirLatestFile: CollectionAndItsLatestFile[];
|
||||
activeCollection?: number;
|
||||
setActiveCollection: (id?: number) => void;
|
||||
setDialogMessage: SetDialogMessage;
|
||||
|
@ -31,12 +39,11 @@ interface CollectionProps {
|
|||
collectionFilesCount: Map<number, number>;
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
margin: 10px auto;
|
||||
const CollectionContainer = styled.div`
|
||||
overflow-y: hidden;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
width: calc(100% - 80px);
|
||||
position: relative;
|
||||
padding: 0 24px;
|
||||
|
||||
|
@ -54,6 +61,14 @@ const Wrapper = styled.div`
|
|||
scroll-behavior: smooth;
|
||||
`;
|
||||
|
||||
const CollectionBar = styled.div`
|
||||
width: 100%;
|
||||
margin: 10px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
`;
|
||||
|
||||
const Chip = styled.button<{ active: boolean }>`
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
|
@ -84,6 +99,8 @@ export default function Collections(props: CollectionProps) {
|
|||
scrollWidth?: number;
|
||||
clientWidth?: number;
|
||||
}>({});
|
||||
const [collectionSortBy, setCollectionSortBy] =
|
||||
useState<COLLECTION_SORT_BY>(COLLECTION_SORT_BY.MODIFICATION_TIME);
|
||||
|
||||
const updateScrollObj = () => {
|
||||
if (collectionRef.current) {
|
||||
|
@ -165,81 +182,96 @@ export default function Collections(props: CollectionProps) {
|
|||
)}
|
||||
syncWithRemote={props.syncWithRemote}
|
||||
/>
|
||||
<Container>
|
||||
{scrollObj.scrollLeft > 0 && (
|
||||
<NavigationButton
|
||||
scrollDirection={SCROLL_DIRECTION.LEFT}
|
||||
onClick={scrollCollection(SCROLL_DIRECTION.LEFT)}
|
||||
/>
|
||||
)}
|
||||
<Wrapper ref={collectionRef} onScroll={updateScrollObj}>
|
||||
<Chip
|
||||
active={activeCollection === ALL_SECTION}
|
||||
onClick={clickHandler(ALL_SECTION)}>
|
||||
{constants.ALL}
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
<CollectionBar>
|
||||
<CollectionContainer>
|
||||
{scrollObj.scrollLeft > 0 && (
|
||||
<NavigationButton
|
||||
scrollDirection={SCROLL_DIRECTION.LEFT}
|
||||
onClick={scrollCollection(
|
||||
SCROLL_DIRECTION.LEFT
|
||||
)}
|
||||
/>
|
||||
</Chip>
|
||||
{collections?.map((item) => (
|
||||
<OverlayTrigger
|
||||
key={item.id}
|
||||
placement="top"
|
||||
delay={{ show: 250, hide: 400 }}
|
||||
overlay={renderTooltip(item.id)}>
|
||||
<Chip
|
||||
active={activeCollection === item.id}
|
||||
onClick={clickHandler(item.id)}>
|
||||
{item.name}
|
||||
{item.type !== CollectionType.favorites &&
|
||||
item.owner.id === user?.id ? (
|
||||
<OverlayTrigger
|
||||
rootClose
|
||||
trigger="click"
|
||||
placement="bottom"
|
||||
overlay={collectionOptions}>
|
||||
<OptionIcon
|
||||
onClick={() =>
|
||||
setSelectedCollectionID(
|
||||
item.id
|
||||
)
|
||||
}
|
||||
)}
|
||||
<Wrapper ref={collectionRef} onScroll={updateScrollObj}>
|
||||
<Chip
|
||||
active={activeCollection === ALL_SECTION}
|
||||
onClick={clickHandler(ALL_SECTION)}>
|
||||
{constants.ALL}
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
/>
|
||||
</Chip>
|
||||
{sortCollections(
|
||||
collections,
|
||||
props.collectionAndTheirLatestFile,
|
||||
collectionSortBy
|
||||
).map((item) => (
|
||||
<OverlayTrigger
|
||||
key={item.id}
|
||||
placement="top"
|
||||
delay={{ show: 250, hide: 400 }}
|
||||
overlay={renderTooltip(item.id)}>
|
||||
<Chip
|
||||
active={activeCollection === item.id}
|
||||
onClick={clickHandler(item.id)}>
|
||||
{item.name}
|
||||
{item.type !==
|
||||
CollectionType.favorites &&
|
||||
item.owner.id === user?.id ? (
|
||||
<OverlayTrigger
|
||||
rootClose
|
||||
trigger="click"
|
||||
placement="bottom"
|
||||
overlay={collectionOptions}>
|
||||
<OptionIcon
|
||||
onClick={() =>
|
||||
setSelectedCollectionID(
|
||||
item.id
|
||||
)
|
||||
}
|
||||
/>
|
||||
</OverlayTrigger>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
/>
|
||||
</OverlayTrigger>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Chip>
|
||||
</OverlayTrigger>
|
||||
))}
|
||||
<Chip
|
||||
active={activeCollection === ARCHIVE_SECTION}
|
||||
onClick={clickHandler(ARCHIVE_SECTION)}>
|
||||
{constants.ARCHIVE}
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
)}
|
||||
</Chip>
|
||||
</OverlayTrigger>
|
||||
))}
|
||||
<Chip
|
||||
active={activeCollection === ARCHIVE_SECTION}
|
||||
onClick={clickHandler(ARCHIVE_SECTION)}>
|
||||
{constants.ARCHIVE}
|
||||
<div
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '24px',
|
||||
}}
|
||||
/>
|
||||
</Chip>
|
||||
</Wrapper>
|
||||
{scrollObj.scrollLeft <
|
||||
scrollObj.scrollWidth - scrollObj.clientWidth && (
|
||||
<NavigationButton
|
||||
scrollDirection={SCROLL_DIRECTION.RIGHT}
|
||||
onClick={scrollCollection(
|
||||
SCROLL_DIRECTION.RIGHT
|
||||
)}
|
||||
/>
|
||||
</Chip>
|
||||
</Wrapper>
|
||||
{scrollObj.scrollLeft <
|
||||
scrollObj.scrollWidth - scrollObj.clientWidth && (
|
||||
<NavigationButton
|
||||
scrollDirection={SCROLL_DIRECTION.RIGHT}
|
||||
onClick={scrollCollection(SCROLL_DIRECTION.RIGHT)}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
)}
|
||||
</CollectionContainer>
|
||||
<CollectionSort
|
||||
setCollectionSortBy={setCollectionSortBy}
|
||||
activeSortBy={collectionSortBy}
|
||||
/>
|
||||
</CollectionBar>
|
||||
</>
|
||||
)
|
||||
);
|
||||
|
|
|
@ -6,10 +6,10 @@ export enum ButtonVariant {
|
|||
secondary = 'secondary',
|
||||
warning = 'warning',
|
||||
}
|
||||
type Props = React.PropsWithChildren<{
|
||||
onClick: any;
|
||||
export type LinkButtonProps = React.PropsWithChildren<{
|
||||
onClick: () => void;
|
||||
variant?: string;
|
||||
style?: any;
|
||||
style?: React.CSSProperties;
|
||||
}>;
|
||||
|
||||
export function getVariantColor(variant: string) {
|
||||
|
@ -26,7 +26,7 @@ export function getVariantColor(variant: string) {
|
|||
return '#d1d1d1';
|
||||
}
|
||||
}
|
||||
export default function LinkButton(props: Props) {
|
||||
export default function LinkButton(props: LinkButtonProps) {
|
||||
return (
|
||||
<h5
|
||||
style={{
|
||||
|
|
|
@ -51,6 +51,14 @@ const SelectionContainer = styled.div`
|
|||
display: flex;
|
||||
`;
|
||||
|
||||
export const IconWithMessage = (props) => (
|
||||
<OverlayTrigger
|
||||
placement="bottom"
|
||||
overlay={<p style={{ zIndex: 1002 }}>{props.message}</p>}>
|
||||
{props.children}
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
||||
const SelectedFileOptions = ({
|
||||
addToCollectionHelper,
|
||||
moveToCollectionHelper,
|
||||
|
@ -94,14 +102,6 @@ const SelectedFileOptions = ({
|
|||
});
|
||||
};
|
||||
|
||||
const IconWithMessage = (props) => (
|
||||
<OverlayTrigger
|
||||
placement="bottom"
|
||||
overlay={<p style={{ zIndex: 1002 }}>{props.message}</p>}>
|
||||
{props.children}
|
||||
</OverlayTrigger>
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectionBar>
|
||||
<SelectionContainer>
|
||||
|
|
|
@ -526,6 +526,7 @@ export default function Gallery() {
|
|||
/>
|
||||
<Collections
|
||||
collections={collections}
|
||||
collectionAndTheirLatestFile={collectionsAndTheirLatestFile}
|
||||
searchMode={searchMode}
|
||||
activeCollection={activeCollection}
|
||||
setActiveCollection={setActiveCollection}
|
||||
|
|
|
@ -69,6 +69,12 @@ export interface CollectionAndItsLatestFile {
|
|||
file: File;
|
||||
}
|
||||
|
||||
export enum COLLECTION_SORT_BY {
|
||||
LATEST_FILE,
|
||||
MODIFICATION_TIME,
|
||||
NAME,
|
||||
}
|
||||
|
||||
const getCollectionWithSecrets = async (
|
||||
collection: Collection,
|
||||
masterKey: string
|
||||
|
@ -219,13 +225,9 @@ export const getCollectionsAndTheirLatestFile = (
|
|||
}
|
||||
});
|
||||
const collectionsAndTheirLatestFile: CollectionAndItsLatestFile[] = [];
|
||||
const userID = getData(LS_KEYS.USER)?.id;
|
||||
|
||||
for (const collection of collections) {
|
||||
if (
|
||||
collection.owner.id !== userID ||
|
||||
collection.type === CollectionType.favorites
|
||||
) {
|
||||
if (collection.type === CollectionType.favorites) {
|
||||
continue;
|
||||
}
|
||||
collectionsAndTheirLatestFile.push({
|
||||
|
@ -591,3 +593,62 @@ export const getNonEmptyCollections = (
|
|||
nonEmptyCollectionsIds.has(collection.id)
|
||||
);
|
||||
};
|
||||
|
||||
export function sortCollections(
|
||||
collections: Collection[],
|
||||
collectionAndTheirLatestFile: CollectionAndItsLatestFile[],
|
||||
sortBy: COLLECTION_SORT_BY
|
||||
) {
|
||||
return collections.sort((collectionA, collectionB) => {
|
||||
switch (sortBy) {
|
||||
case COLLECTION_SORT_BY.LATEST_FILE:
|
||||
return compareCollectionsLatestFile(
|
||||
collectionAndTheirLatestFile,
|
||||
collectionA,
|
||||
collectionB
|
||||
);
|
||||
case COLLECTION_SORT_BY.MODIFICATION_TIME:
|
||||
return collectionB.updationTime - collectionA.updationTime;
|
||||
case COLLECTION_SORT_BY.NAME:
|
||||
return collectionA.name.localeCompare(collectionB.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function compareCollectionsLatestFile(
|
||||
collectionAndTheirLatestFile: CollectionAndItsLatestFile[],
|
||||
collectionA: Collection,
|
||||
collectionB: Collection
|
||||
) {
|
||||
const CollectionALatestFile = getCollectionLatestFile(
|
||||
collectionAndTheirLatestFile,
|
||||
collectionA
|
||||
);
|
||||
const CollectionBLatestFile = getCollectionLatestFile(
|
||||
collectionAndTheirLatestFile,
|
||||
collectionB
|
||||
);
|
||||
|
||||
return (
|
||||
CollectionBLatestFile.updationTime - CollectionALatestFile.updationTime
|
||||
);
|
||||
}
|
||||
|
||||
function getCollectionLatestFile(
|
||||
collectionAndTheirLatestFile: CollectionAndItsLatestFile[],
|
||||
collection: Collection
|
||||
) {
|
||||
const collectionAndItsLatestFile = collectionAndTheirLatestFile.filter(
|
||||
(collectionAndItsLatestFile) =>
|
||||
collectionAndItsLatestFile.collection.id === collection.id
|
||||
);
|
||||
if (collectionAndItsLatestFile.length === 1) {
|
||||
return collectionAndItsLatestFile[0].file;
|
||||
} else {
|
||||
logError(
|
||||
Error('collection missing from collectionLatestFile list'),
|
||||
''
|
||||
);
|
||||
return { updationTime: 0 };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -548,6 +548,10 @@ const englishConstants = {
|
|||
UNARCHIVE: 'un-archive',
|
||||
MOVE: 'move',
|
||||
ADD: 'add',
|
||||
SORT: 'sort',
|
||||
SORT_BY_LATEST_PHOTO: 'most recent photo',
|
||||
SORT_BY_MODIFICATION_TIME: 'last modified',
|
||||
SORT_BY_COLLECTION_NAME: 'album title',
|
||||
};
|
||||
|
||||
export default englishConstants;
|
||||
|
|
Loading…
Reference in a new issue