2021-07-25 12:50:22 -07:00
import React from 'react' ;
import { connect } from 'react-redux' ;
import { defineMessages , injectIntl } from 'react-intl' ;
import PropTypes from 'prop-types' ;
import ImmutablePureComponent from 'react-immutable-pure-component' ;
import Column from '../ui/components/column' ;
import { createSelector } from 'reselect' ;
import { Map as ImmutableMap , OrderedSet as ImmutableOrderedSet } from 'immutable' ;
2021-07-25 13:08:14 -07:00
import RestrictedInstance from './components/restricted_instance' ;
2021-07-25 14:16:37 -07:00
import Accordion from 'soapbox/features/ui/components/accordion' ;
2021-07-26 09:46:44 -07:00
import ScrollableList from 'soapbox/components/scrollable_list' ;
import { federationRestrictionsDisclosed } from 'soapbox/utils/state' ;
2021-07-25 12:50:22 -07:00
const getHosts = createSelector ( [
state => state . getIn ( [ 'instance' , 'pleroma' , 'metadata' , 'federation' , 'mrf_simple' ] , ImmutableMap ( ) ) ,
] , ( simplePolicy ) => {
return simplePolicy
. deleteAll ( [ 'accept' , 'reject_deletes' , 'report_removal' ] )
. reduce ( ( acc , hosts ) => acc . union ( hosts ) , ImmutableOrderedSet ( ) )
. sort ( ) ;
} ) ;
const messages = defineMessages ( {
heading : { id : 'column.federation_restrictions' , defaultMessage : 'Federation Restrictions' } ,
2021-07-25 14:16:37 -07:00
boxTitle : { id : 'federation_restrictions.explanation_box.title' , defaultMessage : 'Instance-specific policies' } ,
boxMessage : { id : 'federation_restrictions.explanation_box.message' , defaultMessage : 'Normally servers on the Fediverse can communicate freely. {siteTitle} has imposed restrictions on the following servers.' } ,
2021-07-26 09:46:44 -07:00
emptyMessage : { id : 'federation_restrictions.empty_message' , defaultMessage : '{siteTitle} has not restricted any instances.' } ,
notDisclosed : { id : 'federation_restrictions.not_disclosed_message' , defaultMessage : '{siteTitle} does not disclose federation restrictions through the API.' } ,
2021-07-25 12:50:22 -07:00
} ) ;
const mapStateToProps = state => ( {
siteTitle : state . getIn ( [ 'instance' , 'title' ] ) ,
hosts : getHosts ( state ) ,
2021-07-26 09:46:44 -07:00
disclosed : federationRestrictionsDisclosed ( state ) ,
2021-07-25 12:50:22 -07:00
} ) ;
export default @ connect ( mapStateToProps )
@ injectIntl
class FederationRestrictions extends ImmutablePureComponent {
static propTypes = {
intl : PropTypes . object . isRequired ,
2021-07-26 09:46:44 -07:00
disclosed : PropTypes . bool ,
2021-07-25 12:50:22 -07:00
} ;
2021-07-25 14:16:37 -07:00
state = {
explanationBoxExpanded : true ,
}
toggleExplanationBox = setting => {
this . setState ( { explanationBoxExpanded : setting } ) ;
}
2021-07-25 12:50:22 -07:00
render ( ) {
2021-07-26 09:46:44 -07:00
const { intl , hosts , siteTitle , disclosed } = this . props ;
2021-07-25 14:16:37 -07:00
const { explanationBoxExpanded } = this . state ;
2021-07-25 12:50:22 -07:00
2021-07-26 09:46:44 -07:00
const emptyMessage = disclosed ? messages . emptyMessage : messages . notDisclosed ;
2021-07-25 12:50:22 -07:00
return (
< Column icon = 'gavel' heading = { intl . formatMessage ( messages . heading ) } backBtnSlim >
2021-07-25 14:16:37 -07:00
< div className = 'explanation-box' >
< Accordion
headline = { intl . formatMessage ( messages . boxTitle ) }
expanded = { explanationBoxExpanded }
onToggle = { this . toggleExplanationBox }
>
{ intl . formatMessage ( messages . boxMessage , { siteTitle } ) }
< / A c c o r d i o n >
< / d i v >
2021-07-25 12:50:22 -07:00
< div className = 'federation-restrictions' >
2021-07-26 09:46:44 -07:00
< ScrollableList emptyMessage = { intl . formatMessage ( emptyMessage , { siteTitle } ) } >
{ hosts . map ( host => < RestrictedInstance key = { host } host = { host } / > ) }
< / S c r o l l a b l e L i s t >
2021-07-25 12:50:22 -07:00
< / d i v >
< / C o l u m n >
) ;
}
}