import PropTypes from 'prop-types'; import { PureComponent } from 'react'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { Helmet } from 'react-helmet'; import { List as ImmutableList } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import DisabledIcon from '@/material-icons/400-24px/close-fill.svg?react'; import EnabledIcon from '@/material-icons/400-24px/done-fill.svg?react'; import ExpandMoreIcon from '@/material-icons/400-24px/expand_more.svg?react'; import { fetchServer, fetchExtendedDescription, fetchDomainBlocks } from 'mastodon/actions/server'; import { Account } from 'mastodon/components/account'; import Column from 'mastodon/components/column'; import { Icon } from 'mastodon/components/icon'; import { ServerHeroImage } from 'mastodon/components/server_hero_image'; import { Skeleton } from 'mastodon/components/skeleton'; import { LinkFooter} from 'mastodon/features/ui/components/link_footer'; const messages = defineMessages({ title: { id: 'column.about', defaultMessage: 'About' }, rules: { id: 'about.rules', defaultMessage: 'Server rules' }, blocks: { id: 'about.blocks', defaultMessage: 'Moderated servers' }, fullTextSearch: { id: 'about.full_text_search', defaultMessage: 'Full text search' }, localTimeline: { id: 'column.community', defaultMessage: 'Local timeline' }, noop: { id: 'about.domain_blocks.noop.title', defaultMessage: 'Soft limited' }, noopExplanation: { id: 'about.domain_blocks.noop.explanation', defaultMessage: 'This server is limited partically.' }, silenced: { id: 'about.domain_blocks.silenced.title', defaultMessage: 'Limited' }, silencedExplanation: { id: 'about.domain_blocks.silenced.explanation', defaultMessage: 'You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.' }, suspended: { id: 'about.domain_blocks.suspended.title', defaultMessage: 'Suspended' }, suspendedExplanation: { id: 'about.domain_blocks.suspended.explanation', defaultMessage: 'No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.' }, publicUnlistedVisibility: { id: 'privacy.public_unlisted.short', defaultMessage: 'Local public' }, publicVisibility: { id: 'about.public_visibility', defaultMessage: 'Public visibility' }, emojiReaction: { id: 'status.emoji_reaction', defaultMessage: 'Emoji reaction' }, enabled: { id: 'about.enabled', defaultMessage: 'Enabled' }, disabled: { id: 'about.disabled', defaultMessage: 'Disabled' }, capabilities: { id: 'about.kmyblue_capabilities', defaultMessage: 'Features available in this server' }, }); const severityMessages = { silence: { title: messages.silenced, explanation: messages.silencedExplanation, }, suspend: { title: messages.suspended, explanation: messages.suspendedExplanation, }, noop: { title: messages.noop, explanation: messages.noopExplanation, }, }; const mapStateToProps = state => ({ server: state.getIn(['server', 'server']), extendedDescription: state.getIn(['server', 'extendedDescription']), domainBlocks: state.getIn(['server', 'domainBlocks']), }); class Section extends PureComponent { static propTypes = { title: PropTypes.string, children: PropTypes.node, open: PropTypes.bool, onOpen: PropTypes.func, }; state = { collapsed: !this.props.open, }; handleClick = () => { const { onOpen } = this.props; const { collapsed } = this.state; this.setState({ collapsed: !collapsed }, () => onOpen && onOpen()); }; render () { const { title, children } = this.props; const { collapsed } = this.state; return (
{title}
{!collapsed && (
{children}
)}
); } } class CapabilityIcon extends PureComponent { static propTypes = { intl: PropTypes.object.isRequired, state: PropTypes.bool, }; render () { const { intl, state } = this.props; if (state) { return ( {intl.formatMessage(messages.enabled)} ); } else { return ( {intl.formatMessage(messages.disabled)} ); } } } class About extends PureComponent { static propTypes = { server: ImmutablePropTypes.map, extendedDescription: ImmutablePropTypes.map, domainBlocks: ImmutablePropTypes.contains({ isLoading: PropTypes.bool, isAvailable: PropTypes.bool, items: ImmutablePropTypes.list, }), dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, multiColumn: PropTypes.bool, }; componentDidMount () { const { dispatch } = this.props; dispatch(fetchServer()); dispatch(fetchExtendedDescription()); } handleDomainBlocksOpen = () => { const { dispatch } = this.props; dispatch(fetchDomainBlocks()); }; render () { const { multiColumn, intl, server, extendedDescription, domainBlocks } = this.props; const isLoading = server.get('isLoading'); const fedibirdCapabilities = server.get('fedibird_capabilities') || []; // thinking about isLoading is true const isPublicUnlistedVisibility = fedibirdCapabilities.includes('kmyblue_visibility_public_unlisted'); const isPublicVisibility = !fedibirdCapabilities.includes('kmyblue_no_public_visibility'); const isEmojiReaction = fedibirdCapabilities.includes('emoji_reaction'); const isLocalTimeline = !fedibirdCapabilities.includes('timeline_no_local'); const isFullTextSearch = server.getIn(['configuration', 'search', 'enabled']); const email = server.getIn(['contact', 'email']) || ''; const emailLink = email.startsWith('https://') ? email : `mailto:${email}`; return (
`${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />

{isLoading ? : server.get('domain')}


{isLoading ? : {server.getIn(['contact', 'email'])}}
{extendedDescription.get('isLoading') ? ( <>


) : (extendedDescription.get('content')?.length > 0 ? (
) : (

))}
{!isLoading && (server.get('rules', ImmutableList()).isEmpty() ? (

) : (
    {server.get('rules').map(rule => (
  1. {rule.get('text')}
    {rule.get('hint').length > 0 && (
    {rule.get('hint')}
    )}
  2. ))}
))}

{!isLoading && (
  1. {intl.formatMessage(messages.emojiReaction)}:
  2. {intl.formatMessage(messages.publicVisibility)}:
  3. {intl.formatMessage(messages.publicUnlistedVisibility)}:
  4. {intl.formatMessage(messages.localTimeline)}:
  5. {intl.formatMessage(messages.fullTextSearch)}:
)}
{domainBlocks.get('isLoading') ? ( <>
) : (domainBlocks.get('isAvailable') ? ( <>

{domainBlocks.get('items').size > 0 && (
{domainBlocks.get('items').map(block => (
{block.get('domain')}
{intl.formatMessage(severityMessages[block.get('severity_ex') || block.get('severity')].title)}

{(block.get('comment') || '').length > 0 ? block.get('comment') : }

))}
)} ) : (

))}

{intl.formatMessage(messages.title)}
); } } export default connect(mapStateToProps)(injectIntl(About));