Merge pull request #636 from ente-io/fix-minor-issues

Fix minor issues
This commit is contained in:
Manav 2022-07-06 16:04:21 +05:30 committed by GitHub
commit 3ee1bb06c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 101 additions and 48 deletions

View file

@ -7,6 +7,7 @@ import OverflowMenu from 'components/OverflowMenu/menu';
export interface CollectionSortProps { export interface CollectionSortProps {
setCollectionSortBy: (sortBy: COLLECTION_SORT_BY) => void; setCollectionSortBy: (sortBy: COLLECTION_SORT_BY) => void;
activeSortBy: COLLECTION_SORT_BY; activeSortBy: COLLECTION_SORT_BY;
nestedInDialog?: boolean;
disableBG?: boolean; disableBG?: boolean;
} }
@ -15,6 +16,13 @@ export default function CollectionSort(props: CollectionSortProps) {
<OverflowMenu <OverflowMenu
ariaControls="collection-sort" ariaControls="collection-sort"
triggerButtonIcon={<SortIcon />} triggerButtonIcon={<SortIcon />}
menuPaperProps={{
sx: {
backgroundColor: (theme) =>
props.nestedInDialog &&
theme.palette.background.overPaper,
},
}}
triggerButtonProps={{ triggerButtonProps={{
sx: { sx: {
background: (theme) => background: (theme) =>

View file

@ -32,6 +32,7 @@ export default function AllCollectionsHeader({
<CollectionSort <CollectionSort
activeSortBy={collectionSortBy} activeSortBy={collectionSortBy}
setCollectionSortBy={setCollectionSortBy} setCollectionSortBy={setCollectionSortBy}
nestedInDialog
/> />
<IconButtonWithBG onClick={onClose}> <IconButtonWithBG onClick={onClose}>
<Close /> <Close />

View file

@ -1,4 +1,6 @@
import SingleInputForm from 'components/SingleInputForm'; import SingleInputForm, {
SingleInputFormProps,
} from 'components/SingleInputForm';
import { GalleryContext } from 'pages/gallery'; import { GalleryContext } from 'pages/gallery';
import React, { useContext } from 'react'; import React, { useContext } from 'react';
import { shareCollection } from 'services/collectionService'; import { shareCollection } from 'services/collectionService';
@ -8,18 +10,22 @@ import { handleSharingErrors } from 'utils/error';
import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { getData, LS_KEYS } from 'utils/storage/localStorage';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import { CollectionShareSharees } from './sharees'; import { CollectionShareSharees } from './sharees';
export default function EmailShare({ collection }) { export default function EmailShare({ collection }) {
const galleryContext = useContext(GalleryContext); const galleryContext = useContext(GalleryContext);
const collectionShare = async (email, setFieldError) => { const collectionShare: SingleInputFormProps['callback'] = async (
email,
setFieldError
) => {
try { try {
const user: User = getData(LS_KEYS.USER); const user: User = getData(LS_KEYS.USER);
if (email === user.email) { if (email === user.email) {
setFieldError('email', constants.SHARE_WITH_SELF); setFieldError(constants.SHARE_WITH_SELF);
} else if ( } else if (
collection?.sharees?.find((value) => value.email === email) collection?.sharees?.find((value) => value.email === email)
) { ) {
setFieldError('email', constants.ALREADY_SHARED(email)); setFieldError(constants.ALREADY_SHARED(email));
} else { } else {
await shareCollection(collection, email); await shareCollection(collection, email);
await sleep(2000); await sleep(2000);
@ -27,7 +33,7 @@ export default function EmailShare({ collection }) {
} }
} catch (e) { } catch (e) {
const errorMessage = handleSharingErrors(e); const errorMessage = handleSharingErrors(e);
setFieldError('email', errorMessage); setFieldError(errorMessage);
} }
}; };
return ( return (
@ -41,6 +47,7 @@ export default function EmailShare({ collection }) {
size: 'medium', size: 'medium',
sx: { mt: 1, mb: 2 }, sx: { mt: 1, mb: 2 },
}} }}
disableAutoFocus
/> />
<CollectionShareSharees collection={collection} /> <CollectionShareSharees collection={collection} />
</> </>

View file

@ -1,19 +1,11 @@
import { DialogContent, DialogTitle, styled } from '@mui/material'; import { Dialog, Stack, Typography } from '@mui/material';
import DialogBoxBase from 'components/DialogBox/base'; import SingleInputForm, {
import SingleInputForm from 'components/SingleInputForm'; SingleInputFormProps,
} from 'components/SingleInputForm';
import React from 'react'; import React from 'react';
import CryptoWorker from 'utils/crypto'; import CryptoWorker from 'utils/crypto';
import constants from 'utils/strings/constants'; 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({ export function PublicLinkSetPassword({
open, open,
onClose, onClose,
@ -22,13 +14,16 @@ export function PublicLinkSetPassword({
updatePublicShareURLHelper, updatePublicShareURLHelper,
setChangePasswordView, setChangePasswordView,
}) { }) {
const savePassword = async (passphrase, setFieldError) => { const savePassword: SingleInputFormProps['callback'] = async (
passphrase,
setFieldError
) => {
if (passphrase && passphrase.trim().length >= 1) { if (passphrase && passphrase.trim().length >= 1) {
await enablePublicUrlPassword(passphrase); await enablePublicUrlPassword(passphrase);
setChangePasswordView(false); setChangePasswordView(false);
publicShareProp.passwordEnabled = true; publicShareProp.passwordEnabled = true;
} else { } else {
setFieldError('linkPassword', 'can not be empty'); setFieldError('can not be empty');
} }
}; };
@ -46,9 +41,17 @@ export function PublicLinkSetPassword({
}); });
}; };
return ( return (
<SetPublicLinkSetPasswordDialog open={open} onClose={onClose}> <Dialog
<DialogTitle>{constants.PASSWORD_LOCK}</DialogTitle> open={open}
<DialogContent> 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 <SingleInputForm
callback={savePassword} callback={savePassword}
placeholder={constants.RETURN_PASSPHRASE_HINT} placeholder={constants.RETURN_PASSPHRASE_HINT}
@ -57,7 +60,7 @@ export function PublicLinkSetPassword({
secondaryButtonAction={onClose} secondaryButtonAction={onClose}
submitButtonProps={{ sx: { mt: 1, mb: 2 } }} submitButtonProps={{ sx: { mt: 1, mb: 2 } }}
/> />
</DialogContent> </Stack>
</SetPublicLinkSetPasswordDialog> </Dialog>
); );
} }

View file

@ -18,6 +18,12 @@ const ShareeRow = ({ sharee, collectionUnshare }: IProps) => {
<SpaceBetweenFlex> <SpaceBetweenFlex>
{sharee.email} {sharee.email}
<OverflowMenu <OverflowMenu
menuPaperProps={{
sx: {
backgroundColor: (theme) =>
theme.palette.background.overPaper,
},
}}
ariaControls={`email-share-${sharee.email}`} ariaControls={`email-share-${sharee.email}`}
triggerButtonIcon={<MoreHorizIcon />}> triggerButtonIcon={<MoreHorizIcon />}>
<OverflowMenuOption <OverflowMenuOption

View file

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import Menu from '@mui/material/Menu'; import Menu from '@mui/material/Menu';
import { IconButton, styled } from '@mui/material'; import { IconButton, PaperProps, styled } from '@mui/material';
import { OverflowMenuContext } from 'contexts/overflowMenu'; import { OverflowMenuContext } from 'contexts/overflowMenu';
export interface Iprops { export interface Iprops {
@ -8,6 +8,7 @@ export interface Iprops {
triggerButtonProps?: any; triggerButtonProps?: any;
children?: React.ReactNode; children?: React.ReactNode;
ariaControls: string; ariaControls: string;
menuPaperProps?: Partial<PaperProps>;
} }
const StyledMenu = styled(Menu)` const StyledMenu = styled(Menu)`
@ -27,6 +28,7 @@ export default function OverflowMenu({
ariaControls, ariaControls,
triggerButtonIcon, triggerButtonIcon,
triggerButtonProps, triggerButtonProps,
menuPaperProps,
}: Iprops) { }: Iprops) {
const [sortByEl, setSortByEl] = useState(null); const [sortByEl, setSortByEl] = useState(null);
const handleClose = () => setSortByEl(null); const handleClose = () => setSortByEl(null);
@ -49,6 +51,7 @@ export default function OverflowMenu({
disablePadding: true, disablePadding: true,
'aria-labelledby': ariaControls, 'aria-labelledby': ariaControls,
}} }}
PaperProps={menuPaperProps}
anchorOrigin={{ anchorOrigin={{
vertical: 'bottom', vertical: 'bottom',
horizontal: 'right', horizontal: 'right',

View file

@ -10,7 +10,7 @@ interface IProps {
export default function HeaderSection({ closeSidebar }: IProps) { export default function HeaderSection({ closeSidebar }: IProps) {
return ( return (
<SpaceBetweenFlex mt={0.5} mb={1} px={1.5}> <SpaceBetweenFlex mt={0.5} mb={1} pl={1.5}>
<EnteLogo /> <EnteLogo />
<IconButton <IconButton
aria-label="close" aria-label="close"

View file

@ -22,6 +22,7 @@ export interface SingleInputFormProps {
submitButtonProps?: any; submitButtonProps?: any;
initialValue?: string; initialValue?: string;
secondaryButtonAction?: () => void; secondaryButtonAction?: () => void;
disableAutoFocus?: boolean;
} }
export default function SingleInputForm(props: SingleInputFormProps) { export default function SingleInputForm(props: SingleInputFormProps) {
@ -90,7 +91,7 @@ export default function SingleInputForm(props: SingleInputFormProps) {
error={Boolean(errors.inputValue)} error={Boolean(errors.inputValue)}
helperText={errors.inputValue} helperText={errors.inputValue}
disabled={loading} disabled={loading}
autoFocus autoFocus={!props.disableAutoFocus}
InputProps={{ InputProps={{
endAdornment: props.fieldType === 'password' && ( endAdornment: props.fieldType === 'password' && (
<ShowHidePassword <ShowHidePassword

View file

@ -46,7 +46,7 @@ const ActivePlanButton = styled((props: ButtonProps) => (
transition: 'transform .2s ease-in-out', transition: 'transform .2s ease-in-out',
}, },
'&:hover .MuiButton-endIcon': { '&:hover .MuiButton-endIcon': {
transform: 'translateX(10px)', transform: 'translateX(4px)',
}, },
})); }));

View file

@ -12,7 +12,9 @@ import CryptoWorker, {
decryptAndStoreToken, decryptAndStoreToken,
SaveKeyInSessionStore, SaveKeyInSessionStore,
} from 'utils/crypto'; } from 'utils/crypto';
import SingleInputForm from 'components/SingleInputForm'; import SingleInputForm, {
SingleInputFormProps,
} from 'components/SingleInputForm';
import VerticallyCentered from 'components/Container'; import VerticallyCentered from 'components/Container';
import { Button } from 'react-bootstrap'; import { Button } from 'react-bootstrap';
import { AppContext } from 'pages/_app'; import { AppContext } from 'pages/_app';
@ -52,7 +54,10 @@ export default function Recover() {
appContext.showNavBar(true); appContext.showNavBar(true);
}, []); }, []);
const recover = async (recoveryKey: string, setFieldError) => { const recover: SingleInputFormProps['callback'] = async (
recoveryKey: string,
setFieldError
) => {
try { try {
// check if user is entering mnemonic recovery key // check if user is entering mnemonic recovery key
if (recoveryKey.trim().indexOf(' ') > 0) { if (recoveryKey.trim().indexOf(' ') > 0) {
@ -74,7 +79,7 @@ export default function Recover() {
router.push(PAGES.CHANGE_PASSWORD); router.push(PAGES.CHANGE_PASSWORD);
} catch (e) { } catch (e) {
logError(e, 'password recovery failed'); logError(e, 'password recovery failed');
setFieldError('passphrase', constants.INCORRECT_RECOVERY_KEY); setFieldError(constants.INCORRECT_RECOVERY_KEY);
} }
}; };

View file

@ -29,7 +29,9 @@ import EnteSpinner from 'components/EnteSpinner';
import CryptoWorker from 'utils/crypto'; import CryptoWorker from 'utils/crypto';
import { PAGES } from 'constants/pages'; import { PAGES } from 'constants/pages';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import SingleInputForm from 'components/SingleInputForm'; import SingleInputForm, {
SingleInputFormProps,
} from 'components/SingleInputForm';
import { Card } from 'react-bootstrap'; import { Card } from 'react-bootstrap';
import { logError } from 'utils/sentry'; import { logError } from 'utils/sentry';
import SharedAlbumNavbar from 'components/pages/sharedAlbum/Navbar'; 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 { try {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await new CryptoWorker();
let hashedPassword: string = null; let hashedPassword: string = null;
@ -225,10 +230,7 @@ export default function PublicCollectionGallery() {
); );
} catch (e) { } catch (e) {
logError(e, 'failed to derive key for verifyLinkPassword'); logError(e, 'failed to derive key for verifyLinkPassword');
setFieldError( setFieldError(`${constants.UNKNOWN_ERROR} ${e.message}`);
'passphrase',
`${constants.UNKNOWN_ERROR} ${e.message}`
);
return; return;
} }
const collectionUID = getPublicCollectionUID(token.current); const collectionUID = getPublicCollectionUID(token.current);
@ -242,7 +244,7 @@ export default function PublicCollectionGallery() {
} catch (e) { } catch (e) {
const parsedError = parseSharingErrorCodes(e); const parsedError = parseSharingErrorCodes(e);
if (parsedError.message === CustomError.TOKEN_EXPIRED) { if (parsedError.message === CustomError.TOKEN_EXPIRED) {
setFieldError('passphrase', constants.INCORRECT_PASSPHRASE); setFieldError(constants.INCORRECT_PASSPHRASE);
return; return;
} }
throw e; throw e;
@ -251,10 +253,7 @@ export default function PublicCollectionGallery() {
appContext.finishLoading(); appContext.finishLoading();
} catch (e) { } catch (e) {
logError(e, 'failed to verifyLinkPassword'); logError(e, 'failed to verifyLinkPassword');
setFieldError( setFieldError(`${constants.UNKNOWN_ERROR} ${e.message}`);
'passphrase',
`${constants.UNKNOWN_ERROR} ${e.message}`
);
} }
}; };

View file

@ -3,7 +3,9 @@ import constants from 'utils/strings/constants';
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import CryptoWorker, { B64EncryptionResult } from 'utils/crypto'; import CryptoWorker, { B64EncryptionResult } from 'utils/crypto';
import SingleInputForm from 'components/SingleInputForm'; import SingleInputForm, {
SingleInputFormProps,
} from 'components/SingleInputForm';
import VerticallyCentered from 'components/Container'; import VerticallyCentered from 'components/Container';
import { Button } from 'react-bootstrap'; import { Button } from 'react-bootstrap';
import { logError } from 'utils/sentry'; import { logError } from 'utils/sentry';
@ -45,7 +47,10 @@ export default function Recover() {
main(); main();
}, []); }, []);
const recover = async (recoveryKey: string, setFieldError) => { const recover: SingleInputFormProps['callback'] = async (
recoveryKey: string,
setFieldError
) => {
try { try {
// check if user is entering mnemonic recovery key // check if user is entering mnemonic recovery key
if (recoveryKey.trim().indexOf(' ') > 0) { if (recoveryKey.trim().indexOf(' ') > 0) {
@ -73,7 +78,7 @@ export default function Recover() {
router.push(PAGES.CREDENTIALS); router.push(PAGES.CREDENTIALS);
} catch (e) { } catch (e) {
logError(e, 'two factor recovery failed'); logError(e, 'two factor recovery failed');
setFieldError('passphrase', constants.INCORRECT_RECOVERY_KEY); setFieldError(constants.INCORRECT_RECOVERY_KEY);
} }
}; };

View file

@ -6,6 +6,9 @@ import {
} from '@mui/material/styles'; } from '@mui/material/styles';
declare module '@mui/material/styles' { declare module '@mui/material/styles' {
interface TypeBackground {
overPaper?: string;
}
interface Palette { interface Palette {
accent: PaletteColor; accent: PaletteColor;
fill: PaletteColor; fill: PaletteColor;
@ -84,16 +87,21 @@ const darkThemeOptions = createTheme({
}, },
}, },
MuiBackdrop: { MuiDrawer: {
styleOverrides: { styleOverrides: {
root: { root: {
'.MuiBackdrop-root': {
backgroundColor: 'rgba(0,0,0,0.65)', backgroundColor: 'rgba(0,0,0,0.65)',
}, },
}, },
}, },
},
MuiDialog: { MuiDialog: {
styleOverrides: { styleOverrides: {
root: { root: {
'.MuiBackdrop-root': {
backgroundColor: 'rgba(0,0,0,0.65)',
},
'& .MuiDialog-paper': { '& .MuiDialog-paper': {
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.25)', 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)', secondary: 'rgba(256,256,256,0.24)',
disabled: 'rgba(256,256,256,0.16)', disabled: 'rgba(256,256,256,0.16)',
}, },
background: { default: '#000000', paper: '#141414' }, background: {
default: '#000000',
paper: '#141414',
overPaper: '#1b1b1b',
},
grey: { grey: {
A100: '#ccc', A100: '#ccc',
A200: 'rgba(256, 256, 256, 0.24)', A200: 'rgba(256, 256, 256, 0.24)',

View file

@ -55,6 +55,9 @@ export function makeHumanReadableStorage(
bytes: number, bytes: number,
round: 'round-up' | 'round-down' = 'round-down' round: 'round-up' | 'round-down' = 'round-down'
): string { ): string {
if (bytes === 0) {
return '0 MB';
}
const i = Math.floor(Math.log(bytes) / Math.log(1024)); const i = Math.floor(Math.log(bytes) / Math.log(1024));
let quantity = bytes / Math.pow(1024, i); let quantity = bytes / Math.pow(1024, i);