2022-10-07 08:14:31 +00:00
import PropTypes from 'prop-types' ;
2023-05-23 15:15:17 +00:00
import { PureComponent } from 'react' ;
2022-10-07 08:14:31 +00:00
import { FormattedMessage } from 'react-intl' ;
2023-05-23 15:15:17 +00:00
2022-10-07 08:14:31 +00:00
import classNames from 'classnames' ;
2023-05-23 15:15:17 +00:00
import { connect } from 'react-redux' ;
2022-10-26 17:35:55 +00:00
import { openModal , closeModal } from 'mastodon/actions/modal' ;
2023-05-23 15:15:17 +00:00
import { Icon } from 'mastodon/components/icon' ;
import { registrationsOpen } from 'mastodon/initial_state' ;
2022-10-07 08:14:31 +00:00
const mapStateToProps = ( state , { accountId } ) => ( {
displayNameHtml : state . getIn ( [ 'accounts' , accountId , 'display_name_html' ] ) ,
2023-05-30 17:01:42 +00:00
signupUrl : state . getIn ( [ 'server' , 'server' , 'registrations' , 'url' ] , null ) || '/auth/sign_up' ,
2022-10-07 08:14:31 +00:00
} ) ;
2022-10-26 17:35:55 +00:00
const mapDispatchToProps = ( dispatch ) => ( {
onSignupClick ( ) {
2023-05-25 13:42:37 +00:00
dispatch ( closeModal ( {
modalType : undefined ,
ignoreFocus : false ,
} ) ) ;
dispatch ( openModal ( { modalType : 'CLOSED_REGISTRATIONS' } ) ) ;
2022-10-26 17:35:55 +00:00
} ,
} ) ;
2023-05-23 08:52:27 +00:00
class Copypaste extends PureComponent {
2022-10-07 08:14:31 +00:00
static propTypes = {
value : PropTypes . string ,
} ;
state = {
copied : false ,
} ;
setRef = c => {
this . input = c ;
2023-01-30 00:45:35 +00:00
} ;
2022-10-07 08:14:31 +00:00
handleInputClick = ( ) => {
this . setState ( { copied : false } ) ;
this . input . focus ( ) ;
this . input . select ( ) ;
this . input . setSelectionRange ( 0 , this . input . value . length ) ;
2023-01-30 00:45:35 +00:00
} ;
2022-10-07 08:14:31 +00:00
handleButtonClick = ( ) => {
const { value } = this . props ;
navigator . clipboard . writeText ( value ) ;
this . input . blur ( ) ;
this . setState ( { copied : true } ) ;
this . timeout = setTimeout ( ( ) => this . setState ( { copied : false } ) , 700 ) ;
2023-01-30 00:45:35 +00:00
} ;
2022-10-07 08:14:31 +00:00
componentWillUnmount ( ) {
if ( this . timeout ) clearTimeout ( this . timeout ) ;
}
render ( ) {
const { value } = this . props ;
const { copied } = this . state ;
return (
< div className = { classNames ( 'copypaste' , { copied } ) } >
< input
type = 'text'
ref = { this . setRef }
value = { value }
readOnly
onClick = { this . handleInputClick }
/ >
< button className = 'button' onClick = { this . handleButtonClick } >
{ copied ? < FormattedMessage id = 'copypaste.copied' defaultMessage = 'Copied' / > : < FormattedMessage id = 'copypaste.copy' defaultMessage = 'Copy' / > }
< / button >
< / div >
) ;
}
}
2023-05-23 08:52:27 +00:00
class InteractionModal extends PureComponent {
2022-10-07 08:14:31 +00:00
static propTypes = {
displayNameHtml : PropTypes . string ,
url : PropTypes . string ,
type : PropTypes . oneOf ( [ 'reply' , 'reblog' , 'favourite' , 'follow' ] ) ,
2022-10-26 17:35:55 +00:00
onSignupClick : PropTypes . func . isRequired ,
2023-05-23 13:17:09 +00:00
signupUrl : PropTypes . string . isRequired ,
2022-10-07 08:14:31 +00:00
} ;
2022-10-26 17:35:55 +00:00
handleSignupClick = ( ) => {
this . props . onSignupClick ( ) ;
2023-01-30 00:45:35 +00:00
} ;
2022-10-26 17:35:55 +00:00
2022-10-07 08:14:31 +00:00
render ( ) {
2023-05-23 13:17:09 +00:00
const { url , type , displayNameHtml , signupUrl } = this . props ;
2022-10-07 08:14:31 +00:00
const name = < bdi dangerouslySetInnerHTML = { { _ _html : displayNameHtml } } / > ;
let title , actionDescription , icon ;
switch ( type ) {
case 'reply' :
icon = < Icon id = 'reply' / > ;
title = < FormattedMessage id = 'interaction_modal.title.reply' defaultMessage = "Reply to {name}'s post" values = { { name } } / > ;
actionDescription = < FormattedMessage id = 'interaction_modal.description.reply' defaultMessage = 'With an account on Mastodon, you can respond to this post.' / > ;
break ;
case 'reblog' :
icon = < Icon id = 'retweet' / > ;
title = < FormattedMessage id = 'interaction_modal.title.reblog' defaultMessage = "Boost {name}'s post" values = { { name } } / > ;
actionDescription = < FormattedMessage id = 'interaction_modal.description.reblog' defaultMessage = 'With an account on Mastodon, you can boost this post to share it with your own followers.' / > ;
break ;
case 'favourite' :
icon = < Icon id = 'star' / > ;
title = < FormattedMessage id = 'interaction_modal.title.favourite' defaultMessage = "Favourite {name}'s post" values = { { name } } / > ;
actionDescription = < FormattedMessage id = 'interaction_modal.description.favourite' defaultMessage = 'With an account on Mastodon, you can favourite this post to let the author know you appreciate it and save it for later.' / > ;
break ;
case 'follow' :
icon = < Icon id = 'user-plus' / > ;
title = < FormattedMessage id = 'interaction_modal.title.follow' defaultMessage = 'Follow {name}' values = { { name } } / > ;
actionDescription = < FormattedMessage id = 'interaction_modal.description.follow' defaultMessage = 'With an account on Mastodon, you can follow {name} to receive their posts in your home feed.' values = { { name } } / > ;
break ;
}
2022-10-26 17:35:55 +00:00
let signupButton ;
if ( registrationsOpen ) {
signupButton = (
2023-05-23 13:17:09 +00:00
< a href = { signupUrl } className = 'button button--block button-tertiary' >
2022-10-26 17:35:55 +00:00
< FormattedMessage id = 'sign_in_banner.create_account' defaultMessage = 'Create account' / >
< / a >
) ;
} else {
signupButton = (
< button className = 'button button--block button-tertiary' onClick = { this . handleSignupClick } >
< FormattedMessage id = 'sign_in_banner.create_account' defaultMessage = 'Create account' / >
< / button >
) ;
}
2022-10-07 08:14:31 +00:00
return (
< div className = 'modal-root__modal interaction-modal' >
< div className = 'interaction-modal__lead' >
< h3 > < span className = 'interaction-modal__icon' > { icon } < / span > { title } < / h3 >
< p > { actionDescription } < FormattedMessage id = 'interaction_modal.preamble' defaultMessage = "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one." / > < / p >
< / div >
< div className = 'interaction-modal__choices' >
< div className = 'interaction-modal__choices__choice' >
< h3 > < FormattedMessage id = 'interaction_modal.on_this_server' defaultMessage = 'On this server' / > < / h3 >
2023-05-10 18:17:55 +00:00
< a href = '/auth/sign_in' className = 'button button--block' > < FormattedMessage id = 'sign_in_banner.sign_in' defaultMessage = 'Login' / > < / a >
2022-10-26 17:35:55 +00:00
{ signupButton }
2022-10-07 08:14:31 +00:00
< / div >
< div className = 'interaction-modal__choices__choice' >
< h3 > < FormattedMessage id = 'interaction_modal.on_another_server' defaultMessage = 'On a different server' / > < / h3 >
2022-11-10 07:49:48 +00:00
< p > < FormattedMessage id = 'interaction_modal.other_server_instructions' defaultMessage = 'Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.' / > < / p >
2022-10-07 08:14:31 +00:00
< Copypaste value = { url } / >
< / div >
< / div >
< / div >
) ;
}
}
2023-03-24 02:17:53 +00:00
export default connect ( mapStateToProps , mapDispatchToProps ) ( InteractionModal ) ;