diff --git a/.flowconfig b/.flowconfig index a399c31e8..4870244e1 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,5 +1,6 @@ [ignore] .*\.typeface\.json +.*/node_modules/findup/.* [include] diff --git a/flow-typed/notification.js b/flow-typed/notification.js index 5d1f3f2ba..f3ccfd49f 100644 --- a/flow-typed/notification.js +++ b/flow-typed/notification.js @@ -21,6 +21,8 @@ declare type WebNotification = { }, dynamic: { comment_author: string, + hash: string, + claim_title: string, }, email: {}, }, @@ -28,4 +30,5 @@ declare type WebNotification = { type: string, updated_at: string, user_id: number, + group_count?: number, }; diff --git a/ui/component/notification/view.jsx b/ui/component/notification/view.jsx index ce4e04e33..c6cd177d3 100644 --- a/ui/component/notification/view.jsx +++ b/ui/component/notification/view.jsx @@ -1,4 +1,6 @@ // @flow + +import { NOTIFICATION_CREATOR_SUBSCRIBER, NOTIFICATION_COMMENT } from 'constants/notifications'; import * as ICONS from 'constants/icons'; import React from 'react'; import Icon from 'component/common/icon'; @@ -14,14 +16,14 @@ type Props = { children: any, }; -const NOTIFICATION_CREATOR_SUBSCRIBER = 'creator_subscriber'; -const NOTIFICATION_COMMENT = 'comment'; - export default function Notification(props: Props) { const { notification, menuButton = false } = props; - const notificationTarget = notification && notification.notification_parameters.device.target; - const notificationLink = formatLbryUrlForWeb(notificationTarget); const { push } = useHistory(); + const notificationTarget = notification && notification.notification_parameters.device.target; + let notificationLink = formatLbryUrlForWeb(notificationTarget); + if (notification.notification_rule === NOTIFICATION_COMMENT && notification.notification_parameters.dynamic.hash) { + notificationLink += `?lc=${notification.notification_parameters.dynamic.hash}`; + } let icon; switch (notification.notification_rule) { @@ -29,7 +31,7 @@ export default function Notification(props: Props) { icon = ; break; case NOTIFICATION_COMMENT: - icon = ; + icon = ; break; default: icon = ; @@ -52,8 +54,20 @@ export default function Notification(props: Props) {
{icon}
-
{notification.notification_parameters.device.title}
-
{notification.notification_parameters.device.text}
+
+ {notification.notification_rule !== NOTIFICATION_COMMENT && ( +
{notification.notification_parameters.device.title}
+ )} + +
+ {notification.notification_parameters.device.text.replace( + // This is terrible and will be replaced when I make the comment channel clickable + 'commented on', + notification.group_count ? `left ${notification.group_count} comments on` : 'commented on' + )} +
+
+
diff --git a/ui/constants/notifications.js b/ui/constants/notifications.js new file mode 100644 index 000000000..f11d20a7b --- /dev/null +++ b/ui/constants/notifications.js @@ -0,0 +1,2 @@ +export const NOTIFICATION_CREATOR_SUBSCRIBER = 'creator_subscriber'; +export const NOTIFICATION_COMMENT = 'comment'; diff --git a/ui/page/notifications/view.jsx b/ui/page/notifications/view.jsx index fd2517689..dbe52e000 100644 --- a/ui/page/notifications/view.jsx +++ b/ui/page/notifications/view.jsx @@ -1,4 +1,5 @@ // @flow +import { NOTIFICATION_COMMENT } from 'constants/notifications'; import React from 'react'; import Page from 'component/page'; import Card from 'component/common/card'; @@ -13,6 +14,51 @@ type Props = { export default function NotificationsPage(props: Props) { const { notifications, fetching } = props; + // Group sequential comment notifications if they are by the same author + let groupedCount = 1; + const groupedNotifications = + notifications && + notifications.reduce((list, notification, index) => { + if (index === 0) { + return [notification]; + } + + const previousNotification = notifications[index - 1]; + const isCommentNotification = notification.notification_rule === NOTIFICATION_COMMENT; + const previousIsCommentNotification = previousNotification.notification_rule === NOTIFICATION_COMMENT; + if (isCommentNotification && previousIsCommentNotification) { + const notificationTarget = notification.notification_parameters.device.target; + const previousTarget = previousNotification && previousNotification.notification_parameters.device.target; + const author = notification.notification_parameters.dynamic.comment_author; + const previousAuthor = previousNotification.notification_parameters.dynamic.comment_author; + + if (author === previousAuthor && notificationTarget === previousTarget) { + const newList = [...list]; + newList.pop(); + groupedCount += 1; + const newNotification = { + ...previousNotification, + group_count: groupedCount, + }; + + newList[index - groupedCount] = newNotification; + return newList; + } else { + if (groupedCount > 1) { + groupedCount = 1; + } + + return [...list, notification]; + } + } else { + if (groupedCount > 1) { + groupedCount = 1; + } + + return [...list, notification]; + } + }, []); + return ( {fetching && ( @@ -20,13 +66,17 @@ export default function NotificationsPage(props: Props) {
)} - {notifications && notifications.length > 0 ? ( + {groupedNotifications && groupedNotifications.length > 0 ? ( - {notifications.map((notification, index) => { + {groupedNotifications.map((notification, index) => { + if (!notification) { + return null; + } + return ; })}
diff --git a/ui/scss/component/_notification.scss b/ui/scss/component/_notification.scss index 23a4e890a..66f71e858 100644 --- a/ui/scss/component/_notification.scss +++ b/ui/scss/component/_notification.scss @@ -13,25 +13,41 @@ } } +.notification__icon { + .icon__wrapper { + margin-right: var(--spacing-m); + } +} + .notification__wrapper { width: 100%; display: flex; + + .channel-thumbnail { + @include handleChannelGif(3rem); + } } .notification__content { - margin-left: var(--spacing-m); + display: flex; + flex: 1; + justify-content: space-between; + align-items: center; } .notification__title { - font-size: var(--font-large); + font-size: var(--font-small); + font-weight: bold; + color: var(--color-text); + margin-bottom: var(--spacing-s); } .notification__text { font-size: var(--font-body); - margin-top: var(--spacing-s); } .notification__time { @extend .help; + margin-bottom: 0; margin-top: 0; }