2019-08-07 06:02:36 +01:00
import ReactSwipeableViews from 'react-swipeable-views' ;
import classNames from 'classnames' ;
import { FormattedMessage } from 'react-intl' ;
2020-03-04 23:08:08 +00:00
import { closeOnboarding } from '../actions/onboarding' ;
2019-08-07 06:02:36 +01:00
2020-03-25 03:08:43 +00:00
// : todo :
2020-04-08 02:06:59 +01:00
class FrameWelcome extends React . Component {
2019-08-07 06:02:36 +01:00
static propTypes = {
domain : PropTypes . string . isRequired ,
onNext : PropTypes . func . isRequired ,
} ;
shouldComponentUpdate ( nextProps ) {
2020-01-29 21:53:33 +00:00
return nextProps . domain !== this . props . domain ;
2019-08-07 06:02:36 +01:00
}
render ( ) {
const { domain , onNext } = this . props ;
return (
< div className = 'introduction__frame' >
< div className = 'introduction__text introduction__text--centered' >
< h3 >
< FormattedMessage id = 'introduction.welcome.headline' defaultMessage = 'First steps' / >
< / h 3 >
< p >
< FormattedMessage
id = 'introduction.welcome.text'
defaultMessage = "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name."
values = { {
domain : < code > { domain } < / c o d e >
} }
/ >
< / p >
< / d i v >
< div className = 'introduction__action' >
< button className = 'button' onClick = { onNext } >
< FormattedMessage id = 'introduction.welcome.action' defaultMessage = "Let's go!" / >
< / b u t t o n >
< / d i v >
< / d i v >
) ;
}
}
2020-04-08 02:06:59 +01:00
class FrameFederation extends React . Component {
2019-08-07 06:02:36 +01:00
static propTypes = {
onNext : PropTypes . func . isRequired ,
}
shouldComponentUpdate ( ) {
2020-01-29 21:53:33 +00:00
return false ;
2019-08-07 06:02:36 +01:00
}
render ( ) {
return (
< div className = 'introduction__frame' >
< div className = 'introduction__text introduction__text--columnized' >
< div >
< h3 >
< FormattedMessage id = 'introduction.federation.home.headline' defaultMessage = 'Home' / >
< / h 3 >
< p >
< FormattedMessage
id = 'introduction.federation.home.text'
defaultMessage = 'Posts from people you follow will appear in your home feed. You can follow anyone on any server!'
/ >
< / p >
< / d i v >
< / d i v >
< div className = 'introduction__action' >
< button className = 'button' onClick = { onNext } >
< FormattedMessage id = 'introduction.federation.action' defaultMessage = 'Next' / >
< / b u t t o n >
< / d i v >
< / d i v >
)
}
} ;
2020-04-08 02:06:59 +01:00
class FrameInteractions extends React . Component {
2019-08-07 06:02:36 +01:00
static propTypes = {
onNext : PropTypes . func . isRequired ,
} ;
shouldComponentUpdate ( ) {
return false ;
}
render ( ) {
return (
< div className = 'introduction__frame' >
< div className = 'introduction__text introduction__text--columnized' >
< div >
< h3 >
< FormattedMessage id = 'introduction.interactions.reply.headline' defaultMessage = 'Reply' / >
< / h 3 >
< p >
< FormattedMessage
id = 'introduction.interactions.reply.text'
defaultMessage = "You can reply to other people's and your own gabs, which will chain them together in a conversation."
/ >
< / p >
< / d i v >
< div >
< h3 >
2020-03-04 22:50:15 +00:00
< FormattedMessage id = 'introduction.interactions.repost.headline' defaultMessage = 'Repost' / >
2019-08-07 06:02:36 +01:00
< / h 3 >
< p >
2020-03-04 22:50:15 +00:00
< FormattedMessage id = 'introduction.interactions.repost.text' defaultMessage = "You can share other people's gabs with your followers by reposting them." / >
2019-08-07 06:02:36 +01:00
< / p >
< / d i v >
< div >
< h3 >
2020-03-04 22:26:01 +00:00
< FormattedMessage id = 'introduction.interactions.favorite.headline' defaultMessage = 'Favorite' / >
2019-08-07 06:02:36 +01:00
< / h 3 >
< p >
2020-03-04 22:26:01 +00:00
< FormattedMessage id = 'introduction.interactions.favorite.text' defaultMessage = 'You can save a gab for later, and let the author know that you liked it, by favoriting it.' / >
2019-08-07 06:02:36 +01:00
< / p >
< / d i v >
< / d i v >
< div className = 'introduction__action' >
< button className = 'button' onClick = { onNext } >
< FormattedMessage id = 'introduction.interactions.action' defaultMessage = 'Finish tutorial!' / >
< / b u t t o n >
< / d i v >
< / d i v >
) ;
}
}
2020-02-25 16:04:44 +00:00
export default
@ connect ( state => ( { domain : state . getIn ( [ 'meta' , 'domain' ] ) } ) )
2019-08-07 06:02:36 +01:00
class Introduction extends PureComponent {
static propTypes = {
domain : PropTypes . string . isRequired ,
dispatch : PropTypes . func . isRequired ,
} ;
state = {
currentIndex : 0 ,
} ;
componentWillMount ( ) {
this . pages = [
< FrameWelcome domain = { this . props . domain } onNext = { this . handleNext } / > ,
< FrameFederation onNext = { this . handleNext } / > ,
< FrameInteractions onNext = { this . handleFinish } / > ,
] ;
}
componentDidMount ( ) {
window . addEventListener ( 'keyup' , this . handleKeyUp ) ;
}
componentWillUnmount ( ) {
window . addEventListener ( 'keyup' , this . handleKeyUp ) ;
}
handleDot = ( e ) => {
const i = Number ( e . currentTarget . getAttribute ( 'data-index' ) ) ;
e . preventDefault ( ) ;
this . setState ( { currentIndex : i } ) ;
}
handlePrev = ( ) => {
this . setState ( ( { currentIndex } ) => ( {
currentIndex : Math . max ( 0 , currentIndex - 1 ) ,
} ) ) ;
}
handleNext = ( ) => {
const { pages } = this ;
this . setState ( ( { currentIndex } ) => ( {
currentIndex : Math . min ( currentIndex + 1 , pages . length - 1 ) ,
} ) ) ;
}
handleSwipe = ( index ) => {
this . setState ( { currentIndex : index } ) ;
}
handleFinish = ( ) => {
this . props . dispatch ( closeOnboarding ( ) ) ;
}
handleKeyUp = ( { key } ) => {
switch ( key ) {
case 'ArrowLeft' :
this . handlePrev ( ) ;
break ;
case 'ArrowRight' :
this . handleNext ( ) ;
break ;
}
}
render ( ) {
const { currentIndex } = this . state ;
const { pages } = this ;
return (
< div className = 'introduction' >
< ReactSwipeableViews index = { currentIndex } onChangeIndex = { this . handleSwipe } className = 'introduction__pager' >
{ pages . map ( ( page , i ) => (
< div key = { i } className = { classNames ( 'introduction__frame-wrapper' , { 'active' : i === currentIndex } ) } > { page } < / d i v >
) ) }
< / R e a c t S w i p e a b l e V i e w s >
< div className = 'introduction__dots' >
{ pages . map ( ( _ , i ) => (
< div
key = { ` dot- ${ i } ` }
role = 'button'
tabIndex = '0'
data - index = { i }
onClick = { this . handleDot }
className = { classNames ( 'introduction__dot' , { active : i === currentIndex } ) }
/ >
) ) }
< / d i v >
< / d i v >
) ;
}
}