Notifications: refactor makeGetNotification, pass the full rebuilt notification all the way through

merge-requests/817/head
Alex Gleason 2021-10-22 17:11:32 -05:00
rodzic 03541ccc6f
commit acf316faf6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
4 zmienionych plików z 77 dodań i 47 usunięć

Wyświetl plik

@ -36,7 +36,6 @@ class Notification extends ImmutablePureComponent {
onFavourite: PropTypes.func.isRequired, onFavourite: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired, onReblog: PropTypes.func.isRequired,
onToggleHidden: PropTypes.func.isRequired, onToggleHidden: PropTypes.func.isRequired,
status: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
getScrollPosition: PropTypes.func, getScrollPosition: PropTypes.func,
updateScrollBottom: PropTypes.func, updateScrollBottom: PropTypes.func,
@ -58,7 +57,7 @@ class Notification extends ImmutablePureComponent {
const { notification } = this.props; const { notification } = this.props;
if (notification.get('status')) { if (notification.get('status')) {
this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}/posts/${notification.get('status')}`); this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}/posts/${notification.getIn(['status', 'id'])}`);
} else { } else {
this.handleOpenProfile(); this.handleOpenProfile();
} }
@ -77,17 +76,20 @@ class Notification extends ImmutablePureComponent {
} }
handleHotkeyFavourite = () => { handleHotkeyFavourite = () => {
const { status } = this.props; const { notification } = this.props;
const status = notification.get('status');
if (status) this.props.onFavourite(status); if (status) this.props.onFavourite(status);
} }
handleHotkeyBoost = e => { handleHotkeyBoost = e => {
const { status } = this.props; const { notification } = this.props;
const status = notification.get('status');
if (status) this.props.onReblog(status, e); if (status) this.props.onReblog(status, e);
} }
handleHotkeyToggleHidden = () => { handleHotkeyToggleHidden = () => {
const { status } = this.props; const { notification } = this.props;
const status = notification.get('status');
if (status) this.props.onToggleHidden(status); if (status) this.props.onToggleHidden(status);
} }
@ -105,12 +107,30 @@ class Notification extends ImmutablePureComponent {
}; };
} }
renderFollow(notification, account, link) { renderLink = account => {
return (
<bdi>
<Permalink
className='notification__display-name'
href={`/@${account.get('acct')}`}
title={account.get('acct')}
to={`/@${account.get('acct')}`}
dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }}
/>
</bdi>
);
}
renderFollow(notification) {
const { intl } = this.props; const { intl } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-follow focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow', defaultMessage: '{name} followed you' }, { name: account.get('acct') }), notification.get('created_at'))}> <div className='notification notification-follow focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow', defaultMessage: '{name} followed you' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
<div className='notification__message'> <div className='notification__message'>
<div className='notification__icon-wrapper'> <div className='notification__icon-wrapper'>
<Icon src={require('@tabler/icons/icons/user-plus.svg')} /> <Icon src={require('@tabler/icons/icons/user-plus.svg')} />
@ -121,18 +141,21 @@ class Notification extends ImmutablePureComponent {
</span> </span>
</div> </div>
<AccountContainer id={account.get('id')} withNote={false} hidden={this.props.hidden} /> <AccountContainer id={notification.getIn(['account', 'id'])} withNote={false} hidden={this.props.hidden} />
</div> </div>
</HotKeys> </HotKeys>
); );
} }
renderFollowRequest(notification, account, link) { renderFollowRequest(notification) {
const { intl, unread } = this.props; const { intl, unread } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className={classNames('notification notification-follow-request focusable', { unread })} tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow_request', defaultMessage: '{name} has requested to follow you' }, { name: account.get('acct') }), notification.get('created_at'))}> <div className={classNames('notification notification-follow-request focusable', { unread })} tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow_request', defaultMessage: '{name} has requested to follow you' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
<div className='notification__message'> <div className='notification__message'>
<div className='notification__icon-wrapper'> <div className='notification__icon-wrapper'>
<Icon src={require('@tabler/icons/icons/user.svg')} /> <Icon src={require('@tabler/icons/icons/user.svg')} />
@ -143,7 +166,7 @@ class Notification extends ImmutablePureComponent {
</span> </span>
</div> </div>
<FollowRequestContainer id={account.get('id')} withNote={false} hidden={this.props.hidden} /> <FollowRequestContainer id={notification.getIn(['account', 'id'])} withNote={false} hidden={this.props.hidden} />
</div> </div>
</HotKeys> </HotKeys>
); );
@ -153,7 +176,7 @@ class Notification extends ImmutablePureComponent {
return ( return (
<div className='notification notification-mention' tabIndex='0'> <div className='notification notification-mention' tabIndex='0'>
<StatusContainer <StatusContainer
id={notification.get('status')} id={notification.getIn(['status', 'id'])}
withDismiss withDismiss
hidden={this.props.hidden} hidden={this.props.hidden}
onMoveDown={this.handleMoveDown} onMoveDown={this.handleMoveDown}
@ -168,9 +191,12 @@ class Notification extends ImmutablePureComponent {
); );
} }
renderChatMention(notification, link) { renderChatMention(notification) {
const { intl } = this.props; const { intl } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-chat-mention focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.chat_mention', defaultMessage: '{name} sent you a message' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}> <div className='notification notification-chat-mention focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.chat_mention', defaultMessage: '{name} sent you a message' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
@ -195,9 +221,12 @@ class Notification extends ImmutablePureComponent {
); );
} }
renderEmojiReact(notification, link) { renderEmojiReact(notification) {
const { intl } = this.props; const { intl } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-emoji-react focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.pleroma:emoji_reaction', defaultMessage: '{name} reacted to your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}> <div className='notification notification-emoji-react focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.pleroma:emoji_reaction', defaultMessage: '{name} reacted to your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
@ -212,7 +241,7 @@ class Notification extends ImmutablePureComponent {
</div> </div>
<StatusContainer <StatusContainer
id={notification.get('status')} id={notification.getIn(['status', 'id'])}
account={notification.get('account')} account={notification.get('account')}
muted muted
withDismiss withDismiss
@ -227,9 +256,12 @@ class Notification extends ImmutablePureComponent {
); );
} }
renderFavourite(notification, link) { renderFavourite(notification) {
const { intl } = this.props; const { intl } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-favourite focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.favourite', defaultMessage: '{name} liked your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}> <div className='notification notification-favourite focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.favourite', defaultMessage: '{name} liked your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
@ -244,7 +276,7 @@ class Notification extends ImmutablePureComponent {
</div> </div>
<StatusContainer <StatusContainer
id={notification.get('status')} id={notification.getIn(['status', 'id'])}
account={notification.get('account')} account={notification.get('account')}
muted muted
withDismiss withDismiss
@ -259,9 +291,12 @@ class Notification extends ImmutablePureComponent {
); );
} }
renderReblog(notification, link) { renderReblog(notification) {
const { intl } = this.props; const { intl } = this.props;
const account = notification.get('account');
const link = this.renderLink(account);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-reblog focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.reblog', defaultMessage: '{name} reposted your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}> <div className='notification notification-reblog focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.reblog', defaultMessage: '{name} reposted your post' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
@ -276,7 +311,7 @@ class Notification extends ImmutablePureComponent {
</div> </div>
<StatusContainer <StatusContainer
id={notification.get('status')} id={notification.getIn(['status', 'id'])}
account={notification.get('account')} account={notification.get('account')}
muted muted
withDismiss withDismiss
@ -308,7 +343,7 @@ class Notification extends ImmutablePureComponent {
</div> </div>
<StatusContainer <StatusContainer
id={notification.get('status')} id={notification.getIn(['status', 'id'])}
account={notification.get('account')} account={notification.get('account')}
muted muted
withDismiss withDismiss
@ -323,14 +358,17 @@ class Notification extends ImmutablePureComponent {
); );
} }
renderMove(notification, account, targetAccount, link) { renderMove(notification) {
const { intl } = this.props; const { intl } = this.props;
const targetLink = <bdi><Permalink className='notification__display-name' href={`/@${targetAccount.get('acct')}`} to={`/@${targetAccount.get('acct')}`}>{targetAccount.get('acct')}</Permalink></bdi>; const account = notification.get('account');
const target = notification.get('target');
const link = this.renderLink(account);
const targetLink = this.renderLink(target);
return ( return (
<HotKeys handlers={this.getHandlers()}> <HotKeys handlers={this.getHandlers()}>
<div className='notification notification-move focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.move', defaultMessage: '{name} moved to {targetName}' }, { name: account.get('acct'), targetName: targetAccount.get('acct') }), notification.get('created_at'))}> <div className='notification notification-move focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.move', defaultMessage: '{name} moved to {targetName}' }, { name: notification.getIn(['account', 'acct']), targetName: notification.getIn(['target', 'acct']) }), notification.get('created_at'))}>
<div className='notification__message'> <div className='notification__message'>
<div className='notification__icon-wrapper'> <div className='notification__icon-wrapper'>
<Icon src={require('@tabler/icons/icons/briefcase.svg')} /> <Icon src={require('@tabler/icons/icons/briefcase.svg')} />
@ -341,7 +379,7 @@ class Notification extends ImmutablePureComponent {
</span> </span>
</div> </div>
<AccountContainer id={targetAccount.get('id')} withNote={false} hidden={this.props.hidden} /> <AccountContainer id={notification.getIn(['target', 'id'])} withNote={false} hidden={this.props.hidden} />
</div> </div>
</HotKeys> </HotKeys>
); );
@ -349,30 +387,26 @@ class Notification extends ImmutablePureComponent {
render() { render() {
const { notification } = this.props; const { notification } = this.props;
const account = notification.get('account');
const targetAccount = notification.get('target');
const displayNameHtml = { __html: account.get('display_name_html') };
const link = <bdi><Permalink className='notification__display-name' href={`/@${account.get('acct')}`} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
switch(notification.get('type')) { switch(notification.get('type')) {
case 'follow': case 'follow':
return this.renderFollow(notification, account, link); return this.renderFollow(notification);
case 'follow_request': case 'follow_request':
return this.renderFollowRequest(notification, account, link); return this.renderFollowRequest(notification);
case 'mention': case 'mention':
return this.renderMention(notification); return this.renderMention(notification);
case 'favourite': case 'favourite':
return this.renderFavourite(notification, link); return this.renderFavourite(notification);
case 'reblog': case 'reblog':
return this.renderReblog(notification, link); return this.renderReblog(notification);
case 'poll': case 'poll':
return this.renderPoll(notification); return this.renderPoll(notification);
case 'move': case 'move':
return this.renderMove(notification, account, targetAccount, link); return this.renderMove(notification);
case 'pleroma:emoji_reaction': case 'pleroma:emoji_reaction':
return this.renderEmojiReact(notification, link); return this.renderEmojiReact(notification);
case 'pleroma:chat_mention': case 'pleroma:chat_mention':
return this.renderChatMention(notification, link); return this.renderChatMention(notification);
} }
return null; return null;

Wyświetl plik

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeGetNotification, makeGetStatus } from '../../../selectors'; import { makeGetNotification } from '../../../selectors';
import Notification from '../components/notification'; import Notification from '../components/notification';
import { openModal } from '../../../actions/modal'; import { openModal } from '../../../actions/modal';
import { mentionCompose } from '../../../actions/compose'; import { mentionCompose } from '../../../actions/compose';
@ -17,13 +17,10 @@ import { getSettings } from 'soapbox/actions/settings';
const makeMapStateToProps = () => { const makeMapStateToProps = () => {
const getNotification = makeGetNotification(); const getNotification = makeGetNotification();
const getStatus = makeGetStatus();
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const notification = getNotification(state, props.notification, props.accountId, props.targetId);
return { return {
notification: notification, notification: getNotification(state, props.notification),
status: notification.get('status') ? getStatus(state, { id: notification.get('status') }) : null,
}; };
}; };

Wyświetl plik

@ -152,8 +152,6 @@ class Notifications extends React.PureComponent {
<NotificationContainer <NotificationContainer
key={item.get('id')} key={item.get('id')}
notification={item} notification={item}
accountId={item.get('account')}
targetId={item.get('target')}
onMoveUp={this.handleMoveUp} onMoveUp={this.handleMoveUp}
onMoveDown={this.handleMoveDown} onMoveDown={this.handleMoveDown}
/> />

Wyświetl plik

@ -182,11 +182,12 @@ export const getAlerts = createSelector([getAlertsBase], (base) => {
export const makeGetNotification = () => { export const makeGetNotification = () => {
return createSelector([ return createSelector([
(_, base) => base, (state, notification) => notification,
(state, _, accountId) => state.getIn(['accounts', accountId]), (state, notification) => state.getIn(['accounts', notification.get('account')]),
(state, _, __, targetId) => state.getIn(['accounts', targetId]), (state, notification) => state.getIn(['accounts', notification.get('target')]),
], (base, account, target) => { (state, notification) => state.getIn(['statuses', notification.get('status')]),
return base.set('account', account).set('target', target); ], (notification, account, target, status) => {
return notification.merge({ account, target, status });
}); });
}; };