group comment notifications and clean up notification style
This commit is contained in:
parent
9fc3d10d4b
commit
9acbdf9825
6 changed files with 99 additions and 13 deletions
|
@ -1,5 +1,6 @@
|
|||
[ignore]
|
||||
.*\.typeface\.json
|
||||
.*/node_modules/findup/.*
|
||||
|
||||
[include]
|
||||
|
||||
|
|
3
flow-typed/notification.js
vendored
3
flow-typed/notification.js
vendored
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 = <Icon icon={ICONS.SUBSCRIBE} sectionIcon className="notification__icon" />;
|
||||
break;
|
||||
case NOTIFICATION_COMMENT:
|
||||
icon = <ChannelThumbnail uri={notification.notification_parameters.dynamic.comment_author} />;
|
||||
icon = <ChannelThumbnail small uri={notification.notification_parameters.dynamic.comment_author} />;
|
||||
break;
|
||||
default:
|
||||
icon = <Icon icon={ICONS.NOTIFICATION} sectionIcon className="notification__icon" />;
|
||||
|
@ -52,8 +54,20 @@ export default function Notification(props: Props) {
|
|||
<div className="notification__wrapper">
|
||||
<div className="notification__icon">{icon}</div>
|
||||
<div className="notification__content">
|
||||
<div className="notification__title">{notification.notification_parameters.device.title}</div>
|
||||
<div className="notification__text">{notification.notification_parameters.device.text}</div>
|
||||
<div>
|
||||
{notification.notification_rule !== NOTIFICATION_COMMENT && (
|
||||
<div className="notification__title">{notification.notification_parameters.device.title}</div>
|
||||
)}
|
||||
|
||||
<div className="notification__text">
|
||||
{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'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="notification__time">
|
||||
<DateTime timeAgo date={notification.created_at} />
|
||||
</div>
|
||||
|
|
2
ui/constants/notifications.js
Normal file
2
ui/constants/notifications.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const NOTIFICATION_CREATOR_SUBSCRIBER = 'creator_subscriber';
|
||||
export const NOTIFICATION_COMMENT = 'comment';
|
|
@ -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 (
|
||||
<Page>
|
||||
{fetching && (
|
||||
|
@ -20,13 +66,17 @@ export default function NotificationsPage(props: Props) {
|
|||
<Spinner delayed />
|
||||
</div>
|
||||
)}
|
||||
{notifications && notifications.length > 0 ? (
|
||||
{groupedNotifications && groupedNotifications.length > 0 ? (
|
||||
<Card
|
||||
isBodyList
|
||||
title={__('Notifications')}
|
||||
body={
|
||||
<div className="notification_list">
|
||||
{notifications.map((notification, index) => {
|
||||
{groupedNotifications.map((notification, index) => {
|
||||
if (!notification) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Notification key={notification.id} notification={notification} />;
|
||||
})}
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue