commit
3ee1bb06c5
|
@ -7,6 +7,7 @@ import OverflowMenu from 'components/OverflowMenu/menu';
|
|||
export interface CollectionSortProps {
|
||||
setCollectionSortBy: (sortBy: COLLECTION_SORT_BY) => void;
|
||||
activeSortBy: COLLECTION_SORT_BY;
|
||||
nestedInDialog?: boolean;
|
||||
disableBG?: boolean;
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,13 @@ export default function CollectionSort(props: CollectionSortProps) {
|
|||
<OverflowMenu
|
||||
ariaControls="collection-sort"
|
||||
triggerButtonIcon={<SortIcon />}
|
||||
menuPaperProps={{
|
||||
sx: {
|
||||
backgroundColor: (theme) =>
|
||||
props.nestedInDialog &&
|
||||
theme.palette.background.overPaper,
|
||||
},
|
||||
}}
|
||||
triggerButtonProps={{
|
||||
sx: {
|
||||
background: (theme) =>
|
||||
|
|
|
@ -32,6 +32,7 @@ export default function AllCollectionsHeader({
|
|||
<CollectionSort
|
||||
activeSortBy={collectionSortBy}
|
||||
setCollectionSortBy={setCollectionSortBy}
|
||||
nestedInDialog
|
||||
/>
|
||||
<IconButtonWithBG onClick={onClose}>
|
||||
<Close />
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import SingleInputForm from 'components/SingleInputForm';
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from 'components/SingleInputForm';
|
||||
import { GalleryContext } from 'pages/gallery';
|
||||
import React, { useContext } from 'react';
|
||||
import { shareCollection } from 'services/collectionService';
|
||||
|
@ -8,18 +10,22 @@ import { handleSharingErrors } from 'utils/error';
|
|||
import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
||||
import constants from 'utils/strings/constants';
|
||||
import { CollectionShareSharees } from './sharees';
|
||||
|
||||
export default function EmailShare({ collection }) {
|
||||
const galleryContext = useContext(GalleryContext);
|
||||
|
||||
const collectionShare = async (email, setFieldError) => {
|
||||
const collectionShare: SingleInputFormProps['callback'] = async (
|
||||
email,
|
||||
setFieldError
|
||||
) => {
|
||||
try {
|
||||
const user: User = getData(LS_KEYS.USER);
|
||||
if (email === user.email) {
|
||||
setFieldError('email', constants.SHARE_WITH_SELF);
|
||||
setFieldError(constants.SHARE_WITH_SELF);
|
||||
} else if (
|
||||
collection?.sharees?.find((value) => value.email === email)
|
||||
) {
|
||||
setFieldError('email', constants.ALREADY_SHARED(email));
|
||||
setFieldError(constants.ALREADY_SHARED(email));
|
||||
} else {
|
||||
await shareCollection(collection, email);
|
||||
await sleep(2000);
|
||||
|
@ -27,7 +33,7 @@ export default function EmailShare({ collection }) {
|
|||
}
|
||||
} catch (e) {
|
||||
const errorMessage = handleSharingErrors(e);
|
||||
setFieldError('email', errorMessage);
|
||||
setFieldError(errorMessage);
|
||||
}
|
||||
};
|
||||
return (
|
||||
|
@ -41,6 +47,7 @@ export default function EmailShare({ collection }) {
|
|||
size: 'medium',
|
||||
sx: { mt: 1, mb: 2 },
|
||||
}}
|
||||
disableAutoFocus
|
||||
/>
|
||||
<CollectionShareSharees collection={collection} />
|
||||
</>
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import { DialogContent, DialogTitle, styled } from '@mui/material';
|
||||
import DialogBoxBase from 'components/DialogBox/base';
|
||||
import SingleInputForm from 'components/SingleInputForm';
|
||||
import { Dialog, Stack, Typography } from '@mui/material';
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from 'components/SingleInputForm';
|
||||
import React from 'react';
|
||||
import CryptoWorker from 'utils/crypto';
|
||||
import constants from 'utils/strings/constants';
|
||||
|
||||
const SetPublicLinkSetPasswordDialog = styled(DialogBoxBase)(({ theme }) => ({
|
||||
'& .MuiDialog-container': {
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
'& .MuiDialog-paper': {
|
||||
marginRight: theme.spacing(9),
|
||||
},
|
||||
}));
|
||||
|
||||
export function PublicLinkSetPassword({
|
||||
open,
|
||||
onClose,
|
||||
|
@ -22,13 +14,16 @@ export function PublicLinkSetPassword({
|
|||
updatePublicShareURLHelper,
|
||||
setChangePasswordView,
|
||||
}) {
|
||||
const savePassword = async (passphrase, setFieldError) => {
|
||||
const savePassword: SingleInputFormProps['callback'] = async (
|
||||
passphrase,
|
||||
setFieldError
|
||||
) => {
|
||||
if (passphrase && passphrase.trim().length >= 1) {
|
||||
await enablePublicUrlPassword(passphrase);
|
||||
setChangePasswordView(false);
|
||||
publicShareProp.passwordEnabled = true;
|
||||
} else {
|
||||
setFieldError('linkPassword', 'can not be empty');
|
||||
setFieldError('can not be empty');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -46,9 +41,17 @@ export function PublicLinkSetPassword({
|
|||
});
|
||||
};
|
||||
return (
|
||||
<SetPublicLinkSetPasswordDialog open={open} onClose={onClose}>
|
||||
<DialogTitle>{constants.PASSWORD_LOCK}</DialogTitle>
|
||||
<DialogContent>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
disablePortal
|
||||
BackdropProps={{ sx: { position: 'absolute' } }}
|
||||
sx={{ position: 'absolute' }}
|
||||
PaperProps={{ sx: { p: 1 } }}>
|
||||
<Stack spacing={3} p={1.5}>
|
||||
<Typography variant="h3" px={1} py={0.5} fontWeight={'bold'}>
|
||||
{constants.PASSWORD_LOCK}
|
||||
</Typography>
|
||||
<SingleInputForm
|
||||
callback={savePassword}
|
||||
placeholder={constants.RETURN_PASSPHRASE_HINT}
|
||||
|
@ -57,7 +60,7 @@ export function PublicLinkSetPassword({
|
|||
secondaryButtonAction={onClose}
|
||||
submitButtonProps={{ sx: { mt: 1, mb: 2 } }}
|
||||
/>
|
||||
</DialogContent>
|
||||
</SetPublicLinkSetPasswordDialog>
|
||||
</Stack>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ const ShareeRow = ({ sharee, collectionUnshare }: IProps) => {
|
|||
<SpaceBetweenFlex>
|
||||
{sharee.email}
|
||||
<OverflowMenu
|
||||
menuPaperProps={{
|
||||
sx: {
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.background.overPaper,
|
||||
},
|
||||
}}
|
||||
ariaControls={`email-share-${sharee.email}`}
|
||||
triggerButtonIcon={<MoreHorizIcon />}>
|
||||
<OverflowMenuOption
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import { IconButton, styled } from '@mui/material';
|
||||
import { IconButton, PaperProps, styled } from '@mui/material';
|
||||
import { OverflowMenuContext } from 'contexts/overflowMenu';
|
||||
|
||||
export interface Iprops {
|
||||
|
@ -8,6 +8,7 @@ export interface Iprops {
|
|||
triggerButtonProps?: any;
|
||||
children?: React.ReactNode;
|
||||
ariaControls: string;
|
||||
menuPaperProps?: Partial<PaperProps>;
|
||||
}
|
||||
|
||||
const StyledMenu = styled(Menu)`
|
||||
|
@ -27,6 +28,7 @@ export default function OverflowMenu({
|
|||
ariaControls,
|
||||
triggerButtonIcon,
|
||||
triggerButtonProps,
|
||||
menuPaperProps,
|
||||
}: Iprops) {
|
||||
const [sortByEl, setSortByEl] = useState(null);
|
||||
const handleClose = () => setSortByEl(null);
|
||||
|
@ -49,6 +51,7 @@ export default function OverflowMenu({
|
|||
disablePadding: true,
|
||||
'aria-labelledby': ariaControls,
|
||||
}}
|
||||
PaperProps={menuPaperProps}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
|
|
|
@ -10,7 +10,7 @@ interface IProps {
|
|||
|
||||
export default function HeaderSection({ closeSidebar }: IProps) {
|
||||
return (
|
||||
<SpaceBetweenFlex mt={0.5} mb={1} px={1.5}>
|
||||
<SpaceBetweenFlex mt={0.5} mb={1} pl={1.5}>
|
||||
<EnteLogo />
|
||||
<IconButton
|
||||
aria-label="close"
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface SingleInputFormProps {
|
|||
submitButtonProps?: any;
|
||||
initialValue?: string;
|
||||
secondaryButtonAction?: () => void;
|
||||
disableAutoFocus?: boolean;
|
||||
}
|
||||
|
||||
export default function SingleInputForm(props: SingleInputFormProps) {
|
||||
|
@ -90,7 +91,7 @@ export default function SingleInputForm(props: SingleInputFormProps) {
|
|||
error={Boolean(errors.inputValue)}
|
||||
helperText={errors.inputValue}
|
||||
disabled={loading}
|
||||
autoFocus
|
||||
autoFocus={!props.disableAutoFocus}
|
||||
InputProps={{
|
||||
endAdornment: props.fieldType === 'password' && (
|
||||
<ShowHidePassword
|
||||
|
|
|
@ -46,7 +46,7 @@ const ActivePlanButton = styled((props: ButtonProps) => (
|
|||
transition: 'transform .2s ease-in-out',
|
||||
},
|
||||
'&:hover .MuiButton-endIcon': {
|
||||
transform: 'translateX(10px)',
|
||||
transform: 'translateX(4px)',
|
||||
},
|
||||
}));
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ import CryptoWorker, {
|
|||
decryptAndStoreToken,
|
||||
SaveKeyInSessionStore,
|
||||
} from 'utils/crypto';
|
||||
import SingleInputForm from 'components/SingleInputForm';
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from 'components/SingleInputForm';
|
||||
import VerticallyCentered from 'components/Container';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { AppContext } from 'pages/_app';
|
||||
|
@ -52,7 +54,10 @@ export default function Recover() {
|
|||
appContext.showNavBar(true);
|
||||
}, []);
|
||||
|
||||
const recover = async (recoveryKey: string, setFieldError) => {
|
||||
const recover: SingleInputFormProps['callback'] = async (
|
||||
recoveryKey: string,
|
||||
setFieldError
|
||||
) => {
|
||||
try {
|
||||
// check if user is entering mnemonic recovery key
|
||||
if (recoveryKey.trim().indexOf(' ') > 0) {
|
||||
|
@ -74,7 +79,7 @@ export default function Recover() {
|
|||
router.push(PAGES.CHANGE_PASSWORD);
|
||||
} catch (e) {
|
||||
logError(e, 'password recovery failed');
|
||||
setFieldError('passphrase', constants.INCORRECT_RECOVERY_KEY);
|
||||
setFieldError(constants.INCORRECT_RECOVERY_KEY);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ import EnteSpinner from 'components/EnteSpinner';
|
|||
import CryptoWorker from 'utils/crypto';
|
||||
import { PAGES } from 'constants/pages';
|
||||
import { useRouter } from 'next/router';
|
||||
import SingleInputForm from 'components/SingleInputForm';
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from 'components/SingleInputForm';
|
||||
import { Card } from 'react-bootstrap';
|
||||
import { logError } from 'utils/sentry';
|
||||
import SharedAlbumNavbar from 'components/pages/sharedAlbum/Navbar';
|
||||
|
@ -211,7 +213,10 @@ export default function PublicCollectionGallery() {
|
|||
}
|
||||
};
|
||||
|
||||
const verifyLinkPassword = async (password, setFieldError) => {
|
||||
const verifyLinkPassword: SingleInputFormProps['callback'] = async (
|
||||
password,
|
||||
setFieldError
|
||||
) => {
|
||||
try {
|
||||
const cryptoWorker = await new CryptoWorker();
|
||||
let hashedPassword: string = null;
|
||||
|
@ -225,10 +230,7 @@ export default function PublicCollectionGallery() {
|
|||
);
|
||||
} catch (e) {
|
||||
logError(e, 'failed to derive key for verifyLinkPassword');
|
||||
setFieldError(
|
||||
'passphrase',
|
||||
`${constants.UNKNOWN_ERROR} ${e.message}`
|
||||
);
|
||||
setFieldError(`${constants.UNKNOWN_ERROR} ${e.message}`);
|
||||
return;
|
||||
}
|
||||
const collectionUID = getPublicCollectionUID(token.current);
|
||||
|
@ -242,7 +244,7 @@ export default function PublicCollectionGallery() {
|
|||
} catch (e) {
|
||||
const parsedError = parseSharingErrorCodes(e);
|
||||
if (parsedError.message === CustomError.TOKEN_EXPIRED) {
|
||||
setFieldError('passphrase', constants.INCORRECT_PASSPHRASE);
|
||||
setFieldError(constants.INCORRECT_PASSPHRASE);
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
|
@ -251,10 +253,7 @@ export default function PublicCollectionGallery() {
|
|||
appContext.finishLoading();
|
||||
} catch (e) {
|
||||
logError(e, 'failed to verifyLinkPassword');
|
||||
setFieldError(
|
||||
'passphrase',
|
||||
`${constants.UNKNOWN_ERROR} ${e.message}`
|
||||
);
|
||||
setFieldError(`${constants.UNKNOWN_ERROR} ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@ import constants from 'utils/strings/constants';
|
|||
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
|
||||
import { useRouter } from 'next/router';
|
||||
import CryptoWorker, { B64EncryptionResult } from 'utils/crypto';
|
||||
import SingleInputForm from 'components/SingleInputForm';
|
||||
import SingleInputForm, {
|
||||
SingleInputFormProps,
|
||||
} from 'components/SingleInputForm';
|
||||
import VerticallyCentered from 'components/Container';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { logError } from 'utils/sentry';
|
||||
|
@ -45,7 +47,10 @@ export default function Recover() {
|
|||
main();
|
||||
}, []);
|
||||
|
||||
const recover = async (recoveryKey: string, setFieldError) => {
|
||||
const recover: SingleInputFormProps['callback'] = async (
|
||||
recoveryKey: string,
|
||||
setFieldError
|
||||
) => {
|
||||
try {
|
||||
// check if user is entering mnemonic recovery key
|
||||
if (recoveryKey.trim().indexOf(' ') > 0) {
|
||||
|
@ -73,7 +78,7 @@ export default function Recover() {
|
|||
router.push(PAGES.CREDENTIALS);
|
||||
} catch (e) {
|
||||
logError(e, 'two factor recovery failed');
|
||||
setFieldError('passphrase', constants.INCORRECT_RECOVERY_KEY);
|
||||
setFieldError(constants.INCORRECT_RECOVERY_KEY);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@ import {
|
|||
} from '@mui/material/styles';
|
||||
|
||||
declare module '@mui/material/styles' {
|
||||
interface TypeBackground {
|
||||
overPaper?: string;
|
||||
}
|
||||
interface Palette {
|
||||
accent: PaletteColor;
|
||||
fill: PaletteColor;
|
||||
|
@ -84,16 +87,21 @@ const darkThemeOptions = createTheme({
|
|||
},
|
||||
},
|
||||
|
||||
MuiBackdrop: {
|
||||
MuiDrawer: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'.MuiBackdrop-root': {
|
||||
backgroundColor: 'rgba(0,0,0,0.65)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'.MuiBackdrop-root': {
|
||||
backgroundColor: 'rgba(0,0,0,0.65)',
|
||||
},
|
||||
'& .MuiDialog-paper': {
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.25)',
|
||||
},
|
||||
|
@ -275,7 +283,11 @@ const darkThemeOptions = createTheme({
|
|||
secondary: 'rgba(256,256,256,0.24)',
|
||||
disabled: 'rgba(256,256,256,0.16)',
|
||||
},
|
||||
background: { default: '#000000', paper: '#141414' },
|
||||
background: {
|
||||
default: '#000000',
|
||||
paper: '#141414',
|
||||
overPaper: '#1b1b1b',
|
||||
},
|
||||
grey: {
|
||||
A100: '#ccc',
|
||||
A200: 'rgba(256, 256, 256, 0.24)',
|
||||
|
|
|
@ -55,6 +55,9 @@ export function makeHumanReadableStorage(
|
|||
bytes: number,
|
||||
round: 'round-up' | 'round-down' = 'round-down'
|
||||
): string {
|
||||
if (bytes === 0) {
|
||||
return '0 MB';
|
||||
}
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
|
||||
let quantity = bytes / Math.pow(1024, i);
|
||||
|
|
Loading…
Reference in a new issue