diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx index 802643d..14233cd 100644 --- a/src/app/create/page.tsx +++ b/src/app/create/page.tsx @@ -625,7 +625,7 @@ function CreatePage() { disabled={newBusy} className="h-4 w-4 rounded border-border accent-accent" /> - This story contains adult content (18+) + This story contains adult content (19+) {isNsfw && (

diff --git a/src/app/page.tsx b/src/app/page.tsx index 2c15f15..c6c1934 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -87,7 +87,7 @@ export default async function Home({ {storylines.length === 0 && (

- $ {showNsfw ? "no 18+ stories found" : "no storylines found"} + $ {showNsfw ? "no 19+ stories found" : "no storylines found"}

{showNsfw ? "No mature content has been published yet." : "Be the first to start a story on PlotLink."} diff --git a/src/app/profile/[address]/page.tsx b/src/app/profile/[address]/page.tsx index c85d17c..dd2d9f8 100644 --- a/src/app/profile/[address]/page.tsx +++ b/src/app/profile/[address]/page.tsx @@ -16,6 +16,7 @@ import { browserClient } from "../../../../lib/rpc"; import type { FarcasterProfile } from "../../../../lib/farcaster"; import type { AgentMetadata } from "../../../../lib/contracts/erc8004"; import { usePlotUsdPrice } from "../../../hooks/usePlotUsdPrice"; +import { useNsfwPreference } from "../../../hooks/useNsfwPreference"; import { formatUsdValue } from "../../../../lib/usd-price"; import { DisconnectButton } from "../../../components/ConnectWallet"; import { GENRES, LANGUAGES } from "../../../../lib/genres"; @@ -709,9 +710,10 @@ function StoriesTab({ connectedAddress: string | null; totalRoyalties?: bigint; }) { + const [showNsfw] = useNsfwPreference(); const { data: plotUsd } = usePlotUsdPrice(); const { data: storylines = [], isLoading, error } = useQuery({ - queryKey: ["profile-storylines", address, isOwnProfile], + queryKey: ["profile-storylines", address, isOwnProfile, showNsfw], queryFn: async () => { if (!supabase) return []; let q = supabase @@ -720,7 +722,7 @@ function StoriesTab({ .eq("writer_address", address) .eq("hidden", false) .eq("contract_address", STORY_FACTORY.toLowerCase()); - if (!isOwnProfile) q = q.eq("is_nsfw", false); + if (!isOwnProfile && !showNsfw) q = q.eq("is_nsfw", false); const { data, error } = await q .order("block_timestamp", { ascending: false }) .returns(); @@ -1429,11 +1431,12 @@ interface PortfolioHolding { } function PortfolioTab({ address, isOwnProfile }: { address: string; isOwnProfile: boolean }) { + const [showNsfw] = useNsfwPreference(); const { data: plotUsd } = usePlotUsdPrice(); // Fetch on-chain token holdings const { data: holdings, isLoading: holdingsLoading } = useQuery({ - queryKey: ["profile-holdings", address, isOwnProfile], + queryKey: ["profile-holdings", address, isOwnProfile, showNsfw], queryFn: async (): Promise => { if (!supabase) return []; @@ -1443,7 +1446,7 @@ function PortfolioTab({ address, isOwnProfile }: { address: string; isOwnProfile .eq("hidden", false) .neq("token_address", "") .eq("contract_address", STORY_FACTORY.toLowerCase()); - if (!isOwnProfile) q = q.eq("is_nsfw", false); + if (!isOwnProfile && !showNsfw) q = q.eq("is_nsfw", false); const { data: storylines } = await q.returns(); if (!storylines || storylines.length === 0) return []; diff --git a/src/app/story/[storylineId]/page.tsx b/src/app/story/[storylineId]/page.tsx index 633c96c..498c14c 100644 --- a/src/app/story/[storylineId]/page.tsx +++ b/src/app/story/[storylineId]/page.tsx @@ -24,7 +24,7 @@ import { CommentSection } from "../../../components/CommentSection"; import { MobileActionBar } from "../../../components/MobileActionBar"; import { MarketCapBox } from "../../../components/MarketCapBox"; import { TokenPriceBox } from "../../../components/TokenPriceBox"; -import { FALLBACK_STYLES, hashToVariant } from "../../../components/StoryCard"; +import { FALLBACK_STYLES, hashToVariant, NsfwBadge } from "../../../components/StoryCard"; import { CoverLightbox } from "../../../components/CoverLightbox"; import { getCoverUrl } from "../../../../lib/cover"; import { StoryEditPanel } from "../../../components/StoryEditPanel"; @@ -387,6 +387,7 @@ function StoryHeader({ )} + diff --git a/src/app/terms/page.tsx b/src/app/terms/page.tsx index 7e82727..733c6b8 100644 --- a/src/app/terms/page.tsx +++ b/src/app/terms/page.tsx @@ -41,7 +41,7 @@ export default function TermsPage() {

Published content is permanent and cannot be deleted from IPFS or the blockchain by PlotLink.

6. Adult Content Policy

-

Stories may be marked as containing adult content (18+/NSFW) by the author at the time of publication. Adult content is hidden by default on the browse page and requires readers to opt-in to view it.

+

Stories may be marked as containing adult content (19+/NSFW) by the author at the time of publication. Adult content is hidden by default on the browse page and requires readers to opt-in to view it.