Merge branch 'main' into ShareAlbum-Redesign
This commit is contained in:
commit
182fe73cf3
2
.github/workflows/l18n-crowdin.yml
vendored
2
.github/workflows/l18n-crowdin.yml
vendored
|
@ -16,6 +16,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- name: crowdin action
|
||||
uses: crowdin/github-action@v1
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
"@stripe/stripe-js": "^1.13.2",
|
||||
"@tensorflow-models/coco-ssd": "^2.2.2",
|
||||
"@tensorflow/tfjs-backend-cpu": "^3.13.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^3.11.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^4.8.0",
|
||||
"@tensorflow/tfjs-converter": "^3.11.0",
|
||||
"@tensorflow/tfjs-core": "^3.11.0",
|
||||
"@tensorflow/tfjs-tflite": "^0.0.1-alpha.7",
|
||||
"@zip.js/zip.js": "^2.4.2",
|
||||
"axios": "^0.21.3",
|
||||
"bip39": "^3.0.4",
|
||||
"blazeface-back": "^0.0.8",
|
||||
"blazeface-back": "^0.0.9",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bs58": "^4.0.1",
|
||||
"chrono-node": "^2.2.6",
|
||||
|
@ -47,7 +47,6 @@
|
|||
"get-user-locale": "^2.1.3",
|
||||
"hdbscan": "0.0.1-alpha.5",
|
||||
"heic-convert": "^1.2.4",
|
||||
"http-proxy-middleware": "^1.0.5",
|
||||
"i18next": "^22.4.11",
|
||||
"i18next-http-backend": "^2.1.1",
|
||||
"idb": "^7.0.0",
|
||||
|
@ -58,7 +57,7 @@
|
|||
"libsodium-wrappers": "^0.7.8",
|
||||
"localforage": "^1.9.0",
|
||||
"memoize-one": "^6.0.0",
|
||||
"ml-matrix": "^6.8.2",
|
||||
"ml-matrix": "^6.10.4",
|
||||
"next": "^13.1.2",
|
||||
"next-transpile-modules": "^10.0.0",
|
||||
"otpauth": "^9.0.2",
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -563,5 +563,7 @@
|
|||
"NEWEST_FIRST": "Newest first",
|
||||
"OLDEST_FIRST": "Oldest first",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "This file could not be previewed. Click here to download the original.",
|
||||
"SELECT_COLLECTION":"Select album"
|
||||
"SELECT_COLLECTION":"Select album",
|
||||
"PIN_ALBUM":"Pin album",
|
||||
"UNPIN_ALBUM":"Unpin album"
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "Detalles",
|
||||
"VIEW_EXIF": "Ver todos los datos de EXIF",
|
||||
"NO_EXIF": "No hay datos EXIF",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "Détails",
|
||||
"VIEW_EXIF": "Visualiser toutes les données EXIF",
|
||||
"NO_EXIF": "Aucune donnée EXIF",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "Details",
|
||||
"VIEW_EXIF": "Bekijk alle EXIF gegevens",
|
||||
"NO_EXIF": "Geen EXIF gegevens",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "Nieuwste eerst",
|
||||
"OLDEST_FIRST": "Oudste eerst",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "Dit bestand kan niet worden bekeken in de app, klik hier om het origineel te downloaden",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "",
|
||||
"VIEW_EXIF": "",
|
||||
"NO_EXIF": "",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -235,12 +235,11 @@
|
|||
"MAP": "",
|
||||
"MAP_SETTINGS": "",
|
||||
"ENABLE_MAPS": "",
|
||||
"ENABLE_MAP": "",
|
||||
"DISABLE_MAPS": "",
|
||||
"ENABLE_MAP_DESCRIPTION_1": "",
|
||||
"ENABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION_3": "",
|
||||
"DISABLE_MAP_DESCRIPTION_1": "",
|
||||
"DISABLE_MAP_DESCRIPTION_2": "",
|
||||
"ENABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP_DESCRIPTION": "",
|
||||
"DISABLE_MAP": "",
|
||||
"DETAILS": "详情",
|
||||
"VIEW_EXIF": "查看所有 EXIF 数据",
|
||||
"NO_EXIF": "无 EXIF 数据",
|
||||
|
@ -538,5 +537,7 @@
|
|||
"NEWEST_FIRST": "",
|
||||
"OLDEST_FIRST": "",
|
||||
"CONVERSION_FAILED_NOTIFICATION_MESSAGE": "",
|
||||
"SELECT_COLLECTION": ""
|
||||
"SELECT_COLLECTION": "",
|
||||
"PIN_ALBUM": "",
|
||||
"UNPIN_ALBUM": ""
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export default function AllCollectionCard({
|
|||
return (
|
||||
<CollectionCard
|
||||
collectionTile={AllCollectionTile}
|
||||
latestFile={collectionSummary.latestFile}
|
||||
coverFile={collectionSummary.coverFile}
|
||||
onClick={() => onCollectionClick(collectionSummary.id)}
|
||||
isScrolling={isScrolling}>
|
||||
<AllCollectionTileText>
|
||||
|
|
|
@ -8,13 +8,13 @@ import { LoadingThumbnail } from 'components/PlaceholderThumbnails';
|
|||
|
||||
export default function CollectionCard(props: {
|
||||
children?: any;
|
||||
latestFile: EnteFile;
|
||||
coverFile: EnteFile;
|
||||
onClick: () => void;
|
||||
collectionTile: any;
|
||||
isScrolling?: boolean;
|
||||
}) {
|
||||
const {
|
||||
latestFile: file,
|
||||
coverFile: file,
|
||||
onClick,
|
||||
children,
|
||||
collectionTile: CustomCollectionTile,
|
||||
|
|
|
@ -14,6 +14,7 @@ import ArchiveIcon from '@mui/icons-material/Archive';
|
|||
import PeopleIcon from '@mui/icons-material/People';
|
||||
import LinkIcon from '@mui/icons-material/Link';
|
||||
import { CollectionSummary } from 'types/collection';
|
||||
import PushPin from '@mui/icons-material/PushPin';
|
||||
|
||||
interface Iprops {
|
||||
collectionSummary: CollectionSummary;
|
||||
|
@ -29,7 +30,7 @@ const CollectionListBarCard = (props: Iprops) => {
|
|||
<Box>
|
||||
<CollectionCard
|
||||
collectionTile={CollectionBarTile}
|
||||
latestFile={collectionSummary.latestFile}
|
||||
coverFile={collectionSummary.coverFile}
|
||||
onClick={() => {
|
||||
onCollectionClick(collectionSummary.id);
|
||||
}}>
|
||||
|
@ -71,6 +72,7 @@ function CollectionCardIcon({ collectionType }) {
|
|||
{collectionType === CollectionSummaryType.sharedOnlyViaLink && (
|
||||
<LinkIcon />
|
||||
)}
|
||||
{collectionType === CollectionSummaryType.pinned && <PushPin />}
|
||||
</CollectionBarTileIcon>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ const CollectionCardContainer = React.memo(
|
|||
);
|
||||
|
||||
const getItemKey = (index: number, data: ItemData) => {
|
||||
return `${data.collectionSummaries[index].id}-${data.collectionSummaries[index].latestFile?.id}`;
|
||||
return `${data.collectionSummaries[index].id}-${data.collectionSummaries[index].coverFile?.id}`;
|
||||
};
|
||||
|
||||
const CollectionListBar = (props: IProps) => {
|
||||
|
|
|
@ -9,9 +9,12 @@ import Unarchive from '@mui/icons-material/Unarchive';
|
|||
import ArchiveOutlined from '@mui/icons-material/ArchiveOutlined';
|
||||
import SortIcon from '@mui/icons-material/Sort';
|
||||
import { t } from 'i18next';
|
||||
import PushPinOutlined from '@mui/icons-material/PushPinOutlined';
|
||||
import { UnPinIcon } from 'components/icons/UnPinIcon';
|
||||
|
||||
interface Iprops {
|
||||
IsArchived: boolean;
|
||||
isArchived: boolean;
|
||||
isPinned: boolean;
|
||||
handleCollectionAction: (
|
||||
action: CollectionActions,
|
||||
loader?: boolean
|
||||
|
@ -19,7 +22,8 @@ interface Iprops {
|
|||
}
|
||||
|
||||
export function AlbumCollectionOption({
|
||||
IsArchived,
|
||||
isArchived,
|
||||
isPinned,
|
||||
handleCollectionAction,
|
||||
}: Iprops) {
|
||||
return (
|
||||
|
@ -40,7 +44,26 @@ export function AlbumCollectionOption({
|
|||
startIcon={<SortIcon />}>
|
||||
{t('SORT_BY')}
|
||||
</OverflowMenuOption>
|
||||
{IsArchived ? (
|
||||
{isPinned ? (
|
||||
<OverflowMenuOption
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.UNPIN_ALBUM,
|
||||
false
|
||||
)}
|
||||
startIcon={<UnPinIcon />}>
|
||||
{t('UNPIN_ALBUM')}
|
||||
</OverflowMenuOption>
|
||||
) : (
|
||||
<OverflowMenuOption
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.PIN_ALBUM,
|
||||
false
|
||||
)}
|
||||
startIcon={<PushPinOutlined />}>
|
||||
{t('PIN_ALBUM')}
|
||||
</OverflowMenuOption>
|
||||
)}
|
||||
{isArchived ? (
|
||||
<OverflowMenuOption
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.UNARCHIVE
|
||||
|
|
|
@ -3,23 +3,46 @@ import React from 'react';
|
|||
import LogoutIcon from '@mui/icons-material/Logout';
|
||||
import { CollectionActions } from '.';
|
||||
import { t } from 'i18next';
|
||||
import Unarchive from '@mui/icons-material/Unarchive';
|
||||
import ArchiveOutlined from '@mui/icons-material/ArchiveOutlined';
|
||||
|
||||
interface Iprops {
|
||||
isArchived: boolean;
|
||||
handleCollectionAction: (
|
||||
action: CollectionActions,
|
||||
loader?: boolean
|
||||
) => (...args: any[]) => Promise<void>;
|
||||
}
|
||||
|
||||
export function SharedCollectionOption({ handleCollectionAction }: Iprops) {
|
||||
export function SharedCollectionOption({
|
||||
isArchived,
|
||||
handleCollectionAction,
|
||||
}: Iprops) {
|
||||
return (
|
||||
<OverflowMenuOption
|
||||
startIcon={<LogoutIcon />}
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.CONFIRM_LEAVE_SHARED_ALBUM,
|
||||
false
|
||||
)}>
|
||||
{t('LEAVE_ALBUM')}
|
||||
</OverflowMenuOption>
|
||||
<>
|
||||
{isArchived ? (
|
||||
<OverflowMenuOption
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.UNARCHIVE
|
||||
)}
|
||||
startIcon={<Unarchive />}>
|
||||
{t('UNARCHIVE_COLLECTION')}
|
||||
</OverflowMenuOption>
|
||||
) : (
|
||||
<OverflowMenuOption
|
||||
onClick={handleCollectionAction(CollectionActions.ARCHIVE)}
|
||||
startIcon={<ArchiveOutlined />}>
|
||||
{t('ARCHIVE_COLLECTION')}
|
||||
</OverflowMenuOption>
|
||||
)}
|
||||
<OverflowMenuOption
|
||||
startIcon={<LogoutIcon />}
|
||||
onClick={handleCollectionAction(
|
||||
CollectionActions.CONFIRM_LEAVE_SHARED_ALBUM,
|
||||
false
|
||||
)}>
|
||||
{t('LEAVE_ALBUM')}
|
||||
</OverflowMenuOption>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, { useContext, useRef, useState } from 'react';
|
|||
import * as CollectionAPI from 'services/collectionService';
|
||||
import * as TrashService from 'services/trashService';
|
||||
import {
|
||||
changeCollectionOrder,
|
||||
changeCollectionSortOrder,
|
||||
changeCollectionVisibility,
|
||||
downloadAllCollectionFiles,
|
||||
|
@ -10,7 +11,7 @@ import {
|
|||
} from 'utils/collection';
|
||||
import { SetCollectionNamerAttributes } from '../CollectionNamer';
|
||||
import { Collection } from 'types/collection';
|
||||
import { IsArchived } from 'utils/magicMetadata';
|
||||
import { isArchivedCollection, isPinnedCollection } from 'utils/magicMetadata';
|
||||
import { GalleryContext } from 'pages/gallery';
|
||||
import { logError } from 'utils/sentry';
|
||||
import { VISIBILITY_STATE } from 'types/magicMetadata';
|
||||
|
@ -53,6 +54,8 @@ export enum CollectionActions {
|
|||
LEAVE_SHARED_ALBUM,
|
||||
SHOW_SORT_ORDER_MENU,
|
||||
UPDATE_COLLECTION_SORT_ORDER,
|
||||
PIN_ALBUM,
|
||||
UNPIN_ALBUM,
|
||||
}
|
||||
|
||||
const CollectionOptions = (props: CollectionOptionsProps) => {
|
||||
|
@ -132,6 +135,12 @@ const CollectionOptions = (props: CollectionOptionsProps) => {
|
|||
case CollectionActions.UPDATE_COLLECTION_SORT_ORDER:
|
||||
callback = updateCollectionSortOrder;
|
||||
break;
|
||||
case CollectionActions.PIN_ALBUM:
|
||||
callback = pinAlbum;
|
||||
break;
|
||||
case CollectionActions.UNPIN_ALBUM:
|
||||
callback = unPinAlbum;
|
||||
break;
|
||||
default:
|
||||
logError(
|
||||
Error('invalid collection action '),
|
||||
|
@ -290,6 +299,14 @@ const CollectionOptions = (props: CollectionOptionsProps) => {
|
|||
await changeCollectionSortOrder(activeCollection, asc);
|
||||
};
|
||||
|
||||
const pinAlbum = async () => {
|
||||
await changeCollectionOrder(activeCollection, 1);
|
||||
};
|
||||
|
||||
const unPinAlbum = async () => {
|
||||
await changeCollectionOrder(activeCollection, 0);
|
||||
};
|
||||
|
||||
return (
|
||||
<HorizontalFlex sx={{ display: 'inline-flex', gap: '16px' }}>
|
||||
<QuickOptions
|
||||
|
@ -326,11 +343,13 @@ const CollectionOptions = (props: CollectionOptionsProps) => {
|
|||
collectionSummaryType ===
|
||||
CollectionSummaryType.incomingShareCollaborator ? (
|
||||
<SharedCollectionOption
|
||||
isArchived={isArchivedCollection(activeCollection)}
|
||||
handleCollectionAction={handleCollectionAction}
|
||||
/>
|
||||
) : (
|
||||
<AlbumCollectionOption
|
||||
IsArchived={IsArchived(activeCollection)}
|
||||
isArchived={isArchivedCollection(activeCollection)}
|
||||
isPinned={isPinnedCollection(activeCollection)}
|
||||
handleCollectionAction={handleCollectionAction}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -22,7 +22,7 @@ export default function AddCollectionButton({ showNextModal }: Iprops) {
|
|||
<CollectionCard
|
||||
collectionTile={AllCollectionTile}
|
||||
onClick={() => showNextModal()}
|
||||
latestFile={null}>
|
||||
coverFile={null}>
|
||||
<AllCollectionTileText>
|
||||
{t('CREATE_COLLECTION')}
|
||||
</AllCollectionTileText>
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function CollectionSelectorCard({
|
|||
return (
|
||||
<CollectionCard
|
||||
collectionTile={AllCollectionTile}
|
||||
latestFile={collectionSummary.latestFile}
|
||||
coverFile={collectionSummary.coverFile}
|
||||
onClick={() => onCollectionClick(collectionSummary.id)}>
|
||||
<AllCollectionTileText>
|
||||
<Typography>{collectionSummary.name}</Typography>
|
||||
|
|
|
@ -45,7 +45,6 @@ interface Props {
|
|||
deletedFileIds?: Set<number>;
|
||||
setDeletedFileIds?: (value: Set<number>) => void;
|
||||
activeCollection: number;
|
||||
isIncomingSharedCollection?: boolean;
|
||||
enableDownload?: boolean;
|
||||
fileToCollectionsMap: Map<number, number[]>;
|
||||
collectionNameMap: Map<number, string>;
|
||||
|
@ -61,7 +60,6 @@ const PhotoFrame = ({
|
|||
deletedFileIds,
|
||||
setDeletedFileIds,
|
||||
activeCollection,
|
||||
isIncomingSharedCollection,
|
||||
enableDownload,
|
||||
fileToCollectionsMap,
|
||||
collectionNameMap,
|
||||
|
@ -529,7 +527,6 @@ const PhotoFrame = ({
|
|||
favItemIds={favItemIds}
|
||||
deletedFileIds={deletedFileIds}
|
||||
setDeletedFileIds={setDeletedFileIds}
|
||||
isIncomingSharedCollection={isIncomingSharedCollection}
|
||||
isTrashCollection={activeCollection === TRASH_SECTION}
|
||||
isHiddenCollection={activeCollection === HIDDEN_SECTION}
|
||||
enableDownload={enableDownload}
|
||||
|
|
|
@ -37,6 +37,7 @@ import {
|
|||
getMapDisableConfirmationDialog,
|
||||
getMapEnableConfirmationDialog,
|
||||
} from 'utils/ui';
|
||||
import { PublicCollectionGalleryContext } from 'utils/publicCollectionGallery';
|
||||
|
||||
export const FileInfoSidebar = styled((props: DialogProps) => (
|
||||
<EnteDrawer {...props} anchor="right" />
|
||||
|
@ -97,6 +98,9 @@ export function FileInfo({
|
|||
}: Iprops) {
|
||||
const appContext = useContext(AppContext);
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
const publicCollectionGalleryContext = useContext(
|
||||
PublicCollectionGalleryContext
|
||||
);
|
||||
|
||||
const [parsedExifData, setParsedExifData] = useState<Record<string, any>>();
|
||||
const [showExif, setShowExif] = useState(false);
|
||||
|
@ -235,7 +239,8 @@ export function FileInfo({
|
|||
icon={<LocationOnOutlined />}
|
||||
title={t('LOCATION')}
|
||||
caption={
|
||||
!appContext.mapEnabled ? (
|
||||
!appContext.mapEnabled ||
|
||||
publicCollectionGalleryContext.accessedThroughSharedURL ? (
|
||||
<Link
|
||||
href={getOpenStreetMapLink(location)}
|
||||
target="_blank"
|
||||
|
@ -264,13 +269,15 @@ export function FileInfo({
|
|||
/>
|
||||
}
|
||||
/>
|
||||
<MapBox
|
||||
location={location}
|
||||
mapEnabled={appContext.mapEnabled}
|
||||
openUpdateMapConfirmationDialog={
|
||||
openEnableMapConfirmationDialog
|
||||
}
|
||||
/>
|
||||
{!publicCollectionGalleryContext.accessedThroughSharedURL && (
|
||||
<MapBox
|
||||
location={location}
|
||||
mapEnabled={appContext.mapEnabled}
|
||||
openUpdateMapConfirmationDialog={
|
||||
openEnableMapConfirmationDialog
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<InfoItem
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useContext, useEffect, useRef, useState } from 'react';
|
||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import Photoswipe from 'photoswipe';
|
||||
import PhotoswipeUIDefault from 'photoswipe/dist/photoswipe-ui-default';
|
||||
import classnames from 'classnames';
|
||||
|
@ -43,6 +43,7 @@ import { t } from 'i18next';
|
|||
import { getParsedExifData } from 'services/upload/exifService';
|
||||
import { getFileType } from 'services/typeDetectionService';
|
||||
import { ConversionFailedNotification } from './styledComponents/ConversionFailedNotification';
|
||||
import { GalleryContext } from 'pages/gallery';
|
||||
|
||||
interface PhotoswipeFullscreenAPI {
|
||||
enter: () => void;
|
||||
|
@ -71,7 +72,6 @@ interface Iprops {
|
|||
favItemIds: Set<number>;
|
||||
deletedFileIds: Set<number>;
|
||||
setDeletedFileIds?: (value: Set<number>) => void;
|
||||
isIncomingSharedCollection: boolean;
|
||||
isTrashCollection: boolean;
|
||||
isHiddenCollection: boolean;
|
||||
enableDownload: boolean;
|
||||
|
@ -99,10 +99,14 @@ function PhotoViewer(props: Iprops) {
|
|||
const publicCollectionGalleryContext = useContext(
|
||||
PublicCollectionGalleryContext
|
||||
);
|
||||
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
const appContext = useContext(AppContext);
|
||||
|
||||
const exifExtractionInProgress = useRef<string>(null);
|
||||
const [shouldShowCopyOption] = useState(isClipboardItemPresent());
|
||||
const shouldShowCopyOption = useMemo(() => isClipboardItemPresent(), []);
|
||||
|
||||
const [isOwnFile, setIsOwnFile] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!pswpElement) return;
|
||||
|
@ -245,6 +249,13 @@ function PhotoViewer(props: Iprops) {
|
|||
setIsFav(isInFav(file));
|
||||
}
|
||||
|
||||
function updateIsOwnFile(file: EnteFile) {
|
||||
const isOwnFile =
|
||||
!publicCollectionGalleryContext.accessedThroughSharedURL &&
|
||||
galleryContext.user?.id === file.ownerID;
|
||||
setIsOwnFile(isOwnFile);
|
||||
}
|
||||
|
||||
const openPhotoSwipe = () => {
|
||||
const { items, currentIndex } = props;
|
||||
const options = {
|
||||
|
@ -307,7 +318,12 @@ function PhotoViewer(props: Iprops) {
|
|||
photoSwipe.listen('beforeChange', () => {
|
||||
if (!photoSwipe?.currItem) return;
|
||||
const currItem = photoSwipe.currItem as EnteFile;
|
||||
const videoTags = document.getElementsByTagName('video');
|
||||
for (const videoTag of videoTags) {
|
||||
videoTag.pause();
|
||||
}
|
||||
updateFavButton(currItem);
|
||||
updateIsOwnFile(currItem);
|
||||
if (currItem.metadata.fileType !== FILE_TYPE.IMAGE) {
|
||||
setExif({ key: currItem.src, value: null });
|
||||
return;
|
||||
|
@ -370,8 +386,9 @@ function PhotoViewer(props: Iprops) {
|
|||
const onFavClick = async (file: EnteFile) => {
|
||||
try {
|
||||
if (
|
||||
!file ||
|
||||
props.isTrashCollection ||
|
||||
props.isIncomingSharedCollection ||
|
||||
!isOwnFile ||
|
||||
props.isHiddenCollection
|
||||
) {
|
||||
return;
|
||||
|
@ -408,11 +425,7 @@ function PhotoViewer(props: Iprops) {
|
|||
};
|
||||
|
||||
const confirmTrashFile = (file: EnteFile) => {
|
||||
if (
|
||||
!file ||
|
||||
props.isIncomingSharedCollection ||
|
||||
props.isTrashCollection
|
||||
) {
|
||||
if (!file || !isOwnFile || props.isTrashCollection) {
|
||||
return;
|
||||
}
|
||||
appContext.setDialogMessage(getTrashFileMessage(() => trashFile(file)));
|
||||
|
@ -599,19 +612,18 @@ function PhotoViewer(props: Iprops) {
|
|||
<ContentCopy fontSize="small" />
|
||||
</button>
|
||||
)}
|
||||
{!props.isIncomingSharedCollection &&
|
||||
!props.isTrashCollection && (
|
||||
<button
|
||||
className="pswp__button pswp__button--custom"
|
||||
title={t('DELETE_OPTION')}
|
||||
onClick={() => {
|
||||
confirmTrashFile(
|
||||
photoSwipe?.currItem as EnteFile
|
||||
);
|
||||
}}>
|
||||
<DeleteIcon fontSize="small" />
|
||||
</button>
|
||||
)}
|
||||
{isOwnFile && !props.isTrashCollection && (
|
||||
<button
|
||||
className="pswp__button pswp__button--custom"
|
||||
title={t('DELETE_OPTION')}
|
||||
onClick={() => {
|
||||
confirmTrashFile(
|
||||
photoSwipe?.currItem as EnteFile
|
||||
);
|
||||
}}>
|
||||
<DeleteIcon fontSize="small" />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="pswp__button pswp__button--zoom"
|
||||
title={t('ZOOM_IN_OUT')}
|
||||
|
@ -627,7 +639,7 @@ function PhotoViewer(props: Iprops) {
|
|||
onClick={handleOpenInfo}>
|
||||
<InfoIcon fontSize="small" />
|
||||
</button>
|
||||
{!props.isIncomingSharedCollection &&
|
||||
{isOwnFile &&
|
||||
!props.isTrashCollection &&
|
||||
!props.isHiddenCollection && (
|
||||
<button
|
||||
|
@ -678,10 +690,10 @@ function PhotoViewer(props: Iprops) {
|
|||
</div>
|
||||
</div>
|
||||
<FileInfo
|
||||
shouldDisableEdits={props.isIncomingSharedCollection}
|
||||
shouldDisableEdits={!isOwnFile}
|
||||
showCollectionChips={
|
||||
!props.isTrashCollection &&
|
||||
!props.isIncomingSharedCollection &&
|
||||
isOwnFile &&
|
||||
!props.isHiddenCollection
|
||||
}
|
||||
showInfo={showInfo}
|
||||
|
|
|
@ -40,7 +40,7 @@ const LabelWithInfo = ({ data }: { data: SearchOption }) => {
|
|||
{data.previewFiles.map((file) => (
|
||||
<CollectionCard
|
||||
key={file.id}
|
||||
latestFile={file}
|
||||
coverFile={file}
|
||||
onClick={() => null}
|
||||
collectionTile={ResultPreviewTile}
|
||||
/>
|
||||
|
|
|
@ -18,21 +18,17 @@ export function FamilySubscriptionCardContent({ userDetails }: Iprops) {
|
|||
return userDetails.usage;
|
||||
}
|
||||
}, [userDetails]);
|
||||
const totalStorage =
|
||||
userDetails.familyData.storage + (userDetails.storageBonus ?? 0);
|
||||
|
||||
return (
|
||||
<>
|
||||
<StorageSection
|
||||
storage={userDetails.familyData.storage}
|
||||
usage={totalUsage}
|
||||
/>
|
||||
<StorageSection storage={totalStorage} usage={totalUsage} />
|
||||
<FamilyUsageSection
|
||||
userUsage={userDetails.usage}
|
||||
fileCount={userDetails.fileCount}
|
||||
totalUsage={totalUsage}
|
||||
totalStorage={
|
||||
userDetails.familyData.storage +
|
||||
(userDetails.storageBonus ?? 0)
|
||||
}
|
||||
totalStorage={totalStorage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -8,19 +8,15 @@ interface Iprops {
|
|||
}
|
||||
|
||||
export function IndividualSubscriptionCardContent({ userDetails }: Iprops) {
|
||||
const totalStorage =
|
||||
userDetails.subscription.storage + (userDetails.storageBonus ?? 0);
|
||||
return (
|
||||
<>
|
||||
<StorageSection
|
||||
storage={userDetails.subscription.storage}
|
||||
usage={userDetails.usage}
|
||||
/>
|
||||
<StorageSection storage={totalStorage} usage={userDetails.usage} />
|
||||
<IndividualUsageSection
|
||||
usage={userDetails.usage}
|
||||
fileCount={userDetails.fileCount}
|
||||
storage={
|
||||
userDetails.subscription.storage +
|
||||
(userDetails.storageBonus ?? 0)
|
||||
}
|
||||
storage={totalStorage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -30,6 +30,7 @@ export interface SingleInputFormProps {
|
|||
autoComplete?: string;
|
||||
blockButton?: boolean;
|
||||
hiddenLabel?: boolean;
|
||||
disableAutoComplete?: boolean;
|
||||
}
|
||||
|
||||
export default function SingleInputForm(props: SingleInputFormProps) {
|
||||
|
@ -109,6 +110,11 @@ export default function SingleInputForm(props: SingleInputFormProps) {
|
|||
autoFocus={!props.disableAutoFocus}
|
||||
autoComplete={props.autoComplete}
|
||||
InputProps={{
|
||||
autoComplete:
|
||||
props.disableAutoComplete ||
|
||||
props.fieldType === 'password'
|
||||
? 'off'
|
||||
: 'on',
|
||||
endAdornment: props.fieldType === 'password' && (
|
||||
<ShowHidePassword
|
||||
showPassword={showPassword}
|
||||
|
|
78
apps/photos/src/components/icons/UnPinIcon.tsx
Normal file
78
apps/photos/src/components/icons/UnPinIcon.tsx
Normal file
|
@ -0,0 +1,78 @@
|
|||
import SvgIcon from '@mui/material/SvgIcon';
|
||||
|
||||
export const UnPinIcon = (props) => {
|
||||
return (
|
||||
<SvgIcon
|
||||
id="eNi9tomYy271"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -960 960 960"
|
||||
shape-rendering="geometricPrecision"
|
||||
text-rendering="geometricPrecision"
|
||||
{...props}>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="eNi9tomYy273-fill"
|
||||
x1="0"
|
||||
y1="0.5"
|
||||
x2="1"
|
||||
y2="0.5"
|
||||
spreadMethod="pad"
|
||||
gradientUnits="objectBoundingBox"
|
||||
gradientTransform="translate(0 0)">
|
||||
<stop
|
||||
id="eNi9tomYy273-fill-0"
|
||||
offset="100%"
|
||||
stop-color="#fff"
|
||||
/>
|
||||
<stop
|
||||
id="eNi9tomYy273-fill-1"
|
||||
offset="100%"
|
||||
stop-color="#fff"
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M634,-448l86,77v60h-210v241l-30,30-30-30v-241h-210v-60l80-77v-332h-50v-60h414v60h-50v332Zm-313,77h312l-59-55v-354h-194v354l-59,55Zm156,0" />
|
||||
<rect
|
||||
width="26.347306"
|
||||
height="26.347306"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(29.14543 20.40785-1.147153 1.638304 147.37857-852.859017)"
|
||||
fill="url(#eNi9tomYy273-fill)"
|
||||
stroke-width="0"
|
||||
/>
|
||||
<rect
|
||||
width="65.868264"
|
||||
height="8.383234"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(.961684 0.648664-.559193 0.829038 575.09991-562.860814)"
|
||||
fill="#f8eeee"
|
||||
stroke-width="0"
|
||||
/>
|
||||
<rect
|
||||
width="65.868264"
|
||||
height="8.383234"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(.961684 0.648664-.559193 0.829038 322.549012-741.890754)"
|
||||
fill="#fff"
|
||||
stroke-width="0"
|
||||
/>
|
||||
<rect
|
||||
width="96"
|
||||
height="96"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="translate(1379.418154-389.125449)"
|
||||
fill="#d2dbed"
|
||||
stroke-width="0"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
};
|
||||
|
||||
UnPinIcon.defaultProps = {
|
||||
height: 20,
|
||||
width: 20,
|
||||
};
|
|
@ -20,8 +20,7 @@ import {
|
|||
import { FILE_TYPE } from 'constants/file';
|
||||
import AlbumOutlined from '@mui/icons-material/AlbumOutlined';
|
||||
import Avatar from './Avatar';
|
||||
import { User } from 'types/user';
|
||||
import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
||||
import { shouldShowAvatar } from 'utils/file';
|
||||
|
||||
interface IProps {
|
||||
file: EnteFile;
|
||||
|
@ -217,7 +216,7 @@ const Cont = styled('div')<{ disabled: boolean }>`
|
|||
`;
|
||||
|
||||
export default function PreviewCard(props: IProps) {
|
||||
const { thumbs } = useContext(GalleryContext);
|
||||
const { thumbs, user } = useContext(GalleryContext);
|
||||
|
||||
const {
|
||||
file,
|
||||
|
@ -334,8 +333,6 @@ export default function PreviewCard(props: IProps) {
|
|||
}
|
||||
};
|
||||
|
||||
const user: User = getData(LS_KEYS.USER);
|
||||
|
||||
return (
|
||||
<Cont
|
||||
key={`thumb-${file.id}-${props.showPlaceholder}`}
|
||||
|
@ -371,9 +368,7 @@ export default function PreviewCard(props: IProps) {
|
|||
)
|
||||
)}
|
||||
<SelectedOverlay selected={selected} />
|
||||
{(file.ownerID !== user.id ||
|
||||
(file.ownerID === user.id &&
|
||||
file.pubMagicMetadata?.data?.uploaderName)) && (
|
||||
{shouldShowAvatar(file, user) && (
|
||||
<AvatarOverlay>
|
||||
<Avatar file={file} />
|
||||
</AvatarOverlay>
|
||||
|
|
|
@ -24,6 +24,7 @@ export enum CollectionSummaryType {
|
|||
sharedOnlyViaLink = 'sharedOnlyViaLink',
|
||||
archived = 'archived',
|
||||
hidden = 'hidden',
|
||||
pinned = 'pinned',
|
||||
}
|
||||
export enum COLLECTION_LIST_SORT_BY {
|
||||
NAME,
|
||||
|
@ -39,16 +40,17 @@ export const COLLECTION_SORT_ORDER = new Map([
|
|||
[CollectionSummaryType.all, 0],
|
||||
[CollectionSummaryType.uncategorized, 1],
|
||||
[CollectionSummaryType.favorites, 2],
|
||||
[CollectionSummaryType.album, 3],
|
||||
[CollectionSummaryType.folder, 3],
|
||||
[CollectionSummaryType.incomingShareViewer, 3],
|
||||
[CollectionSummaryType.incomingShareCollaborator, 3],
|
||||
[CollectionSummaryType.outgoingShare, 3],
|
||||
[CollectionSummaryType.sharedOnlyViaLink, 3],
|
||||
[CollectionSummaryType.archived, 3],
|
||||
[CollectionSummaryType.archive, 4],
|
||||
[CollectionSummaryType.trash, 5],
|
||||
[CollectionSummaryType.hidden, 5],
|
||||
[CollectionSummaryType.pinned, 3],
|
||||
[CollectionSummaryType.album, 4],
|
||||
[CollectionSummaryType.folder, 4],
|
||||
[CollectionSummaryType.incomingShareViewer, 4],
|
||||
[CollectionSummaryType.incomingShareCollaborator, 4],
|
||||
[CollectionSummaryType.outgoingShare, 4],
|
||||
[CollectionSummaryType.sharedOnlyViaLink, 4],
|
||||
[CollectionSummaryType.archived, 4],
|
||||
[CollectionSummaryType.archive, 5],
|
||||
[CollectionSummaryType.trash, 6],
|
||||
[CollectionSummaryType.hidden, 7],
|
||||
]);
|
||||
|
||||
export const SYSTEM_COLLECTION_TYPES = new Set([
|
||||
|
|
|
@ -53,7 +53,6 @@ import {
|
|||
downloadFiles,
|
||||
getSelectedFiles,
|
||||
getUniqueFiles,
|
||||
isSharedFile,
|
||||
mergeMetadata,
|
||||
sortFiles,
|
||||
} from 'utils/file';
|
||||
|
@ -120,7 +119,7 @@ import ExportModal from 'components/ExportModal';
|
|||
import GalleryEmptyState from 'components/GalleryEmptyState';
|
||||
import AuthenticateUserModal from 'components/AuthenticateUserModal';
|
||||
import useMemoSingleThreaded from 'hooks/useMemoSingleThreaded';
|
||||
import { IsArchived } from 'utils/magicMetadata';
|
||||
import { isArchivedFile } from 'utils/magicMetadata';
|
||||
import { isSameDayAnyYear, isInsideLocationTag } from 'utils/search';
|
||||
import { getSessionExpiredMessage } from 'utils/ui';
|
||||
import { syncEntities } from 'services/entityService';
|
||||
|
@ -444,10 +443,6 @@ export default function Gallery() {
|
|||
|
||||
// SEARCH MODE
|
||||
if (isInSearchMode) {
|
||||
// shared files are not searchable
|
||||
if (isSharedFile(user, item)) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
search?.date &&
|
||||
!isSameDayAnyYear(search.date)(
|
||||
|
@ -492,15 +487,6 @@ export default function Gallery() {
|
|||
return true;
|
||||
}
|
||||
|
||||
// shared files can only be seen in their respective collection
|
||||
if (isSharedFile(user, item)) {
|
||||
if (activeCollection === item.collectionID) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// archived collections files can only be seen in their respective collection
|
||||
if (archivedCollections.has(item.collectionID)) {
|
||||
if (activeCollection === item.collectionID) {
|
||||
|
@ -511,7 +497,7 @@ export default function Gallery() {
|
|||
}
|
||||
|
||||
// Archived files can only be seen in archive section or their respective collection
|
||||
if (IsArchived(item)) {
|
||||
if (isArchivedFile(item)) {
|
||||
if (
|
||||
activeCollection === ARCHIVE_SECTION ||
|
||||
activeCollection === item.collectionID
|
||||
|
@ -698,15 +684,15 @@ export default function Gallery() {
|
|||
: selectedFiles.filter(
|
||||
(file) => file.ownerID === user.id
|
||||
);
|
||||
if (toProcessFiles.length === 0) {
|
||||
return;
|
||||
if (toProcessFiles.length > 0) {
|
||||
await handleCollectionOps(
|
||||
ops,
|
||||
collection,
|
||||
toProcessFiles,
|
||||
selected.collectionID
|
||||
);
|
||||
}
|
||||
await handleCollectionOps(
|
||||
ops,
|
||||
collection,
|
||||
toProcessFiles,
|
||||
selected.collectionID
|
||||
);
|
||||
|
||||
clearSelection();
|
||||
await syncWithRemote(false, true);
|
||||
setActiveCollection(collection.id);
|
||||
|
@ -1034,12 +1020,6 @@ export default function Gallery() {
|
|||
deletedFileIds={deletedFileIds}
|
||||
setDeletedFileIds={setDeletedFileIds}
|
||||
activeCollection={activeCollection}
|
||||
isIncomingSharedCollection={
|
||||
collectionSummaries.get(activeCollection)?.type ===
|
||||
CollectionSummaryType.incomingShareCollaborator ||
|
||||
collectionSummaries.get(activeCollection)?.type ===
|
||||
CollectionSummaryType.incomingShareViewer
|
||||
}
|
||||
enableDownload={true}
|
||||
fileToCollectionsMap={fileToCollectionsMap}
|
||||
collectionNameMap={collectionNameMap}
|
||||
|
|
|
@ -105,6 +105,7 @@ export default function Recover() {
|
|||
fieldType="text"
|
||||
placeholder={t('RECOVERY_KEY_HINT')}
|
||||
buttonText={t('RECOVER')}
|
||||
disableAutoComplete
|
||||
/>
|
||||
<FormPaperFooter style={{ justifyContent: 'space-between' }}>
|
||||
<LinkButton onClick={showNoRecoveryKeyMessage}>
|
||||
|
|
|
@ -447,7 +447,6 @@ export default function PublicCollectionGallery() {
|
|||
setSelected={() => null}
|
||||
selected={{ count: 0, collectionID: null, ownCount: 0 }}
|
||||
activeCollection={ALL_SECTION}
|
||||
isIncomingSharedCollection
|
||||
enableDownload={downloadEnabled}
|
||||
fileToCollectionsMap={null}
|
||||
collectionNameMap={null}
|
||||
|
|
|
@ -152,6 +152,7 @@ export default function Recover() {
|
|||
fieldType="text"
|
||||
placeholder={t('RECOVERY_KEY_HINT')}
|
||||
buttonText={t('RECOVER')}
|
||||
disableAutoComplete
|
||||
/>
|
||||
<FormPaperFooter style={{ justifyContent: 'space-between' }}>
|
||||
<LinkButton onClick={() => showContactSupportDialog()}>
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from 'utils/file';
|
||||
import {
|
||||
Collection,
|
||||
CollectionLatestFiles,
|
||||
CollectionToFileMap,
|
||||
AddToCollectionRequest,
|
||||
MoveToCollectionRequest,
|
||||
EncryptedFileKey,
|
||||
|
@ -30,6 +30,7 @@ import {
|
|||
CollectionMagicMetadataProps,
|
||||
CollectionPublicMagicMetadata,
|
||||
RemoveFromCollectionRequest,
|
||||
CollectionShareeMagicMetadata,
|
||||
} from 'types/collection';
|
||||
import {
|
||||
COLLECTION_LIST_SORT_BY,
|
||||
|
@ -43,7 +44,12 @@ import {
|
|||
HIDDEN_SECTION,
|
||||
} from 'constants/collection';
|
||||
import { SUB_TYPE, UpdateMagicMetadataRequest } from 'types/magicMetadata';
|
||||
import { IsArchived, updateMagicMetadata } from 'utils/magicMetadata';
|
||||
import {
|
||||
isArchivedCollection,
|
||||
isArchivedFile,
|
||||
isPinnedCollection,
|
||||
updateMagicMetadata,
|
||||
} from 'utils/magicMetadata';
|
||||
import { User } from 'types/user';
|
||||
import {
|
||||
isQuickLinkCollection,
|
||||
|
@ -140,12 +146,25 @@ const getCollectionWithSecrets = async (
|
|||
};
|
||||
}
|
||||
|
||||
let collectionShareeMagicMetadata: CollectionShareeMagicMetadata;
|
||||
if (collection.sharedMagicMetadata?.data) {
|
||||
collectionShareeMagicMetadata = {
|
||||
...collection.sharedMagicMetadata,
|
||||
data: await cryptoWorker.decryptMetadata(
|
||||
collection.sharedMagicMetadata.data,
|
||||
collection.sharedMagicMetadata.header,
|
||||
collectionKey
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...collection,
|
||||
name: collectionName,
|
||||
key: collectionKey,
|
||||
magicMetadata: collectionMagicMetadata,
|
||||
pubMagicMetadata: collectionPublicMagicMetadata,
|
||||
sharedMagicMetadata: collectionShareeMagicMetadata,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -278,10 +297,9 @@ export const getCollection = async (
|
|||
};
|
||||
|
||||
export const getCollectionLatestFiles = (
|
||||
user: User,
|
||||
files: EnteFile[],
|
||||
archivedCollections: Set<number>
|
||||
): CollectionLatestFiles => {
|
||||
): CollectionToFileMap => {
|
||||
const latestFiles = new Map<number, EnteFile>();
|
||||
|
||||
files.forEach((file) => {
|
||||
|
@ -290,8 +308,7 @@ export const getCollectionLatestFiles = (
|
|||
}
|
||||
if (
|
||||
!latestFiles.has(ALL_SECTION) &&
|
||||
!IsArchived(file) &&
|
||||
file.ownerID === user.id &&
|
||||
!isArchivedFile(file) &&
|
||||
!archivedCollections.has(file.collectionID)
|
||||
) {
|
||||
latestFiles.set(ALL_SECTION, file);
|
||||
|
@ -300,6 +317,54 @@ export const getCollectionLatestFiles = (
|
|||
return latestFiles;
|
||||
};
|
||||
|
||||
export const getCollectionCoverFiles = (
|
||||
files: EnteFile[],
|
||||
archivedCollections: Set<number>,
|
||||
collections: Collection[]
|
||||
): CollectionToFileMap => {
|
||||
const collectionIDToFileMap = groupFilesBasedOnCollectionID(files);
|
||||
|
||||
const coverFiles = new Map<number, EnteFile>();
|
||||
|
||||
collections.forEach((collection) => {
|
||||
const collectionFiles = collectionIDToFileMap.get(collection.id);
|
||||
if (!collectionFiles || collectionFiles.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (typeof collection.pubMagicMetadata?.data?.coverID !== 'undefined') {
|
||||
const coverFile = collectionFiles.find(
|
||||
(file) => file.id === collection.pubMagicMetadata?.data?.coverID
|
||||
);
|
||||
if (coverFile) {
|
||||
coverFiles.set(collection.id, coverFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (collection.pubMagicMetadata?.data?.asc) {
|
||||
coverFiles.set(
|
||||
collection.id,
|
||||
collectionFiles[collectionFiles.length - 1]
|
||||
);
|
||||
} else {
|
||||
coverFiles.set(collection.id, collectionFiles[0]);
|
||||
}
|
||||
});
|
||||
|
||||
for (const file of files) {
|
||||
if (coverFiles.has(ALL_SECTION)) {
|
||||
break;
|
||||
}
|
||||
if (
|
||||
!isArchivedFile(file) &&
|
||||
!archivedCollections.has(file.collectionID)
|
||||
) {
|
||||
coverFiles.set(ALL_SECTION, file);
|
||||
}
|
||||
}
|
||||
|
||||
return coverFiles;
|
||||
};
|
||||
|
||||
export const getFavItemIds = async (
|
||||
files: EnteFile[]
|
||||
): Promise<Set<number>> => {
|
||||
|
@ -360,6 +425,7 @@ const createCollection = async (
|
|||
isDeleted: false,
|
||||
magicMetadata: encryptedMagicMetadata,
|
||||
pubMagicMetadata: null,
|
||||
sharedMagicMetadata: null,
|
||||
};
|
||||
const createdCollection = await postCollection(newCollection, token);
|
||||
const decryptedCreatedCollection = await getCollectionWithSecrets(
|
||||
|
@ -739,6 +805,50 @@ export const updateCollectionMagicMetadata = async (
|
|||
return updatedCollection;
|
||||
};
|
||||
|
||||
export const updateSharedCollectionMagicMetadata = async (
|
||||
collection: Collection,
|
||||
updatedMagicMetadata: CollectionMagicMetadata
|
||||
) => {
|
||||
const token = getToken();
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cryptoWorker = await ComlinkCryptoWorker.getInstance();
|
||||
|
||||
const { file: encryptedMagicMetadata } = await cryptoWorker.encryptMetadata(
|
||||
updatedMagicMetadata.data,
|
||||
collection.key
|
||||
);
|
||||
|
||||
const reqBody: UpdateMagicMetadataRequest = {
|
||||
id: collection.id,
|
||||
magicMetadata: {
|
||||
version: updatedMagicMetadata.version,
|
||||
count: updatedMagicMetadata.count,
|
||||
data: encryptedMagicMetadata.encryptedData,
|
||||
header: encryptedMagicMetadata.decryptionHeader,
|
||||
},
|
||||
};
|
||||
|
||||
await HTTPService.put(
|
||||
`${ENDPOINT}/collections/sharee-magic-metadata`,
|
||||
reqBody,
|
||||
null,
|
||||
{
|
||||
'X-Auth-Token': token,
|
||||
}
|
||||
);
|
||||
const updatedCollection: Collection = {
|
||||
...collection,
|
||||
magicMetadata: {
|
||||
...updatedMagicMetadata,
|
||||
version: updatedMagicMetadata.version + 1,
|
||||
},
|
||||
};
|
||||
return updatedCollection;
|
||||
};
|
||||
|
||||
export const updatePublicCollectionMagicMetadata = async (
|
||||
collection: Collection,
|
||||
updatedPublicMagicMetadata: CollectionPublicMagicMetadata
|
||||
|
@ -973,6 +1083,7 @@ export function sortCollectionSummaries(
|
|||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
})
|
||||
.sort((a, b) => b.order - a.order)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
COLLECTION_SORT_ORDER.get(a.type) -
|
||||
|
@ -1005,10 +1116,14 @@ export async function getCollectionSummaries(
|
|||
): Promise<CollectionSummaries> {
|
||||
const collectionSummaries: CollectionSummaries = new Map();
|
||||
const collectionLatestFiles = getCollectionLatestFiles(
|
||||
user,
|
||||
files,
|
||||
archivedCollections
|
||||
);
|
||||
const collectionCoverFiles = getCollectionCoverFiles(
|
||||
files,
|
||||
archivedCollections,
|
||||
collections
|
||||
);
|
||||
const collectionFilesCount = getCollectionsFileCount(
|
||||
files,
|
||||
trashedFiles,
|
||||
|
@ -1032,10 +1147,12 @@ export async function getCollectionSummaries(
|
|||
type = CollectionSummaryType.outgoingShare;
|
||||
} else if (isSharedOnlyViaLink(collection)) {
|
||||
type = CollectionSummaryType.sharedOnlyViaLink;
|
||||
} else if (IsArchived(collection)) {
|
||||
} else if (isArchivedCollection(collection)) {
|
||||
type = CollectionSummaryType.archived;
|
||||
} else if (isHiddenCollection(collection)) {
|
||||
type = CollectionSummaryType.hidden;
|
||||
} else if (isPinnedCollection(collection)) {
|
||||
type = CollectionSummaryType.pinned;
|
||||
} else {
|
||||
type = CollectionSummaryType[collection.type];
|
||||
}
|
||||
|
@ -1044,9 +1161,11 @@ export async function getCollectionSummaries(
|
|||
id: collection.id,
|
||||
name: collection.name,
|
||||
latestFile: collectionLatestFiles.get(collection.id),
|
||||
coverFile: collectionCoverFiles.get(collection.id),
|
||||
fileCount: collectionFilesCount.get(collection.id) ?? 0,
|
||||
updationTime: collection.updationTime,
|
||||
type: type,
|
||||
order: collection.magicMetadata?.data?.order ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1074,7 +1193,11 @@ export async function getCollectionSummaries(
|
|||
|
||||
collectionSummaries.set(
|
||||
ALL_SECTION,
|
||||
getAllCollectionSummaries(collectionFilesCount, collectionLatestFiles)
|
||||
getAllCollectionSummaries(
|
||||
collectionFilesCount,
|
||||
collectionCoverFiles,
|
||||
collectionLatestFiles
|
||||
)
|
||||
);
|
||||
collectionSummaries.set(
|
||||
ARCHIVE_SECTION,
|
||||
|
@ -1119,7 +1242,7 @@ function getCollectionsFileCount(
|
|||
for (const file of files) {
|
||||
if (isSharedFile(user, file)) {
|
||||
continue;
|
||||
} else if (IsArchived(file)) {
|
||||
} else if (isArchivedFile(file)) {
|
||||
uniqueArchivedFileIDs.add(file.id);
|
||||
} else if (!archivedCollections.has(file.collectionID)) {
|
||||
uniqueAllSectionFileIDs.add(file.id);
|
||||
|
@ -1134,15 +1257,18 @@ function getCollectionsFileCount(
|
|||
|
||||
function getAllCollectionSummaries(
|
||||
collectionFilesCount: CollectionFilesCount,
|
||||
collectionsLatestFile: CollectionLatestFiles
|
||||
collectionCoverFiles: CollectionToFileMap,
|
||||
collectionsLatestFile: CollectionToFileMap
|
||||
): CollectionSummary {
|
||||
return {
|
||||
id: ALL_SECTION,
|
||||
name: t('ALL_SECTION_NAME'),
|
||||
type: CollectionSummaryType.all,
|
||||
coverFile: collectionCoverFiles.get(ALL_SECTION),
|
||||
latestFile: collectionsLatestFile.get(ALL_SECTION),
|
||||
fileCount: collectionFilesCount.get(ALL_SECTION) || 0,
|
||||
updationTime: collectionsLatestFile.get(ALL_SECTION)?.updationTime,
|
||||
order: 1,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1152,49 +1278,57 @@ function getDummyUncategorizedCollectionSummaries(): CollectionSummary {
|
|||
name: t('UNCATEGORIZED'),
|
||||
type: CollectionSummaryType.uncategorized,
|
||||
latestFile: null,
|
||||
coverFile: null,
|
||||
fileCount: 0,
|
||||
updationTime: 0,
|
||||
order: 1,
|
||||
};
|
||||
}
|
||||
|
||||
function getHiddenCollectionSummaries(
|
||||
collectionFilesCount: CollectionFilesCount,
|
||||
collectionsLatestFile: CollectionLatestFiles
|
||||
collectionsLatestFile: CollectionToFileMap
|
||||
): CollectionSummary {
|
||||
return {
|
||||
id: HIDDEN_SECTION,
|
||||
name: t('HIDDEN'),
|
||||
type: CollectionSummaryType.hidden,
|
||||
coverFile: null,
|
||||
latestFile: collectionsLatestFile.get(HIDDEN_SECTION),
|
||||
fileCount: collectionFilesCount.get(HIDDEN_SECTION) ?? 0,
|
||||
updationTime: collectionsLatestFile.get(HIDDEN_SECTION)?.updationTime,
|
||||
order: -1,
|
||||
};
|
||||
}
|
||||
function getArchivedCollectionSummaries(
|
||||
collectionFilesCount: CollectionFilesCount,
|
||||
collectionsLatestFile: CollectionLatestFiles
|
||||
collectionsLatestFile: CollectionToFileMap
|
||||
): CollectionSummary {
|
||||
return {
|
||||
id: ARCHIVE_SECTION,
|
||||
name: t('ARCHIVE_SECTION_NAME'),
|
||||
type: CollectionSummaryType.archive,
|
||||
coverFile: null,
|
||||
latestFile: collectionsLatestFile.get(ARCHIVE_SECTION),
|
||||
fileCount: collectionFilesCount.get(ARCHIVE_SECTION) ?? 0,
|
||||
updationTime: collectionsLatestFile.get(ARCHIVE_SECTION)?.updationTime,
|
||||
order: -1,
|
||||
};
|
||||
}
|
||||
|
||||
function getTrashedCollectionSummaries(
|
||||
collectionFilesCount: CollectionFilesCount,
|
||||
collectionsLatestFile: CollectionLatestFiles
|
||||
collectionsLatestFile: CollectionToFileMap
|
||||
): CollectionSummary {
|
||||
return {
|
||||
id: TRASH_SECTION,
|
||||
name: t('TRASH'),
|
||||
type: CollectionSummaryType.trash,
|
||||
coverFile: null,
|
||||
latestFile: collectionsLatestFile.get(TRASH_SECTION),
|
||||
fileCount: collectionFilesCount.get(TRASH_SECTION) ?? 0,
|
||||
updationTime: collectionsLatestFile.get(TRASH_SECTION)?.updationTime,
|
||||
order: -1,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@ import {
|
|||
} from 'utils/search';
|
||||
import { Person, Thing } from 'types/machineLearning';
|
||||
import { getUniqueFiles } from 'utils/file';
|
||||
import { User } from 'types/user';
|
||||
import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
||||
import { getLatestEntities } from './entityService';
|
||||
import { LocationTag, LocationTagData, EntityType } from 'types/entity';
|
||||
|
||||
|
@ -66,7 +64,6 @@ function convertSuggestionsToOptions(
|
|||
suggestions: Suggestion[],
|
||||
files: EnteFile[]
|
||||
) {
|
||||
const user = getData(LS_KEYS.USER) as User;
|
||||
const previewImageAppendedOptions: SearchOption[] = suggestions
|
||||
.map((suggestion) => ({
|
||||
suggestion,
|
||||
|
@ -74,7 +71,7 @@ function convertSuggestionsToOptions(
|
|||
}))
|
||||
.map(({ suggestion, searchQuery }) => {
|
||||
const resultFiles = getUniqueFiles(
|
||||
files.filter((file) => isSearchedFile(user, file, searchQuery))
|
||||
files.filter((file) => isSearchedFile(file, searchQuery))
|
||||
);
|
||||
return {
|
||||
...suggestion,
|
||||
|
@ -260,21 +257,14 @@ function searchCollection(
|
|||
}
|
||||
|
||||
function searchFilesByName(searchPhrase: string, files: EnteFile[]) {
|
||||
const user = getData(LS_KEYS.USER) as User;
|
||||
if (!user) return [];
|
||||
return files.filter(
|
||||
(file) =>
|
||||
file.ownerID === user.id &&
|
||||
file.metadata.title.toLowerCase().includes(searchPhrase)
|
||||
return files.filter((file) =>
|
||||
file.metadata.title.toLowerCase().includes(searchPhrase)
|
||||
);
|
||||
}
|
||||
|
||||
function searchFilesByCaption(searchPhrase: string, files: EnteFile[]) {
|
||||
const user = getData(LS_KEYS.USER) as User;
|
||||
if (!user) return [];
|
||||
return files.filter(
|
||||
(file) =>
|
||||
file.ownerID === user.id &&
|
||||
file.pubMagicMetadata &&
|
||||
file.pubMagicMetadata.data.caption
|
||||
?.toLowerCase()
|
||||
|
@ -324,13 +314,10 @@ async function searchThing(searchPhrase: string) {
|
|||
);
|
||||
}
|
||||
|
||||
function isSearchedFile(user: User, file: EnteFile, search: Search) {
|
||||
function isSearchedFile(file: EnteFile, search: Search) {
|
||||
if (search?.collection) {
|
||||
return search.collection === file.collectionID;
|
||||
}
|
||||
if (file.ownerID !== user.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (search?.date) {
|
||||
return isSameDayAnyYear(search.date)(
|
||||
|
|
|
@ -37,6 +37,7 @@ export interface EncryptedCollection {
|
|||
isDeleted: boolean;
|
||||
magicMetadata: EncryptedMagicMetadata;
|
||||
pubMagicMetadata: EncryptedMagicMetadata;
|
||||
sharedMagicMetadata: EncryptedMagicMetadata;
|
||||
}
|
||||
|
||||
export interface Collection
|
||||
|
@ -48,11 +49,13 @@ export interface Collection
|
|||
| 'nameDecryptionNonce'
|
||||
| 'magicMetadata'
|
||||
| 'pubMagicMetadata'
|
||||
| 'sharedMagicMetadata'
|
||||
> {
|
||||
key: string;
|
||||
name: string;
|
||||
magicMetadata: CollectionMagicMetadata;
|
||||
pubMagicMetadata: CollectionPublicMagicMetadata;
|
||||
sharedMagicMetadata: CollectionShareeMagicMetadata;
|
||||
}
|
||||
|
||||
export interface PublicURL {
|
||||
|
@ -108,7 +111,7 @@ export interface collectionAttributes {
|
|||
pathDecryptionNonce?: string;
|
||||
}
|
||||
|
||||
export type CollectionLatestFiles = Map<number, EnteFile>;
|
||||
export type CollectionToFileMap = Map<number, EnteFile>;
|
||||
|
||||
export interface RemoveFromCollectionRequest {
|
||||
collectionID: number;
|
||||
|
@ -118,11 +121,18 @@ export interface RemoveFromCollectionRequest {
|
|||
export interface CollectionMagicMetadataProps {
|
||||
visibility?: VISIBILITY_STATE;
|
||||
subType?: SUB_TYPE;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export type CollectionMagicMetadata =
|
||||
MagicMetadataCore<CollectionMagicMetadataProps>;
|
||||
|
||||
export interface CollectionShareeMetadataProps {
|
||||
visibility?: VISIBILITY_STATE;
|
||||
}
|
||||
export type CollectionShareeMagicMetadata =
|
||||
MagicMetadataCore<CollectionShareeMetadataProps>;
|
||||
|
||||
export interface CollectionPublicMagicMetadataProps {
|
||||
asc?: boolean;
|
||||
coverID?: number;
|
||||
|
@ -135,9 +145,11 @@ export interface CollectionSummary {
|
|||
id: number;
|
||||
name: string;
|
||||
type: CollectionSummaryType;
|
||||
coverFile: EnteFile;
|
||||
latestFile: EnteFile;
|
||||
fileCount: number;
|
||||
updationTime: number;
|
||||
order: number;
|
||||
}
|
||||
|
||||
export type CollectionSummaries = Map<number, CollectionSummary>;
|
||||
|
|
|
@ -163,7 +163,7 @@ export async function updateSubscription(
|
|||
|
||||
export async function cancelSubscription(
|
||||
setDialogMessage: SetDialogBoxAttributes,
|
||||
closePlanSelectorModal: () => null,
|
||||
closePlanSelectorModal: () => void,
|
||||
setLoading: SetLoading
|
||||
) {
|
||||
try {
|
||||
|
@ -188,7 +188,7 @@ export async function cancelSubscription(
|
|||
|
||||
export async function activateSubscription(
|
||||
setDialogMessage: SetDialogBoxAttributes,
|
||||
closePlanSelectorModal: () => null,
|
||||
closePlanSelectorModal: () => void,
|
||||
setLoading: SetLoading
|
||||
) {
|
||||
try {
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
unhideToCollection,
|
||||
updateCollectionMagicMetadata,
|
||||
updatePublicCollectionMagicMetadata,
|
||||
updateSharedCollectionMagicMetadata,
|
||||
} from 'services/collectionService';
|
||||
import { downloadFiles } from 'utils/file';
|
||||
import { getLocalFiles, getLocalHiddenFiles } from 'services/fileService';
|
||||
|
@ -34,7 +35,7 @@ import {
|
|||
} from 'constants/collection';
|
||||
import { getUnixTimeInMicroSecondsWithDelta } from 'utils/time';
|
||||
import { SUB_TYPE, VISIBILITY_STATE } from 'types/magicMetadata';
|
||||
import { IsArchived, updateMagicMetadata } from 'utils/magicMetadata';
|
||||
import { isArchivedCollection, updateMagicMetadata } from 'utils/magicMetadata';
|
||||
import { getAlbumsURL } from 'utils/common/apiUtil';
|
||||
import bs58 from 'bs58';
|
||||
import { t } from 'i18next';
|
||||
|
@ -166,12 +167,29 @@ export const changeCollectionVisibility = async (
|
|||
visibility,
|
||||
};
|
||||
|
||||
const updatedMagicMetadata = await updateMagicMetadata(
|
||||
updatedMagicMetadataProps,
|
||||
collection.magicMetadata,
|
||||
collection.key
|
||||
);
|
||||
await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
|
||||
const user: User = getData(LS_KEYS.USER);
|
||||
if (collection.owner.id === user.id) {
|
||||
const updatedMagicMetadata = await updateMagicMetadata(
|
||||
updatedMagicMetadataProps,
|
||||
collection.magicMetadata,
|
||||
collection.key
|
||||
);
|
||||
|
||||
await updateCollectionMagicMetadata(
|
||||
collection,
|
||||
updatedMagicMetadata
|
||||
);
|
||||
} else {
|
||||
const updatedMagicMetadata = await updateMagicMetadata(
|
||||
updatedMagicMetadataProps,
|
||||
collection.sharedMagicMetadata,
|
||||
collection.key
|
||||
);
|
||||
await updateSharedCollectionMagicMetadata(
|
||||
collection,
|
||||
updatedMagicMetadata
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e, 'change collection visibility failed');
|
||||
throw e;
|
||||
|
@ -198,6 +216,27 @@ export const changeCollectionSortOrder = async (
|
|||
collection,
|
||||
updatedPubMagicMetadata
|
||||
);
|
||||
} catch (e) {
|
||||
logError(e, 'change collection sort order failed');
|
||||
}
|
||||
};
|
||||
|
||||
export const changeCollectionOrder = async (
|
||||
collection: Collection,
|
||||
order: number
|
||||
) => {
|
||||
try {
|
||||
const updatedMagicMetadataProps: CollectionMagicMetadataProps = {
|
||||
order,
|
||||
};
|
||||
|
||||
const updatedMagicMetadata = await updateMagicMetadata(
|
||||
updatedMagicMetadataProps,
|
||||
collection.magicMetadata,
|
||||
collection.key
|
||||
);
|
||||
|
||||
await updateCollectionMagicMetadata(collection, updatedMagicMetadata);
|
||||
} catch (e) {
|
||||
logError(e, 'change collection order failed');
|
||||
}
|
||||
|
@ -226,7 +265,9 @@ export const changeCollectionSubType = async (
|
|||
|
||||
export const getArchivedCollections = (collections: Collection[]) => {
|
||||
return new Set<number>(
|
||||
collections.filter(IsArchived).map((collection) => collection.id)
|
||||
collections
|
||||
.filter(isArchivedCollection)
|
||||
.map((collection) => collection.id)
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -268,7 +309,8 @@ export const showDownloadQuickOption = (type: CollectionSummaryType) => {
|
|||
type === CollectionSummaryType.incomingShareCollaborator ||
|
||||
type === CollectionSummaryType.outgoingShare ||
|
||||
type === CollectionSummaryType.sharedOnlyViaLink ||
|
||||
type === CollectionSummaryType.archived
|
||||
type === CollectionSummaryType.archived ||
|
||||
type === CollectionSummaryType.pinned
|
||||
);
|
||||
};
|
||||
export const showShareQuickOption = (type: CollectionSummaryType) => {
|
||||
|
@ -279,7 +321,8 @@ export const showShareQuickOption = (type: CollectionSummaryType) => {
|
|||
type === CollectionSummaryType.sharedOnlyViaLink ||
|
||||
type === CollectionSummaryType.archived ||
|
||||
type === CollectionSummaryType.incomingShareViewer ||
|
||||
type === CollectionSummaryType.incomingShareCollaborator
|
||||
type === CollectionSummaryType.incomingShareCollaborator ||
|
||||
type === CollectionSummaryType.pinned
|
||||
);
|
||||
};
|
||||
export const shouldBeShownOnCollectionBar = (type: CollectionSummaryType) => {
|
||||
|
|
|
@ -28,7 +28,7 @@ import PublicCollectionDownloadManager from 'services/publicCollectionDownloadMa
|
|||
import heicConversionService from 'services/heicConversionService';
|
||||
import * as ffmpegService from 'services/ffmpeg/ffmpegService';
|
||||
import { VISIBILITY_STATE } from 'types/magicMetadata';
|
||||
import { IsArchived, updateMagicMetadata } from 'utils/magicMetadata';
|
||||
import { isArchivedFile, updateMagicMetadata } from 'utils/magicMetadata';
|
||||
|
||||
import { addLocalLog, addLogLine } from 'utils/logging';
|
||||
import { CustomError } from 'utils/error';
|
||||
|
@ -576,7 +576,7 @@ export const isImageOrVideo = (fileType: FILE_TYPE) =>
|
|||
[FILE_TYPE.IMAGE, FILE_TYPE.VIDEO].includes(fileType);
|
||||
|
||||
export const getArchivedFiles = (files: EnteFile[]) => {
|
||||
return files.filter(IsArchived).map((file) => file.id);
|
||||
return files.filter(isArchivedFile).map((file) => file.id);
|
||||
};
|
||||
|
||||
export const createTypedObjectURL = async (blob: Blob, fileName: string) => {
|
||||
|
@ -672,3 +672,22 @@ export function constructFileToCollectionMap(files: EnteFile[]) {
|
|||
});
|
||||
return fileToCollectionsMap;
|
||||
}
|
||||
|
||||
export const shouldShowAvatar = (file: EnteFile, user: User) => {
|
||||
if (!file || !user) {
|
||||
return false;
|
||||
}
|
||||
// is Shared file
|
||||
else if (file.ownerID !== user.id) {
|
||||
return true;
|
||||
}
|
||||
// is public collected file
|
||||
else if (
|
||||
file.ownerID === user.id &&
|
||||
file.pubMagicMetadata?.data?.uploaderName
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,17 +3,42 @@ import { EnteFile } from 'types/file';
|
|||
import { MagicMetadataCore, VISIBILITY_STATE } from 'types/magicMetadata';
|
||||
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
|
||||
|
||||
export function IsArchived(item: Collection | EnteFile) {
|
||||
export function isArchivedFile(item: EnteFile): boolean {
|
||||
if (!item || !item.magicMetadata || !item.magicMetadata.data) {
|
||||
return false;
|
||||
}
|
||||
return item.magicMetadata.data.visibility === VISIBILITY_STATE.ARCHIVED;
|
||||
}
|
||||
|
||||
export function isArchivedCollection(item: Collection): boolean {
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.magicMetadata && item.magicMetadata.data) {
|
||||
return item.magicMetadata.data.visibility === VISIBILITY_STATE.ARCHIVED;
|
||||
}
|
||||
|
||||
if (item.sharedMagicMetadata && item.sharedMagicMetadata.data) {
|
||||
return (
|
||||
item.sharedMagicMetadata.data.visibility ===
|
||||
VISIBILITY_STATE.ARCHIVED
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isPinnedCollection(item: Collection) {
|
||||
if (
|
||||
!item ||
|
||||
!item.magicMetadata ||
|
||||
!item.magicMetadata.data ||
|
||||
typeof item.magicMetadata.data === 'string' ||
|
||||
typeof item.magicMetadata.data.visibility === 'undefined'
|
||||
typeof item.magicMetadata.data.order === 'undefined'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return item.magicMetadata.data.visibility === VISIBILITY_STATE.ARCHIVED;
|
||||
return item.magicMetadata.data.order !== 0;
|
||||
}
|
||||
|
||||
export async function updateMagicMetadata<T>(
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
"jsx": "preserve",
|
||||
"jsxImportSource": "@emotion/react",
|
||||
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"strictBindCallApply": false,
|
||||
"strictNullChecks": false,
|
||||
"strictPropertyInitialization": false,
|
||||
"target": "es5",
|
||||
"useUnknownInCatchVariables": false
|
||||
},
|
||||
|
|
170
yarn.lock
170
yarn.lock
|
@ -674,13 +674,13 @@
|
|||
resolved "https://registry.npmjs.org/@tensorflow-models/coco-ssd/-/coco-ssd-2.2.2.tgz"
|
||||
integrity sha512-Jey2JscmKEValcFZH2ZLz14s8KPRmVtfJ0d0M3dPhvBp9dJiGNanVXr/pJAY5OS7emKj9uSciGhdkHWXY9Hovw==
|
||||
|
||||
"@tensorflow/tfjs-backend-cpu@3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.11.0.tgz"
|
||||
integrity sha512-ShLkrZ4/rmhZwzGKenMFDfQnaEbyZgWA5F8JRa52Iob/vptlZeuOzjq87CZKmZMUmDswR9A2kjzovT/H1bJdWQ==
|
||||
"@tensorflow/tfjs-backend-cpu@4.8.0":
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.8.0.tgz#6281ab0a93400f2b5c7b2efa07b0befb895a0260"
|
||||
integrity sha512-kT4WZeM4cuuZ+dSCMatrC9YiqV4dxpFzjxKOKwdS41gdg5QKQGW7caScCe55thO/Xpp7VOJXncDYeaMH7GcxCA==
|
||||
dependencies:
|
||||
"@types/seedrandom" "2.4.27"
|
||||
seedrandom "2.4.3"
|
||||
"@types/seedrandom" "^2.4.28"
|
||||
seedrandom "^3.0.5"
|
||||
|
||||
"@tensorflow/tfjs-backend-cpu@^3.13.0":
|
||||
version "3.13.0"
|
||||
|
@ -690,17 +690,16 @@
|
|||
"@types/seedrandom" "2.4.27"
|
||||
seedrandom "2.4.3"
|
||||
|
||||
"@tensorflow/tfjs-backend-webgl@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.11.0.tgz"
|
||||
integrity sha512-rNnc/dZ7LIl9O/Pn9W24I1h8kgpJ+XvG8NrdNSfIoWPCW4fvPSlU7B3yMeZXvRneny+z+T3xRs96nWyU2mZBJw==
|
||||
"@tensorflow/tfjs-backend-webgl@^4.8.0":
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.8.0.tgz#b361c28660aee3d33554b0b50032a8d78bcd268c"
|
||||
integrity sha512-iAJzQbndBtarV+OWk9Ukur5U0Xk/4t7j7O5WhPQO/q9yuRyWjAT6MPaCEW/+Ew4XC8yJGuvlfL0Oqi1X0drvfA==
|
||||
dependencies:
|
||||
"@tensorflow/tfjs-backend-cpu" "3.11.0"
|
||||
"@tensorflow/tfjs-backend-cpu" "4.8.0"
|
||||
"@types/offscreencanvas" "~2019.3.0"
|
||||
"@types/seedrandom" "2.4.27"
|
||||
"@types/seedrandom" "^2.4.28"
|
||||
"@types/webgl-ext" "0.0.30"
|
||||
"@types/webgl2" "0.0.6"
|
||||
seedrandom "2.4.3"
|
||||
seedrandom "^3.0.5"
|
||||
|
||||
"@tensorflow/tfjs-converter@^3.11.0":
|
||||
version "3.11.0"
|
||||
|
@ -752,13 +751,6 @@
|
|||
resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz"
|
||||
integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==
|
||||
|
||||
"@types/http-proxy@^1.17.5":
|
||||
version "1.17.9"
|
||||
resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz"
|
||||
integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/invariant@^2.2.33":
|
||||
version "2.2.35"
|
||||
resolved "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz"
|
||||
|
@ -803,16 +795,16 @@
|
|||
resolved "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz"
|
||||
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
|
||||
|
||||
"@types/node@*", "@types/node@^14.6.4":
|
||||
version "14.17.15"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz"
|
||||
integrity sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA==
|
||||
|
||||
"@types/node@11.11.6":
|
||||
version "11.11.6"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz"
|
||||
integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==
|
||||
|
||||
"@types/node@^14.6.4":
|
||||
version "14.17.15"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz"
|
||||
integrity sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA==
|
||||
|
||||
"@types/offscreencanvas@~2019.3.0":
|
||||
version "2019.3.0"
|
||||
resolved "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz"
|
||||
|
@ -931,6 +923,11 @@
|
|||
resolved "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz"
|
||||
integrity sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE=
|
||||
|
||||
"@types/seedrandom@^2.4.28":
|
||||
version "2.4.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.30.tgz#d2efe425869b84163c2d56e779dddadb9372cbfa"
|
||||
integrity sha512-AnxLHewubLVzoF/A4qdxBGHCKifw8cY32iro3DQX9TPcetE95zBeVt3jnsvtvAUf1vwzMfwzp4t/L2yqPlnjkQ==
|
||||
|
||||
"@types/semver@^7.3.12":
|
||||
version "7.3.13"
|
||||
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz"
|
||||
|
@ -951,11 +948,6 @@
|
|||
resolved "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz"
|
||||
integrity sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==
|
||||
|
||||
"@types/webgl2@0.0.6":
|
||||
version "0.0.6"
|
||||
resolved "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.6.tgz"
|
||||
integrity sha512-50GQhDVTq/herLMiqSQkdtRu+d5q/cWHn4VvKJtrj4DJAjo1MNkWYa2MA41BaBO1q1HgsUjuQvEOk0QHvlnAaQ==
|
||||
|
||||
"@types/wicg-file-system-access@^2020.9.5":
|
||||
version "2020.9.5"
|
||||
resolved "https://registry.npmjs.org/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.5.tgz"
|
||||
|
@ -1302,10 +1294,10 @@ bip39@^3.0.4:
|
|||
pbkdf2 "^3.0.9"
|
||||
randombytes "^2.0.1"
|
||||
|
||||
blazeface-back@^0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.npmjs.org/blazeface-back/-/blazeface-back-0.0.8.tgz"
|
||||
integrity sha512-7eYoSPJ9JvV2cHp+qwW+YNvrdTDFzMGnSGCGR24Lx6OluwPa+qX4NqNrBv31ukw2Ne/FkvFHhZuUDpxpowr+Bg==
|
||||
blazeface-back@^0.0.9:
|
||||
version "0.0.9"
|
||||
resolved "https://registry.yarnpkg.com/blazeface-back/-/blazeface-back-0.0.9.tgz#a8a26a0022950eb21136693f2fca3c52315ad2a4"
|
||||
integrity sha512-t0i5V117j074d7d7mlLaRq9n/bYchXcSEgpWVbGGloV68A6Jn22t4SNoEC3t+MOsU8H+eXoDv2/6+JsqActM1g==
|
||||
|
||||
bootstrap@^4.5.2:
|
||||
version "4.6.0"
|
||||
|
@ -2058,7 +2050,7 @@ esutils@^2.0.2:
|
|||
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
eventemitter3@^4.0.0, eventemitter3@^4.0.7:
|
||||
eventemitter3@^4.0.7:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
@ -2184,7 +2176,7 @@ fn-name@~3.0.0:
|
|||
resolved "https://registry.npmjs.org/fn-name/-/fn-name-3.0.0.tgz"
|
||||
integrity sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA==
|
||||
|
||||
follow-redirects@^1.0.0, follow-redirects@^1.14.0:
|
||||
follow-redirects@^1.14.0:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz"
|
||||
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
|
||||
|
@ -2491,26 +2483,6 @@ html-tokenize@^2.0.0:
|
|||
readable-stream "~1.0.27-1"
|
||||
through2 "~0.4.1"
|
||||
|
||||
http-proxy-middleware@^1.0.5:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz"
|
||||
integrity sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==
|
||||
dependencies:
|
||||
"@types/http-proxy" "^1.17.5"
|
||||
http-proxy "^1.18.1"
|
||||
is-glob "^4.0.1"
|
||||
is-plain-obj "^3.0.0"
|
||||
micromatch "^4.0.2"
|
||||
|
||||
http-proxy@^1.18.1:
|
||||
version "1.18.1"
|
||||
resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz"
|
||||
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.0"
|
||||
follow-redirects "^1.0.0"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
https-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz"
|
||||
|
@ -2615,10 +2587,10 @@ invariant@^2.2.4:
|
|||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
is-any-array@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/is-any-array/-/is-any-array-1.0.1.tgz"
|
||||
integrity sha512-m+FSiaONxBt2W0h9XOUngMBu/WW8uzAKbSk4Ty2aeCcQJ+muBqENexvxUHtDpX65fk5AMCROxqgNX0sSAHstcw==
|
||||
is-any-array@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-2.0.1.tgz#9233242a9c098220290aa2ec28f82ca7fa79899e"
|
||||
integrity sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==
|
||||
|
||||
is-arguments@^1.1.1:
|
||||
version "1.1.1"
|
||||
|
@ -2735,11 +2707,6 @@ is-path-inside@^3.0.3:
|
|||
resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
|
||||
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
|
||||
|
||||
is-plain-obj@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz"
|
||||
integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
|
||||
|
||||
is-reference@1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz"
|
||||
|
@ -3142,7 +3109,7 @@ merge2@^1.3.0, merge2@^1.4.1:
|
|||
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
micromatch@^4.0.2, micromatch@^4.0.4:
|
||||
micromatch@^4.0.4:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
|
||||
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
|
||||
|
@ -3181,35 +3148,36 @@ mkdirp@^0.5.5:
|
|||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ml-array-max@^1.2.3:
|
||||
ml-array-max@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/ml-array-max/-/ml-array-max-1.2.4.tgz#2373e2b7e51c8807e456cc0ef364c5863713623b"
|
||||
integrity sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==
|
||||
dependencies:
|
||||
is-any-array "^2.0.0"
|
||||
|
||||
ml-array-min@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.3.tgz"
|
||||
integrity sha512-49YwnLlAf4/E/VyezUz+SNfSBhPE8JTahxRPuyM9S9Uv+ft5x0C8A4trtkDgrttMxoxbhudTA1yg8zgJZaYtpA==
|
||||
resolved "https://registry.yarnpkg.com/ml-array-min/-/ml-array-min-1.2.3.tgz#662f027c400105816b849cc3cd786915d0801495"
|
||||
integrity sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==
|
||||
dependencies:
|
||||
is-any-array "^1.0.0"
|
||||
is-any-array "^2.0.0"
|
||||
|
||||
ml-array-min@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.2.tgz"
|
||||
integrity sha512-yidQcOHFaGEuVr6FcwAn+QvKXJv1Lxel5fyKrO+aXGJGp97Mt+p8r21WYtikS/PTVbxdSrliQ0UK4wSHYHHgzQ==
|
||||
ml-array-rescale@^1.3.7:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz#c4d129320d113a732e62dd963dc1695bba9a5340"
|
||||
integrity sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==
|
||||
dependencies:
|
||||
is-any-array "^1.0.0"
|
||||
is-any-array "^2.0.0"
|
||||
ml-array-max "^1.2.4"
|
||||
ml-array-min "^1.2.3"
|
||||
|
||||
ml-array-rescale@^1.3.6:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.6.tgz"
|
||||
integrity sha512-Lzj45T6hvHNdht924JQhHzInIK+ilC55zn98uraZUvLBkOWOJGOztEkRM0xyzAjWvVuhpszLADOnoVwfBSnj8w==
|
||||
ml-matrix@^6.10.4:
|
||||
version "6.10.4"
|
||||
resolved "https://registry.yarnpkg.com/ml-matrix/-/ml-matrix-6.10.4.tgz#babee344b20062d9c123aa801c2e5d0d0c7477f6"
|
||||
integrity sha512-rUyEhfNPzqFsltYwvjNeYQXlYEaVea3KgzcJKJteQUj2WVAGFx9fLNRjtMR9mg2B6bd5buxlmkZmxM4hmO+SKg==
|
||||
dependencies:
|
||||
is-any-array "^1.0.0"
|
||||
ml-array-max "^1.2.3"
|
||||
ml-array-min "^1.2.2"
|
||||
|
||||
ml-matrix@^6.8.2:
|
||||
version "6.8.2"
|
||||
resolved "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.8.2.tgz"
|
||||
integrity sha512-5o2gVLFyieDSgsStEU5mqty4MZqfeytYA/gJqBSw5/Xuob0X2UrFX/k7FDh+YAwjzG/1l8nYa0oDaJ0sGs/RlA==
|
||||
dependencies:
|
||||
ml-array-rescale "^1.3.6"
|
||||
is-any-array "^2.0.0"
|
||||
ml-array-rescale "^1.3.7"
|
||||
|
||||
mrmime@^1.0.0:
|
||||
version "1.0.1"
|
||||
|
@ -3852,11 +3820,6 @@ regexp.prototype.flags@^1.4.3:
|
|||
define-properties "^1.1.3"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
requires-port@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
|
||||
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
|
||||
|
@ -3977,20 +3940,25 @@ seedrandom@2.4.3:
|
|||
resolved "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz"
|
||||
integrity sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=
|
||||
|
||||
seedrandom@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
|
||||
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
|
||||
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
|
||||
|
||||
semver@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
version "6.3.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||
|
||||
semver@^7.3.7:
|
||||
version "7.3.8"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz"
|
||||
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
|
||||
version "7.5.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
|
||||
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
|
|
Loading…
Reference in a new issue