Display unread marker for notifications
parent
ae698469d0
commit
66e9a77e36
|
@ -122,6 +122,7 @@ class Status extends ImmutablePureComponent {
|
|||
'notification',
|
||||
'hidden',
|
||||
'expanded',
|
||||
'unread',
|
||||
]
|
||||
|
||||
updateOnStates = [
|
||||
|
|
|
@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
import classNames from 'classnames';
|
||||
|
||||
// Our imports.
|
||||
import Permalink from 'flavours/glitch/components/permalink';
|
||||
|
@ -19,6 +20,7 @@ export default class NotificationFollow extends ImmutablePureComponent {
|
|||
id: PropTypes.string.isRequired,
|
||||
account: ImmutablePropTypes.map.isRequired,
|
||||
notification: ImmutablePropTypes.map.isRequired,
|
||||
unread: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleMoveUp = () => {
|
||||
|
@ -59,7 +61,7 @@ export default class NotificationFollow extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { account, notification, hidden } = this.props;
|
||||
const { account, notification, hidden, unread } = this.props;
|
||||
|
||||
// Links to the display name.
|
||||
const displayName = account.get('display_name_html') || account.get('username');
|
||||
|
@ -76,7 +78,7 @@ export default class NotificationFollow extends ImmutablePureComponent {
|
|||
// Renders.
|
||||
return (
|
||||
<HotKeys handlers={this.getHandlers()}>
|
||||
<div className='notification notification-follow focusable' tabIndex='0'>
|
||||
<div className={classNames('notification notification-follow focusable', { unread })} tabIndex='0'>
|
||||
<div className='notification__message'>
|
||||
<div className='notification__favourite-icon-wrapper'>
|
||||
<Icon fixedWidth id='user-plus' />
|
||||
|
|
|
@ -10,6 +10,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
import NotificationOverlayContainer from '../containers/overlay_container';
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const messages = defineMessages({
|
||||
authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
|
||||
|
@ -25,6 +26,7 @@ class FollowRequest extends ImmutablePureComponent {
|
|||
onReject: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
notification: ImmutablePropTypes.map.isRequired,
|
||||
unread: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleMoveUp = () => {
|
||||
|
@ -65,7 +67,7 @@ class FollowRequest extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { intl, hidden, account, onAuthorize, onReject, notification } = this.props;
|
||||
const { intl, hidden, account, onAuthorize, onReject, notification, unread } = this.props;
|
||||
|
||||
if (!account) {
|
||||
return <div />;
|
||||
|
@ -94,7 +96,7 @@ class FollowRequest extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<HotKeys handlers={this.getHandlers()}>
|
||||
<div className='notification notification-follow-request focusable' tabIndex='0'>
|
||||
<div className={classNames('notification notification-follow-request focusable', { unread })} tabIndex='0'>
|
||||
<div className='notification__message'>
|
||||
<div className='notification__favourite-icon-wrapper'>
|
||||
<Icon id='user' fixedWidth />
|
||||
|
|
|
@ -46,6 +46,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
case 'follow_request':
|
||||
|
@ -58,6 +59,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
onMoveDown={onMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
onMention={onMention}
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
case 'mention':
|
||||
|
@ -77,6 +79,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
cacheMediaWidth={this.props.cacheMediaWidth}
|
||||
onUnmount={this.props.onUnmount}
|
||||
withDismiss
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
case 'favourite':
|
||||
|
@ -98,6 +101,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
cacheMediaWidth={this.props.cacheMediaWidth}
|
||||
onUnmount={this.props.onUnmount}
|
||||
withDismiss
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
case 'reblog':
|
||||
|
@ -119,6 +123,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
cacheMediaWidth={this.props.cacheMediaWidth}
|
||||
onUnmount={this.props.onUnmount}
|
||||
withDismiss
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
case 'poll':
|
||||
|
@ -140,6 +145,7 @@ export default class Notification extends ImmutablePureComponent {
|
|||
cacheMediaWidth={this.props.cacheMediaWidth}
|
||||
onUnmount={this.props.onUnmount}
|
||||
withDismiss
|
||||
unread={this.props.unread}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
|
|
|
@ -24,6 +24,7 @@ import { debounce } from 'lodash';
|
|||
import ScrollableList from 'flavours/glitch/components/scrollable_list';
|
||||
import LoadGap from 'flavours/glitch/components/load_gap';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import compareId from 'flavours/glitch/util/compare_id';
|
||||
|
||||
import NotificationPurgeButtonsContainer from 'flavours/glitch/containers/notification_purge_buttons_container';
|
||||
|
||||
|
@ -56,6 +57,7 @@ const mapStateToProps = state => ({
|
|||
hasMore: state.getIn(['notifications', 'hasMore']),
|
||||
numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size,
|
||||
notifCleaningActive: state.getIn(['notifications', 'cleaningMode']),
|
||||
lastReadId: state.getIn(['notifications', 'lastReadId']),
|
||||
});
|
||||
|
||||
/* glitch */
|
||||
|
@ -93,6 +95,7 @@ class Notifications extends React.PureComponent {
|
|||
onEnterCleaningMode: PropTypes.func,
|
||||
onMount: PropTypes.func,
|
||||
onUnmount: PropTypes.func,
|
||||
lastReadId: PropTypes.string,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -195,7 +198,7 @@ class Notifications extends React.PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar } = this.props;
|
||||
const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId } = this.props;
|
||||
const { notifCleaning, notifCleaningActive } = this.props;
|
||||
const { animatingNCD } = this.state;
|
||||
const pinned = !!columnId;
|
||||
|
@ -224,6 +227,7 @@ class Notifications extends React.PureComponent {
|
|||
accountId={item.get('account')}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
unread={lastReadId && compareId(item.get('id'), lastReadId) > 0}
|
||||
/>
|
||||
));
|
||||
} else {
|
||||
|
|
|
@ -1054,3 +1054,22 @@ a.status-card.compact:hover {
|
|||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.notification,
|
||||
.status {
|
||||
position: relative;
|
||||
|
||||
&.unread {
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-left: 2px solid $highlight-text-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue