+
{images.map((image, index) => (
@@ -78,7 +71,6 @@ export function ImageCarousel({
}}
styles={{ toolbar: { paddingTop: '2.25rem' } }}
/>
- {isNsfw && }
)
}
diff --git a/src/components/ImageGallery/index.tsx b/src/components/ImageGallery/index.tsx
index f2afb33b..8b252495 100644
--- a/src/components/ImageGallery/index.tsx
+++ b/src/components/ImageGallery/index.tsx
@@ -7,18 +7,15 @@ import { createPortal } from 'react-dom'
import Lightbox from 'yet-another-react-lightbox'
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
import Image from '../Image'
-import NsfwOverlay from '../NsfwOverlay'
export default function ImageGallery({
className,
images,
- isNsfw = false,
start = 0,
end = images.length
}: {
className?: string
images: TImageInfo[]
- isNsfw?: boolean
start?: number
end?: number
}) {
@@ -83,13 +80,7 @@ export default function ImageGallery({
}
return (
-
+
{imageContent}
{index >= 0 &&
createPortal(
@@ -112,7 +103,6 @@ export default function ImageGallery({
,
document.body
)}
- {isNsfw &&
}
)
}
diff --git a/src/components/Note/NsfwNote.tsx b/src/components/Note/NsfwNote.tsx
new file mode 100644
index 00000000..a0cb0391
--- /dev/null
+++ b/src/components/Note/NsfwNote.tsx
@@ -0,0 +1,23 @@
+import { Button } from '@/components/ui/button'
+import { Eye } from 'lucide-react'
+import { useTranslation } from 'react-i18next'
+
+export default function NsfwNote({ show }: { show: () => void }) {
+ const { t } = useTranslation()
+
+ return (
+
+
{t('🔞 NSFW 🔞')}
+
+
+ )
+}
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx
index efa34d21..8c3c950b 100644
--- a/src/components/Note/index.tsx
+++ b/src/components/Note/index.tsx
@@ -3,13 +3,14 @@ import {
extractImageInfosFromEventTags,
getParentEventId,
getUsingClient,
+ isNsfwEvent,
isPictureEvent,
isSupportedKind
} from '@/lib/event'
import { toNote } from '@/lib/link'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { Event, kinds } from 'nostr-tools'
-import { useMemo } from 'react'
+import { useMemo, useState } from 'react'
import Content from '../Content'
import { FormattedTimestamp } from '../FormattedTimestamp'
import ImageGallery from '../ImageGallery'
@@ -21,6 +22,7 @@ import UserAvatar from '../UserAvatar'
import Username from '../Username'
import Highlight from './Highlight'
import IValue from './IValue'
+import NsfwNote from './NsfwNote'
import { UnknownNote } from './UnknownNote'
export default function Note({
@@ -45,6 +47,18 @@ export default function Note({
[event]
)
const usingClient = useMemo(() => getUsingClient(event), [event])
+ const [showNsfw, setShowNsfw] = useState(false)
+
+ let content: React.ReactNode
+ if (!isSupportedKind(event.kind)) {
+ content =
+ } else if (isNsfwEvent(event) && !showNsfw) {
+ content =
setShowNsfw(true)} />
+ } else if (event.kind === kinds.Highlights) {
+ content =
+ } else {
+ content =
+ }
return (
@@ -90,13 +104,7 @@ export default function Note({
/>
)}
- {event.kind === kinds.Highlights ? (
-
- ) : isSupportedKind(event.kind) ? (
-
- ) : (
-
- )}
+ {content}
{imageInfos.length > 0 && }
)
diff --git a/src/components/NsfwOverlay/index.tsx b/src/components/NsfwOverlay/index.tsx
deleted file mode 100644
index 895d05de..00000000
--- a/src/components/NsfwOverlay/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { cn } from '@/lib/utils'
-import { useState } from 'react'
-
-export default function NsfwOverlay({ className }: { className?: string }) {
- const [isHidden, setIsHidden] = useState(true)
-
- return (
- isHidden && (
- {
- e.stopPropagation()
- setIsHidden(false)
- }}
- />
- )
- )
-}
diff --git a/src/components/PictureContent/index.tsx b/src/components/PictureContent/index.tsx
index 276ed3b8..36e63614 100644
--- a/src/components/PictureContent/index.tsx
+++ b/src/components/PictureContent/index.tsx
@@ -1,13 +1,13 @@
import {
EmbeddedEmojiParser,
- EmbeddedLNInvoiceParser,
EmbeddedHashtagParser,
+ EmbeddedLNInvoiceParser,
EmbeddedMentionParser,
EmbeddedNormalUrlParser,
EmbeddedWebsocketUrlParser,
parseContent
} from '@/lib/content-parser'
-import { extractEmojiInfosFromTags, extractImageInfosFromEventTags, isNsfwEvent } from '@/lib/event'
+import { extractEmojiInfosFromTags, extractImageInfosFromEventTags } from '@/lib/event'
import { cn } from '@/lib/utils'
import { Event } from 'nostr-tools'
import { memo, useMemo } from 'react'
@@ -18,12 +18,11 @@ import {
EmbeddedNormalUrl,
EmbeddedWebsocketUrl
} from '../Embedded'
-import { ImageCarousel } from '../ImageCarousel'
import Emoji from '../Emoji'
+import { ImageCarousel } from '../ImageCarousel'
const PictureContent = memo(({ event, className }: { event: Event; className?: string }) => {
const images = useMemo(() => extractImageInfosFromEventTags(event), [event])
- const isNsfw = isNsfwEvent(event)
const nodes = parseContent(event.content, [
EmbeddedNormalUrlParser,
@@ -38,7 +37,7 @@ const PictureContent = memo(({ event, className }: { event: Event; className?: s
return (
-
+
{nodes.map((node, index) => {
if (node.type === 'text') {
diff --git a/src/components/PostEditor/PostContent.tsx b/src/components/PostEditor/PostContent.tsx
index a7c4adcd..77607107 100644
--- a/src/components/PostEditor/PostContent.tsx
+++ b/src/components/PostEditor/PostContent.tsx
@@ -37,6 +37,7 @@ export default function PostContent({
const [addClientTag, setAddClientTag] = useState(false)
const [specifiedRelayUrls, setSpecifiedRelayUrls] = useState
(undefined)
const [mentions, setMentions] = useState([])
+ const [isNsfw, setIsNsfw] = useState(false)
const canPost = !!text && !posting && !uploadingFiles
const post = async (e?: React.MouseEvent) => {
@@ -50,12 +51,14 @@ export default function PostContent({
parentEvent && parentEvent.kind !== kinds.ShortTextNote
? await createCommentDraftEvent(text, parentEvent, mentions, {
addClientTag,
- protectedEvent: !!specifiedRelayUrls
+ protectedEvent: !!specifiedRelayUrls,
+ isNsfw
})
: await createShortTextNoteDraftEvent(text, mentions, {
parentEvent,
addClientTag,
- protectedEvent: !!specifiedRelayUrls
+ protectedEvent: !!specifiedRelayUrls,
+ isNsfw
})
await publish(draftEvent, { specifiedRelayUrls })
postContentCache.clearPostCache({ defaultContent, parentEvent })
@@ -159,6 +162,8 @@ export default function PostContent({
show={showMoreOptions}
addClientTag={addClientTag}
setAddClientTag={setAddClientTag}
+ isNsfw={isNsfw}
+ setIsNsfw={setIsNsfw}
/>