diff --git a/src/components/CollectionShare.tsx b/src/components/CollectionShare.tsx index 820bf1394..99e227ef8 100644 --- a/src/components/CollectionShare.tsx +++ b/src/components/CollectionShare.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import constants from 'utils/strings/constants'; import { Formik, FormikHelpers } from 'formik'; import * as Yup from 'yup'; @@ -20,6 +20,8 @@ import { Collection } from 'types/collection'; import { transformShareURLForHost } from 'utils/collection'; import { Row, Value } from './Container'; import { CodeBlock } from './CodeBlock'; +import { ButtonVariant, getVariantColor } from './pages/gallery/LinkButton'; +import { handleSharingErrors } from 'utils/error'; interface Props { show: boolean; @@ -38,6 +40,13 @@ interface ShareeProps { function CollectionShare(props: Props) { const [loading, setLoading] = useState(false); const galleryContext = useContext(GalleryContext); + const [sharableLinkError, setSharableLinkError] = useState(null); + const [publicShareUrl, setPublicShareUrl] = useState(null); + + useEffect( + () => setPublicShareUrl(props.collection?.publicURLs?.[0]?.url || null), + [props.collection] + ); const collectionShare = async ( { email }: formValues, @@ -58,20 +67,7 @@ function CollectionShare(props: Props) { resetForm(); } } catch (e) { - let errorMessage = null; - switch (e?.status) { - case 400: - errorMessage = constants.SHARING_BAD_REQUEST_ERROR; - break; - case 402: - errorMessage = constants.SHARING_DISABLED_FOR_FREE_ACCOUNTS; - break; - case 404: - errorMessage = constants.USER_DOES_NOT_EXIST; - break; - default: - errorMessage = `${constants.UNKNOWN_ERROR} ${e.message}`; - } + const errorMessage = handleSharingErrors(e); setFieldError('email', errorMessage); } finally { setLoading(false); @@ -83,14 +79,31 @@ function CollectionShare(props: Props) { }; const createSharableURLHelper = async () => { - const publicURL = await createShareableURL(props.collection); - props.collection.publicURLs = [publicURL]; - await props.syncWithRemote(); + try { + galleryContext.startLoading(); + const publicURL = await createShareableURL(props.collection); + galleryContext.finishLoading(); + setPublicShareUrl(publicURL.url); + await galleryContext.syncWithRemote(false, true); + } catch (e) { + const errorMessage = handleSharingErrors(e); + setSharableLinkError(errorMessage); + } finally { + galleryContext.finishLoading(); + } }; const deleteSharableURLHelper = async () => { - await deleteShareableURL(props.collection); - await props.syncWithRemote(); + try { + await deleteShareableURL(props.collection); + setPublicShareUrl(null); + await galleryContext.syncWithRemote(false, true); + } catch (e) { + const errorMessage = handleSharingErrors(e); + setSharableLinkError(errorMessage); + } finally { + galleryContext.finishLoading(); + } }; const deleteSharableLink = () => { @@ -107,7 +120,8 @@ function CollectionShare(props: Props) { }; const handleCollectionPublicSharing = () => { - if (props.collection.publicURLs?.length > 0) { + setSharableLinkError(null); + if (publicShareUrl) { deleteSharableLink(); } else { createSharableURLHelper(); @@ -206,12 +220,19 @@ function CollectionShare(props: Props) { 0} + checked={!!publicShareUrl} id="collection-public-sharing-toggler" className="custom-switch-md" onChange={handleCollectionPublicSharing} /> + + {sharableLinkError} +
- {props.collection.publicURLs?.length > 0 && ( + {publicShareUrl && (
<>{constants.PUBLIC_URL} null, syncWithRemote: () => null, setDialogMessage: () => null, + startLoading: () => null, + finishLoading: () => null, }; export const GalleryContext = createContext( @@ -546,6 +548,8 @@ export default function Gallery() { setActiveCollection, syncWithRemote, setDialogMessage, + startLoading, + finishLoading, }}> void; syncWithRemote: (force?: boolean, silent?: boolean) => Promise; setDialogMessage: SetDialogMessage; + startLoading: () => void; + finishLoading: () => void; }; diff --git a/src/utils/error/index.ts b/src/utils/error/index.ts index 9d27c0252..5df22ec1c 100644 --- a/src/utils/error/index.ts +++ b/src/utils/error/index.ts @@ -51,17 +51,13 @@ function parseUploadError(error: AxiosResponse) { case ServerErrorCodes.FILE_TOO_LARGE: parsedMessage = CustomError.FILE_TOO_LARGE; break; + default: + parsedMessage = `${constants.UNKNOWN_ERROR} statusCode:${errorCode}`; } } - if (parsedMessage) { - return { - parsedError: new Error(parsedMessage), - }; - } else { - return { - parsedError: new Error(CustomError.UNKNOWN_ERROR), - }; - } + return { + parsedError: new Error(parsedMessage), + }; } export function handleUploadError(error: AxiosResponse | Error): Error { @@ -105,3 +101,25 @@ export function errorWithContext(originalError: Error, context: string) { originalError.stack; return errorWithContext; } + +export const handleSharingErrors = (e) => { + let errorMessage = null; + if ('status' in e) { + switch (e?.status) { + case 400: + errorMessage = constants.SHARING_BAD_REQUEST_ERROR; + break; + case 402: + errorMessage = constants.SHARING_DISABLED_FOR_FREE_ACCOUNTS; + break; + case 404: + errorMessage = constants.USER_DOES_NOT_EXIST; + break; + default: + errorMessage = `${constants.UNKNOWN_ERROR} statusCode:${e.status}`; + } + } else { + errorMessage = e.message; + } + return errorMessage; +};