- $ {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.
Authors are responsible for accurately marking their content as adult-only when it contains material not suitable for general audiences
PlotLink reserves the right to flag or reclassify any story as adult-only if it determines the content is not suitable for general audiences