Inline
This commit is contained in:
@@ -4,7 +4,7 @@ import { PublicLinkCreated } from "@/new/photos/components/share/PublicLinkCreat
|
||||
import { useEffect, useState } from "react";
|
||||
import { appendCollectionKeyToShareURL } from "utils/collection";
|
||||
import EnablePublicShareOptions from "./EnablePublicShareOptions";
|
||||
import ManagePublicShare from "./managePublicShare";
|
||||
import { ManagePublicShare } from "./managePublicShare";
|
||||
|
||||
export default function PublicShare({
|
||||
collection,
|
||||
|
||||
@@ -1,266 +0,0 @@
|
||||
import { MenuItemDivider, MenuItemGroup } from "@/base/components/Menu";
|
||||
import { SidebarDrawer } from "@/base/components/mui/SidebarDrawer";
|
||||
import { Titlebar } from "@/base/components/Titlebar";
|
||||
import type {
|
||||
Collection,
|
||||
PublicURL,
|
||||
UpdatePublicURL,
|
||||
} from "@/media/collection";
|
||||
import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem";
|
||||
import ChevronRight from "@mui/icons-material/ChevronRight";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||
import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline";
|
||||
import { DialogProps, Stack, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { GalleryContext } from "pages/gallery";
|
||||
import { useContext, useMemo, useState } from "react";
|
||||
import {
|
||||
deleteShareableURL,
|
||||
updateShareableURL,
|
||||
} from "services/collectionService";
|
||||
import { SetPublicShareProp } from "types/publicCollection";
|
||||
import { getDeviceLimitOptions } from "utils/collection";
|
||||
import { handleSharingErrors } from "utils/error/ui";
|
||||
import { ManageDownloadAccess } from "./downloadAccess";
|
||||
import { ManageLinkExpiry } from "./linkExpiry";
|
||||
import { ManageLinkPassword } from "./linkPassword";
|
||||
import { ManagePublicCollect } from "./publicCollect";
|
||||
|
||||
interface ManagePublicShareOptionsProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
setPublicShareProp: SetPublicShareProp;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onRootClose: () => void;
|
||||
publicShareUrl: string;
|
||||
}
|
||||
|
||||
export const ManagePublicShareOptions: React.FC<
|
||||
ManagePublicShareOptionsProps
|
||||
> = ({
|
||||
publicShareProp,
|
||||
collection,
|
||||
setPublicShareProp,
|
||||
open,
|
||||
onClose,
|
||||
onRootClose,
|
||||
publicShareUrl,
|
||||
}) => {
|
||||
const handleDrawerClose: DialogProps["onClose"] = (_, reason) => {
|
||||
if (reason === "backdropClick") {
|
||||
onRootClose();
|
||||
} else {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
|
||||
const [sharableLinkError, setSharableLinkError] = useState(null);
|
||||
|
||||
const updatePublicShareURLHelper = async (req: UpdatePublicURL) => {
|
||||
try {
|
||||
galleryContext.setBlockingLoad(true);
|
||||
const response = await updateShareableURL(req);
|
||||
setPublicShareProp(response);
|
||||
galleryContext.syncWithRemote(false, true);
|
||||
} catch (e) {
|
||||
const errorMessage = handleSharingErrors(e);
|
||||
setSharableLinkError(errorMessage);
|
||||
} finally {
|
||||
galleryContext.setBlockingLoad(false);
|
||||
}
|
||||
};
|
||||
const disablePublicSharing = async () => {
|
||||
try {
|
||||
galleryContext.setBlockingLoad(true);
|
||||
await deleteShareableURL(collection);
|
||||
setPublicShareProp(null);
|
||||
galleryContext.syncWithRemote(false, true);
|
||||
onClose();
|
||||
} catch (e) {
|
||||
const errorMessage = handleSharingErrors(e);
|
||||
setSharableLinkError(errorMessage);
|
||||
} finally {
|
||||
galleryContext.setBlockingLoad(false);
|
||||
}
|
||||
};
|
||||
const copyToClipboardHelper = (text: string) => () => {
|
||||
navigator.clipboard.writeText(text);
|
||||
};
|
||||
return (
|
||||
<SidebarDrawer anchor="right" open={open} onClose={handleDrawerClose}>
|
||||
<Stack spacing={"4px"} py={"12px"}>
|
||||
<Titlebar
|
||||
onClose={onClose}
|
||||
title={t("share_album")}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<Stack py={"20px"} px={"8px"} spacing={"32px"}>
|
||||
<Stack spacing={3}>
|
||||
<ManagePublicCollect
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
<ManageLinkExpiry
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<MenuItemGroup>
|
||||
<ManageDeviceLimit
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<MenuItemDivider />
|
||||
<ManageDownloadAccess
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
<MenuItemDivider />
|
||||
<ManageLinkPassword
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup>
|
||||
<EnteMenuItem
|
||||
startIcon={<ContentCopyIcon />}
|
||||
onClick={copyToClipboardHelper(publicShareUrl)}
|
||||
label={t("copy_link")}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup>
|
||||
<EnteMenuItem
|
||||
color="critical"
|
||||
startIcon={<RemoveCircleOutline />}
|
||||
onClick={disablePublicSharing}
|
||||
label={t("REMOVE_LINK")}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
</Stack>
|
||||
{sharableLinkError && (
|
||||
<Typography
|
||||
textAlign={"center"}
|
||||
variant="small"
|
||||
sx={{
|
||||
color: (theme) => theme.colors.danger.A700,
|
||||
mt: 0.5,
|
||||
}}
|
||||
>
|
||||
{sharableLinkError}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</SidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
interface ManageDeviceLimitProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
updatePublicShareURLHelper: (req: UpdatePublicURL) => Promise<void>;
|
||||
onRootClose: () => void;
|
||||
}
|
||||
|
||||
export const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
|
||||
collection,
|
||||
publicShareProp,
|
||||
updatePublicShareURLHelper,
|
||||
onRootClose,
|
||||
}) => {
|
||||
const updateDeviceLimit = async (newLimit: number) => {
|
||||
return updatePublicShareURLHelper({
|
||||
collectionID: collection.id,
|
||||
deviceLimit: newLimit,
|
||||
});
|
||||
};
|
||||
const [isChangeDeviceLimitVisible, setIsChangeDeviceLimitVisible] =
|
||||
useState(false);
|
||||
const deviceLimitOptions = useMemo(() => getDeviceLimitOptions(), []);
|
||||
|
||||
const closeDeviceLimitChangeModal = () =>
|
||||
setIsChangeDeviceLimitVisible(false);
|
||||
const openDeviceLimitChangeModalView = () =>
|
||||
setIsChangeDeviceLimitVisible(true);
|
||||
|
||||
const changeDeviceLimitValue = (value: number) => async () => {
|
||||
await updateDeviceLimit(value);
|
||||
setIsChangeDeviceLimitVisible(false);
|
||||
};
|
||||
|
||||
const handleDrawerClose: DialogProps["onClose"] = (_, reason) => {
|
||||
if (reason === "backdropClick") {
|
||||
onRootClose();
|
||||
} else {
|
||||
closeDeviceLimitChangeModal();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EnteMenuItem
|
||||
label={t("LINK_DEVICE_LIMIT")}
|
||||
variant="captioned"
|
||||
subText={
|
||||
publicShareProp.deviceLimit === 0
|
||||
? t("NO_DEVICE_LIMIT")
|
||||
: publicShareProp.deviceLimit.toString()
|
||||
}
|
||||
onClick={openDeviceLimitChangeModalView}
|
||||
endIcon={<ChevronRight />}
|
||||
/>
|
||||
|
||||
<SidebarDrawer
|
||||
anchor="right"
|
||||
open={isChangeDeviceLimitVisible}
|
||||
onClose={handleDrawerClose}
|
||||
>
|
||||
<Stack spacing={"4px"} py={"12px"}>
|
||||
<Titlebar
|
||||
onClose={closeDeviceLimitChangeModal}
|
||||
title={t("LINK_DEVICE_LIMIT")}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<Stack py={"20px"} px={"8px"} spacing={"32px"}>
|
||||
<MenuItemGroup>
|
||||
{deviceLimitOptions.map((item, index) => (
|
||||
<>
|
||||
<EnteMenuItem
|
||||
fontWeight="normal"
|
||||
key={item.label}
|
||||
onClick={changeDeviceLimitValue(
|
||||
item.value,
|
||||
)}
|
||||
label={item.label}
|
||||
/>
|
||||
{index !==
|
||||
deviceLimitOptions.length - 1 && (
|
||||
<MenuItemDivider />
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</MenuItemGroup>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</SidebarDrawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,22 +1,42 @@
|
||||
import { MenuItemDivider, MenuItemGroup } from "@/base/components/Menu";
|
||||
import type { Collection, PublicURL } from "@/media/collection";
|
||||
import { SidebarDrawer } from "@/base/components/mui/SidebarDrawer";
|
||||
import { Titlebar } from "@/base/components/Titlebar";
|
||||
import type {
|
||||
Collection,
|
||||
PublicURL,
|
||||
UpdatePublicURL,
|
||||
} from "@/media/collection";
|
||||
import { EnteMenuItem } from "@ente/shared/components/Menu/EnteMenuItem";
|
||||
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
import {
|
||||
default as ChevronRight,
|
||||
default as ChevronRightIcon,
|
||||
} from "@mui/icons-material/ChevronRight";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopyOutlined";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import LinkIcon from "@mui/icons-material/Link";
|
||||
import PublicIcon from "@mui/icons-material/Public";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import RemoveCircleOutline from "@mui/icons-material/RemoveCircleOutline";
|
||||
import { DialogProps, Stack, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useState } from "react";
|
||||
import { GalleryContext } from "pages/gallery";
|
||||
import { useContext, useMemo, useState } from "react";
|
||||
import {
|
||||
deleteShareableURL,
|
||||
updateShareableURL,
|
||||
} from "services/collectionService";
|
||||
import { SetPublicShareProp } from "types/publicCollection";
|
||||
import {ManagePublicShareOptions} from "./manage";
|
||||
import { getDeviceLimitOptions } from "utils/collection";
|
||||
import { handleSharingErrors } from "utils/error/ui";
|
||||
import { ManageDownloadAccess } from "./manage/downloadAccess";
|
||||
import { ManageLinkExpiry } from "./manage/linkExpiry";
|
||||
import { ManageLinkPassword } from "./manage/linkPassword";
|
||||
import { ManagePublicCollect } from "./manage/publicCollect";
|
||||
|
||||
export const isLinkExpired = (validTill: number) => {
|
||||
return validTill && validTill < Date.now() * 1000;
|
||||
};
|
||||
|
||||
interface Iprops {
|
||||
interface ManagePublicShareProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
setPublicShareProp: SetPublicShareProp;
|
||||
@@ -24,14 +44,15 @@ interface Iprops {
|
||||
publicShareUrl: string;
|
||||
copyToClipboardHelper: () => void;
|
||||
}
|
||||
export default function ManagePublicShare({
|
||||
|
||||
export const ManagePublicShare: React.FC<ManagePublicShareProps> = ({
|
||||
publicShareProp,
|
||||
setPublicShareProp,
|
||||
collection,
|
||||
onRootClose,
|
||||
publicShareUrl,
|
||||
copyToClipboardHelper,
|
||||
}: Iprops) {
|
||||
}) => {
|
||||
const [manageShareView, setManageShareView] = useState(false);
|
||||
const closeManageShare = () => setManageShareView(false);
|
||||
const openManageShare = () => setManageShareView(true);
|
||||
@@ -80,4 +101,243 @@ export default function ManagePublicShare({
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface ManagePublicShareOptionsProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
setPublicShareProp: SetPublicShareProp;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onRootClose: () => void;
|
||||
publicShareUrl: string;
|
||||
}
|
||||
|
||||
export const ManagePublicShareOptions: React.FC<
|
||||
ManagePublicShareOptionsProps
|
||||
> = ({
|
||||
publicShareProp,
|
||||
collection,
|
||||
setPublicShareProp,
|
||||
open,
|
||||
onClose,
|
||||
onRootClose,
|
||||
publicShareUrl,
|
||||
}) => {
|
||||
const handleDrawerClose: DialogProps["onClose"] = (_, reason) => {
|
||||
if (reason === "backdropClick") {
|
||||
onRootClose();
|
||||
} else {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
|
||||
const [sharableLinkError, setSharableLinkError] = useState(null);
|
||||
|
||||
const updatePublicShareURLHelper = async (req: UpdatePublicURL) => {
|
||||
try {
|
||||
galleryContext.setBlockingLoad(true);
|
||||
const response = await updateShareableURL(req);
|
||||
setPublicShareProp(response);
|
||||
galleryContext.syncWithRemote(false, true);
|
||||
} catch (e) {
|
||||
const errorMessage = handleSharingErrors(e);
|
||||
setSharableLinkError(errorMessage);
|
||||
} finally {
|
||||
galleryContext.setBlockingLoad(false);
|
||||
}
|
||||
};
|
||||
const disablePublicSharing = async () => {
|
||||
try {
|
||||
galleryContext.setBlockingLoad(true);
|
||||
await deleteShareableURL(collection);
|
||||
setPublicShareProp(null);
|
||||
galleryContext.syncWithRemote(false, true);
|
||||
onClose();
|
||||
} catch (e) {
|
||||
const errorMessage = handleSharingErrors(e);
|
||||
setSharableLinkError(errorMessage);
|
||||
} finally {
|
||||
galleryContext.setBlockingLoad(false);
|
||||
}
|
||||
};
|
||||
const copyToClipboardHelper = (text: string) => () => {
|
||||
navigator.clipboard.writeText(text);
|
||||
};
|
||||
return (
|
||||
<SidebarDrawer anchor="right" open={open} onClose={handleDrawerClose}>
|
||||
<Stack spacing={"4px"} py={"12px"}>
|
||||
<Titlebar
|
||||
onClose={onClose}
|
||||
title={t("share_album")}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<Stack py={"20px"} px={"8px"} spacing={"32px"}>
|
||||
<Stack spacing={3}>
|
||||
<ManagePublicCollect
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
<ManageLinkExpiry
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<MenuItemGroup>
|
||||
<ManageDeviceLimit
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<MenuItemDivider />
|
||||
<ManageDownloadAccess
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
<MenuItemDivider />
|
||||
<ManageLinkPassword
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup>
|
||||
<EnteMenuItem
|
||||
startIcon={<ContentCopyIcon />}
|
||||
onClick={copyToClipboardHelper(publicShareUrl)}
|
||||
label={t("copy_link")}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup>
|
||||
<EnteMenuItem
|
||||
color="critical"
|
||||
startIcon={<RemoveCircleOutline />}
|
||||
onClick={disablePublicSharing}
|
||||
label={t("REMOVE_LINK")}
|
||||
/>
|
||||
</MenuItemGroup>
|
||||
</Stack>
|
||||
{sharableLinkError && (
|
||||
<Typography
|
||||
textAlign={"center"}
|
||||
variant="small"
|
||||
sx={{
|
||||
color: (theme) => theme.colors.danger.A700,
|
||||
mt: 0.5,
|
||||
}}
|
||||
>
|
||||
{sharableLinkError}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</SidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
interface ManageDeviceLimitProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
updatePublicShareURLHelper: (req: UpdatePublicURL) => Promise<void>;
|
||||
onRootClose: () => void;
|
||||
}
|
||||
|
||||
export const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
|
||||
collection,
|
||||
publicShareProp,
|
||||
updatePublicShareURLHelper,
|
||||
onRootClose,
|
||||
}) => {
|
||||
const updateDeviceLimit = async (newLimit: number) => {
|
||||
return updatePublicShareURLHelper({
|
||||
collectionID: collection.id,
|
||||
deviceLimit: newLimit,
|
||||
});
|
||||
};
|
||||
const [isChangeDeviceLimitVisible, setIsChangeDeviceLimitVisible] =
|
||||
useState(false);
|
||||
const deviceLimitOptions = useMemo(() => getDeviceLimitOptions(), []);
|
||||
|
||||
const closeDeviceLimitChangeModal = () =>
|
||||
setIsChangeDeviceLimitVisible(false);
|
||||
const openDeviceLimitChangeModalView = () =>
|
||||
setIsChangeDeviceLimitVisible(true);
|
||||
|
||||
const changeDeviceLimitValue = (value: number) => async () => {
|
||||
await updateDeviceLimit(value);
|
||||
setIsChangeDeviceLimitVisible(false);
|
||||
};
|
||||
|
||||
const handleDrawerClose: DialogProps["onClose"] = (_, reason) => {
|
||||
if (reason === "backdropClick") {
|
||||
onRootClose();
|
||||
} else {
|
||||
closeDeviceLimitChangeModal();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EnteMenuItem
|
||||
label={t("LINK_DEVICE_LIMIT")}
|
||||
variant="captioned"
|
||||
subText={
|
||||
publicShareProp.deviceLimit === 0
|
||||
? t("NO_DEVICE_LIMIT")
|
||||
: publicShareProp.deviceLimit.toString()
|
||||
}
|
||||
onClick={openDeviceLimitChangeModalView}
|
||||
endIcon={<ChevronRight />}
|
||||
/>
|
||||
|
||||
<SidebarDrawer
|
||||
anchor="right"
|
||||
open={isChangeDeviceLimitVisible}
|
||||
onClose={handleDrawerClose}
|
||||
>
|
||||
<Stack spacing={"4px"} py={"12px"}>
|
||||
<Titlebar
|
||||
onClose={closeDeviceLimitChangeModal}
|
||||
title={t("LINK_DEVICE_LIMIT")}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<Stack py={"20px"} px={"8px"} spacing={"32px"}>
|
||||
<MenuItemGroup>
|
||||
{deviceLimitOptions.map((item, index) => (
|
||||
<>
|
||||
<EnteMenuItem
|
||||
fontWeight="normal"
|
||||
key={item.label}
|
||||
onClick={changeDeviceLimitValue(
|
||||
item.value,
|
||||
)}
|
||||
label={item.label}
|
||||
/>
|
||||
{index !==
|
||||
deviceLimitOptions.length - 1 && (
|
||||
<MenuItemDivider />
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</MenuItemGroup>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</SidebarDrawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user