@ -5,32 +5,150 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom' ;
import ImmutablePureComponent from 'react-immutable-pure-component' ;
import IconButton from 'soapbox/components/icon_button' ;
import snackbar from 'soapbox/actions/snackbar' ;
import { remoteInteraction } from 'soapbox/actions/interactions' ;
import { getFeatures } from 'soapbox/utils/features' ;
const messages = defineMessages ( {
close : { id : 'lightbox.close' , defaultMessage : 'Close' } ,
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' } ,
} ) ;
const mapStateToProps = state => {
const me = state . get ( 'me' ) ;
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' ] ) ;
return {
account : state . getIn ( [ 'accounts' , me ] ) ,
features ,
siteTitle : state . getIn ( [ 'instance' , 'title' ] ) ,
userName ,
remoteInteractionsAPI : features . remoteInteractionsAPI ,
} ;
} ;
const mapDispatchToProps = dispatch => ( {
dispatch ,
onRemoteInteraction ( ap _id , account ) {
return dispatch ( remoteInteraction ( ap _id , account ) ) ;
} ,
} ) ;
class UnauthorizedModal extends ImmutablePureComponent {
static propTypes = {
intl : PropTypes . object . isRequired ,
features : PropTypes . object . isRequired ,
onClose : PropTypes . func . isRequired ,
onRemoteInteraction : PropTypes . func . isRequired ,
userName : PropTypes . string ,
} ;
state = {
account : '' ,
} ;
onAccountChange = e => {
this . setState ( { account : e . target . value } ) ;
}
onClickClose = ( ) => {
this . props . onClose ( 'UNAUTHORIZED' ) ;
} ;
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 } < / 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 >
< 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 >
< Link to = '/auth/sign_in' className = 'unauthorized-modal-content__button button button-secondary' onClick = { this . onClickClose } >
< FormattedMessage id = 'account.login' defaultMessage = 'Log in' / >
< / L i n k >
< / d i v >
< / d i v >
) ;
}
render ( ) {
const { intl , siteTitle } = this . props ;
const { intl , features , siteTitle } = this . props ;
if ( features . remoteInteractionsAPI && features . federating ) return this . renderRemoteInteractions ( ) ;
return (
< div className = 'modal-root__modal compose-modal unauthorized-modal' >
@ -61,4 +179,4 @@ class UnauthorizedModal extends ImmutablePureComponent {
}
export default injectIntl ( connect ( mapStateToProps )( UnauthorizedModal ) ) ;
export default injectIntl ( connect ( mapStateToProps , mapDispatchToProps )( UnauthorizedModal ) ) ;