feat: support content warning

This commit is contained in:
reya
2024-06-21 08:57:49 +07:00
parent 4f0f210076
commit 59eaaec903
2 changed files with 54 additions and 12 deletions

View File

@@ -1,7 +1,7 @@
import { cn } from "@lume/utils"; import { cn } from "@lume/utils";
import { useRouteContext } from "@tanstack/react-router"; import { useRouteContext } from "@tanstack/react-router";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { type ReactNode, useMemo } from "react"; import { type ReactNode, useMemo, useState } from "react";
import reactStringReplace from "react-string-replace"; import reactStringReplace from "react-string-replace";
import { Hashtag } from "./mentions/hashtag"; import { Hashtag } from "./mentions/hashtag";
import { MentionNote } from "./mentions/note"; import { MentionNote } from "./mentions/note";
@@ -23,6 +23,8 @@ export function NoteContent({
}) { }) {
const { settings } = useRouteContext({ strict: false }); const { settings } = useRouteContext({ strict: false });
const event = useNoteContext(); const event = useNoteContext();
const warning = useMemo(() => event.warning, [event]);
const content = useMemo(() => { const content = useMemo(() => {
try { try {
// Get parsed meta // Get parsed meta
@@ -91,8 +93,29 @@ export function NoteContent({
} }
}, [event.content]); }, [event.content]);
const [blurred, setBlurred] = useState(() => warning?.length > 0);
return ( return (
<div className="flex flex-col gap-2"> <div className="relative flex flex-col gap-2">
{blurred ? (
<div className="absolute inset-0 z-10 flex items-center justify-center w-full h-full bg-black/80 backdrop-blur-xl">
<div className="flex flex-col items-center justify-center gap-2 text-center">
<p className="text-sm text-white/60">
The content is hidden because the author
<br />
marked it with a warning for a reason:
</p>
<p className="text-sm font-medium text-white">{warning}</p>
<button
type="button"
onClick={() => setBlurred(false)}
className="inline-flex items-center justify-center px-2 mt-4 text-sm font-medium border rounded-lg text-white/70 h-9 w-max bg-white/20 hover:bg-white/30 border-white/5"
>
View anyway
</button>
</div>
</div>
) : null}
<div <div
className={cn( className={cn(
"select-text text-pretty content-break overflow-hidden", "select-text text-pretty content-break overflow-hidden",
@@ -104,12 +127,16 @@ export function NoteContent({
> >
{content} {content}
</div> </div>
{settings.display_media && event.meta?.images.length ? ( {settings.display_media ? (
<>
{event.meta?.images.length ? (
<Images urls={event.meta.images} /> <Images urls={event.meta.images} />
) : null} ) : null}
{settings.display_media && event.meta?.videos.length ? ( {event.meta?.videos.length ? (
<Videos urls={event.meta.videos} /> <Videos urls={event.meta.videos} />
) : null} ) : null}
</>
) : null}
</div> </div>
); );
} }

View File

@@ -25,11 +25,6 @@ export class LumeEvent {
Object.assign(this, event); Object.assign(this, event);
} }
get isWarning() {
const tag = this.tags.find((tag) => tag[0] === "content-warning");
return tag?.[1]; // return: reason;
}
get isQuote() { get isQuote() {
return this.tags.filter((tag) => tag[0] === "q").length > 0; return this.tags.filter((tag) => tag[0] === "q").length > 0;
} }
@@ -95,6 +90,26 @@ export class LumeEvent {
return { id, relayHint }; return { id, relayHint };
} }
get warning() {
const warningTag = this.tags.filter(
(tag) => tag[0] === "content-warning",
)?.[0];
if (warningTag) {
return warningTag[1];
} else {
const nsfwTag = this.tags.filter(
(tag) => tag[0] === "t" && tag[1] === "NSFW",
)?.[0];
if (nsfwTag) {
return "NSFW";
} else {
return null;
}
}
}
public async getAllReplies() { public async getAllReplies() {
const query = await commands.getReplies(this.id); const query = await commands.getReplies(this.id);