[Glitch] Add confirmation modal when logging out from the web app

Port fd3d45d38f to glitch-soc

Signed-off-by: Thibaut Girka <thib@sitedethib.com>
This commit is contained in:
ThibG 2019-08-26 18:24:10 +02:00 committed by Thibaut Girka
parent 7c22e32562
commit f11e9d5524
4 changed files with 122 additions and 29 deletions

View File

@ -53,8 +53,18 @@ class Header extends ImmutablePureComponent {
showNotificationsBadge: PropTypes.bool, showNotificationsBadge: PropTypes.bool,
intl: PropTypes.object, intl: PropTypes.object,
onSettingsClick: PropTypes.func, onSettingsClick: PropTypes.func,
onLogout: PropTypes.func.isRequired,
}; };
handleLogoutClick = e => {
e.preventDefault();
e.stopPropagation();
this.props.onLogout();
return false;
}
render () { render () {
const { intl, columns, unreadNotifications, showNotificationsBadge, onSettingsClick } = this.props; const { intl, columns, unreadNotifications, showNotificationsBadge, onSettingsClick } = this.props;
@ -114,7 +124,7 @@ class Header extends ImmutablePureComponent {
><Icon icon='cogs' /></a> ><Icon icon='cogs' /></a>
<a <a
aria-label={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)}
data-method='delete' onClick={this.handleLogoutClick}
href={ signOutLink } href={ signOutLink }
title={intl.formatMessage(messages.logout)} title={intl.formatMessage(messages.logout)}
><Icon icon='sign-out' /></a> ><Icon icon='sign-out' /></a>

View File

@ -1,6 +1,13 @@
import { openModal } from 'flavours/glitch/actions/modal'; import { openModal } from 'flavours/glitch/actions/modal';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { defineMessages, injectIntl } from 'react-intl';
import Header from '../components/header'; import Header from '../components/header';
import { logOut } from 'flavours/glitch/util/log_out';
const messages = defineMessages({
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
});
const mapStateToProps = state => { const mapStateToProps = state => {
return { return {
@ -16,6 +23,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
e.stopPropagation(); e.stopPropagation();
dispatch(openModal('SETTINGS', {})); dispatch(openModal('SETTINGS', {}));
}, },
onLogout () {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.logoutMessage),
confirm: intl.formatMessage(messages.logoutConfirm),
onConfirm: () => logOut(),
}));
},
}); });
export default connect(mapStateToProps, mapDispatchToProps)(Header); export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Header));

View File

@ -1,11 +1,48 @@
import { connect } from 'react-redux';
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { invitesEnabled, version, repository, source_url } from 'flavours/glitch/util/initial_state'; import { invitesEnabled, version, repository, source_url } from 'flavours/glitch/util/initial_state';
import { signOutLink } from 'flavours/glitch/util/backend_links'; import { signOutLink } from 'flavours/glitch/util/backend_links';
import { logOut } from 'flavours/glitch/util/log_out';
import { openModal } from 'flavours/glitch/actions/modal';
const LinkFooter = () => ( const messages = defineMessages({
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
});
const mapDispatchToProps = (dispatch, { intl }) => ({
onLogout () {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.logoutMessage),
confirm: intl.formatMessage(messages.logoutConfirm),
onConfirm: () => logOut(),
}));
},
});
export default @injectIntl
@connect(null, mapDispatchToProps)
class LinkFooter extends React.PureComponent {
static propTypes = {
onLogout: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleLogoutClick = e => {
e.preventDefault();
e.stopPropagation();
this.props.onLogout();
return false;
}
render () {
return (
<div className='getting-started__footer'> <div className='getting-started__footer'>
<ul> <ul>
{invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>} {invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
@ -15,7 +52,7 @@ const LinkFooter = () => (
<li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li> <li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
<li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li> <li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
<li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a> · </li> <li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a> · </li>
<li><a href={signOutLink} data-method='delete'><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a></li> <li><a href={signOutLink} onClick={this.handleLogoutClick}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a></li>
</ul> </ul>
<p> <p>
@ -28,9 +65,7 @@ const LinkFooter = () => (
/> />
</p> </p>
</div> </div>
); );
}
LinkFooter.propTypes = {
}; };
export default LinkFooter;

View File

@ -0,0 +1,34 @@
import Rails from 'rails-ujs';
import { signOutLink } from 'flavours/glitch/util/backend_links';
export const logOut = () => {
const form = document.createElement('form');
const methodInput = document.createElement('input');
methodInput.setAttribute('name', '_method');
methodInput.setAttribute('value', 'delete');
methodInput.setAttribute('type', 'hidden');
form.appendChild(methodInput);
const csrfToken = Rails.csrfToken();
const csrfParam = Rails.csrfParam();
if (csrfParam && csrfToken) {
const csrfInput = document.createElement('input');
csrfInput.setAttribute('name', csrfParam);
csrfInput.setAttribute('value', csrfToken);
csrfInput.setAttribute('type', 'hidden');
form.appendChild(csrfInput);
}
const submitButton = document.createElement('input');
submitButton.setAttribute('type', 'submit');
form.appendChild(submitButton);
form.method = 'post';
form.action = signOutLink;
form.style.display = 'none';
document.body.appendChild(form);
submitButton.click();
};