diff --git a/docs/notifications.json b/docs/notifications.json index 5c73430660c062..b017e3209c7ab9 100644 --- a/docs/notifications.json +++ b/docs/notifications.json @@ -1,15 +1,20 @@ [ - { - "id": 27, - "text": "You can follow us on Twitter to receive exclusive tips and updates about Material-UI and the React ecosystem." - }, { "id": 35, - "text": "Let's translate! 帮助 Material-UI 将文档翻译成中文. 🇨🇳", + "title": "Let's translate!", + "text": "帮助 Material-UI 将文档翻译成中文. 🇨🇳", "userLanguage": "zh" }, + { + "id": 47, + "date": "2020-01-25", + "title": "New blog post", + "text": "2019 in review and beyond. 2019 was a great year for Material-UI. It puts us on an exciting path to solve even greater challenges in the coming years!" + }, { "id": 48, - "text": "Material-UI is hiring a senior software developer." + "date": "2020-02-08", + "title": "Material-UI is hiring", + "text": "We're looking for a senior software developer to join the team." } -] +] \ No newline at end of file diff --git a/docs/src/modules/components/AppFrame.js b/docs/src/modules/components/AppFrame.js index b9beb7520cbc44..304fc23609a2a5 100644 --- a/docs/src/modules/components/AppFrame.js +++ b/docs/src/modules/components/AppFrame.js @@ -204,7 +204,6 @@ function AppFrame(props) { {t('skipToContent')} - @@ -320,6 +319,7 @@ function AppFrame(props) { )} + ({ + paper: { + transformOrigin: 'top right', + }, + list: { + maxWidth: theme.spacing(40), + maxHeight: theme.spacing(40), + overflow: 'auto', + }, + listItem: { + display: 'flex', + flexDirection: 'column', + }, +})); function getLastSeenNotification() { const seen = getCookie('lastSeenNotification'); @@ -15,6 +41,10 @@ function getLastSeenNotification() { let messages = null; +if (process.env.NODE_ENV !== 'production') { + messages = notifications; +} + async function getMessages() { try { if (!messages) { @@ -32,43 +62,58 @@ async function getMessages() { } export default function Notifications() { + const classes = useStyles(); + const [messageList, setMessageList] = React.useState([]); + const [unseenNotificationsCount, setUnseenNotificationsCount] = React.useState(0); const [open, setOpen] = React.useState(false); - const [message, setMessage] = React.useState({}); - const { route } = useRouter(); + const [tooltipOpen, setTooltipOpen] = React.useState(false); + const anchorRef = React.useRef(null); const t = useSelector(state => state.options.t); const userLanguage = useSelector(state => state.options.userLanguage); + const handleToggle = () => { + setOpen(prevOpen => !prevOpen); + setTooltipOpen(false); + setUnseenNotificationsCount(0); + document.cookie = `lastSeenNotification=${messageList[0].id};path=/;max-age=31536000`; + }; + + const handleClose = () => { + setOpen(false); + }; + + const handleTooltipOpen = () => { + setTooltipOpen(!open); + }; + + const handleTooltipClose = () => { + setTooltipOpen(false); + }; + const handleMessage = () => { const lastSeen = getLastSeenNotification(); - const unseenMessages = messages.filter(message2 => { - if (message2.id <= lastSeen) { - return false; - } + const userMessages = messages.filter(message => { if ( - message2.userLanguage && - message2.userLanguage !== userLanguage && - message2.userLanguage !== navigator.language.substring(0, 2) + message.userLanguage && + message.userLanguage !== userLanguage && + message.userLanguage !== navigator.language.substring(0, 2) ) { return false; } - - if (message2.route && message2.route !== route) { - return false; - } - return true; }); - if (unseenMessages.length > 0) { - setMessage(unseenMessages[0]); - setOpen(true); + const unseenCount = userMessages.reduce( + (count, message) => (message.id > lastSeen ? count + 1 : count), + 0, + ); + + if (unseenCount > 0) { + setUnseenNotificationsCount(unseenCount); } - }; - const handleClose = () => { - setOpen(false); - document.cookie = `lastSeenNotification=${message.id};path=/;max-age=31536000`; + setMessageList(userMessages.reverse()); }; React.useEffect(() => { @@ -89,25 +134,78 @@ export default function Notifications() { return () => { active = false; }; - }, [route]); + }, []); return ( - - } - action={ - - } - open={open} - autoHideDuration={20e3} - onClose={handleClose} - onExited={handleMessage} - /> + + + + + + + + + + {({ TransitionProps }) => ( + + + + + {messageList.map((message, index) => ( + + + {message.date && ( + + )} + + } + secondaryTypographyProps={{ color: 'textPrimary' }} + /> + + {index < messageList.length - 1 ? : null} + + ))} + + + + + )} + + ); } diff --git a/docs/translations/translations.json b/docs/translations/translations.json index 00557e6e00826c..5c4e040134862a 100644 --- a/docs/translations/translations.json +++ b/docs/translations/translations.json @@ -5,6 +5,7 @@ "useDarkTheme": "Use dark theme", "toggleTheme": "Toggle light/dark theme", "toggleRTL": "Toggle right-to-left/left-to-right", + "toggleNotifications": "Toggle notifications panel", "github": "GitHub repository", "strapline": "React components for faster and easier web development. Build your own design system, or start with Material Design.", "getStarted": "Get Started",