From f11e9d552478c45f8559391e21528c89931a9b64 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 26 Aug 2019 18:24:10 +0200 Subject: [PATCH] [Glitch] Add confirmation modal when logging out from the web app Port fd3d45d38f289815bed0adc7eaa3b15894ddb8fb to glitch-soc Signed-off-by: Thibaut Girka --- .../features/compose/components/header.js | 12 ++- .../compose/containers/header_container.js | 16 +++- .../features/ui/components/link_footer.js | 89 +++++++++++++------ .../flavours/glitch/util/log_out.js | 34 +++++++ 4 files changed, 122 insertions(+), 29 deletions(-) create mode 100644 app/javascript/flavours/glitch/util/log_out.js diff --git a/app/javascript/flavours/glitch/features/compose/components/header.js b/app/javascript/flavours/glitch/features/compose/components/header.js index 2e29084f25..8b0f540ef8 100644 --- a/app/javascript/flavours/glitch/features/compose/components/header.js +++ b/app/javascript/flavours/glitch/features/compose/components/header.js @@ -53,8 +53,18 @@ class Header extends ImmutablePureComponent { showNotificationsBadge: PropTypes.bool, intl: PropTypes.object, onSettingsClick: PropTypes.func, + onLogout: PropTypes.func.isRequired, }; + handleLogoutClick = e => { + e.preventDefault(); + e.stopPropagation(); + + this.props.onLogout(); + + return false; + } + render () { const { intl, columns, unreadNotifications, showNotificationsBadge, onSettingsClick } = this.props; @@ -114,7 +124,7 @@ class Header extends ImmutablePureComponent { > diff --git a/app/javascript/flavours/glitch/features/compose/containers/header_container.js b/app/javascript/flavours/glitch/features/compose/containers/header_container.js index ce1dea3196..b4dcb4d569 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/header_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/header_container.js @@ -1,6 +1,13 @@ import { openModal } from 'flavours/glitch/actions/modal'; import { connect } from 'react-redux'; +import { defineMessages, injectIntl } from 'react-intl'; 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 => { return { @@ -16,6 +23,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ e.stopPropagation(); 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)); diff --git a/app/javascript/flavours/glitch/features/ui/components/link_footer.js b/app/javascript/flavours/glitch/features/ui/components/link_footer.js index 3e724fffb9..1712da83e3 100644 --- a/app/javascript/flavours/glitch/features/ui/components/link_footer.js +++ b/app/javascript/flavours/glitch/features/ui/components/link_footer.js @@ -1,36 +1,71 @@ +import { connect } from 'react-redux'; import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { invitesEnabled, version, repository, source_url } from 'flavours/glitch/util/initial_state'; 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 = () => ( -
-
    - {invitesEnabled &&
  • ·
  • } -
  • ·
  • -
  • ·
  • -
  • ·
  • -
  • ·
  • -
  • ·
  • -
  • ·
  • -
  • -
+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' }, +}); -

- glitch-soc/mastodon (v{version}), - Mastodon: Mastodon }} - /> -

-
-); +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 ( +
+
    + {invitesEnabled &&
  • ·
  • } +
  • ·
  • +
  • ·
  • +
  • ·
  • +
  • ·
  • +
  • ·
  • +
  • ·
  • +
  • +
+ +

+ glitch-soc/mastodon (v{version}), + Mastodon: Mastodon }} + /> +

+
+ ); + } -LinkFooter.propTypes = { }; - -export default LinkFooter; diff --git a/app/javascript/flavours/glitch/util/log_out.js b/app/javascript/flavours/glitch/util/log_out.js new file mode 100644 index 0000000000..8e16592937 --- /dev/null +++ b/app/javascript/flavours/glitch/util/log_out.js @@ -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(); +};