setting for showing content warning posts
Some checks failed
continuous-integration/drone/push Build is running
continuous-integration/drone/pr Build is failing

This commit is contained in:
Martti Malmi 2023-11-28 20:19:11 +02:00
parent 9749883cc1
commit 9393e3342d
6 changed files with 86 additions and 41 deletions

View File

@ -40,7 +40,7 @@ export function NoteInner(props: NoteProps) {
const { ref, inView } = useInView({ triggerOnce: true }); const { ref, inView } = useInView({ triggerOnce: true });
const { reactions, reposts, deletions, zaps } = useEventReactions(NostrLink.fromEvent(ev), related); const { reactions, reposts, deletions, zaps } = useEventReactions(NostrLink.fromEvent(ev), related);
const login = useLogin(); const login = useLogin();
const { pinned, bookmarked } = login; const { pinned, bookmarked } = useLogin();
const { publisher, system } = useEventPublisher(); const { publisher, system } = useEventPublisher();
const [translated, setTranslated] = useState<NoteTranslation>(); const [translated, setTranslated] = useState<NoteTranslation>();
const [showTranslation, setShowTranslation] = useState(true); const [showTranslation, setShowTranslation] = useState(true);
@ -140,39 +140,45 @@ export function NoteInner(props: NoteProps) {
</b> </b>
); );
} }
const contentWarning = ev.tags.find(a => a[0] === "content-warning"); if (!login.appData.item.showContentWarningPosts) {
if (contentWarning) { const contentWarning = ev.tags.find(a => a[0] === "content-warning");
return ( if (contentWarning) {
<Reveal return (
message={ <Reveal
<> message={
<FormattedMessage <>
defaultMessage="The author has marked this note as a <i>sensitive topic</i>" <FormattedMessage
id="StKzTE" defaultMessage="The author has marked this note as a <i>sensitive topic</i>"
values={{ id="StKzTE"
i: c => <i>{c}</i>, values={{
}} i: c => <i>{c}</i>,
/> }}
{contentWarning[1] && ( />
<> {contentWarning[1] && (
&nbsp; <>
<FormattedMessage &nbsp;
defaultMessage="Reason: <i>{reason}</i>" <FormattedMessage
id="6OSOXl" defaultMessage="Reason: <i>{reason}</i>"
values={{ id="6OSOXl"
i: c => <i>{c}</i>, values={{
reason: contentWarning[1], i: c => <i>{c}</i>,
}} reason: contentWarning[1],
/> }}
</> />
)} </>
&nbsp; )}
<FormattedMessage defaultMessage="Click here to load anyway" id="IoQq+a" /> . <FormattedMessage defaultMessage="Click here to load anyway" id="IoQq+a" />.{" "}
</> <Link to="/settings/moderation">
}> <i>
{innerContent} <FormattedMessage defaultMessage="Settings" id="D3idYv" />
</Reveal> </i>
); </Link>
</>
}>
{innerContent}
</Reveal>
);
}
} }
return innerContent; return innerContent;
}; };

View File

