bigbuffet-rw/app/soapbox/features/ui/components/unauthorized_modal.js

183 lines
7.4 KiB
JavaScript
Raw Normal View History

2020-03-27 13:59:38 -07:00
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePureComponent from 'react-immutable-pure-component';
2020-03-27 13:59:38 -07:00
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
2020-06-07 14:55:28 -07:00
import { Link } from 'react-router-dom';
2022-01-02 12:43:53 -08:00
import { remoteInteraction } from 'soapbox/actions/interactions';
import snackbar from 'soapbox/actions/snackbar';
import IconButton from 'soapbox/components/icon_button';
2022-01-02 12:43:53 -08:00
import { getFeatures } from 'soapbox/utils/features';
2020-03-27 13:59:38 -07:00
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
2022-01-02 12:43:53 -08:00
accountPlaceholder: { id: 'remote_interaction.account_placeholder', defaultMessage: 'Enter your username@domain you want to act from' },
userNotFoundError: { id: 'remote_interaction.user_not_found_error', defaultMessage: 'Couldn\'t find given user' },
2020-03-27 13:59:38 -07:00
});
2022-01-02 12:43:53 -08:00
const mapStateToProps = (state, props) => {
const instance = state.get('instance');
const features = getFeatures(instance);
if (props.action !== 'FOLLOW') {
return {
features,
siteTitle: state.getIn(['instance', 'title']),
remoteInteractionsAPI: features.remoteInteractionsAPI,
};
}
const userName = state.getIn(['accounts', props.account, 'display_name']);
2020-03-27 13:59:38 -07:00
return {
2022-01-02 12:43:53 -08:00
features,
2020-04-01 13:31:40 -07:00
siteTitle: state.getIn(['instance', 'title']),
2022-01-02 12:43:53 -08:00
userName,
remoteInteractionsAPI: features.remoteInteractionsAPI,
2020-03-27 13:59:38 -07:00
};
};
2022-01-02 12:43:53 -08:00
const mapDispatchToProps = dispatch => ({
dispatch,
onRemoteInteraction(ap_id, account) {
return dispatch(remoteInteraction(ap_id, account));
},
});
2020-03-27 13:59:38 -07:00
class UnauthorizedModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
2022-01-02 12:43:53 -08:00
features: PropTypes.object.isRequired,
2020-03-27 13:59:38 -07:00
onClose: PropTypes.func.isRequired,
2022-01-02 12:43:53 -08:00
onRemoteInteraction: PropTypes.func.isRequired,
userName: PropTypes.string,
};
state = {
account: '',
2020-03-27 13:59:38 -07:00
};
2022-01-02 12:43:53 -08:00
onAccountChange = e => {
this.setState({ account: e.target.value });
}
2020-03-27 13:59:38 -07:00
onClickClose = () => {
this.props.onClose('UNAUTHORIZED');
};
2022-01-02 12:43:53 -08:00
onClickProceed = e => {
e.preventDefault();
const { intl, ap_id, dispatch, onClose, onRemoteInteraction } = this.props;
const { account } = this.state;
onRemoteInteraction(ap_id, account)
.then(url => {
window.open(url, '_new', 'noopener,noreferrer');
onClose('UNAUTHORIZED');
})
.catch(error => {
if (error.message === 'Couldn\'t find user') {
dispatch(snackbar.error(intl.formatMessage(messages.userNotFoundError)));
}
});
}
renderRemoteInteractions() {
const { intl, siteTitle, userName, action } = this.props;
const { account } = this.state;
let header;
let button;
if (action === 'FOLLOW') {
header = <FormattedMessage id='remote_interaction.follow_title' defaultMessage='Follow {user} remotely' values={{ user: userName }} />;
button = <FormattedMessage id='remote_interaction.follow' defaultMessage='Proceed to follow' />;
} else if (action === 'REPLY') {
header = <FormattedMessage id='remote_interaction.reply_title' defaultMessage='Reply to a post remotely' />;
button = <FormattedMessage id='remote_interaction.reply' defaultMessage='Proceed to reply' />;
} else if (action === 'REBLOG') {
header = <FormattedMessage id='remote_interaction.reblog_title' defaultMessage='Reblog a post remotely' />;
button = <FormattedMessage id='remote_interaction.reblog' defaultMessage='Proceed to repost' />;
} else if (action === 'FAVOURITE') {
header = <FormattedMessage id='remote_interaction.favourite_title' defaultMessage='Like a post remotely' />;
button = <FormattedMessage id='remote_interaction.favourite' defaultMessage='Proceed to like' />;
} else if (action === 'POLL_VOTE') {
header = <FormattedMessage id='remote_interaction.poll_vote_title' defaultMessage='Vote in a poll remotely' />;
button = <FormattedMessage id='remote_interaction.poll_vote' defaultMessage='Proceed to vote' />;
}
return (
<div className='modal-root__modal compose-modal unauthorized-modal remote-interaction-modal'>
<div className='compose-modal__header'>
<h3 className='compose-modal__header__title'>{header}</h3>
<IconButton className='compose-modal__close' title={intl.formatMessage(messages.close)} src={require('@tabler/icons/icons/x.svg')} onClick={this.onClickClose} />
</div>
<div className='remote-interaction-modal__content'>
<form className='simple_form remote-interaction-modal__fields'>
<input
type='text'
placeholder={intl.formatMessage(messages.accountPlaceholder)}
name='remote_follow[acct]'
value={account}
autoCorrect='off'
autoCapitalize='off'
onChange={this.onAccountChange}
required
/>
<button className='button' onClick={this.onClickProceed}>{button}</button>
</form>
<div className='remote-interaction-modal__divider'>
<span>
<FormattedMessage id='remote_interaction.divider' defaultMessage='or' />
</span>
</div>
<h3 className='compose-modal__header__title'><FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{ site_title: siteTitle }} /></h3>
<Link to='/' className='unauthorized-modal-content__button button' onClick={this.onClickClose}>
<FormattedMessage id='account.register' defaultMessage='Sign up' />
</Link>
<Link to='/auth/sign_in' className='unauthorized-modal-content__button button button-secondary' onClick={this.onClickClose}>
<FormattedMessage id='account.login' defaultMessage='Log in' />
</Link>
</div>
</div>
);
}
render() {
const { intl, features, siteTitle, action } = this.props;
2022-01-02 12:43:53 -08:00
if (action && features.remoteInteractionsAPI && features.federating) return this.renderRemoteInteractions();
2020-03-27 13:59:38 -07:00
return (
<div className='modal-root__modal compose-modal unauthorized-modal'>
<div className='compose-modal__header'>
2020-04-14 11:44:40 -07:00
<h3 className='compose-modal__header__title'><FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{ site_title: siteTitle }} /></h3>
<IconButton className='compose-modal__close' title={intl.formatMessage(messages.close)} src={require('@tabler/icons/icons/x.svg')} onClick={this.onClickClose} />
2020-03-27 13:59:38 -07:00
</div>
<div className='compose-modal__content'>
<div className='unauthorized-modal__content'>
<span className='unauthorized-modal-content__text'>
<FormattedMessage id='unauthorized_modal.text' defaultMessage='You need to be logged in to do that.' />
</span>
2020-06-07 14:55:28 -07:00
<Link to='/' className='unauthorized-modal-content__button button'>
2020-03-27 13:59:38 -07:00
<FormattedMessage id='account.register' defaultMessage='Sign up' />
2020-06-07 14:55:28 -07:00
</Link>
2020-03-27 13:59:38 -07:00
</div>
</div>
<div className='unauthorized-modal__footer'>
2020-04-14 11:44:40 -07:00
<FormattedMessage
id='unauthorized_modal.footer' defaultMessage='Already have an account? {login}.' values={{
2020-06-07 14:55:28 -07:00
login: <Link to='/auth/sign_in'><FormattedMessage id='account.login' defaultMessage='Log in' /></Link>,
2020-04-14 11:44:40 -07:00
}}
/>
2020-03-27 13:59:38 -07:00
</div>
</div>
);
}
2020-04-14 11:44:40 -07:00
2020-03-27 13:59:38 -07:00
}
2022-01-02 12:43:53 -08:00
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(UnauthorizedModal));