2020-03-27 13:59:38 -07:00
import PropTypes from 'prop-types' ;
2022-01-10 14:17:52 -08:00
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' ;
2022-01-10 14:17:52 -08:00
import { connect } from 'react-redux' ;
2022-03-21 11:09:01 -07:00
import { Link , withRouter } from 'react-router-dom' ;
2022-01-10 14:25:06 -08:00
2022-01-02 12:43:53 -08:00
import { remoteInteraction } from 'soapbox/actions/interactions' ;
2022-01-10 14:17:52 -08:00
import snackbar from 'soapbox/actions/snackbar' ;
2022-02-25 07:08:05 -08:00
import { getSoapboxConfig } from 'soapbox/actions/soapbox' ;
2022-01-10 14:17:52 -08:00
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
2022-03-21 11:09:01 -07:00
import { Modal , Stack , Text } from '../../../components/ui' ;
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 ) ;
2022-02-25 07:08:05 -08:00
const soapboxConfig = getSoapboxConfig ( state ) ;
2022-01-02 12:43:53 -08:00
if ( props . action !== 'FOLLOW' ) {
return {
features ,
siteTitle : state . getIn ( [ 'instance' , 'title' ] ) ,
remoteInteractionsAPI : features . remoteInteractionsAPI ,
2022-02-25 07:08:05 -08:00
singleUserMode : soapboxConfig . get ( 'singleUserMode' ) ,
2022-01-02 12:43:53 -08:00
} ;
}
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 ,
2022-02-25 07:08:05 -08:00
singleUserMode : soapboxConfig . get ( 'singleUserMode' ) ,
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 ) ) ;
} ,
} ) ;
2022-03-21 11:09:01 -07:00
@ withRouter
2020-03-27 13:59:38 -07:00
class UnauthorizedModal extends ImmutablePureComponent {
2022-03-21 11:09:01 -07:00
static contextTypes = {
router : PropTypes . object . isRequired ,
} ;
2020-03-27 13:59:38 -07:00
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 ,
2022-02-25 07:08:05 -08:00
singleUserMode : PropTypes . bool ,
2022-01-02 12:43:53 -08:00
} ;
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 ) ) ) ;
}
} ) ;
}
2022-03-21 11:09:01 -07:00
onLogin = ( e ) => {
e . preventDefault ( ) ;
this . context . router . history . push ( '/login' ) ;
this . onClickClose ( ) ;
}
onRegister = ( e ) => {
e . preventDefault ( ) ;
this . context . router . history . push ( '/' ) ;
this . onClickClose ( ) ;
}
2022-01-02 12:43:53 -08:00
renderRemoteInteractions ( ) {
2022-02-25 07:08:05 -08:00
const { intl , siteTitle , userName , action , singleUserMode } = this . props ;
2022-01-02 12:43:53 -08:00
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 } < / h 3 >
< IconButton className = 'compose-modal__close' title = { intl . formatMessage ( messages . close ) } src = { require ( '@tabler/icons/icons/x.svg' ) } onClick = { this . onClickClose } / >
< / d i v >
< 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 } < / b u t t o n >
< / f o r m >
< div className = 'remote-interaction-modal__divider' >
< span >
< FormattedMessage id = 'remote_interaction.divider' defaultMessage = 'or' / >
< / s p a n >
< / d i v >
2022-02-25 07:08:05 -08:00
{ ! singleUserMode && (
< >
< h3 className = 'compose-modal__header__title' > < FormattedMessage id = 'unauthorized_modal.title' defaultMessage = 'Sign up for {site_title}' values = { { site _title : siteTitle } } / > < / h 3 >
< Link to = '/' className = 'unauthorized-modal-content__button button' onClick = { this . onClickClose } >
< FormattedMessage id = 'account.register' defaultMessage = 'Sign up' / >
< / L i n k >
< / >
) }
2022-03-21 11:09:01 -07:00
< Link to = '/login' className = 'unauthorized-modal-content__button button button-secondary' onClick = { this . onClickClose } >
2022-01-02 12:43:53 -08:00
< FormattedMessage id = 'account.login' defaultMessage = 'Log in' / >
< / L i n k >
< / d i v >
< / d i v >
) ;
}
2020-04-14 14:47:35 -07:00
render ( ) {
2022-03-21 11:09:01 -07:00
const { features , siteTitle , action } = this . props ;
2022-01-02 12:43:53 -08:00
2022-01-06 11:55:06 -08:00
if ( action && features . remoteInteractionsAPI && features . federating ) return this . renderRemoteInteractions ( ) ;
2020-03-27 13:59:38 -07:00
return (
2022-03-21 11:09:01 -07:00
< Modal
title = { < FormattedMessage id = 'unauthorized_modal.title' defaultMessage = 'Sign up for {site_title}' values = { { site _title : siteTitle } } / > }
onClose = { this . onClickClose }
confirmationAction = { this . onLogin }
confirmationText = { < FormattedMessage id = 'account.login' defaultMessage = 'Log in' / > }
secondaryAction = { this . onRegister }
secondaryText = { < FormattedMessage id = 'account.register' defaultMessage = 'Sign up' / > }
>
< Stack >
< Text >
< FormattedMessage id = 'unauthorized_modal.text' defaultMessage = 'You need to be logged in to do that.' / >
< / T e x t >
< / S t a c k >
< / M o d a l >
2020-03-27 13:59:38 -07:00
) ;
}
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 ) ) ;