@ -20,6 +20,7 @@ export const enum LoginSessionType {
export interface SnortAppData { export interface SnortAppData {
mutedWords: Array<string>; mutedWords: Array<string>;
showContentWarningPosts: boolean;
preferences: UserPreferences; preferences: UserPreferences;
} }

View File

@ -9,7 +9,7 @@ import AccountsPage from "@/Pages/settings/Accounts";
import { WalletSettingsRoutes } from "@/Pages/settings/WalletSettings"; import { WalletSettingsRoutes } from "@/Pages/settings/WalletSettings";
import { ManageHandleRoutes } from "@/Pages/settings/handle"; import { ManageHandleRoutes } from "@/Pages/settings/handle";
import ExportKeys from "@/Pages/settings/Keys"; import ExportKeys from "@/Pages/settings/Keys";
import { ModerationSettings } from "@/Pages/settings/Moderation"; import ModerationSettings from "@/Pages/settings/Moderation";
import { CacheSettings } from "./settings/Cache"; import { CacheSettings } from "./settings/Cache";
import messages from "./messages"; import messages from "./messages";

View File

@ -1,30 +1,41 @@
import { unixNowMs } from "@snort/shared"; import { unixNowMs } from "@snort/shared";
import useLogin from "@/Hooks/useLogin"; import useLogin from "@/Hooks/useLogin";
import { updateAppData } from "@/Login"; import { SnortAppData, updateAppData } from "@/Login";
import { appendDedupe } from "@/SnortUtils"; import { appendDedupe } from "@/SnortUtils";
import { useState } from "react"; import { useState } from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
export function ModerationSettings() { export default function ModerationSettingsPage() {
const login = useLogin(); const login = useLogin();
const [muteWord, setMuteWord] = useState(""); const [muteWord, setMuteWord] = useState("");
const appData = login.appData.item;
function addMutedWord() { function addMutedWord() {
updateAppData(login.id, ad => ({ updateAppData(login.id, ad => ({
item: { item: {
...ad, ...ad,
mutedWords: appendDedupe(login.appData.item.mutedWords, [muteWord]), mutedWords: appendDedupe(appData.mutedWords, [muteWord]),
}, },
timestamp: unixNowMs(), timestamp: unixNowMs(),
})); }));
setMuteWord(""); setMuteWord("");
} }
const handleToggle = (setting: keyof SnortAppData) => {
updateAppData(login.id, ad => ({
item: {
...ad,
[setting]: !appData[setting],
},
timestamp: unixNowMs(),
}));
};
function removeMutedWord(word: string) { function removeMutedWord(word: string) {
updateAppData(login.id, ad => ({ updateAppData(login.id, ad => ({
item: { item: {
...ad, ...ad,
mutedWords: login.appData.item.mutedWords.filter(a => a !== word), mutedWords: appData.mutedWords.filter(a => a !== word),
}, },
timestamp: unixNowMs(), timestamp: unixNowMs(),
})); }));
@ -34,8 +45,27 @@ export function ModerationSettings() {
return ( return (
<> <>
<h2> <h2>
<FormattedMessage defaultMessage="Muted Words" id="AN0Z7Q" /> <FormattedMessage defaultMessage="Moderation" id="wofVHy" />
</h2> </h2>
<div className="py-4 flex flex-col gap-2">
<div className="flex items-center mb-2">
<input
type="checkbox"
checked={appData.showContentWarningPosts}
onChange={() => handleToggle("showContentWarningPosts")}
className="mr-2"
id="showContentWarningPosts"
/>
<label htmlFor="showContentWarningPosts">
<FormattedMessage defaultMessage="Show posts that have a content warning tag" id="fQN+tq" />
</label>
</div>
</div>
<h3>
<FormattedMessage defaultMessage="Muted Words" id="AN0Z7Q" />
</h3>
<div className="flex flex-col g12"> <div className="flex flex-col g12">
<div className="flex g8"> <div className="flex g8">
<input <input
@ -49,7 +79,7 @@ export function ModerationSettings() {
<FormattedMessage defaultMessage="Add" id="2/2yg+" /> <FormattedMessage defaultMessage="Add" id="2/2yg+" />
</button> </button>
</div> </div>
{login.appData.item.mutedWords.map(v => ( {appData.mutedWords.map(v => (
<div className="p br b flex items-center justify-between"> <div className="p br b flex items-center justify-between">
<div>{v}</div> <div>{v}</div>
<button type="button" onClick={() => removeMutedWord(v)}> <button type="button" onClick={() => removeMutedWord(v)}>

View File

@ -1074,6 +1074,9 @@
"fOksnD": { "fOksnD": {
"defaultMessage": "Can't vote because LNURL service does not support zaps" "defaultMessage": "Can't vote because LNURL service does not support zaps"
}, },
"fQN+tq": {
"defaultMessage": "Show posts that have a content warning tag"
},
"fWZYP5": { "fWZYP5": {
"defaultMessage": "Pinned" "defaultMessage": "Pinned"
}, },
@ -1485,6 +1488,9 @@
"wih7iJ": { "wih7iJ": {
"defaultMessage": "name is blocked" "defaultMessage": "name is blocked"
}, },
"wofVHy": {
"defaultMessage": "Moderation"
},
"wqyN/i": { "wqyN/i": {
"defaultMessage": "Find out more info about {service} at {link}" "defaultMessage": "Find out more info about {service} at {link}"
}, },

View File

@ -353,6 +353,7 @@
"fBI91o": "Zap", "fBI91o": "Zap",
"fBlba3": "Thanks for using {site}, please consider donating if you can.", "fBlba3": "Thanks for using {site}, please consider donating if you can.",
"fOksnD": "Can't vote because LNURL service does not support zaps", "fOksnD": "Can't vote because LNURL service does not support zaps",
"fQN+tq": "Show posts that have a content warning tag",
"fWZYP5": "Pinned", "fWZYP5": "Pinned",
"fX5RYm": "Pick a few topics of interest", "fX5RYm": "Pick a few topics of interest",
"filwqD": "Read", "filwqD": "Read",
@ -489,6 +490,7 @@
"wSZR47": "Submit", "wSZR47": "Submit",
"wWLwvh": "Anon", "wWLwvh": "Anon",
"wih7iJ": "name is blocked", "wih7iJ": "name is blocked",
"wofVHy": "Moderation",
"wqyN/i": "Find out more info about {service} at {link}", "wqyN/i": "Find out more info about {service} at {link}",
"wtLjP6": "Copy ID", "wtLjP6": "Copy ID",
"x/Fx2P": "Fund the services that you use by splitting a portion of all your zaps into a pool of funds!", "x/Fx2P": "Fund the services that you use by splitting a portion of all your zaps into a pool of funds!",