2020-03-27 13:59:38 -07:00
import React from 'react' ;
import { connect } from 'react-redux' ;
import { defineMessages , injectIntl , FormattedMessage } from 'react-intl' ;
import PropTypes from 'prop-types' ;
import StatusListContainer from '../ui/containers/status_list_container' ;
import Column from '../../components/column' ;
import ColumnSettingsContainer from './containers/column_settings_container' ;
import HomeColumnHeader from '../../components/home_column_header' ;
2020-10-01 13:54:29 -07:00
import Accordion from 'soapbox/features/ui/components/accordion' ;
2020-04-14 13:45:38 -07:00
import { expandPublicTimeline } from '../../actions/timelines' ;
import { connectPublicStream } from '../../actions/streaming' ;
2020-03-27 13:59:38 -07:00
import { Link } from 'react-router-dom' ;
2020-10-01 13:54:29 -07:00
import { changeSetting , getSettings } from 'soapbox/actions/settings' ;
2020-03-27 13:59:38 -07:00
const messages = defineMessages ( {
title : { id : 'column.public' , defaultMessage : 'Federated timeline' } ,
2021-04-26 10:11:47 -07:00
dismiss : { id : 'fediverse_tab.explanation_box.dismiss' , defaultMessage : 'Don\'t show again' } ,
2020-03-27 13:59:38 -07:00
} ) ;
const mapStateToProps = state => {
2020-10-01 13:54:29 -07:00
const settings = getSettings ( state ) ;
const onlyMedia = settings . getIn ( [ 'public' , 'other' , 'onlyMedia' ] ) ;
2020-03-27 13:59:38 -07:00
const timelineId = 'public' ;
return {
timelineId ,
onlyMedia ,
hasUnread : state . getIn ( [ 'timelines' , ` ${ timelineId } ${ onlyMedia ? ':media' : '' } ` , 'unread' ] ) > 0 ,
2020-04-01 13:31:40 -07:00
siteTitle : state . getIn ( [ 'instance' , 'title' ] ) ,
2020-10-01 13:54:29 -07:00
explanationBoxExpanded : settings . get ( 'explanationBox' ) ,
2021-04-26 10:11:47 -07:00
showExplanationBox : settings . get ( 'showExplanationBox' ) ,
2020-03-27 13:59:38 -07:00
} ;
} ;
export default @ connect ( mapStateToProps )
@ injectIntl
class CommunityTimeline extends React . PureComponent {
static contextTypes = {
router : PropTypes . object ,
} ;
static propTypes = {
dispatch : PropTypes . func . isRequired ,
intl : PropTypes . object . isRequired ,
hasUnread : PropTypes . bool ,
onlyMedia : PropTypes . bool ,
timelineId : PropTypes . string ,
2020-04-14 14:37:17 -07:00
siteTitle : PropTypes . string ,
2021-04-26 10:11:47 -07:00
showExplanationBox : PropTypes . bool ,
2020-10-01 13:54:29 -07:00
explanationBoxExpanded : PropTypes . bool ,
2020-03-27 13:59:38 -07:00
} ;
2020-04-14 14:47:35 -07:00
componentDidMount ( ) {
2020-03-27 13:59:38 -07:00
const { dispatch , onlyMedia } = this . props ;
dispatch ( expandPublicTimeline ( { onlyMedia } ) ) ;
this . disconnect = dispatch ( connectPublicStream ( { onlyMedia } ) ) ;
}
2020-04-14 14:47:35 -07:00
componentDidUpdate ( prevProps ) {
2020-03-27 13:59:38 -07:00
if ( prevProps . onlyMedia !== this . props . onlyMedia ) {
const { dispatch , onlyMedia } = this . props ;
this . disconnect ( ) ;
dispatch ( expandPublicTimeline ( { onlyMedia } ) ) ;
this . disconnect = dispatch ( connectPublicStream ( { onlyMedia } ) ) ;
}
}
2020-04-14 14:47:35 -07:00
componentWillUnmount ( ) {
2020-03-27 13:59:38 -07:00
if ( this . disconnect ) {
this . disconnect ( ) ;
this . disconnect = null ;
}
}
2021-04-26 10:11:47 -07:00
explanationBoxMenu = ( ) => {
const { intl } = this . props ;
return [ { text : intl . formatMessage ( messages . dismiss ) , action : this . dismissExplanationBox } ] ;
}
dismissExplanationBox = ( ) => {
this . props . dispatch ( changeSetting ( [ 'showExplanationBox' ] , false ) ) ;
}
2020-10-01 13:54:29 -07:00
toggleExplanationBox = ( setting ) => {
this . props . dispatch ( changeSetting ( [ 'explanationBox' ] , setting ) ) ;
}
2020-03-27 13:59:38 -07:00
handleLoadMore = maxId => {
const { dispatch , onlyMedia } = this . props ;
dispatch ( expandPublicTimeline ( { maxId , onlyMedia } ) ) ;
}
2020-04-14 14:47:35 -07:00
render ( ) {
2021-04-26 10:11:47 -07:00
const { intl , hasUnread , onlyMedia , timelineId , siteTitle , showExplanationBox , explanationBoxExpanded } = this . props ;
2020-03-27 13:59:38 -07:00
return (
< Column label = { intl . formatMessage ( messages . title ) } >
< HomeColumnHeader activeItem = 'fediverse' active = { hasUnread } >
< ColumnSettingsContainer / >
< / H o m e C o l u m n H e a d e r >
2021-04-26 10:11:47 -07:00
{ showExplanationBox && < div className = 'explanation-box' >
2020-10-01 13:54:29 -07:00
< Accordion
headline = { < FormattedMessage id = 'fediverse_tab.explanation_box.title' defaultMessage = 'What is the Fediverse?' / > }
2021-04-26 10:11:47 -07:00
menu = { this . explanationBoxMenu ( ) }
2020-10-01 13:54:29 -07:00
expanded = { explanationBoxExpanded }
onToggle = { this . toggleExplanationBox }
2020-12-31 18:18:57 -08:00
>
< FormattedMessage
id = 'fediverse_tab.explanation_box.explanation'
defaultMessage = '{site_title} is part of the Fediverse, a social network made up of thousands of independent social media sites (aka "servers"). The posts you see here are from 3rd-party servers. You have the freedom to engage with them, or to block any server you don't like. Pay attention to the full username after the second @ symbol to know which server a post is from. To see only {site_title} posts, visit {local}.'
values = { {
site _title : siteTitle ,
local : (
< Link to = '/timeline/local' >
< FormattedMessage
id = 'empty_column.home.local_tab'
defaultMessage = 'the {site_title} tab'
values = { { site _title : siteTitle } }
/ >
< / L i n k >
) ,
} }
/ >
< / A c c o r d i o n >
2021-04-26 10:11:47 -07:00
< / d i v > }
2020-03-27 13:59:38 -07:00
< StatusListContainer
scrollKey = { ` ${ timelineId } _timeline ` }
timelineId = { ` ${ timelineId } ${ onlyMedia ? ':media' : '' } ` }
onLoadMore = { this . handleLoadMore }
emptyMessage = { < FormattedMessage id = 'empty_column.public' defaultMessage = 'There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' / > }
/ >
< / C o l u m n >
) ;
}
}