about summary refs log tree commit diff
path: root/app/javascript/glitch
diff options
context:
space:
mode:
authorOndřej Hruška <ondra@ondrovo.com>2017-07-30 18:36:28 +0200
committerbeatrix <beatrix.bitrot@gmail.com>2017-07-30 12:36:28 -0400
commit6ff084dbbb06e5c2f131546829066435f2bf8f8a (patch)
tree06386f3ffadc2148b1f49be93cff1eb9ac685262 /app/javascript/glitch
parent9aaf3218d24bb8b3eb1de697243c13637398ab46 (diff)
Improved notifications cleaning UI with set operations (#109)
* added notification cleaning drawer

* bugfix

* fully implemented set operations for notif cleaning

* i18n for notif cleaning drawer & improved logic slightly. Also added a confirm dialog

* - notif dismiss "overlay" now shoves the notif aside to avoid overlap
- added focus ring to header buttons
- removed notif overlay entirely from DOM if mode is disabled

* removed comment

* CSS tuning - inconsistent division lines fix
Diffstat (limited to 'app/javascript/glitch')
-rw-r--r--app/javascript/glitch/components/column/notif_cleaning_widget/container.js34
-rw-r--r--app/javascript/glitch/components/column/notif_cleaning_widget/notification_purge_buttons.js86
-rw-r--r--app/javascript/glitch/components/notification/container.js1
-rw-r--r--app/javascript/glitch/components/notification/overlay/container.js2
-rw-r--r--app/javascript/glitch/components/notification/overlay/notification_overlay.js16
-rw-r--r--app/javascript/glitch/locales/en.json11
6 files changed, 74 insertions, 76 deletions
diff --git a/app/javascript/glitch/components/column/notif_cleaning_widget/container.js b/app/javascript/glitch/components/column/notif_cleaning_widget/container.js
index bf079e3c4..d3507d752 100644
--- a/app/javascript/glitch/components/column/notif_cleaning_widget/container.js
+++ b/app/javascript/glitch/components/column/notif_cleaning_widget/container.js
@@ -24,7 +24,10 @@ import NotificationPurgeButtons from './notification_purge_buttons';
 import {
   deleteMarkedNotifications,
   enterNotificationClearingMode,
+  markAllNotifications,
 } from '../../../../mastodon/actions/notifications';
+import { defineMessages, injectIntl } from 'react-intl';
+import { openModal } from '../../../../mastodon/actions/modal';
 
 //  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
@@ -39,18 +42,39 @@ deleting notifications.
 
 */
 
-const mapDispatchToProps = dispatch => ({
+const messages = defineMessages({
+  clearMessage: { id: 'notifications.marked_clear_confirmation', defaultMessage: 'Are you sure you want to permanently clear all selected notifications?' },
+  clearConfirm: { id: 'notifications.marked_clear', defaultMessage: 'Clear selected notifications' },
+});
+
+const mapDispatchToProps = (dispatch, { intl }) => ({
   onEnterCleaningMode(yes) {
     dispatch(enterNotificationClearingMode(yes));
   },
 
-  onDeleteMarkedNotifications() {
-    dispatch(deleteMarkedNotifications());
+  onDeleteMarked() {
+    dispatch(openModal('CONFIRM', {
+      message: intl.formatMessage(messages.clearMessage),
+      confirm: intl.formatMessage(messages.clearConfirm),
+      onConfirm: () => dispatch(deleteMarkedNotifications()),
+    }));
+  },
+
+  onMarkAll() {
+    dispatch(markAllNotifications(true));
+  },
+
+  onMarkNone() {
+    dispatch(markAllNotifications(false));
+  },
+
+  onInvert() {
+    dispatch(markAllNotifications(null));
   },
 });
 
 const mapStateToProps = state => ({
-  active: state.getIn(['notifications', 'cleaningMode']),
+  markNewForDelete: state.getIn(['notifications', 'markNewForDelete']),
 });
 
-export default connect(mapStateToProps, mapDispatchToProps)(NotificationPurgeButtons);
+export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(NotificationPurgeButtons));
diff --git a/app/javascript/glitch/components/column/notif_cleaning_widget/notification_purge_buttons.js b/app/javascript/glitch/components/column/notif_cleaning_widget/notification_purge_buttons.js
index e41572256..62c887fb7 100644
--- a/app/javascript/glitch/components/column/notif_cleaning_widget/notification_purge_buttons.js
+++ b/app/javascript/glitch/components/column/notif_cleaning_widget/notification_purge_buttons.js
@@ -16,83 +16,45 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 //  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
 const messages = defineMessages({
-  enter : { id: 'notification_purge.start', defaultMessage: 'Enter notification cleaning mode' },
-  accept : { id: 'notification_purge.confirm', defaultMessage: 'Dismiss selected notifications' },
-  abort : { id: 'notification_purge.abort', defaultMessage: 'Leave cleaning mode' },
+  btnAll : { id: 'notification_purge.btn_all', defaultMessage: 'Select\nall' },
+  btnNone : { id: 'notification_purge.btn_none', defaultMessage: 'Select\nnone' },
+  btnInvert : { id: 'notification_purge.btn_invert', defaultMessage: 'Invert\nselection' },
+  btnApply : { id: 'notification_purge.btn_apply', defaultMessage: 'Clear\nselected' },
 });
 
 @injectIntl
 export default class NotificationPurgeButtons extends ImmutablePureComponent {
 
   static propTypes = {
-    // Nukes all marked notifications
-    onDeleteMarkedNotifications : PropTypes.func.isRequired,
-    // Enables or disables the mode
-    // and also clears the marked status of all notifications
-    onEnterCleaningMode : PropTypes.func.isRequired,
-    // Active state, changed via onStateChange()
-    active: PropTypes.bool.isRequired,
-    // i18n
+    onDeleteMarked : PropTypes.func.isRequired,
+    onMarkAll : PropTypes.func.isRequired,
+    onMarkNone : PropTypes.func.isRequired,
+    onInvert : PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
+    markNewForDelete: PropTypes.bool,
   };
 
-  onEnterBtnClick = () => {
-    this.props.onEnterCleaningMode(true);
-  }
-
-  onAcceptBtnClick = () => {
-    this.props.onDeleteMarkedNotifications();
-  }
-
-  onAbortBtnClick = () => {
-    this.props.onEnterCleaningMode(false);
-  }
-
   render () {
-    const { intl, active } = this.props;
-
-    const msgEnter = intl.formatMessage(messages.enter);
-    const msgAccept = intl.formatMessage(messages.accept);
-    const msgAbort = intl.formatMessage(messages.abort);
-
-    let enterButton, acceptButton, abortButton;
+    const { intl, markNewForDelete } = this.props;
 
-    if (active) {
-      acceptButton = (
-        <button
-          className='active'
-          aria-label={msgAccept}
-          title={msgAccept}
-          onClick={this.onAcceptBtnClick}
-        >
-          <i className='fa fa-check' />
+    //className='active'
+    return (
+      <div className='column-header__notif-cleaning-buttons'>
+        <button onClick={this.props.onMarkAll} className={markNewForDelete ? 'active' : ''}>
+          <b>∀</b><br />{intl.formatMessage(messages.btnAll)}
         </button>
-      );
-      abortButton = (
-        <button
-          className='active'
-          aria-label={msgAbort}
-          title={msgAbort}
-          onClick={this.onAbortBtnClick}
-        >
-          <i className='fa fa-times' />
+
+        <button onClick={this.props.onMarkNone} className={!markNewForDelete ? 'active' : ''}>
+          <b>∅</b><br />{intl.formatMessage(messages.btnNone)}
         </button>
-      );
-    } else {
-      enterButton = (
-        <button
-          aria-label={msgEnter}
-          title={msgEnter}
-          onClick={this.onEnterBtnClick}
-        >
-          <i className='fa fa-eraser' />
+
+        <button onClick={this.props.onInvert}>
+          <b>¬</b><br />{intl.formatMessage(messages.btnInvert)}
         </button>
-      );
-    }
 
-    return (
-      <div className='column-header__notif-cleaning-buttons'>
-        {acceptButton}{abortButton}{enterButton}
+        <button onClick={this.props.onDeleteMarked}>
+          <i className='fa fa-trash' /><br />{intl.formatMessage(messages.btnApply)}
+        </button>
       </div>
     );
   }
diff --git a/app/javascript/glitch/components/notification/container.js b/app/javascript/glitch/components/notification/container.js
index 7d2590684..e29d6ba60 100644
--- a/app/javascript/glitch/components/notification/container.js
+++ b/app/javascript/glitch/components/notification/container.js
@@ -45,6 +45,7 @@ const makeMapStateToProps = () => {
   const mapStateToProps = (state, props) => ({
     notification: getNotification(state, props.notification, props.accountId),
     settings: state.get('local_settings'),
+    notifCleaning: state.getIn(['notifications', 'cleaningMode']),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/glitch/components/notification/overlay/container.js b/app/javascript/glitch/components/notification/overlay/container.js
index 019b78d0b..089f615f0 100644
--- a/app/javascript/glitch/components/notification/overlay/container.js
+++ b/app/javascript/glitch/components/notification/overlay/container.js
@@ -43,7 +43,7 @@ const mapDispatchToProps = dispatch => ({
 });
 
 const mapStateToProps = state => ({
-  revealed: state.getIn(['notifications', 'cleaningMode']),
+  show: state.getIn(['notifications', 'cleaningMode']),
 });
 
 export default connect(mapStateToProps, mapDispatchToProps)(NotificationOverlay);
diff --git a/app/javascript/glitch/components/notification/overlay/notification_overlay.js b/app/javascript/glitch/components/notification/overlay/notification_overlay.js
index 73eda718f..aaca95cac 100644
--- a/app/javascript/glitch/components/notification/overlay/notification_overlay.js
+++ b/app/javascript/glitch/components/notification/overlay/notification_overlay.js
@@ -24,7 +24,7 @@ export default class NotificationOverlay extends ImmutablePureComponent {
   static propTypes = {
     notification    : ImmutablePropTypes.map.isRequired,
     onMarkForDelete : PropTypes.func.isRequired,
-    revealed        : PropTypes.bool.isRequired,
+    show            : PropTypes.bool.isRequired,
     intl            : PropTypes.object.isRequired,
   };
 
@@ -35,25 +35,27 @@ export default class NotificationOverlay extends ImmutablePureComponent {
   }
 
   render () {
-    const { notification, revealed, intl } = this.props;
+    const { notification, show, intl } = this.props;
 
     const active = notification.get('markedForDelete');
     const label = intl.formatMessage(messages.markForDeletion);
 
-    return (
+    return show ? (
       <div
         aria-label={label}
         role='checkbox'
         aria-checked={active}
         tabIndex={0}
-        className={`notification__dismiss-overlay ${active ? 'active' : ''} ${revealed ? 'show' : ''}`}
+        className={`notification__dismiss-overlay ${active ? 'active' : ''}`}
         onClick={this.onToggleMark}
       >
-        <div className='notification__dismiss-overlay__ckbox' aria-hidden='true' title={label}>
-          {active ? (<i className='fa fa-check' />) : ''}
+        <div className='wrappy'>
+          <div className='ckbox' aria-hidden='true' title={label}>
+            {active ? (<i className='fa fa-check' />) : ''}
+          </div>
         </div>
       </div>
-    );
+    ) : null;
   }
 
 }
diff --git a/app/javascript/glitch/locales/en.json b/app/javascript/glitch/locales/en.json
index 21616f556..7ec381de1 100644
--- a/app/javascript/glitch/locales/en.json
+++ b/app/javascript/glitch/locales/en.json
@@ -29,5 +29,14 @@
   "settings.navbar_under": "Navbar at the bottom (Mobile only)",
   "status.collapse": "Collapse",
   "status.uncollapse": "Uncollapse",
-  "notification.markForDeletion": "Mark for deletion"
+
+  "notification.markForDeletion": "Mark for deletion",
+  "notifications.clear": "Clear all my notifications",
+  "notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
+  "notifications.marked_clear": "Clear selected notifications",
+
+  "notification_purge.btn_all": "Select\nall",
+  "notification_purge.btn_none": "Select\nnone",
+  "notification_purge.btn_invert": "Invert\nselection",
+  "notification_purge.btn_apply": "Clear\nselected"
 }