Add button to dismiss desktop notifications permissions banner (#15141)
parent
f1858f08c2
commit
4790a126be
|
@ -37,8 +37,9 @@ export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
|
||||||
|
|
||||||
export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
|
export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
|
||||||
|
|
||||||
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||||
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
||||||
|
export const NOTIFICATIONS_DISMISS_BROWSER_PERMISSION = 'NOTIFICATIONS_DISMISS_BROWSER_PERMISSION';
|
||||||
|
|
||||||
defineMessages({
|
defineMessages({
|
||||||
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
||||||
|
@ -283,3 +284,7 @@ export function setBrowserPermission (value) {
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const dismissBrowserPermission = () => ({
|
||||||
|
type: NOTIFICATIONS_DISMISS_BROWSER_PERMISSION,
|
||||||
|
});
|
||||||
|
|
|
@ -1,25 +1,42 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'mastodon/components/icon';
|
import Icon from 'mastodon/components/icon';
|
||||||
import Button from 'mastodon/components/button';
|
import Button from 'mastodon/components/button';
|
||||||
import { requestBrowserPermission } from 'mastodon/actions/notifications';
|
import IconButton from 'mastodon/components/icon_button';
|
||||||
|
import { requestBrowserPermission, dismissBrowserPermission } from 'mastodon/actions/notifications';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
export default @connect(() => {})
|
const messages = defineMessages({
|
||||||
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export default @connect()
|
||||||
|
@injectIntl
|
||||||
class NotificationsPermissionBanner extends React.PureComponent {
|
class NotificationsPermissionBanner extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.dispatch(requestBrowserPermission());
|
this.props.dispatch(requestBrowserPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleClose = () => {
|
||||||
|
this.props.dispatch(dismissBrowserPermission());
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='notifications-permission-banner'>
|
<div className='notifications-permission-banner'>
|
||||||
|
<div className='notifications-permission-banner__close'>
|
||||||
|
<IconButton icon='times' onClick={this.handleClose} title={intl.formatMessage(messages.close)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2><FormattedMessage id='notifications_permission_banner.title' defaultMessage='Never miss a thing' /></h2>
|
<h2><FormattedMessage id='notifications_permission_banner.title' defaultMessage='Never miss a thing' /></h2>
|
||||||
<p><FormattedMessage id='notifications_permission_banner.how_to_control' defaultMessage="To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled." values={{ icon: <Icon id='sliders' /> }} /></p>
|
<p><FormattedMessage id='notifications_permission_banner.how_to_control' defaultMessage="To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled." values={{ icon: <Icon id='sliders' /> }} /></p>
|
||||||
<Button onClick={this.handleClick}><FormattedMessage id='notifications_permission_banner.enable' defaultMessage='Enable desktop notifications' /></Button>
|
<Button onClick={this.handleClick}><FormattedMessage id='notifications_permission_banner.enable' defaultMessage='Enable desktop notifications' /></Button>
|
||||||
|
|
|
@ -7,12 +7,18 @@ import IconButton from 'mastodon/components/icon_button';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import Avatar from 'mastodon/components/avatar';
|
import Avatar from 'mastodon/components/avatar';
|
||||||
import DisplayName from 'mastodon/components/display_name';
|
import DisplayName from 'mastodon/components/display_name';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||||
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state, { accountId }) => ({
|
const mapStateToProps = (state, { accountId }) => ({
|
||||||
account: state.getIn(['accounts', accountId]),
|
account: state.getIn(['accounts', accountId]),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @connect(mapStateToProps)
|
export default @connect(mapStateToProps)
|
||||||
|
@injectIntl
|
||||||
class Header extends ImmutablePureComponent {
|
class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -20,10 +26,11 @@ class Header extends ImmutablePureComponent {
|
||||||
statusId: PropTypes.string.isRequired,
|
statusId: PropTypes.string.isRequired,
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
account: ImmutablePropTypes.map.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, statusId, onClose } = this.props;
|
const { account, statusId, onClose, intl } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='picture-in-picture__header'>
|
<div className='picture-in-picture__header'>
|
||||||
|
@ -32,7 +39,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<IconButton icon='times' onClick={onClose} title='Close' />
|
<IconButton icon='times' onClick={onClose} title={intl.formatMessage(messages.close)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
NOTIFICATIONS_MARK_AS_READ,
|
NOTIFICATIONS_MARK_AS_READ,
|
||||||
NOTIFICATIONS_SET_BROWSER_SUPPORT,
|
NOTIFICATIONS_SET_BROWSER_SUPPORT,
|
||||||
NOTIFICATIONS_SET_BROWSER_PERMISSION,
|
NOTIFICATIONS_SET_BROWSER_PERMISSION,
|
||||||
|
NOTIFICATIONS_DISMISS_BROWSER_PERMISSION,
|
||||||
} from '../actions/notifications';
|
} from '../actions/notifications';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
|
@ -250,6 +251,8 @@ export default function notifications(state = initialState, action) {
|
||||||
return state.set('browserSupport', action.value);
|
return state.set('browserSupport', action.value);
|
||||||
case NOTIFICATIONS_SET_BROWSER_PERMISSION:
|
case NOTIFICATIONS_SET_BROWSER_PERMISSION:
|
||||||
return state.set('browserPermission', action.value);
|
return state.set('browserPermission', action.value);
|
||||||
|
case NOTIFICATIONS_DISMISS_BROWSER_PERMISSION:
|
||||||
|
return state.set('browserPermission', 'denied');
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7204,6 +7204,13 @@ noscript {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__close {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
Loading…
Reference in New Issue