update notification ui
This commit is contained in:
parent
abb2270745
commit
b9b4a9b617
94
src/components/Notification.tsx
Normal file
94
src/components/Notification.tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
IconButton,
|
||||
Paper,
|
||||
Snackbar,
|
||||
SnackbarProps,
|
||||
Stack,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import React from 'react';
|
||||
import { NotificationAttributes } from 'types/gallery';
|
||||
|
||||
import DiscFullIcon from '@mui/icons-material/DiscFull';
|
||||
|
||||
interface Iprops {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
attributes: NotificationAttributes;
|
||||
}
|
||||
|
||||
export default function Notification({ open, onClose, attributes }: Iprops) {
|
||||
if (!attributes) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const handleClose: SnackbarProps['onClose'] = (_, reason) => {
|
||||
if (!reason) {
|
||||
onClose;
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
attributes.action?.callback();
|
||||
};
|
||||
return (
|
||||
<Snackbar
|
||||
onClose={handleClose}
|
||||
open={open}
|
||||
anchorOrigin={{
|
||||
horizontal: 'right',
|
||||
vertical: 'bottom',
|
||||
}}>
|
||||
<Paper
|
||||
component={Button}
|
||||
color={attributes.variant}
|
||||
onClick={handleClick}
|
||||
css={`
|
||||
width: 320px;
|
||||
padding: 12px 16px;
|
||||
`}
|
||||
sx={{ textAlign: 'left' }}>
|
||||
<Stack
|
||||
flex={'1'}
|
||||
spacing={2}
|
||||
direction="row"
|
||||
alignItems={'center'}>
|
||||
<Box>
|
||||
<DiscFullIcon fontSize="large" />
|
||||
</Box>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="rgba(255, 255, 255, 0.7)"
|
||||
mb={0.5}>
|
||||
{attributes.message}{' '}
|
||||
</Typography>
|
||||
{attributes?.action && (
|
||||
<Typography
|
||||
mb={0.5}
|
||||
css={`
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 19px;
|
||||
`}>
|
||||
{attributes?.action.text}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
<Box>
|
||||
<IconButton
|
||||
onClick={onClose}
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
||||
}}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Snackbar>
|
||||
);
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Toast } from 'react-bootstrap';
|
||||
import styled from 'styled-components';
|
||||
import { NotificationAttributes } from 'types/gallery';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
right: 10px;
|
||||
z-index: 1501;
|
||||
min-height: 100px;
|
||||
`;
|
||||
const AUTO_HIDE_TIME_IN_MILLISECONDS = 3000;
|
||||
|
||||
interface Iprops {
|
||||
attributes: NotificationAttributes;
|
||||
clearAttributes: () => void;
|
||||
}
|
||||
|
||||
export default function ToastNotification({
|
||||
attributes,
|
||||
clearAttributes,
|
||||
}: Iprops) {
|
||||
const [show, setShow] = useState(false);
|
||||
const closeToast = () => {
|
||||
setShow(false);
|
||||
clearAttributes();
|
||||
};
|
||||
useEffect(() => {
|
||||
if (!attributes) {
|
||||
setShow(false);
|
||||
} else {
|
||||
setShow(true);
|
||||
}
|
||||
}, [attributes]);
|
||||
return (
|
||||
<Wrapper>
|
||||
<Toast
|
||||
onClose={closeToast}
|
||||
show={show}
|
||||
delay={AUTO_HIDE_TIME_IN_MILLISECONDS}
|
||||
autohide>
|
||||
{attributes?.title && (
|
||||
<Toast.Header
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}>
|
||||
<h6 style={{ marginBottom: 0 }}>{attributes.title} </h6>
|
||||
</Toast.Header>
|
||||
)}
|
||||
{attributes?.message && (
|
||||
<Toast.Body>{attributes.message}</Toast.Body>
|
||||
)}
|
||||
</Toast>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
|
@ -102,7 +102,7 @@ import {
|
|||
NotificationAttributes,
|
||||
} from 'types/gallery';
|
||||
import { VISIBILITY_STATE } from 'types/magicMetadata';
|
||||
import ToastNotification from 'components/ToastNotification';
|
||||
import Notification from 'components/Notification';
|
||||
import { ElectronFile } from 'types/upload';
|
||||
import importService from 'services/importService';
|
||||
import Collections from 'components/Collections';
|
||||
|
@ -147,9 +147,7 @@ export default function Gallery() {
|
|||
|
||||
const [files, setFiles] = useState<EnteFile[]>(null);
|
||||
const [favItemIds, setFavItemIds] = useState<Set<number>>();
|
||||
const [bannerMessage, setBannerMessage] = useState<JSX.Element | string>(
|
||||
null
|
||||
);
|
||||
const [bannerMessage, setBannerMessage] = useState<JSX.Element | string>();
|
||||
const [isFirstLoad, setIsFirstLoad] = useState(false);
|
||||
const [isFirstFetch, setIsFirstFetch] = useState(false);
|
||||
const [selected, setSelected] = useState<SelectedState>({
|
||||
|
@ -194,6 +192,10 @@ export default function Gallery() {
|
|||
const [fixCreationTimeAttributes, setFixCreationTimeAttributes] =
|
||||
useState<FixCreationTimeAttributes>(null);
|
||||
|
||||
const [notificationView, setNotificationView] = useState(false);
|
||||
|
||||
const closeNotification = () => setNotificationView(false);
|
||||
|
||||
const [notificationAttributes, setNotificationAttributes] =
|
||||
useState<NotificationAttributes>(null);
|
||||
|
||||
|
@ -202,8 +204,6 @@ export default function Gallery() {
|
|||
|
||||
const showPlanSelectorModal = () => setPlanModalView(true);
|
||||
|
||||
const clearNotificationAttributes = () => setNotificationAttributes(null);
|
||||
|
||||
const [electronFiles, setElectronFiles] = useState<ElectronFile[]>(null);
|
||||
const [uploadTypeSelectorView, setUploadTypeSelectorView] = useState(false);
|
||||
|
||||
|
@ -259,6 +259,11 @@ export default function Gallery() {
|
|||
[fixCreationTimeAttributes]
|
||||
);
|
||||
|
||||
useEffect(
|
||||
() => notificationAttributes && setNotificationView(true),
|
||||
[notificationAttributes]
|
||||
);
|
||||
|
||||
useEffect(() => setDroppedFiles(acceptedFiles), [acceptedFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -602,9 +607,10 @@ export default function Gallery() {
|
|||
setLoading={setBlockingLoad}
|
||||
/>
|
||||
<AlertBanner bannerMessage={bannerMessage} />
|
||||
<ToastNotification
|
||||
<Notification
|
||||
open={notificationView}
|
||||
onClose={closeNotification}
|
||||
attributes={notificationAttributes}
|
||||
clearAttributes={clearNotificationAttributes}
|
||||
/>
|
||||
<CollectionNamer
|
||||
show={collectionNamerView}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { ButtonProps } from '@mui/material';
|
||||
import { Collection } from 'types/collection';
|
||||
import { EnteFile } from 'types/file';
|
||||
import { Search, SearchResultSummary } from 'types/search';
|
||||
|
@ -28,6 +29,10 @@ export type GalleryContextType = {
|
|||
};
|
||||
|
||||
export interface NotificationAttributes {
|
||||
message: string;
|
||||
title: string;
|
||||
variant: ButtonProps['color'];
|
||||
message: JSX.Element | string;
|
||||
action?: {
|
||||
text: string;
|
||||
callback: () => void;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue