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;
}