forked from abner/for-legacy-web
feat: geoblock age restricted content
https://www.ofcom.org.uk/online-safety/protecting-children/online-age-checks-must-be-in-force-from-tomorrow https://petition.parliament.uk/petitions/722903 https://wikimediafoundation.org/news/2025/07/17/wikimedia-foundation-challenges-uk-online-safety-act-regulations/master
parent
2a1f7cb8bb
commit
3dc9f6b045
|
|
@ -4,9 +4,9 @@ import { Channel } from "revolt.js";
|
||||||
import styled from "styled-components/macro";
|
import styled from "styled-components/macro";
|
||||||
|
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { Button, Checkbox } from "@revoltchat/ui";
|
import { Button, Checkbox, Preloader } from "@revoltchat/ui";
|
||||||
|
|
||||||
import { useApplicationState } from "../../mobx/State";
|
import { useApplicationState } from "../../mobx/State";
|
||||||
import { SECTION_NSFW } from "../../mobx/stores/Layout";
|
import { SECTION_NSFW } from "../../mobx/stores/Layout";
|
||||||
|
|
@ -45,14 +45,36 @@ type Props = {
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let geoBlock:
|
||||||
|
| undefined
|
||||||
|
| {
|
||||||
|
countryCode: string;
|
||||||
|
isAgeRestrictedGeo: true;
|
||||||
|
};
|
||||||
|
|
||||||
export default observer((props: Props) => {
|
export default observer((props: Props) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const layout = useApplicationState().layout;
|
const layout = useApplicationState().layout;
|
||||||
|
const [geoLoaded, setGeoLoaded] = useState(typeof geoBlock !== "undefined");
|
||||||
const [ageGate, setAgeGate] = useState(false);
|
const [ageGate, setAgeGate] = useState(false);
|
||||||
|
|
||||||
if (ageGate || !props.gated) {
|
useEffect(() => {
|
||||||
|
if (!geoLoaded) {
|
||||||
|
fetch("https://geo.revolt.chat")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
geoBlock = data;
|
||||||
|
setGeoLoaded(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!geoBlock) return <Preloader type="spinner" />;
|
||||||
|
|
||||||
|
if ((ageGate && !geoBlock.isAgeRestrictedGeo) || !props.gated) {
|
||||||
return <>{props.children}</>;
|
return <>{props.children}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
props.channel.channel_type === "Group" ||
|
props.channel.channel_type === "Group" ||
|
||||||
|
|
@ -76,23 +98,50 @@ export default observer((props: Props) => {
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
{geoBlock.isAgeRestrictedGeo ? (
|
||||||
|
<div style={{ maxWidth: "420px", textAlign: "center" }}>
|
||||||
|
This content is not available in your country.
|
||||||
|
{geoBlock.countryCode === "GB" && (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Ofcom sets a legal requirement for platforms to
|
||||||
|
verify the age of users to access age restricted
|
||||||
|
content. Revolt neither has the ability to implement
|
||||||
|
nor currently intends to implement these measures as
|
||||||
|
the current available solutions come with privacy
|
||||||
|
and cost concerns.
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
title={<Text id="app.main.channel.nsfw.confirm" />}
|
title={<Text id="app.main.channel.nsfw.confirm" />}
|
||||||
value={layout.getSectionState(SECTION_NSFW, false)}
|
value={layout.getSectionState(SECTION_NSFW, false)}
|
||||||
onChange={() => layout.toggleSectionState(SECTION_NSFW, false)}
|
onChange={() =>
|
||||||
|
layout.toggleSectionState(SECTION_NSFW, false)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<Button palette="secondary" onClick={() => history.goBack()}>
|
<Button
|
||||||
|
palette="secondary"
|
||||||
|
onClick={() => history.goBack()}>
|
||||||
<Text id="app.special.modals.actions.back" />
|
<Text id="app.special.modals.actions.back" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
layout.getSectionState(SECTION_NSFW) && setAgeGate(true)
|
layout.getSectionState(SECTION_NSFW) &&
|
||||||
|
setAgeGate(true)
|
||||||
}>
|
}>
|
||||||
<Text id={`app.main.channel.nsfw.${props.type}.confirm`} />
|
<Text
|
||||||
|
id={`app.main.channel.nsfw.${props.type}.confirm`}
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Base>
|
</Base>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue