Fix
This commit is contained in:
parent
ab55cad02e
commit
be07032ad7
1 changed files with 159 additions and 71 deletions
|
@ -14,13 +14,13 @@ 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 { 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 { 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';
|
||||
import { LinkFooter } from 'mastodon/features/ui/components/link_footer';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.about', defaultMessage: 'About' },
|
||||
|
@ -40,6 +40,10 @@ const messages = defineMessages({
|
|||
enabled: { id: 'about.enabled', defaultMessage: 'Enabled' },
|
||||
disabled: { id: 'about.disabled', defaultMessage: 'Disabled' },
|
||||
capabilities: { id: 'about.kmyblue_capabilities', defaultMessage: 'Features available in this server' },
|
||||
joinFediverse: {
|
||||
id: 'about.join_fediverse',
|
||||
defaultMessage: "Join the Fediverse, become part of a community, and break free from Big Tech™'s stranglehold on public discourse."
|
||||
},
|
||||
});
|
||||
|
||||
const severityMessages = {
|
||||
|
@ -59,14 +63,13 @@ const severityMessages = {
|
|||
},
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
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,
|
||||
|
@ -85,49 +88,64 @@ class Section extends PureComponent {
|
|||
this.setState({ collapsed: !collapsed }, () => onOpen && onOpen());
|
||||
};
|
||||
|
||||
render () {
|
||||
handleKeyDown = (e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
this.handleClick();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { title, children } = this.props;
|
||||
const { collapsed } = this.state;
|
||||
|
||||
return (
|
||||
<div className={classNames('about__section', { active: !collapsed })}>
|
||||
<div className='about__section__title' role='button' tabIndex={0} onClick={this.handleClick}>
|
||||
<div
|
||||
className="about__section__title"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={this.handleClick}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
aria-expanded={!collapsed}
|
||||
>
|
||||
<Icon id={collapsed ? 'chevron-right' : 'chevron-down'} icon={collapsed ? ChevronRightIcon : ExpandMoreIcon} /> {title}
|
||||
</div>
|
||||
|
||||
{!collapsed && (
|
||||
<div className='about__section__body'>{children}</div>
|
||||
)}
|
||||
{!collapsed && <div className="about__section__body">{children}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CapabilityIcon extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
state: PropTypes.bool,
|
||||
};
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { intl, state } = this.props;
|
||||
|
||||
if (state) {
|
||||
return (
|
||||
<span className='capability-icon enabled'><Icon id='check' icon={EnabledIcon} title={intl.formatMessage(messages.enabled)} />{intl.formatMessage(messages.enabled)}</span>
|
||||
<span className="capability-icon enabled">
|
||||
<Icon id="check" icon={EnabledIcon} title={intl.formatMessage(messages.enabled)} />
|
||||
{intl.formatMessage(messages.enabled)}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className='capability-icon disabled'><Icon id='times' icon={DisabledIcon} title={intl.formatMessage(messages.disabled)} />{intl.formatMessage(messages.disabled)}</span>
|
||||
<span className="capability-icon disabled">
|
||||
<Icon id="times" icon={DisabledIcon} title={intl.formatMessage(messages.disabled)} />
|
||||
{intl.formatMessage(messages.disabled)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class About extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
server: ImmutablePropTypes.map,
|
||||
extendedDescription: ImmutablePropTypes.map,
|
||||
|
@ -141,7 +159,7 @@ class About extends PureComponent {
|
|||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(fetchServer());
|
||||
dispatch(fetchExtendedDescription());
|
||||
|
@ -152,11 +170,11 @@ class About extends PureComponent {
|
|||
dispatch(fetchDomainBlocks());
|
||||
};
|
||||
|
||||
render () {
|
||||
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 fedibirdCapabilities = server.get('fedibird_capabilities') || [];
|
||||
const isPublicUnlistedVisibility = fedibirdCapabilities.includes('kmyblue_visibility_public_unlisted');
|
||||
const isPublicVisibility = !fedibirdCapabilities.includes('kmyblue_no_public_visibility');
|
||||
const isEmojiReaction = fedibirdCapabilities.includes('emoji_reaction');
|
||||
|
@ -169,59 +187,88 @@ class About extends PureComponent {
|
|||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
|
||||
<div className='scrollable about'>
|
||||
<div className='about__header'>
|
||||
<ServerHeroImage blurhash={server.getIn(['thumbnail', 'blurhash'])} src={server.getIn(['thumbnail', 'url'])} srcSet={server.getIn(['thumbnail', 'versions'])?.map((value, key) => `${value} ${key.replace('@', '')}`).join(', ')} className='about__header__hero' />
|
||||
<h1>{isLoading ? <Skeleton width='10ch' /> : server.get('domain')}</h1>
|
||||
<p><FormattedMessage id='about.powered_by' defaultMessage='Social media powered by You!' /></p>
|
||||
<div className="scrollable about">
|
||||
<div className="about__header">
|
||||
<ServerHeroImage
|
||||
blurhash={server.getIn(['thumbnail', 'blurhash'])}
|
||||
src={server.getIn(['thumbnail', 'url'])}
|
||||
srcSet={server
|
||||
.getIn(['thumbnail', 'versions'])
|
||||
?.map((value, key) => `${value} ${key.replace('@', '')}`)
|
||||
.join(', ')}
|
||||
className="about__header__hero"
|
||||
/>
|
||||
<h1>{isLoading ? <Skeleton width="10ch" /> : server.get('domain')}</h1>
|
||||
<p>
|
||||
<FormattedMessage id="about.powered_by" defaultMessage="Social media powered by You!" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='about__meta'>
|
||||
<div className='about__meta__column'>
|
||||
<h4><FormattedMessage id='server_banner.administered_by' defaultMessage='Administered by:' /></h4>
|
||||
<div className="about__meta">
|
||||
<div className="about__meta__column">
|
||||
<h4>
|
||||
<FormattedMessage id="server_banner.administered_by" defaultMessage="Administered by:" />
|
||||
</h4>
|
||||
|
||||
<Account id={server.getIn(['contact', 'account', 'id'])} size={36} minimal />
|
||||
</div>
|
||||
|
||||
<hr className='about__meta__divider' />
|
||||
<hr className="about__meta__divider" />
|
||||
|
||||
<div className='about__meta__column'>
|
||||
<h4><FormattedMessage id='about.contact' defaultMessage='Contact:' /></h4>
|
||||
<div className="about__meta__column">
|
||||
<h4>
|
||||
<FormattedMessage id="about.contact" defaultMessage="Contact:" />
|
||||
</h4>
|
||||
|
||||
{isLoading ? <Skeleton width='10ch' /> : <a className='about__mail' href={emailLink}>{server.getIn(['contact', 'email'])}</a>}
|
||||
{isLoading ? (
|
||||
<Skeleton width="10ch" />
|
||||
) : (
|
||||
<a className="about__mail" href={emailLink}>
|
||||
{server.getIn(['contact', 'email'])}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Section open title={intl.formatMessage(messages.title)}>
|
||||
{extendedDescription.get('isLoading') ? (
|
||||
<>
|
||||
<Skeleton width='100%' />
|
||||
<Skeleton width="100%" />
|
||||
<br />
|
||||
<Skeleton width='100%' />
|
||||
<Skeleton width="100%" />
|
||||
<br />
|
||||
<Skeleton width='100%' />
|
||||
<Skeleton width="100%" />
|
||||
<br />
|
||||
<Skeleton width='70%' />
|
||||
<Skeleton width="70%" />
|
||||
</>
|
||||
) : (extendedDescription.get('content')?.length > 0 ? (
|
||||
<div
|
||||
className='prose'
|
||||
dangerouslySetInnerHTML={{ __html: extendedDescription.get('content') }}
|
||||
/>
|
||||
) : extendedDescription.get('content')?.length > 0 ? (
|
||||
<div className="prose" dangerouslySetInnerHTML={{ __html: extendedDescription.get('content') }} />
|
||||
) : (
|
||||
<p><FormattedMessage id='about.not_available' defaultMessage='This information has not been made available on this server.' /></p>
|
||||
))}
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="about.not_available"
|
||||
defaultMessage="This information has not been made available on this server."
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
<Section title={intl.formatMessage(messages.rules)}>
|
||||
{!isLoading && (server.get('rules', ImmutableList()).isEmpty() ? (
|
||||
<p><FormattedMessage id='about.not_available' defaultMessage='This information has not been made available on this server.' /></p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="about.not_available"
|
||||
defaultMessage="This information has not been made available on this server."
|
||||
/>
|
||||
</p>
|
||||
) : (
|
||||
<ol className='rules-list'>
|
||||
{server.get('rules').map(rule => (
|
||||
<ol className="rules-list">
|
||||
{server.get('rules').map((rule) => (
|
||||
<li key={rule.get('id')}>
|
||||
<div className='rules-list__text'>{rule.get('text')}</div>
|
||||
{rule.get('hint').length > 0 && (<div className='rules-list__hint'>{rule.get('hint')}</div>)}
|
||||
<div className="rules-list__text">{rule.get('text')}</div>
|
||||
{!!rule.get('hint') && rule.get('hint').length > 0 && (
|
||||
<div className="rules-list__hint">{rule.get('hint')}</div>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
|
@ -229,23 +276,38 @@ class About extends PureComponent {
|
|||
</Section>
|
||||
|
||||
<Section title={intl.formatMessage(messages.capabilities)}>
|
||||
<p><FormattedMessage id='about.kmyblue_capability' defaultMessage='Server unique features are configured as follows.' /></p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="about.kmyblue_capability"
|
||||
defaultMessage="This server is using unique features are configured as follows."
|
||||
/>
|
||||
</p>
|
||||
{!isLoading && (
|
||||
<ol className='rules-list'>
|
||||
<ol className="rules-list">
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.emojiReaction)}: <CapabilityIcon state={isEmojiReaction} intl={intl} /></span>
|
||||
<span className="rules-list__text">
|
||||
{intl.formatMessage(messages.emojiReaction)}: <CapabilityIcon state={isEmojiReaction} intl={intl} />
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.publicVisibility)}: <CapabilityIcon state={isPublicVisibility} intl={intl} /></span>
|
||||
<span className="rules-list__text">
|
||||
{intl.formatMessage(messages.publicVisibility)}: <CapabilityIcon state={isPublicVisibility} intl={intl} />
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.publicUnlistedVisibility)}: <CapabilityIcon state={isPublicUnlistedVisibility} intl={intl} /></span>
|
||||
<span className="rules-list__text">
|
||||
{intl.formatMessage(messages.publicUnlistedVisibility)}: <CapabilityIcon state={isPublicUnlistedVisibility} intl={intl} />
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.localTimeline)}: <CapabilityIcon state={isLocalTimeline} intl={intl} /></span>
|
||||
<span className="rules-list__text">
|
||||
{intl.formatMessage(messages.localTimeline)}: <CapabilityIcon state={isLocalTimeline} intl={intl} />
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.fullTextSearch)}: <CapabilityIcon state={isFullTextSearch} intl={intl} /></span>
|
||||
<span className="rules-list__text">
|
||||
{intl.formatMessage(messages.fullTextSearch)}: <CapabilityIcon state={isFullTextSearch} intl={intl} />
|
||||
</span>
|
||||
</li>
|
||||
</ol>
|
||||
)}
|
||||
|
@ -254,49 +316,75 @@ class About extends PureComponent {
|
|||
<Section title={intl.formatMessage(messages.blocks)} onOpen={this.handleDomainBlocksOpen}>
|
||||
{domainBlocks.get('isLoading') ? (
|
||||
<>
|
||||
<Skeleton width='100%' />
|
||||
<Skeleton width="100%" />
|
||||
<br />
|
||||
<Skeleton width='70%' />
|
||||
<Skeleton width="70%" />
|
||||
</>
|
||||
) : (domainBlocks.get('isAvailable') ? (
|
||||
) : domainBlocks.get('isAvailable') ? (
|
||||
<>
|
||||
<p><FormattedMessage id='about.domain_blocks.preamble' defaultMessage='Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.' /></p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="about.domain_blocks.preamble"
|
||||
defaultMessage="Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server."
|
||||
/>
|
||||
</p>
|
||||
|
||||
{domainBlocks.get('items').size > 0 && (
|
||||
<div className='about__domain-blocks'>
|
||||
{domainBlocks.get('items').map(block => (
|
||||
<div className='about__domain-blocks__domain' key={block.get('domain')}>
|
||||
<div className='about__domain-blocks__domain__header'>
|
||||
<h6><span title={`SHA-256: ${block.get('digest')}`}>{block.get('domain')}</span></h6>
|
||||
<span className='about__domain-blocks__domain__type' title={intl.formatMessage(severityMessages[block.get('severity')].explanation)}>{intl.formatMessage(severityMessages[block.get('severity_ex') || block.get('severity')].title)}</span>
|
||||
<div className="about__domain-blocks">
|
||||
{domainBlocks.get('items').map((block) => (
|
||||
<div className="about__domain-blocks__domain" key={block.get('domain')}>
|
||||
<div className="about__domain-blocks__domain__header">
|
||||
<h6>
|
||||
<span title={`SHA-256: ${block.get('digest')}`}>{block.get('domain')}</span>
|
||||
</h6>
|
||||
<span
|
||||
className="about__domain-blocks__domain__type"
|
||||
title={intl.formatMessage(severityMessages[block.get('severity')].explanation)}
|
||||
>
|
||||
{intl.formatMessage(
|
||||
severityMessages[block.get('severity_ex') || block.get('severity')].title
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p>{(block.get('comment') || '').length > 0 ? block.get('comment') : <FormattedMessage id='about.domain_blocks.no_reason_available' defaultMessage='Reason not available' />}</p>
|
||||
<p>
|
||||
{(block.get('comment') || '').length > 0 ? (
|
||||
block.get('comment')
|
||||
) : (
|
||||
<FormattedMessage id="about.domain_blocks.no_reason_available" defaultMessage="Reason not available" />
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<p><FormattedMessage id='about.not_available' defaultMessage='This information has not been made available on this server.' /></p>
|
||||
))}
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="about.not_available"
|
||||
defaultMessage="This information has not been made available on this server."
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</Section>
|
||||
|
||||
<LinkFooter />
|
||||
|
||||
<div className='about__footer'>
|
||||
<p><FormattedMessage id='about.disclaimer' defaultMessage='Join the Fediverse, become part of a community, and break free from Big Tech™'s stranglehold on public discourse.' /></p>
|
||||
<div className="about__footer">
|
||||
<p>
|
||||
<FormattedMessage {...messages.joinFediverse} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages.title)}</title>
|
||||
<meta name='robots' content='all' />
|
||||
<meta name="robots" content="all" />
|
||||
</Helmet>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(injectIntl(About));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue