added Archive logic

This commit is contained in:
abhinav-grd 2021-09-21 16:08:03 +05:30
parent 3021fd4a43
commit ea6a2165e2
3 changed files with 81 additions and 3 deletions

View file

@ -8,6 +8,7 @@ import CrossIcon from 'components/icons/CrossIcon';
import AddIcon from 'components/icons/AddIcon';
import { IconButton } from 'components/Container';
import constants from 'utils/strings/constants';
import Archive from 'components/icons/archive';
interface Props {
addToCollectionHelper: (collectionName, collection) => void;
@ -17,6 +18,7 @@ interface Props {
deleteFileHelper: () => void;
count: number;
clearSelection: () => void;
archiveFilesHelper: () => void;
}
const SelectionBar = styled(Navbar)`
@ -41,6 +43,7 @@ const SelectedFileOptions = ({
deleteFileHelper,
count,
clearSelection,
archiveFilesHelper,
}: Props) => {
const addToCollection = () =>
setCollectionSelectorAttributes({
@ -72,6 +75,9 @@ const SelectedFileOptions = ({
{count} {constants.SELECTED}
</div>
</SelectionContainer>
<IconButton onClick={archiveFilesHelper}>
<Archive />
</IconButton>
<IconButton onClick={addToCollection}>
<AddIcon />
</IconButton>

View file

@ -12,6 +12,7 @@ import {
getLocalFiles,
deleteFiles,
syncFiles,
updateMagicMetadata,
} from 'services/fileService';
import styled from 'styled-components';
import LoadingBar from 'react-top-loading-bar';
@ -44,7 +45,11 @@ import { useDropzone } from 'react-dropzone';
import EnteSpinner from 'components/EnteSpinner';
import { LoadingOverlay } from 'components/LoadingOverlay';
import PhotoFrame from 'components/PhotoFrame';
import { getSelectedFileIds, sortFilesIntoCollections } from 'utils/file';
import {
archiveFiles,
getSelectedFileIds,
sortFilesIntoCollections,
} from 'utils/file';
import { addFilesToCollection } from 'utils/collection';
import SearchBar, { DateValue } from 'components/SearchBar';
import { Bbox } from 'services/searchService';
@ -314,6 +319,36 @@ export default function Gallery() {
});
}
};
const archiveFilesHelper = async () => {
loadingBar.current?.continuousStart();
try {
const archivedFiles = await archiveFiles(files, selected);
await updateMagicMetadata(archivedFiles);
setDeleted([...deleted, ...archivedFiles.map((file) => file.id)]);
} catch (e) {
console.log(e);
switch (e.status?.toString()) {
case ServerErrorCodes.FORBIDDEN:
setDialogMessage({
title: constants.ERROR,
staticBackdrop: true,
close: { variant: 'danger' },
content: constants.NOT_FILE_OWNER,
});
return;
}
setDialogMessage({
title: constants.ERROR,
staticBackdrop: true,
close: { variant: 'danger' },
content: constants.UNKNOWN_ERROR,
});
} finally {
clearSelection();
syncWithRemote();
loadingBar.current.complete();
}
};
const showCreateCollectionModal = () =>
setCollectionNamerAttributes({
@ -488,6 +523,7 @@ export default function Gallery() {
selected.collectionID === activeCollection && (
<SelectedFileOptions
addToCollectionHelper={addToCollectionHelper}
archiveFilesHelper={archiveFilesHelper}
showCreateCollectionModal={
showCreateCollectionModal
}

View file

@ -1,13 +1,18 @@
import { SelectedState } from 'pages/gallery';
import { Collection } from 'services/collectionService';
import {
File,
fileAttribute,
FILE_TYPE,
MagicMetadataProps,
NEW_MAGIC_METADATA,
VISIBILITY_STATE,
} from 'services/fileService';
import { decodeMotionPhoto } from 'services/motionPhotoService';
import { getMimeTypeFromBlob } from 'services/upload/readFileService';
import { EncryptionResult } from 'services/upload/uploadService';
import CryptoWorker from 'utils/crypto';
import { logError } from 'utils/sentry';
export const TYPE_HEIC = 'heic';
export const TYPE_HEIF = 'heif';
@ -47,7 +52,7 @@ export function sortFilesIntoCollections(files: File[]) {
return collectionWiseFiles;
}
export function getSelectedFileIds(selectedFiles) {
export function getSelectedFileIds(selectedFiles: SelectedState) {
const filesIDs: number[] = [];
for (const [key, val] of Object.entries(selectedFiles)) {
if (typeof val === 'boolean' && val) {
@ -56,7 +61,10 @@ export function getSelectedFileIds(selectedFiles) {
}
return filesIDs;
}
export function getSelectedFiles(selectedFiles, files: File[]): File[] {
export function getSelectedFiles(
selectedFiles: SelectedState,
files: File[]
): File[] {
const filesIDs = new Set(getSelectedFileIds(selectedFiles));
const filesToDelete: File[] = [];
for (const file of files) {
@ -213,3 +221,31 @@ export function fileIsArchived(file: File) {
}
return file.magicMetadata.data.visibility === VISIBILITY_STATE.ARCHIVED;
}
export async function archiveFiles(files: File[], selected: SelectedState) {
const worker = await new CryptoWorker();
const selectedFiles = getSelectedFiles(selected, files);
for (const file of selectedFiles) {
if (!file.magicMetadata) {
file.magicMetadata = NEW_MAGIC_METADATA;
}
if (typeof file.magicMetadata.data === 'string') {
logError(Error('magic metadata not decrypted'), '');
return;
}
const updatedMagicMetadataProps: MagicMetadataProps = {
...file.magicMetadata.data,
visibility: VISIBILITY_STATE.ARCHIVED,
};
const encryptedMagicMetadata: EncryptionResult =
await worker.encryptMetadata(updatedMagicMetadataProps);
file.magicMetadata = {
version: file.magicMetadata.version + 1,
count: Object.keys(updatedMagicMetadataProps).length,
data: encryptedMagicMetadata.file
.encryptedData as unknown as string,
header: encryptedMagicMetadata.file.decryptionHeader,
};
}
return selectedFiles;
}