feat: add nsfw toggle to post editor
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
|||||||
EmbeddedWebsocketUrlParser,
|
EmbeddedWebsocketUrlParser,
|
||||||
parseContent
|
parseContent
|
||||||
} from '@/lib/content-parser'
|
} from '@/lib/content-parser'
|
||||||
import { extractEmojiInfosFromTags, isNsfwEvent } from '@/lib/event'
|
import { extractEmojiInfosFromTags } from '@/lib/event'
|
||||||
import { extractImageInfoFromTag } from '@/lib/tag'
|
import { extractImageInfoFromTag } from '@/lib/tag'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import mediaUpload from '@/services/media-upload.service'
|
import mediaUpload from '@/services/media-upload.service'
|
||||||
@@ -88,20 +88,11 @@ const Content = memo(({ event, className }: { event: Event; className?: string }
|
|||||||
const end = imageIndex + (Array.isArray(node.data) ? node.data.length : 1)
|
const end = imageIndex + (Array.isArray(node.data) ? node.data.length : 1)
|
||||||
imageIndex = end
|
imageIndex = end
|
||||||
return (
|
return (
|
||||||
<ImageGallery
|
<ImageGallery className="mt-2" key={index} images={allImages} start={start} end={end} />
|
||||||
className="mt-2"
|
|
||||||
key={index}
|
|
||||||
images={allImages}
|
|
||||||
isNsfw={isNsfwEvent(event)}
|
|
||||||
start={start}
|
|
||||||
end={end}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (node.type === 'video') {
|
if (node.type === 'video') {
|
||||||
return (
|
return <VideoPlayer className="mt-2" key={index} src={node.data} />
|
||||||
<VideoPlayer className="mt-2" key={index} src={node.data} isNsfw={isNsfwEvent(event)} />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (node.type === 'url') {
|
if (node.type === 'url') {
|
||||||
return <EmbeddedNormalUrl url={node.data} key={index} />
|
return <EmbeddedNormalUrl url={node.data} key={index} />
|
||||||
|
|||||||
@@ -6,15 +6,8 @@ import { useEffect, useState } from 'react'
|
|||||||
import Lightbox from 'yet-another-react-lightbox'
|
import Lightbox from 'yet-another-react-lightbox'
|
||||||
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
|
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
|
||||||
import Image from '../Image'
|
import Image from '../Image'
|
||||||
import NsfwOverlay from '../NsfwOverlay'
|
|
||||||
|
|
||||||
export function ImageCarousel({
|
export function ImageCarousel({ images }: { images: TImageInfo[] }) {
|
||||||
images,
|
|
||||||
isNsfw = false
|
|
||||||
}: {
|
|
||||||
images: TImageInfo[]
|
|
||||||
isNsfw?: boolean
|
|
||||||
}) {
|
|
||||||
const [api, setApi] = useState<CarouselApi>()
|
const [api, setApi] = useState<CarouselApi>()
|
||||||
const [currentIndex, setCurrentIndex] = useState(0)
|
const [currentIndex, setCurrentIndex] = useState(0)
|
||||||
const [lightboxIndex, setLightboxIndex] = useState(-1)
|
const [lightboxIndex, setLightboxIndex] = useState(-1)
|
||||||
@@ -42,7 +35,7 @@ export function ImageCarousel({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative space-y-2">
|
<div className="space-y-2">
|
||||||
<Carousel className="w-full" setApi={setApi}>
|
<Carousel className="w-full" setApi={setApi}>
|
||||||
<CarouselContent className="xl:px-4">
|
<CarouselContent className="xl:px-4">
|
||||||
{images.map((image, index) => (
|
{images.map((image, index) => (
|
||||||
@@ -78,7 +71,6 @@ export function ImageCarousel({
|
|||||||
}}
|
}}
|
||||||
styles={{ toolbar: { paddingTop: '2.25rem' } }}
|
styles={{ toolbar: { paddingTop: '2.25rem' } }}
|
||||||
/>
|
/>
|
||||||
{isNsfw && <NsfwOverlay className="rounded-lg" />}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,15 @@ import { createPortal } from 'react-dom'
|
|||||||
import Lightbox from 'yet-another-react-lightbox'
|
import Lightbox from 'yet-another-react-lightbox'
|
||||||
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
|
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
|
||||||
import Image from '../Image'
|
import Image from '../Image'
|
||||||
import NsfwOverlay from '../NsfwOverlay'
|
|
||||||
|
|
||||||
export default function ImageGallery({
|
export default function ImageGallery({
|
||||||
className,
|
className,
|
||||||
images,
|
images,
|
||||||
isNsfw = false,
|
|
||||||
start = 0,
|
start = 0,
|
||||||
end = images.length
|
end = images.length
|
||||||
}: {
|
}: {
|
||||||
className?: string
|
className?: string
|
||||||
images: TImageInfo[]
|
images: TImageInfo[]
|
||||||
isNsfw?: boolean
|
|
||||||
start?: number
|
start?: number
|
||||||
end?: number
|
end?: number
|
||||||
}) {
|
}) {
|
||||||
@@ -83,13 +80,7 @@ export default function ImageGallery({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={cn(displayImages.length === 1 ? 'w-fit max-w-full' : 'w-full', className)}>
|
||||||
className={cn(
|
|
||||||
'relative',
|
|
||||||
displayImages.length === 1 ? 'w-fit max-w-full' : 'w-full',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{imageContent}
|
{imageContent}
|
||||||
{index >= 0 &&
|
{index >= 0 &&
|
||||||
createPortal(
|
createPortal(
|
||||||
@@ -112,7 +103,6 @@ export default function ImageGallery({
|
|||||||
</div>,
|
</div>,
|
||||||
document.body
|
document.body
|
||||||
)}
|
)}
|
||||||
{isNsfw && <NsfwOverlay className="rounded-lg" />}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/components/Note/NsfwNote.tsx
Normal file
23
src/components/Note/NsfwNote.tsx
Normal file
@@ -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 (
|
||||||
|
<div className="flex flex-col gap-2 items-center text-muted-foreground font-medium my-4">
|
||||||
|
<div>{t('🔞 NSFW 🔞')}</div>
|
||||||
|
<Button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
show()
|
||||||
|
}}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<Eye />
|
||||||
|
{t('Temporarily display this note')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,13 +3,14 @@ import {
|
|||||||
extractImageInfosFromEventTags,
|
extractImageInfosFromEventTags,
|
||||||
getParentEventId,
|
getParentEventId,
|
||||||
getUsingClient,
|
getUsingClient,
|
||||||
|
isNsfwEvent,
|
||||||
isPictureEvent,
|
isPictureEvent,
|
||||||
isSupportedKind
|
isSupportedKind
|
||||||
} from '@/lib/event'
|
} from '@/lib/event'
|
||||||
import { toNote } from '@/lib/link'
|
import { toNote } from '@/lib/link'
|
||||||
import { useScreenSize } from '@/providers/ScreenSizeProvider'
|
import { useScreenSize } from '@/providers/ScreenSizeProvider'
|
||||||
import { Event, kinds } from 'nostr-tools'
|
import { Event, kinds } from 'nostr-tools'
|
||||||
import { useMemo } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import Content from '../Content'
|
import Content from '../Content'
|
||||||
import { FormattedTimestamp } from '../FormattedTimestamp'
|
import { FormattedTimestamp } from '../FormattedTimestamp'
|
||||||
import ImageGallery from '../ImageGallery'
|
import ImageGallery from '../ImageGallery'
|
||||||
@@ -21,6 +22,7 @@ import UserAvatar from '../UserAvatar'
|
|||||||
import Username from '../Username'
|
import Username from '../Username'
|
||||||
import Highlight from './Highlight'
|
import Highlight from './Highlight'
|
||||||
import IValue from './IValue'
|
import IValue from './IValue'
|
||||||
|
import NsfwNote from './NsfwNote'
|
||||||
import { UnknownNote } from './UnknownNote'
|
import { UnknownNote } from './UnknownNote'
|
||||||
|
|
||||||
export default function Note({
|
export default function Note({
|
||||||
@@ -45,6 +47,18 @@ export default function Note({
|
|||||||
[event]
|
[event]
|
||||||
)
|
)
|
||||||
const usingClient = useMemo(() => getUsingClient(event), [event])
|
const usingClient = useMemo(() => getUsingClient(event), [event])
|
||||||
|
const [showNsfw, setShowNsfw] = useState(false)
|
||||||
|
|
||||||
|
let content: React.ReactNode
|
||||||
|
if (!isSupportedKind(event.kind)) {
|
||||||
|
content = <UnknownNote className="mt-2" event={event} />
|
||||||
|
} else if (isNsfwEvent(event) && !showNsfw) {
|
||||||
|
content = <NsfwNote show={() => setShowNsfw(true)} />
|
||||||
|
} else if (event.kind === kinds.Highlights) {
|
||||||
|
content = <Highlight className="mt-2" event={event} />
|
||||||
|
} else {
|
||||||
|
content = <Content className="mt-2" event={event} />
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
@@ -90,13 +104,7 @@ export default function Note({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<IValue event={event} className="mt-2" />
|
<IValue event={event} className="mt-2" />
|
||||||
{event.kind === kinds.Highlights ? (
|
{content}
|
||||||
<Highlight className="mt-2" event={event} />
|
|
||||||
) : isSupportedKind(event.kind) ? (
|
|
||||||
<Content className="mt-2" event={event} />
|
|
||||||
) : (
|
|
||||||
<UnknownNote className="mt-2" event={event} />
|
|
||||||
)}
|
|
||||||
{imageInfos.length > 0 && <ImageGallery images={imageInfos} />}
|
{imageInfos.length > 0 && <ImageGallery images={imageInfos} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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 && (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
'absolute top-0 left-0 backdrop-blur-3xl w-full h-full cursor-pointer',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
setIsHidden(false)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
EmbeddedEmojiParser,
|
EmbeddedEmojiParser,
|
||||||
EmbeddedLNInvoiceParser,
|
|
||||||
EmbeddedHashtagParser,
|
EmbeddedHashtagParser,
|
||||||
|
EmbeddedLNInvoiceParser,
|
||||||
EmbeddedMentionParser,
|
EmbeddedMentionParser,
|
||||||
EmbeddedNormalUrlParser,
|
EmbeddedNormalUrlParser,
|
||||||
EmbeddedWebsocketUrlParser,
|
EmbeddedWebsocketUrlParser,
|
||||||
parseContent
|
parseContent
|
||||||
} from '@/lib/content-parser'
|
} from '@/lib/content-parser'
|
||||||
import { extractEmojiInfosFromTags, extractImageInfosFromEventTags, isNsfwEvent } from '@/lib/event'
|
import { extractEmojiInfosFromTags, extractImageInfosFromEventTags } from '@/lib/event'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { Event } from 'nostr-tools'
|
import { Event } from 'nostr-tools'
|
||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
@@ -18,12 +18,11 @@ import {
|
|||||||
EmbeddedNormalUrl,
|
EmbeddedNormalUrl,
|
||||||
EmbeddedWebsocketUrl
|
EmbeddedWebsocketUrl
|
||||||
} from '../Embedded'
|
} from '../Embedded'
|
||||||
import { ImageCarousel } from '../ImageCarousel'
|
|
||||||
import Emoji from '../Emoji'
|
import Emoji from '../Emoji'
|
||||||
|
import { ImageCarousel } from '../ImageCarousel'
|
||||||
|
|
||||||
const PictureContent = memo(({ event, className }: { event: Event; className?: string }) => {
|
const PictureContent = memo(({ event, className }: { event: Event; className?: string }) => {
|
||||||
const images = useMemo(() => extractImageInfosFromEventTags(event), [event])
|
const images = useMemo(() => extractImageInfosFromEventTags(event), [event])
|
||||||
const isNsfw = isNsfwEvent(event)
|
|
||||||
|
|
||||||
const nodes = parseContent(event.content, [
|
const nodes = parseContent(event.content, [
|
||||||
EmbeddedNormalUrlParser,
|
EmbeddedNormalUrlParser,
|
||||||
@@ -38,7 +37,7 @@ const PictureContent = memo(({ event, className }: { event: Event; className?: s
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('text-wrap break-words whitespace-pre-wrap space-y-2', className)}>
|
<div className={cn('text-wrap break-words whitespace-pre-wrap space-y-2', className)}>
|
||||||
<ImageCarousel images={images} isNsfw={isNsfw} />
|
<ImageCarousel images={images} />
|
||||||
<div className="px-4">
|
<div className="px-4">
|
||||||
{nodes.map((node, index) => {
|
{nodes.map((node, index) => {
|
||||||
if (node.type === 'text') {
|
if (node.type === 'text') {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export default function PostContent({
|
|||||||
const [addClientTag, setAddClientTag] = useState(false)
|
const [addClientTag, setAddClientTag] = useState(false)
|
||||||
const [specifiedRelayUrls, setSpecifiedRelayUrls] = useState<string[] | undefined>(undefined)
|
const [specifiedRelayUrls, setSpecifiedRelayUrls] = useState<string[] | undefined>(undefined)
|
||||||
const [mentions, setMentions] = useState<string[]>([])
|
const [mentions, setMentions] = useState<string[]>([])
|
||||||
|
const [isNsfw, setIsNsfw] = useState(false)
|
||||||
const canPost = !!text && !posting && !uploadingFiles
|
const canPost = !!text && !posting && !uploadingFiles
|
||||||
|
|
||||||
const post = async (e?: React.MouseEvent) => {
|
const post = async (e?: React.MouseEvent) => {
|
||||||
@@ -50,12 +51,14 @@ export default function PostContent({
|
|||||||
parentEvent && parentEvent.kind !== kinds.ShortTextNote
|
parentEvent && parentEvent.kind !== kinds.ShortTextNote
|
||||||
? await createCommentDraftEvent(text, parentEvent, mentions, {
|
? await createCommentDraftEvent(text, parentEvent, mentions, {
|
||||||
addClientTag,
|
addClientTag,
|
||||||
protectedEvent: !!specifiedRelayUrls
|
protectedEvent: !!specifiedRelayUrls,
|
||||||
|
isNsfw
|
||||||
})
|
})
|
||||||
: await createShortTextNoteDraftEvent(text, mentions, {
|
: await createShortTextNoteDraftEvent(text, mentions, {
|
||||||
parentEvent,
|
parentEvent,
|
||||||
addClientTag,
|
addClientTag,
|
||||||
protectedEvent: !!specifiedRelayUrls
|
protectedEvent: !!specifiedRelayUrls,
|
||||||
|
isNsfw
|
||||||
})
|
})
|
||||||
await publish(draftEvent, { specifiedRelayUrls })
|
await publish(draftEvent, { specifiedRelayUrls })
|
||||||
postContentCache.clearPostCache({ defaultContent, parentEvent })
|
postContentCache.clearPostCache({ defaultContent, parentEvent })
|
||||||
@@ -159,6 +162,8 @@ export default function PostContent({
|
|||||||
show={showMoreOptions}
|
show={showMoreOptions}
|
||||||
addClientTag={addClientTag}
|
addClientTag={addClientTag}
|
||||||
setAddClientTag={setAddClientTag}
|
setAddClientTag={setAddClientTag}
|
||||||
|
isNsfw={isNsfw}
|
||||||
|
setIsNsfw={setIsNsfw}
|
||||||
/>
|
/>
|
||||||
<div className="flex gap-2 items-center justify-around sm:hidden">
|
<div className="flex gap-2 items-center justify-around sm:hidden">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ import { useTranslation } from 'react-i18next'
|
|||||||
export default function PostOptions({
|
export default function PostOptions({
|
||||||
show,
|
show,
|
||||||
addClientTag,
|
addClientTag,
|
||||||
setAddClientTag
|
setAddClientTag,
|
||||||
|
isNsfw,
|
||||||
|
setIsNsfw
|
||||||
}: {
|
}: {
|
||||||
show: boolean
|
show: boolean
|
||||||
addClientTag: boolean
|
addClientTag: boolean
|
||||||
setAddClientTag: Dispatch<SetStateAction<boolean>>
|
setAddClientTag: Dispatch<SetStateAction<boolean>>
|
||||||
|
isNsfw: boolean
|
||||||
|
setIsNsfw: Dispatch<SetStateAction<boolean>>
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@@ -26,14 +30,29 @@ export default function PostOptions({
|
|||||||
window.localStorage.setItem(StorageKey.ADD_CLIENT_TAG, checked.toString())
|
window.localStorage.setItem(StorageKey.ADD_CLIENT_TAG, checked.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onNsfwChange = (checked: boolean) => {
|
||||||
|
setIsNsfw(checked)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="add-client-tag">{t('Add client tag')}</Label>
|
<div className="flex items-center space-x-2">
|
||||||
<Switch id="add-client-tag" checked={addClientTag} onCheckedChange={onAddClientTagChange} />
|
<Label htmlFor="add-client-tag">{t('Add client tag')}</Label>
|
||||||
|
<Switch
|
||||||
|
id="add-client-tag"
|
||||||
|
checked={addClientTag}
|
||||||
|
onCheckedChange={onAddClientTagChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-muted-foreground text-xs">
|
||||||
|
{t('Show others this was sent via Jumble')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted-foreground text-xs">
|
|
||||||
{t('Show others this was sent via Jumble')}
|
<div className="flex items-center space-x-2">
|
||||||
|
<Label htmlFor="add-nsfw-tag">{t('NSFW')}</Label>
|
||||||
|
<Switch id="add-nsfw-tag" checked={isNsfw} onCheckedChange={onNsfwChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,17 +2,8 @@ import { cn, isInViewport } from '@/lib/utils'
|
|||||||
import { useAutoplay } from '@/providers/AutoplayProvider'
|
import { useAutoplay } from '@/providers/AutoplayProvider'
|
||||||
import videoManager from '@/services/video-manager.service'
|
import videoManager from '@/services/video-manager.service'
|
||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import NsfwOverlay from '../NsfwOverlay'
|
|
||||||
|
|
||||||
export default function VideoPlayer({
|
export default function VideoPlayer({ src, className }: { src: string; className?: string }) {
|
||||||
src,
|
|
||||||
className,
|
|
||||||
isNsfw = false
|
|
||||||
}: {
|
|
||||||
src: string
|
|
||||||
className?: string
|
|
||||||
isNsfw?: boolean
|
|
||||||
}) {
|
|
||||||
const { autoplay } = useAutoplay()
|
const { autoplay } = useAutoplay()
|
||||||
const videoRef = useRef<HTMLVideoElement>(null)
|
const videoRef = useRef<HTMLVideoElement>(null)
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
@@ -48,7 +39,7 @@ export default function VideoPlayer({
|
|||||||
}, [autoplay])
|
}, [autoplay])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="relative">
|
<div ref={containerRef}>
|
||||||
<video
|
<video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
controls
|
controls
|
||||||
@@ -61,7 +52,6 @@ export default function VideoPlayer({
|
|||||||
}}
|
}}
|
||||||
muted
|
muted
|
||||||
/>
|
/>
|
||||||
{isNsfw && <NsfwOverlay className="rounded-lg" />}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export async function createShortTextNoteDraftEvent(
|
|||||||
parentEvent?: Event
|
parentEvent?: Event
|
||||||
addClientTag?: boolean
|
addClientTag?: boolean
|
||||||
protectedEvent?: boolean
|
protectedEvent?: boolean
|
||||||
|
isNsfw?: boolean
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<TDraftEvent> {
|
): Promise<TDraftEvent> {
|
||||||
const { quoteEventIds, rootETag, parentETag } = await extractRelatedEventIds(
|
const { quoteEventIds, rootETag, parentETag } = await extractRelatedEventIds(
|
||||||
@@ -103,6 +104,10 @@ export async function createShortTextNoteDraftEvent(
|
|||||||
tags.push(['client', 'jumble'])
|
tags.push(['client', 'jumble'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.isNsfw) {
|
||||||
|
tags.push(['content-warning', 'NSFW'])
|
||||||
|
}
|
||||||
|
|
||||||
if (options.protectedEvent) {
|
if (options.protectedEvent) {
|
||||||
tags.push(['-'])
|
tags.push(['-'])
|
||||||
}
|
}
|
||||||
@@ -182,6 +187,7 @@ export async function createCommentDraftEvent(
|
|||||||
options: {
|
options: {
|
||||||
addClientTag?: boolean
|
addClientTag?: boolean
|
||||||
protectedEvent?: boolean
|
protectedEvent?: boolean
|
||||||
|
isNsfw?: boolean
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<TDraftEvent> {
|
): Promise<TDraftEvent> {
|
||||||
const {
|
const {
|
||||||
@@ -241,6 +247,10 @@ export async function createCommentDraftEvent(
|
|||||||
tags.push(['client', 'jumble'])
|
tags.push(['client', 'jumble'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.isNsfw) {
|
||||||
|
tags.push(['content-warning', 'NSFW'])
|
||||||
|
}
|
||||||
|
|
||||||
if (options.protectedEvent) {
|
if (options.protectedEvent) {
|
||||||
tags.push(['-'])
|
tags.push(['-'])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user