diff --git a/configUtil.js b/configUtil.js index 438114a99..47c36a1ad 100644 --- a/configUtil.js +++ b/configUtil.js @@ -26,8 +26,6 @@ module.exports = { '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: { diff --git a/sentry.client.config.js b/sentry.client.config.js index 09e2fe20d..8d85c07d9 100644 --- a/sentry.client.config.js +++ b/sentry.client.config.js @@ -1,5 +1,5 @@ import * as Sentry from '@sentry/nextjs'; -import { getSentryTunnelUrl } from 'utils/common/apiUtil'; +import { getSentryTunnelURL } from 'utils/common/apiUtil'; import { getUserAnonymizedID } from 'utils/user'; import { getSentryDSN, @@ -21,7 +21,7 @@ Sentry.init({ release: SENTRY_RELEASE, attachStacktrace: true, autoSessionTracking: false, - tunnel: getSentryTunnelUrl(), + tunnel: getSentryTunnelURL(), // ... // Note: if you want to override the automatic release value, do not set a // `release` value here - use the environment variable `SENTRY_RELEASE`, so diff --git a/src/components/PhotoFrame.tsx b/src/components/PhotoFrame.tsx index 2532c6aeb..712dd5810 100644 --- a/src/components/PhotoFrame.tsx +++ b/src/components/PhotoFrame.tsx @@ -209,7 +209,7 @@ const PhotoFrame = ({ }); }, [files, deleted, search, activeCollection]); - const updateUrl = (index: number) => (url: string) => { + const updateURL = (index: number) => (url: string) => { files[index] = { ...files[index], msrc: url, @@ -240,7 +240,7 @@ const PhotoFrame = ({ setFiles(files); }; - const updateSrcUrl = async (index: number, url: string) => { + const updateSrcURL = async (index: number, url: string) => { files[index] = { ...files[index], w: window.innerWidth, @@ -337,7 +337,7 @@ const PhotoFrame = ({ selected[file[index].id] ?? false }`} file={file[index]} - updateUrl={updateUrl(file[index].dataIndex)} + updateURL={updateURL(file[index].dataIndex)} onClick={onThumbnailClick(index)} selectable={!isSharedCollection} onSelect={handleSelect(file[index].id, index)} @@ -370,7 +370,7 @@ const PhotoFrame = ({ url = await DownloadManager.getThumbnail(item); galleryContext.thumbs.set(item.id, url); } - updateUrl(item.dataIndex)(url); + updateURL(item.dataIndex)(url); item.msrc = url; if (!item.src) { item.src = url; @@ -397,7 +397,7 @@ const PhotoFrame = ({ url = await DownloadManager.getFile(item, true); galleryContext.files.set(item.id, url); } - await updateSrcUrl(item.dataIndex, url); + await updateSrcURL(item.dataIndex, url); item.html = files[item.dataIndex].html; item.src = files[item.dataIndex].src; item.w = files[item.dataIndex].w; diff --git a/src/components/PhotoSwipe/PhotoSwipe.tsx b/src/components/PhotoSwipe/PhotoSwipe.tsx index 22d922c75..2cf0e0701 100644 --- a/src/components/PhotoSwipe/PhotoSwipe.tsx +++ b/src/components/PhotoSwipe/PhotoSwipe.tsx @@ -91,9 +91,11 @@ const renderInfoItem = (label: string, value: string | JSX.Element) => ( ); function RenderCreationTime({ + shouldDisableEdits, file, scheduleUpdate, }: { + shouldDisableEdits: boolean; file: EnteFile; scheduleUpdate: () => void; }) { @@ -160,24 +162,25 @@ function RenderCreationTime({ - {!isInEditMode ? ( - - - - ) : ( - <> - - {loading ? ( - - ) : ( - - )} + {!shouldDisableEdits && + (!isInEditMode ? ( + + - - - - - )} + ) : ( + <> + + {loading ? ( + + ) : ( + + )} + + + + + + ))} @@ -275,9 +278,11 @@ const FileNameEditForm = ({ filename, saveEdits, discardEdits, extension }) => { }; function RenderFileName({ + shouldDisableEdits, file, scheduleUpdate, }: { + shouldDisableEdits: boolean; file: EnteFile; scheduleUpdate: () => void; }) { @@ -322,13 +327,18 @@ function RenderFileName({ {getFileTitle(filename, extension)} - - - - - + {!shouldDisableEdits && ( + + + + + + )} ) : ( )} {metadata?.creationTime && ( @@ -744,6 +757,7 @@ function PhotoSwipe(props: Iprops) { { - const recoveryKey = await getRecoveryKey(); - if (!recoveryKey) { + try { + const recoveryKey = await getRecoveryKey(); + setRecoveryKey(bip39.entropyToMnemonic(recoveryKey)); + } catch (e) { somethingWentWrong(); props.onHide(); } - setRecoveryKey(bip39.entropyToMnemonic(recoveryKey)); }; main(); }, [props.show]); diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 29ae3390f..03da1a9c9 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -238,7 +238,9 @@ export default function Sidebar(props: Props) { onHide={() => setRecoveryModalView(false)} somethingWentWrong={() => props.setDialogMessage({ - title: constants.RECOVER_KEY_GENERATION_FAILED, + title: constants.ERROR, + content: + constants.RECOVER_KEY_GENERATION_FAILED, close: { variant: 'danger' }, }) } diff --git a/src/components/pages/gallery/CollectionSelector.tsx b/src/components/pages/gallery/CollectionSelector.tsx index ad39e3782..7a72a1266 100644 --- a/src/components/pages/gallery/CollectionSelector.tsx +++ b/src/components/pages/gallery/CollectionSelector.tsx @@ -82,7 +82,7 @@ function CollectionSelector({ {}} + updateURL={() => {}} onSelect={() => {}} forcedEnable /> diff --git a/src/components/pages/gallery/PlanSelector.tsx b/src/components/pages/gallery/PlanSelector.tsx index 3e2b0f0fe..15533acfb 100644 --- a/src/components/pages/gallery/PlanSelector.tsx +++ b/src/components/pages/gallery/PlanSelector.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Form, Modal, Button } from 'react-bootstrap'; import constants from 'utils/strings/constants'; import styled, { css } from 'styled-components'; @@ -21,9 +21,10 @@ import { reverseString } from 'utils/common'; import { SetDialogMessage } from 'components/MessageDialog'; import ArrowEast from 'components/icons/ArrowEast'; import LinkButton from './LinkButton'; -import { DeadCenter } from 'pages/gallery'; +import { DeadCenter, GalleryContext } from 'pages/gallery'; import billingService from 'services/billingService'; import { SetLoading } from 'types/gallery'; +import { logError } from 'utils/sentry'; export const PlanIcon = styled.div<{ currentlySubscribed: boolean }>` border-radius: 20px; @@ -86,6 +87,8 @@ function PlanSelector(props: Props) { const subscription: Subscription = getUserSubscription(); const [plans, setPlans] = useState(null); const [planPeriod, setPlanPeriod] = useState(PLAN_PERIOD.YEAR); + const galleryContext = useContext(GalleryContext); + const togglePeriod = () => { setPlanPeriod((prevPeriod) => prevPeriod === PLAN_PERIOD.MONTH @@ -93,9 +96,16 @@ function PlanSelector(props: Props) { : PLAN_PERIOD.MONTH ); }; + function onReopenClick() { + galleryContext.closeMessageDialog(); + galleryContext.showPlanSelectorModal(); + } useEffect(() => { - if (props.modalView) { - const main = async () => { + if (!props.modalView) { + return; + } + const main = async () => { + try { props.setLoading(true); let plans = await billingService.getPlans(); @@ -111,10 +121,24 @@ function PlanSelector(props: Props) { plans = [planForSubscription(subscription), ...plans]; } setPlans(plans); + } catch (e) { + logError(e, 'plan selector modal open failed'); + props.closeModal(); + props.setDialogMessage({ + title: constants.OPEN_PLAN_SELECTOR_MODAL_FAILED, + content: constants.UNKNOWN_ERROR, + close: { text: 'close', variant: 'danger' }, + proceed: { + text: constants.REOPEN_PLAN_SELECTOR_MODAL, + variant: 'success', + action: onReopenClick, + }, + }); + } finally { props.setLoading(false); - }; - main(); - } + } + }; + main(); }, [props.modalView]); async function onPlanSelect(plan: Plan) { diff --git a/src/components/pages/gallery/PreviewCard.tsx b/src/components/pages/gallery/PreviewCard.tsx index 54b09410e..8652d5e2e 100644 --- a/src/components/pages/gallery/PreviewCard.tsx +++ b/src/components/pages/gallery/PreviewCard.tsx @@ -9,7 +9,7 @@ import { GAP_BTW_TILES } from 'constants/gallery'; interface IProps { file: EnteFile; - updateUrl: (url: string) => void; + updateURL: (url: string) => void; onClick?: () => void; forcedEnable?: boolean; selectable?: boolean; @@ -161,7 +161,7 @@ export default function PreviewCard(props: IProps) { const { file, onClick, - updateUrl, + updateURL, forcedEnable, selectable, selected, @@ -185,7 +185,7 @@ export default function PreviewCard(props: IProps) { if (!file.src) { file.src = url; } - updateUrl(url); + updateURL(url); } } catch (e) { // no-op diff --git a/src/components/pages/gallery/UploadProgress.tsx b/src/components/pages/gallery/UploadProgress.tsx index 38052ff16..27c72555c 100644 --- a/src/components/pages/gallery/UploadProgress.tsx +++ b/src/components/pages/gallery/UploadProgress.tsx @@ -129,10 +129,7 @@ const InProgressSection = (props: InProgressProps) => { {fileList.map(({ fileName, progress }) => (
  • - {constants.FILE_UPLOAD_PROGRESS( - fileName, - progress - )} + {`${fileName} - ${progress}%`}
  • ))}
    @@ -235,10 +232,20 @@ export default function UploadProgress(props: Props) { /> + { + appContext.showNavBar(true); + setLoading(false); + }, []); + return ( + + {loading ? ( + Loading... + ) : ( + constants.NOT_FOUND + )} + + ); +} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5d170715b..42323cc61 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -479,8 +479,8 @@ type AppContextType = { sharedFiles: File[]; resetSharedFiles: () => void; setDisappearingFlashMessage: (message: FlashMessage) => void; - redirectUrl: string; - setRedirectUrl: (url: string) => void; + redirectURL: string; + setRedirectURL: (url: string) => void; }; export enum FLASH_MESSAGE_TYPE { @@ -510,7 +510,7 @@ export default function App({ Component, err }) { const [sharedFiles, setSharedFiles] = useState(null); const [redirectName, setRedirectName] = useState(null); const [flashMessage, setFlashMessage] = useState(null); - const [redirectUrl, setRedirectUrl] = useState(null); + const [redirectURL, setRedirectURL] = useState(null); useEffect(() => { if ( !('serviceWorker' in navigator) || @@ -644,8 +644,8 @@ export default function App({ Component, err }) { sharedFiles, resetSharedFiles, setDisappearingFlashMessage, - redirectUrl, - setRedirectUrl, + redirectURL, + setRedirectURL, }}> {loading ? ( diff --git a/src/pages/credentials/index.tsx b/src/pages/credentials/index.tsx index 86d44ce5f..2171b8b81 100644 --- a/src/pages/credentials/index.tsx +++ b/src/pages/credentials/index.tsx @@ -76,9 +76,9 @@ export default function Credentials() { } await SaveKeyInSessionStore(SESSION_KEYS.ENCRYPTION_KEY, key); await decryptAndStoreToken(key); - const redirectUrl = appContext.redirectUrl; - appContext.setRedirectUrl(null); - router.push(redirectUrl ?? PAGES.GALLERY); + const redirectURL = appContext.redirectURL; + appContext.setRedirectURL(null); + router.push(redirectURL ?? PAGES.GALLERY); } catch (e) { logError(e, 'user entered a wrong password'); setFieldError('passphrase', constants.INCORRECT_PASSPHRASE); diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index cfbfdfc1a..0a1bf7292 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -119,6 +119,7 @@ const defaultGalleryContext: GalleryContextType = { thumbs: new Map(), files: new Map(), showPlanSelectorModal: () => null, + closeMessageDialog: () => null, setActiveCollection: () => null, syncWithRemote: () => null, }; @@ -144,7 +145,7 @@ export default function Gallery() { collectionID: 0, }); const [dialogMessage, setDialogMessage] = useState(); - const [dialogView, setDialogView] = useState(false); + const [messageDialogView, setMessageDialogView] = useState(false); const [planModalView, setPlanModalView] = useState(false); const [loading, setLoading] = useState(false); const [collectionSelectorAttributes, setCollectionSelectorAttributes] = @@ -186,10 +187,13 @@ export default function Gallery() { const [fixCreationTimeAttributes, setFixCreationTimeAttributes] = useState(null); + const showPlanSelectorModal = () => setPlanModalView(true); + const closeMessageDialog = () => setMessageDialogView(false); + useEffect(() => { const key = getKey(SESSION_KEYS.ENCRYPTION_KEY); if (!key) { - appContext.setRedirectUrl(router.asPath); + appContext.setRedirectURL(router.asPath); router.push(PAGES.ROOT); return; } @@ -218,7 +222,7 @@ export default function Gallery() { appContext.showNavBar(true); }, []); - useEffect(() => setDialogView(true), [dialogMessage]); + useEffect(() => setMessageDialogView(true), [dialogMessage]); useEffect( () => collectionSelectorAttributes && setCollectionSelectorView(true), @@ -536,7 +540,8 @@ export default function Gallery() { setPlanModalView(true), + showPlanSelectorModal, + closeMessageDialog, setActiveCollection, syncWithRemote, }}> @@ -563,8 +568,8 @@ export default function Gallery() { setDialogView(false)} + show={messageDialogView} + onHide={closeMessageDialog} attributes={dialogMessage} /> >(); - private thumbnailObjectUrlPromise = new Map>(); + private fileObjectURLPromise = new Map>(); + private thumbnailObjectURLPromise = new Map>(); public async getThumbnail(file: EnteFile) { try { @@ -22,10 +22,18 @@ class DownloadManager { if (!token) { return null; } - if (!this.thumbnailObjectUrlPromise.get(file.id)) { + if (!this.thumbnailObjectURLPromise.get(file.id)) { const downloadPromise = async () => { - const thumbnailCache = await caches.open('thumbs'); - const cacheResp: Response = await thumbnailCache.match( + const thumbnailCache = await (async () => { + try { + return await caches.open('thumbs'); + } catch (e) { + return null; + // ignore + } + })(); + + const cacheResp: Response = await thumbnailCache?.match( file.id.toString() ); if (cacheResp) { @@ -34,7 +42,7 @@ class DownloadManager { const thumb = await this.downloadThumb(token, file); const thumbBlob = new Blob([thumb]); try { - await thumbnailCache.put( + await thumbnailCache?.put( file.id.toString(), new Response(thumbBlob) ); @@ -43,12 +51,12 @@ class DownloadManager { } return URL.createObjectURL(thumbBlob); }; - this.thumbnailObjectUrlPromise.set(file.id, downloadPromise()); + this.thumbnailObjectURLPromise.set(file.id, downloadPromise()); } - return await this.thumbnailObjectUrlPromise.get(file.id); + return await this.thumbnailObjectURLPromise.get(file.id); } catch (e) { - this.thumbnailObjectUrlPromise.delete(file.id); + this.thumbnailObjectURLPromise.delete(file.id); logError(e, 'get preview Failed'); throw e; } @@ -56,7 +64,7 @@ class DownloadManager { downloadThumb = async (token: string, file: EnteFile) => { const resp = await HTTPService.get( - getThumbnailUrl(file.id), + getThumbnailURL(file.id), null, { 'X-Auth-Token': token }, { responseType: 'arraybuffer' } @@ -84,23 +92,23 @@ class DownloadManager { } return URL.createObjectURL(fileBlob); }; - if (!this.fileObjectUrlPromise.get(fileKey)) { - this.fileObjectUrlPromise.set( + if (!this.fileObjectURLPromise.get(fileKey)) { + this.fileObjectURLPromise.set( fileKey, getFilePromise(shouldBeConverted) ); } - const fileURL = await this.fileObjectUrlPromise.get(fileKey); + const fileURL = await this.fileObjectURLPromise.get(fileKey); return fileURL; } catch (e) { - this.fileObjectUrlPromise.delete(fileKey); + this.fileObjectURLPromise.delete(fileKey); logError(e, 'Failed to get File'); throw e; } }; public async getCachedOriginalFile(file: EnteFile) { - return await this.fileObjectUrlPromise.get(file.id.toString()); + return await this.fileObjectURLPromise.get(file.id.toString()); } async downloadFile(file: EnteFile) { @@ -114,7 +122,7 @@ class DownloadManager { file.metadata.fileType === FILE_TYPE.LIVE_PHOTO ) { const resp = await HTTPService.get( - getFileUrl(file.id), + getFileURL(file.id), null, { 'X-Auth-Token': token }, { responseType: 'arraybuffer' } @@ -126,7 +134,7 @@ class DownloadManager { ); return generateStreamFromArrayBuffer(decrypted); } - const resp = await fetch(getFileUrl(file.id), { + const resp = await fetch(getFileURL(file.id), { headers: { 'X-Auth-Token': token, }, diff --git a/src/services/trashService.ts b/src/services/trashService.ts index 36ea04756..dc8b09e72 100644 --- a/src/services/trashService.ts +++ b/src/services/trashService.ts @@ -129,6 +129,7 @@ export const updateTrash = async ( } catch (e) { logError(e, 'Get trash files failed'); } + return currentTrash; }; function removeDuplicates(trash: Trash) { diff --git a/src/services/upload/exifService.ts b/src/services/upload/exifService.ts index e463598ed..685994235 100644 --- a/src/services/upload/exifService.ts +++ b/src/services/upload/exifService.ts @@ -85,11 +85,11 @@ export async function updateFileCreationDateInEXIF( export async function convertImageToDataURL(reader: FileReader, url: string) { const blob = await fetch(url).then((r) => r.blob()); - const dataUrl = await new Promise((resolve) => { + const dataURL = await new Promise((resolve) => { reader.onload = () => resolve(reader.result as string); reader.readAsDataURL(blob); }); - return dataUrl; + return dataURL; } function dataURIToBlob(dataURI) { diff --git a/src/services/upload/uiService.ts b/src/services/upload/uiService.ts index 7857bb8b6..2d9f67753 100644 --- a/src/services/upload/uiService.ts +++ b/src/services/upload/uiService.ts @@ -1,4 +1,5 @@ import { + FileUploadResults, RANDOM_PERCENTAGE_PROGRESS_FOR_PUT, UPLOAD_STAGES, } from 'constants/upload'; @@ -9,7 +10,7 @@ class UIService { private filesUploaded: number; private totalFileCount: number; private fileProgress: Map; - private uploadResult: Map; + private uploadResult: Map; private progressUpdater: ProgressUpdater; init(progressUpdater: ProgressUpdater) { @@ -47,8 +48,8 @@ class UIService { this.updateProgressBarUI(); } - moveFileToResultList(filename: string) { - this.uploadResult.set(filename, this.fileProgress.get(filename)); + moveFileToResultList(filename: string, uploadResult: FileUploadResults) { + this.uploadResult.set(filename, uploadResult); this.fileProgress.delete(filename); this.updateProgressBarUI(); } diff --git a/src/services/upload/uploadManager.ts b/src/services/upload/uploadManager.ts index 1da78b92a..f8236482d 100644 --- a/src/services/upload/uploadManager.ts +++ b/src/services/upload/uploadManager.ts @@ -185,7 +185,11 @@ class UploadManager { this.failedFiles.push(fileWithCollection); } - UIService.moveFileToResultList(fileWithCollection.file.name); + UIService.moveFileToResultList( + fileWithCollection.file.name, + fileUploadResult + ); + UploadService.reducePendingUploadCount(); } } diff --git a/src/services/upload/uploadService.ts b/src/services/upload/uploadService.ts index a624d3c93..54b65b46c 100644 --- a/src/services/upload/uploadService.ts +++ b/src/services/upload/uploadService.ts @@ -36,6 +36,10 @@ class UploadService { await this.preFetchUploadURLs(); } + reducePendingUploadCount() { + this.pendingUploadCount--; + } + async readFile( worker: any, reader: FileReader, diff --git a/src/services/upload/uploader.ts b/src/services/upload/uploader.ts index aee78c2b9..879e51abd 100644 --- a/src/services/upload/uploader.ts +++ b/src/services/upload/uploader.ts @@ -1,5 +1,4 @@ import { EnteFile } from 'types/file'; -import { sleep } from 'utils/common'; import { handleUploadError, CustomError } from 'utils/error'; import { decryptFile } from 'utils/file'; import { logError } from 'utils/sentry'; @@ -22,7 +21,6 @@ import { import { FILE_TYPE } from 'constants/file'; import { FileUploadResults } from 'constants/upload'; -const TwoSecondInMillSeconds = 2000; const FIVE_GB_IN_BYTES = 5 * 1024 * 1024 * 1024; interface UploadResponse { fileUploadResult: FileUploadResults; @@ -46,12 +44,6 @@ export default async function uploader( try { if (rawFile.size >= FIVE_GB_IN_BYTES) { - UIService.setFileProgress( - rawFile.name, - FileUploadResults.TOO_LARGE - ); - // wait two second before removing the file from the progress in file section - await sleep(TwoSecondInMillSeconds); return { fileUploadResult: FileUploadResults.TOO_LARGE }; } fileTypeInfo = await getFileType(reader, rawFile); @@ -65,10 +57,7 @@ export default async function uploader( ); if (fileAlreadyInCollection(existingFilesInCollection, metadata)) { - UIService.setFileProgress(rawFile.name, FileUploadResults.SKIPPED); - // wait two second before removing the file from the progress in file section - await sleep(TwoSecondInMillSeconds); - return { fileUploadResult: FileUploadResults.SKIPPED }; + return { fileUploadResult: FileUploadResults.ALREADY_UPLOADED }; } file = await UploadService.readFile( @@ -105,7 +94,6 @@ export default async function uploader( const uploadedFile = await UploadHttpClient.uploadFile(uploadFile); const decryptedFile = await decryptFile(uploadedFile, collection); - UIService.setFileProgress(rawFile.name, FileUploadResults.UPLOADED); UIService.increaseFileUploaded(); return { fileUploadResult: FileUploadResults.UPLOADED, @@ -118,29 +106,15 @@ export default async function uploader( const error = handleUploadError(e); switch (error.message) { case CustomError.ETAG_MISSING: - UIService.setFileProgress( - rawFile.name, - FileUploadResults.BLOCKED - ); return { fileUploadResult: FileUploadResults.BLOCKED }; case CustomError.UNSUPPORTED_FILE_FORMAT: - UIService.setFileProgress( - rawFile.name, - FileUploadResults.UNSUPPORTED - ); return { fileUploadResult: FileUploadResults.UNSUPPORTED }; - case CustomError.FILE_TOO_LARGE: - UIService.setFileProgress( - rawFile.name, - FileUploadResults.TOO_LARGE - ); - return { fileUploadResult: FileUploadResults.TOO_LARGE }; + return { + fileUploadResult: + FileUploadResults.LARGER_THAN_AVAILABLE_STORAGE, + }; default: - UIService.setFileProgress( - rawFile.name, - FileUploadResults.FAILED - ); return { fileUploadResult: FileUploadResults.FAILED }; } } finally { diff --git a/src/services/userService.ts b/src/services/userService.ts index 5cdd08ca1..eeffcf75b 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -72,13 +72,21 @@ export const setRecoveryKey = (token: string, recoveryKey: RecoveryKey) => }); export const logoutUser = async () => { - // ignore server logout result as logoutUser can be triggered before sign up or on token expiry - await _logout(); - clearKeys(); - clearData(); - await caches.delete('thumbs'); - await clearFiles(); - router.push(PAGES.ROOT); + try { + // ignore server logout result as logoutUser can be triggered before sign up or on token expiry + await _logout(); + clearKeys(); + clearData(); + try { + await caches.delete('thumbs'); + } catch (e) { + // ignore + } + await clearFiles(); + router.push(PAGES.ROOT); + } catch (e) { + logError(e, 'logoutUser failed'); + } }; export const clearFiles = async () => { diff --git a/src/types/gallery/index.ts b/src/types/gallery/index.ts index e7c10e3ce..8000e5d58 100644 --- a/src/types/gallery/index.ts +++ b/src/types/gallery/index.ts @@ -26,6 +26,7 @@ export type GalleryContextType = { thumbs: Map; files: Map; showPlanSelectorModal: () => void; + closeMessageDialog: () => void; setActiveCollection: (collection: number) => void; syncWithRemote: (force?: boolean, silent?: boolean) => Promise; }; diff --git a/src/utils/common/apiUtil.ts b/src/utils/common/apiUtil.ts index 8288e6d30..fc59793c0 100644 --- a/src/utils/common/apiUtil.ts +++ b/src/utils/common/apiUtil.ts @@ -4,7 +4,7 @@ export const getEndpoint = () => { return endPoint; }; -export const getFileUrl = (id: number) => { +export const getFileURL = (id: number) => { if (process.env.NEXT_PUBLIC_ENTE_ENDPOINT !== undefined) { return ( `${process.env.NEXT_PUBLIC_ENTE_ENDPOINT}/files/download/${id}` ?? @@ -14,7 +14,7 @@ export const getFileUrl = (id: number) => { return `https://files.ente.io/?fileID=${id}`; }; -export const getThumbnailUrl = (id: number) => { +export const getThumbnailURL = (id: number) => { if (process.env.NEXT_PUBLIC_ENTE_ENDPOINT !== undefined) { return ( `${process.env.NEXT_PUBLIC_ENTE_ENDPOINT}/files/preview/${id}` ?? @@ -24,11 +24,11 @@ export const getThumbnailUrl = (id: number) => { return `https://thumbnails.ente.io/?fileID=${id}`; }; -export const getSentryTunnelUrl = () => { +export const getSentryTunnelURL = () => { return `https://sentry-reporter.ente.io`; }; -export const getPaymentsUrl = () => { +export const getPaymentsURL = () => { if (process.env.NEXT_PUBLIC_ENTE_ENDPOINT !== undefined) { return process.env.NEXT_PUBLIC_ENTE_PAYMENT_ENDPOINT; } diff --git a/src/utils/crypto/index.ts b/src/utils/crypto/index.ts index 9e1e39bd5..3b0604393 100644 --- a/src/utils/crypto/index.ts +++ b/src/utils/crypto/index.ts @@ -106,7 +106,7 @@ export const SaveKeyInSessionStore = async ( }; export const getRecoveryKey = async () => { - let recoveryKey = null; + let recoveryKey: string = null; try { const cryptoWorker = await new CryptoWorker(); @@ -129,6 +129,7 @@ export const getRecoveryKey = async () => { return recoveryKey; } catch (e) { logError(e, 'getRecoveryKey failed'); + throw e; } }; @@ -138,7 +139,7 @@ async function createNewRecoveryKey() { const cryptoWorker = await new CryptoWorker(); - const recoveryKey = await cryptoWorker.generateEncryptionKey(); + const recoveryKey: string = await cryptoWorker.generateEncryptionKey(); const encryptedMasterKey: B64EncryptionResult = await cryptoWorker.encryptToB64(masterKey, recoveryKey); const encryptedRecoveryKey: B64EncryptionResult = diff --git a/src/utils/storage/localForage.ts b/src/utils/storage/localForage.ts index aa27dd08e..b807318a6 100644 --- a/src/utils/storage/localForage.ts +++ b/src/utils/storage/localForage.ts @@ -4,7 +4,6 @@ import localForage from 'localforage'; if (runningInBrowser()) { localForage.config({ - driver: localForage.INDEXEDDB, name: 'ente-files', version: 1.0, storeName: 'files', diff --git a/src/utils/strings/englishConstants.tsx b/src/utils/strings/englishConstants.tsx index 7ada30d45..271c704f9 100644 --- a/src/utils/strings/englishConstants.tsx +++ b/src/utils/strings/englishConstants.tsx @@ -109,26 +109,6 @@ const englishConstants = { }, UPLOADING_FILES: 'file upload', FILE_NOT_UPLOADED_LIST: 'the following files were not uploaded', - FILE_UPLOAD_PROGRESS: (name: string, progress: number) => ( -
    - {name} - {' - '} - - {(() => { - switch (progress) { - case -1: - return 'failed'; - case -2: - return 'already uploaded, skipping...'; - case -3: - return 'unsupported file format, skipping....'; - default: - return `${progress}%`; - } - })()} - -
    - ), SUBSCRIPTION_EXPIRED: (action) => ( <> your subscription has expired, please a{' '} @@ -546,8 +526,11 @@ const englishConstants = { BLOCKED_UPLOADS: 'blocked uploads', INPROGRESS_UPLOADS: 'uploads in progress', TOO_LARGE_UPLOADS: 'large files', - TOO_LARGE_INFO: + LARGER_THAN_AVAILABLE_STORAGE_UPLOADS: 'insufficient storage', + LARGER_THAN_AVAILABLE_STORAGE_INFO: 'these files were not uploaded as they exceed the maximum size limit for your storage plan', + TOO_LARGE_INFO: + 'these files were not uploaded as they exceed our maximum file size limit', UPLOAD_TO_COLLECTION: 'upload to album', ARCHIVE: 'archive', ALL: 'all', @@ -621,6 +604,9 @@ const englishConstants = { DATE_TIME_ORIGINAL: 'EXIF:DateTimeOriginal', DATE_TIME_DIGITIZED: 'EXIF:DateTimeDigitized', CUSTOM_TIME: 'custom time', + REOPEN_PLAN_SELECTOR_MODAL: 're-open plans', + OPEN_PLAN_SELECTOR_MODAL_FAILED: 'failed to open plans', + NOT_FOUND: '404 not found', }; export default englishConstants; diff --git a/yarn.lock b/yarn.lock index fcb0daec0..a19a5143e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4592,9 +4592,9 @@ ms@2.1.2, ms@^2.1.1: integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== nanoid@^3.1.23: - version "3.1.25" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== native-url@0.3.4: version "0.3.4"