Add button to manually mark all notifications as read

This commit is contained in:
Thibaut Girka 2020-09-15 23:42:58 +02:00 committed by ThibG
parent 94c290d7d2
commit f1c0cf9806
3 changed files with 41 additions and 3 deletions

View file

@ -45,6 +45,8 @@ export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY'; export const NOTIFICATIONS_SET_VISIBILITY = 'NOTIFICATIONS_SET_VISIBILITY';
export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
defineMessages({ defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
}); });
@ -318,3 +320,9 @@ export function setFilter (filterType) {
dispatch(saveSettings()); dispatch(saveSettings());
}; };
}; };
export function markNotificationsAsRead() {
return {
type: NOTIFICATIONS_MARK_AS_READ,
};
};

View file

@ -12,6 +12,7 @@ import {
mountNotifications, mountNotifications,
unmountNotifications, unmountNotifications,
loadPending, loadPending,
markNotificationsAsRead,
} from 'flavours/glitch/actions/notifications'; } from 'flavours/glitch/actions/notifications';
import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns'; import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';
import NotificationContainer from './containers/notification_container'; import NotificationContainer from './containers/notification_container';
@ -31,6 +32,7 @@ import NotificationPurgeButtonsContainer from 'flavours/glitch/containers/notifi
const messages = defineMessages({ const messages = defineMessages({
title: { id: 'column.notifications', defaultMessage: 'Notifications' }, title: { id: 'column.notifications', defaultMessage: 'Notifications' },
enterNotifCleaning : { id: 'notification_purge.start', defaultMessage: 'Enter notification cleaning mode' }, 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([ const getNotifications = createSelector([
@ -58,6 +60,7 @@ const mapStateToProps = state => ({
numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size,
notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), notifCleaningActive: state.getIn(['notifications', 'cleaningMode']),
lastReadId: state.getIn(['notifications', 'readMarkerId']), 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 */ /* glitch */
@ -65,6 +68,9 @@ const mapDispatchToProps = dispatch => ({
onEnterCleaningMode(yes) { onEnterCleaningMode(yes) {
dispatch(enterNotificationClearingMode(yes)); dispatch(enterNotificationClearingMode(yes));
}, },
onMarkAsRead() {
dispatch(markNotificationsAsRead());
},
onMount() { onMount() {
dispatch(mountNotifications()); dispatch(mountNotifications());
}, },
@ -96,6 +102,7 @@ class Notifications extends React.PureComponent {
onMount: PropTypes.func, onMount: PropTypes.func,
onUnmount: PropTypes.func, onUnmount: PropTypes.func,
lastReadId: PropTypes.string, lastReadId: PropTypes.string,
canMarkAsRead: PropTypes.bool,
}; };
static defaultProps = { static defaultProps = {
@ -197,8 +204,12 @@ class Notifications extends React.PureComponent {
this.props.onEnterCleaningMode(!this.props.notifCleaningActive); this.props.onEnterCleaningMode(!this.props.notifCleaningActive);
} }
handleMarkAsRead = () => {
this.props.onMarkAsRead();
}
render () { 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 { notifCleaning, notifCleaningActive } = this.props;
const { animatingNCD } = this.state; const { animatingNCD } = this.state;
const pinned = !!columnId; const pinned = !!columnId;
@ -256,6 +267,21 @@ class Notifications extends React.PureComponent {
</ScrollableList> </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', { const notifCleaningButtonClassName = classNames('column-header__button', {
'active': notifCleaningActive, 'active': notifCleaningActive,
}); });
@ -267,7 +293,7 @@ class Notifications extends React.PureComponent {
const msgEnterNotifCleaning = intl.formatMessage(messages.enterNotifCleaning); const msgEnterNotifCleaning = intl.formatMessage(messages.enterNotifCleaning);
const notifCleaningButton = ( extraButtons.push(
<button <button
aria-label={msgEnterNotifCleaning} aria-label={msgEnterNotifCleaning}
title={msgEnterNotifCleaning} title={msgEnterNotifCleaning}
@ -304,7 +330,7 @@ class Notifications extends React.PureComponent {
pinned={pinned} pinned={pinned}
multiColumn={multiColumn} multiColumn={multiColumn}
localSettings={this.props.localSettings} localSettings={this.props.localSettings}
extraButton={notifCleaningButton} extraButton={extraButtons}
appendContent={notifCleaningDrawer} appendContent={notifCleaningDrawer}
> >
<ColumnSettingsContainer /> <ColumnSettingsContainer />

View file

@ -16,6 +16,7 @@ import {
NOTIFICATIONS_DELETE_MARKED_FAIL, NOTIFICATIONS_DELETE_MARKED_FAIL,
NOTIFICATIONS_ENTER_CLEARING_MODE, NOTIFICATIONS_ENTER_CLEARING_MODE,
NOTIFICATIONS_MARK_ALL_FOR_DELETE, NOTIFICATIONS_MARK_ALL_FOR_DELETE,
NOTIFICATIONS_MARK_AS_READ,
} from 'flavours/glitch/actions/notifications'; } from 'flavours/glitch/actions/notifications';
import { import {
ACCOUNT_BLOCK_SUCCESS, ACCOUNT_BLOCK_SUCCESS,
@ -297,6 +298,9 @@ export default function notifications(state = initialState, action) {
} }
return markAllForDelete(st, action.yes); return markAllForDelete(st, action.yes);
case NOTIFICATIONS_MARK_AS_READ:
return recountUnread(state, state.get('items').first().get('id'));
default: default:
return state; return state;
} }