diff options
author | Ondřej Hruška <ondra@ondrovo.com> | 2017-07-30 18:36:28 +0200 |
---|---|---|
committer | beatrix <beatrix.bitrot@gmail.com> | 2017-07-30 12:36:28 -0400 |
commit | 6ff084dbbb06e5c2f131546829066435f2bf8f8a (patch) | |
tree | 06386f3ffadc2148b1f49be93cff1eb9ac685262 /app/javascript/glitch | |
parent | 9aaf3218d24bb8b3eb1de697243c13637398ab46 (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')
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" } |