diff --git a/app/soapbox/features/federation_restrictions/components/instance_restrictions.js b/app/soapbox/features/federation_restrictions/components/instance_restrictions.js new file mode 100644 index 000000000..595b5a418 --- /dev/null +++ b/app/soapbox/features/federation_restrictions/components/instance_restrictions.js @@ -0,0 +1,177 @@ +'use strict'; + +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import Icon from 'soapbox/components/icon'; + +const hasRestrictions = remoteInstance => { + return remoteInstance + .get('federation') + .deleteAll(['accept', 'reject_deletes', 'report_removal']) + .reduce((acc, value) => acc || value, false); +}; + +const mapStateToProps = state => { + return { + instance: state.get('instance'), + }; +}; + +export default @connect(mapStateToProps) +class InstanceRestrictions extends ImmutablePureComponent { + + static propTypes = { + intl: PropTypes.object.isRequired, + remoteInstance: ImmutablePropTypes.map.isRequired, + instance: ImmutablePropTypes.map, + }; + + renderRestrictions = () => { + const { remoteInstance } = this.props; + const items = []; + + const { + avatar_removal, + banner_removal, + federated_timeline_removal, + followers_only, + media_nsfw, + media_removal, + } = remoteInstance.get('federation').toJS(); + + const fullMediaRemoval = media_removal && avatar_removal && banner_removal; + const partialMediaRemoval = media_removal || avatar_removal || banner_removal; + + if (followers_only) { + items.push(( +
+
+ +
+
+ +
+
+ )); + } else if (federated_timeline_removal) { + items.push(( +
+
+ +
+
+ +
+
+ )); + } + + if (fullMediaRemoval) { + items.push(( +
+
+ +
+
+ +
+
+ )); + } else if (partialMediaRemoval) { + items.push(( +
+
+ +
+
+ +
+
+ )); + } + + if (!fullMediaRemoval && media_nsfw) { + items.push(( +
+
+ +
+
+ +
+
+ )); + } + + return items; + } + + renderContent = () => { + const { instance, remoteInstance } = this.props; + if (!instance || !remoteInstance) return null; + + const host = remoteInstance.get('host'); + const siteTitle = instance.get('title'); + + if (remoteInstance.getIn(['federation', 'reject']) === true) { + return ( +
+ + +
+ ); + } else if (hasRestrictions(remoteInstance)) { + return [ + ( +
+ +
+ ), + this.renderRestrictions(), + ]; + } else { + return ( +
+ + +
+ ); + } + } + + render() { + return
{this.renderContent()}
; + } + +} diff --git a/app/soapbox/features/federation_restrictions/components/restricted_instance.js b/app/soapbox/features/federation_restrictions/components/restricted_instance.js index 30775c10c..cc62f0d7d 100644 --- a/app/soapbox/features/federation_restrictions/components/restricted_instance.js +++ b/app/soapbox/features/federation_restrictions/components/restricted_instance.js @@ -4,6 +4,8 @@ import PropTypes from 'prop-types'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { makeGetRemoteInstance } from 'soapbox/selectors'; import classNames from 'classnames'; +import InstanceRestrictions from './instance_restrictions'; +import Icon from 'soapbox/components/icon'; const getRemoteInstance = makeGetRemoteInstance(); @@ -20,12 +22,36 @@ class RestrictedInstance extends ImmutablePureComponent { host: PropTypes.string.isRequired, } + state = { + expanded: false, + } + + toggleExpanded = e => { + this.setState({ expanded: !this.state.expanded }); + e.preventDefault(); + } + render() { const { remoteInstance } = this.props; + const { expanded } = this.state; return ( -
- {remoteInstance.get('host')} +
+ +
+ +
+
+ {remoteInstance.get('host')} +
+
+
+ +
); } diff --git a/app/styles/components/federation-restrictions.scss b/app/styles/components/federation-restrictions.scss index 5b869c6d5..dab37d89b 100644 --- a/app/styles/components/federation-restrictions.scss +++ b/app/styles/components/federation-restrictions.scss @@ -3,9 +3,55 @@ } .restricted-instance { - padding: 10px 0; + &__header { + padding: 10px 0; + display: flex; + text-decoration: none; + color: var(--primary-text-color); + } - &--reject { + &__icon { + width: 16px; + } + + &--expanded &__icon i.fa { + transform: translateX(-3px); + } + + &--reject &__host { text-decoration: line-through; } + + &__restrictions { + height: 0; + overflow: hidden; + } + + &--expanded &__restrictions { + height: auto; + } + + .instance-restrictions { + padding: 5px 0 5px 15px; + border-left: 3px solid hsla(var(--primary-text-color_hsl), 0.4); + color: var(--primary-text-color--faint); + margin-bottom: 15px; + + .federation-restriction { + padding: 7px 0; + font-size: 14px; + } + + &__message { + margin-bottom: 10px; + + i.fa { + padding-right: 10px; + } + + &:last-child { + margin-bottom: 0; + } + } + } }