From b5927301cf086035cb3e5eac008cad12bcdcb352 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 13 Oct 2020 00:37:21 +0200 Subject: [Glitch] Fix browser notification permission request logic Port f54ca3d08e068af07a5b7a8b139e7658b3236db8 to glitch-soc Signed-off-by: Thibaut Girka --- .../notifications/components/column_settings.js | 39 +++++++++++++++++++++- .../containers/column_settings_container.js | 35 +++++++++++++++++-- .../glitch/features/notifications/index.js | 3 ++ .../ui/components/notifications_counter_icon.js | 1 + 4 files changed, 75 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js index e4d5d0eda..33ed139c7 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js +++ b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js @@ -4,6 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { FormattedMessage } from 'react-intl'; import ClearColumnButton from './clear_column_button'; import SettingToggle from './setting_toggle'; +import Icon from 'flavours/glitch/components/icon'; export default class ColumnSettings extends React.PureComponent { @@ -12,6 +13,10 @@ export default class ColumnSettings extends React.PureComponent { pushSettings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, onClear: PropTypes.func.isRequired, + onRequestNotificationPermission: PropTypes.func.isRequired, + alertsEnabled: PropTypes.bool, + browserSupport: PropTypes.bool, + browserPermission: PropTypes.bool, }; onPushChange = (path, checked) => { @@ -19,7 +24,7 @@ export default class ColumnSettings extends React.PureComponent { } render () { - const { settings, pushSettings, onChange, onClear } = this.props; + const { settings, pushSettings, onChange, onClear, onRequestNotificationPermission, alertsEnabled, browserSupport, browserPermission } = this.props; const filterShowStr = ; const filterAdvancedStr = ; @@ -31,8 +36,40 @@ export default class ColumnSettings extends React.PureComponent { const pushStr = showPushSettings && ; const pushMeta = showPushSettings && ; + const settingsIssues = []; + + if (alertsEnabled && browserSupport && browserPermission !== 'granted') { + if (browserPermission === 'denied') { + settingsIssues.push( + + ); + } else if (browserPermission === 'default') { + settingsIssues.push( + + ); + } + } + return (
+ {settingsIssues && ( +
+ {settingsIssues} +
+ )} +
diff --git a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js index 4b863712a..b4e309fce 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js @@ -3,28 +3,55 @@ import { defineMessages, injectIntl } from 'react-intl'; import ColumnSettings from '../components/column_settings'; import { changeSetting } from 'flavours/glitch/actions/settings'; import { setFilter } from 'flavours/glitch/actions/notifications'; -import { clearNotifications } from 'flavours/glitch/actions/notifications'; +import { clearNotifications, requestBrowserPermission } from 'flavours/glitch/actions/notifications'; import { changeAlerts as changePushNotifications } from 'flavours/glitch/actions/push_notifications'; import { openModal } from 'flavours/glitch/actions/modal'; +import { showAlert } from 'flavours/glitch/actions/alerts'; const messages = defineMessages({ clearMessage: { id: 'notifications.clear_confirmation', defaultMessage: 'Are you sure you want to permanently clear all your notifications?' }, clearConfirm: { id: 'notifications.clear', defaultMessage: 'Clear notifications' }, + permissionDenied: { id: 'notifications.permission_denied', defaultMessage: 'Cannot enable desktop notifications as permission has been denied.' }, }); const mapStateToProps = state => ({ settings: state.getIn(['settings', 'notifications']), pushSettings: state.get('push_notifications'), + alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true), + browserSupport: state.getIn(['notifications', 'browserSupport']), + browserPermission: state.getIn(['notifications', 'browserPermission']), }); const mapDispatchToProps = (dispatch, { intl }) => ({ onChange (path, checked) { if (path[0] === 'push') { - dispatch(changePushNotifications(path.slice(1), checked)); + if (checked && typeof window.Notification !== 'undefined' && Notification.permission !== 'granted') { + dispatch(requestBrowserPermission((permission) => { + if (permission === 'granted') { + dispatch(changePushNotifications(path.slice(1), checked)); + } else { + dispatch(showAlert(undefined, messages.permissionDenied)); + } + })); + } else { + dispatch(changePushNotifications(path.slice(1), checked)); + } } else if (path[0] === 'quickFilter') { dispatch(changeSetting(['notifications', ...path], checked)); dispatch(setFilter('all')); + } else if (path[0] === 'alerts' && checked && typeof window.Notification !== 'undefined' && Notification.permission !== 'granted') { + if (checked && typeof window.Notification !== 'undefined' && Notification.permission !== 'granted') { + dispatch(requestBrowserPermission((permission) => { + if (permission === 'granted') { + dispatch(changeSetting(['notifications', ...path], checked)); + } else { + dispatch(showAlert(undefined, messages.permissionDenied)); + } + })); + } else { + dispatch(changeSetting(['notifications', ...path], checked)); + } } else { dispatch(changeSetting(['notifications', ...path], checked)); } @@ -38,6 +65,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ })); }, + onRequestNotificationPermission () { + dispatch(requestBrowserPermission()); + }, + }); export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ColumnSettings)); diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index 18db7e0d2..87fb3074b 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -62,6 +62,7 @@ const mapStateToProps = state => ({ notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), lastReadId: state.getIn(['notifications', 'readMarkerId']), canMarkAsRead: state.getIn(['notifications', 'readMarkerId']) !== '0' && getNotifications(state).some(item => item !== null && compareId(item.get('id'), state.getIn(['notifications', 'readMarkerId'])) > 0), + needsNotificationPermission: state.getIn(['settings', 'notifications', 'alerts']).includes(true) && state.getIn(['notifications', 'browserSupport']) && state.getIn(['notifications', 'browserPermission']) !== 'granted', }); /* glitch */ @@ -105,6 +106,7 @@ class Notifications extends React.PureComponent { onUnmount: PropTypes.func, lastReadId: PropTypes.string, canMarkAsRead: PropTypes.bool, + needsNotificationPermission: PropTypes.bool, }; static defaultProps = { @@ -333,6 +335,7 @@ class Notifications extends React.PureComponent { multiColumn={multiColumn} localSettings={this.props.localSettings} extraButton={extraButtons} + collapseIssues={this.props.needsNotificationPermission} appendContent={notifCleaningDrawer} > diff --git a/app/javascript/flavours/glitch/features/ui/components/notifications_counter_icon.js b/app/javascript/flavours/glitch/features/ui/components/notifications_counter_icon.js index 6b52ef9b4..ef195013c 100644 --- a/app/javascript/flavours/glitch/features/ui/components/notifications_counter_icon.js +++ b/app/javascript/flavours/glitch/features/ui/components/notifications_counter_icon.js @@ -3,6 +3,7 @@ import IconWithBadge from 'flavours/glitch/components/icon_with_badge'; const mapStateToProps = state => ({ count: state.getIn(['local_settings', 'notifications', 'tab_badge']) ? state.getIn(['notifications', 'unread']) : 0, + issueBadge: state.getIn(['settings', 'notifications', 'alerts']).includes(true) && state.getIn(['notifications', 'browserSupport']) && state.getIn(['notifications', 'browserPermission']) !== 'granted', id: 'bell', }); -- cgit