From 799f85b089a52e3ac2d18135e4c6d71ad12d8bab Mon Sep 17 00:00:00 2001 From: Abhinav Date: Mon, 15 Nov 2021 13:56:33 +0530 Subject: [PATCH 01/69] fix process queue processed from the end --- src/services/upload/queueProcessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/upload/queueProcessor.ts b/src/services/upload/queueProcessor.ts index 6d9e86fc6..8deddf66f 100644 --- a/src/services/upload/queueProcessor.ts +++ b/src/services/upload/queueProcessor.ts @@ -53,7 +53,7 @@ export default class QueueProcessor { public async processQueue() { while (this.requestQueue.length > 0) { - const queueItem = this.requestQueue.pop(); + const queueItem = this.requestQueue.shift(); let response = null; if (queueItem.isCanceled.status) { From e925663dbad22507135db37f2f1659a0a8a3ddeb Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 7 Dec 2021 13:19:10 +0530 Subject: [PATCH 02/69] make internal function private --- src/services/upload/queueProcessor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/upload/queueProcessor.ts b/src/services/upload/queueProcessor.ts index 8deddf66f..5c2c8d8a2 100644 --- a/src/services/upload/queueProcessor.ts +++ b/src/services/upload/queueProcessor.ts @@ -43,7 +43,7 @@ export default class QueueProcessor { return { promise, canceller }; } - async pollQueue() { + private async pollQueue() { if (this.requestInProcessing < this.maxParallelProcesses) { this.requestInProcessing++; await this.processQueue(); @@ -51,7 +51,7 @@ export default class QueueProcessor { } } - public async processQueue() { + private async processQueue() { while (this.requestQueue.length > 0) { const queueItem = this.requestQueue.shift(); let response = null; From d5199acc43d87de2af1bb79dfe41608fc01b6e42 Mon Sep 17 00:00:00 2001 From: Shailesh Pandit Date: Wed, 8 Dec 2021 11:53:34 +0530 Subject: [PATCH 03/69] Extract common types in upload service to upload types Required for not including code required for upload service in other parts just requiring common types e.g. ffmpegService is included in machine learning web worker while including downloadManager service --- src/services/fileService.ts | 6 +--- src/services/migrateThumbnailService.ts | 3 +- src/services/upload/encryptionService.ts | 3 +- src/services/upload/metadataService.ts | 2 +- src/services/upload/multiPartUploadService.ts | 6 ++-- src/services/upload/readFileService.ts | 2 +- src/services/upload/uploadService.ts | 34 +++++-------------- src/services/upload/uploader.ts | 2 +- src/types/upload/index.ts | 27 +++++++++++++++ src/utils/export/index.ts | 2 +- src/utils/upload/index.ts | 2 +- 11 files changed, 47 insertions(+), 42 deletions(-) create mode 100644 src/types/upload/index.ts diff --git a/src/services/fileService.ts b/src/services/fileService.ts index 0c0b2861d..af794e892 100644 --- a/src/services/fileService.ts +++ b/src/services/fileService.ts @@ -2,11 +2,7 @@ import { getEndpoint } from 'utils/common/apiUtil'; import localForage from 'utils/storage/localForage'; import { getToken } from 'utils/common/key'; -import { - DataStream, - EncryptionResult, - MetadataObject, -} from './upload/uploadService'; +import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; import { Collection } from './collectionService'; import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; diff --git a/src/services/migrateThumbnailService.ts b/src/services/migrateThumbnailService.ts index 4245a4538..07bec18cd 100644 --- a/src/services/migrateThumbnailService.ts +++ b/src/services/migrateThumbnailService.ts @@ -7,10 +7,11 @@ import { getEndpoint } from 'utils/common/apiUtil'; import HTTPService from 'services/HTTPService'; import CryptoWorker from 'utils/crypto'; import uploadHttpClient from 'services/upload/uploadHttpClient'; -import { EncryptionResult, UploadURL } from 'services/upload/uploadService'; +import { UploadURL } from 'services/upload/uploadService'; import { SetProgressTracker } from 'components/FixLargeThumbnail'; import { getFileType } from './upload/readFileService'; import { getLocalTrash, getTrashedFiles } from './trashService'; +import { EncryptionResult } from 'types/upload'; const ENDPOINT = getEndpoint(); const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB diff --git a/src/services/upload/encryptionService.ts b/src/services/upload/encryptionService.ts index 3ea654cf0..512bff778 100644 --- a/src/services/upload/encryptionService.ts +++ b/src/services/upload/encryptionService.ts @@ -1,4 +1,5 @@ -import { DataStream, EncryptionResult, isDataStream } from './uploadService'; +import { DataStream, EncryptionResult } from 'types/upload'; +import { isDataStream } from './uploadService'; async function encryptFileStream(worker, fileData: DataStream) { const { stream, chunkCount } = fileData; diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index 305b0b202..f0e045e70 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -2,7 +2,7 @@ import { FILE_TYPE } from 'services/fileService'; import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { FileTypeInfo } from './readFileService'; -import { MetadataObject } from './uploadService'; +import { MetadataObject } from 'types/upload'; export interface Location { latitude: number; diff --git a/src/services/upload/multiPartUploadService.ts b/src/services/upload/multiPartUploadService.ts index be082ba7a..020b50c50 100644 --- a/src/services/upload/multiPartUploadService.ts +++ b/src/services/upload/multiPartUploadService.ts @@ -1,11 +1,9 @@ -import { - FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART, - DataStream, -} from './uploadService'; +import { FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART } from './uploadService'; import UploadHttpClient from './uploadHttpClient'; import * as convert from 'xml-js'; import UIService, { RANDOM_PERCENTAGE_PROGRESS_FOR_PUT } from './uiService'; import { CustomError } from 'utils/common/errorUtil'; +import { DataStream } from 'types/upload'; interface PartEtag { PartNumber: number; diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 3342fd572..7d85b2b5f 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -3,7 +3,7 @@ import { FORMAT_MISSED_BY_FILE_TYPE_LIB, } from 'services/fileService'; import { logError } from 'utils/sentry'; -import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from './uploadService'; +import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from 'types/upload'; import FileType from 'file-type/browser'; import { CustomError } from 'utils/common/errorUtil'; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index a14682772..b45ec71d2 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -1,4 +1,4 @@ -import { fileAttribute, FILE_TYPE } from '../fileService'; +import { fileAttribute } from '../fileService'; import { Collection } from '../collectionService'; import { logError } from 'utils/sentry'; import UploadHttpClient from './uploadHttpClient'; @@ -14,16 +14,17 @@ import { FileTypeInfo, } from './readFileService'; import { encryptFiledata } from './encryptionService'; -import { ENCRYPTION_CHUNK_SIZE } from 'types'; import { uploadStreamUsingMultipart } from './multiPartUploadService'; import UIService from './uiService'; import { handleUploadError } from 'utils/common/errorUtil'; import { MetadataMap } from './uploadManager'; - -// this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part. -export const MULTIPART_PART_SIZE = 20 * 1024 * 1024; - -export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE; +import { + DataStream, + EncryptionResult, + FILE_READER_CHUNK_SIZE, + MetadataObject, + MULTIPART_PART_SIZE, +} from 'types/upload'; export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor( MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE @@ -34,34 +35,15 @@ export interface UploadURL { objectKey: string; } -export interface DataStream { - stream: ReadableStream; - chunkCount: number; -} - export function isDataStream(object: any): object is DataStream { return 'stream' in object; } -export interface EncryptionResult { - file: fileAttribute; - key: string; -} export interface B64EncryptionResult { encryptedData: string; key: string; nonce: string; } -export interface MetadataObject { - title: string; - creationTime: number; - modificationTime: number; - latitude: number; - longitude: number; - fileType: FILE_TYPE; - hasStaticThumbnail?: boolean; -} - export interface FileInMemory { filedata: Uint8Array | DataStream; thumbnail: Uint8Array; diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index aef8bd962..7e9204309 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -12,11 +12,11 @@ import UploadService, { EncryptedFile, FileInMemory, FileWithMetadata, - MetadataObject, UploadFile, } from './uploadService'; import uploadService from './uploadService'; import { FileTypeInfo, getFileType } from './readFileService'; +import { MetadataObject } from 'types/upload'; const TwoSecondInMillSeconds = 2000; const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts new file mode 100644 index 000000000..a91a8ad3d --- /dev/null +++ b/src/types/upload/index.ts @@ -0,0 +1,27 @@ +import { fileAttribute, FILE_TYPE } from 'services/fileService'; +import { ENCRYPTION_CHUNK_SIZE } from 'types'; + +// this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part. +export const MULTIPART_PART_SIZE = 20 * 1024 * 1024; + +export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE; + +export interface DataStream { + stream: ReadableStream; + chunkCount: number; +} + +export interface EncryptionResult { + file: fileAttribute; + key: string; +} + +export interface MetadataObject { + title: string; + creationTime: number; + modificationTime: number; + latitude: number; + longitude: number; + fileType: FILE_TYPE; + hasStaticThumbnail?: boolean; +} diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index 1aca1446b..c8f7448bc 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -1,6 +1,6 @@ import { ExportRecord } from 'services/exportService'; import { File } from 'services/fileService'; -import { MetadataObject } from 'services/upload/uploadService'; +import { MetadataObject } from 'types/upload'; import { formatDate } from 'utils/file'; export const getExportRecordFileUID = (file: File) => diff --git a/src/utils/upload/index.ts b/src/utils/upload/index.ts index ded536051..bbc15c8b6 100644 --- a/src/utils/upload/index.ts +++ b/src/utils/upload/index.ts @@ -1,5 +1,5 @@ import { FileWithCollection } from 'services/upload/uploadManager'; -import { MetadataObject } from 'services/upload/uploadService'; +import { MetadataObject } from 'types/upload'; import { File } from 'services/fileService'; const TYPE_JSON = 'json'; From 1a1c4d145ca12d7fba992c4e0f7160c6965669f6 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 14:05:41 +0530 Subject: [PATCH 04/69] created types for billing and renamed billingUtil to billing/index --- src/components/Sidebar.tsx | 4 +-- src/components/pages/gallery/PlanSelector.tsx | 5 +-- src/pages/gallery/index.tsx | 2 +- src/services/billingService.ts | 32 ++----------------- src/services/exportService.ts | 2 +- src/services/upload/thumbnailService.ts | 2 +- src/services/userService.ts | 2 +- src/types/billing/index.ts | 29 +++++++++++++++++ .../{billingUtil.ts => billing/index.ts} | 13 +++----- 9 files changed, 45 insertions(+), 46 deletions(-) create mode 100644 src/types/billing/index.ts rename src/utils/{billingUtil.ts => billing/index.ts} (97%) diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 8d7358048..ea04f8887 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -13,7 +13,7 @@ import { isSubscriptionCancelled, isSubscribed, convertToHumanReadable, -} from 'utils/billingUtil'; +} from 'utils/billing'; import isElectron from 'is-electron'; import { Collection } from 'services/collectionService'; @@ -30,7 +30,7 @@ import ExportModal from './ExportModal'; import { GalleryContext, SetLoading } from 'pages/gallery'; import InProgressIcon from './icons/InProgressIcon'; import exportService from 'services/exportService'; -import { Subscription } from 'services/billingService'; +import { Subscription } from 'types/billing'; import { PAGES } from 'types'; import { ARCHIVE_SECTION, diff --git a/src/components/pages/gallery/PlanSelector.tsx b/src/components/pages/gallery/PlanSelector.tsx index 4894b44f4..0c8d15cf7 100644 --- a/src/components/pages/gallery/PlanSelector.tsx +++ b/src/components/pages/gallery/PlanSelector.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { Form, Modal, Button } from 'react-bootstrap'; import constants from 'utils/strings/constants'; import styled from 'styled-components'; -import billingService, { Plan, Subscription } from 'services/billingService'; +import { Plan, Subscription } from 'types/billing'; import { convertBytesToGBs, getUserSubscription, @@ -16,12 +16,13 @@ import { hasPaidSubscription, isOnFreePlan, planForSubscription, -} from 'utils/billingUtil'; +} from 'utils/billing'; import { reverseString } from 'utils/common'; import { SetDialogMessage } from 'components/MessageDialog'; import ArrowEast from 'components/icons/ArrowEast'; import LinkButton from './LinkButton'; import { DeadCenter, SetLoading } from 'pages/gallery'; +import billingService from 'services/billingService'; export const PlanIcon = styled.div<{ selected: boolean }>` border-radius: 20px; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index df8bf8982..ffea9f47f 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -31,7 +31,7 @@ import { } from 'services/collectionService'; import constants from 'utils/strings/constants'; import billingService from 'services/billingService'; -import { checkSubscriptionPurchase } from 'utils/billingUtil'; +import { checkSubscriptionPurchase } from 'utils/billing'; import FullScreenDropZone from 'components/FullScreenDropZone'; import Sidebar from 'components/Sidebar'; diff --git a/src/services/billingService.ts b/src/services/billingService.ts index 7c09d5fba..d73df6441 100644 --- a/src/services/billingService.ts +++ b/src/services/billingService.ts @@ -1,42 +1,14 @@ import { getEndpoint, getPaymentsUrl } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { setData, LS_KEYS } from 'utils/storage/localStorage'; -import { convertToHumanReadable } from 'utils/billingUtil'; +import { convertToHumanReadable } from 'utils/billing'; import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; import { getPaymentToken } from './userService'; +import { Plan, PaymentActionType, Subscription } from 'types/billing'; const ENDPOINT = getEndpoint(); -enum PaymentActionType { - Buy = 'buy', - Update = 'update', -} -export interface Subscription { - id: number; - userID: number; - productID: string; - storage: number; - originalTransactionID: string; - expiryTime: number; - paymentProvider: string; - attributes: { - isCancelled: boolean; - }; - price: string; - period: string; -} -export interface Plan { - id: string; - androidID: string; - iosID: string; - storage: number; - price: string; - period: string; - stripeID: string; -} - -export const FREE_PLAN = 'free'; class billingService { public async getPlans(): Promise { try { diff --git a/src/services/exportService.ts b/src/services/exportService.ts index e6e8a1425..f210b23ec 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -40,7 +40,7 @@ import { } from 'utils/file'; import { User } from './userService'; import { updateFileCreationDateInEXIF } from './upload/exifService'; -import { MetadataObject } from './upload/uploadService'; +import { MetadataObject } from 'types/upload'; import QueueProcessor from './upload/queueProcessor'; export type CollectionIDPathMap = Map; diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 8872150df..0bb4fd474 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -3,7 +3,7 @@ import { CustomError, errorWithContext } from 'utils/common/errorUtil'; import { logError } from 'utils/sentry'; import { BLACK_THUMBNAIL_BASE64 } from '../../../public/images/black-thumbnail-b64'; import FFmpegService from 'services/ffmpegService'; -import { convertToHumanReadable } from 'utils/billingUtil'; +import { convertToHumanReadable } from 'utils/billing'; import { isFileHEIC } from 'utils/file'; import { FileTypeInfo } from './readFileService'; diff --git a/src/services/userService.ts b/src/services/userService.ts index 5960b076f..02d8a6482 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -8,7 +8,7 @@ import { getToken } from 'utils/common/key'; import HTTPService from './HTTPService'; import { B64EncryptionResult } from 'utils/crypto'; import { logError } from 'utils/sentry'; -import { Subscription } from './billingService'; +import { Subscription } from 'types/billing'; export interface UpdatedKey { kekSalt: string; diff --git a/src/types/billing/index.ts b/src/types/billing/index.ts new file mode 100644 index 000000000..464239ac8 --- /dev/null +++ b/src/types/billing/index.ts @@ -0,0 +1,29 @@ +export enum PaymentActionType { + Buy = 'buy', + Update = 'update', +} +export const FREE_PLAN = 'free'; + +export interface Subscription { + id: number; + userID: number; + productID: string; + storage: number; + originalTransactionID: string; + expiryTime: number; + paymentProvider: string; + attributes: { + isCancelled: boolean; + }; + price: string; + period: string; +} +export interface Plan { + id: string; + androidID: string; + iosID: string; + storage: number; + price: string; + period: string; + stripeID: string; +} diff --git a/src/utils/billingUtil.ts b/src/utils/billing/index.ts similarity index 97% rename from src/utils/billingUtil.ts rename to src/utils/billing/index.ts index 43e1e1924..3ea369fe0 100644 --- a/src/utils/billingUtil.ts +++ b/src/utils/billing/index.ts @@ -1,15 +1,12 @@ import constants from 'utils/strings/constants'; -import billingService, { - FREE_PLAN, - Plan, - Subscription, -} from 'services/billingService'; +import billingService from 'services/billingService'; +import { FREE_PLAN, Plan, Subscription } from 'types/billing'; import { NextRouter } from 'next/router'; import { SetDialogMessage } from 'components/MessageDialog'; import { SetLoading } from 'pages/gallery'; -import { getData, LS_KEYS } from './storage/localStorage'; -import { CustomError } from './common/errorUtil'; -import { logError } from './sentry'; +import { getData, LS_KEYS } from '../storage/localStorage'; +import { CustomError } from '../common/errorUtil'; +import { logError } from '../sentry'; const STRIPE = 'stripe'; From 2aba5cb0580e187b22ab1f2b989439cae6a6b0fe Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 14:17:38 +0530 Subject: [PATCH 05/69] moved collection related types to types/collection --- src/components/CollectionShare.tsx | 7 +- src/components/SearchBar.tsx | 2 +- src/components/Sidebar.tsx | 2 +- .../pages/gallery/CollectionOptions.tsx | 7 +- .../pages/gallery/CollectionSelector.tsx | 11 +-- .../pages/gallery/CollectionSort.tsx | 2 +- .../pages/gallery/CollectionSortOptions.tsx | 2 +- src/components/pages/gallery/Collections.tsx | 14 ++-- .../pages/gallery/SelectedFileOptions.tsx | 2 +- src/components/pages/gallery/Upload.tsx | 7 +- src/pages/gallery/index.tsx | 8 +- src/services/collectionService.ts | 84 ++++--------------- src/services/exportService.ts | 2 +- src/services/fileService.ts | 2 +- src/services/searchService.ts | 2 +- src/services/trashService.ts | 3 +- src/services/upload/uploadManager.ts | 3 +- src/services/upload/uploadService.ts | 2 +- src/types/collection/index.ts | 66 +++++++++++++++ src/utils/collection/index.ts | 3 +- src/utils/export/index.ts | 2 +- src/utils/file/index.ts | 2 +- 22 files changed, 122 insertions(+), 113 deletions(-) create mode 100644 src/types/collection/index.ts diff --git a/src/components/CollectionShare.tsx b/src/components/CollectionShare.tsx index 25051f266..9c234bffc 100644 --- a/src/components/CollectionShare.tsx +++ b/src/components/CollectionShare.tsx @@ -7,14 +7,11 @@ import FormControl from 'react-bootstrap/FormControl'; import { Button, Col, Table } from 'react-bootstrap'; import { DeadCenter } from 'pages/gallery'; import { User } from 'services/userService'; -import { - Collection, - shareCollection, - unshareCollection, -} from 'services/collectionService'; +import { shareCollection, unshareCollection } from 'services/collectionService'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import SubmitButton from './SubmitButton'; import MessageDialog from './MessageDialog'; +import { Collection } from 'types/collection'; interface Props { show: boolean; diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index f3f42615d..f4e48a6f7 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -19,7 +19,7 @@ import LocationIcon from './icons/LocationIcon'; import DateIcon from './icons/DateIcon'; import SearchIcon from './icons/SearchIcon'; import CloseIcon from './icons/CloseIcon'; -import { Collection } from 'services/collectionService'; +import { Collection } from 'types/collection'; import CollectionIcon from './icons/CollectionIcon'; import { File, FILE_TYPE } from 'services/fileService'; import ImageIcon from './icons/ImageIcon'; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index ea04f8887..d8f1918c9 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -16,7 +16,7 @@ import { } from 'utils/billing'; import isElectron from 'is-electron'; -import { Collection } from 'services/collectionService'; +import { Collection } from 'types/collection'; import { useRouter } from 'next/router'; import LinkButton from './pages/gallery/LinkButton'; import { downloadApp } from 'utils/common'; diff --git a/src/components/pages/gallery/CollectionOptions.tsx b/src/components/pages/gallery/CollectionOptions.tsx index e34be88f4..dd9ce740a 100644 --- a/src/components/pages/gallery/CollectionOptions.tsx +++ b/src/components/pages/gallery/CollectionOptions.tsx @@ -1,16 +1,13 @@ import React from 'react'; import { SetDialogMessage } from 'components/MessageDialog'; import { ListGroup, Popover } from 'react-bootstrap'; -import { - Collection, - deleteCollection, - renameCollection, -} from 'services/collectionService'; +import { deleteCollection, renameCollection } from 'services/collectionService'; import { downloadCollection, getSelectedCollection } from 'utils/collection'; import constants from 'utils/strings/constants'; import { SetCollectionNamerAttributes } from './CollectionNamer'; import LinkButton, { ButtonVariant, LinkButtonProps } from './LinkButton'; import { sleep } from 'utils/common'; +import { Collection } from 'types/collection'; interface CollectionOptionsProps { syncWithRemote: () => Promise; diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index b5d691eee..128b32e23 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -1,15 +1,16 @@ import React, { useEffect, useState } from 'react'; import { Card, Modal } from 'react-bootstrap'; import styled from 'styled-components'; -import { - Collection, - CollectionAndItsLatestFile, - CollectionType, -} from 'services/collectionService'; +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'; +import { + Collection, + CollectionAndItsLatestFile, + CollectionType, +} from 'types/collection'; export const CollectionIcon = styled.div` width: 200px; diff --git a/src/components/pages/gallery/CollectionSort.tsx b/src/components/pages/gallery/CollectionSort.tsx index 9d0c2a68c..80d212ad3 100644 --- a/src/components/pages/gallery/CollectionSort.tsx +++ b/src/components/pages/gallery/CollectionSort.tsx @@ -2,7 +2,7 @@ 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 { COLLECTION_SORT_BY } from 'types/collection'; import constants from 'utils/strings/constants'; import CollectionSortOptions from './CollectionSortOptions'; import { IconWithMessage } from './SelectedFileOptions'; diff --git a/src/components/pages/gallery/CollectionSortOptions.tsx b/src/components/pages/gallery/CollectionSortOptions.tsx index aff226140..52a0ee9eb 100644 --- a/src/components/pages/gallery/CollectionSortOptions.tsx +++ b/src/components/pages/gallery/CollectionSortOptions.tsx @@ -2,7 +2,7 @@ import { 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 { COLLECTION_SORT_BY } from 'types/collection'; import styled from 'styled-components'; import constants from 'utils/strings/constants'; import { MenuItem, MenuLink } from './CollectionOptions'; diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index b67e05ccc..3a43b0fb2 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -5,16 +5,16 @@ import NavigationButton, { } from 'components/NavigationButton'; import React, { useEffect, useRef, useState } from 'react'; import { OverlayTrigger, Tooltip } from 'react-bootstrap'; -import { - Collection, - CollectionAndItsLatestFile, - CollectionType, - COLLECTION_SORT_BY, - sortCollections, -} from 'services/collectionService'; +import { sortCollections } from 'services/collectionService'; import { User } from 'services/userService'; import styled from 'styled-components'; import { IMAGE_CONTAINER_MAX_WIDTH } from 'types'; +import { + Collection, + CollectionAndItsLatestFile, + COLLECTION_SORT_BY, + CollectionType, +} from 'types/collection'; import { getSelectedCollection } from 'utils/collection'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; diff --git a/src/components/pages/gallery/SelectedFileOptions.tsx b/src/components/pages/gallery/SelectedFileOptions.tsx index 7985e5a1c..ce79cfd8d 100644 --- a/src/components/pages/gallery/SelectedFileOptions.tsx +++ b/src/components/pages/gallery/SelectedFileOptions.tsx @@ -14,7 +14,7 @@ import { COLLECTION_OPS_TYPE } from 'utils/collection'; import { ALL_SECTION, ARCHIVE_SECTION, TRASH_SECTION } from './Collections'; import UnArchive from 'components/icons/UnArchive'; import { OverlayTrigger } from 'react-bootstrap'; -import { Collection } from 'services/collectionService'; +import { Collection } from 'types/collection'; import RemoveIcon from 'components/icons/RemoveIcon'; import RestoreIcon from 'components/icons/RestoreIcon'; import ClockIcon from 'components/icons/ClockIcon'; diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index df694188b..4c322dcb0 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -1,10 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; -import { - Collection, - syncCollections, - createAlbum, -} from 'services/collectionService'; +import { syncCollections, createAlbum } from 'services/collectionService'; import constants from 'utils/strings/constants'; import { SetDialogMessage } from 'components/MessageDialog'; import UploadProgress from './UploadProgress'; @@ -23,6 +19,7 @@ import UploadManager, { import uploadManager from 'services/upload/uploadManager'; import { METADATA_FOLDER_NAME } from 'services/exportService'; import { getUserFacingErrorMessage } from 'utils/common/errorUtil'; +import { Collection } from 'types/collection'; const FIRST_ALBUM_NAME = 'My First Album'; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index ffea9f47f..80c5a2821 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -19,15 +19,12 @@ import { import styled from 'styled-components'; import LoadingBar from 'react-top-loading-bar'; import { - Collection, syncCollections, - CollectionAndItsLatestFile, getCollectionsAndTheirLatestFile, getFavItemIds, getLocalCollections, getNonEmptyCollections, createCollection, - CollectionType, } from 'services/collectionService'; import constants from 'utils/strings/constants'; import billingService from 'services/billingService'; @@ -98,6 +95,11 @@ import DeleteBtn from 'components/DeleteBtn'; import FixCreationTime, { FixCreationTimeAttributes, } from 'components/FixCreationTime'; +import { + Collection, + CollectionAndItsLatestFile, + CollectionType, +} from 'types/collection'; export const DeadCenter = styled.div` flex: 1; diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index 3a44d8936..388422d79 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -6,80 +6,28 @@ import { getActualKey, getToken } from 'utils/common/key'; import CryptoWorker from 'utils/crypto'; import { SetDialogMessage } from 'components/MessageDialog'; import constants from 'utils/strings/constants'; -import { getPublicKey, User } from './userService'; +import { getPublicKey } from './userService'; import { B64EncryptionResult } from 'utils/crypto'; import HTTPService from './HTTPService'; import { File } from './fileService'; import { logError } from 'utils/sentry'; import { CustomError } from 'utils/common/errorUtil'; import { sortFiles } from 'utils/file'; +import { + Collection, + COLLECTION_UPDATION_TIME, + COLLECTION_SORT_BY, + CollectionAndItsLatestFile, + CollectionType, + AddToCollectionRequest, + MoveToCollectionRequest, + EncryptedFileKey, + RemoveFromCollectionRequest, + COLLECTION_TABLE, +} from 'types/collection'; const ENDPOINT = getEndpoint(); -export enum CollectionType { - folder = 'folder', - favorites = 'favorites', - album = 'album', -} - -const COLLECTION_UPDATION_TIME = 'collection-updation-time'; -const COLLECTIONS = 'collections'; - -export interface Collection { - id: number; - owner: User; - key?: string; - name?: string; - encryptedName?: string; - nameDecryptionNonce?: string; - type: CollectionType; - attributes: collectionAttributes; - sharees: User[]; - updationTime: number; - encryptedKey: string; - keyDecryptionNonce: string; - isDeleted: boolean; - isSharedCollection?: boolean; -} - -interface EncryptedFileKey { - id: number; - encryptedKey: string; - keyDecryptionNonce: string; -} - -interface AddToCollectionRequest { - collectionID: number; - files: EncryptedFileKey[]; -} - -interface MoveToCollectionRequest { - fromCollectionID: number; - toCollectionID: number; - files: EncryptedFileKey[]; -} - -interface collectionAttributes { - encryptedPath?: string; - pathDecryptionNonce?: string; -} - -export interface CollectionAndItsLatestFile { - collection: Collection; - file: File; -} - -export enum COLLECTION_SORT_BY { - LATEST_FILE, - MODIFICATION_TIME, - NAME, -} - -interface RemoveFromCollectionRequest { - collectionID: number; - fileIDs: number[]; -} - const getCollectionWithSecrets = async ( collection: Collection, masterKey: string @@ -164,7 +112,7 @@ const getCollections = async ( export const getLocalCollections = async (): Promise => { const collections: Collection[] = - (await localForage.getItem(COLLECTIONS)) ?? []; + (await localForage.getItem(COLLECTION_TABLE)) ?? []; return collections; }; @@ -212,7 +160,7 @@ export const syncCollections = async () => { [], COLLECTION_SORT_BY.MODIFICATION_TIME ); - await localForage.setItem(COLLECTIONS, collections); + await localForage.setItem(COLLECTION_TABLE, collections); await localForage.setItem(COLLECTION_UPDATION_TIME, updationTime); return collections; }; @@ -365,7 +313,7 @@ export const addToFavorites = async (file: File) => { CollectionType.favorites ); const localCollections = await getLocalCollections(); - await localForage.setItem(COLLECTIONS, [ + await localForage.setItem(COLLECTION_TABLE, [ ...localCollections, favCollection, ]); diff --git a/src/services/exportService.ts b/src/services/exportService.ts index f210b23ec..0c560667d 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -23,7 +23,6 @@ import { retryAsyncFunction } from 'utils/network'; import { logError } from 'utils/sentry'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { - Collection, getLocalCollections, getNonEmptyCollections, } from './collectionService'; @@ -42,6 +41,7 @@ import { User } from './userService'; import { updateFileCreationDateInEXIF } from './upload/exifService'; import { MetadataObject } from 'types/upload'; import QueueProcessor from './upload/queueProcessor'; +import { Collection } from 'types/collection'; export type CollectionIDPathMap = Map; export interface ExportProgress { diff --git a/src/services/fileService.ts b/src/services/fileService.ts index af794e892..247ec8ea8 100644 --- a/src/services/fileService.ts +++ b/src/services/fileService.ts @@ -3,7 +3,7 @@ import localForage from 'utils/storage/localForage'; import { getToken } from 'utils/common/key'; import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; -import { Collection } from './collectionService'; +import { Collection } from 'types/collection'; import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; import { decryptFile, mergeMetadata, sortFiles } from 'utils/file'; diff --git a/src/services/searchService.ts b/src/services/searchService.ts index 7d41fed8a..4bb3f02e0 100644 --- a/src/services/searchService.ts +++ b/src/services/searchService.ts @@ -3,7 +3,7 @@ import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { DateValue, Suggestion, SuggestionType } from 'components/SearchBar'; import HTTPService from './HTTPService'; -import { Collection } from './collectionService'; +import { Collection } from 'types/collection'; import { File } from './fileService'; import { logError } from 'utils/sentry'; diff --git a/src/services/trashService.ts b/src/services/trashService.ts index 11cc3933a..544575b67 100644 --- a/src/services/trashService.ts +++ b/src/services/trashService.ts @@ -1,10 +1,11 @@ import { SetFiles } from 'pages/gallery'; +import { Collection } from 'types/collection'; import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { decryptFile, mergeMetadata, sortFiles } from 'utils/file'; import { logError } from 'utils/sentry'; import localForage from 'utils/storage/localForage'; -import { Collection, getCollection } from './collectionService'; +import { getCollection } from './collectionService'; import { File } from './fileService'; import HTTPService from './HTTPService'; diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index fe9db1016..f96c9ccce 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -1,5 +1,5 @@ import { File, getLocalFiles, setLocalFiles } from '../fileService'; -import { Collection, getLocalCollections } from '../collectionService'; +import { getLocalCollections } from '../collectionService'; import { SetFiles } from 'pages/gallery'; import { ComlinkWorker, getDedicatedCryptoWorker } from 'utils/crypto'; import { @@ -19,6 +19,7 @@ import uploader from './uploader'; import UIService from './uiService'; import UploadService from './uploadService'; import { CustomError } from 'utils/common/errorUtil'; +import { Collection } from 'types/collection'; const MAX_CONCURRENT_UPLOADS = 4; const FILE_UPLOAD_COMPLETED = 100; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index b45ec71d2..a05fae631 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -1,5 +1,5 @@ import { fileAttribute } from '../fileService'; -import { Collection } from '../collectionService'; +import { Collection } from 'types/collection'; import { logError } from 'utils/sentry'; import UploadHttpClient from './uploadHttpClient'; import { diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts new file mode 100644 index 000000000..7d3a07598 --- /dev/null +++ b/src/types/collection/index.ts @@ -0,0 +1,66 @@ +import { User } from 'services/userService'; +import { File } from 'services/fileService'; + +export const COLLECTION_UPDATION_TIME = 'collection-updation-time'; +export const COLLECTION_TABLE = 'collections'; + +export enum CollectionType { + folder = 'folder', + favorites = 'favorites', + album = 'album', +} + +export interface Collection { + id: number; + owner: User; + key?: string; + name?: string; + encryptedName?: string; + nameDecryptionNonce?: string; + type: CollectionType; + attributes: collectionAttributes; + sharees: User[]; + updationTime: number; + encryptedKey: string; + keyDecryptionNonce: string; + isDeleted: boolean; + isSharedCollection?: boolean; +} + +export interface EncryptedFileKey { + id: number; + encryptedKey: string; + keyDecryptionNonce: string; +} + +export interface AddToCollectionRequest { + collectionID: number; + files: EncryptedFileKey[]; +} + +export interface MoveToCollectionRequest { + fromCollectionID: number; + toCollectionID: number; + files: EncryptedFileKey[]; +} + +export interface collectionAttributes { + encryptedPath?: string; + pathDecryptionNonce?: string; +} + +export interface CollectionAndItsLatestFile { + collection: Collection; + file: File; +} + +export enum COLLECTION_SORT_BY { + LATEST_FILE, + MODIFICATION_TIME, + NAME, +} + +export interface RemoveFromCollectionRequest { + collectionID: number; + fileIDs: number[]; +} diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index 46aae90e9..abc557bc6 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -1,7 +1,5 @@ import { addToCollection, - Collection, - CollectionType, moveToCollection, removeFromCollection, restoreToCollection, @@ -15,6 +13,7 @@ import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { SetDialogMessage } from 'components/MessageDialog'; import { logError } from 'utils/sentry'; import constants from 'utils/strings/constants'; +import { Collection, CollectionType } from 'types/collection'; export enum COLLECTION_OPS_TYPE { ADD, diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index 410d372ba..5a8c2105a 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -1,4 +1,4 @@ -import { Collection } from 'services/collectionService'; +import { Collection } from 'types/collection'; import exportService, { CollectionIDPathMap, ExportRecord, diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index ea911e08a..66bcd9ea1 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -1,5 +1,5 @@ import { SelectedState } from 'pages/gallery'; -import { Collection } from 'services/collectionService'; +import { Collection } from 'types/collection'; import { File, fileAttribute, From f8af3a9a399f8f19ab84884dcb766525863a4e69 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 14:21:47 +0530 Subject: [PATCH 06/69] moved export types to types/export --- src/components/ExportFinished.tsx | 2 +- src/components/ExportInProgress.tsx | 2 +- src/components/ExportModal.tsx | 5 +- src/components/pages/gallery/Upload.tsx | 2 +- src/services/exportService.ts | 65 ++++--------------------- src/types/export/index.ts | 54 ++++++++++++++++++++ src/utils/export/index.ts | 5 +- 7 files changed, 73 insertions(+), 62 deletions(-) create mode 100644 src/types/export/index.ts diff --git a/src/components/ExportFinished.tsx b/src/components/ExportFinished.tsx index 5fc263d88..563286512 100644 --- a/src/components/ExportFinished.tsx +++ b/src/components/ExportFinished.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button } from 'react-bootstrap'; -import { ExportStats } from 'services/exportService'; +import { ExportStats } from 'types/export'; import { formatDateTime } from 'utils/file'; import constants from 'utils/strings/constants'; import { Label, Row, Value } from './Container'; diff --git a/src/components/ExportInProgress.tsx b/src/components/ExportInProgress.tsx index 3a714ecc8..27d9ed887 100644 --- a/src/components/ExportInProgress.tsx +++ b/src/components/ExportInProgress.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button, ProgressBar } from 'react-bootstrap'; -import { ExportProgress, ExportStage } from 'services/exportService'; +import { ExportProgress, ExportStage } from 'types/export'; import styled from 'styled-components'; import constants from 'utils/strings/constants'; diff --git a/src/components/ExportModal.tsx b/src/components/ExportModal.tsx index f7c3c6c80..91cb4ace4 100644 --- a/src/components/ExportModal.tsx +++ b/src/components/ExportModal.tsx @@ -1,12 +1,13 @@ import isElectron from 'is-electron'; import React, { useEffect, useState } from 'react'; import { Button } from 'react-bootstrap'; -import exportService, { +import exportService from 'services/exportService'; +import { ExportProgress, ExportStage, ExportStats, ExportType, -} from 'services/exportService'; +} from 'types/export'; import { getLocalFiles } from 'services/fileService'; import { User } from 'services/userService'; import styled from 'styled-components'; diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 4c322dcb0..476e7f586 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -17,7 +17,7 @@ import UploadManager, { UPLOAD_STAGES, } from 'services/upload/uploadManager'; import uploadManager from 'services/upload/uploadManager'; -import { METADATA_FOLDER_NAME } from 'services/exportService'; +import { METADATA_FOLDER_NAME } from 'types/export'; import { getUserFacingErrorMessage } from 'utils/common/errorUtil'; import { Collection } from 'types/collection'; diff --git a/src/services/exportService.ts b/src/services/exportService.ts index 0c560667d..3f42a36d2 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -42,61 +42,16 @@ import { updateFileCreationDateInEXIF } from './upload/exifService'; import { MetadataObject } from 'types/upload'; import QueueProcessor from './upload/queueProcessor'; import { Collection } from 'types/collection'; - -export type CollectionIDPathMap = Map; -export interface ExportProgress { - current: number; - total: number; -} -export interface ExportedCollectionPaths { - [collectionID: number]: string; -} -export interface ExportStats { - failed: number; - success: number; -} - -const LATEST_EXPORT_VERSION = 1; - -export interface ExportRecord { - version?: number; - stage?: ExportStage; - lastAttemptTimestamp?: number; - progress?: ExportProgress; - queuedFiles?: string[]; - exportedFiles?: string[]; - failedFiles?: string[]; - exportedCollectionPaths?: ExportedCollectionPaths; -} -export enum ExportStage { - INIT, - INPROGRESS, - PAUSED, - FINISHED, -} - -enum ExportNotification { - START = 'export started', - IN_PROGRESS = 'export already in progress', - FINISH = 'export finished', - FAILED = 'export failed', - ABORT = 'export aborted', - PAUSE = 'export paused', - UP_TO_DATE = `no new files to export`, -} - -enum RecordType { - SUCCESS = 'success', - FAILED = 'failed', -} -export enum ExportType { - NEW, - PENDING, - RETRY_FAILED, -} - -const EXPORT_RECORD_FILE_NAME = 'export_status.json'; -export const METADATA_FOLDER_NAME = 'metadata'; +import { + ExportProgress, + ExportType, + ExportNotification, + CollectionIDPathMap, + RecordType, + ExportRecord, + EXPORT_RECORD_FILE_NAME, + LATEST_EXPORT_VERSION, +} from 'types/export'; class ExportService { ElectronAPIs: any; diff --git a/src/types/export/index.ts b/src/types/export/index.ts new file mode 100644 index 000000000..14249e57d --- /dev/null +++ b/src/types/export/index.ts @@ -0,0 +1,54 @@ +export const EXPORT_RECORD_FILE_NAME = 'export_status.json'; +export const METADATA_FOLDER_NAME = 'metadata'; + +export enum ExportNotification { + START = 'export started', + IN_PROGRESS = 'export already in progress', + FINISH = 'export finished', + FAILED = 'export failed', + ABORT = 'export aborted', + PAUSE = 'export paused', + UP_TO_DATE = `no new files to export`, +} + +export enum RecordType { + SUCCESS = 'success', + FAILED = 'failed', +} +export const LATEST_EXPORT_VERSION = 1; + +export type CollectionIDPathMap = Map; +export interface ExportProgress { + current: number; + total: number; +} +export interface ExportedCollectionPaths { + [collectionID: number]: string; +} +export interface ExportStats { + failed: number; + success: number; +} + +export interface ExportRecord { + version?: number; + stage?: ExportStage; + lastAttemptTimestamp?: number; + progress?: ExportProgress; + queuedFiles?: string[]; + exportedFiles?: string[]; + failedFiles?: string[]; + exportedCollectionPaths?: ExportedCollectionPaths; +} +export enum ExportStage { + INIT, + INPROGRESS, + PAUSED, + FINISHED, +} + +export enum ExportType { + NEW, + PENDING, + RETRY_FAILED, +} diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index 5a8c2105a..f0238ad25 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -1,9 +1,10 @@ import { Collection } from 'types/collection'; -import exportService, { +import exportService from 'services/exportService'; +import { CollectionIDPathMap, ExportRecord, METADATA_FOLDER_NAME, -} from 'services/exportService'; +} from 'types/export'; import { File } from 'services/fileService'; import { MetadataObject } from 'types/upload'; import { formatDate, splitFilenameAndExtension } from 'utils/file'; From aba964922ef7a45690e9c4596823c13a2aa53390 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 15:20:14 +0530 Subject: [PATCH 07/69] moved file related types to types/file --- src/components/EnteDateTimePicker.tsx | 8 +- src/components/FixCreationTime/index.tsx | 4 +- src/components/PhotoFrame.tsx | 12 +- src/components/PhotoList.tsx | 8 +- src/components/PhotoSwipe/PhotoSwipe.tsx | 17 +- src/components/SearchBar.tsx | 5 +- src/components/pages/gallery/PreviewCard.tsx | 4 +- src/components/pages/gallery/Upload.tsx | 6 +- src/pages/gallery/index.tsx | 9 +- src/services/collectionService.ts | 26 ++-- src/services/downloadManager.ts | 13 +- src/services/exportService.ts | 24 +-- src/services/fileService.ts | 156 +++---------------- src/services/migrateThumbnailService.ts | 5 +- src/services/searchService.ts | 5 +- src/services/trashService.ts | 9 +- src/services/updateCreationTimeWithExif.ts | 6 +- src/services/upload/exifService.ts | 2 +- src/services/upload/metadataService.ts | 6 +- src/services/upload/readFileService.ts | 27 ++-- src/services/upload/thumbnailService.ts | 14 +- src/services/upload/uploadHttpClient.ts | 4 +- src/services/upload/uploadManager.ts | 9 +- src/services/upload/uploadService.ts | 4 +- src/services/upload/uploader.ts | 6 +- src/types/collection/index.ts | 4 +- src/types/file/index.ts | 105 +++++++++++++ src/types/upload/index.ts | 9 +- src/utils/collection/index.ts | 5 +- src/utils/export/index.ts | 20 ++- src/utils/file/index.ts | 59 +++---- src/utils/search/index.ts | 4 +- src/utils/upload/index.ts | 5 +- 33 files changed, 311 insertions(+), 289 deletions(-) create mode 100644 src/types/file/index.ts diff --git a/src/components/EnteDateTimePicker.tsx b/src/components/EnteDateTimePicker.tsx index de4d37f71..fcc955e64 100644 --- a/src/components/EnteDateTimePicker.tsx +++ b/src/components/EnteDateTimePicker.tsx @@ -1,12 +1,12 @@ import React from 'react'; + +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; import { MIN_EDITED_CREATION_TIME, MAX_EDITED_CREATION_TIME, ALL_TIME, -} from 'services/fileService'; - -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; +} from 'types/file'; const isSameDay = (first, second) => first.getFullYear() === second.getFullYear() && diff --git a/src/components/FixCreationTime/index.tsx b/src/components/FixCreationTime/index.tsx index 1e39fde44..dd5fc26d1 100644 --- a/src/components/FixCreationTime/index.tsx +++ b/src/components/FixCreationTime/index.tsx @@ -3,14 +3,14 @@ import MessageDialog from '../MessageDialog'; import React, { useContext, useEffect, useState } from 'react'; import { updateCreationTimeWithExif } from 'services/updateCreationTimeWithExif'; import { GalleryContext } from 'pages/gallery'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; import FixCreationTimeRunning from './running'; import FixCreationTimeFooter from './footer'; import { Formik } from 'formik'; import FixCreationTimeOptions from './options'; export interface FixCreationTimeAttributes { - files: File[]; + files: EnteFile[]; } interface Props { diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index b91ea03ca..0ac495b0a 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -8,7 +8,7 @@ import { import PreviewCard from './pages/gallery/PreviewCard'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { Button } from 'react-bootstrap'; -import { File, FILE_TYPE } from 'services/fileService'; +import { EnteFile, FILE_TYPE } from 'types/file'; import styled from 'styled-components'; import DownloadManager from 'services/downloadManager'; import constants from 'utils/strings/constants'; @@ -53,7 +53,7 @@ const EmptyScreen = styled.div` `; interface Props { - files: File[]; + files: EnteFile[]; setFiles: SetFiles; syncWithRemote: () => Promise; favItemIds: Set; @@ -320,7 +320,7 @@ const PhotoFrame = ({ } } }; - const getThumbnail = (file: File[], index: number) => ( + const getThumbnail = (file: EnteFile[], index: number) => ( ); - const getSlideData = async (instance: any, index: number, item: File) => { + const getSlideData = async ( + instance: any, + index: number, + item: EnteFile + ) => { if (!item.msrc) { try { let url: string; diff --git a/src/components/PhotoList.tsx b/src/components/PhotoList.tsx index f8dce46ab..4c9e0c67a 100644 --- a/src/components/PhotoList.tsx +++ b/src/components/PhotoList.tsx @@ -1,7 +1,7 @@ import React, { useRef, useEffect } from 'react'; import { VariableSizeList as List } from 'react-window'; import styled from 'styled-components'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; import { IMAGE_CONTAINER_MAX_WIDTH, IMAGE_CONTAINER_MAX_HEIGHT, @@ -23,7 +23,7 @@ enum ITEM_TYPE { interface TimeStampListItem { itemType: ITEM_TYPE; - items?: File[]; + items?: EnteFile[]; itemStartIndex?: number; date?: string; dates?: { @@ -102,9 +102,9 @@ const NothingContainer = styled.div<{ span: number }>` interface Props { height: number; width: number; - filteredData: File[]; + filteredData: EnteFile[]; showBanner: boolean; - getThumbnail: (file: File[], index: number) => JSX.Element; + getThumbnail: (file: EnteFile[], index: number) => JSX.Element; activeCollection: number; resetFetching: () => void; } diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx index 58fd6852b..ac0efb5b4 100644 --- a/src/components/PhotoSwipe/PhotoSwipe.tsx +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -7,11 +7,8 @@ import { addToFavorites, removeFromFavorites, } from 'services/collectionService'; -import { - File, - MAX_EDITED_FILE_NAME_LENGTH, - updatePublicMagicMetadata, -} from 'services/fileService'; +import { updatePublicMagicMetadata } from 'services/fileService'; +import { EnteFile, MAX_EDITED_FILE_NAME_LENGTH } from 'types/file'; import constants from 'utils/strings/constants'; import exifr from 'exifr'; import Modal from 'react-bootstrap/Modal'; @@ -51,7 +48,7 @@ interface Iprops { items: any[]; currentIndex?: number; onClose?: (needUpdate: boolean) => void; - gettingData: (instance: any, index: number, item: File) => void; + gettingData: (instance: any, index: number, item: EnteFile) => void; id?: string; className?: string; favItemIds: Set; @@ -87,7 +84,7 @@ function RenderCreationTime({ file, scheduleUpdate, }: { - file: File; + file: EnteFile; scheduleUpdate: () => void; }) { const originalCreationTime = new Date(file?.metadata.creationTime / 1000); @@ -267,7 +264,7 @@ function RenderFileName({ file, scheduleUpdate, }: { - file: File; + file: EnteFile; scheduleUpdate: () => void; }) { const originalTitle = file?.metadata.title; @@ -456,7 +453,7 @@ function PhotoSwipe(props: Iprops) { const { isOpen, items } = props; const [isFav, setIsFav] = useState(false); const [showInfo, setShowInfo] = useState(false); - const [metadata, setMetaData] = useState(null); + const [metadata, setMetaData] = useState(null); const [exif, setExif] = useState(null); const needUpdate = useRef(false); @@ -624,7 +621,7 @@ function PhotoSwipe(props: Iprops) { }; function updateInfo() { - const file: File = this?.currItem; + const file: EnteFile = this?.currItem; if (file?.metadata) { setMetaData(file.metadata); setExif(null); diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index f4e48a6f7..a9dd2c796 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -21,10 +21,11 @@ import SearchIcon from './icons/SearchIcon'; import CloseIcon from './icons/CloseIcon'; import { Collection } from 'types/collection'; import CollectionIcon from './icons/CollectionIcon'; -import { File, FILE_TYPE } from 'services/fileService'; + import ImageIcon from './icons/ImageIcon'; import VideoIcon from './icons/VideoIcon'; import { IconButton } from './Container'; +import { EnteFile, FILE_TYPE } from 'types/file'; const Wrapper = styled.div<{ isDisabled: boolean; isOpen: boolean }>` position: fixed; @@ -101,7 +102,7 @@ interface Props { searchStats: SearchStats; collections: Collection[]; setActiveCollection: (id: number) => void; - files: File[]; + files: EnteFile[]; } export default function SearchBar(props: Props) { const [value, setValue] = useState(null); diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index ddb4f7de0..62552cad5 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -1,5 +1,5 @@ import React, { useContext, useLayoutEffect, useRef, useState } from 'react'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; import styled from 'styled-components'; import PlayCircleOutline from 'components/icons/PlayCircleOutline'; import DownloadManager from 'services/downloadManager'; @@ -8,7 +8,7 @@ import { GalleryContext } from 'pages/gallery'; import { GAP_BTW_TILES } from 'types'; interface IProps { - file: File; + file: EnteFile; updateUrl: (url: string) => void; onClick?: () => void; forcedEnable?: boolean; diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 476e7f586..7a1517cfd 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -26,7 +26,7 @@ const FIRST_ALBUM_NAME = 'My First Album'; interface Props { syncWithRemote: (force?: boolean, silent?: boolean) => Promise; setBannerMessage: (message: string | JSX.Element) => void; - acceptedFiles: globalThis.File[]; + acceptedFiles: File[]; closeCollectionSelector: () => void; setCollectionSelectorAttributes: SetCollectionSelectorAttributes; setCollectionNamerAttributes: SetCollectionNamerAttributes; @@ -158,7 +158,7 @@ export default function Upload(props: Props) { }; } function getCollectionWiseFiles() { - const collectionWiseFiles = new Map(); + const collectionWiseFiles = new Map(); for (const file of props.acceptedFiles) { const filePath = file['path'] as string; @@ -200,7 +200,7 @@ export default function Upload(props: Props) { const filesWithCollectionToUpload: FileWithCollection[] = []; const collections: Collection[] = []; - let collectionWiseFiles = new Map(); + let collectionWiseFiles = new Map(); if (strategy === UPLOAD_STRATEGY.SINGLE_COLLECTION) { collectionWiseFiles.set(collectionName, props.acceptedFiles); } else { diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index 80c5a2821..cecafc80c 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -8,11 +8,9 @@ import React, { import { useRouter } from 'next/router'; import { clearKeys, getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; import { - File, getLocalFiles, syncFiles, updateMagicMetadata, - VISIBILITY_STATE, trashFiles, deleteFromTrash, } from 'services/fileService'; @@ -100,6 +98,7 @@ import { CollectionAndItsLatestFile, CollectionType, } from 'types/collection'; +import { EnteFile, VISIBILITY_STATE } from 'types/file'; export const DeadCenter = styled.div` flex: 1; @@ -121,7 +120,7 @@ export type SelectedState = { count: number; collectionID: number; }; -export type SetFiles = React.Dispatch>; +export type SetFiles = React.Dispatch>; export type SetCollections = React.Dispatch>; export type SetLoading = React.Dispatch>; export type setSearchStats = React.Dispatch>; @@ -161,7 +160,7 @@ export default function Gallery() { const [collections, setCollections] = useState([]); const [collectionsAndTheirLatestFile, setCollectionsAndTheirLatestFile] = useState([]); - const [files, setFiles] = useState(null); + const [files, setFiles] = useState(null); const [favItemIds, setFavItemIds] = useState>(); const [bannerMessage, setBannerMessage] = useState( null @@ -341,7 +340,7 @@ export default function Gallery() { const setDerivativeState = async ( collections: Collection[], - files: File[] + files: EnteFile[] ) => { const favItemIds = await getFavItemIds(files); setFavItemIds(favItemIds); diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index 388422d79..e87da0225 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -9,7 +9,7 @@ import constants from 'utils/strings/constants'; import { getPublicKey } from './userService'; import { B64EncryptionResult } from 'utils/crypto'; import HTTPService from './HTTPService'; -import { File } from './fileService'; +import { EnteFile } from 'types/file'; import { logError } from 'utils/sentry'; import { CustomError } from 'utils/common/errorUtil'; import { sortFiles } from 'utils/file'; @@ -191,9 +191,9 @@ export const getCollection = async ( export const getCollectionsAndTheirLatestFile = ( collections: Collection[], - files: File[] + files: EnteFile[] ): CollectionAndItsLatestFile[] => { - const latestFile = new Map(); + const latestFile = new Map(); files.forEach((file) => { if (!latestFile.has(file.collectionID)) { @@ -211,7 +211,9 @@ export const getCollectionsAndTheirLatestFile = ( return collectionsAndTheirLatestFile; }; -export const getFavItemIds = async (files: File[]): Promise> => { +export const getFavItemIds = async ( + files: EnteFile[] +): Promise> => { const favCollection = await getFavCollection(); if (!favCollection) return new Set(); @@ -304,7 +306,7 @@ const postCollection = async ( } }; -export const addToFavorites = async (file: File) => { +export const addToFavorites = async (file: EnteFile) => { try { let favCollection = await getFavCollection(); if (!favCollection) { @@ -324,7 +326,7 @@ export const addToFavorites = async (file: File) => { } }; -export const removeFromFavorites = async (file: File) => { +export const removeFromFavorites = async (file: EnteFile) => { try { const favCollection = await getFavCollection(); if (!favCollection) { @@ -338,7 +340,7 @@ export const removeFromFavorites = async (file: File) => { export const addToCollection = async ( collection: Collection, - files: File[] + files: EnteFile[] ) => { try { const token = getToken(); @@ -365,7 +367,7 @@ export const addToCollection = async ( export const restoreToCollection = async ( collection: Collection, - files: File[] + files: EnteFile[] ) => { try { const token = getToken(); @@ -392,7 +394,7 @@ export const restoreToCollection = async ( export const moveToCollection = async ( fromCollectionID: number, toCollection: Collection, - files: File[] + files: EnteFile[] ) => { try { const token = getToken(); @@ -420,7 +422,7 @@ export const moveToCollection = async ( const encryptWithNewCollectionKey = async ( newCollection: Collection, - files: File[] + files: EnteFile[] ): Promise => { const fileKeysEncryptedWithNewCollection: EncryptedFileKey[] = []; const worker = await new CryptoWorker(); @@ -442,7 +444,7 @@ const encryptWithNewCollectionKey = async ( }; export const removeFromCollection = async ( collection: Collection, - files: File[] + files: EnteFile[] ) => { try { const token = getToken(); @@ -585,7 +587,7 @@ export const getFavCollection = async () => { export const getNonEmptyCollections = ( collections: Collection[], - files: File[] + files: EnteFile[] ) => { const nonEmptyCollectionsIds = new Set(); for (const file of files) { diff --git a/src/services/downloadManager.ts b/src/services/downloadManager.ts index 5e4c4b856..219b49345 100644 --- a/src/services/downloadManager.ts +++ b/src/services/downloadManager.ts @@ -7,14 +7,15 @@ import { needsConversionForPreview, } from 'utils/file'; import HTTPService from './HTTPService'; -import { File, FILE_TYPE } from './fileService'; +import { EnteFile, FILE_TYPE } from 'types/file'; + import { logError } from 'utils/sentry'; class DownloadManager { private fileObjectUrlPromise = new Map>(); private thumbnailObjectUrlPromise = new Map>(); - public async getThumbnail(file: File) { + public async getThumbnail(file: EnteFile) { try { const token = getToken(); if (!token) { @@ -52,7 +53,7 @@ class DownloadManager { } } - downloadThumb = async (token: string, file: File) => { + downloadThumb = async (token: string, file: EnteFile) => { const resp = await HTTPService.get( getThumbnailUrl(file.id), null, @@ -68,7 +69,7 @@ class DownloadManager { return decrypted; }; - getFile = async (file: File, forPreview = false) => { + getFile = async (file: EnteFile, forPreview = false) => { const shouldBeConverted = forPreview && needsConversionForPreview(file); const fileKey = shouldBeConverted ? `${file.id}_converted` @@ -97,11 +98,11 @@ class DownloadManager { } }; - public async getCachedOriginalFile(file: File) { + public async getCachedOriginalFile(file: EnteFile) { return await this.fileObjectUrlPromise.get(file.id.toString()); } - async downloadFile(file: File) { + async downloadFile(file: EnteFile) { const worker = await new CryptoWorker(); const token = getToken(); if (!token) { diff --git a/src/services/exportService.ts b/src/services/exportService.ts index 3f42a36d2..762afc0ff 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -27,7 +27,9 @@ import { getNonEmptyCollections, } from './collectionService'; import downloadManager from './downloadManager'; -import { File, FILE_TYPE, getLocalFiles } from './fileService'; +import { getLocalFiles } from './fileService'; +import { EnteFile, FILE_TYPE } from 'types/file'; + import { decodeMotionPhoto } from './motionPhotoService'; import { fileNameWithoutExtension, @@ -94,7 +96,7 @@ class ExportService { } const user: User = getData(LS_KEYS.USER); - let filesToExport: File[]; + let filesToExport: EnteFile[]; const localFiles = await getLocalFiles(); const userPersonalFiles = localFiles .filter((file) => file.ownerID === user?.id) @@ -165,7 +167,7 @@ class ExportService { } async fileExporter( - files: File[], + files: EnteFile[], newCollections: Collection[], renamedCollections: Collection[], collectionIDPathMap: CollectionIDPathMap, @@ -273,13 +275,17 @@ class ExportService { throw e; } } - async addFilesQueuedRecord(folder: string, files: File[]) { + async addFilesQueuedRecord(folder: string, files: EnteFile[]) { const exportRecord = await this.getExportRecord(folder); exportRecord.queuedFiles = files.map(getExportRecordFileUID); await this.updateExportRecord(exportRecord, folder); } - async addFileExportedRecord(folder: string, file: File, type: RecordType) { + async addFileExportedRecord( + folder: string, + file: EnteFile, + type: RecordType + ) { const fileUID = getExportRecordFileUID(file); const exportRecord = await this.getExportRecord(folder); exportRecord.queuedFiles = exportRecord.queuedFiles.filter( @@ -417,7 +423,7 @@ class ExportService { } } - async downloadAndSave(file: File, collectionPath: string) { + async downloadAndSave(file: EnteFile, collectionPath: string) { file.metadata = mergeMetadata([file])[0].metadata; const fileSaveName = getUniqueFileSaveName( collectionPath, @@ -453,7 +459,7 @@ class ExportService { private async exportMotionPhoto( fileStream: ReadableStream, - file: File, + file: EnteFile, collectionPath: string ) { const fileBlob = await new Response(fileStream).blob(); @@ -527,7 +533,7 @@ class ExportService { private async migrateExport( exportDir: string, collections: Collection[], - allFiles: File[] + allFiles: EnteFile[] ) { const exportRecord = await this.getExportRecord(exportDir); const currentVersion = exportRecord?.version ?? 0; @@ -588,7 +594,7 @@ class ExportService { `fileID_fileName` to newer `fileName(numbered)` format */ private async migrateFiles( - files: File[], + files: EnteFile[], collectionIDPathMap: Map ) { for (let file of files) { diff --git a/src/services/fileService.ts b/src/services/fileService.ts index 247ec8ea8..9ba10e7e4 100644 --- a/src/services/fileService.ts +++ b/src/services/fileService.ts @@ -2,136 +2,28 @@ import { getEndpoint } from 'utils/common/apiUtil'; import localForage from 'utils/storage/localForage'; import { getToken } from 'utils/common/key'; -import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; +import { EncryptionResult } from 'types/upload'; import { Collection } from 'types/collection'; import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; import { decryptFile, mergeMetadata, sortFiles } from 'utils/file'; import CryptoWorker from 'utils/crypto'; +import { + EnteFile, + FILES_TABLE, + TrashRequest, + UpdateMagicMetadataRequest, +} from 'types/file'; const ENDPOINT = getEndpoint(); -const FILES_TABLE = 'files'; - -export const MIN_EDITED_CREATION_TIME = new Date(1800, 0, 1); -export const MAX_EDITED_CREATION_TIME = new Date(); -export const ALL_TIME = new Date(1800, 0, 1, 23, 59, 59); - -export const MAX_EDITED_FILE_NAME_LENGTH = 100; - -export interface fileAttribute { - encryptedData?: DataStream | Uint8Array; - objectKey?: string; - decryptionHeader: string; -} - -export enum FILE_TYPE { - IMAGE, - VIDEO, - LIVE_PHOTO, - OTHERS, -} - -/* Build error occurred - ReferenceError: Cannot access 'FILE_TYPE' before initialization - when it was placed in readFileService -*/ -// list of format that were missed by type-detection for some files. -export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ - { fileType: FILE_TYPE.IMAGE, exactType: 'jpeg' }, - { fileType: FILE_TYPE.IMAGE, exactType: 'jpg' }, - { fileType: FILE_TYPE.VIDEO, exactType: 'webm' }, -]; - -export enum VISIBILITY_STATE { - VISIBLE, - ARCHIVED, -} - -export interface MagicMetadataCore { - version: number; - count: number; - header: string; - data: Record; -} - -export interface EncryptedMagicMetadataCore - extends Omit { - data: string; -} - -export interface MagicMetadataProps { - visibility?: VISIBILITY_STATE; -} - -export interface MagicMetadata extends Omit { - data: MagicMetadataProps; -} - -export interface PublicMagicMetadataProps { - editedTime?: number; - editedName?: string; -} - -export interface PublicMagicMetadata extends Omit { - data: PublicMagicMetadataProps; -} - -export interface File { - id: number; - collectionID: number; - ownerID: number; - file: fileAttribute; - thumbnail: fileAttribute; - metadata: MetadataObject; - magicMetadata: MagicMetadata; - pubMagicMetadata: PublicMagicMetadata; - encryptedKey: string; - keyDecryptionNonce: string; - key: string; - src: string; - msrc: string; - html: string; - w: number; - h: number; - isDeleted: boolean; - isTrashed?: boolean; - deleteBy?: number; - dataIndex: number; - updationTime: number; -} - -interface UpdateMagicMetadataRequest { - metadataList: UpdateMagicMetadata[]; -} - -interface UpdateMagicMetadata { - id: number; - magicMetadata: EncryptedMagicMetadataCore; -} - -export const NEW_MAGIC_METADATA: MagicMetadataCore = { - version: 0, - data: {}, - header: null, - count: 0, -}; - -interface TrashRequest { - items: TrashRequestItems[]; -} - -interface TrashRequestItems { - fileID: number; - collectionID: number; -} export const getLocalFiles = async () => { - const files: Array = - (await localForage.getItem(FILES_TABLE)) || []; + const files: Array = + (await localForage.getItem(FILES_TABLE)) || []; return files; }; -export const setLocalFiles = async (files: File[]) => { +export const setLocalFiles = async (files: EnteFile[]) => { await localForage.setItem(FILES_TABLE, files); }; @@ -140,7 +32,7 @@ const getCollectionLastSyncTime = async (collection: Collection) => export const syncFiles = async ( collections: Collection[], - setFiles: (files: File[]) => void + setFiles: (files: EnteFile[]) => void ) => { const localFiles = await getLocalFiles(); let files = await removeDeletedCollectionFiles(collections, localFiles); @@ -159,7 +51,7 @@ export const syncFiles = async ( const fetchedFiles = (await getFiles(collection, lastSyncTime, files, setFiles)) ?? []; files.push(...fetchedFiles); - const latestVersionFiles = new Map(); + const latestVersionFiles = new Map(); files.forEach((file) => { const uid = `${file.collectionID}-${file.id}`; if ( @@ -190,11 +82,11 @@ export const syncFiles = async ( export const getFiles = async ( collection: Collection, sinceTime: number, - files: File[], - setFiles: (files: File[]) => void -): Promise => { + files: EnteFile[], + setFiles: (files: EnteFile[]) => void +): Promise => { try { - const decryptedFiles: File[] = []; + const decryptedFiles: EnteFile[] = []; let time = sinceTime; let resp; do { @@ -215,12 +107,12 @@ export const getFiles = async ( decryptedFiles.push( ...(await Promise.all( - resp.data.diff.map(async (file: File) => { + resp.data.diff.map(async (file: EnteFile) => { if (!file.isDeleted) { file = await decryptFile(file, collection); } return file; - }) as Promise[] + }) as Promise[] )) ); @@ -245,7 +137,7 @@ export const getFiles = async ( const removeDeletedCollectionFiles = async ( collections: Collection[], - files: File[] + files: EnteFile[] ) => { const syncedCollectionIds = new Set(); for (const collection of collections) { @@ -255,7 +147,7 @@ const removeDeletedCollectionFiles = async ( return files; }; -export const trashFiles = async (filesToTrash: File[]) => { +export const trashFiles = async (filesToTrash: EnteFile[]) => { try { const token = getToken(); if (!token) { @@ -296,7 +188,7 @@ export const deleteFromTrash = async (filesToDelete: number[]) => { } }; -export const updateMagicMetadata = async (files: File[]) => { +export const updateMagicMetadata = async (files: EnteFile[]) => { const token = getToken(); if (!token) { return; @@ -320,7 +212,7 @@ export const updateMagicMetadata = async (files: File[]) => { 'X-Auth-Token': token, }); return files.map( - (file): File => ({ + (file): EnteFile => ({ ...file, magicMetadata: { ...file.magicMetadata, @@ -330,7 +222,7 @@ export const updateMagicMetadata = async (files: File[]) => { ); }; -export const updatePublicMagicMetadata = async (files: File[]) => { +export const updatePublicMagicMetadata = async (files: EnteFile[]) => { const token = getToken(); if (!token) { return; @@ -359,7 +251,7 @@ export const updatePublicMagicMetadata = async (files: File[]) => { } ); return files.map( - (file): File => ({ + (file): EnteFile => ({ ...file, pubMagicMetadata: { ...file.pubMagicMetadata, diff --git a/src/services/migrateThumbnailService.ts b/src/services/migrateThumbnailService.ts index 07bec18cd..c2a6aa0c1 100644 --- a/src/services/migrateThumbnailService.ts +++ b/src/services/migrateThumbnailService.ts @@ -1,5 +1,5 @@ import downloadManager from 'services/downloadManager'; -import { fileAttribute, getLocalFiles } from 'services/fileService'; +import { getLocalFiles } from 'services/fileService'; import { generateThumbnail } from 'services/upload/thumbnailService'; import { getToken } from 'utils/common/key'; import { logError } from 'utils/sentry'; @@ -12,6 +12,7 @@ import { SetProgressTracker } from 'components/FixLargeThumbnail'; import { getFileType } from './upload/readFileService'; import { getLocalTrash, getTrashedFiles } from './trashService'; import { EncryptionResult } from 'types/upload'; +import { fileAttribute } from 'types/file'; const ENDPOINT = getEndpoint(); const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB @@ -72,7 +73,7 @@ export async function replaceThumbnail( token, file ); - const dummyImageFile = new globalThis.File( + const dummyImageFile = new File( [originalThumbnail], file.metadata.title ); diff --git a/src/services/searchService.ts b/src/services/searchService.ts index 4bb3f02e0..b9e014c1d 100644 --- a/src/services/searchService.ts +++ b/src/services/searchService.ts @@ -4,7 +4,8 @@ import { getToken } from 'utils/common/key'; import { DateValue, Suggestion, SuggestionType } from 'components/SearchBar'; import HTTPService from './HTTPService'; import { Collection } from 'types/collection'; -import { File } from './fileService'; +import { EnteFile } from 'types/file'; + import { logError } from 'utils/sentry'; const ENDPOINT = getEndpoint(); @@ -118,7 +119,7 @@ export function searchCollection( ); } -export function searchFiles(searchPhrase: string, files: File[]) { +export function searchFiles(searchPhrase: string, files: EnteFile[]) { return files .map((file, idx) => ({ title: file.metadata.title, diff --git a/src/services/trashService.ts b/src/services/trashService.ts index 544575b67..c31f63176 100644 --- a/src/services/trashService.ts +++ b/src/services/trashService.ts @@ -6,7 +6,8 @@ import { decryptFile, mergeMetadata, sortFiles } from 'utils/file'; import { logError } from 'utils/sentry'; import localForage from 'utils/storage/localForage'; import { getCollection } from './collectionService'; -import { File } from './fileService'; +import { EnteFile } from 'types/file'; + import HTTPService from './HTTPService'; const TRASH = 'file-trash'; @@ -16,7 +17,7 @@ const DELETED_COLLECTION = 'deleted-collection'; const ENDPOINT = getEndpoint(); export interface TrashItem { - file: File; + file: EnteFile; isDeleted: boolean; isRestored: boolean; deleteBy: number; @@ -53,7 +54,7 @@ async function getLastSyncTime() { export async function syncTrash( collections: Collection[], setFiles: SetFiles, - files: File[] + files: EnteFile[] ): Promise { const trash = await getLocalTrash(); collections = [...collections, ...(await getLocalDeletedCollections())]; @@ -80,7 +81,7 @@ export const updateTrash = async ( collections: Map, sinceTime: number, setFiles: SetFiles, - files: File[], + files: EnteFile[], currentTrash: Trash ): Promise => { try { diff --git a/src/services/updateCreationTimeWithExif.ts b/src/services/updateCreationTimeWithExif.ts index b88004f54..ec36d1f0d 100644 --- a/src/services/updateCreationTimeWithExif.ts +++ b/src/services/updateCreationTimeWithExif.ts @@ -8,12 +8,14 @@ import { } from 'utils/file'; import { logError } from 'utils/sentry'; import downloadManager from './downloadManager'; -import { File, FILE_TYPE, updatePublicMagicMetadata } from './fileService'; +import { updatePublicMagicMetadata } from './fileService'; +import { EnteFile, FILE_TYPE } from 'types/file'; + import { getRawExif, getUNIXTime } from './upload/exifService'; import { getFileType } from './upload/readFileService'; export async function updateCreationTimeWithExif( - filesToBeUpdated: File[], + filesToBeUpdated: EnteFile[], fixOption: FIX_OPTIONS, customTime: Date, setProgressTracker: SetProgressTracker diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index 5792267c8..05768b374 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -28,7 +28,7 @@ interface ParsedEXIFData { } export async function getExifData( - receivedFile: globalThis.File, + receivedFile: File, fileTypeInfo: FileTypeInfo ): Promise { const nullExifData: ParsedEXIFData = { diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index f0e045e70..c9ebdf0d9 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -1,4 +1,4 @@ -import { FILE_TYPE } from 'services/fileService'; +import { FILE_TYPE } from 'types/file'; import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { FileTypeInfo } from './readFileService'; @@ -29,7 +29,7 @@ const NULL_PARSED_METADATA_JSON: ParsedMetaDataJSON = { }; export async function extractMetadata( - receivedFile: globalThis.File, + receivedFile: File, fileTypeInfo: FileTypeInfo ) { let exifData = null; @@ -52,7 +52,7 @@ export async function extractMetadata( export const getMetadataMapKey = (collectionID: number, title: string) => `${collectionID}_${title}`; -export async function parseMetadataJSON(receivedFile: globalThis.File) { +export async function parseMetadataJSON(receivedFile: File) { try { const metadataJSON: object = await new Promise((resolve, reject) => { const reader = new FileReader(); diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index e17be4b4a..fc9c0aca0 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -1,9 +1,10 @@ -import { - FILE_TYPE, - FORMAT_MISSED_BY_FILE_TYPE_LIB, -} from 'services/fileService'; +import { FILE_TYPE } from 'types/file'; import { logError } from 'utils/sentry'; -import { FILE_READER_CHUNK_SIZE, MULTIPART_PART_SIZE } from 'types/upload'; +import { + FILE_READER_CHUNK_SIZE, + FORMAT_MISSED_BY_FILE_TYPE_LIB, + MULTIPART_PART_SIZE, +} from 'types/upload'; import FileType from 'file-type/browser'; import { CustomError } from 'utils/common/errorUtil'; import { getFileExtension } from 'utils/file'; @@ -13,7 +14,7 @@ const TYPE_IMAGE = 'image'; const EDITED_FILE_SUFFIX = '-edited'; const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100; -export async function getFileData(worker, file: globalThis.File) { +export async function getFileData(worker, file: File) { if (file.size > MULTIPART_PART_SIZE) { return getFileStream(worker, file, FILE_READER_CHUNK_SIZE); } else { @@ -28,7 +29,7 @@ export interface FileTypeInfo { export async function getFileType( worker, - receivedFile: globalThis.File + receivedFile: File ): Promise { try { let fileType: FILE_TYPE; @@ -67,7 +68,7 @@ export async function getFileType( Get the original file name for edited file to associate it to original file's metadataJSON file as edited file doesn't have their own metadata file */ -export function getFileOriginalName(file: globalThis.File) { +export function getFileOriginalName(file: File) { let originalName: string = null; const isEditedFile = file.name.endsWith(EDITED_FILE_SUFFIX); @@ -79,7 +80,7 @@ export function getFileOriginalName(file: globalThis.File) { return originalName; } -async function getMimeType(worker, file: globalThis.File) { +async function getMimeType(worker, file: File) { const fileChunkBlob = file.slice(0, CHUNK_SIZE_FOR_TYPE_DETECTION); return getMimeTypeFromBlob(worker, fileChunkBlob); } @@ -94,7 +95,7 @@ export async function getMimeTypeFromBlob(worker, fileBlob: Blob) { } } -function getFileStream(worker, file: globalThis.File, chunkSize: number) { +function getFileStream(worker, file: File, chunkSize: number) { const fileChunkReader = fileChunkReaderMaker(worker, file, chunkSize); const stream = new ReadableStream({ @@ -114,11 +115,7 @@ function getFileStream(worker, file: globalThis.File, chunkSize: number) { }; } -async function* fileChunkReaderMaker( - worker, - file: globalThis.File, - chunkSize: number -) { +async function* fileChunkReaderMaker(worker, file: File, chunkSize: number) { let offset = 0; while (offset < file.size) { const blob = file.slice(offset, chunkSize + offset); diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 0bb4fd474..5b1605fde 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -1,4 +1,4 @@ -import { FILE_TYPE } from 'services/fileService'; +import { FILE_TYPE } from 'types/file'; import { CustomError, errorWithContext } from 'utils/common/errorUtil'; import { logError } from 'utils/sentry'; import { BLACK_THUMBNAIL_BASE64 } from '../../../public/images/black-thumbnail-b64'; @@ -22,7 +22,7 @@ interface Dimension { export async function generateThumbnail( worker, - file: globalThis.File, + file: File, fileTypeInfo: FileTypeInfo ): Promise<{ thumbnail: Uint8Array; hasStaticThumbnail: boolean }> { try { @@ -72,7 +72,7 @@ export async function generateThumbnail( export async function generateImageThumbnail( worker, - file: globalThis.File, + file: File, isHEIC: boolean ) { const canvas = document.createElement('canvas'); @@ -82,11 +82,7 @@ export async function generateImageThumbnail( let timeout = null; if (isHEIC) { - file = new globalThis.File( - [await worker.convertHEIC2JPEG(file)], - null, - null - ); + file = new File([await worker.convertHEIC2JPEG(file)], null, null); } let image = new Image(); imageURL = URL.createObjectURL(file); @@ -130,7 +126,7 @@ export async function generateImageThumbnail( return canvas; } -export async function generateVideoThumbnail(file: globalThis.File) { +export async function generateVideoThumbnail(file: File) { const canvas = document.createElement('canvas'); const canvasCTX = canvas.getContext('2d'); diff --git a/src/services/upload/uploadHttpClient.ts b/src/services/upload/uploadHttpClient.ts index a3bc006e5..968e5f53f 100644 --- a/src/services/upload/uploadHttpClient.ts +++ b/src/services/upload/uploadHttpClient.ts @@ -3,7 +3,7 @@ import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { logError } from 'utils/sentry'; import { UploadFile, UploadURL } from './uploadService'; -import { File } from '../fileService'; +import { EnteFile } from 'types/file'; import { CustomError, handleUploadError } from 'utils/common/errorUtil'; import { retryAsyncFunction } from 'utils/network'; import { MultipartUploadURLs } from './multiPartUploadService'; @@ -14,7 +14,7 @@ const MAX_URL_REQUESTS = 50; class UploadHttpClient { private uploadURLFetchInProgress = null; - async uploadFile(uploadFile: UploadFile): Promise { + async uploadFile(uploadFile: UploadFile): Promise { try { const token = getToken(); if (!token) { diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index f96c9ccce..46c53d1e2 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -1,4 +1,4 @@ -import { File, getLocalFiles, setLocalFiles } from '../fileService'; +import { getLocalFiles, setLocalFiles } from '../fileService'; import { getLocalCollections } from '../collectionService'; import { SetFiles } from 'pages/gallery'; import { ComlinkWorker, getDedicatedCryptoWorker } from 'utils/crypto'; @@ -20,6 +20,7 @@ import UIService from './uiService'; import UploadService from './uploadService'; import { CustomError } from 'utils/common/errorUtil'; import { Collection } from 'types/collection'; +import { EnteFile } from 'types/file'; const MAX_CONCURRENT_UPLOADS = 4; const FILE_UPLOAD_COMPLETED = 100; @@ -34,7 +35,7 @@ export enum FileUploadResults { } export interface FileWithCollection { - file: globalThis.File; + file: File; collectionID?: number; collection?: Collection; } @@ -53,8 +54,8 @@ class UploadManager { private metadataMap: MetadataMap; private filesToBeUploaded: FileWithCollection[]; private failedFiles: FileWithCollection[]; - private existingFilesCollectionWise: Map; - private existingFiles: File[]; + private existingFilesCollectionWise: Map; + private existingFiles: EnteFile[]; private setFiles: SetFiles; private collections: Map; public initUploader(progressUpdater: ProgressUpdater, setFiles: SetFiles) { diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index a05fae631..dcfd648b8 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -1,4 +1,4 @@ -import { fileAttribute } from '../fileService'; +import { fileAttribute } from 'types/file'; import { Collection } from 'types/collection'; import { logError } from 'utils/sentry'; import UploadHttpClient from './uploadHttpClient'; @@ -86,7 +86,7 @@ class UploadService { async readFile( worker: any, - rawFile: globalThis.File, + rawFile: File, fileTypeInfo: FileTypeInfo ): Promise { const { thumbnail, hasStaticThumbnail } = await generateThumbnail( diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 7e9204309..6fa015116 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -1,4 +1,4 @@ -import { File, FILE_TYPE } from 'services/fileService'; +import { EnteFile, FILE_TYPE } from 'types/file'; import { sleep } from 'utils/common'; import { handleUploadError, CustomError } from 'utils/common/errorUtil'; import { decryptFile } from 'utils/file'; @@ -22,11 +22,11 @@ const TwoSecondInMillSeconds = 2000; const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024; interface UploadResponse { fileUploadResult: FileUploadResults; - file?: File; + file?: EnteFile; } export default async function uploader( worker: any, - existingFilesInCollection: File[], + existingFilesInCollection: EnteFile[], fileWithCollection: FileWithCollection ): Promise { const { file: rawFile, collection } = fileWithCollection; diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 7d3a07598..4cab16298 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -1,5 +1,5 @@ import { User } from 'services/userService'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; export const COLLECTION_UPDATION_TIME = 'collection-updation-time'; export const COLLECTION_TABLE = 'collections'; @@ -51,7 +51,7 @@ export interface collectionAttributes { export interface CollectionAndItsLatestFile { collection: Collection; - file: File; + file: EnteFile; } export enum COLLECTION_SORT_BY { diff --git a/src/types/file/index.ts b/src/types/file/index.ts new file mode 100644 index 000000000..e48172834 --- /dev/null +++ b/src/types/file/index.ts @@ -0,0 +1,105 @@ +import { DataStream, MetadataObject } from 'types/upload'; + +export const FILES_TABLE = 'files'; + +export const MIN_EDITED_CREATION_TIME = new Date(1800, 0, 1); +export const MAX_EDITED_CREATION_TIME = new Date(); +export const ALL_TIME = new Date(1800, 0, 1, 23, 59, 59); + +export const MAX_EDITED_FILE_NAME_LENGTH = 100; + +export interface fileAttribute { + encryptedData?: DataStream | Uint8Array; + objectKey?: string; + decryptionHeader: string; +} + +export enum FILE_TYPE { + IMAGE, + VIDEO, + LIVE_PHOTO, + OTHERS, +} + +export enum VISIBILITY_STATE { + VISIBLE, + ARCHIVED, +} + +export interface MagicMetadataCore { + version: number; + count: number; + header: string; + data: Record; +} + +export interface EncryptedMagicMetadataCore + extends Omit { + data: string; +} + +export interface MagicMetadataProps { + visibility?: VISIBILITY_STATE; +} + +export interface MagicMetadata extends Omit { + data: MagicMetadataProps; +} + +export interface PublicMagicMetadataProps { + editedTime?: number; + editedName?: string; +} + +export interface PublicMagicMetadata extends Omit { + data: PublicMagicMetadataProps; +} + +export interface EnteFile { + id: number; + collectionID: number; + ownerID: number; + file: fileAttribute; + thumbnail: fileAttribute; + metadata: MetadataObject; + magicMetadata: MagicMetadata; + pubMagicMetadata: PublicMagicMetadata; + encryptedKey: string; + keyDecryptionNonce: string; + key: string; + src: string; + msrc: string; + html: string; + w: number; + h: number; + isDeleted: boolean; + isTrashed?: boolean; + deleteBy?: number; + dataIndex: number; + updationTime: number; +} + +export interface UpdateMagicMetadataRequest { + metadataList: UpdateMagicMetadata[]; +} + +export interface UpdateMagicMetadata { + id: number; + magicMetadata: EncryptedMagicMetadataCore; +} + +export const NEW_MAGIC_METADATA: MagicMetadataCore = { + version: 0, + data: {}, + header: null, + count: 0, +}; + +export interface TrashRequest { + items: TrashRequestItems[]; +} + +export interface TrashRequestItems { + fileID: number; + collectionID: number; +} diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index a91a8ad3d..5f8616623 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,6 +1,13 @@ -import { fileAttribute, FILE_TYPE } from 'services/fileService'; +import { fileAttribute, FILE_TYPE } from 'types/file'; import { ENCRYPTION_CHUNK_SIZE } from 'types'; +// list of format that were missed by type-detection for some files. +export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ + { fileType: FILE_TYPE.IMAGE, exactType: 'jpeg' }, + { fileType: FILE_TYPE.IMAGE, exactType: 'jpg' }, + { fileType: FILE_TYPE.VIDEO, exactType: 'webm' }, +]; + // this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part. export const MULTIPART_PART_SIZE = 20 * 1024 * 1024; diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index abc557bc6..0b328bc62 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -5,7 +5,8 @@ import { restoreToCollection, } from 'services/collectionService'; import { downloadFiles, getSelectedFiles } from 'utils/file'; -import { File, getLocalFiles } from 'services/fileService'; +import { getLocalFiles } from 'services/fileService'; +import { EnteFile } from 'types/file'; import { CustomError } from 'utils/common/errorUtil'; import { SelectedState } from 'pages/gallery'; import { User } from 'services/userService'; @@ -25,7 +26,7 @@ export async function handleCollectionOps( type: COLLECTION_OPS_TYPE, setCollectionSelectorView: (value: boolean) => void, selected: SelectedState, - files: File[], + files: EnteFile[], setActiveCollection: (id: number) => void, collection: Collection ) { diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index f0238ad25..7f3eab2ca 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -5,15 +5,16 @@ import { ExportRecord, METADATA_FOLDER_NAME, } from 'types/export'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; + import { MetadataObject } from 'types/upload'; import { formatDate, splitFilenameAndExtension } from 'utils/file'; -export const getExportRecordFileUID = (file: File) => +export const getExportRecordFileUID = (file: EnteFile) => `${file.id}_${file.collectionID}_${file.updationTime}`; export const getExportQueuedFiles = ( - allFiles: File[], + allFiles: EnteFile[], exportRecord: ExportRecord ) => { const queuedFiles = new Set(exportRecord?.queuedFiles); @@ -79,7 +80,7 @@ export const getCollectionsRenamedAfterLastExport = ( }; export const getFilesUploadedAfterLastExport = ( - allFiles: File[], + allFiles: EnteFile[], exportRecord: ExportRecord ) => { const exportedFiles = new Set(exportRecord?.exportedFiles); @@ -93,7 +94,7 @@ export const getFilesUploadedAfterLastExport = ( }; export const getExportedFiles = ( - allFiles: File[], + allFiles: EnteFile[], exportRecord: ExportRecord ) => { const exportedFileIds = new Set(exportRecord?.exportedFiles); @@ -107,7 +108,7 @@ export const getExportedFiles = ( }; export const getExportFailedFiles = ( - allFiles: File[], + allFiles: EnteFile[], exportRecord: ExportRecord ) => { const failedFiles = new Set(exportRecord?.failedFiles); @@ -224,14 +225,17 @@ export const getOldCollectionFolderPath = ( collection: Collection ) => `${dir}/${collection.id}_${oldSanitizeName(collection.name)}`; -export const getOldFileSavePath = (collectionFolderPath: string, file: File) => +export const getOldFileSavePath = ( + collectionFolderPath: string, + file: EnteFile +) => `${collectionFolderPath}/${file.id}_${oldSanitizeName( file.metadata.title )}`; export const getOldFileMetadataSavePath = ( collectionFolderPath: string, - file: File + file: EnteFile ) => `${collectionFolderPath}/${METADATA_FOLDER_NAME}/${ file.id diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 66bcd9ea1..1e2b19df3 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -1,14 +1,14 @@ import { SelectedState } from 'pages/gallery'; import { Collection } from 'types/collection'; import { - File, + EnteFile, fileAttribute, FILE_TYPE, MagicMetadataProps, NEW_MAGIC_METADATA, PublicMagicMetadataProps, VISIBILITY_STATE, -} from 'services/fileService'; +} from 'types/file'; import { decodeMotionPhoto } from 'services/motionPhotoService'; import { getMimeTypeFromBlob } from 'services/upload/readFileService'; import DownloadManager from 'services/downloadManager'; @@ -40,7 +40,7 @@ export function downloadAsFile(filename: string, content: string) { a.remove(); } -export async function downloadFile(file: File) { +export async function downloadFile(file: EnteFile) { const a = document.createElement('a'); a.style.display = 'none'; let fileURL = await DownloadManager.getCachedOriginalFile(file); @@ -89,8 +89,8 @@ export function isFileHEIC(mimeType: string) { ); } -export function sortFilesIntoCollections(files: File[]) { - const collectionWiseFiles = new Map(); +export function sortFilesIntoCollections(files: EnteFile[]) { + const collectionWiseFiles = new Map(); for (const file of files) { if (!collectionWiseFiles.has(file.collectionID)) { collectionWiseFiles.set(file.collectionID, []); @@ -111,10 +111,10 @@ function getSelectedFileIds(selectedFiles: SelectedState) { } export function getSelectedFiles( selected: SelectedState, - files: File[] -): File[] { + files: EnteFile[] +): EnteFile[] { const filesIDs = new Set(getSelectedFileIds(selected)); - const selectedFiles: File[] = []; + const selectedFiles: EnteFile[] = []; const foundFiles = new Set(); for (const file of files) { if (filesIDs.has(file.id) && !foundFiles.has(file.id)) { @@ -181,7 +181,7 @@ export function formatDateRelative(date: number) { ); } -export function sortFiles(files: File[]) { +export function sortFiles(files: EnteFile[]) { // sort according to modification time first files = files.sort((a, b) => { if (!b.metadata?.modificationTime) { @@ -209,7 +209,7 @@ export function sortFiles(files: File[]) { return files; } -export async function decryptFile(file: File, collection: Collection) { +export async function decryptFile(file: EnteFile, collection: Collection) { try { const worker = await new CryptoWorker(); file.key = await worker.decryptB64( @@ -244,7 +244,7 @@ export async function decryptFile(file: File, collection: Collection) { } } -export function removeUnnecessaryFileProps(files: File[]): File[] { +export function removeUnnecessaryFileProps(files: EnteFile[]): EnteFile[] { const stripedFiles = files.map((file) => { delete file.src; delete file.msrc; @@ -294,7 +294,7 @@ export function generateStreamFromArrayBuffer(data: Uint8Array) { }); } -export async function convertForPreview(file: File, fileBlob: Blob) { +export async function convertForPreview(file: EnteFile, fileBlob: Blob) { if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) { const originalName = fileNameWithoutExtension(file.metadata.title); const motionPhoto = await decodeMotionPhoto(fileBlob, originalName); @@ -312,7 +312,7 @@ export async function convertForPreview(file: File, fileBlob: Blob) { return fileBlob; } -export function fileIsArchived(file: File) { +export function fileIsArchived(file: EnteFile) { if ( !file || !file.magicMetadata || @@ -326,7 +326,7 @@ export function fileIsArchived(file: File) { } export async function updateMagicMetadataProps( - file: File, + file: EnteFile, magicMetadataUpdates: MagicMetadataProps ) { const worker = await new CryptoWorker(); @@ -362,7 +362,7 @@ export async function updateMagicMetadataProps( } } export async function updatePublicMagicMetadataProps( - file: File, + file: EnteFile, publicMetadataUpdates: PublicMagicMetadataProps ) { const worker = await new CryptoWorker(); @@ -397,12 +397,12 @@ export async function updatePublicMagicMetadataProps( } export async function changeFilesVisibility( - files: File[], + files: EnteFile[], selected: SelectedState, visibility: VISIBILITY_STATE ) { const selectedFiles = getSelectedFiles(selected, files); - const updatedFiles: File[] = []; + const updatedFiles: EnteFile[] = []; for (const file of selectedFiles) { const updatedMagicMetadataProps: MagicMetadataProps = { visibility, @@ -415,7 +415,10 @@ export async function changeFilesVisibility( return updatedFiles; } -export async function changeFileCreationTime(file: File, editedTime: number) { +export async function changeFileCreationTime( + file: EnteFile, + editedTime: number +) { const updatedPublicMagicMetadataProps: PublicMagicMetadataProps = { editedTime, }; @@ -426,7 +429,7 @@ export async function changeFileCreationTime(file: File, editedTime: number) { ); } -export async function changeFileName(file: File, editedName: string) { +export async function changeFileName(file: EnteFile, editedName: string) { const updatedPublicMagicMetadataProps: PublicMagicMetadataProps = { editedName, }; @@ -437,7 +440,7 @@ export async function changeFileName(file: File, editedName: string) { ); } -export function isSharedFile(file: File) { +export function isSharedFile(file: EnteFile) { const user: User = getData(LS_KEYS.USER); if (!user?.id || !file?.ownerID) { @@ -446,7 +449,7 @@ export function isSharedFile(file: File) { return file.ownerID !== user.id; } -export function mergeMetadata(files: File[]): File[] { +export function mergeMetadata(files: EnteFile[]): EnteFile[] { return files.map((file) => ({ ...file, metadata: { @@ -467,8 +470,8 @@ export function mergeMetadata(files: File[]): File[] { } export function updateExistingFilePubMetadata( - existingFile: File, - updatedFile: File + existingFile: EnteFile, + updatedFile: EnteFile ) { existingFile.pubMagicMetadata = updatedFile.pubMagicMetadata; existingFile.metadata = mergeMetadata([existingFile])[0].metadata; @@ -476,11 +479,11 @@ export function updateExistingFilePubMetadata( export async function getFileFromURL(fileURL: string) { const fileBlob = await (await fetch(fileURL)).blob(); - const fileFile = new globalThis.File([fileBlob], 'temp'); + const fileFile = new File([fileBlob], 'temp'); return fileFile; } -export function getUniqueFiles(files: File[]) { +export function getUniqueFiles(files: EnteFile[]) { const idSet = new Set(); return files.filter((file) => { if (!idSet.has(file.id)) { @@ -491,7 +494,7 @@ export function getUniqueFiles(files: File[]) { } }); } -export function getNonTrashedUniqueUserFiles(files: File[]) { +export function getNonTrashedUniqueUserFiles(files: EnteFile[]) { const user: User = getData(LS_KEYS.USER) ?? {}; return getUniqueFiles( files.filter( @@ -502,7 +505,7 @@ export function getNonTrashedUniqueUserFiles(files: File[]) { ); } -export async function downloadFiles(files: File[]) { +export async function downloadFiles(files: EnteFile[]) { for (const file of files) { try { await downloadFile(file); @@ -512,7 +515,7 @@ export async function downloadFiles(files: File[]) { } } -export function needsConversionForPreview(file: File) { +export function needsConversionForPreview(file: EnteFile) { const fileExtension = splitFilenameAndExtension(file.metadata.title)[1]; if ( file.metadata.fileType === FILE_TYPE.LIVE_PHOTO || diff --git a/src/utils/search/index.ts b/src/utils/search/index.ts index 60f6211e1..1315782af 100644 --- a/src/utils/search/index.ts +++ b/src/utils/search/index.ts @@ -1,5 +1,5 @@ import { DateValue } from 'components/SearchBar'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; import { Bbox } from 'services/searchService'; export function isInsideBox( @@ -36,7 +36,7 @@ export const isSameDay = (baseDate: DateValue) => (compareDate: Date) => { }; export function getFilesWithCreationDay( - files: File[], + files: EnteFile[], searchedDate: DateValue ) { const isSearchedDate = isSameDay(searchedDate); diff --git a/src/utils/upload/index.ts b/src/utils/upload/index.ts index bbc15c8b6..28761733d 100644 --- a/src/utils/upload/index.ts +++ b/src/utils/upload/index.ts @@ -1,10 +1,11 @@ import { FileWithCollection } from 'services/upload/uploadManager'; import { MetadataObject } from 'types/upload'; -import { File } from 'services/fileService'; +import { EnteFile } from 'types/file'; + const TYPE_JSON = 'json'; export function fileAlreadyInCollection( - existingFilesInCollection: File[], + existingFilesInCollection: EnteFile[], newFileMetadata: MetadataObject ): boolean { for (const existingFile of existingFilesInCollection) { From b5b31a8350e3bbd57a730b3cba4d3b99cbbe7759 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 15:36:07 +0530 Subject: [PATCH 08/69] move non exported constant back to origin file --- src/services/billingService.ts | 7 ++++++- src/services/collectionService.ts | 4 ++-- src/services/exportService.ts | 5 +++-- src/types/billing/index.ts | 6 ------ src/types/collection/index.ts | 3 --- src/types/export/index.ts | 2 -- src/utils/billing/index.ts | 7 ++++--- 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/services/billingService.ts b/src/services/billingService.ts index d73df6441..93f8e7b81 100644 --- a/src/services/billingService.ts +++ b/src/services/billingService.ts @@ -5,10 +5,15 @@ import { convertToHumanReadable } from 'utils/billing'; import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; import { getPaymentToken } from './userService'; -import { Plan, PaymentActionType, Subscription } from 'types/billing'; +import { Plan, Subscription } from 'types/billing'; const ENDPOINT = getEndpoint(); +enum PaymentActionType { + Buy = 'buy', + Update = 'update', +} + class billingService { public async getPlans(): Promise { try { diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index e87da0225..78b904387 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -15,7 +15,6 @@ import { CustomError } from 'utils/common/errorUtil'; import { sortFiles } from 'utils/file'; import { Collection, - COLLECTION_UPDATION_TIME, COLLECTION_SORT_BY, CollectionAndItsLatestFile, CollectionType, @@ -23,10 +22,11 @@ import { MoveToCollectionRequest, EncryptedFileKey, RemoveFromCollectionRequest, - COLLECTION_TABLE, } from 'types/collection'; const ENDPOINT = getEndpoint(); +const COLLECTION_TABLE = 'collections'; +const COLLECTION_UPDATION_TIME = 'collection-updation-time'; const getCollectionWithSecrets = async ( collection: Collection, diff --git a/src/services/exportService.ts b/src/services/exportService.ts index 762afc0ff..ffea764e5 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -51,10 +51,11 @@ import { CollectionIDPathMap, RecordType, ExportRecord, - EXPORT_RECORD_FILE_NAME, - LATEST_EXPORT_VERSION, } from 'types/export'; +const LATEST_EXPORT_VERSION = 1; +const EXPORT_RECORD_FILE_NAME = 'export_status.json'; + class ExportService { ElectronAPIs: any; diff --git a/src/types/billing/index.ts b/src/types/billing/index.ts index 464239ac8..59a19b055 100644 --- a/src/types/billing/index.ts +++ b/src/types/billing/index.ts @@ -1,9 +1,3 @@ -export enum PaymentActionType { - Buy = 'buy', - Update = 'update', -} -export const FREE_PLAN = 'free'; - export interface Subscription { id: number; userID: number; diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 4cab16298..990bd5822 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -1,9 +1,6 @@ import { User } from 'services/userService'; import { EnteFile } from 'types/file'; -export const COLLECTION_UPDATION_TIME = 'collection-updation-time'; -export const COLLECTION_TABLE = 'collections'; - export enum CollectionType { folder = 'folder', favorites = 'favorites', diff --git a/src/types/export/index.ts b/src/types/export/index.ts index 14249e57d..d38eb731b 100644 --- a/src/types/export/index.ts +++ b/src/types/export/index.ts @@ -1,4 +1,3 @@ -export const EXPORT_RECORD_FILE_NAME = 'export_status.json'; export const METADATA_FOLDER_NAME = 'metadata'; export enum ExportNotification { @@ -15,7 +14,6 @@ export enum RecordType { SUCCESS = 'success', FAILED = 'failed', } -export const LATEST_EXPORT_VERSION = 1; export type CollectionIDPathMap = Map; export interface ExportProgress { diff --git a/src/utils/billing/index.ts b/src/utils/billing/index.ts index 3ea369fe0..c681dd71b 100644 --- a/src/utils/billing/index.ts +++ b/src/utils/billing/index.ts @@ -1,6 +1,6 @@ import constants from 'utils/strings/constants'; import billingService from 'services/billingService'; -import { FREE_PLAN, Plan, Subscription } from 'types/billing'; +import { Plan, Subscription } from 'types/billing'; import { NextRouter } from 'next/router'; import { SetDialogMessage } from 'components/MessageDialog'; import { SetLoading } from 'pages/gallery'; @@ -8,7 +8,8 @@ import { getData, LS_KEYS } from '../storage/localStorage'; import { CustomError } from '../common/errorUtil'; import { logError } from '../sentry'; -const STRIPE = 'stripe'; +const PAYMENT_PROVIDER_STRIPE = 'stripe'; +const FREE_PLAN = 'free'; enum FAILURE_REASON { AUTHENTICATION_FAILED = 'authentication_failed', @@ -91,7 +92,7 @@ export function hasStripeSubscription(subscription: Subscription) { return ( hasPaidSubscription(subscription) && subscription.paymentProvider.length > 0 && - subscription.paymentProvider === STRIPE + subscription.paymentProvider === PAYMENT_PROVIDER_STRIPE ); } From 79f6ebc454db4ece2759c468056f64710677802e Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 15:48:33 +0530 Subject: [PATCH 09/69] moved search related types to types/search --- src/components/SearchBar.tsx | 19 +------------------ src/pages/gallery/index.tsx | 4 ++-- src/services/searchService.ts | 14 +++++++------- src/types/search/index.ts | 27 +++++++++++++++++++++++++++ src/utils/search/index.ts | 3 +-- 5 files changed, 38 insertions(+), 29 deletions(-) create mode 100644 src/types/search/index.ts diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index a9dd2c796..a1ad2e360 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -5,7 +5,6 @@ import AsyncSelect from 'react-select/async'; import { components } from 'react-select'; import debounce from 'debounce-promise'; import { - Bbox, getHolidaySuggestion, getYearSuggestion, parseHumanDate, @@ -26,6 +25,7 @@ import ImageIcon from './icons/ImageIcon'; import VideoIcon from './icons/VideoIcon'; import { IconButton } from './Container'; import { EnteFile, FILE_TYPE } from 'types/file'; +import { Suggestion, SuggestionType, DateValue, Bbox } from 'types/search'; const Wrapper = styled.div<{ isDisabled: boolean; isOpen: boolean }>` position: fixed; @@ -76,23 +76,6 @@ const SearchInput = styled.div` margin: auto; `; -export enum SuggestionType { - DATE, - LOCATION, - COLLECTION, - IMAGE, - VIDEO, -} -export interface DateValue { - date?: number; - month?: number; - year?: number; -} -export interface Suggestion { - type: SuggestionType; - label: string; - value: Bbox | DateValue | number; -} interface Props { isOpen: boolean; isFirstFetch: boolean; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index cecafc80c..da09e0da1 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -52,8 +52,8 @@ import { sortFiles, sortFilesIntoCollections, } from 'utils/file'; -import SearchBar, { DateValue } from 'components/SearchBar'; -import { Bbox } from 'services/searchService'; +import { DateValue, Bbox } from 'types/search'; +import SearchBar from 'components/SearchBar'; import SelectedFileOptions from 'components/pages/gallery/SelectedFileOptions'; import CollectionSelector, { CollectionSelectorAttributes, diff --git a/src/services/searchService.ts b/src/services/searchService.ts index b9e014c1d..b69c88e75 100644 --- a/src/services/searchService.ts +++ b/src/services/searchService.ts @@ -1,21 +1,21 @@ import * as chrono from 'chrono-node'; import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; -import { DateValue, Suggestion, SuggestionType } from 'components/SearchBar'; import HTTPService from './HTTPService'; import { Collection } from 'types/collection'; import { EnteFile } from 'types/file'; import { logError } from 'utils/sentry'; +import { + DateValue, + LocationSearchResponse, + Suggestion, + SuggestionType, +} from 'types/search'; const ENDPOINT = getEndpoint(); + const DIGITS = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']); -export type Bbox = [number, number, number, number]; -export interface LocationSearchResponse { - place: string; - bbox: Bbox; -} -export const getMapboxToken = () => process.env.NEXT_PUBLIC_MAPBOX_TOKEN; export function parseHumanDate(humanDate: string): DateValue[] { const date = chrono.parseDate(humanDate); diff --git a/src/types/search/index.ts b/src/types/search/index.ts new file mode 100644 index 000000000..27ba7d255 --- /dev/null +++ b/src/types/search/index.ts @@ -0,0 +1,27 @@ +export type Bbox = [number, number, number, number]; + +export interface LocationSearchResponse { + place: string; + bbox: Bbox; +} +export const getMapboxToken = () => process.env.NEXT_PUBLIC_MAPBOX_TOKEN; + +export enum SuggestionType { + DATE, + LOCATION, + COLLECTION, + IMAGE, + VIDEO, +} + +export interface DateValue { + date?: number; + month?: number; + year?: number; +} + +export interface Suggestion { + type: SuggestionType; + label: string; + value: Bbox | DateValue | number; +} diff --git a/src/utils/search/index.ts b/src/utils/search/index.ts index 1315782af..ce9da7f1c 100644 --- a/src/utils/search/index.ts +++ b/src/utils/search/index.ts @@ -1,6 +1,5 @@ -import { DateValue } from 'components/SearchBar'; import { EnteFile } from 'types/file'; -import { Bbox } from 'services/searchService'; +import { Bbox, DateValue } from 'types/search'; export function isInsideBox( file: { longitude: number; latitude: number }, From 4011b6fbe812f2aac25ac5b75b865594f2c9f8a4 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 15:51:35 +0530 Subject: [PATCH 10/69] move trash related types to types/trash --- src/pages/gallery/index.tsx | 3 ++- src/services/trashService.ts | 11 +---------- src/types/trash/index.ts | 11 +++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 src/types/trash/index.ts diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index da09e0da1..a220c78ae 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -87,8 +87,9 @@ import { getLocalTrash, getTrashedFiles, syncTrash, - Trash, } from 'services/trashService'; +import { Trash } from 'types/trash'; + import DeleteBtn from 'components/DeleteBtn'; import FixCreationTime, { FixCreationTimeAttributes, diff --git a/src/services/trashService.ts b/src/services/trashService.ts index c31f63176..70cfea220 100644 --- a/src/services/trashService.ts +++ b/src/services/trashService.ts @@ -9,6 +9,7 @@ import { getCollection } from './collectionService'; import { EnteFile } from 'types/file'; import HTTPService from './HTTPService'; +import { Trash, TrashItem } from 'types/trash'; const TRASH = 'file-trash'; const TRASH_TIME = 'trash-time'; @@ -16,16 +17,6 @@ const DELETED_COLLECTION = 'deleted-collection'; const ENDPOINT = getEndpoint(); -export interface TrashItem { - file: EnteFile; - isDeleted: boolean; - isRestored: boolean; - deleteBy: number; - createdAt: number; - updatedAt: number; -} -export type Trash = TrashItem[]; - export async function getLocalTrash() { const trash = (await localForage.getItem(TRASH)) || []; return trash; diff --git a/src/types/trash/index.ts b/src/types/trash/index.ts new file mode 100644 index 000000000..9a9492ce6 --- /dev/null +++ b/src/types/trash/index.ts @@ -0,0 +1,11 @@ +import { EnteFile } from 'types/file'; + +export interface TrashItem { + file: EnteFile; + isDeleted: boolean; + isRestored: boolean; + deleteBy: number; + createdAt: number; + updatedAt: number; +} +export type Trash = TrashItem[]; From 41b8ed55a2732aa6348ff6041c3b5ac017d2cee3 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:09:42 +0530 Subject: [PATCH 11/69] moved user related types to types/user --- src/components/CollectionShare.tsx | 2 +- src/components/ExportModal.tsx | 2 +- .../pages/gallery/CollectionSelector.tsx | 2 +- src/components/pages/gallery/Collections.tsx | 2 +- .../pages/gallery/SelectedFileOptions.tsx | 6 +- src/pages/change-password/index.tsx | 3 +- src/pages/credentials/index.tsx | 3 +- src/pages/generate/index.tsx | 5 +- src/pages/recover/index.tsx | 4 +- src/pages/two-factor/setup/index.tsx | 7 +- src/pages/two-factor/verify/index.tsx | 3 +- src/pages/verify/index.tsx | 6 +- src/services/exportService.ts | 3 +- src/services/userService.ts | 68 +++--------------- src/types.ts | 15 ---- src/types/collection/index.ts | 2 +- src/types/user/index.ts | 70 +++++++++++++++++++ src/utils/collection/index.ts | 2 +- src/utils/crypto/index.ts | 2 +- src/utils/file/index.ts | 2 +- 20 files changed, 108 insertions(+), 101 deletions(-) create mode 100644 src/types/user/index.ts diff --git a/src/components/CollectionShare.tsx b/src/components/CollectionShare.tsx index 9c234bffc..3aabd3b0b 100644 --- a/src/components/CollectionShare.tsx +++ b/src/components/CollectionShare.tsx @@ -6,7 +6,7 @@ import Form from 'react-bootstrap/Form'; import FormControl from 'react-bootstrap/FormControl'; import { Button, Col, Table } from 'react-bootstrap'; import { DeadCenter } from 'pages/gallery'; -import { User } from 'services/userService'; +import { User } from 'types/user'; import { shareCollection, unshareCollection } from 'services/collectionService'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import SubmitButton from './SubmitButton'; diff --git a/src/components/ExportModal.tsx b/src/components/ExportModal.tsx index 91cb4ace4..b4822684c 100644 --- a/src/components/ExportModal.tsx +++ b/src/components/ExportModal.tsx @@ -9,7 +9,7 @@ import { ExportType, } from 'types/export'; import { getLocalFiles } from 'services/fileService'; -import { User } from 'services/userService'; +import { User } from 'types/user'; import styled from 'styled-components'; import { sleep } from 'utils/common'; import { getExportRecordFileUID } from 'utils/export'; diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index 128b32e23..9757b4ba7 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -5,7 +5,7 @@ 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'; +import { User } from 'types/user'; import { Collection, CollectionAndItsLatestFile, diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index 3a43b0fb2..77bf323e1 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -6,7 +6,7 @@ import NavigationButton, { import React, { useEffect, useRef, useState } from 'react'; import { OverlayTrigger, Tooltip } from 'react-bootstrap'; import { sortCollections } from 'services/collectionService'; -import { User } from 'services/userService'; +import { User } from 'types/user'; import styled from 'styled-components'; import { IMAGE_CONTAINER_MAX_WIDTH } from 'types'; import { diff --git a/src/components/pages/gallery/SelectedFileOptions.tsx b/src/components/pages/gallery/SelectedFileOptions.tsx index ce79cfd8d..a7ba7249e 100644 --- a/src/components/pages/gallery/SelectedFileOptions.tsx +++ b/src/components/pages/gallery/SelectedFileOptions.tsx @@ -19,11 +19,9 @@ import RemoveIcon from 'components/icons/RemoveIcon'; import RestoreIcon from 'components/icons/RestoreIcon'; import ClockIcon from 'components/icons/ClockIcon'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; -import { - FIX_CREATION_TIME_VISIBLE_TO_USER_IDS, - User, -} from 'services/userService'; +import { FIX_CREATION_TIME_VISIBLE_TO_USER_IDS } from 'services/userService'; import DownloadIcon from 'components/icons/DownloadIcon'; +import { User } from 'types/user'; interface Props { addToCollectionHelper: (collection: Collection) => void; diff --git a/src/pages/change-password/index.tsx b/src/pages/change-password/index.tsx index 1b851342b..c58b0d815 100644 --- a/src/pages/change-password/index.tsx +++ b/src/pages/change-password/index.tsx @@ -8,11 +8,12 @@ import CryptoWorker, { B64EncryptionResult, } from 'utils/crypto'; import { getActualKey } from 'utils/common/key'; -import { setKeys, UpdatedKey } from 'services/userService'; +import { setKeys } from 'services/userService'; import SetPasswordForm from 'components/SetPasswordForm'; import { AppContext } from 'pages/_app'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; import { PAGES } from 'types'; +import { UpdatedKey } from 'types/user'; export interface KEK { key: string; diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx index fff9be33f..4f07100ad 100644 --- a/src/pages/credentials/index.tsx +++ b/src/pages/credentials/index.tsx @@ -3,7 +3,7 @@ import React, { useContext, useEffect, useState } from 'react'; import constants from 'utils/strings/constants'; import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { KeyAttributes, PAGES } from 'types'; +import { PAGES } from 'types'; import { SESSION_KEYS, getKey } from 'utils/storage/sessionStorage'; import CryptoWorker, { decryptAndStoreToken, @@ -18,6 +18,7 @@ import { Button, Card } from 'react-bootstrap'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; import { logError } from 'utils/sentry'; +import { KeyAttributes } from 'types/user'; export default function Credentials() { const router = useRouter(); diff --git a/src/pages/generate/index.tsx b/src/pages/generate/index.tsx index 62d6aa6aa..4d1c57a5a 100644 --- a/src/pages/generate/index.tsx +++ b/src/pages/generate/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useContext } from 'react'; import constants from 'utils/strings/constants'; -import { logoutUser, putAttributes, User } from 'services/userService'; +import { logoutUser, putAttributes } from 'services/userService'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; @@ -12,11 +12,12 @@ import { import SetPasswordForm from 'components/SetPasswordForm'; import { justSignedUp, setJustSignedUp } from 'utils/storage'; import RecoveryKeyModal from 'components/RecoveryKeyModal'; -import { KeyAttributes, PAGES } from 'types'; +import { PAGES } from 'types'; import Container from 'components/Container'; import EnteSpinner from 'components/EnteSpinner'; import { AppContext } from 'pages/_app'; import { logError } from 'utils/sentry'; +import { KeyAttributes, User } from 'types/user'; export interface KEK { key: string; diff --git a/src/pages/recover/index.tsx b/src/pages/recover/index.tsx index fdfe7fbb8..d0c258858 100644 --- a/src/pages/recover/index.tsx +++ b/src/pages/recover/index.tsx @@ -7,7 +7,7 @@ import { setData, } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { KeyAttributes, PAGES } from 'types'; +import { PAGES } from 'types'; import CryptoWorker, { decryptAndStoreToken, SaveKeyInSessionStore, @@ -20,7 +20,7 @@ import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; import { logError } from 'utils/sentry'; import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { User } from 'services/userService'; +import { KeyAttributes, User } from 'types/user'; const bip39 = require('bip39'); // mobile client library only supports english. bip39.setDefaultWordlist('english'); diff --git a/src/pages/two-factor/setup/index.tsx b/src/pages/two-factor/setup/index.tsx index 85a9df614..24587c0f0 100644 --- a/src/pages/two-factor/setup/index.tsx +++ b/src/pages/two-factor/setup/index.tsx @@ -4,11 +4,7 @@ import { CodeBlock, FreeFlowText } from 'components/RecoveryKeyModal'; import { DeadCenter } from 'pages/gallery'; import React, { useContext, useEffect, useState } from 'react'; import { Button, Card } from 'react-bootstrap'; -import { - enableTwoFactor, - setupTwoFactor, - TwoFactorSecret, -} from 'services/userService'; +import { enableTwoFactor, setupTwoFactor } from 'services/userService'; import styled from 'styled-components'; import constants from 'utils/strings/constants'; import Container from 'components/Container'; @@ -19,6 +15,7 @@ import { encryptWithRecoveryKey } from 'utils/crypto'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; import { PAGES } from 'types'; +import { TwoFactorSecret } from 'types/user'; enum SetupMode { QR_CODE, diff --git a/src/pages/two-factor/verify/index.tsx b/src/pages/two-factor/verify/index.tsx index 4c70ea593..d21812ff7 100644 --- a/src/pages/two-factor/verify/index.tsx +++ b/src/pages/two-factor/verify/index.tsx @@ -4,8 +4,9 @@ import VerifyTwoFactor from 'components/VerifyTwoFactor'; import router from 'next/router'; import React, { useEffect, useState } from 'react'; import { Button, Card } from 'react-bootstrap'; -import { logoutUser, User, verifyTwoFactor } from 'services/userService'; +import { logoutUser, verifyTwoFactor } from 'services/userService'; import { PAGES } from 'types'; +import { User } from 'types/user'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 3a8324f79..4e8ca3bac 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -12,8 +12,6 @@ import { getOtt, logoutUser, clearFiles, - EmailVerificationResponse, - User, putAttributes, } from 'services/userService'; import { setIsFirstLogin } from 'utils/storage'; @@ -21,7 +19,9 @@ import SubmitButton from 'components/SubmitButton'; import { clearKeys } from 'utils/storage/sessionStorage'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; -import { KeyAttributes, PAGES } from 'types'; +import { PAGES } from 'types'; +import { User } from '@sentry/nextjs'; +import { KeyAttributes, EmailVerificationResponse } from 'types/user'; interface formValues { ott: string; diff --git a/src/services/exportService.ts b/src/services/exportService.ts index ffea764e5..0ee0643d0 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -39,7 +39,7 @@ import { TYPE_JPEG, TYPE_JPG, } from 'utils/file'; -import { User } from './userService'; + import { updateFileCreationDateInEXIF } from './upload/exifService'; import { MetadataObject } from 'types/upload'; import QueueProcessor from './upload/queueProcessor'; @@ -52,6 +52,7 @@ import { RecordType, ExportRecord, } from 'types/export'; +import { User } from 'types/user'; const LATEST_EXPORT_VERSION = 1; const EXPORT_RECORD_FILE_NAME = 'export_status.json'; diff --git a/src/services/userService.ts b/src/services/userService.ts index 02d8a6482..133cab657 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -1,4 +1,4 @@ -import { KeyAttributes, PAGES } from 'types'; +import { PAGES } from 'types'; import { getEndpoint } from 'utils/common/apiUtil'; import { clearKeys } from 'utils/storage/sessionStorage'; import router from 'next/router'; @@ -8,70 +8,22 @@ import { getToken } from 'utils/common/key'; import HTTPService from './HTTPService'; import { B64EncryptionResult } from 'utils/crypto'; import { logError } from 'utils/sentry'; -import { Subscription } from 'types/billing'; +import { + KeyAttributes, + UpdatedKey, + RecoveryKey, + TwoFactorSecret, + TwoFactorVerificationResponse, + TwoFactorRecoveryResponse, + UserDetails, +} from 'types/user'; -export interface UpdatedKey { - kekSalt: string; - encryptedKey: string; - keyDecryptionNonce: string; - memLimit: number; - opsLimit: number; -} - -export interface RecoveryKey { - masterKeyEncryptedWithRecoveryKey: string; - masterKeyDecryptionNonce: string; - recoveryKeyEncryptedWithMasterKey: string; - recoveryKeyDecryptionNonce: string; -} const ENDPOINT = getEndpoint(); const HAS_SET_KEYS = 'hasSetKeys'; export const FIX_CREATION_TIME_VISIBLE_TO_USER_IDS = [1, 125, 243, 341]; -export interface User { - id: number; - name: string; - email: string; - token: string; - encryptedToken: string; - isTwoFactorEnabled: boolean; - twoFactorSessionID: string; -} -export interface EmailVerificationResponse { - id: number; - keyAttributes?: KeyAttributes; - encryptedToken?: string; - token?: string; - twoFactorSessionID: string; -} - -export interface TwoFactorVerificationResponse { - id: number; - keyAttributes: KeyAttributes; - encryptedToken?: string; - token?: string; -} - -export interface TwoFactorSecret { - secretCode: string; - qrCode: string; -} - -export interface TwoFactorRecoveryResponse { - encryptedSecret: string; - secretDecryptionNonce: string; -} - -export interface UserDetails { - email: string; - usage: number; - fileCount: number; - sharedCollectionCount: number; - subscription: Subscription; -} - export const getOtt = (email: string) => HTTPService.get(`${ENDPOINT}/users/ott`, { email, diff --git a/src/types.ts b/src/types.ts index e7bf5e2af..6a8481bb4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,18 +1,3 @@ -export interface KeyAttributes { - kekSalt: string; - encryptedKey: string; - keyDecryptionNonce: string; - opsLimit: number; - memLimit: number; - publicKey: string; - encryptedSecretKey: string; - secretKeyDecryptionNonce: string; - masterKeyEncryptedWithRecoveryKey: string; - masterKeyDecryptionNonce: string; - recoveryKeyEncryptedWithMasterKey: string; - recoveryKeyDecryptionNonce: string; -} - export const ENCRYPTION_CHUNK_SIZE = 4 * 1024 * 1024; export const GAP_BTW_TILES = 4; export const DATE_CONTAINER_HEIGHT = 48; diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 990bd5822..04b9ddbdb 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -1,4 +1,4 @@ -import { User } from 'services/userService'; +import { User } from 'types/user'; import { EnteFile } from 'types/file'; export enum CollectionType { diff --git a/src/types/user/index.ts b/src/types/user/index.ts new file mode 100644 index 000000000..60d07f57e --- /dev/null +++ b/src/types/user/index.ts @@ -0,0 +1,70 @@ +import { Subscription } from 'types/billing'; + +export interface KeyAttributes { + kekSalt: string; + encryptedKey: string; + keyDecryptionNonce: string; + opsLimit: number; + memLimit: number; + publicKey: string; + encryptedSecretKey: string; + secretKeyDecryptionNonce: string; + masterKeyEncryptedWithRecoveryKey: string; + masterKeyDecryptionNonce: string; + recoveryKeyEncryptedWithMasterKey: string; + recoveryKeyDecryptionNonce: string; +} +export interface UpdatedKey { + kekSalt: string; + encryptedKey: string; + keyDecryptionNonce: string; + memLimit: number; + opsLimit: number; +} +export interface RecoveryKey { + masterKeyEncryptedWithRecoveryKey: string; + masterKeyDecryptionNonce: string; + recoveryKeyEncryptedWithMasterKey: string; + recoveryKeyDecryptionNonce: string; +} +export interface User { + id: number; + name: string; + email: string; + token: string; + encryptedToken: string; + isTwoFactorEnabled: boolean; + twoFactorSessionID: string; +} +export interface EmailVerificationResponse { + id: number; + keyAttributes?: KeyAttributes; + encryptedToken?: string; + token?: string; + twoFactorSessionID: string; +} + +export interface TwoFactorVerificationResponse { + id: number; + keyAttributes: KeyAttributes; + encryptedToken?: string; + token?: string; +} + +export interface TwoFactorSecret { + secretCode: string; + qrCode: string; +} + +export interface TwoFactorRecoveryResponse { + encryptedSecret: string; + secretDecryptionNonce: string; +} + +export interface UserDetails { + email: string; + usage: number; + fileCount: number; + sharedCollectionCount: number; + subscription: Subscription; +} diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index 0b328bc62..97d982e74 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -9,7 +9,7 @@ import { getLocalFiles } from 'services/fileService'; import { EnteFile } from 'types/file'; import { CustomError } from 'utils/common/errorUtil'; import { SelectedState } from 'pages/gallery'; -import { User } from 'services/userService'; +import { User } from 'types/user'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { SetDialogMessage } from 'components/MessageDialog'; import { logError } from 'utils/sentry'; diff --git a/src/utils/crypto/index.ts b/src/utils/crypto/index.ts index 2f6e237c3..d5e942233 100644 --- a/src/utils/crypto/index.ts +++ b/src/utils/crypto/index.ts @@ -1,5 +1,5 @@ import { KEK } from 'pages/generate'; -import { KeyAttributes } from 'types'; +import { KeyAttributes } from 'types/user'; import * as Comlink from 'comlink'; import { runningInBrowser } from 'utils/common'; import { SESSION_KEYS, setKey } from 'utils/storage/sessionStorage'; diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 1e2b19df3..0375179d0 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -13,7 +13,7 @@ import { decodeMotionPhoto } from 'services/motionPhotoService'; import { getMimeTypeFromBlob } from 'services/upload/readFileService'; import DownloadManager from 'services/downloadManager'; import { logError } from 'utils/sentry'; -import { User } from 'services/userService'; +import { User } from 'types/user'; import CryptoWorker from 'utils/crypto'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { updateFileCreationDateInEXIF } from 'services/upload/exifService'; From f30a5103bc4d5fdfdc355c6dafe66d74493f7225 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:12:25 +0530 Subject: [PATCH 12/69] renamed types to util/constants --- src/components/ChangeEmail.tsx | 2 +- src/components/Login.tsx | 2 +- src/components/PhotoList.tsx | 2 +- src/components/Sidebar.tsx | 2 +- src/components/SignUp.tsx | 2 +- src/components/TwoFactorModal.tsx | 2 +- src/components/pages/gallery/Collections.tsx | 2 +- src/components/pages/gallery/PreviewCard.tsx | 2 +- src/pages/change-email/index.tsx | 2 +- src/pages/change-password/index.tsx | 2 +- src/pages/credentials/index.tsx | 2 +- src/pages/gallery/index.tsx | 2 +- src/pages/generate/index.tsx | 2 +- src/pages/index.tsx | 2 +- src/pages/login/index.tsx | 2 +- src/pages/recover/index.tsx | 2 +- src/pages/signup/index.tsx | 2 +- src/pages/two-factor/recover/index.tsx | 2 +- src/pages/two-factor/setup/index.tsx | 2 +- src/pages/two-factor/verify/index.tsx | 2 +- src/pages/verify/index.tsx | 2 +- src/services/userService.ts | 2 +- src/types/upload/index.ts | 2 +- src/{types.ts => utils/constants/index.ts} | 0 src/utils/crypto/libsodium.ts | 2 +- 25 files changed, 24 insertions(+), 24 deletions(-) rename src/{types.ts => utils/constants/index.ts} (100%) diff --git a/src/components/ChangeEmail.tsx b/src/components/ChangeEmail.tsx index 328ae1182..cbf27b0a3 100644 --- a/src/components/ChangeEmail.tsx +++ b/src/components/ChangeEmail.tsx @@ -9,7 +9,7 @@ import { changeEmail, getOTTForEmailChange } from 'services/userService'; import styled from 'styled-components'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; interface formValues { email: string; diff --git a/src/components/Login.tsx b/src/components/Login.tsx index ada00fa11..38b6b6099 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -11,7 +11,7 @@ import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import SubmitButton from 'components/SubmitButton'; import Button from 'react-bootstrap/Button'; import LogoImg from './LogoImg'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; interface formValues { email: string; diff --git a/src/components/PhotoList.tsx b/src/components/PhotoList.tsx index 4c9e0c67a..523865253 100644 --- a/src/components/PhotoList.tsx +++ b/src/components/PhotoList.tsx @@ -9,7 +9,7 @@ import { DATE_CONTAINER_HEIGHT, GAP_BTW_TILES, SPACE_BTW_DATES, -} from 'types'; +} from 'utils/constants'; import constants from 'utils/strings/constants'; const A_DAY = 24 * 60 * 60 * 1000; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index d8f1918c9..2159ad78f 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -31,7 +31,7 @@ import { GalleryContext, SetLoading } from 'pages/gallery'; import InProgressIcon from './icons/InProgressIcon'; import exportService from 'services/exportService'; import { Subscription } from 'types/billing'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { ARCHIVE_SECTION, TRASH_SECTION, diff --git a/src/components/SignUp.tsx b/src/components/SignUp.tsx index 4d46dea42..f31f2999a 100644 --- a/src/components/SignUp.tsx +++ b/src/components/SignUp.tsx @@ -19,7 +19,7 @@ import { setJustSignedUp } from 'utils/storage'; import LogoImg from './LogoImg'; import { logError } from 'utils/sentry'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; interface FormValues { email: string; diff --git a/src/components/TwoFactorModal.tsx b/src/components/TwoFactorModal.tsx index db4421f9d..239c3bf33 100644 --- a/src/components/TwoFactorModal.tsx +++ b/src/components/TwoFactorModal.tsx @@ -4,7 +4,7 @@ import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; import React, { useContext, useEffect, useState } from 'react'; import { Button } from 'react-bootstrap'; import { disableTwoFactor, getTwoFactorStatus } from 'services/userService'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; import { Label, Value, Row } from './Container'; diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index 77bf323e1..1cf609664 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -8,7 +8,7 @@ import { OverlayTrigger, Tooltip } from 'react-bootstrap'; import { sortCollections } from 'services/collectionService'; import { User } from 'types/user'; import styled from 'styled-components'; -import { IMAGE_CONTAINER_MAX_WIDTH } from 'types'; +import { IMAGE_CONTAINER_MAX_WIDTH } from 'utils/constants'; import { Collection, CollectionAndItsLatestFile, diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index 62552cad5..77e343b76 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -5,7 +5,7 @@ import PlayCircleOutline from 'components/icons/PlayCircleOutline'; import DownloadManager from 'services/downloadManager'; import useLongPress from 'utils/common/useLongPress'; import { GalleryContext } from 'pages/gallery'; -import { GAP_BTW_TILES } from 'types'; +import { GAP_BTW_TILES } from 'utils/constants'; interface IProps { file: EnteFile; diff --git a/src/pages/change-email/index.tsx b/src/pages/change-email/index.tsx index dabe9f773..a557da438 100644 --- a/src/pages/change-email/index.tsx +++ b/src/pages/change-email/index.tsx @@ -8,7 +8,7 @@ import { getToken } from 'utils/common/key'; import EnteSpinner from 'components/EnteSpinner'; import ChangeEmailForm from 'components/ChangeEmail'; import EnteCard from 'components/EnteCard'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; function ChangeEmailPage() { const [email, setEmail] = useState(''); diff --git a/src/pages/change-password/index.tsx b/src/pages/change-password/index.tsx index c58b0d815..b297ce406 100644 --- a/src/pages/change-password/index.tsx +++ b/src/pages/change-password/index.tsx @@ -12,7 +12,7 @@ import { setKeys } from 'services/userService'; import SetPasswordForm from 'components/SetPasswordForm'; import { AppContext } from 'pages/_app'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { UpdatedKey } from 'types/user'; export interface KEK { diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx index 4f07100ad..ddf7dbf1a 100644 --- a/src/pages/credentials/index.tsx +++ b/src/pages/credentials/index.tsx @@ -3,7 +3,7 @@ import React, { useContext, useEffect, useState } from 'react'; import constants from 'utils/strings/constants'; import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { SESSION_KEYS, getKey } from 'utils/storage/sessionStorage'; import CryptoWorker, { decryptAndStoreToken, diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index a220c78ae..b49fae21f 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -72,7 +72,7 @@ import Collections, { } from 'components/pages/gallery/Collections'; import { AppContext } from 'pages/_app'; import { CustomError, ServerErrorCodes } from 'utils/common/errorUtil'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { COLLECTION_OPS_TYPE, isSharedCollection, diff --git a/src/pages/generate/index.tsx b/src/pages/generate/index.tsx index 4d1c57a5a..1efba5981 100644 --- a/src/pages/generate/index.tsx +++ b/src/pages/generate/index.tsx @@ -12,7 +12,7 @@ import { import SetPasswordForm from 'components/SetPasswordForm'; import { justSignedUp, setJustSignedUp } from 'utils/storage'; import RecoveryKeyModal from 'components/RecoveryKeyModal'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import Container from 'components/Container'; import EnteSpinner from 'components/EnteSpinner'; import { AppContext } from 'pages/_app'; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 20e1c7161..015d9748c 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -12,7 +12,7 @@ import constants from 'utils/strings/constants'; import localForage from 'utils/storage/localForage'; import IncognitoWarning from 'components/IncognitoWarning'; import { logError } from 'utils/sentry'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; const Container = styled.div` display: flex; diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 3cc3b17ac..561c29b03 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -6,7 +6,7 @@ import Login from 'components/Login'; import Container from 'components/Container'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import Card from 'react-bootstrap/Card'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; export default function Home() { const router = useRouter(); diff --git a/src/pages/recover/index.tsx b/src/pages/recover/index.tsx index d0c258858..b4e3370ed 100644 --- a/src/pages/recover/index.tsx +++ b/src/pages/recover/index.tsx @@ -7,7 +7,7 @@ import { setData, } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import CryptoWorker, { decryptAndStoreToken, SaveKeyInSessionStore, diff --git a/src/pages/signup/index.tsx b/src/pages/signup/index.tsx index 3f88c1955..ce7b105a3 100644 --- a/src/pages/signup/index.tsx +++ b/src/pages/signup/index.tsx @@ -6,7 +6,7 @@ import Container from 'components/Container'; import EnteSpinner from 'components/EnteSpinner'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import SignUp from 'components/SignUp'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; export default function SignUpPage() { const router = useRouter(); diff --git a/src/pages/two-factor/recover/index.tsx b/src/pages/two-factor/recover/index.tsx index 30f599eeb..e7097c73b 100644 --- a/src/pages/two-factor/recover/index.tsx +++ b/src/pages/two-factor/recover/index.tsx @@ -11,7 +11,7 @@ import LogoImg from 'components/LogoImg'; import { logError } from 'utils/sentry'; import { recoverTwoFactor, removeTwoFactor } from 'services/userService'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; const bip39 = require('bip39'); // mobile client library only supports english. bip39.setDefaultWordlist('english'); diff --git a/src/pages/two-factor/setup/index.tsx b/src/pages/two-factor/setup/index.tsx index 24587c0f0..6f051da25 100644 --- a/src/pages/two-factor/setup/index.tsx +++ b/src/pages/two-factor/setup/index.tsx @@ -14,7 +14,7 @@ import { B64EncryptionResult } from 'utils/crypto'; import { encryptWithRecoveryKey } from 'utils/crypto'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { TwoFactorSecret } from 'types/user'; enum SetupMode { diff --git a/src/pages/two-factor/verify/index.tsx b/src/pages/two-factor/verify/index.tsx index d21812ff7..f54a65c98 100644 --- a/src/pages/two-factor/verify/index.tsx +++ b/src/pages/two-factor/verify/index.tsx @@ -5,7 +5,7 @@ import router from 'next/router'; import React, { useEffect, useState } from 'react'; import { Button, Card } from 'react-bootstrap'; import { logoutUser, verifyTwoFactor } from 'services/userService'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { User } from 'types/user'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 4e8ca3bac..21c250638 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -19,7 +19,7 @@ import SubmitButton from 'components/SubmitButton'; import { clearKeys } from 'utils/storage/sessionStorage'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { User } from '@sentry/nextjs'; import { KeyAttributes, EmailVerificationResponse } from 'types/user'; diff --git a/src/services/userService.ts b/src/services/userService.ts index 133cab657..48f835bf6 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -1,4 +1,4 @@ -import { PAGES } from 'types'; +import { PAGES } from 'utils/constants'; import { getEndpoint } from 'utils/common/apiUtil'; import { clearKeys } from 'utils/storage/sessionStorage'; import router from 'next/router'; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 5f8616623..f8e09ec09 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,5 +1,5 @@ import { fileAttribute, FILE_TYPE } from 'types/file'; -import { ENCRYPTION_CHUNK_SIZE } from 'types'; +import { ENCRYPTION_CHUNK_SIZE } from 'utils/constants'; // list of format that were missed by type-detection for some files. export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ diff --git a/src/types.ts b/src/utils/constants/index.ts similarity index 100% rename from src/types.ts rename to src/utils/constants/index.ts diff --git a/src/utils/crypto/libsodium.ts b/src/utils/crypto/libsodium.ts index 3b45c121d..24a386dc7 100644 --- a/src/utils/crypto/libsodium.ts +++ b/src/utils/crypto/libsodium.ts @@ -1,5 +1,5 @@ import sodium, { StateAddress } from 'libsodium-wrappers'; -import { ENCRYPTION_CHUNK_SIZE } from 'types'; +import { ENCRYPTION_CHUNK_SIZE } from 'utils/constants'; export async function decryptChaChaOneShot( data: Uint8Array, From b10a43b3a882a04c6a402bce3b915e9d293bd8af Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:27:59 +0530 Subject: [PATCH 13/69] move gallery related types to types/gallery --- src/components/PhotoFrame.tsx | 9 ++---- src/components/SearchBar.tsx | 2 +- src/components/Sidebar.tsx | 3 +- src/components/TwoFactorModal.tsx | 3 +- src/components/pages/gallery/PlanSelector.tsx | 3 +- src/components/pages/gallery/Upload.tsx | 3 +- src/pages/gallery/index.tsx | 30 +----------------- src/services/trashService.ts | 2 +- src/services/upload/uploadManager.ts | 2 +- src/types/gallery/index.ts | 31 +++++++++++++++++++ src/utils/billing/index.ts | 2 +- src/utils/collection/index.ts | 2 +- src/utils/file/index.ts | 2 +- 13 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 src/types/gallery/index.ts diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index 0ac495b0a..b0d5be55d 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -1,10 +1,4 @@ -import { - GalleryContext, - Search, - SelectedState, - SetFiles, - setSearchStats, -} from 'pages/gallery'; +import { GalleryContext } from 'pages/gallery'; import PreviewCard from './pages/gallery/PreviewCard'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { Button } from 'react-bootstrap'; @@ -25,6 +19,7 @@ import { import { isSharedFile } from 'utils/file'; import { isPlaybackPossible } from 'utils/photoFrame'; import { PhotoList } from './PhotoList'; +import { SetFiles, SelectedState, Search, setSearchStats } from 'types/gallery'; const Container = styled.div` display: block; diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index a1ad2e360..5b9289699 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -1,4 +1,3 @@ -import { Search, SearchStats } from 'pages/gallery'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import AsyncSelect from 'react-select/async'; @@ -26,6 +25,7 @@ import VideoIcon from './icons/VideoIcon'; import { IconButton } from './Container'; import { EnteFile, FILE_TYPE } from 'types/file'; import { Suggestion, SuggestionType, DateValue, Bbox } from 'types/search'; +import { Search, SearchStats } from 'types/gallery'; const Wrapper = styled.div<{ isDisabled: boolean; isOpen: boolean }>` position: fixed; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 2159ad78f..4f7506158 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -27,7 +27,7 @@ import EnteSpinner from './EnteSpinner'; import RecoveryKeyModal from './RecoveryKeyModal'; import TwoFactorModal from './TwoFactorModal'; import ExportModal from './ExportModal'; -import { GalleryContext, SetLoading } from 'pages/gallery'; +import { GalleryContext } from 'pages/gallery'; import InProgressIcon from './icons/InProgressIcon'; import exportService from 'services/exportService'; import { Subscription } from 'types/billing'; @@ -37,6 +37,7 @@ import { TRASH_SECTION, } from 'components/pages/gallery/Collections'; import FixLargeThumbnails from './FixLargeThumbnail'; +import { SetLoading } from 'types/gallery'; interface Props { collections: Collection[]; setDialogMessage: SetDialogMessage; diff --git a/src/components/TwoFactorModal.tsx b/src/components/TwoFactorModal.tsx index 239c3bf33..d5e0707dd 100644 --- a/src/components/TwoFactorModal.tsx +++ b/src/components/TwoFactorModal.tsx @@ -1,9 +1,10 @@ import { useRouter } from 'next/router'; -import { DeadCenter, SetLoading } from 'pages/gallery'; +import { DeadCenter } from 'pages/gallery'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; import React, { useContext, useEffect, useState } from 'react'; import { Button } from 'react-bootstrap'; import { disableTwoFactor, getTwoFactorStatus } from 'services/userService'; +import { SetLoading } from 'types/gallery'; import { PAGES } from 'utils/constants'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; diff --git a/src/components/pages/gallery/PlanSelector.tsx b/src/components/pages/gallery/PlanSelector.tsx index 0c8d15cf7..48156e7f5 100644 --- a/src/components/pages/gallery/PlanSelector.tsx +++ b/src/components/pages/gallery/PlanSelector.tsx @@ -21,8 +21,9 @@ import { reverseString } from 'utils/common'; import { SetDialogMessage } from 'components/MessageDialog'; import ArrowEast from 'components/icons/ArrowEast'; import LinkButton from './LinkButton'; -import { DeadCenter, SetLoading } from 'pages/gallery'; +import { DeadCenter } from 'pages/gallery'; import billingService from 'services/billingService'; +import { SetLoading } from 'types/gallery'; export const PlanIcon = styled.div<{ selected: boolean }>` border-radius: 20px; diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 7a1517cfd..45c894419 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -8,7 +8,7 @@ import UploadProgress from './UploadProgress'; import ChoiceModal from './ChoiceModal'; import { SetCollectionNamerAttributes } from './CollectionNamer'; import { SetCollectionSelectorAttributes } from './CollectionSelector'; -import { GalleryContext, SetFiles, SetLoading } from 'pages/gallery'; +import { GalleryContext } from 'pages/gallery'; import { AppContext } from 'pages/_app'; import { logError } from 'utils/sentry'; import { FileRejection } from 'react-dropzone'; @@ -20,6 +20,7 @@ import uploadManager from 'services/upload/uploadManager'; import { METADATA_FOLDER_NAME } from 'types/export'; import { getUserFacingErrorMessage } from 'utils/common/errorUtil'; import { Collection } from 'types/collection'; +import { SetLoading, SetFiles } from 'types/gallery'; const FIRST_ALBUM_NAME = 'My First Album'; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index b49fae21f..f91ee4323 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -52,7 +52,6 @@ import { sortFiles, sortFilesIntoCollections, } from 'utils/file'; -import { DateValue, Bbox } from 'types/search'; import SearchBar from 'components/SearchBar'; import SelectedFileOptions from 'components/pages/gallery/SelectedFileOptions'; import CollectionSelector, { @@ -100,6 +99,7 @@ import { CollectionType, } from 'types/collection'; import { EnteFile, VISIBILITY_STATE } from 'types/file'; +import { GalleryContextType, SelectedState, Search } from 'types/gallery'; export const DeadCenter = styled.div` flex: 1; @@ -116,34 +116,6 @@ const AlertContainer = styled.div` text-align: center; `; -export type SelectedState = { - [k: number]: boolean; - count: number; - collectionID: number; -}; -export type SetFiles = React.Dispatch>; -export type SetCollections = React.Dispatch>; -export type SetLoading = React.Dispatch>; -export type setSearchStats = React.Dispatch>; - -export type Search = { - date?: DateValue; - location?: Bbox; - fileIndex?: number; -}; -export interface SearchStats { - resultCount: number; - timeTaken: number; -} - -type GalleryContextType = { - thumbs: Map; - files: Map; - showPlanSelectorModal: () => void; - setActiveCollection: (collection: number) => void; - syncWithRemote: (force?: boolean, silent?: boolean) => Promise; -}; - const defaultGalleryContext: GalleryContextType = { thumbs: new Map(), files: new Map(), diff --git a/src/services/trashService.ts b/src/services/trashService.ts index 70cfea220..36ea04756 100644 --- a/src/services/trashService.ts +++ b/src/services/trashService.ts @@ -1,4 +1,4 @@ -import { SetFiles } from 'pages/gallery'; +import { SetFiles } from 'types/gallery'; import { Collection } from 'types/collection'; import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index 46c53d1e2..a093a4327 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -1,6 +1,6 @@ import { getLocalFiles, setLocalFiles } from '../fileService'; import { getLocalCollections } from '../collectionService'; -import { SetFiles } from 'pages/gallery'; +import { SetFiles } from 'types/gallery'; import { ComlinkWorker, getDedicatedCryptoWorker } from 'utils/crypto'; import { sortFilesIntoCollections, diff --git a/src/types/gallery/index.ts b/src/types/gallery/index.ts new file mode 100644 index 000000000..e7c10e3ce --- /dev/null +++ b/src/types/gallery/index.ts @@ -0,0 +1,31 @@ +import { Collection } from 'types/collection'; +import { EnteFile } from 'types/file'; +import { DateValue, Bbox } from 'types/search'; + +export type SelectedState = { + [k: number]: boolean; + count: number; + collectionID: number; +}; +export type SetFiles = React.Dispatch>; +export type SetCollections = React.Dispatch>; +export type SetLoading = React.Dispatch>; +export type setSearchStats = React.Dispatch>; + +export type Search = { + date?: DateValue; + location?: Bbox; + fileIndex?: number; +}; +export interface SearchStats { + resultCount: number; + timeTaken: number; +} + +export type GalleryContextType = { + thumbs: Map; + files: Map; + showPlanSelectorModal: () => void; + setActiveCollection: (collection: number) => void; + syncWithRemote: (force?: boolean, silent?: boolean) => Promise; +}; diff --git a/src/utils/billing/index.ts b/src/utils/billing/index.ts index c681dd71b..e731db1fe 100644 --- a/src/utils/billing/index.ts +++ b/src/utils/billing/index.ts @@ -3,7 +3,7 @@ import billingService from 'services/billingService'; import { Plan, Subscription } from 'types/billing'; import { NextRouter } from 'next/router'; import { SetDialogMessage } from 'components/MessageDialog'; -import { SetLoading } from 'pages/gallery'; +import { SetLoading } from 'types/gallery'; import { getData, LS_KEYS } from '../storage/localStorage'; import { CustomError } from '../common/errorUtil'; import { logError } from '../sentry'; diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index 97d982e74..38c706882 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -8,7 +8,7 @@ import { downloadFiles, getSelectedFiles } from 'utils/file'; import { getLocalFiles } from 'services/fileService'; import { EnteFile } from 'types/file'; import { CustomError } from 'utils/common/errorUtil'; -import { SelectedState } from 'pages/gallery'; +import { SelectedState } from 'types/gallery'; import { User } from 'types/user'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { SetDialogMessage } from 'components/MessageDialog'; diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 0375179d0..bf7c3ca27 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -1,4 +1,4 @@ -import { SelectedState } from 'pages/gallery'; +import { SelectedState } from 'types/gallery'; import { Collection } from 'types/collection'; import { EnteFile, From dfdf2897d40da2dbd1c62dd20740a01c6b5b711c Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:46:30 +0530 Subject: [PATCH 14/69] move constants from util to src directory and split into sub folders --- src/components/ChangeEmail.tsx | 2 +- src/components/Login.tsx | 2 +- src/components/PhotoList.tsx | 2 +- src/components/Sidebar.tsx | 2 +- src/components/SignUp.tsx | 2 +- src/components/TwoFactorModal.tsx | 2 +- src/components/pages/gallery/Collections.tsx | 2 +- src/components/pages/gallery/PreviewCard.tsx | 2 +- src/constants/crypto/index.ts | 1 + src/constants/gallery/index.ts | 7 +++++++ src/{utils/constants => constants/pages}/index.ts | 9 --------- src/pages/change-email/index.tsx | 2 +- src/pages/change-password/index.tsx | 2 +- src/pages/credentials/index.tsx | 2 +- src/pages/gallery/index.tsx | 2 +- src/pages/generate/index.tsx | 2 +- src/pages/index.tsx | 2 +- src/pages/login/index.tsx | 2 +- src/pages/recover/index.tsx | 2 +- src/pages/signup/index.tsx | 2 +- src/pages/two-factor/recover/index.tsx | 2 +- src/pages/two-factor/setup/index.tsx | 2 +- src/pages/two-factor/verify/index.tsx | 2 +- src/pages/verify/index.tsx | 2 +- src/services/userService.ts | 2 +- src/types/upload/index.ts | 2 +- src/utils/crypto/libsodium.ts | 2 +- 27 files changed, 32 insertions(+), 33 deletions(-) create mode 100644 src/constants/crypto/index.ts create mode 100644 src/constants/gallery/index.ts rename src/{utils/constants => constants/pages}/index.ts (57%) diff --git a/src/components/ChangeEmail.tsx b/src/components/ChangeEmail.tsx index cbf27b0a3..0eb94a694 100644 --- a/src/components/ChangeEmail.tsx +++ b/src/components/ChangeEmail.tsx @@ -9,7 +9,7 @@ import { changeEmail, getOTTForEmailChange } from 'services/userService'; import styled from 'styled-components'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; interface formValues { email: string; diff --git a/src/components/Login.tsx b/src/components/Login.tsx index 38b6b6099..1309d2b97 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -11,7 +11,7 @@ import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import SubmitButton from 'components/SubmitButton'; import Button from 'react-bootstrap/Button'; import LogoImg from './LogoImg'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; interface formValues { email: string; diff --git a/src/components/PhotoList.tsx b/src/components/PhotoList.tsx index 523865253..0c34407ba 100644 --- a/src/components/PhotoList.tsx +++ b/src/components/PhotoList.tsx @@ -9,7 +9,7 @@ import { DATE_CONTAINER_HEIGHT, GAP_BTW_TILES, SPACE_BTW_DATES, -} from 'utils/constants'; +} from 'constants/gallery'; import constants from 'utils/strings/constants'; const A_DAY = 24 * 60 * 60 * 1000; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 4f7506158..28e502464 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -31,7 +31,7 @@ import { GalleryContext } from 'pages/gallery'; import InProgressIcon from './icons/InProgressIcon'; import exportService from 'services/exportService'; import { Subscription } from 'types/billing'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { ARCHIVE_SECTION, TRASH_SECTION, diff --git a/src/components/SignUp.tsx b/src/components/SignUp.tsx index f31f2999a..8a2399f86 100644 --- a/src/components/SignUp.tsx +++ b/src/components/SignUp.tsx @@ -19,7 +19,7 @@ import { setJustSignedUp } from 'utils/storage'; import LogoImg from './LogoImg'; import { logError } from 'utils/sentry'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; interface FormValues { email: string; diff --git a/src/components/TwoFactorModal.tsx b/src/components/TwoFactorModal.tsx index d5e0707dd..c7597fac2 100644 --- a/src/components/TwoFactorModal.tsx +++ b/src/components/TwoFactorModal.tsx @@ -5,7 +5,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { Button } from 'react-bootstrap'; import { disableTwoFactor, getTwoFactorStatus } from 'services/userService'; import { SetLoading } from 'types/gallery'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; import { Label, Value, Row } from './Container'; diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index 1cf609664..923948a10 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -8,7 +8,7 @@ import { OverlayTrigger, Tooltip } from 'react-bootstrap'; import { sortCollections } from 'services/collectionService'; import { User } from 'types/user'; import styled from 'styled-components'; -import { IMAGE_CONTAINER_MAX_WIDTH } from 'utils/constants'; +import { IMAGE_CONTAINER_MAX_WIDTH } from 'constants/gallery'; import { Collection, CollectionAndItsLatestFile, diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index 77e343b76..6454832ce 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -5,7 +5,7 @@ import PlayCircleOutline from 'components/icons/PlayCircleOutline'; import DownloadManager from 'services/downloadManager'; import useLongPress from 'utils/common/useLongPress'; import { GalleryContext } from 'pages/gallery'; -import { GAP_BTW_TILES } from 'utils/constants'; +import { GAP_BTW_TILES } from 'constants/gallery'; interface IProps { file: EnteFile; diff --git a/src/constants/crypto/index.ts b/src/constants/crypto/index.ts new file mode 100644 index 000000000..9226ed874 --- /dev/null +++ b/src/constants/crypto/index.ts @@ -0,0 +1 @@ +export const ENCRYPTION_CHUNK_SIZE = 4 * 1024 * 1024; diff --git a/src/constants/gallery/index.ts b/src/constants/gallery/index.ts new file mode 100644 index 000000000..be5c385f4 --- /dev/null +++ b/src/constants/gallery/index.ts @@ -0,0 +1,7 @@ +export const GAP_BTW_TILES = 4; +export const DATE_CONTAINER_HEIGHT = 48; +export const IMAGE_CONTAINER_MAX_HEIGHT = 200; +export const IMAGE_CONTAINER_MAX_WIDTH = + IMAGE_CONTAINER_MAX_HEIGHT - GAP_BTW_TILES; +export const MIN_COLUMNS = 4; +export const SPACE_BTW_DATES = 44; diff --git a/src/utils/constants/index.ts b/src/constants/pages/index.ts similarity index 57% rename from src/utils/constants/index.ts rename to src/constants/pages/index.ts index 6a8481bb4..aad2a4831 100644 --- a/src/utils/constants/index.ts +++ b/src/constants/pages/index.ts @@ -1,12 +1,3 @@ -export const ENCRYPTION_CHUNK_SIZE = 4 * 1024 * 1024; -export const GAP_BTW_TILES = 4; -export const DATE_CONTAINER_HEIGHT = 48; -export const IMAGE_CONTAINER_MAX_HEIGHT = 200; -export const IMAGE_CONTAINER_MAX_WIDTH = - IMAGE_CONTAINER_MAX_HEIGHT - GAP_BTW_TILES; -export const MIN_COLUMNS = 4; -export const SPACE_BTW_DATES = 44; - export enum PAGES { CHANGE_EMAIL = '/change-email', CHANGE_PASSWORD = '/change-password', diff --git a/src/pages/change-email/index.tsx b/src/pages/change-email/index.tsx index a557da438..f81b971a6 100644 --- a/src/pages/change-email/index.tsx +++ b/src/pages/change-email/index.tsx @@ -8,7 +8,7 @@ import { getToken } from 'utils/common/key'; import EnteSpinner from 'components/EnteSpinner'; import ChangeEmailForm from 'components/ChangeEmail'; import EnteCard from 'components/EnteCard'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; function ChangeEmailPage() { const [email, setEmail] = useState(''); diff --git a/src/pages/change-password/index.tsx b/src/pages/change-password/index.tsx index b297ce406..1eaee4a70 100644 --- a/src/pages/change-password/index.tsx +++ b/src/pages/change-password/index.tsx @@ -12,7 +12,7 @@ import { setKeys } from 'services/userService'; import SetPasswordForm from 'components/SetPasswordForm'; import { AppContext } from 'pages/_app'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { UpdatedKey } from 'types/user'; export interface KEK { diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx index ddf7dbf1a..86d44ce5f 100644 --- a/src/pages/credentials/index.tsx +++ b/src/pages/credentials/index.tsx @@ -3,7 +3,7 @@ import React, { useContext, useEffect, useState } from 'react'; import constants from 'utils/strings/constants'; import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { SESSION_KEYS, getKey } from 'utils/storage/sessionStorage'; import CryptoWorker, { decryptAndStoreToken, diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index f91ee4323..a8452b1cb 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -71,7 +71,7 @@ import Collections, { } from 'components/pages/gallery/Collections'; import { AppContext } from 'pages/_app'; import { CustomError, ServerErrorCodes } from 'utils/common/errorUtil'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { COLLECTION_OPS_TYPE, isSharedCollection, diff --git a/src/pages/generate/index.tsx b/src/pages/generate/index.tsx index 1efba5981..8457b6940 100644 --- a/src/pages/generate/index.tsx +++ b/src/pages/generate/index.tsx @@ -12,7 +12,7 @@ import { import SetPasswordForm from 'components/SetPasswordForm'; import { justSignedUp, setJustSignedUp } from 'utils/storage'; import RecoveryKeyModal from 'components/RecoveryKeyModal'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import Container from 'components/Container'; import EnteSpinner from 'components/EnteSpinner'; import { AppContext } from 'pages/_app'; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 015d9748c..4d80828c5 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -12,7 +12,7 @@ import constants from 'utils/strings/constants'; import localForage from 'utils/storage/localForage'; import IncognitoWarning from 'components/IncognitoWarning'; import { logError } from 'utils/sentry'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; const Container = styled.div` display: flex; diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 561c29b03..ef056f426 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -6,7 +6,7 @@ import Login from 'components/Login'; import Container from 'components/Container'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import Card from 'react-bootstrap/Card'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; export default function Home() { const router = useRouter(); diff --git a/src/pages/recover/index.tsx b/src/pages/recover/index.tsx index b4e3370ed..a6a7deee9 100644 --- a/src/pages/recover/index.tsx +++ b/src/pages/recover/index.tsx @@ -7,7 +7,7 @@ import { setData, } from 'utils/storage/localStorage'; import { useRouter } from 'next/router'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import CryptoWorker, { decryptAndStoreToken, SaveKeyInSessionStore, diff --git a/src/pages/signup/index.tsx b/src/pages/signup/index.tsx index ce7b105a3..78d2e5e27 100644 --- a/src/pages/signup/index.tsx +++ b/src/pages/signup/index.tsx @@ -6,7 +6,7 @@ import Container from 'components/Container'; import EnteSpinner from 'components/EnteSpinner'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import SignUp from 'components/SignUp'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; export default function SignUpPage() { const router = useRouter(); diff --git a/src/pages/two-factor/recover/index.tsx b/src/pages/two-factor/recover/index.tsx index e7097c73b..867f4983b 100644 --- a/src/pages/two-factor/recover/index.tsx +++ b/src/pages/two-factor/recover/index.tsx @@ -11,7 +11,7 @@ import LogoImg from 'components/LogoImg'; import { logError } from 'utils/sentry'; import { recoverTwoFactor, removeTwoFactor } from 'services/userService'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; const bip39 = require('bip39'); // mobile client library only supports english. bip39.setDefaultWordlist('english'); diff --git a/src/pages/two-factor/setup/index.tsx b/src/pages/two-factor/setup/index.tsx index 6f051da25..8fe4d432e 100644 --- a/src/pages/two-factor/setup/index.tsx +++ b/src/pages/two-factor/setup/index.tsx @@ -14,7 +14,7 @@ import { B64EncryptionResult } from 'utils/crypto'; import { encryptWithRecoveryKey } from 'utils/crypto'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import { AppContext, FLASH_MESSAGE_TYPE } from 'pages/_app'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { TwoFactorSecret } from 'types/user'; enum SetupMode { diff --git a/src/pages/two-factor/verify/index.tsx b/src/pages/two-factor/verify/index.tsx index f54a65c98..3ccdb14ee 100644 --- a/src/pages/two-factor/verify/index.tsx +++ b/src/pages/two-factor/verify/index.tsx @@ -5,7 +5,7 @@ import router from 'next/router'; import React, { useEffect, useState } from 'react'; import { Button, Card } from 'react-bootstrap'; import { logoutUser, verifyTwoFactor } from 'services/userService'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { User } from 'types/user'; import { setData, LS_KEYS, getData } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 21c250638..07023c5de 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -19,7 +19,7 @@ import SubmitButton from 'components/SubmitButton'; import { clearKeys } from 'utils/storage/sessionStorage'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { User } from '@sentry/nextjs'; import { KeyAttributes, EmailVerificationResponse } from 'types/user'; diff --git a/src/services/userService.ts b/src/services/userService.ts index 48f835bf6..94a5b2851 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -1,4 +1,4 @@ -import { PAGES } from 'utils/constants'; +import { PAGES } from 'constants/pages'; import { getEndpoint } from 'utils/common/apiUtil'; import { clearKeys } from 'utils/storage/sessionStorage'; import router from 'next/router'; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index f8e09ec09..59bb15f70 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,5 +1,5 @@ import { fileAttribute, FILE_TYPE } from 'types/file'; -import { ENCRYPTION_CHUNK_SIZE } from 'utils/constants'; +import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; // list of format that were missed by type-detection for some files. export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ diff --git a/src/utils/crypto/libsodium.ts b/src/utils/crypto/libsodium.ts index 24a386dc7..e4678a2c7 100644 --- a/src/utils/crypto/libsodium.ts +++ b/src/utils/crypto/libsodium.ts @@ -1,5 +1,5 @@ import sodium, { StateAddress } from 'libsodium-wrappers'; -import { ENCRYPTION_CHUNK_SIZE } from 'utils/constants'; +import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; export async function decryptChaChaOneShot( data: Uint8Array, From 5a840033880d4bf88def20eb442d52b54d3f836b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:54:39 +0530 Subject: [PATCH 15/69] move collection constants to constants/collection --- src/components/PhotoFrame.tsx | 2 +- src/components/Sidebar.tsx | 5 +---- src/components/pages/gallery/Collections.tsx | 9 +++++---- src/components/pages/gallery/SelectedFileOptions.tsx | 6 +++++- src/constants/collection/index.ts | 3 +++ src/pages/gallery/index.tsx | 5 +++-- 6 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 src/constants/collection/index.ts diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index b0d5be55d..af54667db 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -15,7 +15,7 @@ import { ALL_SECTION, ARCHIVE_SECTION, TRASH_SECTION, -} from './pages/gallery/Collections'; +} from 'constants/collection'; import { isSharedFile } from 'utils/file'; import { isPlaybackPossible } from 'utils/photoFrame'; import { PhotoList } from './PhotoList'; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 28e502464..29ae3390f 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -32,10 +32,7 @@ import InProgressIcon from './icons/InProgressIcon'; import exportService from 'services/exportService'; import { Subscription } from 'types/billing'; import { PAGES } from 'constants/pages'; -import { - ARCHIVE_SECTION, - TRASH_SECTION, -} from 'components/pages/gallery/Collections'; +import { ARCHIVE_SECTION, TRASH_SECTION } from 'constants/collection'; import FixLargeThumbnails from './FixLargeThumbnail'; import { SetLoading } from 'types/gallery'; interface Props { diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index 923948a10..590367057 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -22,10 +22,11 @@ import { SetCollectionNamerAttributes } from './CollectionNamer'; import CollectionOptions from './CollectionOptions'; import CollectionSort from './CollectionSort'; import OptionIcon, { OptionIconWrapper } from './OptionIcon'; - -export const ARCHIVE_SECTION = -1; -export const TRASH_SECTION = -2; -export const ALL_SECTION = 0; +import { + ALL_SECTION, + ARCHIVE_SECTION, + TRASH_SECTION, +} from 'constants/collection'; interface CollectionProps { collections: Collection[]; diff --git a/src/components/pages/gallery/SelectedFileOptions.tsx b/src/components/pages/gallery/SelectedFileOptions.tsx index a7ba7249e..ac5c0ed76 100644 --- a/src/components/pages/gallery/SelectedFileOptions.tsx +++ b/src/components/pages/gallery/SelectedFileOptions.tsx @@ -11,7 +11,11 @@ import constants from 'utils/strings/constants'; import Archive from 'components/icons/Archive'; import MoveIcon from 'components/icons/MoveIcon'; import { COLLECTION_OPS_TYPE } from 'utils/collection'; -import { ALL_SECTION, ARCHIVE_SECTION, TRASH_SECTION } from './Collections'; +import { + ALL_SECTION, + ARCHIVE_SECTION, + TRASH_SECTION, +} from 'constants/collection'; import UnArchive from 'components/icons/UnArchive'; import { OverlayTrigger } from 'react-bootstrap'; import { Collection } from 'types/collection'; diff --git a/src/constants/collection/index.ts b/src/constants/collection/index.ts new file mode 100644 index 000000000..4164301d7 --- /dev/null +++ b/src/constants/collection/index.ts @@ -0,0 +1,3 @@ +export const ARCHIVE_SECTION = -1; +export const TRASH_SECTION = -2; +export const ALL_SECTION = 0; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index a8452b1cb..0dba44731 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -64,11 +64,11 @@ import AlertBanner from 'components/pages/gallery/AlertBanner'; import UploadButton from 'components/pages/gallery/UploadButton'; import PlanSelector from 'components/pages/gallery/PlanSelector'; import Upload from 'components/pages/gallery/Upload'; -import Collections, { +import { ALL_SECTION, ARCHIVE_SECTION, TRASH_SECTION, -} from 'components/pages/gallery/Collections'; +} from 'constants/collection'; import { AppContext } from 'pages/_app'; import { CustomError, ServerErrorCodes } from 'utils/common/errorUtil'; import { PAGES } from 'constants/pages'; @@ -100,6 +100,7 @@ import { } from 'types/collection'; import { EnteFile, VISIBILITY_STATE } from 'types/file'; import { GalleryContextType, SelectedState, Search } from 'types/gallery'; +import Collections from 'components/pages/gallery/Collections'; export const DeadCenter = styled.div` flex: 1; From eddfbed37cb413b26345b8f37d87cd757203b463 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 16:57:57 +0530 Subject: [PATCH 16/69] moved user constants to constants/user --- src/constants/user/index.ts | 1 + src/services/userService.ts | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 src/constants/user/index.ts diff --git a/src/constants/user/index.ts b/src/constants/user/index.ts new file mode 100644 index 000000000..12221f4e6 --- /dev/null +++ b/src/constants/user/index.ts @@ -0,0 +1 @@ +export const FIX_CREATION_TIME_VISIBLE_TO_USER_IDS = [1, 125, 243, 341]; diff --git a/src/services/userService.ts b/src/services/userService.ts index 94a5b2851..5cdd08ca1 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -22,8 +22,6 @@ const ENDPOINT = getEndpoint(); const HAS_SET_KEYS = 'hasSetKeys'; -export const FIX_CREATION_TIME_VISIBLE_TO_USER_IDS = [1, 125, 243, 341]; - export const getOtt = (email: string) => HTTPService.get(`${ENDPOINT}/users/ott`, { email, From 9b48275144f52ff6bf93b8e56f1c96165c3564ea Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 17:01:22 +0530 Subject: [PATCH 17/69] moved upload constants to constants/upload --- src/constants/upload/index.ts | 23 +++++++++++++++++++ src/services/upload/exifService.ts | 3 ++- src/services/upload/metadataService.ts | 3 +-- src/services/upload/multiPartUploadService.ts | 7 ++++-- src/services/upload/readFileService.ts | 2 +- src/services/upload/uiService.ts | 3 +-- src/services/upload/uploadService.ts | 12 +--------- src/types/upload/index.ts | 13 ----------- 8 files changed, 34 insertions(+), 32 deletions(-) create mode 100644 src/constants/upload/index.ts diff --git a/src/constants/upload/index.ts b/src/constants/upload/index.ts new file mode 100644 index 000000000..245ad3a12 --- /dev/null +++ b/src/constants/upload/index.ts @@ -0,0 +1,23 @@ +import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; +import { FILE_TYPE } from 'types/file'; +import { Location } from 'services/upload/metadataService'; + +// list of format that were missed by type-detection for some files. +export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ + { fileType: FILE_TYPE.IMAGE, exactType: 'jpeg' }, + { fileType: FILE_TYPE.IMAGE, exactType: 'jpg' }, + { fileType: FILE_TYPE.VIDEO, exactType: 'webm' }, +]; + +// this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part. +export const MULTIPART_PART_SIZE = 20 * 1024 * 1024; + +export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE; + +export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor( + MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE +); + +export const NULL_LOCATION: Location = { latitude: null, longitude: null }; + +export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random(); diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index 05768b374..fa24f02fc 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -1,7 +1,8 @@ import exifr from 'exifr'; import piexif from 'piexifjs'; import { logError } from 'utils/sentry'; -import { NULL_LOCATION, Location } from './metadataService'; +import { NULL_LOCATION } from 'constants/upload'; +import { Location } from 'services/upload/metadataService'; import { FileTypeInfo } from './readFileService'; const EXIF_TAGS_NEEDED = [ diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index c9ebdf0d9..25dc158f7 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -3,6 +3,7 @@ import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { FileTypeInfo } from './readFileService'; import { MetadataObject } from 'types/upload'; +import { NULL_LOCATION } from 'constants/upload'; export interface Location { latitude: number; @@ -20,8 +21,6 @@ interface ParsedMetaDataJSONWithTitle { parsedMetaDataJSON: ParsedMetaDataJSON; } -export const NULL_LOCATION: Location = { latitude: null, longitude: null }; - const NULL_PARSED_METADATA_JSON: ParsedMetaDataJSON = { creationTime: null, modificationTime: null, diff --git a/src/services/upload/multiPartUploadService.ts b/src/services/upload/multiPartUploadService.ts index 020b50c50..022de1912 100644 --- a/src/services/upload/multiPartUploadService.ts +++ b/src/services/upload/multiPartUploadService.ts @@ -1,7 +1,10 @@ -import { FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART } from './uploadService'; +import { + FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART, + RANDOM_PERCENTAGE_PROGRESS_FOR_PUT, +} from 'constants/upload'; +import UIService from './uiService'; import UploadHttpClient from './uploadHttpClient'; import * as convert from 'xml-js'; -import UIService, { RANDOM_PERCENTAGE_PROGRESS_FOR_PUT } from './uiService'; import { CustomError } from 'utils/common/errorUtil'; import { DataStream } from 'types/upload'; diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index fc9c0aca0..3b533ea9b 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -4,7 +4,7 @@ import { FILE_READER_CHUNK_SIZE, FORMAT_MISSED_BY_FILE_TYPE_LIB, MULTIPART_PART_SIZE, -} from 'types/upload'; +} from 'constants/upload'; import FileType from 'file-type/browser'; import { CustomError } from 'utils/common/errorUtil'; import { getFileExtension } from 'utils/file'; diff --git a/src/services/upload/uiService.ts b/src/services/upload/uiService.ts index d85f8f743..9d64ba99c 100644 --- a/src/services/upload/uiService.ts +++ b/src/services/upload/uiService.ts @@ -1,8 +1,7 @@ import { ProgressUpdater } from 'components/pages/gallery/Upload'; +import { RANDOM_PERCENTAGE_PROGRESS_FOR_PUT } from 'constants/upload'; import { UPLOAD_STAGES } from './uploadManager'; -export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random(); - class UIService { private perFileProgress: number; private filesUploaded: number; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index dcfd648b8..ab4839675 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -18,17 +18,7 @@ import { uploadStreamUsingMultipart } from './multiPartUploadService'; import UIService from './uiService'; import { handleUploadError } from 'utils/common/errorUtil'; import { MetadataMap } from './uploadManager'; -import { - DataStream, - EncryptionResult, - FILE_READER_CHUNK_SIZE, - MetadataObject, - MULTIPART_PART_SIZE, -} from 'types/upload'; - -export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor( - MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE -); +import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; export interface UploadURL { url: string; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 59bb15f70..8f32ab7fb 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,17 +1,4 @@ import { fileAttribute, FILE_TYPE } from 'types/file'; -import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; - -// list of format that were missed by type-detection for some files. -export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ - { fileType: FILE_TYPE.IMAGE, exactType: 'jpeg' }, - { fileType: FILE_TYPE.IMAGE, exactType: 'jpg' }, - { fileType: FILE_TYPE.VIDEO, exactType: 'webm' }, -]; - -// this is the chunk size of the un-encrypted file which is read and encrypted before uploading it as a single part. -export const MULTIPART_PART_SIZE = 20 * 1024 * 1024; - -export const FILE_READER_CHUNK_SIZE = ENCRYPTION_CHUNK_SIZE; export interface DataStream { stream: ReadableStream; From 8f0a0d3f18266355cf69b28ba3f01b1f666b8d37 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 17:12:43 +0530 Subject: [PATCH 18/69] fix FIX_CREATION_TIME_VISIBLE_TO_USER_IDS import --- src/components/pages/gallery/SelectedFileOptions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/pages/gallery/SelectedFileOptions.tsx b/src/components/pages/gallery/SelectedFileOptions.tsx index ac5c0ed76..c661f589f 100644 --- a/src/components/pages/gallery/SelectedFileOptions.tsx +++ b/src/components/pages/gallery/SelectedFileOptions.tsx @@ -23,7 +23,7 @@ import RemoveIcon from 'components/icons/RemoveIcon'; import RestoreIcon from 'components/icons/RestoreIcon'; import ClockIcon from 'components/icons/ClockIcon'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; -import { FIX_CREATION_TIME_VISIBLE_TO_USER_IDS } from 'services/userService'; +import { FIX_CREATION_TIME_VISIBLE_TO_USER_IDS } from 'constants/user'; import DownloadIcon from 'components/icons/DownloadIcon'; import { User } from 'types/user'; From 88ea78ebb396681d458e1c6d754b9d43f194b74b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 17:13:15 +0530 Subject: [PATCH 19/69] dont export constants used only in one file --- src/services/fileService.ts | 8 ++------ src/services/upload/thumbnailService.ts | 2 +- src/types/file/index.ts | 2 -- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/services/fileService.ts b/src/services/fileService.ts index 9ba10e7e4..8c9f0ece3 100644 --- a/src/services/fileService.ts +++ b/src/services/fileService.ts @@ -8,14 +8,10 @@ import HTTPService from './HTTPService'; import { logError } from 'utils/sentry'; import { decryptFile, mergeMetadata, sortFiles } from 'utils/file'; import CryptoWorker from 'utils/crypto'; -import { - EnteFile, - FILES_TABLE, - TrashRequest, - UpdateMagicMetadataRequest, -} from 'types/file'; +import { EnteFile, TrashRequest, UpdateMagicMetadataRequest } from 'types/file'; const ENDPOINT = getEndpoint(); +const FILES_TABLE = 'files'; export const getLocalFiles = async () => { const files: Array = diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 5b1605fde..387c71294 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -9,7 +9,7 @@ import { FileTypeInfo } from './readFileService'; const MAX_THUMBNAIL_DIMENSION = 720; const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10; -export const MAX_THUMBNAIL_SIZE = 100 * 1024; +const MAX_THUMBNAIL_SIZE = 100 * 1024; const MIN_QUALITY = 0.5; const MAX_QUALITY = 0.7; diff --git a/src/types/file/index.ts b/src/types/file/index.ts index e48172834..a668a520a 100644 --- a/src/types/file/index.ts +++ b/src/types/file/index.ts @@ -1,7 +1,5 @@ import { DataStream, MetadataObject } from 'types/upload'; -export const FILES_TABLE = 'files'; - export const MIN_EDITED_CREATION_TIME = new Date(1800, 0, 1); export const MAX_EDITED_CREATION_TIME = new Date(); export const ALL_TIME = new Date(1800, 0, 1, 23, 59, 59); From 8a96b73b37e390a7c5e478b457dc5ffc6d6f5fd1 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 17:19:14 +0530 Subject: [PATCH 20/69] moved export constants to constants/export --- src/components/pages/gallery/Upload.tsx | 2 +- src/constants/export/index.ts | 1 + src/types/export/index.ts | 2 -- src/utils/export/index.ts | 8 +++----- 4 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 src/constants/export/index.ts diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 45c894419..1eef7a1e7 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -17,7 +17,7 @@ import UploadManager, { UPLOAD_STAGES, } from 'services/upload/uploadManager'; import uploadManager from 'services/upload/uploadManager'; -import { METADATA_FOLDER_NAME } from 'types/export'; +import { METADATA_FOLDER_NAME } from 'constants/export'; import { getUserFacingErrorMessage } from 'utils/common/errorUtil'; import { Collection } from 'types/collection'; import { SetLoading, SetFiles } from 'types/gallery'; diff --git a/src/constants/export/index.ts b/src/constants/export/index.ts new file mode 100644 index 000000000..9b50d8d75 --- /dev/null +++ b/src/constants/export/index.ts @@ -0,0 +1 @@ +export const METADATA_FOLDER_NAME = 'metadata'; diff --git a/src/types/export/index.ts b/src/types/export/index.ts index d38eb731b..0c222ef08 100644 --- a/src/types/export/index.ts +++ b/src/types/export/index.ts @@ -1,5 +1,3 @@ -export const METADATA_FOLDER_NAME = 'metadata'; - export enum ExportNotification { START = 'export started', IN_PROGRESS = 'export already in progress', diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index 7f3eab2ca..44a2be4f1 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -1,14 +1,12 @@ import { Collection } from 'types/collection'; import exportService from 'services/exportService'; -import { - CollectionIDPathMap, - ExportRecord, - METADATA_FOLDER_NAME, -} from 'types/export'; +import { CollectionIDPathMap, ExportRecord } from 'types/export'; + import { EnteFile } from 'types/file'; import { MetadataObject } from 'types/upload'; import { formatDate, splitFilenameAndExtension } from 'utils/file'; +import { METADATA_FOLDER_NAME } from 'constants/export'; export const getExportRecordFileUID = (file: EnteFile) => `${file.id}_${file.collectionID}_${file.updationTime}`; From 11e990ffe9b712d2c6c18ca81c5e1f28a5e897b5 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Tue, 4 Jan 2022 17:23:13 +0530 Subject: [PATCH 21/69] move file constants to constants/file --- src/components/EnteDateTimePicker.tsx | 2 +- src/components/PhotoSwipe/PhotoSwipe.tsx | 3 ++- src/constants/file/index.ts | 10 ++++++++++ src/services/exportService.ts | 3 +-- src/types/file/index.ts | 6 ------ src/types/search/index.ts | 1 - src/utils/file/index.ts | 15 +-------------- 7 files changed, 15 insertions(+), 25 deletions(-) create mode 100644 src/constants/file/index.ts diff --git a/src/components/EnteDateTimePicker.tsx b/src/components/EnteDateTimePicker.tsx index fcc955e64..16cea425d 100644 --- a/src/components/EnteDateTimePicker.tsx +++ b/src/components/EnteDateTimePicker.tsx @@ -6,7 +6,7 @@ import { MIN_EDITED_CREATION_TIME, MAX_EDITED_CREATION_TIME, ALL_TIME, -} from 'types/file'; +} from 'constants/file'; const isSameDay = (first, second) => first.getFullYear() === second.getFullYear() && diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx index ac0efb5b4..56902e10b 100644 --- a/src/components/PhotoSwipe/PhotoSwipe.tsx +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -8,7 +8,7 @@ import { removeFromFavorites, } from 'services/collectionService'; import { updatePublicMagicMetadata } from 'services/fileService'; -import { EnteFile, MAX_EDITED_FILE_NAME_LENGTH } from 'types/file'; +import { EnteFile } from 'types/file'; import constants from 'utils/strings/constants'; import exifr from 'exifr'; import Modal from 'react-bootstrap/Modal'; @@ -42,6 +42,7 @@ import { Formik } from 'formik'; import * as Yup from 'yup'; import EnteSpinner from 'components/EnteSpinner'; import EnteDateTimePicker from 'components/EnteDateTimePicker'; +import { MAX_EDITED_FILE_NAME_LENGTH } from 'constants/file'; interface Iprops { isOpen: boolean; diff --git a/src/constants/file/index.ts b/src/constants/file/index.ts new file mode 100644 index 000000000..0b936b865 --- /dev/null +++ b/src/constants/file/index.ts @@ -0,0 +1,10 @@ +export const MIN_EDITED_CREATION_TIME = new Date(1800, 0, 1); +export const MAX_EDITED_CREATION_TIME = new Date(); +export const ALL_TIME = new Date(1800, 0, 1, 23, 59, 59); + +export const MAX_EDITED_FILE_NAME_LENGTH = 100; + +export const TYPE_HEIC = 'heic'; +export const TYPE_HEIF = 'heif'; +export const TYPE_JPEG = 'jpeg'; +export const TYPE_JPG = 'jpg'; diff --git a/src/services/exportService.ts b/src/services/exportService.ts index 0ee0643d0..f670e95bb 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -36,8 +36,6 @@ import { generateStreamFromArrayBuffer, getFileExtension, mergeMetadata, - TYPE_JPEG, - TYPE_JPG, } from 'utils/file'; import { updateFileCreationDateInEXIF } from './upload/exifService'; @@ -53,6 +51,7 @@ import { ExportRecord, } from 'types/export'; import { User } from 'types/user'; +import { TYPE_JPEG, TYPE_JPG } from 'constants/file'; const LATEST_EXPORT_VERSION = 1; const EXPORT_RECORD_FILE_NAME = 'export_status.json'; diff --git a/src/types/file/index.ts b/src/types/file/index.ts index a668a520a..293c6ea3d 100644 --- a/src/types/file/index.ts +++ b/src/types/file/index.ts @@ -1,11 +1,5 @@ import { DataStream, MetadataObject } from 'types/upload'; -export const MIN_EDITED_CREATION_TIME = new Date(1800, 0, 1); -export const MAX_EDITED_CREATION_TIME = new Date(); -export const ALL_TIME = new Date(1800, 0, 1, 23, 59, 59); - -export const MAX_EDITED_FILE_NAME_LENGTH = 100; - export interface fileAttribute { encryptedData?: DataStream | Uint8Array; objectKey?: string; diff --git a/src/types/search/index.ts b/src/types/search/index.ts index 27ba7d255..0f3a7bfff 100644 --- a/src/types/search/index.ts +++ b/src/types/search/index.ts @@ -4,7 +4,6 @@ export interface LocationSearchResponse { place: string; bbox: Bbox; } -export const getMapboxToken = () => process.env.NEXT_PUBLIC_MAPBOX_TOKEN; export enum SuggestionType { DATE, diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index bf7c3ca27..06027bcee 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -17,12 +17,7 @@ import { User } from 'types/user'; import CryptoWorker from 'utils/crypto'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { updateFileCreationDateInEXIF } from 'services/upload/exifService'; - -export const TYPE_HEIC = 'heic'; -export const TYPE_HEIF = 'heif'; -export const TYPE_JPEG = 'jpeg'; -export const TYPE_JPG = 'jpg'; -const UNSUPPORTED_FORMATS = ['flv', 'mkv', '3gp', 'avi', 'wmv']; +import { TYPE_JPEG, TYPE_JPG, TYPE_HEIC, TYPE_HEIF } from 'constants/file'; export function downloadAsFile(filename: string, content: string) { const file = new Blob([content], { @@ -125,14 +120,6 @@ export function getSelectedFiles( return selectedFiles; } -export function checkFileFormatSupport(name: string) { - for (const format of UNSUPPORTED_FORMATS) { - if (name.toLowerCase().endsWith(format)) { - throw Error('unsupported format'); - } - } -} - export function formatDate(date: number | Date) { const dateTimeFormat = new Intl.DateTimeFormat('en-IN', { weekday: 'short', From ce22425be9c545b211c25bf0e25fcc2279d26385 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:11:32 +0530 Subject: [PATCH 22/69] move collection enum to constants/collection --- src/components/pages/gallery/CollectionSelector.tsx | 8 ++------ src/components/pages/gallery/CollectionSort.tsx | 2 +- .../pages/gallery/CollectionSortOptions.tsx | 2 +- src/components/pages/gallery/Collections.tsx | 9 +++------ src/constants/collection/index.ts | 12 ++++++++++++ src/pages/gallery/index.tsx | 7 ++----- src/services/collectionService.ts | 3 +-- src/types/collection/index.ts | 13 +------------ src/utils/collection/index.ts | 3 ++- 9 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index 9757b4ba7..d5f7b606b 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -1,16 +1,12 @@ import React, { useEffect, useState } from 'react'; import { Card, Modal } from 'react-bootstrap'; import styled from 'styled-components'; -import {} from 'services/collectionService'; import AddCollectionButton from './AddCollectionButton'; import PreviewCard from './PreviewCard'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { User } from 'types/user'; -import { - Collection, - CollectionAndItsLatestFile, - CollectionType, -} from 'types/collection'; +import { Collection, CollectionAndItsLatestFile } from 'types/collection'; +import { CollectionType } from 'constants/collection'; export const CollectionIcon = styled.div` width: 200px; diff --git a/src/components/pages/gallery/CollectionSort.tsx b/src/components/pages/gallery/CollectionSort.tsx index 80d212ad3..7f0c52b6b 100644 --- a/src/components/pages/gallery/CollectionSort.tsx +++ b/src/components/pages/gallery/CollectionSort.tsx @@ -2,7 +2,7 @@ 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 'types/collection'; +import { COLLECTION_SORT_BY } from 'constants/collection'; import constants from 'utils/strings/constants'; import CollectionSortOptions from './CollectionSortOptions'; import { IconWithMessage } from './SelectedFileOptions'; diff --git a/src/components/pages/gallery/CollectionSortOptions.tsx b/src/components/pages/gallery/CollectionSortOptions.tsx index 52a0ee9eb..a209c8998 100644 --- a/src/components/pages/gallery/CollectionSortOptions.tsx +++ b/src/components/pages/gallery/CollectionSortOptions.tsx @@ -2,7 +2,7 @@ import { 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 'types/collection'; +import { COLLECTION_SORT_BY } from 'constants/collection'; import styled from 'styled-components'; import constants from 'utils/strings/constants'; import { MenuItem, MenuLink } from './CollectionOptions'; diff --git a/src/components/pages/gallery/Collections.tsx b/src/components/pages/gallery/Collections.tsx index 590367057..e0380c7f1 100644 --- a/src/components/pages/gallery/Collections.tsx +++ b/src/components/pages/gallery/Collections.tsx @@ -9,12 +9,7 @@ import { sortCollections } from 'services/collectionService'; import { User } from 'types/user'; import styled from 'styled-components'; import { IMAGE_CONTAINER_MAX_WIDTH } from 'constants/gallery'; -import { - Collection, - CollectionAndItsLatestFile, - COLLECTION_SORT_BY, - CollectionType, -} from 'types/collection'; +import { Collection, CollectionAndItsLatestFile } from 'types/collection'; import { getSelectedCollection } from 'utils/collection'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import constants from 'utils/strings/constants'; @@ -25,6 +20,8 @@ import OptionIcon, { OptionIconWrapper } from './OptionIcon'; import { ALL_SECTION, ARCHIVE_SECTION, + CollectionType, + COLLECTION_SORT_BY, TRASH_SECTION, } from 'constants/collection'; diff --git a/src/constants/collection/index.ts b/src/constants/collection/index.ts index 4164301d7..afb10f0e4 100644 --- a/src/constants/collection/index.ts +++ b/src/constants/collection/index.ts @@ -1,3 +1,15 @@ export const ARCHIVE_SECTION = -1; export const TRASH_SECTION = -2; export const ALL_SECTION = 0; + +export enum CollectionType { + folder = 'folder', + favorites = 'favorites', + album = 'album', +} + +export enum COLLECTION_SORT_BY { + LATEST_FILE, + MODIFICATION_TIME, + NAME, +} diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index 0dba44731..fe206b2ca 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -67,6 +67,7 @@ import Upload from 'components/pages/gallery/Upload'; import { ALL_SECTION, ARCHIVE_SECTION, + CollectionType, TRASH_SECTION, } from 'constants/collection'; import { AppContext } from 'pages/_app'; @@ -93,11 +94,7 @@ import DeleteBtn from 'components/DeleteBtn'; import FixCreationTime, { FixCreationTimeAttributes, } from 'components/FixCreationTime'; -import { - Collection, - CollectionAndItsLatestFile, - CollectionType, -} from 'types/collection'; +import { Collection, CollectionAndItsLatestFile } from 'types/collection'; import { EnteFile, VISIBILITY_STATE } from 'types/file'; import { GalleryContextType, SelectedState, Search } from 'types/gallery'; import Collections from 'components/pages/gallery/Collections'; diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index 78b904387..9b26c370c 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -15,14 +15,13 @@ import { CustomError } from 'utils/common/errorUtil'; import { sortFiles } from 'utils/file'; import { Collection, - COLLECTION_SORT_BY, CollectionAndItsLatestFile, - CollectionType, AddToCollectionRequest, MoveToCollectionRequest, EncryptedFileKey, RemoveFromCollectionRequest, } from 'types/collection'; +import { COLLECTION_SORT_BY, CollectionType } from 'constants/collection'; const ENDPOINT = getEndpoint(); const COLLECTION_TABLE = 'collections'; diff --git a/src/types/collection/index.ts b/src/types/collection/index.ts index 04b9ddbdb..b6e35693a 100644 --- a/src/types/collection/index.ts +++ b/src/types/collection/index.ts @@ -1,11 +1,6 @@ import { User } from 'types/user'; import { EnteFile } from 'types/file'; - -export enum CollectionType { - folder = 'folder', - favorites = 'favorites', - album = 'album', -} +import { CollectionType } from 'constants/collection'; export interface Collection { id: number; @@ -51,12 +46,6 @@ export interface CollectionAndItsLatestFile { file: EnteFile; } -export enum COLLECTION_SORT_BY { - LATEST_FILE, - MODIFICATION_TIME, - NAME, -} - export interface RemoveFromCollectionRequest { collectionID: number; fileIDs: number[]; diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index 38c706882..5b7567dc2 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -14,7 +14,8 @@ import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { SetDialogMessage } from 'components/MessageDialog'; import { logError } from 'utils/sentry'; import constants from 'utils/strings/constants'; -import { Collection, CollectionType } from 'types/collection'; +import { Collection } from 'types/collection'; +import { CollectionType } from 'constants/collection'; export enum COLLECTION_OPS_TYPE { ADD, From 9e0fef474311252d36cbf681f7b01ad2a1639b4a Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:14:22 +0530 Subject: [PATCH 23/69] move export enums to constants/export --- src/components/ExportInProgress.tsx | 3 ++- src/components/ExportModal.tsx | 8 ++------ src/constants/export/index.ts | 27 +++++++++++++++++++++++++++ src/services/exportService.ts | 4 +--- src/types/export/index.ts | 27 +-------------------------- 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/components/ExportInProgress.tsx b/src/components/ExportInProgress.tsx index 27d9ed887..6f508a545 100644 --- a/src/components/ExportInProgress.tsx +++ b/src/components/ExportInProgress.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { Button, ProgressBar } from 'react-bootstrap'; -import { ExportProgress, ExportStage } from 'types/export'; +import { ExportProgress } from 'types/export'; import styled from 'styled-components'; import constants from 'utils/strings/constants'; +import { ExportStage } from 'constants/export'; export const ComfySpan = styled.span` word-spacing: 1rem; diff --git a/src/components/ExportModal.tsx b/src/components/ExportModal.tsx index b4822684c..17f1c790f 100644 --- a/src/components/ExportModal.tsx +++ b/src/components/ExportModal.tsx @@ -2,12 +2,7 @@ import isElectron from 'is-electron'; import React, { useEffect, useState } from 'react'; import { Button } from 'react-bootstrap'; import exportService from 'services/exportService'; -import { - ExportProgress, - ExportStage, - ExportStats, - ExportType, -} from 'types/export'; +import { ExportProgress, ExportStats } from 'types/export'; import { getLocalFiles } from 'services/fileService'; import { User } from 'types/user'; import styled from 'styled-components'; @@ -23,6 +18,7 @@ import ExportInProgress from './ExportInProgress'; import FolderIcon from './icons/FolderIcon'; import InProgressIcon from './icons/InProgressIcon'; import MessageDialog from './MessageDialog'; +import { ExportStage, ExportType } from 'constants/export'; const FolderIconWrapper = styled.div` width: 15%; diff --git a/src/constants/export/index.ts b/src/constants/export/index.ts index 9b50d8d75..4dcdc8f71 100644 --- a/src/constants/export/index.ts +++ b/src/constants/export/index.ts @@ -1 +1,28 @@ export const METADATA_FOLDER_NAME = 'metadata'; + +export enum ExportNotification { + START = 'export started', + IN_PROGRESS = 'export already in progress', + FINISH = 'export finished', + FAILED = 'export failed', + ABORT = 'export aborted', + PAUSE = 'export paused', + UP_TO_DATE = `no new files to export`, +} + +export enum RecordType { + SUCCESS = 'success', + FAILED = 'failed', +} +export enum ExportStage { + INIT, + INPROGRESS, + PAUSED, + FINISHED, +} + +export enum ExportType { + NEW, + PENDING, + RETRY_FAILED, +} diff --git a/src/services/exportService.ts b/src/services/exportService.ts index f670e95bb..ca78c47c4 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -44,14 +44,12 @@ import QueueProcessor from './upload/queueProcessor'; import { Collection } from 'types/collection'; import { ExportProgress, - ExportType, - ExportNotification, CollectionIDPathMap, - RecordType, ExportRecord, } from 'types/export'; import { User } from 'types/user'; import { TYPE_JPEG, TYPE_JPG } from 'constants/file'; +import { ExportType, ExportNotification, RecordType } from 'constants/export'; const LATEST_EXPORT_VERSION = 1; const EXPORT_RECORD_FILE_NAME = 'export_status.json'; diff --git a/src/types/export/index.ts b/src/types/export/index.ts index 0c222ef08..baf210f4c 100644 --- a/src/types/export/index.ts +++ b/src/types/export/index.ts @@ -1,17 +1,4 @@ -export enum ExportNotification { - START = 'export started', - IN_PROGRESS = 'export already in progress', - FINISH = 'export finished', - FAILED = 'export failed', - ABORT = 'export aborted', - PAUSE = 'export paused', - UP_TO_DATE = `no new files to export`, -} - -export enum RecordType { - SUCCESS = 'success', - FAILED = 'failed', -} +import { ExportStage } from 'constants/export'; export type CollectionIDPathMap = Map; export interface ExportProgress { @@ -36,15 +23,3 @@ export interface ExportRecord { failedFiles?: string[]; exportedCollectionPaths?: ExportedCollectionPaths; } -export enum ExportStage { - INIT, - INPROGRESS, - PAUSED, - FINISHED, -} - -export enum ExportType { - NEW, - PENDING, - RETRY_FAILED, -} From b00d7ea2b00fb47b4440032c4d0fdf32a436ca80 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:18:46 +0530 Subject: [PATCH 24/69] move file enums to constants/file --- src/components/PhotoFrame.tsx | 3 ++- src/components/SearchBar.tsx | 3 ++- src/constants/file/index.ts | 12 ++++++++++++ src/constants/upload/index.ts | 2 +- src/pages/gallery/index.tsx | 3 ++- src/services/downloadManager.ts | 3 ++- src/services/exportService.ts | 4 ++-- src/services/updateCreationTimeWithExif.ts | 3 ++- src/services/upload/metadataService.ts | 2 +- src/services/upload/readFileService.ts | 2 +- src/services/upload/thumbnailService.ts | 2 +- src/services/upload/uploader.ts | 3 ++- src/types/file/index.ts | 13 +------------ src/types/upload/index.ts | 3 ++- src/utils/file/index.ts | 11 ++++++++--- 15 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index af54667db..4f0ced8a2 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -2,7 +2,7 @@ import { GalleryContext } from 'pages/gallery'; import PreviewCard from './pages/gallery/PreviewCard'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { Button } from 'react-bootstrap'; -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import styled from 'styled-components'; import DownloadManager from 'services/downloadManager'; import constants from 'utils/strings/constants'; @@ -20,6 +20,7 @@ import { isSharedFile } from 'utils/file'; import { isPlaybackPossible } from 'utils/photoFrame'; import { PhotoList } from './PhotoList'; import { SetFiles, SelectedState, Search, setSearchStats } from 'types/gallery'; +import { FILE_TYPE } from 'constants/file'; const Container = styled.div` display: block; diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 5b9289699..b47680be9 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -23,9 +23,10 @@ import CollectionIcon from './icons/CollectionIcon'; import ImageIcon from './icons/ImageIcon'; import VideoIcon from './icons/VideoIcon'; import { IconButton } from './Container'; -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import { Suggestion, SuggestionType, DateValue, Bbox } from 'types/search'; import { Search, SearchStats } from 'types/gallery'; +import { FILE_TYPE } from 'constants/file'; const Wrapper = styled.div<{ isDisabled: boolean; isOpen: boolean }>` position: fixed; diff --git a/src/constants/file/index.ts b/src/constants/file/index.ts index 0b936b865..36ed503b8 100644 --- a/src/constants/file/index.ts +++ b/src/constants/file/index.ts @@ -8,3 +8,15 @@ export const TYPE_HEIC = 'heic'; export const TYPE_HEIF = 'heif'; export const TYPE_JPEG = 'jpeg'; export const TYPE_JPG = 'jpg'; + +export enum FILE_TYPE { + IMAGE, + VIDEO, + LIVE_PHOTO, + OTHERS, +} + +export enum VISIBILITY_STATE { + VISIBLE, + ARCHIVED, +} diff --git a/src/constants/upload/index.ts b/src/constants/upload/index.ts index 245ad3a12..195dd2ff2 100644 --- a/src/constants/upload/index.ts +++ b/src/constants/upload/index.ts @@ -1,5 +1,5 @@ import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; -import { FILE_TYPE } from 'types/file'; +import { FILE_TYPE } from 'constants/file'; import { Location } from 'services/upload/metadataService'; // list of format that were missed by type-detection for some files. diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index fe206b2ca..7e30faced 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -95,9 +95,10 @@ import FixCreationTime, { FixCreationTimeAttributes, } from 'components/FixCreationTime'; import { Collection, CollectionAndItsLatestFile } from 'types/collection'; -import { EnteFile, VISIBILITY_STATE } from 'types/file'; +import { EnteFile } from 'types/file'; import { GalleryContextType, SelectedState, Search } from 'types/gallery'; import Collections from 'components/pages/gallery/Collections'; +import { VISIBILITY_STATE } from 'constants/file'; export const DeadCenter = styled.div` flex: 1; diff --git a/src/services/downloadManager.ts b/src/services/downloadManager.ts index 219b49345..e49ca0ff7 100644 --- a/src/services/downloadManager.ts +++ b/src/services/downloadManager.ts @@ -7,9 +7,10 @@ import { needsConversionForPreview, } from 'utils/file'; import HTTPService from './HTTPService'; -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import { logError } from 'utils/sentry'; +import { FILE_TYPE } from 'constants/file'; class DownloadManager { private fileObjectUrlPromise = new Map>(); diff --git a/src/services/exportService.ts b/src/services/exportService.ts index ca78c47c4..7a28b9acd 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -28,7 +28,7 @@ import { } from './collectionService'; import downloadManager from './downloadManager'; import { getLocalFiles } from './fileService'; -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import { decodeMotionPhoto } from './motionPhotoService'; import { @@ -48,7 +48,7 @@ import { ExportRecord, } from 'types/export'; import { User } from 'types/user'; -import { TYPE_JPEG, TYPE_JPG } from 'constants/file'; +import { FILE_TYPE, TYPE_JPEG, TYPE_JPG } from 'constants/file'; import { ExportType, ExportNotification, RecordType } from 'constants/export'; const LATEST_EXPORT_VERSION = 1; diff --git a/src/services/updateCreationTimeWithExif.ts b/src/services/updateCreationTimeWithExif.ts index ec36d1f0d..edc58327d 100644 --- a/src/services/updateCreationTimeWithExif.ts +++ b/src/services/updateCreationTimeWithExif.ts @@ -9,10 +9,11 @@ import { import { logError } from 'utils/sentry'; import downloadManager from './downloadManager'; import { updatePublicMagicMetadata } from './fileService'; -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import { getRawExif, getUNIXTime } from './upload/exifService'; import { getFileType } from './upload/readFileService'; +import { FILE_TYPE } from 'constants/file'; export async function updateCreationTimeWithExif( filesToBeUpdated: EnteFile[], diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index 25dc158f7..0cea55283 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -1,4 +1,4 @@ -import { FILE_TYPE } from 'types/file'; +import { FILE_TYPE } from 'constants/file'; import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { FileTypeInfo } from './readFileService'; diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 3b533ea9b..4c91e9b0e 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -1,4 +1,4 @@ -import { FILE_TYPE } from 'types/file'; +import { FILE_TYPE } from 'constants/file'; import { logError } from 'utils/sentry'; import { FILE_READER_CHUNK_SIZE, diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 387c71294..f2a9a4b3b 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -1,4 +1,4 @@ -import { FILE_TYPE } from 'types/file'; +import { FILE_TYPE } from 'constants/file'; import { CustomError, errorWithContext } from 'utils/common/errorUtil'; import { logError } from 'utils/sentry'; import { BLACK_THUMBNAIL_BASE64 } from '../../../public/images/black-thumbnail-b64'; diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 6fa015116..a945b7caf 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -1,4 +1,4 @@ -import { EnteFile, FILE_TYPE } from 'types/file'; +import { EnteFile } from 'types/file'; import { sleep } from 'utils/common'; import { handleUploadError, CustomError } from 'utils/common/errorUtil'; import { decryptFile } from 'utils/file'; @@ -17,6 +17,7 @@ import UploadService, { import uploadService from './uploadService'; import { FileTypeInfo, getFileType } from './readFileService'; import { MetadataObject } from 'types/upload'; +import { FILE_TYPE } from 'constants/file'; const TwoSecondInMillSeconds = 2000; const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024; diff --git a/src/types/file/index.ts b/src/types/file/index.ts index 293c6ea3d..989832ef0 100644 --- a/src/types/file/index.ts +++ b/src/types/file/index.ts @@ -1,3 +1,4 @@ +import { VISIBILITY_STATE } from 'constants/file'; import { DataStream, MetadataObject } from 'types/upload'; export interface fileAttribute { @@ -6,18 +7,6 @@ export interface fileAttribute { decryptionHeader: string; } -export enum FILE_TYPE { - IMAGE, - VIDEO, - LIVE_PHOTO, - OTHERS, -} - -export enum VISIBILITY_STATE { - VISIBLE, - ARCHIVED, -} - export interface MagicMetadataCore { version: number; count: number; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 8f32ab7fb..08c86f577 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,4 +1,5 @@ -import { fileAttribute, FILE_TYPE } from 'types/file'; +import { FILE_TYPE } from 'constants/file'; +import { fileAttribute } from 'types/file'; export interface DataStream { stream: ReadableStream; diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 06027bcee..507f6638a 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -3,11 +3,9 @@ import { Collection } from 'types/collection'; import { EnteFile, fileAttribute, - FILE_TYPE, MagicMetadataProps, NEW_MAGIC_METADATA, PublicMagicMetadataProps, - VISIBILITY_STATE, } from 'types/file'; import { decodeMotionPhoto } from 'services/motionPhotoService'; import { getMimeTypeFromBlob } from 'services/upload/readFileService'; @@ -17,7 +15,14 @@ import { User } from 'types/user'; import CryptoWorker from 'utils/crypto'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { updateFileCreationDateInEXIF } from 'services/upload/exifService'; -import { TYPE_JPEG, TYPE_JPG, TYPE_HEIC, TYPE_HEIF } from 'constants/file'; +import { + TYPE_JPEG, + TYPE_JPG, + TYPE_HEIC, + TYPE_HEIF, + FILE_TYPE, + VISIBILITY_STATE, +} from 'constants/file'; export function downloadAsFile(filename: string, content: string) { const file = new Blob([content], { From a5849600b12cec66c08e0302c2bbf40305944bd9 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:25:48 +0530 Subject: [PATCH 25/69] move errorUtil from utils/common to utils/error --- src/components/pages/gallery/Upload.tsx | 2 +- src/pages/gallery/index.tsx | 2 +- src/services/collectionService.ts | 2 +- src/services/ffmpegService.ts | 2 +- src/services/upload/multiPartUploadService.ts | 2 +- src/services/upload/queueProcessor.ts | 2 +- src/services/upload/readFileService.ts | 2 +- src/services/upload/thumbnailService.ts | 2 +- src/services/upload/uploadHttpClient.ts | 2 +- src/services/upload/uploadManager.ts | 2 +- src/services/upload/uploadService.ts | 2 +- src/services/upload/uploader.ts | 2 +- src/utils/billing/index.ts | 2 +- src/utils/collection/index.ts | 2 +- src/utils/common/key.ts | 2 +- src/utils/{common/errorUtil.ts => error/index.ts} | 0 src/utils/sentry/index.ts | 2 +- 17 files changed, 16 insertions(+), 16 deletions(-) rename src/utils/{common/errorUtil.ts => error/index.ts} (100%) diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 1eef7a1e7..71cbb0877 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -18,7 +18,7 @@ import UploadManager, { } from 'services/upload/uploadManager'; import uploadManager from 'services/upload/uploadManager'; import { METADATA_FOLDER_NAME } from 'constants/export'; -import { getUserFacingErrorMessage } from 'utils/common/errorUtil'; +import { getUserFacingErrorMessage } from 'utils/error'; import { Collection } from 'types/collection'; import { SetLoading, SetFiles } from 'types/gallery'; diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index 7e30faced..cfbfdfc1a 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -71,7 +71,7 @@ import { TRASH_SECTION, } from 'constants/collection'; import { AppContext } from 'pages/_app'; -import { CustomError, ServerErrorCodes } from 'utils/common/errorUtil'; +import { CustomError, ServerErrorCodes } from 'utils/error'; import { PAGES } from 'constants/pages'; import { COLLECTION_OPS_TYPE, diff --git a/src/services/collectionService.ts b/src/services/collectionService.ts index 9b26c370c..cd63c2e56 100644 --- a/src/services/collectionService.ts +++ b/src/services/collectionService.ts @@ -11,7 +11,7 @@ import { B64EncryptionResult } from 'utils/crypto'; import HTTPService from './HTTPService'; import { EnteFile } from 'types/file'; import { logError } from 'utils/sentry'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { sortFiles } from 'utils/file'; import { Collection, diff --git a/src/services/ffmpegService.ts b/src/services/ffmpegService.ts index 1184593b4..4596181e1 100644 --- a/src/services/ffmpegService.ts +++ b/src/services/ffmpegService.ts @@ -1,5 +1,5 @@ import { createFFmpeg, FFmpeg } from '@ffmpeg/ffmpeg'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { logError } from 'utils/sentry'; import QueueProcessor from './upload/queueProcessor'; import { getUint8ArrayView } from './upload/readFileService'; diff --git a/src/services/upload/multiPartUploadService.ts b/src/services/upload/multiPartUploadService.ts index 022de1912..35f72cd4f 100644 --- a/src/services/upload/multiPartUploadService.ts +++ b/src/services/upload/multiPartUploadService.ts @@ -5,7 +5,7 @@ import { import UIService from './uiService'; import UploadHttpClient from './uploadHttpClient'; import * as convert from 'xml-js'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { DataStream } from 'types/upload'; interface PartEtag { diff --git a/src/services/upload/queueProcessor.ts b/src/services/upload/queueProcessor.ts index 6d9e86fc6..977660a8a 100644 --- a/src/services/upload/queueProcessor.ts +++ b/src/services/upload/queueProcessor.ts @@ -1,4 +1,4 @@ -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; interface RequestQueueItem { request: (canceller?: RequestCanceller) => Promise; diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 4c91e9b0e..696a8ec4b 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -6,7 +6,7 @@ import { MULTIPART_PART_SIZE, } from 'constants/upload'; import FileType from 'file-type/browser'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { getFileExtension } from 'utils/file'; const TYPE_VIDEO = 'video'; diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index f2a9a4b3b..50539f444 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -1,5 +1,5 @@ import { FILE_TYPE } from 'constants/file'; -import { CustomError, errorWithContext } from 'utils/common/errorUtil'; +import { CustomError, errorWithContext } from 'utils/error'; import { logError } from 'utils/sentry'; import { BLACK_THUMBNAIL_BASE64 } from '../../../public/images/black-thumbnail-b64'; import FFmpegService from 'services/ffmpegService'; diff --git a/src/services/upload/uploadHttpClient.ts b/src/services/upload/uploadHttpClient.ts index 968e5f53f..4497e1356 100644 --- a/src/services/upload/uploadHttpClient.ts +++ b/src/services/upload/uploadHttpClient.ts @@ -4,7 +4,7 @@ import { getToken } from 'utils/common/key'; import { logError } from 'utils/sentry'; import { UploadFile, UploadURL } from './uploadService'; import { EnteFile } from 'types/file'; -import { CustomError, handleUploadError } from 'utils/common/errorUtil'; +import { CustomError, handleUploadError } from 'utils/error'; import { retryAsyncFunction } from 'utils/network'; import { MultipartUploadURLs } from './multiPartUploadService'; diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index a093a4327..d24fc2b05 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -18,7 +18,7 @@ import { ProgressUpdater } from 'components/pages/gallery/Upload'; import uploader from './uploader'; import UIService from './uiService'; import UploadService from './uploadService'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { Collection } from 'types/collection'; import { EnteFile } from 'types/file'; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index ab4839675..8673c8759 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -16,7 +16,7 @@ import { import { encryptFiledata } from './encryptionService'; import { uploadStreamUsingMultipart } from './multiPartUploadService'; import UIService from './uiService'; -import { handleUploadError } from 'utils/common/errorUtil'; +import { handleUploadError } from 'utils/error'; import { MetadataMap } from './uploadManager'; import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index a945b7caf..4e454ae66 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -1,6 +1,6 @@ import { EnteFile } from 'types/file'; import { sleep } from 'utils/common'; -import { handleUploadError, CustomError } from 'utils/common/errorUtil'; +import { handleUploadError, CustomError } from 'utils/error'; import { decryptFile } from 'utils/file'; import { logError } from 'utils/sentry'; import { fileAlreadyInCollection } from 'utils/upload'; diff --git a/src/utils/billing/index.ts b/src/utils/billing/index.ts index e731db1fe..e8043d61d 100644 --- a/src/utils/billing/index.ts +++ b/src/utils/billing/index.ts @@ -5,7 +5,7 @@ import { NextRouter } from 'next/router'; import { SetDialogMessage } from 'components/MessageDialog'; import { SetLoading } from 'types/gallery'; import { getData, LS_KEYS } from '../storage/localStorage'; -import { CustomError } from '../common/errorUtil'; +import { CustomError } from '../error'; import { logError } from '../sentry'; const PAYMENT_PROVIDER_STRIPE = 'stripe'; diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts index 5b7567dc2..e63500b60 100644 --- a/src/utils/collection/index.ts +++ b/src/utils/collection/index.ts @@ -7,7 +7,7 @@ import { import { downloadFiles, getSelectedFiles } from 'utils/file'; import { getLocalFiles } from 'services/fileService'; import { EnteFile } from 'types/file'; -import { CustomError } from 'utils/common/errorUtil'; +import { CustomError } from 'utils/error'; import { SelectedState } from 'types/gallery'; import { User } from 'types/user'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; diff --git a/src/utils/common/key.ts b/src/utils/common/key.ts index 17d14b8ad..d3130d1fe 100644 --- a/src/utils/common/key.ts +++ b/src/utils/common/key.ts @@ -2,7 +2,7 @@ import { B64EncryptionResult } from 'utils/crypto'; import CryptoWorker from 'utils/crypto'; import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; -import { CustomError } from './errorUtil'; +import { CustomError } from '../error'; export const getActualKey = async () => { try { diff --git a/src/utils/common/errorUtil.ts b/src/utils/error/index.ts similarity index 100% rename from src/utils/common/errorUtil.ts rename to src/utils/error/index.ts diff --git a/src/utils/sentry/index.ts b/src/utils/sentry/index.ts index b3d4c87ca..a37919d34 100644 --- a/src/utils/sentry/index.ts +++ b/src/utils/sentry/index.ts @@ -1,5 +1,5 @@ import * as Sentry from '@sentry/nextjs'; -import { errorWithContext } from 'utils/common/errorUtil'; +import { errorWithContext } from 'utils/error'; import { getUserAnonymizedID } from 'utils/user'; export const logError = ( From 63960c207bf9487569802731af296c8b4c47c8f2 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:40:36 +0530 Subject: [PATCH 26/69] fix User import --- src/pages/verify/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 07023c5de..88f38663c 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -20,7 +20,7 @@ import { clearKeys } from 'utils/storage/sessionStorage'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; import { PAGES } from 'constants/pages'; -import { User } from '@sentry/nextjs'; +import { User } from 'types/user'; import { KeyAttributes, EmailVerificationResponse } from 'types/user'; interface formValues { From caef21f9396b4f826875ac5c00ce00f1b4dcfda8 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:41:16 +0530 Subject: [PATCH 27/69] merge types/user imports --- src/pages/verify/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 88f38663c..d12563012 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -20,8 +20,7 @@ import { clearKeys } from 'utils/storage/sessionStorage'; import { AppContext } from 'pages/_app'; import LogoImg from 'components/LogoImg'; import { PAGES } from 'constants/pages'; -import { User } from 'types/user'; -import { KeyAttributes, EmailVerificationResponse } from 'types/user'; +import { KeyAttributes, EmailVerificationResponse, User } from 'types/user'; interface formValues { ott: string; From 44bc3916a5b280ccbd9b8a063233b25ccdd945fa Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:46:57 +0530 Subject: [PATCH 28/69] move isDataStream type check util function to types/upload --- src/services/upload/encryptionService.ts | 3 +-- src/services/upload/uploadService.ts | 10 ++++++---- src/types/upload/index.ts | 4 ++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/services/upload/encryptionService.ts b/src/services/upload/encryptionService.ts index 512bff778..edbc4864b 100644 --- a/src/services/upload/encryptionService.ts +++ b/src/services/upload/encryptionService.ts @@ -1,5 +1,4 @@ -import { DataStream, EncryptionResult } from 'types/upload'; -import { isDataStream } from './uploadService'; +import { DataStream, EncryptionResult, isDataStream } from 'types/upload'; async function encryptFileStream(worker, fileData: DataStream) { const { stream, chunkCount } = fileData; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 8673c8759..32b7377cd 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -18,16 +18,18 @@ import { uploadStreamUsingMultipart } from './multiPartUploadService'; import UIService from './uiService'; import { handleUploadError } from 'utils/error'; import { MetadataMap } from './uploadManager'; -import { DataStream, EncryptionResult, MetadataObject } from 'types/upload'; +import { + DataStream, + EncryptionResult, + isDataStream, + MetadataObject, +} from 'types/upload'; export interface UploadURL { url: string; objectKey: string; } -export function isDataStream(object: any): object is DataStream { - return 'stream' in object; -} export interface B64EncryptionResult { encryptedData: string; key: string; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 08c86f577..2b79f71a4 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -6,6 +6,10 @@ export interface DataStream { chunkCount: number; } +export function isDataStream(object: any): object is DataStream { + return 'stream' in object; +} + export interface EncryptionResult { file: fileAttribute; key: string; From 7285af69775504adf85792abd4b4d116c7cd93b6 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 12:50:10 +0530 Subject: [PATCH 29/69] keep NULL_LOCATION along with Location type defination --- src/constants/upload/index.ts | 3 --- src/services/upload/exifService.ts | 3 +-- src/services/upload/metadataService.ts | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/constants/upload/index.ts b/src/constants/upload/index.ts index 195dd2ff2..36da767a8 100644 --- a/src/constants/upload/index.ts +++ b/src/constants/upload/index.ts @@ -1,6 +1,5 @@ import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; import { FILE_TYPE } from 'constants/file'; -import { Location } from 'services/upload/metadataService'; // list of format that were missed by type-detection for some files. export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ @@ -18,6 +17,4 @@ export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor( MULTIPART_PART_SIZE / FILE_READER_CHUNK_SIZE ); -export const NULL_LOCATION: Location = { latitude: null, longitude: null }; - export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random(); diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index fa24f02fc..43ea9222a 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -1,8 +1,7 @@ import exifr from 'exifr'; import piexif from 'piexifjs'; import { logError } from 'utils/sentry'; -import { NULL_LOCATION } from 'constants/upload'; -import { Location } from 'services/upload/metadataService'; +import { Location, NULL_LOCATION } from 'services/upload/metadataService'; import { FileTypeInfo } from './readFileService'; const EXIF_TAGS_NEEDED = [ diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index 0cea55283..5c2d40221 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -3,7 +3,6 @@ import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { FileTypeInfo } from './readFileService'; import { MetadataObject } from 'types/upload'; -import { NULL_LOCATION } from 'constants/upload'; export interface Location { latitude: number; @@ -21,6 +20,8 @@ interface ParsedMetaDataJSONWithTitle { parsedMetaDataJSON: ParsedMetaDataJSON; } +export const NULL_LOCATION: Location = { latitude: null, longitude: null }; + const NULL_PARSED_METADATA_JSON: ParsedMetaDataJSON = { creationTime: null, modificationTime: null, From 344d2b2c0c9f28110ff53c1951a93685368240c5 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 13:00:29 +0530 Subject: [PATCH 30/69] move ProgressUpdater interface to UIService --- src/components/pages/gallery/Upload.tsx | 12 ------------ src/services/upload/uiService.ts | 14 +++++++++++++- src/services/upload/uploadManager.ts | 3 +-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 71cbb0877..39cfe24bc 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -49,18 +49,6 @@ interface AnalysisResult { suggestedCollectionName: string; multipleFolders: boolean; } -export interface ProgressUpdater { - setPercentComplete: React.Dispatch>; - setFileCounter: React.Dispatch< - React.SetStateAction<{ - finished: number; - total: number; - }> - >; - setUploadStage: React.Dispatch>; - setFileProgress: React.Dispatch>>; - setUploadResult: React.Dispatch>>; -} export default function Upload(props: Props) { const [progressView, setProgressView] = useState(false); diff --git a/src/services/upload/uiService.ts b/src/services/upload/uiService.ts index 9d64ba99c..5001deda0 100644 --- a/src/services/upload/uiService.ts +++ b/src/services/upload/uiService.ts @@ -1,7 +1,19 @@ -import { ProgressUpdater } from 'components/pages/gallery/Upload'; import { RANDOM_PERCENTAGE_PROGRESS_FOR_PUT } from 'constants/upload'; import { UPLOAD_STAGES } from './uploadManager'; +export interface ProgressUpdater { + setPercentComplete: React.Dispatch>; + setFileCounter: React.Dispatch< + React.SetStateAction<{ + finished: number; + total: number; + }> + >; + setUploadStage: React.Dispatch>; + setFileProgress: React.Dispatch>>; + setUploadResult: React.Dispatch>>; +} + class UIService { private perFileProgress: number; private filesUploaded: number; diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index d24fc2b05..f783b16cb 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -14,9 +14,8 @@ import { parseMetadataJSON, } from './metadataService'; import { segregateFiles } from 'utils/upload'; -import { ProgressUpdater } from 'components/pages/gallery/Upload'; import uploader from './uploader'; -import UIService from './uiService'; +import UIService, { ProgressUpdater } from './uiService'; import UploadService from './uploadService'; import { CustomError } from 'utils/error'; import { Collection } from 'types/collection'; From 2faade0d421d8f004843a0876ac775c6cb113995 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 13:05:18 +0530 Subject: [PATCH 31/69] move KEK interface to types --- src/pages/change-password/index.tsx | 8 +------- src/pages/generate/index.tsx | 6 ------ src/types/user/index.ts | 6 ++++++ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/pages/change-password/index.tsx b/src/pages/change-password/index.tsx index 1eaee4a70..a9137edfe 100644 --- a/src/pages/change-password/index.tsx +++ b/src/pages/change-password/index.tsx @@ -13,13 +13,7 @@ import SetPasswordForm from 'components/SetPasswordForm'; import { AppContext } from 'pages/_app'; import { SESSION_KEYS } from 'utils/storage/sessionStorage'; import { PAGES } from 'constants/pages'; -import { UpdatedKey } from 'types/user'; - -export interface KEK { - key: string; - opsLimit: number; - memLimit: number; -} +import { KEK, UpdatedKey } from 'types/user'; export default function Generate() { const [token, setToken] = useState(); diff --git a/src/pages/generate/index.tsx b/src/pages/generate/index.tsx index 8457b6940..659fc2da9 100644 --- a/src/pages/generate/index.tsx +++ b/src/pages/generate/index.tsx @@ -19,12 +19,6 @@ import { AppContext } from 'pages/_app'; import { logError } from 'utils/sentry'; import { KeyAttributes, User } from 'types/user'; -export interface KEK { - key: string; - opsLimit: number; - memLimit: number; -} - export default function Generate() { const [token, setToken] = useState(); const router = useRouter(); diff --git a/src/types/user/index.ts b/src/types/user/index.ts index 60d07f57e..72ad9ba8f 100644 --- a/src/types/user/index.ts +++ b/src/types/user/index.ts @@ -14,6 +14,12 @@ export interface KeyAttributes { recoveryKeyEncryptedWithMasterKey: string; recoveryKeyDecryptionNonce: string; } +export interface KEK { + key: string; + opsLimit: number; + memLimit: number; +} + export interface UpdatedKey { kekSalt: string; encryptedKey: string; From e4f649c4670d5f89f4f85aca1b4507a43a7963b6 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 13:27:10 +0530 Subject: [PATCH 32/69] refactor upload service constants and types --- src/components/pages/gallery/Upload.tsx | 9 +- .../pages/gallery/UploadProgress.tsx | 6 +- src/constants/upload/index.ts | 19 ++++ src/services/migrateThumbnailService.ts | 3 +- src/services/upload/exifService.ts | 5 +- src/services/upload/metadataService.ts | 22 ++--- src/services/upload/multiPartUploadService.ts | 8 +- src/services/upload/readFileService.ts | 6 +- src/services/upload/thumbnailService.ts | 2 +- src/services/upload/uiService.ts | 20 ++--- src/services/upload/uploadHttpClient.ts | 3 +- src/services/upload/uploadManager.ts | 39 ++------- src/services/upload/uploadService.ts | 66 +++----------- src/services/upload/uploader.ts | 15 ++-- src/types/upload/index.ts | 86 +++++++++++++++++++ src/utils/crypto/index.ts | 3 +- src/utils/upload/index.ts | 3 +- 17 files changed, 164 insertions(+), 151 deletions(-) diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index 39cfe24bc..a8a6a2962 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -12,15 +12,14 @@ import { GalleryContext } from 'pages/gallery'; import { AppContext } from 'pages/_app'; import { logError } from 'utils/sentry'; import { FileRejection } from 'react-dropzone'; -import UploadManager, { - FileWithCollection, - UPLOAD_STAGES, -} from 'services/upload/uploadManager'; +import UploadManager from 'services/upload/uploadManager'; import uploadManager from 'services/upload/uploadManager'; import { METADATA_FOLDER_NAME } from 'constants/export'; import { getUserFacingErrorMessage } from 'utils/error'; import { Collection } from 'types/collection'; import { SetLoading, SetFiles } from 'types/gallery'; +import { UPLOAD_STAGES } from 'constants/upload'; +import { FileWithCollection } from 'types/upload'; const FIRST_ALBUM_NAME = 'My First Album'; @@ -40,7 +39,7 @@ interface Props { isFirstUpload: boolean; } -export enum UPLOAD_STRATEGY { +enum UPLOAD_STRATEGY { SINGLE_COLLECTION, COLLECTION_PER_FOLDER, } diff --git a/src/components/pages/gallery/UploadProgress.tsx b/src/components/pages/gallery/UploadProgress.tsx index d92e9685f..38052ff16 100644 --- a/src/components/pages/gallery/UploadProgress.tsx +++ b/src/components/pages/gallery/UploadProgress.tsx @@ -3,15 +3,13 @@ import ExpandMore from 'components/icons/ExpandMore'; import React, { useState } from 'react'; import { Button, Modal, ProgressBar } from 'react-bootstrap'; import { FileRejection } from 'react-dropzone'; -import { - FileUploadResults, - UPLOAD_STAGES, -} from 'services/upload/uploadManager'; + import styled from 'styled-components'; import { DESKTOP_APP_DOWNLOAD_URL } from 'utils/common'; import constants from 'utils/strings/constants'; import { Collapse } from 'react-collapse'; import { ButtonVariant, getVariantColor } from './LinkButton'; +import { FileUploadResults, UPLOAD_STAGES } from 'constants/upload'; interface Props { fileCounter; diff --git a/src/constants/upload/index.ts b/src/constants/upload/index.ts index 36da767a8..6a35e8203 100644 --- a/src/constants/upload/index.ts +++ b/src/constants/upload/index.ts @@ -1,5 +1,6 @@ import { ENCRYPTION_CHUNK_SIZE } from 'constants/crypto'; import { FILE_TYPE } from 'constants/file'; +import { Location } from 'types/upload'; // list of format that were missed by type-detection for some files. export const FORMAT_MISSED_BY_FILE_TYPE_LIB = [ @@ -18,3 +19,21 @@ export const FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART = Math.floor( ); export const RANDOM_PERCENTAGE_PROGRESS_FOR_PUT = () => 90 + 10 * Math.random(); + +export const NULL_LOCATION: Location = { latitude: null, longitude: null }; + +export enum UPLOAD_STAGES { + START, + READING_GOOGLE_METADATA_FILES, + UPLOADING, + FINISH, +} + +export enum FileUploadResults { + FAILED = -1, + SKIPPED = -2, + UNSUPPORTED = -3, + BLOCKED = -4, + TOO_LARGE = -5, + UPLOADED = 100, +} diff --git a/src/services/migrateThumbnailService.ts b/src/services/migrateThumbnailService.ts index c2a6aa0c1..03d26d940 100644 --- a/src/services/migrateThumbnailService.ts +++ b/src/services/migrateThumbnailService.ts @@ -7,11 +7,10 @@ import { getEndpoint } from 'utils/common/apiUtil'; import HTTPService from 'services/HTTPService'; import CryptoWorker from 'utils/crypto'; import uploadHttpClient from 'services/upload/uploadHttpClient'; -import { UploadURL } from 'services/upload/uploadService'; import { SetProgressTracker } from 'components/FixLargeThumbnail'; import { getFileType } from './upload/readFileService'; import { getLocalTrash, getTrashedFiles } from './trashService'; -import { EncryptionResult } from 'types/upload'; +import { EncryptionResult, UploadURL } from 'types/upload'; import { fileAttribute } from 'types/file'; const ENDPOINT = getEndpoint(); diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index 43ea9222a..6a97e78e1 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -1,8 +1,9 @@ +import { NULL_LOCATION } from 'constants/upload'; +import { Location } from 'types/upload'; import exifr from 'exifr'; import piexif from 'piexifjs'; +import { FileTypeInfo } from 'types/upload'; import { logError } from 'utils/sentry'; -import { Location, NULL_LOCATION } from 'services/upload/metadataService'; -import { FileTypeInfo } from './readFileService'; const EXIF_TAGS_NEEDED = [ 'DateTimeOriginal', diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index 5c2d40221..2c114017a 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -1,27 +1,19 @@ import { FILE_TYPE } from 'constants/file'; import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; -import { FileTypeInfo } from './readFileService'; -import { MetadataObject } from 'types/upload'; +import { + MetadataObject, + ParsedMetaDataJSON, + Location, + FileTypeInfo, +} from 'types/upload'; +import { NULL_LOCATION } from 'constants/upload'; -export interface Location { - latitude: number; - longitude: number; -} - -export interface ParsedMetaDataJSON { - creationTime: number; - modificationTime: number; - latitude: number; - longitude: number; -} interface ParsedMetaDataJSONWithTitle { title: string; parsedMetaDataJSON: ParsedMetaDataJSON; } -export const NULL_LOCATION: Location = { latitude: null, longitude: null }; - const NULL_PARSED_METADATA_JSON: ParsedMetaDataJSON = { creationTime: null, modificationTime: null, diff --git a/src/services/upload/multiPartUploadService.ts b/src/services/upload/multiPartUploadService.ts index 35f72cd4f..ddecde550 100644 --- a/src/services/upload/multiPartUploadService.ts +++ b/src/services/upload/multiPartUploadService.ts @@ -6,19 +6,13 @@ import UIService from './uiService'; import UploadHttpClient from './uploadHttpClient'; import * as convert from 'xml-js'; import { CustomError } from 'utils/error'; -import { DataStream } from 'types/upload'; +import { DataStream, MultipartUploadURLs } from 'types/upload'; interface PartEtag { PartNumber: number; ETag: string; } -export interface MultipartUploadURLs { - objectKey: string; - partURLs: string[]; - completeURL: string; -} - function calculatePartCount(chunkCount: number) { const partCount = Math.ceil( chunkCount / FILE_CHUNKS_COMBINED_FOR_A_UPLOAD_PART diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 696a8ec4b..710621c76 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -8,6 +8,7 @@ import { import FileType from 'file-type/browser'; import { CustomError } from 'utils/error'; import { getFileExtension } from 'utils/file'; +import { FileTypeInfo } from 'types/upload'; const TYPE_VIDEO = 'video'; const TYPE_IMAGE = 'image'; @@ -22,11 +23,6 @@ export async function getFileData(worker, file: File) { } } -export interface FileTypeInfo { - fileType: FILE_TYPE; - exactType: string; -} - export async function getFileType( worker, receivedFile: File diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 50539f444..7cd3ebd85 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -5,7 +5,7 @@ import { BLACK_THUMBNAIL_BASE64 } from '../../../public/images/black-thumbnail-b import FFmpegService from 'services/ffmpegService'; import { convertToHumanReadable } from 'utils/billing'; import { isFileHEIC } from 'utils/file'; -import { FileTypeInfo } from './readFileService'; +import { FileTypeInfo } from 'types/upload'; const MAX_THUMBNAIL_DIMENSION = 720; const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10; diff --git a/src/services/upload/uiService.ts b/src/services/upload/uiService.ts index 5001deda0..7857bb8b6 100644 --- a/src/services/upload/uiService.ts +++ b/src/services/upload/uiService.ts @@ -1,18 +1,8 @@ -import { RANDOM_PERCENTAGE_PROGRESS_FOR_PUT } from 'constants/upload'; -import { UPLOAD_STAGES } from './uploadManager'; - -export interface ProgressUpdater { - setPercentComplete: React.Dispatch>; - setFileCounter: React.Dispatch< - React.SetStateAction<{ - finished: number; - total: number; - }> - >; - setUploadStage: React.Dispatch>; - setFileProgress: React.Dispatch>>; - setUploadResult: React.Dispatch>>; -} +import { + RANDOM_PERCENTAGE_PROGRESS_FOR_PUT, + UPLOAD_STAGES, +} from 'constants/upload'; +import { ProgressUpdater } from 'types/upload'; class UIService { private perFileProgress: number; diff --git a/src/services/upload/uploadHttpClient.ts b/src/services/upload/uploadHttpClient.ts index 4497e1356..0e4d803af 100644 --- a/src/services/upload/uploadHttpClient.ts +++ b/src/services/upload/uploadHttpClient.ts @@ -2,11 +2,10 @@ import HTTPService from 'services/HTTPService'; import { getEndpoint } from 'utils/common/apiUtil'; import { getToken } from 'utils/common/key'; import { logError } from 'utils/sentry'; -import { UploadFile, UploadURL } from './uploadService'; import { EnteFile } from 'types/file'; import { CustomError, handleUploadError } from 'utils/error'; import { retryAsyncFunction } from 'utils/network'; -import { MultipartUploadURLs } from './multiPartUploadService'; +import { UploadFile, UploadURL, MultipartUploadURLs } from 'types/upload'; const ENDPOINT = getEndpoint(); const MAX_URL_REQUESTS = 50; diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index f783b16cb..9b1ec8851 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -8,46 +8,25 @@ import { removeUnnecessaryFileProps, } from 'utils/file'; import { logError } from 'utils/sentry'; -import { - getMetadataMapKey, - ParsedMetaDataJSON, - parseMetadataJSON, -} from './metadataService'; +import { getMetadataMapKey, parseMetadataJSON } from './metadataService'; import { segregateFiles } from 'utils/upload'; import uploader from './uploader'; -import UIService, { ProgressUpdater } from './uiService'; +import UIService from './uiService'; import UploadService from './uploadService'; import { CustomError } from 'utils/error'; import { Collection } from 'types/collection'; import { EnteFile } from 'types/file'; +import { + FileWithCollection, + MetadataMap, + ParsedMetaDataJSON, + ProgressUpdater, +} from 'types/upload'; +import { UPLOAD_STAGES, FileUploadResults } from 'constants/upload'; const MAX_CONCURRENT_UPLOADS = 4; const FILE_UPLOAD_COMPLETED = 100; -export enum FileUploadResults { - FAILED = -1, - SKIPPED = -2, - UNSUPPORTED = -3, - BLOCKED = -4, - TOO_LARGE = -5, - UPLOADED = 100, -} - -export interface FileWithCollection { - file: File; - collectionID?: number; - collection?: Collection; -} - -export enum UPLOAD_STAGES { - START, - READING_GOOGLE_METADATA_FILES, - UPLOADING, - FINISH, -} - -export type MetadataMap = Map; - class UploadManager { private cryptoWorkers = new Array(MAX_CONCURRENT_UPLOADS); private metadataMap: MetadataMap; diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 32b7377cd..87535419b 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -1,70 +1,30 @@ -import { fileAttribute } from 'types/file'; import { Collection } from 'types/collection'; import { logError } from 'utils/sentry'; import UploadHttpClient from './uploadHttpClient'; -import { - extractMetadata, - getMetadataMapKey, - ParsedMetaDataJSON, -} from './metadataService'; +import { extractMetadata, getMetadataMapKey } from './metadataService'; import { generateThumbnail } from './thumbnailService'; -import { - getFileOriginalName, - getFileData, - FileTypeInfo, -} from './readFileService'; +import { getFileOriginalName, getFileData } from './readFileService'; import { encryptFiledata } from './encryptionService'; import { uploadStreamUsingMultipart } from './multiPartUploadService'; import UIService from './uiService'; import { handleUploadError } from 'utils/error'; -import { MetadataMap } from './uploadManager'; import { - DataStream, + B64EncryptionResult, + BackupedFile, + EncryptedFile, EncryptionResult, + FileInMemory, + FileTypeInfo, + FileWithMetadata, isDataStream, + MetadataMap, MetadataObject, + ParsedMetaDataJSON, + ProcessedFile, + UploadFile, + UploadURL, } from 'types/upload'; -export interface UploadURL { - url: string; - objectKey: string; -} - -export interface B64EncryptionResult { - encryptedData: string; - key: string; - nonce: string; -} - -export interface FileInMemory { - filedata: Uint8Array | DataStream; - thumbnail: Uint8Array; - hasStaticThumbnail: boolean; -} - -export interface FileWithMetadata - extends Omit { - metadata: MetadataObject; -} - -export interface EncryptedFile { - file: ProcessedFile; - fileKey: B64EncryptionResult; -} -export interface ProcessedFile { - file: fileAttribute; - thumbnail: fileAttribute; - metadata: fileAttribute; - filename: string; -} -export interface BackupedFile extends Omit {} - -export interface UploadFile extends BackupedFile { - collectionID: number; - encryptedKey: string; - keyDecryptionNonce: string; -} - class UploadService { private uploadURLs: UploadURL[] = []; private metadataMap: Map; diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 4e454ae66..62ea32b23 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -6,18 +6,21 @@ import { logError } from 'utils/sentry'; import { fileAlreadyInCollection } from 'utils/upload'; import UploadHttpClient from './uploadHttpClient'; import UIService from './uiService'; -import { FileUploadResults, FileWithCollection } from './uploadManager'; -import UploadService, { +import UploadService from './uploadService'; +import uploadService from './uploadService'; +import { getFileType } from './readFileService'; +import { BackupedFile, EncryptedFile, FileInMemory, + FileTypeInfo, + FileWithCollection, FileWithMetadata, + MetadataObject, UploadFile, -} from './uploadService'; -import uploadService from './uploadService'; -import { FileTypeInfo, getFileType } from './readFileService'; -import { MetadataObject } from 'types/upload'; +} from 'types/upload'; import { FILE_TYPE } from 'constants/file'; +import { FileUploadResults } from 'constants/upload'; const TwoSecondInMillSeconds = 2000; const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 2b79f71a4..ef0e9f59d 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -1,4 +1,6 @@ import { FILE_TYPE } from 'constants/file'; +import { UPLOAD_STAGES } from 'constants/upload'; +import { Collection } from 'types/collection'; import { fileAttribute } from 'types/file'; export interface DataStream { @@ -24,3 +26,87 @@ export interface MetadataObject { fileType: FILE_TYPE; hasStaticThumbnail?: boolean; } + +export interface Location { + latitude: number; + longitude: number; +} + +export interface ParsedMetaDataJSON { + creationTime: number; + modificationTime: number; + latitude: number; + longitude: number; +} + +export interface MultipartUploadURLs { + objectKey: string; + partURLs: string[]; + completeURL: string; +} + +export interface FileTypeInfo { + fileType: FILE_TYPE; + exactType: string; +} + +export interface ProgressUpdater { + setPercentComplete: React.Dispatch>; + setFileCounter: React.Dispatch< + React.SetStateAction<{ + finished: number; + total: number; + }> + >; + setUploadStage: React.Dispatch>; + setFileProgress: React.Dispatch>>; + setUploadResult: React.Dispatch>>; +} + +export interface FileWithCollection { + file: File; + collectionID?: number; + collection?: Collection; +} + +export type MetadataMap = Map; + +export interface UploadURL { + url: string; + objectKey: string; +} + +export interface B64EncryptionResult { + encryptedData: string; + key: string; + nonce: string; +} + +export interface FileInMemory { + filedata: Uint8Array | DataStream; + thumbnail: Uint8Array; + hasStaticThumbnail: boolean; +} + +export interface FileWithMetadata + extends Omit { + metadata: MetadataObject; +} + +export interface EncryptedFile { + file: ProcessedFile; + fileKey: B64EncryptionResult; +} +export interface ProcessedFile { + file: fileAttribute; + thumbnail: fileAttribute; + metadata: fileAttribute; + filename: string; +} +export interface BackupedFile extends Omit {} + +export interface UploadFile extends BackupedFile { + collectionID: number; + encryptedKey: string; + keyDecryptionNonce: string; +} diff --git a/src/utils/crypto/index.ts b/src/utils/crypto/index.ts index d5e942233..9e1e39bd5 100644 --- a/src/utils/crypto/index.ts +++ b/src/utils/crypto/index.ts @@ -1,5 +1,4 @@ -import { KEK } from 'pages/generate'; -import { KeyAttributes } from 'types/user'; +import { KEK, KeyAttributes } from 'types/user'; import * as Comlink from 'comlink'; import { runningInBrowser } from 'utils/common'; import { SESSION_KEYS, setKey } from 'utils/storage/sessionStorage'; diff --git a/src/utils/upload/index.ts b/src/utils/upload/index.ts index 28761733d..8ca2aeaae 100644 --- a/src/utils/upload/index.ts +++ b/src/utils/upload/index.ts @@ -1,5 +1,4 @@ -import { FileWithCollection } from 'services/upload/uploadManager'; -import { MetadataObject } from 'types/upload'; +import { FileWithCollection, MetadataObject } from 'types/upload'; import { EnteFile } from 'types/file'; const TYPE_JSON = 'json'; From 9e099d4e6704e472ed030b4327e803deac2d6611 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 5 Jan 2022 13:28:24 +0530 Subject: [PATCH 33/69] moved queueProcessor to service directory --- src/services/exportService.ts | 2 +- src/services/ffmpegService.ts | 2 +- src/services/{upload => }/queueProcessor.ts | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/services/{upload => }/queueProcessor.ts (100%) diff --git a/src/services/exportService.ts b/src/services/exportService.ts index 7a28b9acd..d0c08b753 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -40,7 +40,7 @@ import { import { updateFileCreationDateInEXIF } from './upload/exifService'; import { MetadataObject } from 'types/upload'; -import QueueProcessor from './upload/queueProcessor'; +import QueueProcessor from './queueProcessor'; import { Collection } from 'types/collection'; import { ExportProgress, diff --git a/src/services/ffmpegService.ts b/src/services/ffmpegService.ts index 4596181e1..b204504df 100644 --- a/src/services/ffmpegService.ts +++ b/src/services/ffmpegService.ts @@ -1,7 +1,7 @@ import { createFFmpeg, FFmpeg } from '@ffmpeg/ffmpeg'; import { CustomError } from 'utils/error'; import { logError } from 'utils/sentry'; -import QueueProcessor from './upload/queueProcessor'; +import QueueProcessor from './queueProcessor'; import { getUint8ArrayView } from './upload/readFileService'; class FFmpegService { diff --git a/src/services/upload/queueProcessor.ts b/src/services/queueProcessor.ts similarity index 100% rename from src/services/upload/queueProcessor.ts rename to src/services/queueProcessor.ts From 3c4a0f7b6aeec0666d66cc310d5df21cf2eb14a2 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 10:11:33 +0530 Subject: [PATCH 34/69] add loading spinner during creation udpate api call --- src/components/EnteDateTimePicker.tsx | 15 ++++++++++++++- src/components/PhotoSwipe/PhotoSwipe.tsx | 20 +++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/components/EnteDateTimePicker.tsx b/src/components/EnteDateTimePicker.tsx index de4d37f71..09f5530fb 100644 --- a/src/components/EnteDateTimePicker.tsx +++ b/src/components/EnteDateTimePicker.tsx @@ -13,8 +13,21 @@ const isSameDay = (first, second) => first.getMonth() === second.getMonth() && first.getDate() === second.getDate(); -const EnteDateTimePicker = ({ isInEditMode, pickedTime, handleChange }) => ( +interface Props { + loading?: boolean; + isInEditMode: boolean; + pickedTime: Date; + handleChange: (date: Date) => void; +} + +const EnteDateTimePicker = ({ + loading, + isInEditMode, + pickedTime, + handleChange, +}: Props) => ( void; }) { + const [loading, setLoading] = useState(false); const originalCreationTime = new Date(file?.metadata.creationTime / 1000); const [isInEditMode, setIsInEditMode] = useState(false); @@ -100,6 +101,7 @@ function RenderCreationTime({ const saveEdits = async () => { try { + setLoading(true); if (isInEditMode && file) { const unixTimeInMicroSec = pickedTime.getTime() * 1000; if (unixTimeInMicroSec === file?.metadata.creationTime) { @@ -118,14 +120,16 @@ function RenderCreationTime({ } } catch (e) { logError(e, 'failed to update creationTime'); + } finally { + closeEditMode(); + setLoading(false); } - closeEditMode(); }; const discardEdits = () => { setPickedTime(originalCreationTime); closeEditMode(); }; - const handleChange = (newDate) => { + const handleChange = (newDate: Date) => { if (newDate instanceof Date) { setPickedTime(newDate); } @@ -137,6 +141,7 @@ function RenderCreationTime({ {isInEditMode ? ( - + {loading ? ( + + ) : ( + + )} From 14b1e59c90def72d0ff256bba8825bf764aa9341 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 10:21:08 +0530 Subject: [PATCH 35/69] abstract SmallLoadingSpinner --- src/components/PhotoSwipe/PhotoSwipe.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx index e163b7e97..edcf8b6af 100644 --- a/src/components/PhotoSwipe/PhotoSwipe.tsx +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -46,6 +46,14 @@ import * as Yup from 'yup'; import EnteSpinner from 'components/EnteSpinner'; import EnteDateTimePicker from 'components/EnteDateTimePicker'; +const SmallLoadingSpinner = () => ( + +); interface Iprops { isOpen: boolean; items: any[]; @@ -161,12 +169,7 @@ function RenderCreationTime({ <> {loading ? ( - + ) : ( )} @@ -253,12 +256,7 @@ const FileNameEditForm = ({ filename, saveEdits, discardEdits, extension }) => { {loading ? ( - + ) : ( )} From bf6a0ef7ccf6b4c1e2cd77f9ef3409d05db85a77 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 12:14:18 +0530 Subject: [PATCH 36/69] fix double counting selected items if new and previous range select overlap --- src/components/PhotoFrame.tsx | 27 +++++++++----------- src/components/pages/gallery/PreviewCard.tsx | 8 +++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index b91ea03ca..f6e0104a4 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -289,14 +289,19 @@ const PhotoFrame = ({ if (selected.collectionID !== activeCollection) { setSelected({ count: 0, collectionID: 0 }); } - if (checked) { + if (checked && typeof index !== 'undefined') { setRangeStart(index); } setSelected((selected) => ({ ...selected, [id]: checked, - count: checked ? selected.count + 1 : selected.count - 1, + count: + typeof selected[id] !== 'undefined' + ? selected.count + : checked + ? selected.count + 1 + : selected.count - 1, collectionID: activeCollection, })); }; @@ -306,18 +311,12 @@ const PhotoFrame = ({ const handleRangeSelect = (index: number) => () => { if (rangeStart !== index) { - let leftEnd = -1; - let rightEnd = -1; - if (index < rangeStart) { - leftEnd = index + 1; - rightEnd = rangeStart - 1; - } else { - leftEnd = rangeStart + 1; - rightEnd = index - 1; - } - for (let i = leftEnd; i <= rightEnd; i++) { + const direction = + (index - rangeStart) / Math.abs(index - rangeStart); + for (let i = rangeStart + direction; i !== index; i += direction) { handleSelect(filteredData[i].id)(true); } + handleSelect(filteredData[index].id, index)(true); } }; const getThumbnail = (file: File[], index: number) => ( @@ -337,9 +336,7 @@ const PhotoFrame = ({ selectOnClick={selected.count > 0} onHover={onHoverOver(index)} onRangeSelect={handleRangeSelect(index)} - isRangeSelectActive={ - isShiftKeyPressed && (rangeStart || rangeStart === 0) - } + isRangeSelectActive={isShiftKeyPressed && selected.count > 0} isInsSelectRange={ (index >= rangeStart && index <= currentHover) || (index >= currentHover && index <= rangeStart) diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index ddb4f7de0..e5e8fa3b0 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -217,8 +217,9 @@ export default function PreviewCard(props: IProps) { if (selectOnClick) { if (isRangeSelectActive) { onRangeSelect(); + } else { + onSelect?.(!selected); } - onSelect?.(!selected); } else if (file?.msrc || imgSrc) { onClick?.(); } @@ -227,15 +228,16 @@ export default function PreviewCard(props: IProps) { const handleSelect: React.ChangeEventHandler = (e) => { if (isRangeSelectActive) { onRangeSelect?.(); + } else { + onSelect?.(e.target.checked); } - onSelect?.(e.target.checked); }; const longPressCallback = () => { onSelect(!selected); }; const handleHover = () => { - if (selectOnClick) { + if (isRangeSelectActive) { onHover(); } }; From 2044f4f6cf7d439595b8b12488a4d203b1e1250f Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 12:15:13 +0530 Subject: [PATCH 37/69] remove unneccsary console log --- src/components/FixCreationTime/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/FixCreationTime/index.tsx b/src/components/FixCreationTime/index.tsx index 1e39fde44..05af59dea 100644 --- a/src/components/FixCreationTime/index.tsx +++ b/src/components/FixCreationTime/index.tsx @@ -89,7 +89,6 @@ export default function FixCreationTime(props: Props) { } const onSubmit = (values: formValues) => { - console.log(values); startFix(Number(values.option), new Date(values.customTime)); }; From e41b3c184f02edd7091fb9674f9b78125d538579 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 13:07:18 +0530 Subject: [PATCH 38/69] make onSelect required prop --- src/components/pages/gallery/CollectionSelector.tsx | 1 + src/components/pages/gallery/PreviewCard.tsx | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index b5d691eee..2ecc85754 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -86,6 +86,7 @@ function CollectionSelector({ {}} + onSelect={() => {}} forcedEnable /> diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index e5e8fa3b0..d9872746e 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -14,7 +14,7 @@ interface IProps { forcedEnable?: boolean; selectable?: boolean; selected?: boolean; - onSelect?: (checked: boolean) => void; + onSelect: (checked: boolean) => void; onHover?: () => void; onRangeSelect?: () => void; isRangeSelectActive?: boolean; @@ -218,7 +218,7 @@ export default function PreviewCard(props: IProps) { if (isRangeSelectActive) { onRangeSelect(); } else { - onSelect?.(!selected); + onSelect(!selected); } } else if (file?.msrc || imgSrc) { onClick?.(); @@ -229,7 +229,7 @@ export default function PreviewCard(props: IProps) { if (isRangeSelectActive) { onRangeSelect?.(); } else { - onSelect?.(e.target.checked); + onSelect(e.target.checked); } }; From a24ace5946d4dddbfb19811a8cfeaacab1da9ea9 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 13:07:52 +0530 Subject: [PATCH 39/69] deselect items if overlap between range selected value --- src/components/PhotoFrame.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index f6e0104a4..a411983e5 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -289,8 +289,12 @@ const PhotoFrame = ({ if (selected.collectionID !== activeCollection) { setSelected({ count: 0, collectionID: 0 }); } - if (checked && typeof index !== 'undefined') { - setRangeStart(index); + if (typeof index !== 'undefined') { + if (checked) { + setRangeStart(index); + } else { + setRangeStart(undefined); + } } setSelected((selected) => ({ @@ -311,12 +315,13 @@ const PhotoFrame = ({ const handleRangeSelect = (index: number) => () => { if (rangeStart !== index) { + const checked = !!selected[filteredData[index].id]; const direction = (index - rangeStart) / Math.abs(index - rangeStart); - for (let i = rangeStart + direction; i !== index; i += direction) { - handleSelect(filteredData[i].id)(true); + for (let i = rangeStart; i !== index; i += direction) { + handleSelect(filteredData[i].id)(!checked); } - handleSelect(filteredData[index].id, index)(true); + handleSelect(filteredData[index].id, index)(!checked); } }; const getThumbnail = (file: File[], index: number) => ( From 314f8d44b172e1c1384646ac6b22b6dfff06624e Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 13:35:27 +0530 Subject: [PATCH 40/69] handle range deselection --- src/components/PhotoFrame.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index a411983e5..7e169e9b4 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -301,7 +301,7 @@ const PhotoFrame = ({ ...selected, [id]: checked, count: - typeof selected[id] !== 'undefined' + (typeof selected[id] === 'undefined') !== checked ? selected.count : checked ? selected.count + 1 From 6d76611079e249e849920af818d8fdf05f338d86 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 13:53:29 +0530 Subject: [PATCH 41/69] =?UTF-8?q?fix=20counting=20again=20=F0=9F=A5=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PhotoFrame.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index 7e169e9b4..1dec490ce 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -301,7 +301,7 @@ const PhotoFrame = ({ ...selected, [id]: checked, count: - (typeof selected[id] === 'undefined') !== checked + selected[id] === checked ? selected.count : checked ? selected.count + 1 From 73882919d1de4f0d19f8bff6f7033ce7792d04c6 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 6 Jan 2022 14:12:41 +0530 Subject: [PATCH 42/69] handle case where range select with few selected and few unselected items select all the items in the union of two ranges --- src/components/PhotoFrame.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index 1dec490ce..06c257635 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -315,9 +315,12 @@ const PhotoFrame = ({ const handleRangeSelect = (index: number) => () => { if (rangeStart !== index) { - const checked = !!selected[filteredData[index].id]; const direction = (index - rangeStart) / Math.abs(index - rangeStart); + let checked = true; + for (let i = rangeStart; i !== index; i += direction) { + checked = checked && !!selected[filteredData[i].id]; + } for (let i = rangeStart; i !== index; i += direction) { handleSelect(filteredData[i].id)(!checked); } From 19beffa936752e80ffa3887a6b757b931188edb8 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 11:29:01 +0530 Subject: [PATCH 43/69] add headers to development mode app --- next.config.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/next.config.js b/next.config.js index eb784081a..ccf5c637f 100644 --- a/next.config.js +++ b/next.config.js @@ -11,6 +11,44 @@ const gitSha = cp.execSync('git rev-parse --short HEAD', { encoding: 'utf8', }); +const COOP_COEP_HEADERS = { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', +}; + +const WEB_SECURITY_HEADERS = { + 'Strict-Transport-Security': ' max-age=63072000', + 'X-Content-Type-Options': 'nosniff', + 'X-Download-Options': 'noopen', + 'X-Frame-Options': 'deny', + 'X-XSS-Protection': '1; mode=block', + 'Referrer-Policy': 'same-origin', +}; + +const CSP_DIRECTIVES = { + 'default-src': "'none'", + 'img-src': "'self' blob:", + 'style-src': "'self' 'unsafe-inline'", + 'font-src ': "'self'; script-src 'self' 'unsafe-eval' blob:", + 'connect-src': + "'self' https://*.ente.io data: blob: https://ente-prod-eu.s3.eu-central-003.backblazeb2.com ", + 'base-uri ': "'self'", + 'frame-ancestors': " 'none'", + 'form-action': "'none'", + 'report-uri': 'https://csp-reporter.ente.io', + 'report-to': 'https://csp-reporter.ente.io', +}; + +const buildCSPHeader = (directives) => ({ + 'Content-Security-Policy-Report-Only': Object.entries(directives).reduce( + (acc, [key, value]) => acc + `${key} ${value};`, + '' + ), +}); + +const convertToNextHeaderFormat = (headers) => + Object.entries(headers).map(([key, value]) => ({ key, value })); + module.exports = withSentryConfig( withWorkbox( withBundleAnalyzer({ @@ -21,6 +59,20 @@ module.exports = withSentryConfig( swSrc: 'src/serviceWorker.js', exclude: [/manifest\.json$/i], }, + + headers() { + return [ + { + // Apply these headers to all routes in your application.... + source: '/(.*)', + headers: convertToNextHeaderFormat({ + ...COOP_COEP_HEADERS, + ...WEB_SECURITY_HEADERS, + ...buildCSPHeader(CSP_DIRECTIVES), + }), + }, + ]; + }, // https://dev.to/marcinwosinek/how-to-add-resolve-fallback-to-webpack-5-in-nextjs-10-i6j webpack: (config, { isServer }) => { if (!isServer) { From 76c1870fff938af8f4b2293e229074ec8e8a02a7 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 11:32:20 +0530 Subject: [PATCH 44/69] extract constants and util function from next.config file --- configUtil.js | 53 ++++++++++++++++++++++++++++++++++++++++++++ next.config.js | 60 +++++++++++--------------------------------------- tsconfig.json | 16 +++++--------- 3 files changed, 71 insertions(+), 58 deletions(-) create mode 100644 configUtil.js diff --git a/configUtil.js b/configUtil.js new file mode 100644 index 000000000..8df2cc72a --- /dev/null +++ b/configUtil.js @@ -0,0 +1,53 @@ +const cp = require('child_process'); + +module.exports = { + COOP_COEP_HEADERS: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }, + + WEB_SECURITY_HEADERS: { + 'Strict-Transport-Security': ' max-age=63072000', + 'X-Content-Type-Options': 'nosniff', + 'X-Download-Options': 'noopen', + 'X-Frame-Options': 'deny', + 'X-XSS-Protection': '1; mode=block', + 'Referrer-Policy': 'same-origin', + }, + + CSP_DIRECTIVES: { + 'default-src': "'none'", + 'img-src': "'self' blob:", + 'style-src': "'self' 'unsafe-inline'", + 'font-src ': "'self'; script-src 'self' 'unsafe-eval' blob:", + 'connect-src': + "'self' https://*.ente.io data: blob: https://ente-prod-eu.s3.eu-central-003.backblazeb2.com ", + 'base-uri ': "'self'", + 'frame-ancestors': " 'none'", + 'form-action': "'none'", + 'report-uri': 'https://csp-reporter.ente.io', + 'report-to': 'https://csp-reporter.ente.io', + }, + + WORKBOX_CONFIG: { + swSrc: 'src/serviceWorker.js', + exclude: [/manifest\.json$/i], + }, + + ALL_ROUTES: '/(.*)', + + buildCSPHeader: (directives) => ({ + 'Content-Security-Policy-Report-Only': Object.entries( + directives + ).reduce((acc, [key, value]) => acc + `${key} ${value};`, ''), + }), + + convertToNextHeaderFormat: (headers) => + Object.entries(headers).map(([key, value]) => ({ key, value })), + + getGitSha: () => + cp.execSync('git rev-parse --short HEAD', { + cwd: __dirname, + encoding: 'utf8', + }), +}; diff --git a/next.config.js b/next.config.js index ccf5c637f..b9b12c7e6 100644 --- a/next.config.js +++ b/next.config.js @@ -5,49 +5,18 @@ const withWorkbox = require('@ente-io/next-with-workbox'); const { withSentryConfig } = require('@sentry/nextjs'); -const cp = require('child_process'); -const gitSha = cp.execSync('git rev-parse --short HEAD', { - cwd: __dirname, - encoding: 'utf8', -}); +const { + getGitSha, + convertToNextHeaderFormat, + buildCSPHeader, + COOP_COEP_HEADERS, + WEB_SECURITY_HEADERS, + CSP_DIRECTIVES, + WORKBOX_CONFIG, + ALL_ROUTES, +} = require('./configUtil'); -const COOP_COEP_HEADERS = { - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Cross-Origin-Embedder-Policy': 'require-corp', -}; - -const WEB_SECURITY_HEADERS = { - 'Strict-Transport-Security': ' max-age=63072000', - 'X-Content-Type-Options': 'nosniff', - 'X-Download-Options': 'noopen', - 'X-Frame-Options': 'deny', - 'X-XSS-Protection': '1; mode=block', - 'Referrer-Policy': 'same-origin', -}; - -const CSP_DIRECTIVES = { - 'default-src': "'none'", - 'img-src': "'self' blob:", - 'style-src': "'self' 'unsafe-inline'", - 'font-src ': "'self'; script-src 'self' 'unsafe-eval' blob:", - 'connect-src': - "'self' https://*.ente.io data: blob: https://ente-prod-eu.s3.eu-central-003.backblazeb2.com ", - 'base-uri ': "'self'", - 'frame-ancestors': " 'none'", - 'form-action': "'none'", - 'report-uri': 'https://csp-reporter.ente.io', - 'report-to': 'https://csp-reporter.ente.io', -}; - -const buildCSPHeader = (directives) => ({ - 'Content-Security-Policy-Report-Only': Object.entries(directives).reduce( - (acc, [key, value]) => acc + `${key} ${value};`, - '' - ), -}); - -const convertToNextHeaderFormat = (headers) => - Object.entries(headers).map(([key, value]) => ({ key, value })); +const gitSha = getGitSha(); module.exports = withSentryConfig( withWorkbox( @@ -55,16 +24,13 @@ module.exports = withSentryConfig( env: { SENTRY_RELEASE: gitSha, }, - workbox: { - swSrc: 'src/serviceWorker.js', - exclude: [/manifest\.json$/i], - }, + workbox: WORKBOX_CONFIG, headers() { return [ { // Apply these headers to all routes in your application.... - source: '/(.*)', + source: ALL_ROUTES, headers: convertToNextHeaderFormat({ ...COOP_COEP_HEADERS, ...WEB_SECURITY_HEADERS, diff --git a/tsconfig.json b/tsconfig.json index 46e7172e8..4e0195e39 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,7 @@ { "compilerOptions": { "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext", - "webworker" - ], + "lib": ["dom", "dom.iterable", "esnext", "webworker"], "allowJs": true, "skipLibCheck": true, "strict": false, @@ -25,9 +20,8 @@ "next-env.d.ts", "**/*.ts", "**/*.tsx", - "src/pages/index.tsx" + "src/pages/index.tsx", + "configUtil.js" ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + "exclude": ["node_modules"] +} From 509750ff8f20d6eb2dc8a1a73a608d4166c04635 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 17:28:05 +0530 Subject: [PATCH 45/69] refactor sentry config --- configUtil.js | 12 ++++++++++++ next.config.js | 9 ++++++--- sentry.client.config.js | 18 ++++++++++++------ sentry.server.config.js | 16 ++++++++++++---- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/configUtil.js b/configUtil.js index 8df2cc72a..172b9435e 100644 --- a/configUtil.js +++ b/configUtil.js @@ -50,4 +50,16 @@ module.exports = { cwd: __dirname, encoding: 'utf8', }), + + getSentryDSN: () => + process.env.NEXT_PUBLIC_SENTRY_DSN ?? + 'https://860186db60c54c7fbacfe255124958e8@errors.ente.io/4', + + getSentryENV: () => process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development', + + getSentryRelease: () => process.env.SENTRY_RELEASE, + + isSentryEnabled: () => + process.env.SENTRY_ENABLED ?? + (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development', }; diff --git a/next.config.js b/next.config.js index b9b12c7e6..ee9744388 100644 --- a/next.config.js +++ b/next.config.js @@ -14,15 +14,18 @@ const { CSP_DIRECTIVES, WORKBOX_CONFIG, ALL_ROUTES, + isSentryEnabled, } = require('./configUtil'); -const gitSha = getGitSha(); +const GIT_SHA = getGitSha(); + +const SENTRY_ENABLED = isSentryEnabled(); module.exports = withSentryConfig( withWorkbox( withBundleAnalyzer({ env: { - SENTRY_RELEASE: gitSha, + SENTRY_RELEASE: GIT_SHA, }, workbox: WORKBOX_CONFIG, @@ -48,5 +51,5 @@ module.exports = withSentryConfig( }, }) ), - { release: gitSha } + { release: GIT_SHA, dryRun: !SENTRY_ENABLED } ); diff --git a/sentry.client.config.js b/sentry.client.config.js index 25276ba34..c543a0bd8 100644 --- a/sentry.client.config.js +++ b/sentry.client.config.js @@ -1,18 +1,24 @@ import * as Sentry from '@sentry/nextjs'; import { getSentryTunnelUrl } from 'utils/common/apiUtil'; import { getUserAnonymizedID } from 'utils/user'; +import { + getSentryDSN, + getSentryENV, + getSentryRelease, + isSentryEnabled, +} from './configUtil'; -const SENTRY_DSN = - process.env.NEXT_PUBLIC_SENTRY_DSN ?? - 'https://860186db60c54c7fbacfe255124958e8@errors.ente.io/4'; -const SENTRY_ENV = process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development'; +const SENTRY_DSN = getSentryDSN(); +const SENTRY_ENV = getSentryENV(); +const SENTRY_RELEASE = getSentryRelease(); +const ENABLED = isSentryEnabled(); Sentry.setUser({ id: getUserAnonymizedID() }); Sentry.init({ dsn: SENTRY_DSN, - enabled: SENTRY_ENV !== 'development', + enabled: ENABLED, environment: SENTRY_ENV, - release: process.env.SENTRY_RELEASE, + release: SENTRY_RELEASE, attachStacktrace: true, autoSessionTracking: false, tunnel: getSentryTunnelUrl(), diff --git a/sentry.server.config.js b/sentry.server.config.js index 33af4278b..21b0d6d48 100644 --- a/sentry.server.config.js +++ b/sentry.server.config.js @@ -1,12 +1,20 @@ import * as Sentry from '@sentry/nextjs'; +import { + getSentryDSN, + getSentryENV, + getSentryRelease, + isSentryEnabled, +} from './configUtil'; -const SENTRY_DSN = process.env.NEXT_PUBLIC_SENTRY_DSN ?? 'https://860186db60c54c7fbacfe255124958e8@errors.ente.io/4'; -const SENTRY_ENV = process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development'; +const SENTRY_DSN = getSentryDSN(); +const SENTRY_ENV = getSentryENV(); +const SENTRY_RELEASE = getSentryRelease(); +const ENABLED = isSentryEnabled(); Sentry.init({ dsn: SENTRY_DSN, - enabled: SENTRY_ENV !== 'development', + enabled: ENABLED, environment: SENTRY_ENV, - release: process.env.SENTRY_RELEASE, + release: SENTRY_RELEASE, autoSessionTracking: false, }); From fbf6476d70dcbd204d32687b9a47fe88b8ff208a Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 17:52:37 +0530 Subject: [PATCH 46/69] move sentry constants to constants/sentry --- configUtil.js | 8 -------- sentry.client.config.js | 2 +- sentry.server.config.js | 2 +- src/constants/sentry/index.ts | 12 ++++++++++++ 4 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 src/constants/sentry/index.ts diff --git a/configUtil.js b/configUtil.js index 172b9435e..db1cb2634 100644 --- a/configUtil.js +++ b/configUtil.js @@ -51,14 +51,6 @@ module.exports = { encoding: 'utf8', }), - getSentryDSN: () => - process.env.NEXT_PUBLIC_SENTRY_DSN ?? - 'https://860186db60c54c7fbacfe255124958e8@errors.ente.io/4', - - getSentryENV: () => process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development', - - getSentryRelease: () => process.env.SENTRY_RELEASE, - isSentryEnabled: () => process.env.SENTRY_ENABLED ?? (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development', diff --git a/sentry.client.config.js b/sentry.client.config.js index c543a0bd8..4b39522c0 100644 --- a/sentry.client.config.js +++ b/sentry.client.config.js @@ -6,7 +6,7 @@ import { getSentryENV, getSentryRelease, isSentryEnabled, -} from './configUtil'; +} from 'constants/sentry'; const SENTRY_DSN = getSentryDSN(); const SENTRY_ENV = getSentryENV(); diff --git a/sentry.server.config.js b/sentry.server.config.js index 21b0d6d48..62b0029c0 100644 --- a/sentry.server.config.js +++ b/sentry.server.config.js @@ -4,7 +4,7 @@ import { getSentryENV, getSentryRelease, isSentryEnabled, -} from './configUtil'; +} from 'constants/sentry'; const SENTRY_DSN = getSentryDSN(); const SENTRY_ENV = getSentryENV(); diff --git a/src/constants/sentry/index.ts b/src/constants/sentry/index.ts new file mode 100644 index 000000000..4adcecb7f --- /dev/null +++ b/src/constants/sentry/index.ts @@ -0,0 +1,12 @@ +export const getSentryDSN = () => + process.env.NEXT_PUBLIC_SENTRY_DSN ?? + 'https://860186db60c54c7fbacfe255124958e8@errors.ente.io/4'; + +export const getSentryENV = () => + process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development'; + +export const getSentryRelease = () => process.env.SENTRY_RELEASE; + +export const isSentryEnabled = () => + process.env.SENTRY_ENABLED ?? + (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development'; From 5427fbf232cb7d892b83ea1aaf7c782dba9c555d Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 18:06:22 +0530 Subject: [PATCH 47/69] move isSentryEnabled needed by both config util and constants/sentry to seperate file sentryConfigUtil as neither of the two files can import each other --- configUtil.js | 6 ++---- sentryConfigUtil.js | 3 +++ src/constants/sentry/index.ts | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 sentryConfigUtil.js diff --git a/configUtil.js b/configUtil.js index db1cb2634..e0941ea61 100644 --- a/configUtil.js +++ b/configUtil.js @@ -1,4 +1,5 @@ const cp = require('child_process'); +const { isSentryEnabled } = require('./sentryConfigUtil'); module.exports = { COOP_COEP_HEADERS: { @@ -50,8 +51,5 @@ module.exports = { cwd: __dirname, encoding: 'utf8', }), - - isSentryEnabled: () => - process.env.SENTRY_ENABLED ?? - (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development', + isSentryEnabled: isSentryEnabled, }; diff --git a/sentryConfigUtil.js b/sentryConfigUtil.js new file mode 100644 index 000000000..f022efb00 --- /dev/null +++ b/sentryConfigUtil.js @@ -0,0 +1,3 @@ +module.exports.isSentryEnabled = () => + process.env.SENTRY_ENABLED ?? + (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development'; diff --git a/src/constants/sentry/index.ts b/src/constants/sentry/index.ts index 4adcecb7f..79aec9795 100644 --- a/src/constants/sentry/index.ts +++ b/src/constants/sentry/index.ts @@ -7,6 +7,4 @@ export const getSentryENV = () => export const getSentryRelease = () => process.env.SENTRY_RELEASE; -export const isSentryEnabled = () => - process.env.SENTRY_ENABLED ?? - (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development'; +export { isSentryEnabled } from '../../../sentryConfigUtil'; From 2161d8e42180c9705fa4055d921c02c14b15e7b1 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 18:17:24 +0530 Subject: [PATCH 48/69] replace ?? use by if else statements --- sentryConfigUtil.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sentryConfigUtil.js b/sentryConfigUtil.js index f022efb00..d8f5da7a3 100644 --- a/sentryConfigUtil.js +++ b/sentryConfigUtil.js @@ -1,3 +1,10 @@ -module.exports.isSentryEnabled = () => - process.env.SENTRY_ENABLED ?? - (process.env.NEXT_PUBLIC_SENTRY_ENV ?? 'development') !== 'development'; +module.exports.isSentryEnabled = () => { + if (process.env.SENTRY_ENABLED) { + return process.env.SENTRY_ENABLED === 'yes'; + } else { + if (process.env.NEXT_PUBLIC_SENTRY_ENV) { + return process.env.NEXT_PUBLIC_SENTRY_ENV !== 'development'; + } + } + return false; +}; From bd3d6d84ceefd66ed3aad7f886572f8c23df2db7 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 17:24:02 +0530 Subject: [PATCH 49/69] use global file reader and reuse them wherever possible --- src/services/exportService.ts | 5 +++++ src/services/ffmpegService.ts | 19 ++++++++++++++++--- src/services/migrateThumbnailService.ts | 2 ++ src/services/upload/exifService.ts | 6 +++--- src/services/upload/metadataService.ts | 6 ++++-- src/services/upload/readFileService.ts | 8 ++++---- src/services/upload/thumbnailService.ts | 4 +++- src/services/upload/uploadManager.ts | 9 ++++++--- src/services/upload/uploadService.ts | 4 +++- src/services/upload/uploader.ts | 8 +++++++- src/utils/file/index.ts | 1 + src/worker/crypto.worker.js | 24 ------------------------ 12 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/services/exportService.ts b/src/services/exportService.ts index d0c08b753..c4ccbf2b1 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -62,6 +62,7 @@ class ExportService { private stopExport: boolean = false; private pauseExport: boolean = false; private allElectronAPIsExist: boolean = false; + private fileReader: FileReader = null; constructor() { this.ElectronAPIs = runningInBrowser() && window['ElectronAPIs']; @@ -438,7 +439,11 @@ class ExportService { (fileType === TYPE_JPEG || fileType === TYPE_JPG) ) { const fileBlob = await new Response(fileStream).blob(); + if (!this.fileReader) { + this.fileReader = new FileReader(); + } const updatedFileBlob = await updateFileCreationDateInEXIF( + this.fileReader, fileBlob, new Date(file.pubMagicMetadata.data.editedTime / 1000) ); diff --git a/src/services/ffmpegService.ts b/src/services/ffmpegService.ts index b204504df..bd91f34b5 100644 --- a/src/services/ffmpegService.ts +++ b/src/services/ffmpegService.ts @@ -7,6 +7,7 @@ import { getUint8ArrayView } from './upload/readFileService'; class FFmpegService { private ffmpeg: FFmpeg = null; private isLoading = null; + private fileReader: FileReader = null; private generateThumbnailProcessor = new QueueProcessor(1); async init() { @@ -29,11 +30,19 @@ class FFmpegService { if (!this.ffmpeg) { await this.init(); } + if (this.fileReader) { + this.fileReader = new FileReader(); + } if (this.isLoading) { await this.isLoading; } const response = this.generateThumbnailProcessor.queueUpRequest( - generateThumbnailHelper.bind(null, this.ffmpeg, file) + generateThumbnailHelper.bind( + null, + this.ffmpeg, + this.fileReader, + file + ) ); try { return await response.promise; @@ -49,14 +58,18 @@ class FFmpegService { } } -async function generateThumbnailHelper(ffmpeg: FFmpeg, file: File) { +async function generateThumbnailHelper( + ffmpeg: FFmpeg, + reader: FileReader, + file: File +) { try { const inputFileName = `${Date.now().toString()}-${file.name}`; const thumbFileName = `${Date.now().toString()}-thumb.jpeg`; ffmpeg.FS( 'writeFile', inputFileName, - await getUint8ArrayView(new FileReader(), file) + await getUint8ArrayView(reader, file) ); let seekTime = 1.0; let thumb = null; diff --git a/src/services/migrateThumbnailService.ts b/src/services/migrateThumbnailService.ts index 03d26d940..dfea14fba 100644 --- a/src/services/migrateThumbnailService.ts +++ b/src/services/migrateThumbnailService.ts @@ -44,6 +44,7 @@ export async function replaceThumbnail( try { const token = getToken(); const worker = await new CryptoWorker(); + const reader = new FileReader(); const files = await getLocalFiles(); const trash = await getLocalTrash(); const trashFiles = getTrashedFiles(trash); @@ -79,6 +80,7 @@ export async function replaceThumbnail( const fileTypeInfo = await getFileType(worker, dummyImageFile); const { thumbnail: newThumbnail } = await generateThumbnail( worker, + reader, dummyImageFile, fileTypeInfo ); diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index 6a97e78e1..e463598ed 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -57,12 +57,13 @@ export async function getExifData( } export async function updateFileCreationDateInEXIF( + reader: FileReader, fileBlob: Blob, updatedDate: Date ) { try { const fileURL = URL.createObjectURL(fileBlob); - let imageDataURL = await convertImageToDataURL(fileURL); + let imageDataURL = await convertImageToDataURL(reader, fileURL); imageDataURL = 'data:image/jpeg;base64' + imageDataURL.slice(imageDataURL.indexOf(',')); @@ -82,10 +83,9 @@ export async function updateFileCreationDateInEXIF( } } -export async function convertImageToDataURL(url: string) { +export async function convertImageToDataURL(reader: FileReader, url: string) { const blob = await fetch(url).then((r) => r.blob()); const dataUrl = await new Promise((resolve) => { - const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.readAsDataURL(blob); }); diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index 2c114017a..a7233f37d 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -44,10 +44,12 @@ export async function extractMetadata( export const getMetadataMapKey = (collectionID: number, title: string) => `${collectionID}_${title}`; -export async function parseMetadataJSON(receivedFile: File) { +export async function parseMetadataJSON( + reader: FileReader, + receivedFile: File +) { try { const metadataJSON: object = await new Promise((resolve, reject) => { - const reader = new FileReader(); reader.onabort = () => reject(Error('file reading was aborted')); reader.onerror = () => reject(Error('file reading has failed')); reader.onload = () => { diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 710621c76..a3c28eb8b 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -15,11 +15,11 @@ const TYPE_IMAGE = 'image'; const EDITED_FILE_SUFFIX = '-edited'; const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100; -export async function getFileData(worker, file: File) { +export async function getFileData(worker, reader: FileReader, file: File) { if (file.size > MULTIPART_PART_SIZE) { return getFileStream(worker, file, FILE_READER_CHUNK_SIZE); } else { - return await worker.getUint8ArrayView(file); + return await getUint8ArrayView(reader, file); } } @@ -81,9 +81,9 @@ async function getMimeType(worker, file: File) { return getMimeTypeFromBlob(worker, fileChunkBlob); } -export async function getMimeTypeFromBlob(worker, fileBlob: Blob) { +export async function getMimeTypeFromBlob(reader: FileReader, fileBlob: Blob) { try { - const initialFiledata = await worker.getUint8ArrayView(fileBlob); + const initialFiledata = await getUint8ArrayView(reader, fileBlob); const result = await FileType.fromBuffer(initialFiledata); return result.mime; } catch (e) { diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 7cd3ebd85..7d908899d 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -6,6 +6,7 @@ import FFmpegService from 'services/ffmpegService'; import { convertToHumanReadable } from 'utils/billing'; import { isFileHEIC } from 'utils/file'; import { FileTypeInfo } from 'types/upload'; +import { getUint8ArrayView } from './readFileService'; const MAX_THUMBNAIL_DIMENSION = 720; const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10; @@ -22,6 +23,7 @@ interface Dimension { export async function generateThumbnail( worker, + reader: FileReader, file: File, fileTypeInfo: FileTypeInfo ): Promise<{ thumbnail: Uint8Array; hasStaticThumbnail: boolean }> { @@ -50,7 +52,7 @@ export async function generateThumbnail( } } const thumbnailBlob = await thumbnailCanvasToBlob(canvas); - thumbnail = await worker.getUint8ArrayView(thumbnailBlob); + thumbnail = await getUint8ArrayView(reader, thumbnailBlob); if (thumbnail.length === 0) { throw Error('EMPTY THUMBNAIL'); } diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index 9b1ec8851..4c8aad969 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -92,9 +92,10 @@ class UploadManager { private async seedMetadataMap(metadataFiles: FileWithCollection[]) { try { UIService.reset(metadataFiles.length); - + const reader = new FileReader(); for (const fileWithCollection of metadataFiles) { const parsedMetaDataJSONWithTitle = await parseMetadataJSON( + reader, fileWithCollection.file ); if (parsedMetaDataJSONWithTitle) { @@ -137,14 +138,15 @@ class UploadManager { this.cryptoWorkers[i] = cryptoWorker; uploadProcesses.push( this.uploadNextFileInQueue( - await new this.cryptoWorkers[i].comlink() + await new this.cryptoWorkers[i].comlink(), + new FileReader() ) ); } await Promise.all(uploadProcesses); } - private async uploadNextFileInQueue(worker: any) { + private async uploadNextFileInQueue(worker: any, reader: FileReader) { while (this.filesToBeUploaded.length > 0) { const fileWithCollection = this.filesToBeUploaded.pop(); const existingFilesInCollection = @@ -157,6 +159,7 @@ class UploadManager { fileWithCollection.collection = collection; const { fileUploadResult, file } = await uploader( worker, + reader, existingFilesInCollection, fileWithCollection ); diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 87535419b..87a7ee8eb 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -38,16 +38,18 @@ class UploadService { async readFile( worker: any, + reader: FileReader, rawFile: File, fileTypeInfo: FileTypeInfo ): Promise { const { thumbnail, hasStaticThumbnail } = await generateThumbnail( worker, + reader, rawFile, fileTypeInfo ); - const filedata = await getFileData(worker, rawFile); + const filedata = await getFileData(worker, reader, rawFile); return { filedata, diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 62ea32b23..805a3aa0e 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -30,6 +30,7 @@ interface UploadResponse { } export default async function uploader( worker: any, + reader: FileReader, existingFilesInCollection: EnteFile[], fileWithCollection: FileWithCollection ): Promise { @@ -70,7 +71,12 @@ export default async function uploader( return { fileUploadResult: FileUploadResults.SKIPPED }; } - file = await UploadService.readFile(worker, rawFile, fileTypeInfo); + file = await UploadService.readFile( + worker, + reader, + rawFile, + fileTypeInfo + ); if (file.hasStaticThumbnail) { metadata.hasStaticThumbnail = true; } diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 507f6638a..2eab2361b 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -60,6 +60,7 @@ export async function downloadFile(file: EnteFile) { let fileBlob = await (await fetch(fileURL)).blob(); fileBlob = await updateFileCreationDateInEXIF( + new FileReader(), fileBlob, new Date(file.pubMagicMetadata.data.editedTime / 1000) ); diff --git a/src/worker/crypto.worker.js b/src/worker/crypto.worker.js index e4da90107..cf0137831 100644 --- a/src/worker/crypto.worker.js +++ b/src/worker/crypto.worker.js @@ -149,30 +149,6 @@ export class Crypto { return libsodium.fromHex(string); } - // temporary fix for https://github.com/vercel/next.js/issues/25484 - async getUint8ArrayView(file) { - try { - return await new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onabort = () => - reject(Error('file reading was aborted')); - reader.onerror = () => reject(Error('file reading has failed')); - reader.onload = () => { - // Do whatever you want with the file contents - const result = - typeof reader.result === 'string' - ? new TextEncoder().encode(reader.result) - : new Uint8Array(reader.result); - resolve(result); - }; - reader.readAsArrayBuffer(file); - }); - } catch (e) { - console.log(e, 'error reading file to byte-array'); - throw e; - } - } - async convertHEIC2JPEG(file) { return convertHEIC2JPEG(file); } From 8fc784a1f5f73a7e158f4b561dd831a82c0af917 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 18:34:42 +0530 Subject: [PATCH 50/69] replace one missed worker.getUint8ArrayView function --- src/services/upload/readFileService.ts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index a3c28eb8b..b7d9751ff 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -17,7 +17,7 @@ const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100; export async function getFileData(worker, reader: FileReader, file: File) { if (file.size > MULTIPART_PART_SIZE) { - return getFileStream(worker, file, FILE_READER_CHUNK_SIZE); + return getFileStream(worker, reader, file, FILE_READER_CHUNK_SIZE); } else { return await getUint8ArrayView(reader, file); } @@ -91,8 +91,18 @@ export async function getMimeTypeFromBlob(reader: FileReader, fileBlob: Blob) { } } -function getFileStream(worker, file: File, chunkSize: number) { - const fileChunkReader = fileChunkReaderMaker(worker, file, chunkSize); +function getFileStream( + worker, + reader: FileReader, + file: File, + chunkSize: number +) { + const fileChunkReader = fileChunkReaderMaker( + worker, + reader, + file, + chunkSize + ); const stream = new ReadableStream({ async pull(controller: ReadableStreamDefaultController) { @@ -111,11 +121,16 @@ function getFileStream(worker, file: File, chunkSize: number) { }; } -async function* fileChunkReaderMaker(worker, file: File, chunkSize: number) { +async function* fileChunkReaderMaker( + worker, + reader: FileReader, + file: File, + chunkSize: number +) { let offset = 0; while (offset < file.size) { const blob = file.slice(offset, chunkSize + offset); - const fileChunk = await worker.getUint8ArrayView(blob); + const fileChunk = await getUint8ArrayView(reader, blob); yield fileChunk; offset += chunkSize; } From 15a03a87b3479493e5b64732745b4bf5af65c431 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Fri, 7 Jan 2022 19:54:09 +0530 Subject: [PATCH 51/69] rename type MetadataObject to Metadata --- src/services/exportService.ts | 4 ++-- src/services/upload/metadataService.ts | 4 ++-- src/services/upload/uploadService.ts | 6 +++--- src/services/upload/uploader.ts | 4 ++-- src/types/file/index.ts | 4 ++-- src/types/upload/index.ts | 4 ++-- src/utils/export/index.ts | 4 ++-- src/utils/upload/index.ts | 8 ++++---- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/services/exportService.ts b/src/services/exportService.ts index c4ccbf2b1..3e413576a 100644 --- a/src/services/exportService.ts +++ b/src/services/exportService.ts @@ -39,7 +39,7 @@ import { } from 'utils/file'; import { updateFileCreationDateInEXIF } from './upload/exifService'; -import { MetadataObject } from 'types/upload'; +import { Metadata } from 'types/upload'; import QueueProcessor from './queueProcessor'; import { Collection } from 'types/collection'; import { @@ -509,7 +509,7 @@ class ExportService { private async saveMetadataFile( collectionFolderPath: string, fileSaveName: string, - metadata: MetadataObject + metadata: Metadata ) { await this.ElectronAPIs.saveFileToDisk( getFileMetadataSavePath(collectionFolderPath, fileSaveName), diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index a7233f37d..fcc044dc1 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -2,7 +2,7 @@ import { FILE_TYPE } from 'constants/file'; import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { - MetadataObject, + Metadata, ParsedMetaDataJSON, Location, FileTypeInfo, @@ -29,7 +29,7 @@ export async function extractMetadata( exifData = await getExifData(receivedFile, fileTypeInfo); } - const extractedMetadata: MetadataObject = { + const extractedMetadata: Metadata = { title: receivedFile.name, creationTime: exifData?.creationTime ?? receivedFile.lastModified * 1000, diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 87a7ee8eb..a3e8d884d 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -18,7 +18,7 @@ import { FileWithMetadata, isDataStream, MetadataMap, - MetadataObject, + Metadata, ParsedMetaDataJSON, ProcessedFile, UploadFile, @@ -62,13 +62,13 @@ class UploadService { rawFile: File, collection: Collection, fileTypeInfo: FileTypeInfo - ): Promise { + ): Promise { const originalName = getFileOriginalName(rawFile); const googleMetadata = this.metadataMap.get( getMetadataMapKey(collection.id, originalName) ) ?? {}; - const extractedMetadata: MetadataObject = await extractMetadata( + const extractedMetadata: Metadata = await extractMetadata( rawFile, fileTypeInfo ); diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 805a3aa0e..47335c2c8 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -16,7 +16,7 @@ import { FileTypeInfo, FileWithCollection, FileWithMetadata, - MetadataObject, + Metadata, UploadFile, } from 'types/upload'; import { FILE_TYPE } from 'constants/file'; @@ -40,7 +40,7 @@ export default async function uploader( let file: FileInMemory = null; let encryptedFile: EncryptedFile = null; - let metadata: MetadataObject = null; + let metadata: Metadata = null; let fileTypeInfo: FileTypeInfo = null; let fileWithMetadata: FileWithMetadata = null; diff --git a/src/types/file/index.ts b/src/types/file/index.ts index 989832ef0..ab0b1a566 100644 --- a/src/types/file/index.ts +++ b/src/types/file/index.ts @@ -1,5 +1,5 @@ import { VISIBILITY_STATE } from 'constants/file'; -import { DataStream, MetadataObject } from 'types/upload'; +import { DataStream, Metadata } from 'types/upload'; export interface fileAttribute { encryptedData?: DataStream | Uint8Array; @@ -42,7 +42,7 @@ export interface EnteFile { ownerID: number; file: fileAttribute; thumbnail: fileAttribute; - metadata: MetadataObject; + metadata: Metadata; magicMetadata: MagicMetadata; pubMagicMetadata: PublicMagicMetadata; encryptedKey: string; diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index ef0e9f59d..968209c51 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -17,7 +17,7 @@ export interface EncryptionResult { key: string; } -export interface MetadataObject { +export interface Metadata { title: string; creationTime: number; modificationTime: number; @@ -90,7 +90,7 @@ export interface FileInMemory { export interface FileWithMetadata extends Omit { - metadata: MetadataObject; + metadata: Metadata; } export interface EncryptedFile { diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts index 44a2be4f1..ed58f4420 100644 --- a/src/utils/export/index.ts +++ b/src/utils/export/index.ts @@ -4,7 +4,7 @@ import { CollectionIDPathMap, ExportRecord } from 'types/export'; import { EnteFile } from 'types/file'; -import { MetadataObject } from 'types/upload'; +import { Metadata } from 'types/upload'; import { formatDate, splitFilenameAndExtension } from 'utils/file'; import { METADATA_FOLDER_NAME } from 'constants/export'; @@ -127,7 +127,7 @@ export const dedupe = (files: any[]) => { export const getGoogleLikeMetadataFile = ( fileSaveName: string, - metadata: MetadataObject + metadata: Metadata ) => { const creationTime = Math.floor(metadata.creationTime / 1000000); const modificationTime = Math.floor( diff --git a/src/utils/upload/index.ts b/src/utils/upload/index.ts index 8ca2aeaae..ebf11f0a3 100644 --- a/src/utils/upload/index.ts +++ b/src/utils/upload/index.ts @@ -1,11 +1,11 @@ -import { FileWithCollection, MetadataObject } from 'types/upload'; +import { FileWithCollection, Metadata } from 'types/upload'; import { EnteFile } from 'types/file'; const TYPE_JSON = 'json'; export function fileAlreadyInCollection( existingFilesInCollection: EnteFile[], - newFileMetadata: MetadataObject + newFileMetadata: Metadata ): boolean { for (const existingFile of existingFilesInCollection) { if (areFilesSame(existingFile.metadata, newFileMetadata)) { @@ -15,8 +15,8 @@ export function fileAlreadyInCollection( return false; } export function areFilesSame( - existingFile: MetadataObject, - newFile: MetadataObject + existingFile: Metadata, + newFile: Metadata ): boolean { if ( existingFile.fileType === newFile.fileType && From f7884905739ae73ef354827cd10ccb1944da5a91 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 8 Jan 2022 12:29:10 +0530 Subject: [PATCH 52/69] fixc worker passed instead of FileReader to getMimeTypeFromBlob --- src/services/upload/readFileService.ts | 8 ++++---- src/services/upload/uploader.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index b7d9751ff..08ef8dd2e 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -24,12 +24,12 @@ export async function getFileData(worker, reader: FileReader, file: File) { } export async function getFileType( - worker, + reader: FileReader, receivedFile: File ): Promise { try { let fileType: FILE_TYPE; - const mimeType = await getMimeType(worker, receivedFile); + const mimeType = await getMimeType(reader, receivedFile); const typeParts = mimeType?.split('/'); if (typeParts?.length !== 2) { throw Error(CustomError.TYPE_DETECTION_FAILED); @@ -76,9 +76,9 @@ export function getFileOriginalName(file: File) { return originalName; } -async function getMimeType(worker, file: File) { +async function getMimeType(reader: FileReader, file: File) { const fileChunkBlob = file.slice(0, CHUNK_SIZE_FOR_TYPE_DETECTION); - return getMimeTypeFromBlob(worker, fileChunkBlob); + return getMimeTypeFromBlob(reader, fileChunkBlob); } export async function getMimeTypeFromBlob(reader: FileReader, fileBlob: Blob) { diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index 805a3aa0e..ebb86a284 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -54,7 +54,7 @@ export default async function uploader( await sleep(TwoSecondInMillSeconds); return { fileUploadResult: FileUploadResults.TOO_LARGE }; } - fileTypeInfo = await getFileType(worker, rawFile); + fileTypeInfo = await getFileType(reader, rawFile); if (fileTypeInfo.fileType === FILE_TYPE.OTHERS) { throw Error(CustomError.UNSUPPORTED_FILE_FORMAT); } From 585d3acf8899155afca02fc06ad4e80c3e3d5219 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 8 Jan 2022 13:09:43 +0530 Subject: [PATCH 53/69] fix multiple folder detection for sibling folder with no common ancestor --- src/components/pages/gallery/Upload.tsx | 42 +++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index a8a6a2962..ac0379797 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -273,10 +273,14 @@ export default function Upload(props: Props) { }; const uploadToSingleNewCollection = (collectionName: string) => { - uploadFilesToNewCollections( - UPLOAD_STRATEGY.SINGLE_COLLECTION, - collectionName - ); + if (collectionName) { + uploadFilesToNewCollections( + UPLOAD_STRATEGY.SINGLE_COLLECTION, + collectionName + ); + } else { + showCollectionCreateModal(analysisResult); + } }; const showCollectionCreateModal = (analysisResult: AnalysisResult) => { props.setCollectionNamerAttributes({ @@ -291,25 +295,23 @@ export default function Upload(props: Props) { analysisResult: AnalysisResult, isFirstUpload: boolean ) => { - if (!analysisResult.suggestedCollectionName) { - if (isFirstUpload) { - uploadToSingleNewCollection(FIRST_ALBUM_NAME); - } else { - props.setCollectionSelectorAttributes({ - callback: uploadFilesToExistingCollection, - showNextModal: () => - showCollectionCreateModal(analysisResult), - title: constants.UPLOAD_TO_COLLECTION, - }); - } + if (isFirstUpload) { + uploadToSingleNewCollection(FIRST_ALBUM_NAME); } else { + let showNextModal = () => {}; if (analysisResult.multipleFolders) { - setChoiceModalView(true); - } else if (analysisResult.suggestedCollectionName) { - uploadToSingleNewCollection( - analysisResult.suggestedCollectionName - ); + showNextModal = () => setChoiceModalView(true); + } else { + showNextModal = () => + uploadToSingleNewCollection( + analysisResult.suggestedCollectionName + ); } + props.setCollectionSelectorAttributes({ + callback: uploadFilesToExistingCollection, + showNextModal, + title: constants.UPLOAD_TO_COLLECTION, + }); } }; From 0e7ab5c886dcd89320b303e4260c15ad366fd03b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 8 Jan 2022 13:34:50 +0530 Subject: [PATCH 54/69] fix if fileReader not present check --- src/services/ffmpegService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/ffmpegService.ts b/src/services/ffmpegService.ts index bd91f34b5..3914cfea2 100644 --- a/src/services/ffmpegService.ts +++ b/src/services/ffmpegService.ts @@ -30,7 +30,7 @@ class FFmpegService { if (!this.ffmpeg) { await this.init(); } - if (this.fileReader) { + if (!this.fileReader) { this.fileReader = new FileReader(); } if (this.isLoading) { From d4eb4858291224194353f9c9a5f0495a96ddde32 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 8 Jan 2022 13:38:47 +0530 Subject: [PATCH 55/69] handle exifr parsing fail --- src/components/PhotoSwipe/PhotoSwipe.tsx | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx index 32e733d8a..22d922c75 100644 --- a/src/components/PhotoSwipe/PhotoSwipe.tsx +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -43,6 +43,7 @@ import * as Yup from 'yup'; import EnteSpinner from 'components/EnteSpinner'; import EnteDateTimePicker from 'components/EnteDateTimePicker'; import { MAX_EDITED_FILE_NAME_LENGTH } from 'constants/file'; +import { sleep } from 'utils/common'; const SmallLoadingSpinner = () => ( { + const checkExifAvailable = async () => { setExif(null); - setTimeout(() => { + await sleep(100); + try { const img: HTMLImageElement = document.querySelector( '.pswp__img:not(.pswp__img--placeholder)' ); if (img) { - exifr.parse(img).then(function (exifData) { - if (!exifData) { - return; - } - exifData.raw = prettyPrintExif(exifData); - setExif(exifData); - }); + const exifData = await exifr.parse(img); + if (!exifData) { + return; + } + exifData.raw = prettyPrintExif(exifData); + setExif(exifData); } - }, 100); + } catch (e) { + logError(e, 'exifr parsing failed'); + } }; function updateInfo() { From d42af9cd1a35efc74b0625e43f67431e69aa149b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sun, 9 Jan 2022 11:05:50 +0530 Subject: [PATCH 56/69] pass reader correctly instead of passing workers --- src/services/migrateThumbnailService.ts | 2 +- src/services/updateCreationTimeWithExif.ts | 5 ++--- src/services/upload/readFileService.ts | 19 ++++--------------- src/services/upload/uploadService.ts | 2 +- src/utils/file/index.ts | 3 ++- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/services/migrateThumbnailService.ts b/src/services/migrateThumbnailService.ts index dfea14fba..a5c693e97 100644 --- a/src/services/migrateThumbnailService.ts +++ b/src/services/migrateThumbnailService.ts @@ -77,7 +77,7 @@ export async function replaceThumbnail( [originalThumbnail], file.metadata.title ); - const fileTypeInfo = await getFileType(worker, dummyImageFile); + const fileTypeInfo = await getFileType(reader, dummyImageFile); const { thumbnail: newThumbnail } = await generateThumbnail( worker, reader, diff --git a/src/services/updateCreationTimeWithExif.ts b/src/services/updateCreationTimeWithExif.ts index edc58327d..e34f889c0 100644 --- a/src/services/updateCreationTimeWithExif.ts +++ b/src/services/updateCreationTimeWithExif.ts @@ -1,6 +1,5 @@ import { FIX_OPTIONS } from 'components/FixCreationTime'; import { SetProgressTracker } from 'components/FixLargeThumbnail'; -import CryptoWorker from 'utils/crypto'; import { changeFileCreationTime, getFileFromURL, @@ -38,8 +37,8 @@ export async function updateCreationTimeWithExif( } else { const fileURL = await downloadManager.getFile(file); const fileObject = await getFileFromURL(fileURL); - const worker = await new CryptoWorker(); - const fileTypeInfo = await getFileType(worker, fileObject); + const reader = new FileReader(); + const fileTypeInfo = await getFileType(reader, fileObject); const exifData = await getRawExif(fileObject, fileTypeInfo); if (fixOption === FIX_OPTIONS.DATE_TIME_ORIGINAL) { correctCreationTime = getUNIXTime( diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 08ef8dd2e..65bf83b9e 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -15,9 +15,9 @@ const TYPE_IMAGE = 'image'; const EDITED_FILE_SUFFIX = '-edited'; const CHUNK_SIZE_FOR_TYPE_DETECTION = 4100; -export async function getFileData(worker, reader: FileReader, file: File) { +export async function getFileData(reader: FileReader, file: File) { if (file.size > MULTIPART_PART_SIZE) { - return getFileStream(worker, reader, file, FILE_READER_CHUNK_SIZE); + return getFileStream(reader, file, FILE_READER_CHUNK_SIZE); } else { return await getUint8ArrayView(reader, file); } @@ -91,18 +91,8 @@ export async function getMimeTypeFromBlob(reader: FileReader, fileBlob: Blob) { } } -function getFileStream( - worker, - reader: FileReader, - file: File, - chunkSize: number -) { - const fileChunkReader = fileChunkReaderMaker( - worker, - reader, - file, - chunkSize - ); +function getFileStream(reader: FileReader, file: File, chunkSize: number) { + const fileChunkReader = fileChunkReaderMaker(reader, file, chunkSize); const stream = new ReadableStream({ async pull(controller: ReadableStreamDefaultController) { @@ -122,7 +112,6 @@ function getFileStream( } async function* fileChunkReaderMaker( - worker, reader: FileReader, file: File, chunkSize: number diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 87a7ee8eb..6f33b06dd 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -49,7 +49,7 @@ class UploadService { fileTypeInfo ); - const filedata = await getFileData(worker, reader, rawFile); + const filedata = await getFileData(reader, rawFile); return { filedata, diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index 2eab2361b..929c319ea 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -296,9 +296,10 @@ export async function convertForPreview(file: EnteFile, fileBlob: Blob) { const typeFromExtension = getFileExtension(file.metadata.title); const worker = await new CryptoWorker(); + const reader = new FileReader(); const mimeType = - (await getMimeTypeFromBlob(worker, fileBlob)) ?? typeFromExtension; + (await getMimeTypeFromBlob(reader, fileBlob)) ?? typeFromExtension; if (isFileHEIC(mimeType)) { fileBlob = await worker.convertHEIC2JPEG(fileBlob); } From 48eac037ea0bc653d08bcf5a844837119f1d5e26 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sun, 9 Jan 2022 12:25:40 +0530 Subject: [PATCH 57/69] fix getFileOriginalName logic --- src/services/upload/readFileService.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index 710621c76..283d0069c 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -7,7 +7,7 @@ import { } from 'constants/upload'; import FileType from 'file-type/browser'; import { CustomError } from 'utils/error'; -import { getFileExtension } from 'utils/file'; +import { getFileExtension, splitFilenameAndExtension } from 'utils/file'; import { FileTypeInfo } from 'types/upload'; const TYPE_VIDEO = 'video'; @@ -66,13 +66,22 @@ export async function getFileType( */ export function getFileOriginalName(file: File) { let originalName: string = null; + const [nameWithoutExtension, extension] = splitFilenameAndExtension( + file.name + ); - const isEditedFile = file.name.endsWith(EDITED_FILE_SUFFIX); + const isEditedFile = nameWithoutExtension.endsWith(EDITED_FILE_SUFFIX); if (isEditedFile) { - originalName = file.name.slice(0, -1 * EDITED_FILE_SUFFIX.length); + originalName = nameWithoutExtension.slice( + 0, + -1 * EDITED_FILE_SUFFIX.length + ); } else { originalName = file.name; } + if (extension) { + originalName += '.' + extension; + } return originalName; } From 1aec53311d2c20350148d3a8403715315ffef91b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sun, 9 Jan 2022 13:50:52 +0530 Subject: [PATCH 58/69] rename sentry is environement variable to make it accessible in browser --- sentryConfigUtil.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sentryConfigUtil.js b/sentryConfigUtil.js index d8f5da7a3..1b19f2f6b 100644 --- a/sentryConfigUtil.js +++ b/sentryConfigUtil.js @@ -1,6 +1,6 @@ -module.exports.isSentryEnabled = () => { - if (process.env.SENTRY_ENABLED) { - return process.env.SENTRY_ENABLED === 'yes'; +module.exports.getIsSentryEnabled = () => { + if (process.env.NEXT_PUBLIC_IS_SENTRY_ENABLED) { + return process.env.NEXT_PUBLIC_IS_SENTRY_ENABLED === 'yes'; } else { if (process.env.NEXT_PUBLIC_SENTRY_ENV) { return process.env.NEXT_PUBLIC_SENTRY_ENV !== 'development'; From 4cdc93e3453c02dcf872566e34762d3e2967146b Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sun, 9 Jan 2022 13:51:47 +0530 Subject: [PATCH 59/69] renamed sentry constants to follow the global convention --- configUtil.js | 4 ++-- next.config.js | 9 ++++++--- sentry.client.config.js | 6 +++--- sentry.server.config.js | 6 +++--- src/constants/sentry/index.ts | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/configUtil.js b/configUtil.js index e0941ea61..438114a99 100644 --- a/configUtil.js +++ b/configUtil.js @@ -1,5 +1,5 @@ const cp = require('child_process'); -const { isSentryEnabled } = require('./sentryConfigUtil'); +const { getIsSentryEnabled } = require('./sentryConfigUtil'); module.exports = { COOP_COEP_HEADERS: { @@ -51,5 +51,5 @@ module.exports = { cwd: __dirname, encoding: 'utf8', }), - isSentryEnabled: isSentryEnabled, + getIsSentryEnabled: getIsSentryEnabled, }; diff --git a/next.config.js b/next.config.js index ee9744388..1413dd1a9 100644 --- a/next.config.js +++ b/next.config.js @@ -14,12 +14,12 @@ const { CSP_DIRECTIVES, WORKBOX_CONFIG, ALL_ROUTES, - isSentryEnabled, + getIsSentryEnabled, } = require('./configUtil'); const GIT_SHA = getGitSha(); -const SENTRY_ENABLED = isSentryEnabled(); +const IS_SENTRY_ENABLED = getIsSentryEnabled(); module.exports = withSentryConfig( withWorkbox( @@ -51,5 +51,8 @@ module.exports = withSentryConfig( }, }) ), - { release: GIT_SHA, dryRun: !SENTRY_ENABLED } + { + release: GIT_SHA, + dryRun: !IS_SENTRY_ENABLED, + } ); diff --git a/sentry.client.config.js b/sentry.client.config.js index 4b39522c0..09e2fe20d 100644 --- a/sentry.client.config.js +++ b/sentry.client.config.js @@ -5,18 +5,18 @@ import { getSentryDSN, getSentryENV, getSentryRelease, - isSentryEnabled, + getIsSentryEnabled, } from 'constants/sentry'; const SENTRY_DSN = getSentryDSN(); const SENTRY_ENV = getSentryENV(); const SENTRY_RELEASE = getSentryRelease(); -const ENABLED = isSentryEnabled(); +const IS_ENABLED = getIsSentryEnabled(); Sentry.setUser({ id: getUserAnonymizedID() }); Sentry.init({ dsn: SENTRY_DSN, - enabled: ENABLED, + enabled: IS_ENABLED, environment: SENTRY_ENV, release: SENTRY_RELEASE, attachStacktrace: true, diff --git a/sentry.server.config.js b/sentry.server.config.js index 62b0029c0..5d8714c99 100644 --- a/sentry.server.config.js +++ b/sentry.server.config.js @@ -3,17 +3,17 @@ import { getSentryDSN, getSentryENV, getSentryRelease, - isSentryEnabled, + getIsSentryEnabled, } from 'constants/sentry'; const SENTRY_DSN = getSentryDSN(); const SENTRY_ENV = getSentryENV(); const SENTRY_RELEASE = getSentryRelease(); -const ENABLED = isSentryEnabled(); +const IS_ENABLED = getIsSentryEnabled(); Sentry.init({ dsn: SENTRY_DSN, - enabled: ENABLED, + enabled: IS_ENABLED, environment: SENTRY_ENV, release: SENTRY_RELEASE, autoSessionTracking: false, diff --git a/src/constants/sentry/index.ts b/src/constants/sentry/index.ts index 79aec9795..5ccfcebe1 100644 --- a/src/constants/sentry/index.ts +++ b/src/constants/sentry/index.ts @@ -7,4 +7,4 @@ export const getSentryENV = () => export const getSentryRelease = () => process.env.SENTRY_RELEASE; -export { isSentryEnabled } from '../../../sentryConfigUtil'; +export { getIsSentryEnabled } from '../../../sentryConfigUtil'; From 4b14427f360020f46bce0e401151bd5cf81bbc58 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sun, 9 Jan 2022 13:52:57 +0530 Subject: [PATCH 60/69] disable sentry if next phase is PHASE_DEVELOPMENT_SERVER --- next.config.js | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/next.config.js b/next.config.js index 1413dd1a9..056b654ad 100644 --- a/next.config.js +++ b/next.config.js @@ -4,6 +4,7 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({ const withWorkbox = require('@ente-io/next-with-workbox'); const { withSentryConfig } = require('@sentry/nextjs'); +const { PHASE_DEVELOPMENT_SERVER } = require('next/constants'); const { getGitSha, @@ -21,38 +22,39 @@ const GIT_SHA = getGitSha(); const IS_SENTRY_ENABLED = getIsSentryEnabled(); -module.exports = withSentryConfig( - withWorkbox( - withBundleAnalyzer({ - env: { - SENTRY_RELEASE: GIT_SHA, - }, - workbox: WORKBOX_CONFIG, +module.exports = (phase) => + withSentryConfig( + withWorkbox( + withBundleAnalyzer({ + env: { + SENTRY_RELEASE: GIT_SHA, + }, + workbox: WORKBOX_CONFIG, - headers() { - return [ - { - // Apply these headers to all routes in your application.... - source: ALL_ROUTES, - headers: convertToNextHeaderFormat({ - ...COOP_COEP_HEADERS, - ...WEB_SECURITY_HEADERS, - ...buildCSPHeader(CSP_DIRECTIVES), - }), - }, - ]; - }, - // https://dev.to/marcinwosinek/how-to-add-resolve-fallback-to-webpack-5-in-nextjs-10-i6j - webpack: (config, { isServer }) => { - if (!isServer) { - config.resolve.fallback.fs = false; - } - return config; - }, - }) - ), - { - release: GIT_SHA, - dryRun: !IS_SENTRY_ENABLED, - } -); + headers() { + return [ + { + // Apply these headers to all routes in your application.... + source: ALL_ROUTES, + headers: convertToNextHeaderFormat({ + ...COOP_COEP_HEADERS, + ...WEB_SECURITY_HEADERS, + ...buildCSPHeader(CSP_DIRECTIVES), + }), + }, + ]; + }, + // https://dev.to/marcinwosinek/how-to-add-resolve-fallback-to-webpack-5-in-nextjs-10-i6j + webpack: (config, { isServer }) => { + if (!isServer) { + config.resolve.fallback.fs = false; + } + return config; + }, + }) + ), + { + release: GIT_SHA, + dryRun: phase === PHASE_DEVELOPMENT_SERVER || !IS_SENTRY_ENABLED, + } + ); From 25d543aaa044e9642bb556429315d4e71881a208 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:42:48 +0530 Subject: [PATCH 61/69] Create SECURITY.md --- SECURITY.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..1642c8307 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,44 @@ +ente believes that working with security researchers across the globe is crucial to keeping our +users safe. If you believe you've found a security issue in our product or service, we encourage you to +notify us (security@ente.io). We welcome working with you to resolve the issue promptly. Thanks in advance! + +# Disclosure Policy + +- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every + effort to quickly resolve the issue. +- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a + third-party. We may publicly disclose the issue before resolving it, if appropriate. +- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or + degradation of our service. Only interact with accounts you own or with explicit permission of the + account holder. +- If you would like to encrypt your report, please use the PGP key with long ID + `E273695C0403F34F74171932DF6DDDE98EBD2394` (available in the public keyserver pool). + +# In-scope + +- Security issues in any current release of ente. This includes the web app, desktop app, + and mobile apps (iOS and Android). Product downloads are available at https://ente.io. Source + code is available at https://github.com/ente-io. + +# Exclusions + +The following bug classes are out-of scope: + +- Bugs that are already reported on any of ente's issue trackers (https://github.com/ente-io), + or that we already know of. Note that some of our issue tracking is private. +- Issues in an upstream software dependency (ex: Flutter, Next.js etc) which are already reported to the upstream maintainer. +- Attacks requiring physical access to a user's device. +- Self-XSS +- Issues related to software or protocols not under ente's control +- Vulnerabilities in outdated versions of ente +- Missing security best practices that do not directly lead to a vulnerability +- Issues that do not have any impact on the general public + +While researching, we'd like to ask you to refrain from: + +- Denial of service +- Spamming +- Social engineering (including phishing) of ente staff or contractors +- Any physical attempts against ente property or data centers + +Thank you for helping keep ente and our users safe! From bed6a086a6e84941b8f3e4738c01ea9ea9ac798d Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 12 Jan 2022 14:42:46 +0530 Subject: [PATCH 62/69] use suggested if available during first upload --- src/components/pages/gallery/CollectionSelector.tsx | 2 +- src/components/pages/gallery/Upload.tsx | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index 82bb62ecc..ad39e3782 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -50,7 +50,7 @@ function CollectionSelector({ CollectionAndItsLatestFile[] >([]); useEffect(() => { - if (!attributes) { + if (!attributes || !props.show) { return; } const user: User = getData(LS_KEYS.USER); diff --git a/src/components/pages/gallery/Upload.tsx b/src/components/pages/gallery/Upload.tsx index ac0379797..11a2e41ee 100644 --- a/src/components/pages/gallery/Upload.tsx +++ b/src/components/pages/gallery/Upload.tsx @@ -141,7 +141,7 @@ export default function Upload(props: Props) { } } return { - suggestedCollectionName: commonPathPrefix, + suggestedCollectionName: commonPathPrefix || null, multipleFolders: firstFileFolder !== lastFileFolder, }; } @@ -279,14 +279,14 @@ export default function Upload(props: Props) { collectionName ); } else { - showCollectionCreateModal(analysisResult); + showCollectionCreateModal(); } }; - const showCollectionCreateModal = (analysisResult: AnalysisResult) => { + const showCollectionCreateModal = () => { props.setCollectionNamerAttributes({ title: constants.CREATE_COLLECTION, buttonText: constants.CREATE, - autoFilledName: analysisResult?.suggestedCollectionName, + autoFilledName: null, callback: uploadToSingleNewCollection, }); }; @@ -296,7 +296,10 @@ export default function Upload(props: Props) { isFirstUpload: boolean ) => { if (isFirstUpload) { - uploadToSingleNewCollection(FIRST_ALBUM_NAME); + const collectionName = + analysisResult.suggestedCollectionName ?? FIRST_ALBUM_NAME; + + uploadToSingleNewCollection(collectionName); } else { let showNextModal = () => {}; if (analysisResult.multipleFolders) { From f37cac0a39befac6e3ce37b2ab0ba4bf54b593bb Mon Sep 17 00:00:00 2001 From: Abhinav Date: Sat, 8 Jan 2022 10:02:53 +0530 Subject: [PATCH 63/69] fix casing of ParsedMetadataJSON --- src/services/upload/metadataService.ts | 22 +++++++++++----------- src/services/upload/uploadManager.ts | 14 +++++++------- src/services/upload/uploadService.ts | 4 ++-- src/types/upload/index.ts | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/services/upload/metadataService.ts b/src/services/upload/metadataService.ts index fcc044dc1..cc5a6909f 100644 --- a/src/services/upload/metadataService.ts +++ b/src/services/upload/metadataService.ts @@ -3,18 +3,18 @@ import { logError } from 'utils/sentry'; import { getExifData } from './exifService'; import { Metadata, - ParsedMetaDataJSON, + ParsedMetadataJSON, Location, FileTypeInfo, } from 'types/upload'; import { NULL_LOCATION } from 'constants/upload'; -interface ParsedMetaDataJSONWithTitle { +interface ParsedMetadataJSONWithTitle { title: string; - parsedMetaDataJSON: ParsedMetaDataJSON; + parsedMetadataJSON: ParsedMetadataJSON; } -const NULL_PARSED_METADATA_JSON: ParsedMetaDataJSON = { +const NULL_PARSED_METADATA_JSON: ParsedMetadataJSON = { creationTime: null, modificationTime: null, ...NULL_LOCATION, @@ -62,7 +62,7 @@ export async function parseMetadataJSON( reader.readAsText(receivedFile); }); - const parsedMetaDataJSON: ParsedMetaDataJSON = + const parsedMetadataJSON: ParsedMetadataJSON = NULL_PARSED_METADATA_JSON; if (!metadataJSON || !metadataJSON['title']) { return; @@ -73,20 +73,20 @@ export async function parseMetadataJSON( metadataJSON['photoTakenTime'] && metadataJSON['photoTakenTime']['timestamp'] ) { - parsedMetaDataJSON.creationTime = + parsedMetadataJSON.creationTime = metadataJSON['photoTakenTime']['timestamp'] * 1000000; } else if ( metadataJSON['creationTime'] && metadataJSON['creationTime']['timestamp'] ) { - parsedMetaDataJSON.creationTime = + parsedMetadataJSON.creationTime = metadataJSON['creationTime']['timestamp'] * 1000000; } if ( metadataJSON['modificationTime'] && metadataJSON['modificationTime']['timestamp'] ) { - parsedMetaDataJSON.modificationTime = + parsedMetadataJSON.modificationTime = metadataJSON['modificationTime']['timestamp'] * 1000000; } let locationData: Location = NULL_LOCATION; @@ -104,10 +104,10 @@ export async function parseMetadataJSON( locationData = metadataJSON['geoDataExif']; } if (locationData !== null) { - parsedMetaDataJSON.latitude = locationData.latitude; - parsedMetaDataJSON.longitude = locationData.longitude; + parsedMetadataJSON.latitude = locationData.latitude; + parsedMetadataJSON.longitude = locationData.longitude; } - return { title, parsedMetaDataJSON } as ParsedMetaDataJSONWithTitle; + return { title, parsedMetadataJSON } as ParsedMetadataJSONWithTitle; } catch (e) { logError(e, 'parseMetadataJSON failed'); // ignore diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index 4c8aad969..1da78b92a 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -19,7 +19,7 @@ import { EnteFile } from 'types/file'; import { FileWithCollection, MetadataMap, - ParsedMetaDataJSON, + ParsedMetadataJSON, ProgressUpdater, } from 'types/upload'; import { UPLOAD_STAGES, FileUploadResults } from 'constants/upload'; @@ -44,7 +44,7 @@ class UploadManager { private async init(newCollections?: Collection[]) { this.filesToBeUploaded = []; this.failedFiles = []; - this.metadataMap = new Map(); + this.metadataMap = new Map(); this.existingFiles = await getLocalFiles(); this.existingFilesCollectionWise = sortFilesIntoCollections( this.existingFiles @@ -94,19 +94,19 @@ class UploadManager { UIService.reset(metadataFiles.length); const reader = new FileReader(); for (const fileWithCollection of metadataFiles) { - const parsedMetaDataJSONWithTitle = await parseMetadataJSON( + const parsedMetadataJSONWithTitle = await parseMetadataJSON( reader, fileWithCollection.file ); - if (parsedMetaDataJSONWithTitle) { - const { title, parsedMetaDataJSON } = - parsedMetaDataJSONWithTitle; + if (parsedMetadataJSONWithTitle) { + const { title, parsedMetadataJSON } = + parsedMetadataJSONWithTitle; this.metadataMap.set( getMetadataMapKey( fileWithCollection.collectionID, title ), - { ...parsedMetaDataJSON } + { ...parsedMetadataJSON } ); UIService.increaseFileUploaded(); } diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index 70b88ed4f..a624d3c93 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -19,7 +19,7 @@ import { isDataStream, MetadataMap, Metadata, - ParsedMetaDataJSON, + ParsedMetadataJSON, ProcessedFile, UploadFile, UploadURL, @@ -27,7 +27,7 @@ import { class UploadService { private uploadURLs: UploadURL[] = []; - private metadataMap: Map; + private metadataMap: Map; private pendingUploadCount: number = 0; async init(fileCount: number, metadataMap: MetadataMap) { diff --git a/src/types/upload/index.ts b/src/types/upload/index.ts index 968209c51..6e58177bc 100644 --- a/src/types/upload/index.ts +++ b/src/types/upload/index.ts @@ -32,7 +32,7 @@ export interface Location { longitude: number; } -export interface ParsedMetaDataJSON { +export interface ParsedMetadataJSON { creationTime: number; modificationTime: number; latitude: number; @@ -69,7 +69,7 @@ export interface FileWithCollection { collection?: Collection; } -export type MetadataMap = Map; +export type MetadataMap = Map; export interface UploadURL { url: string; From 000f1546fe25085c9f5e947996479c8db88b78fb Mon Sep 17 00:00:00 2001 From: Abhinav Date: Wed, 12 Jan 2022 12:50:03 +0530 Subject: [PATCH 64/69] fix getFileOriginalName if name doesn't have edited suffix --- src/services/upload/readFileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/upload/readFileService.ts b/src/services/upload/readFileService.ts index d4e89ad13..b40ccfe38 100644 --- a/src/services/upload/readFileService.ts +++ b/src/services/upload/readFileService.ts @@ -77,7 +77,7 @@ export function getFileOriginalName(file: File) { -1 * EDITED_FILE_SUFFIX.length ); } else { - originalName = file.name; + originalName = nameWithoutExtension; } if (extension) { originalName += '.' + extension; From 41a23dbc0b7e7024b3c9b3df243fe673af755134 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 13 Jan 2022 10:39:14 +0530 Subject: [PATCH 65/69] fix search count by updating it when filteredData changes --- src/components/PhotoFrame.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index f1dbfa753..f0dcae127 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -130,7 +130,7 @@ const PhotoFrame = ({ onThumbnailClick(filteredDataIdx)(); } } - }, [search]); + }, [search, filteredData]); const resetFetching = () => { setFetching({}); From 6162c26cdcaf40342797e81f1b4cb8b5200f20e2 Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 13 Jan 2022 11:53:11 +0530 Subject: [PATCH 66/69] v0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f06fcb6f2..d5edcd9a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bada-frame", - "version": "0.4.0", + "version": "0.4.1", "private": true, "scripts": { "dev": "next dev", From 6516246499dce9e70072c89b6442a03873c2011e Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 13 Jan 2022 14:18:00 +0530 Subject: [PATCH 67/69] fixes https://sentry.ente.io/organizations/ente/issues/2338/ adds rangeStart undefined check --- src/components/PhotoFrame.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index f0dcae127..073c00e09 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -310,7 +310,7 @@ const PhotoFrame = ({ }; const handleRangeSelect = (index: number) => () => { - if (rangeStart !== index) { + if (typeof rangeStart !== 'undefined' && rangeStart !== index) { const direction = (index - rangeStart) / Math.abs(index - rangeStart); let checked = true; From 13c362f16c9634c67eb40f104767e21d8dc1e4be Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 13 Jan 2022 14:18:50 +0530 Subject: [PATCH 68/69] fixes unable to select consective item range select --- src/components/PhotoFrame.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index 073c00e09..2532c6aeb 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -314,10 +314,18 @@ const PhotoFrame = ({ const direction = (index - rangeStart) / Math.abs(index - rangeStart); let checked = true; - for (let i = rangeStart; i !== index; i += direction) { + for ( + let i = rangeStart; + (index - i) * direction >= 0; + i += direction + ) { checked = checked && !!selected[filteredData[i].id]; } - for (let i = rangeStart; i !== index; i += direction) { + for ( + let i = rangeStart; + (index - i) * direction > 0; + i += direction + ) { handleSelect(filteredData[i].id)(!checked); } handleSelect(filteredData[index].id, index)(!checked); From 9bbc495a3dd4d594b70f0ae08712ca51d93236be Mon Sep 17 00:00:00 2001 From: Abhinav Date: Thu, 13 Jan 2022 15:22:03 +0530 Subject: [PATCH 69/69] v0.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5edcd9a9..3fe166638 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bada-frame", - "version": "0.4.1", + "version": "0.4.2", "private": true, "scripts": { "dev": "next dev",