Display unread marker for notifications
This commit is contained in:
		
							parent
							
								
									ae698469d0
								
							
						
					
					
						commit
						66e9a77e36
					
				
					 6 changed files with 39 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -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 a new issue