New notification cleaning mode (#89)

This PR adds a new notification cleaning mode, super perfectly tuned for accessibility, and removes the previous notification cleaning functionality as it's now redundant.

* w.i.p. notif clearing mode

* Better CSS for selected notification and shorter text if Stretch is off

* wip for rebase ~

* all working in notif clearing mode, except the actual removal

* bulk delete route for piggo

* cleaning + refactor. endpoint gives 422 for some reason

* formatting

* use the right route

* fix broken destroy_multiple

* load more notifs after succ cleaning

* satisfy eslint

* Removed CSS for the old notif delete button

* Tabindex=0 is mandatory

In order to make it possible to tab to this element you must have tab index = 0. Removing this violates WCAG and makes it impossible to use the interface without good eyesight and a mouse. So nobody with certain mobility impairments, vision impairments, or brain injuries would be able to use this feature if you don't have tabindex=0

* Corrected aria-label

Previous label implied a different behavior from what actually happens

* aria role localization & made the overlay behave like a checkbox

* checkboxes css and better contrast

* color tuning for the notif overlay

* fanceh checkboxes etc and nice backgrounds

* SHUT UP TRAVIS
This commit is contained in:
Ondřej Hruška
2017-07-21 20:33:16 +02:00
committed by GitHub
parent 0efd7e7406
commit 604654ccb4
20 changed files with 514 additions and 157 deletions

View File

@@ -8,7 +8,11 @@ import {
NOTIFICATIONS_EXPAND_FAIL,
NOTIFICATIONS_CLEAR,
NOTIFICATIONS_SCROLL_TOP,
NOTIFICATION_DELETE_SUCCESS,
NOTIFICATIONS_DELETE_MARKED_REQUEST,
NOTIFICATIONS_DELETE_MARKED_SUCCESS,
NOTIFICATION_MARK_FOR_DELETE,
NOTIFICATIONS_DELETE_MARKED_FAIL,
NOTIFICATIONS_ENTER_CLEARING_MODE,
} from '../actions/notifications';
import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts';
import { TIMELINE_DELETE } from '../actions/timelines';
@@ -21,12 +25,14 @@ const initialState = ImmutableMap({
unread: 0,
loaded: false,
isLoading: true,
cleaningMode: false,
});
const notificationToMap = notification => ImmutableMap({
id: notification.id,
type: notification.type,
account: notification.account.id,
markedForDelete: false,
status: notification.status ? notification.status.id : null,
});
@@ -93,17 +99,34 @@ const deleteByStatus = (state, statusId) => {
return state.update('items', list => list.filterNot(item => item.get('status') === statusId));
};
const deleteById = (state, notificationId) => {
return state.update('items', list => list.filterNot(item => item.get('id') === notificationId));
const markForDelete = (state, notificationId, yes) => {
return state.update('items', list => list.map(item => {
if(item.get('id') === notificationId) {
return item.set('markedForDelete', yes);
} else {
return item;
}
}));
};
const unmarkAllForDelete = (state) => {
return state.update('items', list => list.map(item => item.set('markedForDelete', false)));
};
const deleteMarkedNotifs = (state) => {
return state.update('items', list => list.filterNot(item => item.get('markedForDelete')));
};
export default function notifications(state = initialState, action) {
switch(action.type) {
case NOTIFICATIONS_REFRESH_REQUEST:
case NOTIFICATIONS_EXPAND_REQUEST:
case NOTIFICATIONS_DELETE_MARKED_REQUEST:
return state.set('isLoading', true);
case NOTIFICATIONS_DELETE_MARKED_FAIL:
case NOTIFICATIONS_REFRESH_FAIL:
case NOTIFICATIONS_EXPAND_FAIL:
return state.set('isLoading', true);
return state.set('isLoading', false);
case NOTIFICATIONS_SCROLL_TOP:
return updateTop(state, action.top);
case NOTIFICATIONS_UPDATE:
@@ -118,8 +141,15 @@ export default function notifications(state = initialState, action) {
return state.set('items', ImmutableList()).set('next', null);
case TIMELINE_DELETE:
return deleteByStatus(state, action.id);
case NOTIFICATION_DELETE_SUCCESS:
return deleteById(state, action.id);
case NOTIFICATION_MARK_FOR_DELETE:
return markForDelete(state, action.id, action.yes);
case NOTIFICATIONS_DELETE_MARKED_SUCCESS:
return deleteMarkedNotifs(state).set('isLoading', false).set('cleaningMode', false);
case NOTIFICATIONS_ENTER_CLEARING_MODE:
const st = state.set('cleaningMode', action.yes);
if (!action.yes)
return unmarkAllForDelete(st);
else return st;
default:
return state;
}