d03bfe2ab8
commit242cfc4b06Author: Zoë Bijl <code@moiety.me> Date: Tue Oct 21 00:22:46 2025 +0200 [bugfix] tweak display name alignment commit23e5d9840fAuthor: Zoë Bijl <code@moiety.me> Date: Tue Oct 21 00:00:59 2025 +0200 [bugfix] improve display name alignment commit1664835c94Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 17:03:52 2025 +0200 [feature] add text-decoration to usernames and hashtags commitd4fdb18549Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 16:38:08 2025 +0200 [bugfix] correct spacing in status__content__spoiler commitc19307a115Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 16:28:30 2025 +0200 [feature] remove giant logo in multi-column view commit51e2c6e1c3Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 16:24:52 2025 +0200 [feature] add gts logo in the multi-column menu commitedc83b0f54Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 16:23:26 2025 +0200 [bugfix] fix width of fullwidth media gallery commit9923c1b6daAuthor: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 15:17:25 2025 +0200 [chore] remove `fixedWith` from icons commit935d6b73efAuthor: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 15:09:43 2025 +0200 [chore] lint commit776f02bd5fAuthor: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 15:07:52 2025 +0200 [bugfix] correctly align multiline column-header button commitd988d35671Author: Zoë Bijl <code@moiety.me> Date: Mon Oct 20 15:04:35 2025 +0200 [feat] add new size variables commit34bcbb669dAuthor: Zoë Bijl <code@moiety.me> Date: Sun Oct 19 23:47:20 2025 +0200 [bugfix] re-enable hicolor privacy icons commit97f2cb8f69Author: Zoë Bijl <code@moiety.me> Date: Sun Oct 19 23:26:16 2025 +0200 [bugfix] correctly align “toot” buttons commit52bcd4b6d0Author: Zoë Bijl <code@moiety.me> Date: Thu Oct 16 16:22:44 2025 +0200 [bugfix] replace `--size` with global `--size-icon` BREAKING CHANGE: any user styles that overwrote `--size` in a `,gts-icon` class will need to be updated. commit9812a2611fAuthor: Zoë Bijl <code@moiety.me> Date: Thu Oct 16 15:53:37 2025 +0200 [bugfix] further tweaks to `.poll__footer` alignment commit798d6fbf79Author: Zoë Bijl <code@moiety.me> Date: Thu Oct 16 15:38:45 2025 +0200 [bugfix] correctly align .poll__footer
225 lines
8.8 KiB
React
225 lines
8.8 KiB
React
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 { fetchServer, fetchDomainBlocks } from "flavours/glitch/actions/server";
|
|
import Column from "flavours/glitch/components/column";
|
|
import { Icon } from "flavours/glitch/components/icon";
|
|
import { ServerHeroImage } from "flavours/glitch/components/server_hero_image";
|
|
import { Skeleton } from "flavours/glitch/components/skeleton";
|
|
import Account from "flavours/glitch/containers/account_container";
|
|
import LinkFooter from "flavours/glitch/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" },
|
|
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." },
|
|
});
|
|
|
|
const severityMessages = {
|
|
silence: {
|
|
title: messages.silenced,
|
|
explanation: messages.silencedExplanation,
|
|
},
|
|
|
|
suspend: {
|
|
title: messages.suspended,
|
|
explanation: messages.suspendedExplanation,
|
|
},
|
|
};
|
|
|
|
const mapStateToProps = state => ({
|
|
server: state.getIn(["server", "server"]),
|
|
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 (
|
|
<div className={classNames("about__section", { active: !collapsed })}>
|
|
<div className='about__section__title' role='button' tabIndex={0} onClick={this.handleClick}>
|
|
<Icon id={collapsed ? "caret-right" : "caret-down"} /> {title}
|
|
</div>
|
|
|
|
{!collapsed && (
|
|
<div className='about__section__body'>{children}</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
class About extends PureComponent {
|
|
|
|
static propTypes = {
|
|
server: 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());
|
|
}
|
|
|
|
handleDomainBlocksOpen = () => {
|
|
const { dispatch } = this.props;
|
|
dispatch(fetchDomainBlocks());
|
|
};
|
|
|
|
render () {
|
|
const { multiColumn, intl, server, domainBlocks } = this.props;
|
|
const isLoading = server.get("isLoading");
|
|
|
|
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='Decentralized social media powered by {torment}' values={{ torment: <a href='https://doom.fandom.com/wiki/Argent_Energy' className='about__mail' target='_blank' rel="noreferrer">torment</a> }} /></p>
|
|
</div>
|
|
|
|
<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} />
|
|
</div>
|
|
|
|
<hr className='about__meta__divider' />
|
|
|
|
<div className='about__meta__column'>
|
|
<h4><FormattedMessage id='about.contact' defaultMessage='Contact:' /></h4>
|
|
|
|
{isLoading ? <Skeleton width='10ch' /> : <a className='about__mail' href={`mailto:${server.getIn(["contact", "email"])}`}>{server.getIn(["contact", "email"])}</a>}
|
|
</div>
|
|
</div>
|
|
|
|
<Section open title={intl.formatMessage(messages.title)}>
|
|
{isLoading ? (
|
|
<>
|
|
<Skeleton width='100%' />
|
|
<br />
|
|
<Skeleton width='100%' />
|
|
<br />
|
|
<Skeleton width='100%' />
|
|
<br />
|
|
<Skeleton width='70%' />
|
|
</>
|
|
) : (server.get("description")?.length > 0 ? (
|
|
<div
|
|
className='prose'
|
|
dangerouslySetInnerHTML={{ __html: server.get("description") }}
|
|
/>
|
|
) : (
|
|
<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>
|
|
) : (
|
|
<ol className='rules-list'>
|
|
{server.get("rules").map(rule => (
|
|
<li key={rule.get("id")}>
|
|
<span className='rules-list__text'>{rule.get("text")}</span>
|
|
</li>
|
|
))}
|
|
</ol>
|
|
))}
|
|
</Section>
|
|
|
|
<Section title={intl.formatMessage(messages.blocks)} onOpen={this.handleDomainBlocksOpen}>
|
|
{domainBlocks.get("isLoading") ? (
|
|
<>
|
|
<Skeleton width='100%' />
|
|
<br />
|
|
<Skeleton width='70%' />
|
|
</>
|
|
) : (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>
|
|
|
|
<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")].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>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
) : (
|
|
<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.fork_disclaimer'
|
|
defaultMessage='Masto-FE (🦥 flavour) is open source software forked from Mastodon via Glitch.'
|
|
/></p>
|
|
</div>
|
|
</div>
|
|
|
|
<Helmet>
|
|
<title>{intl.formatMessage(messages.title)}</title>
|
|
<meta name='robots' content='all' />
|
|
</Helmet>
|
|
</Column>
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
export default connect(mapStateToProps)(injectIntl(About));
|