[web] Convert deprecated titlebar uses (#6074)
This commit is contained in:
@@ -5,7 +5,10 @@ import EditIcon from "@mui/icons-material/Edit";
|
||||
import KeyIcon from "@mui/icons-material/Key";
|
||||
import { Box, Paper, Stack, Typography, styled } from "@mui/material";
|
||||
import { EnteLogo } from "ente-base/components/EnteLogo";
|
||||
import { SidebarDrawer } from "ente-base/components/mui/SidebarDrawer";
|
||||
import {
|
||||
SidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import { NavbarBase } from "ente-base/components/Navbar";
|
||||
import {
|
||||
RowButton,
|
||||
@@ -13,7 +16,6 @@ import {
|
||||
RowButtonGroup,
|
||||
} from "ente-base/components/RowButton";
|
||||
import { SingleInputDialog } from "ente-base/components/SingleInputDialog";
|
||||
import { Titlebar } from "ente-base/components/Titlebar";
|
||||
import { errorDialogAttributes } from "ente-base/components/utils/dialog";
|
||||
import { useModalVisibility } from "ente-base/components/utils/modal";
|
||||
import { useBaseContext } from "ente-base/context";
|
||||
@@ -287,7 +289,7 @@ const ManagePasskeyDrawer: React.FC<ManagePasskeyDrawerProps> = ({
|
||||
<SidebarDrawer anchor="right" {...{ open, onClose }}>
|
||||
{token && passkey && (
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
title={t("manage_passkey")}
|
||||
onRootClose={onClose}
|
||||
@@ -295,7 +297,7 @@ const ManagePasskeyDrawer: React.FC<ManagePasskeyDrawerProps> = ({
|
||||
<CreatedAtEntry>
|
||||
{formattedDateTime(passkey.createdAt)}
|
||||
</CreatedAtEntry>
|
||||
<RowButtonGroup>
|
||||
<RowButtonGroup sx={{ m: 1 }}>
|
||||
<RowButton
|
||||
startIcon={<EditIcon />}
|
||||
label={t("rename_passkey")}
|
||||
|
||||
@@ -12,14 +12,15 @@ import Photo, { default as PhotoIcon } from "@mui/icons-material/Photo";
|
||||
import PublicIcon from "@mui/icons-material/Public";
|
||||
import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline";
|
||||
import WorkspacesIcon from "@mui/icons-material/Workspaces";
|
||||
import { Dialog, DialogProps, Stack, styled, Typography } from "@mui/material";
|
||||
import { Dialog, Stack, styled, Typography } from "@mui/material";
|
||||
import NumberAvatar from "@mui/material/Avatar";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Avatar from "components/pages/gallery/Avatar";
|
||||
import { LoadingButton } from "ente-base/components/mui/LoadingButton";
|
||||
import {
|
||||
NestedSidebarDrawer,
|
||||
SidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
TitledNestedSidebarDrawer,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import {
|
||||
RowButton,
|
||||
@@ -30,9 +31,11 @@ import {
|
||||
RowLabel,
|
||||
RowSwitch,
|
||||
} from "ente-base/components/RowButton";
|
||||
import { Titlebar } from "ente-base/components/Titlebar";
|
||||
import { useClipboardCopy } from "ente-base/components/utils/hooks";
|
||||
import { useModalVisibility } from "ente-base/components/utils/modal";
|
||||
import {
|
||||
useModalVisibility,
|
||||
type ModalVisibilityProps,
|
||||
} from "ente-base/components/utils/modal";
|
||||
import { useBaseContext } from "ente-base/context";
|
||||
import { sharedCryptoWorker } from "ente-base/crypto";
|
||||
import { isHTTP4xxError } from "ente-base/http";
|
||||
@@ -49,7 +52,6 @@ import { PublicLinkCreated } from "ente-new/photos/components/share/PublicLinkCr
|
||||
import { avatarTextColor } from "ente-new/photos/services/avatar";
|
||||
import type { CollectionSummary } from "ente-new/photos/services/collection/ui";
|
||||
import { usePhotosAppContext } from "ente-new/photos/types/context";
|
||||
import { FlexWrapper } from "ente-shared/components/Container";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "ente-shared/components/SingleInputForm";
|
||||
@@ -66,69 +68,52 @@ import {
|
||||
unshareCollection,
|
||||
updateShareableURL,
|
||||
} from "services/collectionService";
|
||||
import { getDeviceLimitOptions } from "utils/collection";
|
||||
import * as Yup from "yup";
|
||||
|
||||
interface CollectionShareProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
type CollectionShareProps = ModalVisibilityProps & {
|
||||
collection: Collection;
|
||||
collectionSummary: CollectionSummary;
|
||||
}
|
||||
};
|
||||
|
||||
export const CollectionShare: React.FC<CollectionShareProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
collection,
|
||||
collectionSummary,
|
||||
...props
|
||||
}) => {
|
||||
const handleRootClose = () => {
|
||||
props.onClose();
|
||||
};
|
||||
const handleDrawerClose: DialogProps["onClose"] = (_, reason) => {
|
||||
if (reason == "backdropClick") {
|
||||
handleRootClose();
|
||||
} else {
|
||||
props.onClose();
|
||||
}
|
||||
};
|
||||
if (!props.collection || !collectionSummary) {
|
||||
if (!collection || !collectionSummary) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const { type } = collectionSummary;
|
||||
|
||||
return (
|
||||
<SidebarDrawer
|
||||
anchor="right"
|
||||
open={props.open}
|
||||
onClose={handleDrawerClose}
|
||||
>
|
||||
<SidebarDrawer anchor="right" {...{ open, onClose }}>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={props.onClose}
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={onClose}
|
||||
title={
|
||||
type == "incomingShareCollaborator" ||
|
||||
type == "incomingShareViewer"
|
||||
? t("sharing_details")
|
||||
: t("share_album")
|
||||
}
|
||||
onRootClose={handleRootClose}
|
||||
caption={props.collection.name}
|
||||
caption={collection.name}
|
||||
/>
|
||||
<Stack sx={{ py: "20px", px: "8px", gap: "24px" }}>
|
||||
{type == "incomingShareCollaborator" ||
|
||||
type == "incomingShareViewer" ? (
|
||||
<SharingDetails
|
||||
collection={props.collection}
|
||||
type={type}
|
||||
/>
|
||||
<SharingDetails {...{ collection, type }} />
|
||||
) : (
|
||||
<>
|
||||
<EmailShare
|
||||
collection={props.collection}
|
||||
onRootClose={handleRootClose}
|
||||
onRootClose={onClose}
|
||||
{...{ collection }}
|
||||
/>
|
||||
<PublicShare
|
||||
collection={props.collection}
|
||||
onRootClose={handleRootClose}
|
||||
onRootClose={onClose}
|
||||
{...{ collection }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -486,6 +471,8 @@ const AddParticipant: React.FC<AddParticipantProps> = ({
|
||||
onRootClose();
|
||||
};
|
||||
|
||||
const title = type == "VIEWER" ? t("add_viewers") : t("add_collaborators");
|
||||
|
||||
const collectionShare: AddParticipantFormProps["callback"] = async ({
|
||||
email,
|
||||
emails,
|
||||
@@ -525,34 +512,20 @@ const AddParticipant: React.FC<AddParticipantProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={title}
|
||||
caption={collection.name}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
{...{ onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={
|
||||
type == "VIEWER"
|
||||
? t("add_viewers")
|
||||
: t("add_collaborators")
|
||||
}
|
||||
caption={collection.name}
|
||||
/>
|
||||
<AddParticipantForm
|
||||
onClose={onClose}
|
||||
callback={collectionShare}
|
||||
optionsList={nonSharedEmails}
|
||||
buttonText={
|
||||
type == "VIEWER"
|
||||
? t("add_viewers")
|
||||
: t("add_collaborators")
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
<AddParticipantForm
|
||||
onClose={onClose}
|
||||
callback={collectionShare}
|
||||
optionsList={nonSharedEmails}
|
||||
buttonText={title}
|
||||
/>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -697,23 +670,17 @@ const AddParticipantForm: React.FC<AddParticipantFormProps> = (props) => {
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
<FlexWrapper
|
||||
px={"8px"}
|
||||
justifyContent={"center"}
|
||||
flexWrap={"nowrap"}
|
||||
>
|
||||
<Stack sx={{ px: "8px", width: "100%" }}>
|
||||
<LoadingButton
|
||||
type="submit"
|
||||
color="accent"
|
||||
fullWidth
|
||||
loading={loading}
|
||||
sx={{ mt: 4, mb: 4 }}
|
||||
>
|
||||
{props.buttonText}
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</FlexWrapper>
|
||||
<Stack sx={{ px: 2 }}>
|
||||
<LoadingButton
|
||||
type="submit"
|
||||
color="accent"
|
||||
fullWidth
|
||||
loading={loading}
|
||||
sx={{ mt: 4, mb: 4 }}
|
||||
>
|
||||
{props.buttonText}
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
</Formik>
|
||||
@@ -738,11 +705,12 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
|
||||
const { showLoadingBar, hideLoadingBar } = usePhotosAppContext();
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
|
||||
const [addParticipantView, setAddParticipantView] = useState(false);
|
||||
const [manageParticipantView, setManageParticipantView] = useState(false);
|
||||
|
||||
const closeAddParticipant = () => setAddParticipantView(false);
|
||||
const openAddParticipant = () => setAddParticipantView(true);
|
||||
const { show: showAddParticipant, props: addParticipantVisibilityProps } =
|
||||
useModalVisibility();
|
||||
const {
|
||||
show: showManageParticipant,
|
||||
props: manageParticipantVisibilityProps,
|
||||
} = useModalVisibility();
|
||||
|
||||
const participantType = useRef<"COLLABORATOR" | "VIEWER">(null);
|
||||
|
||||
@@ -750,12 +718,12 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
|
||||
|
||||
const openAddCollab = () => {
|
||||
participantType.current = "COLLABORATOR";
|
||||
openAddParticipant();
|
||||
showAddParticipant();
|
||||
};
|
||||
|
||||
const openAddViewer = () => {
|
||||
participantType.current = "VIEWER";
|
||||
openAddParticipant();
|
||||
showAddParticipant();
|
||||
};
|
||||
|
||||
const handleRootClose = () => {
|
||||
@@ -793,121 +761,106 @@ const ManageEmailShare: React.FC<ManageEmailShareProps> = ({
|
||||
selectedParticipant.current = collection.sharees.find(
|
||||
(sharee) => sharee.email === email,
|
||||
);
|
||||
setManageParticipantView(true);
|
||||
};
|
||||
const closeManageParticipant = () => {
|
||||
setManageParticipantView(false);
|
||||
showManageParticipant();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={collection.name}
|
||||
caption={t("participants_count", { count: peopleCount })}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={onClose}
|
||||
title={collection.name}
|
||||
onRootClose={handleRootClose}
|
||||
caption={t("participants_count", {
|
||||
count: peopleCount,
|
||||
})}
|
||||
/>
|
||||
<Stack sx={{ gap: "24px", py: "20px", px: "12px" }}>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle
|
||||
icon={<AdminPanelSettingsIcon />}
|
||||
>
|
||||
{t("owner")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
<RowLabel
|
||||
startIcon={<Avatar email={ownerEmail} />}
|
||||
label={isOwner ? t("you") : ownerEmail}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<ModeEditIcon />}>
|
||||
{t("collaborators")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
{collaborators.map((item) => (
|
||||
<React.Fragment key={item}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={() =>
|
||||
openManageParticipant(item)
|
||||
}
|
||||
label={item}
|
||||
startIcon={<Avatar email={item} />}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
<Stack sx={{ gap: "24px", py: "20px", px: "12px" }}>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<AdminPanelSettingsIcon />}>
|
||||
{t("owner")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
<RowLabel
|
||||
startIcon={<Avatar email={ownerEmail} />}
|
||||
label={isOwner ? t("you") : ownerEmail}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<ModeEditIcon />}>
|
||||
{t("collaborators")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
{collaborators.map((item) => (
|
||||
<React.Fragment key={item}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={() =>
|
||||
openManageParticipant(item)
|
||||
}
|
||||
label={item}
|
||||
startIcon={<Avatar email={item} />}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
<RowButton
|
||||
startIcon={<AddIcon />}
|
||||
onClick={openAddCollab}
|
||||
label={
|
||||
collaborators?.length
|
||||
? t("add_more")
|
||||
: t("add_collaborators")
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<Photo />}>
|
||||
{t("viewers")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
{viewers.map((item) => (
|
||||
<React.Fragment key={item}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={() =>
|
||||
openManageParticipant(item)
|
||||
}
|
||||
label={item}
|
||||
startIcon={<Avatar email={item} />}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
<RowButton
|
||||
startIcon={<AddIcon />}
|
||||
onClick={openAddViewer}
|
||||
label={
|
||||
viewers?.length
|
||||
? t("add_more")
|
||||
: t("add_viewers")
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<RowButton
|
||||
startIcon={<AddIcon />}
|
||||
onClick={openAddCollab}
|
||||
label={
|
||||
collaborators?.length
|
||||
? t("add_more")
|
||||
: t("add_collaborators")
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<Photo />}>
|
||||
{t("viewers")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
{viewers.map((item) => (
|
||||
<React.Fragment key={item}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={() =>
|
||||
openManageParticipant(item)
|
||||
}
|
||||
label={item}
|
||||
startIcon={<Avatar email={item} />}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
</React.Fragment>
|
||||
))}
|
||||
<RowButton
|
||||
startIcon={<AddIcon />}
|
||||
onClick={openAddViewer}
|
||||
label={
|
||||
viewers?.length
|
||||
? t("add_more")
|
||||
: t("add_viewers")
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
<ManageParticipant
|
||||
collectionUnshare={collectionUnshare}
|
||||
open={manageParticipantView}
|
||||
collection={collection}
|
||||
onRootClose={onRootClose}
|
||||
onClose={closeManageParticipant}
|
||||
selectedParticipant={selectedParticipant.current}
|
||||
/>
|
||||
</TitledNestedSidebarDrawer>
|
||||
<AddParticipant
|
||||
open={addParticipantView}
|
||||
onClose={closeAddParticipant}
|
||||
{...addParticipantVisibilityProps}
|
||||
onRootClose={onRootClose}
|
||||
collection={collection}
|
||||
type={participantType.current}
|
||||
/>
|
||||
<ManageParticipant
|
||||
{...manageParticipantVisibilityProps}
|
||||
onRootClose={onRootClose}
|
||||
collectionUnshare={collectionUnshare}
|
||||
collection={collection}
|
||||
selectedParticipant={selectedParticipant.current}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1011,83 +964,77 @@ const ManageParticipant: React.FC<ManageParticipantProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("manage")}
|
||||
caption={selectedParticipant.email}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={onClose}
|
||||
title={t("manage")}
|
||||
onRootClose={handleRootClose}
|
||||
caption={selectedParticipant.email}
|
||||
/>
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<Stack>
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "text.muted", padding: 1 }}
|
||||
>
|
||||
{t("added_as")}
|
||||
</Typography>
|
||||
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<Stack>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={handleRoleChange("COLLABORATOR")}
|
||||
label={"Collaborator"}
|
||||
startIcon={<ModeEditIcon />}
|
||||
endIcon={
|
||||
selectedParticipant.role === "COLLABORATOR" && (
|
||||
<DoneIcon />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={handleRoleChange("VIEWER")}
|
||||
label={"Viewer"}
|
||||
startIcon={<PhotoIcon />}
|
||||
endIcon={
|
||||
selectedParticipant.role == "VIEWER" && (
|
||||
<DoneIcon />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "text.muted", padding: 1 }}
|
||||
>
|
||||
{t("collaborator_hint")}
|
||||
</Typography>
|
||||
|
||||
<Stack sx={{ py: "30px" }}>
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "text.muted", padding: 1 }}
|
||||
>
|
||||
{t("added_as")}
|
||||
{t("remove_participant")}
|
||||
</Typography>
|
||||
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
fontWeight="regular"
|
||||
onClick={handleRoleChange("COLLABORATOR")}
|
||||
label={"Collaborator"}
|
||||
startIcon={<ModeEditIcon />}
|
||||
endIcon={
|
||||
selectedParticipant.role ===
|
||||
"COLLABORATOR" && <DoneIcon />
|
||||
}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={handleRoleChange("VIEWER")}
|
||||
label={"Viewer"}
|
||||
startIcon={<PhotoIcon />}
|
||||
endIcon={
|
||||
selectedParticipant.role == "VIEWER" && (
|
||||
<DoneIcon />
|
||||
)
|
||||
}
|
||||
onClick={removeParticipant}
|
||||
label={"Remove"}
|
||||
startIcon={<BlockIcon />}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "text.muted", padding: 1 }}
|
||||
>
|
||||
{t("collaborator_hint")}
|
||||
</Typography>
|
||||
|
||||
<Stack sx={{ py: "30px" }}>
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "text.muted", padding: 1 }}
|
||||
>
|
||||
{t("remove_participant")}
|
||||
</Typography>
|
||||
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
fontWeight="regular"
|
||||
onClick={removeParticipant}
|
||||
label={"Remove"}
|
||||
startIcon={<BlockIcon />}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1289,87 +1236,75 @@ const ManagePublicShareOptions: React.FC<ManagePublicShareOptionsProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("share_album")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={onClose}
|
||||
title={t("share_album")}
|
||||
onRootClose={handleRootClose}
|
||||
<Stack sx={{ gap: 3, py: "20px", px: "8px" }}>
|
||||
<ManagePublicCollect
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
/>
|
||||
<Stack sx={{ gap: 3, py: "20px", px: "8px" }}>
|
||||
<ManagePublicCollect
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
/>
|
||||
<ManageLinkExpiry
|
||||
<ManageLinkExpiry
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<RowButtonGroup>
|
||||
<ManageDeviceLimit
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<RowButtonGroup>
|
||||
<ManageDeviceLimit
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
onRootClose={onRootClose}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<ManageDownloadAccess
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<ManageLinkPassword
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={
|
||||
updatePublicShareURLHelper
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
startIcon={
|
||||
copied ? (
|
||||
<DoneIcon sx={{ color: "accent.main" }} />
|
||||
) : (
|
||||
<ContentCopyIcon />
|
||||
)
|
||||
}
|
||||
onClick={handleCopyLink}
|
||||
label={t("copy_link")}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
startIcon={<RemoveCircleOutlineIcon />}
|
||||
onClick={disablePublicSharing}
|
||||
label={t("remove_link")}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
{sharableLinkError && (
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "critical.main", textAlign: "center" }}
|
||||
>
|
||||
{sharableLinkError}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
<RowButtonDivider />
|
||||
<ManageDownloadAccess
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<ManageLinkPassword
|
||||
collection={collection}
|
||||
publicShareProp={publicShareProp}
|
||||
updatePublicShareURLHelper={updatePublicShareURLHelper}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
startIcon={
|
||||
copied ? (
|
||||
<DoneIcon sx={{ color: "accent.main" }} />
|
||||
) : (
|
||||
<ContentCopyIcon />
|
||||
)
|
||||
}
|
||||
onClick={handleCopyLink}
|
||||
label={t("copy_link")}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
startIcon={<RemoveCircleOutlineIcon />}
|
||||
onClick={disablePublicSharing}
|
||||
label={t("remove_link")}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
{sharableLinkError && (
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{ color: "critical.main", textAlign: "center" }}
|
||||
>
|
||||
{sharableLinkError}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1420,6 +1355,11 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
|
||||
updatePublicShareURLHelper,
|
||||
onRootClose,
|
||||
}) => {
|
||||
const { show: showExpiryOptions, props: expiryOptionsVisibilityProps } =
|
||||
useModalVisibility();
|
||||
|
||||
const options = useMemo(() => shareExpiryOptions(), []);
|
||||
|
||||
const updateDeviceExpiry = async (optionFn) => {
|
||||
return updatePublicShareURLHelper({
|
||||
collectionID: collection.id,
|
||||
@@ -1427,33 +1367,17 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const [shareExpiryOptionsModalView, setShareExpiryOptionsModalView] =
|
||||
useState(false);
|
||||
|
||||
const shareExpireOption = useMemo(() => shareExpiryOptions(), []);
|
||||
|
||||
const closeShareExpiryOptionsModalView = () =>
|
||||
setShareExpiryOptionsModalView(false);
|
||||
|
||||
const openShareExpiryOptionsModalView = () =>
|
||||
setShareExpiryOptionsModalView(true);
|
||||
|
||||
const changeShareExpiryValue = (value: number) => async () => {
|
||||
await updateDeviceExpiry(value);
|
||||
publicShareProp.validTill = value;
|
||||
setShareExpiryOptionsModalView(false);
|
||||
};
|
||||
|
||||
const handleRootClose = () => {
|
||||
closeShareExpiryOptionsModalView();
|
||||
onRootClose();
|
||||
expiryOptionsVisibilityProps.onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
onClick={openShareExpiryOptionsModalView}
|
||||
onClick={showExpiryOptions}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("link_expiry")}
|
||||
color={
|
||||
@@ -1470,43 +1394,34 @@ const ManageLinkExpiry: React.FC<ManageLinkExpiryProps> = ({
|
||||
}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
open={shareExpiryOptionsModalView}
|
||||
onClose={closeShareExpiryOptionsModalView}
|
||||
onRootClose={handleRootClose}
|
||||
{...expiryOptionsVisibilityProps}
|
||||
onRootClose={onRootClose}
|
||||
title={t("link_expiry")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={closeShareExpiryOptionsModalView}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("link_expiry")}
|
||||
/>
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<RowButtonGroup>
|
||||
{shareExpireOption.map((item, index) => (
|
||||
<React.Fragment key={item.value()}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={changeShareExpiryValue(
|
||||
item.value(),
|
||||
)}
|
||||
label={item.label}
|
||||
/>
|
||||
{index !== shareExpireOption.length - 1 && (
|
||||
<RowButtonDivider />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<RowButtonGroup>
|
||||
{options.map(({ label, value }, index) => (
|
||||
<React.Fragment key={value()}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={changeShareExpiryValue(value())}
|
||||
label={label}
|
||||
/>
|
||||
{index != options.length - 1 && (
|
||||
<RowButtonDivider />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const shareExpiryOptions = () => [
|
||||
const shareExpiryOptions = () => [
|
||||
{ label: t("never"), value: () => 0 },
|
||||
{ label: t("after_time.hour"), value: () => microsecsAfter("hour") },
|
||||
{ label: t("after_time.day"), value: () => microsecsAfter("day") },
|
||||
@@ -1550,29 +1465,21 @@ const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
|
||||
updatePublicShareURLHelper,
|
||||
onRootClose,
|
||||
}) => {
|
||||
const { show: showDeviceOptions, props: deviceOptionsVisibilityProps } =
|
||||
useModalVisibility();
|
||||
|
||||
const options = useMemo(() => deviceLimitOptions(), []);
|
||||
|
||||
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 handleRootClose = () => {
|
||||
closeDeviceLimitChangeModal();
|
||||
onRootClose();
|
||||
deviceOptionsVisibilityProps.onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -1584,46 +1491,42 @@ const ManageDeviceLimit: React.FC<ManageDeviceLimitProps> = ({
|
||||
? t("none")
|
||||
: publicShareProp.deviceLimit.toString()
|
||||
}
|
||||
onClick={openDeviceLimitChangeModalView}
|
||||
onClick={showDeviceOptions}
|
||||
endIcon={<ChevronRightIcon />}
|
||||
/>
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
anchor="right"
|
||||
open={isChangeDeviceLimitVisible}
|
||||
onClose={closeDeviceLimitChangeModal}
|
||||
onRootClose={handleRootClose}
|
||||
{...deviceOptionsVisibilityProps}
|
||||
onRootClose={onRootClose}
|
||||
title={t("device_limit")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<Titlebar
|
||||
onClose={closeDeviceLimitChangeModal}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("device_limit")}
|
||||
/>
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<RowButtonGroup>
|
||||
{deviceLimitOptions.map((item, index) => (
|
||||
<React.Fragment key={item.label}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={changeDeviceLimitValue(
|
||||
item.value,
|
||||
)}
|
||||
label={item.label}
|
||||
/>
|
||||
{index !==
|
||||
deviceLimitOptions.length - 1 && (
|
||||
<RowButtonDivider />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack sx={{ gap: "32px", py: "20px", px: "8px" }}>
|
||||
<RowButtonGroup>
|
||||
{options.map(({ label, value }, index) => (
|
||||
<React.Fragment key={label}>
|
||||
<RowButton
|
||||
fontWeight="regular"
|
||||
onClick={changeDeviceLimitValue(value)}
|
||||
label={label}
|
||||
/>
|
||||
{index != options.length - 1 && (
|
||||
<RowButtonDivider />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const deviceLimitOptions = () =>
|
||||
[0, 2, 5, 10, 25, 50].map((i) => ({
|
||||
label: i == 0 ? t("none") : i.toString(),
|
||||
value: i,
|
||||
}));
|
||||
|
||||
interface ManageDownloadAccessProps {
|
||||
publicShareProp: PublicURL;
|
||||
collection: Collection;
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
} from "ente-new/photos/components/PlaceholderThumbnails";
|
||||
import { TileBottomTextOverlay } from "ente-new/photos/components/Tiles";
|
||||
import { TRASH_SECTION } from "ente-new/photos/services/collection";
|
||||
import { FlexWrapper } from "ente-shared/components/Container";
|
||||
import { t } from "i18next";
|
||||
import memoize from "memoize-one";
|
||||
import { GalleryContext } from "pages/gallery";
|
||||
@@ -1019,12 +1018,16 @@ const ListContainer = styled(Box, {
|
||||
}
|
||||
`;
|
||||
|
||||
const ListItemContainer = styled(FlexWrapper)<{ span: number }>`
|
||||
const ListItemContainer = styled("div")<{ span: number }>`
|
||||
grid-column: span ${(props) => props.span};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const FullSpanListItemContainer = styled(FlexWrapper)`
|
||||
const FullSpanListItemContainer = styled("div")`
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const asFullSpanListItem = ({ item, ...rest }: TimeStampListItem) => ({
|
||||
|
||||
@@ -41,9 +41,8 @@ import { ActivityIndicator } from "ente-base/components/mui/ActivityIndicator";
|
||||
import { DialogCloseIconButton } from "ente-base/components/mui/DialogCloseIconButton";
|
||||
import { FocusVisibleButton } from "ente-base/components/mui/FocusVisibleButton";
|
||||
import {
|
||||
NestedSidebarDrawer,
|
||||
SidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
TitledNestedSidebarDrawer,
|
||||
type NestedSidebarDrawerVisibilityProps,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import { useIsSmallWidth } from "ente-base/components/utils/hooks";
|
||||
@@ -658,6 +657,7 @@ const InfoSection: React.FC = () => {
|
||||
|
||||
type AccountProps = NestedSidebarDrawerVisibilityProps &
|
||||
Pick<SidebarProps, "onAuthenticateUser">;
|
||||
|
||||
const Account: React.FC<AccountProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
@@ -689,55 +689,49 @@ const Account: React.FC<AccountProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer {...{ open, onClose }} onRootClose={onRootClose}>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
title={t("account")}
|
||||
onRootClose={handleRootClose}
|
||||
/>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={
|
||||
<HealthAndSafetyIcon
|
||||
sx={{ color: "accent.main" }}
|
||||
/>
|
||||
}
|
||||
label={t("recovery_key")}
|
||||
onClick={showRecoveryKey}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
label={t("two_factor")}
|
||||
onClick={showTwoFactor}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton
|
||||
label={t("passkeys")}
|
||||
onClick={handlePasskeys}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
label={t("change_password")}
|
||||
onClick={handleChangePassword}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton
|
||||
label={t("change_email")}
|
||||
onClick={handleChangeEmail}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
label={t("delete_account")}
|
||||
onClick={showDeleteAccount}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("account")}
|
||||
>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={
|
||||
<HealthAndSafetyIcon
|
||||
sx={{ color: "accent.main" }}
|
||||
/>
|
||||
}
|
||||
label={t("recovery_key")}
|
||||
onClick={showRecoveryKey}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
label={t("two_factor")}
|
||||
onClick={showTwoFactor}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton label={t("passkeys")} onClick={handlePasskeys} />
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
label={t("change_password")}
|
||||
onClick={handleChangePassword}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton
|
||||
label={t("change_email")}
|
||||
onClick={handleChangeEmail}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
color="critical"
|
||||
label={t("delete_account")}
|
||||
onClick={showDeleteAccount}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<RecoveryKey
|
||||
{...recoveryKeyVisibilityProps}
|
||||
@@ -751,7 +745,7 @@ const Account: React.FC<AccountProps> = ({
|
||||
{...deleteAccountVisibilityProps}
|
||||
{...{ onAuthenticateUser }}
|
||||
/>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -782,51 +776,48 @@ const Preferences: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer {...{ open, onClose }} onRootClose={onRootClose}>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
title={t("preferences")}
|
||||
onRootClose={handleRootClose}
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("preferences")}
|
||||
>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<LanguageSelector />
|
||||
<ThemeSelector />
|
||||
<Divider sx={{ my: "2px", opacity: 0.1 }} />
|
||||
{isMLSupported && (
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("ml_search")}
|
||||
onClick={showMLSettings}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
)}
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("map")}
|
||||
onClick={showMapSettings}
|
||||
/>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<LanguageSelector />
|
||||
<ThemeSelector />
|
||||
<Divider sx={{ my: "2px", opacity: 0.1 }} />
|
||||
{isMLSupported && (
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("advanced")}
|
||||
onClick={showAdvancedSettings}
|
||||
/>
|
||||
{isHLSGenerationSupported && (
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<ScienceIcon />}>
|
||||
{t("labs")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("ml_search")}
|
||||
onClick={showMLSettings}
|
||||
<RowSwitch
|
||||
label={t("streamable_videos")}
|
||||
checked={isHLSGenerationEnabled}
|
||||
onClick={() => void toggleHLSGeneration()}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
)}
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("map")}
|
||||
onClick={showMapSettings}
|
||||
/>
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={t("advanced")}
|
||||
onClick={showAdvancedSettings}
|
||||
/>
|
||||
{isHLSGenerationSupported && (
|
||||
<Stack>
|
||||
<RowButtonGroupTitle icon={<ScienceIcon />}>
|
||||
{t("labs")}
|
||||
</RowButtonGroupTitle>
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("streamable_videos")}
|
||||
checked={isHLSGenerationEnabled}
|
||||
onClick={() => void toggleHLSGeneration()}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
<MapSettings
|
||||
{...mapSettingsVisibilityProps}
|
||||
@@ -840,7 +831,7 @@ const Preferences: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
{...mlSettingsVisibilityProps}
|
||||
onRootClose={handleRootClose}
|
||||
/>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -974,28 +965,21 @@ const MapSettings: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("map")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("map")}
|
||||
/>
|
||||
|
||||
<Stack sx={{ px: "16px", py: "20px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("enabled")}
|
||||
checked={mapEnabled}
|
||||
onClick={confirmToggle}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack sx={{ px: "16px", py: "20px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("enabled")}
|
||||
checked={mapEnabled}
|
||||
onClick={confirmToggle}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1032,41 +1016,35 @@ const AdvancedSettings: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
void electron?.toggleAutoLaunch().then(refreshAutoLaunchEnabled);
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("advanced")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("advanced")}
|
||||
/>
|
||||
<Stack sx={{ px: "16px", py: "20px", gap: "24px" }}>
|
||||
<Stack>
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("faster_upload")}
|
||||
checked={!cfUploadProxyDisabled}
|
||||
onClick={toggleProxy}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroupHint>
|
||||
{t("faster_upload_description")}
|
||||
</RowButtonGroupHint>
|
||||
</Stack>
|
||||
{electron && (
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("open_ente_on_startup")}
|
||||
checked={isAutoLaunchEnabled}
|
||||
onClick={toggleAutoLaunch}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
)}
|
||||
<Stack sx={{ px: "16px", py: "20px", gap: "24px" }}>
|
||||
<Stack>
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("faster_upload")}
|
||||
checked={!cfUploadProxyDisabled}
|
||||
onClick={toggleProxy}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroupHint>
|
||||
{t("faster_upload_description")}
|
||||
</RowButtonGroupHint>
|
||||
</Stack>
|
||||
{electron && (
|
||||
<RowButtonGroup>
|
||||
<RowSwitch
|
||||
label={t("open_ente_on_startup")}
|
||||
checked={isAutoLaunchEnabled}
|
||||
onClick={toggleAutoLaunch}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
)}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1106,71 +1084,68 @@ const Help: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer {...{ open, onClose }} onRootClose={onRootClose}>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
title={t("help")}
|
||||
onRootClose={handleRootClose}
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("help")}
|
||||
>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<InfoOutlinedIcon />}
|
||||
label={t("ente_help")}
|
||||
onClick={handleHelp}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<NorthEastIcon />}
|
||||
label={t("blog")}
|
||||
onClick={handleBlog}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton
|
||||
endIcon={<NorthEastIcon />}
|
||||
label={t("request_feature")}
|
||||
onClick={handleRequestFeature}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={
|
||||
<Tooltip title="support@ente.io">
|
||||
<Typography sx={{ fontWeight: "medium" }}>
|
||||
{t("support")}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
}
|
||||
onClick={handleSupport}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack sx={{ px: "16px" }}>
|
||||
<RowButton
|
||||
variant="secondary"
|
||||
label={
|
||||
<Typography variant="mini" color="text.muted">
|
||||
{t("view_logs")}
|
||||
</Typography>
|
||||
}
|
||||
onClick={confirmViewLogs}
|
||||
/>
|
||||
<Stack sx={{ px: "16px", py: "8px", gap: "24px" }}>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<InfoOutlinedIcon />}
|
||||
label={t("ente_help")}
|
||||
onClick={handleHelp}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<NorthEastIcon />}
|
||||
label={t("blog")}
|
||||
onClick={handleBlog}
|
||||
/>
|
||||
<RowButtonDivider />
|
||||
<RowButton
|
||||
endIcon={<NorthEastIcon />}
|
||||
label={t("request_feature")}
|
||||
onClick={handleRequestFeature}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
<RowButtonGroup>
|
||||
<RowButton
|
||||
endIcon={<ChevronRightIcon />}
|
||||
label={
|
||||
<Tooltip title="support@ente.io">
|
||||
<Typography sx={{ fontWeight: "medium" }}>
|
||||
{t("support")}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
}
|
||||
onClick={handleSupport}
|
||||
/>
|
||||
</RowButtonGroup>
|
||||
</Stack>
|
||||
<Stack sx={{ px: "16px" }}>
|
||||
{isDevBuildAndUser() && (
|
||||
<RowButton
|
||||
variant="secondary"
|
||||
label={
|
||||
<Typography variant="mini" color="text.muted">
|
||||
{t("view_logs")}
|
||||
{ut("Test upload")}
|
||||
</Typography>
|
||||
}
|
||||
onClick={confirmViewLogs}
|
||||
onClick={testUpload}
|
||||
/>
|
||||
{isDevBuildAndUser() && (
|
||||
<RowButton
|
||||
variant="secondary"
|
||||
label={
|
||||
<Typography variant="mini" color="text.muted">
|
||||
{ut("Test upload")}
|
||||
</Typography>
|
||||
}
|
||||
onClick={testUpload}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -101,7 +101,6 @@ import {
|
||||
verifyStripeSubscription,
|
||||
} from "ente-new/photos/services/user-details";
|
||||
import { usePhotosAppContext } from "ente-new/photos/types/context";
|
||||
import { FlexWrapper } from "ente-shared/components/Container";
|
||||
import { getData } from "ente-shared/storage/localStorage";
|
||||
import {
|
||||
getToken,
|
||||
@@ -1250,16 +1249,15 @@ const HiddenSectionNavbarContents: React.FC<
|
||||
direction="row"
|
||||
sx={(theme) => ({
|
||||
gap: "24px",
|
||||
width: "100%",
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
background: theme.vars.palette.background.default,
|
||||
})}
|
||||
>
|
||||
<IconButton onClick={onBack}>
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
<FlexWrapper>
|
||||
<Typography>{t("section_hidden")}</Typography>
|
||||
</FlexWrapper>
|
||||
<Typography sx={{ flex: 1 }}>{t("section_hidden")}</Typography>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import {
|
||||
import { safeDirectoryName } from "ente-new/photos/utils/native-fs";
|
||||
import { getData } from "ente-shared/storage/localStorage";
|
||||
import type { User } from "ente-shared/user/types";
|
||||
import { t } from "i18next";
|
||||
import {
|
||||
createAlbum,
|
||||
removeFromCollection,
|
||||
@@ -183,15 +182,6 @@ async function createCollectionDownloadFolder(
|
||||
return collectionDownloadPath;
|
||||
}
|
||||
|
||||
const _intSelectOption = (i: number) => {
|
||||
const label = i === 0 ? t("none") : i.toString();
|
||||
return { label, value: i };
|
||||
};
|
||||
|
||||
export function getDeviceLimitOptions() {
|
||||
return [0, 2, 5, 10, 25, 50].map((i) => _intSelectOption(i));
|
||||
}
|
||||
|
||||
export const changeCollectionVisibility = async (
|
||||
collection: Collection,
|
||||
visibility: ItemVisibility,
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { Box, IconButton, Stack, Typography } from "@mui/material";
|
||||
import { FlexWrapper } from "ente-shared/components/Container";
|
||||
import React from "react";
|
||||
|
||||
interface TitlebarProps {
|
||||
title: string;
|
||||
caption?: string;
|
||||
onClose: () => void;
|
||||
backIsClose?: boolean;
|
||||
onRootClose?: () => void;
|
||||
actionButton?: React.JSX.Element;
|
||||
}
|
||||
|
||||
// TODO: Deprecated in favor of SidebarDrawerTitlebarProps where possible (will
|
||||
// revisit the remaining use cases once those have migrated).
|
||||
export const Titlebar: React.FC<TitlebarProps> = ({
|
||||
title,
|
||||
caption,
|
||||
onClose,
|
||||
backIsClose,
|
||||
actionButton,
|
||||
onRootClose,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<FlexWrapper
|
||||
height={48}
|
||||
alignItems={"center"}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<IconButton
|
||||
onClick={onClose}
|
||||
color={backIsClose ? "secondary" : "primary"}
|
||||
>
|
||||
{backIsClose ? <CloseIcon /> : <ArrowBackIcon />}
|
||||
</IconButton>
|
||||
<Stack direction="row" sx={{ gap: "4px" }}>
|
||||
{actionButton && actionButton}
|
||||
{!backIsClose && (
|
||||
<IconButton onClick={onRootClose} color="secondary">
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</Stack>
|
||||
</FlexWrapper>
|
||||
<Box sx={{ py: 0.5, px: 2 }}>
|
||||
<Typography variant="h3">{title}</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{
|
||||
color: "text.muted",
|
||||
wordBreak: "break-all",
|
||||
minHeight: "17px",
|
||||
}}
|
||||
>
|
||||
{caption}
|
||||
</Typography>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -164,18 +164,67 @@ export const SidebarDrawerTitlebar: React.FC<SidebarDrawerTitlebarProps> = ({
|
||||
</IconButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Box sx={{ px: "16px", py: "4px" }}>
|
||||
<Stack sx={{ px: "16px", gap: "4px" }}>
|
||||
<Typography variant="h3">{title}</Typography>
|
||||
<Typography
|
||||
variant="small"
|
||||
sx={{
|
||||
color: "text.muted",
|
||||
wordBreak: "break-all",
|
||||
px: "1px",
|
||||
minHeight: "17px",
|
||||
}}
|
||||
>
|
||||
{caption}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
/**
|
||||
* A variant of {@link SidebarDrawerTitlebar} with a close button where the back
|
||||
* button is, and none of the other whistles.
|
||||
*
|
||||
* This is currently only used by the top level "File info" screen; the reason
|
||||
* for keeping this here so that it also gets modified when we modify the
|
||||
* spacing etc for {@link SidebarDrawerTitlebar} so that they both look visually
|
||||
* similar (apart from the obvious icon differences).
|
||||
*/
|
||||
export const SidebarDrawerTitlebarClose: React.FC<
|
||||
Pick<SidebarDrawerTitlebarProps, "onClose" | "title">
|
||||
> = ({ title, onClose }) => (
|
||||
<Stack sx={{ gap: "4px" }}>
|
||||
<Stack direction="row" sx={{ justifyContent: "space-between" }}>
|
||||
<IconButton onClick={onClose} color="secondary">
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<Box sx={{ px: "16px", py: "4px" }}>
|
||||
<Typography variant="h3">{title}</Typography>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
/**
|
||||
* A variant of {@link NestedSidebarDrawer} that additionally shows a title.
|
||||
*
|
||||
* {@link NestedSidebarDrawer} is for second level, nested drawers that are
|
||||
* shown atop an already visible {@link SidebarDrawer}. This component combines
|
||||
* the {@link NestedSidebarDrawer} with a {@link SidebarDrawerTitlebar} and some
|
||||
* standard spacing, so that the caller can just provide the content as the
|
||||
* children.
|
||||
*/
|
||||
export const TitledNestedSidebarDrawer: React.FC<
|
||||
React.PropsWithChildren<
|
||||
NestedSidebarDrawerVisibilityProps &
|
||||
Pick<DrawerProps, "anchor"> &
|
||||
SidebarDrawerTitlebarProps
|
||||
>
|
||||
> = ({ open, onClose, onRootClose, anchor, children, ...rest }) => (
|
||||
<NestedSidebarDrawer {...{ open, onClose, onRootClose, anchor }}>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar {...{ onClose, onRootClose }} {...rest} />
|
||||
{children}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
);
|
||||
|
||||
@@ -38,9 +38,12 @@ import { isDesktop } from "ente-base/app";
|
||||
import { LinkButtonUndecorated } from "ente-base/components/LinkButton";
|
||||
import { type ButtonishProps } from "ente-base/components/mui";
|
||||
import { ActivityIndicator } from "ente-base/components/mui/ActivityIndicator";
|
||||
import { SidebarDrawer } from "ente-base/components/mui/SidebarDrawer";
|
||||
import {
|
||||
SidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
SidebarDrawerTitlebarClose,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import { SingleInputForm } from "ente-base/components/SingleInputForm";
|
||||
import { Titlebar } from "ente-base/components/Titlebar";
|
||||
import { EllipsizedTypography } from "ente-base/components/Typography";
|
||||
import {
|
||||
useModalVisibility,
|
||||
@@ -264,7 +267,7 @@ export const FileInfo: React.FC<FileInfoProps> = ({
|
||||
|
||||
return (
|
||||
<FileInfoSidebar {...{ open, onClose }}>
|
||||
<Titlebar onClose={onClose} title={t("info")} backIsClose />
|
||||
<SidebarDrawerTitlebarClose {...{ onClose }} title={t("info")} />
|
||||
<Stack sx={{ pt: 1, pb: 3, gap: "20px" }}>
|
||||
<Caption
|
||||
{...{
|
||||
@@ -596,7 +599,9 @@ const Caption: React.FC<CaptionProps> = ({
|
||||
const { values, errors, handleChange, handleSubmit, resetForm } = formik;
|
||||
|
||||
if (!caption.length && !allowEdits) {
|
||||
return <></>;
|
||||
// Visually take up some space, otherwise the info panel for the shared
|
||||
// photos without a caption looks squished at the top.
|
||||
return <Box sx={{ minHeight: 2 }}></Box>;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -985,11 +990,11 @@ const RawExif: React.FC<RawExifProps> = ({
|
||||
|
||||
return (
|
||||
<FileInfoSidebar open={open} onClose={onClose}>
|
||||
<Titlebar
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("exif")}
|
||||
caption={fileName}
|
||||
onRootClose={handleRootClose}
|
||||
actionButton={
|
||||
<CopyButton size="small" text={JSON.stringify(tags)} />
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@ import { RowButtonGroup, RowSwitch } from "ente-base/components/RowButton";
|
||||
import { ActivityIndicator } from "ente-base/components/mui/ActivityIndicator";
|
||||
import { FocusVisibleButton } from "ente-base/components/mui/FocusVisibleButton";
|
||||
import {
|
||||
NestedSidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
TitledNestedSidebarDrawer,
|
||||
type NestedSidebarDrawerVisibilityProps,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import { useBaseContext } from "ente-base/context";
|
||||
@@ -66,19 +65,13 @@ export const MLSettings: React.FC<NestedSidebarDrawerVisibilityProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("ml_search")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("ml_search")}
|
||||
/>
|
||||
{component}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
{component}
|
||||
</TitledNestedSidebarDrawer>
|
||||
|
||||
<FaceConsentDrawer
|
||||
open={openFaceConsent}
|
||||
@@ -151,19 +144,13 @@ const FaceConsentDrawer: React.FC<FaceConsentDrawerProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("ml_consent_title")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("ml_consent_title")}
|
||||
/>
|
||||
<FaceConsent onConsent={onConsent} onCancel={onClose} />
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
<FaceConsent onConsent={onConsent} onCancel={onClose} />
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ import {
|
||||
} from "ente-base/components/RowButton";
|
||||
import { FocusVisibleButton } from "ente-base/components/mui/FocusVisibleButton";
|
||||
import {
|
||||
NestedSidebarDrawer,
|
||||
SidebarDrawerTitlebar,
|
||||
TitledNestedSidebarDrawer,
|
||||
type NestedSidebarDrawerVisibilityProps,
|
||||
} from "ente-base/components/mui/SidebarDrawer";
|
||||
import { useBaseContext } from "ente-base/context";
|
||||
@@ -52,24 +51,17 @@ export const TwoFactorSettings: React.FC<
|
||||
};
|
||||
|
||||
return (
|
||||
<NestedSidebarDrawer
|
||||
<TitledNestedSidebarDrawer
|
||||
{...{ open, onClose }}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("two_factor_authentication")}
|
||||
>
|
||||
<Stack sx={{ gap: "4px", py: "12px" }}>
|
||||
<SidebarDrawerTitlebar
|
||||
onClose={onClose}
|
||||
onRootClose={handleRootClose}
|
||||
title={t("two_factor_authentication")}
|
||||
/>
|
||||
|
||||
{isTwoFactorEnabled ? (
|
||||
<ManageDrawerContents onRootClose={handleRootClose} />
|
||||
) : (
|
||||
<SetupDrawerContents onRootClose={handleRootClose} />
|
||||
)}
|
||||
</Stack>
|
||||
</NestedSidebarDrawer>
|
||||
{isTwoFactorEnabled ? (
|
||||
<ManageDrawerContents onRootClose={handleRootClose} />
|
||||
) : (
|
||||
<SetupDrawerContents onRootClose={handleRootClose} />
|
||||
)}
|
||||
</TitledNestedSidebarDrawer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user