diff options
Diffstat (limited to 'app/javascript/flavours/glitch')
3 files changed, 41 insertions, 3 deletions
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index ceb1e6df6..b44469cf4 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -45,6 +45,8 @@ export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT'; export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY'; +export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ'; + defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, }); @@ -318,3 +320,9 @@ export function setFilter (filterType) { dispatch(saveSettings()); }; }; + +export function markNotificationsAsRead() { + return { + type: NOTIFICATIONS_MARK_AS_READ, + }; +}; diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index 1c8c68218..d1a0640cb 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -12,6 +12,7 @@ import { mountNotifications, unmountNotifications, loadPending, + markNotificationsAsRead, } from 'flavours/glitch/actions/notifications'; import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns'; import NotificationContainer from './containers/notification_container'; @@ -31,6 +32,7 @@ import NotificationPurgeButtonsContainer from 'flavours/glitch/containers/notifi const messages = defineMessages({ title: { id: 'column.notifications', defaultMessage: 'Notifications' }, enterNotifCleaning : { id: 'notification_purge.start', defaultMessage: 'Enter notification cleaning mode' }, + markAsRead : { id: 'notifications.mark_as_read', defaultMessage: 'Mark every notification as read' }, }); const getNotifications = createSelector([ @@ -58,6 +60,7 @@ const mapStateToProps = state => ({ numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), lastReadId: state.getIn(['notifications', 'readMarkerId']), + canMarkAsRead: !state.getIn(['notifications', 'items']).isEmpty() && state.getIn(['notifications', 'readMarkerId']) !== '0' && compareId(state.getIn(['notifications', 'items']).first().get('id'), state.getIn(['notifications', 'readMarkerId'])) > 0, }); /* glitch */ @@ -65,6 +68,9 @@ const mapDispatchToProps = dispatch => ({ onEnterCleaningMode(yes) { dispatch(enterNotificationClearingMode(yes)); }, + onMarkAsRead() { + dispatch(markNotificationsAsRead()); + }, onMount() { dispatch(mountNotifications()); }, @@ -96,6 +102,7 @@ class Notifications extends React.PureComponent { onMount: PropTypes.func, onUnmount: PropTypes.func, lastReadId: PropTypes.string, + canMarkAsRead: PropTypes.bool, }; static defaultProps = { @@ -197,8 +204,12 @@ class Notifications extends React.PureComponent { this.props.onEnterCleaningMode(!this.props.notifCleaningActive); } + handleMarkAsRead = () => { + this.props.onMarkAsRead(); + } + render () { - const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId } = this.props; + const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead } = this.props; const { notifCleaning, notifCleaningActive } = this.props; const { animatingNCD } = this.state; const pinned = !!columnId; @@ -256,6 +267,21 @@ class Notifications extends React.PureComponent { </ScrollableList> ); + const extraButtons = []; + + if (canMarkAsRead) { + extraButtons.push( + <button + aria-label={intl.formatMessage(messages.markAsRead)} + title={intl.formatMessage(messages.markAsRead)} + onClick={this.handleMarkAsRead} + className='column-header__button' + > + <Icon id='check' /> + </button> + ); + } + const notifCleaningButtonClassName = classNames('column-header__button', { 'active': notifCleaningActive, }); @@ -267,7 +293,7 @@ class Notifications extends React.PureComponent { const msgEnterNotifCleaning = intl.formatMessage(messages.enterNotifCleaning); - const notifCleaningButton = ( + extraButtons.push( <button aria-label={msgEnterNotifCleaning} title={msgEnterNotifCleaning} @@ -304,7 +330,7 @@ class Notifications extends React.PureComponent { pinned={pinned} multiColumn={multiColumn} localSettings={this.props.localSettings} - extraButton={notifCleaningButton} + extraButton={extraButtons} appendContent={notifCleaningDrawer} > <ColumnSettingsContainer /> diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index 7f6784eae..122fd009c 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -16,6 +16,7 @@ import { NOTIFICATIONS_DELETE_MARKED_FAIL, NOTIFICATIONS_ENTER_CLEARING_MODE, NOTIFICATIONS_MARK_ALL_FOR_DELETE, + NOTIFICATIONS_MARK_AS_READ, } from 'flavours/glitch/actions/notifications'; import { ACCOUNT_BLOCK_SUCCESS, @@ -297,6 +298,9 @@ export default function notifications(state = initialState, action) { } return markAllForDelete(st, action.yes); + case NOTIFICATIONS_MARK_AS_READ: + return recountUnread(state, state.get('items').first().get('id')); + default: return state; } |