diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx
index 314b16c6..6df9b6d6 100644
--- a/src/components/Note/index.tsx
+++ b/src/components/Note/index.tsx
@@ -1,5 +1,5 @@
import { useSecondaryPage } from '@/PageManager'
-import { ExtendedKind, SUPPORTED_KINDS } from '@/constants'
+import { ExtendedKind, NSFW_DISPLAY_POLICY, SUPPORTED_KINDS } from '@/constants'
import { getParentStuff, isNsfwEvent } from '@/lib/event'
import { toExternalContent, toNote } from '@/lib/link'
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
@@ -55,10 +55,14 @@ export default function Note({
const { parentEventId, parentExternalContent } = useMemo(() => {
return getParentStuff(event)
}, [event])
- const { defaultShowNsfw } = useContentPolicy()
+ const { nsfwDisplayPolicy } = useContentPolicy()
const [showNsfw, setShowNsfw] = useState(false)
const { mutePubkeySet } = useMuteList()
const [showMuted, setShowMuted] = useState(false)
+ const isNsfw = useMemo(
+ () => (nsfwDisplayPolicy === NSFW_DISPLAY_POLICY.SHOW ? false : isNsfwEvent(event)),
+ [event, nsfwDisplayPolicy]
+ )
let content: React.ReactNode
if (
@@ -72,7 +76,7 @@ export default function Note({
content =
} else if (mutePubkeySet.has(event.pubkey) && !showMuted) {
content = setShowMuted(true)} />
- } else if (!defaultShowNsfw && isNsfwEvent(event) && !showNsfw) {
+ } else if (isNsfw && !showNsfw) {
content = setShowNsfw(true)} />
} else if (event.kind === kinds.Highlights) {
content =
diff --git a/src/components/NoteCard/index.tsx b/src/components/NoteCard/index.tsx
index 3c4adda0..e42726a3 100644
--- a/src/components/NoteCard/index.tsx
+++ b/src/components/NoteCard/index.tsx
@@ -1,5 +1,6 @@
import { Skeleton } from '@/components/ui/skeleton'
-import { isMentioningMutedUsers } from '@/lib/event'
+import { NSFW_DISPLAY_POLICY } from '@/constants'
+import { isMentioningMutedUsers, isNsfwEvent } from '@/lib/event'
import { cn } from '@/lib/utils'
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
@@ -22,7 +23,7 @@ export default function NoteCard({
reposters?: string[]
}) {
const { mutePubkeySet } = useMuteList()
- const { hideContentMentioningMutedUsers } = useContentPolicy()
+ const { hideContentMentioningMutedUsers, nsfwDisplayPolicy } = useContentPolicy()
const shouldHide = useMemo(() => {
if (filterMutedNotes && mutePubkeySet.has(event.pubkey)) {
return true
@@ -30,8 +31,11 @@ export default function NoteCard({
if (hideContentMentioningMutedUsers && isMentioningMutedUsers(event, mutePubkeySet)) {
return true
}
+ if (nsfwDisplayPolicy === NSFW_DISPLAY_POLICY.HIDE && isNsfwEvent(event)) {
+ return true
+ }
return false
- }, [event, filterMutedNotes, mutePubkeySet])
+ }, [event, filterMutedNotes, mutePubkeySet, nsfwDisplayPolicy])
if (shouldHide) return null
if (event.kind === kinds.Repost || event.kind === kinds.GenericRepost) {
diff --git a/src/constants.ts b/src/constants.ts
index 1b748a6b..d59e8136 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -28,7 +28,6 @@ export const StorageKey = {
TRANSLATION_SERVICE_CONFIG_MAP: 'translationServiceConfigMap',
MEDIA_UPLOAD_SERVICE_CONFIG_MAP: 'mediaUploadServiceConfigMap',
HIDE_UNTRUSTED_NOTES: 'hideUntrustedNotes',
- DEFAULT_SHOW_NSFW: 'defaultShowNsfw',
DISMISSED_TOO_MANY_RELAYS_ALERT: 'dismissedTooManyRelaysAlert',
SHOW_KINDS: 'showKinds',
SHOW_KINDS_VERSION: 'showKindsVersion',
@@ -43,6 +42,8 @@ export const StorageKey = {
FILTER_OUT_ONION_RELAYS: 'filterOutOnionRelays',
QUICK_REACTION: 'quickReaction',
QUICK_REACTION_EMOJI: 'quickReactionEmoji',
+ NSFW_DISPLAY_POLICY: 'nsfwDisplayPolicy',
+ DEFAULT_SHOW_NSFW: 'defaultShowNsfw', // deprecated
PINNED_PUBKEYS: 'pinnedPubkeys', // deprecated
MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
@@ -170,6 +171,12 @@ export const MEDIA_AUTO_LOAD_POLICY = {
NEVER: 'never'
} as const
+export const NSFW_DISPLAY_POLICY = {
+ HIDE: 'hide',
+ HIDE_CONTENT: 'hide_content',
+ SHOW: 'show'
+} as const
+
export const MAX_PINNED_NOTES = 10
export const PRIMARY_COLORS = {
diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts
index 17916b90..67bb40c1 100644
--- a/src/i18n/locales/ar.ts
+++ b/src/i18n/locales/ar.ts
@@ -571,6 +571,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'إذا تم التمكين، يمكنك التفاعل بنقرة واحدة. اضغط مع الاستمرار للمزيد من الخيارات',
'Quick reaction emoji': 'رمز تعبيري للرد السريع',
- 'Select emoji': 'اختر رمز تعبيري'
+ 'Select emoji': 'اختر رمز تعبيري',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts
index 40a7f64f..a72da865 100644
--- a/src/i18n/locales/de.ts
+++ b/src/i18n/locales/de.ts
@@ -587,6 +587,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Wenn aktiviert, können Sie mit einem Klick reagieren. Klicken und halten Sie für weitere Optionen',
'Quick reaction emoji': 'Schnellreaktions-Emoji',
- 'Select emoji': 'Emoji auswählen'
+ 'Select emoji': 'Emoji auswählen',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts
index 0ae4608e..effe6198 100644
--- a/src/i18n/locales/en.ts
+++ b/src/i18n/locales/en.ts
@@ -574,6 +574,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'If enabled, you can react with a single click. Click and hold for more options',
'Quick reaction emoji': 'Quick reaction emoji',
- 'Select emoji': 'Select emoji'
+ 'Select emoji': 'Select emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts
index 08062ae0..e2c0c43d 100644
--- a/src/i18n/locales/es.ts
+++ b/src/i18n/locales/es.ts
@@ -583,6 +583,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Si está habilitado, puedes reaccionar con un solo clic. Mantén presionado para más opciones',
'Quick reaction emoji': 'Emoji de reacción rápida',
- 'Select emoji': 'Seleccionar emoji'
+ 'Select emoji': 'Seleccionar emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/fa.ts b/src/i18n/locales/fa.ts
index f616f0b6..eae6b5c4 100644
--- a/src/i18n/locales/fa.ts
+++ b/src/i18n/locales/fa.ts
@@ -577,6 +577,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'اگر فعال باشد، میتوانید با یک کلیک واکنش نشان دهید. برای گزینههای بیشتر کلیک کنید و نگه دارید',
'Quick reaction emoji': 'ایموجی واکنش سریع',
- 'Select emoji': 'انتخاب ایموجی'
+ 'Select emoji': 'انتخاب ایموجی',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts
index d9e15dfe..b40aedd9 100644
--- a/src/i18n/locales/fr.ts
+++ b/src/i18n/locales/fr.ts
@@ -584,8 +584,13 @@ export default {
notes: 'notes',
'Quick reaction': 'Réaction rapide',
'If enabled, you can react with a single click. Click and hold for more options':
- 'Si activé, vous pouvez réagir en un seul clic. Maintenez enfoncé pour plus d\'options',
+ "Si activé, vous pouvez réagir en un seul clic. Maintenez enfoncé pour plus d'options",
'Quick reaction emoji': 'Emoji de réaction rapide',
- 'Select emoji': 'Sélectionner un emoji'
+ 'Select emoji': 'Sélectionner un emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/hi.ts b/src/i18n/locales/hi.ts
index e94b1c8a..50c6f393 100644
--- a/src/i18n/locales/hi.ts
+++ b/src/i18n/locales/hi.ts
@@ -578,6 +578,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'यदि सक्षम है, तो आप एक क्लिक से प्रतिक्रिया दे सकते हैं। अधिक विकल्पों के लिए क्लिक करें और रोकें',
'Quick reaction emoji': 'त्वरित प्रतिक्रिया इमोजी',
- 'Select emoji': 'इमोजी चुनें'
+ 'Select emoji': 'इमोजी चुनें',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/hu.ts b/src/i18n/locales/hu.ts
index 61cba850..435a2663 100644
--- a/src/i18n/locales/hu.ts
+++ b/src/i18n/locales/hu.ts
@@ -572,6 +572,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Ha engedélyezve van, egy kattintással reagálhat. Tartsa lenyomva további lehetőségekért',
'Quick reaction emoji': 'Gyors reakció emoji',
- 'Select emoji': 'Emoji kiválasztása'
+ 'Select emoji': 'Emoji kiválasztása',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts
index 328245cc..c1161411 100644
--- a/src/i18n/locales/it.ts
+++ b/src/i18n/locales/it.ts
@@ -582,6 +582,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Se abilitato, puoi reagire con un solo clic. Fai clic e tieni premuto per altre opzioni',
'Quick reaction emoji': 'Emoji reazione rapida',
- 'Select emoji': 'Seleziona emoji'
+ 'Select emoji': 'Seleziona emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts
index 35d414f8..9141d13e 100644
--- a/src/i18n/locales/ja.ts
+++ b/src/i18n/locales/ja.ts
@@ -577,6 +577,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'有効にすると、ワンクリックでリアクションできます。長押しで他のオプションを表示',
'Quick reaction emoji': 'クイックリアクション絵文字',
- 'Select emoji': '絵文字を選択'
+ 'Select emoji': '絵文字を選択',
+ 'NSFW content display': 'NSFWコンテンツの表示',
+ 'Hide completely': '完全に非表示',
+ 'Show but hide content': '表示するがコンテンツを非表示',
+ 'Show directly': '直接表示',
+ 'Click to view': 'クリックして表示'
}
}
diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts
index c6a2de67..7684c88c 100644
--- a/src/i18n/locales/ko.ts
+++ b/src/i18n/locales/ko.ts
@@ -576,6 +576,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'활성화하면 한 번의 클릭으로 반응할 수 있습니다. 더 많은 옵션을 보려면 길게 누르세요',
'Quick reaction emoji': '빠른 반응 이모지',
- 'Select emoji': '이모지 선택'
+ 'Select emoji': '이모지 선택',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts
index 6fb26145..e4ed880c 100644
--- a/src/i18n/locales/pl.ts
+++ b/src/i18n/locales/pl.ts
@@ -583,6 +583,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Jeśli włączone, możesz zareagować jednym kliknięciem. Kliknij i przytrzymaj, aby uzyskać więcej opcji',
'Quick reaction emoji': 'Emoji szybkiej reakcji',
- 'Select emoji': 'Wybierz emoji'
+ 'Select emoji': 'Wybierz emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts
index cc71d34b..7f5397c5 100644
--- a/src/i18n/locales/pt-BR.ts
+++ b/src/i18n/locales/pt-BR.ts
@@ -578,6 +578,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Se ativado, você pode reagir com um único clique. Clique e segure para mais opções',
'Quick reaction emoji': 'Emoji de reação rápida',
- 'Select emoji': 'Selecionar emoji'
+ 'Select emoji': 'Selecionar emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts
index 98a6f155..00dcaff8 100644
--- a/src/i18n/locales/pt-PT.ts
+++ b/src/i18n/locales/pt-PT.ts
@@ -581,6 +581,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Se ativado, pode reagir com um único clique. Clique e mantenha premido para mais opções',
'Quick reaction emoji': 'Emoji de reação rápida',
- 'Select emoji': 'Selecionar emoji'
+ 'Select emoji': 'Selecionar emoji',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts
index db06931b..188bd82e 100644
--- a/src/i18n/locales/ru.ts
+++ b/src/i18n/locales/ru.ts
@@ -583,6 +583,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'Если включено, вы можете реагировать одним щелчком. Нажмите и удерживайте для дополнительных параметров',
'Quick reaction emoji': 'Эмодзи быстрой реакции',
- 'Select emoji': 'Выбрать эмодзи'
+ 'Select emoji': 'Выбрать эмодзи',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts
index 8aed9307..620b1b6d 100644
--- a/src/i18n/locales/th.ts
+++ b/src/i18n/locales/th.ts
@@ -570,6 +570,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'หากเปิดใช้งาน คุณสามารถรีแอคได้ด้วยคลิกเดียว คลิกค้างไว้สำหรับตัวเลือกเพิ่มเติม',
'Quick reaction emoji': 'อีโมจิรีแอคชั่นด่วน',
- 'Select emoji': 'เลือกอีโมจิ'
+ 'Select emoji': 'เลือกอีโมจิ',
+ 'NSFW content display': 'NSFW content display',
+ 'Hide completely': 'Hide completely',
+ 'Show but hide content': 'Show but hide content',
+ 'Show directly': 'Show directly',
+ 'Click to view': 'Click to view'
}
}
diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts
index 06cc817f..0130e5a0 100644
--- a/src/i18n/locales/zh.ts
+++ b/src/i18n/locales/zh.ts
@@ -563,6 +563,11 @@ export default {
'If enabled, you can react with a single click. Click and hold for more options':
'启用后,您可以通过单击进行点赞。长按以获取更多选项',
'Quick reaction emoji': '快速点赞表情',
- 'Select emoji': '选择表情'
+ 'Select emoji': '选择表情',
+ 'NSFW content display': 'NSFW 内容显示',
+ 'Hide completely': '完全隐藏',
+ 'Show but hide content': '显示但隐藏内容',
+ 'Show directly': '直接显示',
+ 'Click to view': '点击查看'
}
}
diff --git a/src/pages/secondary/GeneralSettingsPage/index.tsx b/src/pages/secondary/GeneralSettingsPage/index.tsx
index e8c87120..c5da59d9 100644
--- a/src/pages/secondary/GeneralSettingsPage/index.tsx
+++ b/src/pages/secondary/GeneralSettingsPage/index.tsx
@@ -4,14 +4,14 @@ import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
import { Switch } from '@/components/ui/switch'
-import { MEDIA_AUTO_LOAD_POLICY } from '@/constants'
+import { MEDIA_AUTO_LOAD_POLICY, NSFW_DISPLAY_POLICY } from '@/constants'
import { LocalizedLanguageNames, TLanguage } from '@/i18n'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { cn, isSupportCheckConnectionType } from '@/lib/utils'
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
-import { TMediaAutoLoadPolicy } from '@/types'
+import { TMediaAutoLoadPolicy, TNsfwDisplayPolicy } from '@/types'
import { SelectValue } from '@radix-ui/react-select'
import { RotateCcw } from 'lucide-react'
import { forwardRef, HTMLProps, useState } from 'react'
@@ -23,8 +23,8 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
const {
autoplay,
setAutoplay,
- defaultShowNsfw,
- setDefaultShowNsfw,
+ nsfwDisplayPolicy,
+ setNsfwDisplayPolicy,
hideContentMentioningMutedUsers,
setHideContentMentioningMutedUsers,
mediaAutoLoadPolicy,
@@ -110,10 +110,24 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
/>
-
diff --git a/src/providers/ContentPolicyProvider.tsx b/src/providers/ContentPolicyProvider.tsx
index 3c25a437..63ab2c7f 100644
--- a/src/providers/ContentPolicyProvider.tsx
+++ b/src/providers/ContentPolicyProvider.tsx
@@ -1,14 +1,14 @@
import { MEDIA_AUTO_LOAD_POLICY } from '@/constants'
import storage from '@/services/local-storage.service'
-import { TMediaAutoLoadPolicy } from '@/types'
+import { TMediaAutoLoadPolicy, TNsfwDisplayPolicy } from '@/types'
import { createContext, useContext, useEffect, useMemo, useState } from 'react'
type TContentPolicyContext = {
autoplay: boolean
setAutoplay: (autoplay: boolean) => void
- defaultShowNsfw: boolean
- setDefaultShowNsfw: (showNsfw: boolean) => void
+ nsfwDisplayPolicy: TNsfwDisplayPolicy
+ setNsfwDisplayPolicy: (policy: TNsfwDisplayPolicy) => void
hideContentMentioningMutedUsers?: boolean
setHideContentMentioningMutedUsers?: (hide: boolean) => void
@@ -33,7 +33,7 @@ export const useContentPolicy = () => {
export function ContentPolicyProvider({ children }: { children: React.ReactNode }) {
const [autoplay, setAutoplay] = useState(storage.getAutoplay())
- const [defaultShowNsfw, setDefaultShowNsfw] = useState(storage.getDefaultShowNsfw())
+ const [nsfwDisplayPolicy, setNsfwDisplayPolicy] = useState(storage.getNsfwDisplayPolicy())
const [hideContentMentioningMutedUsers, setHideContentMentioningMutedUsers] = useState(
storage.getHideContentMentioningMutedUsers()
)
@@ -72,9 +72,9 @@ export function ContentPolicyProvider({ children }: { children: React.ReactNode
setAutoplay(autoplay)
}
- const updateDefaultShowNsfw = (defaultShowNsfw: boolean) => {
- storage.setDefaultShowNsfw(defaultShowNsfw)
- setDefaultShowNsfw(defaultShowNsfw)
+ const updateNsfwDisplayPolicy = (policy: TNsfwDisplayPolicy) => {
+ storage.setNsfwDisplayPolicy(policy)
+ setNsfwDisplayPolicy(policy)
}
const updateHideContentMentioningMutedUsers = (hide: boolean) => {
@@ -97,8 +97,8 @@ export function ContentPolicyProvider({ children }: { children: React.ReactNode
value={{
autoplay,
setAutoplay: updateAutoplay,
- defaultShowNsfw,
- setDefaultShowNsfw: updateDefaultShowNsfw,
+ nsfwDisplayPolicy,
+ setNsfwDisplayPolicy: updateNsfwDisplayPolicy,
hideContentMentioningMutedUsers,
setHideContentMentioningMutedUsers: updateHideContentMentioningMutedUsers,
autoLoadMedia,
diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts
index 2489afd0..cf9adb52 100644
--- a/src/services/local-storage.service.ts
+++ b/src/services/local-storage.service.ts
@@ -5,6 +5,7 @@ import {
ExtendedKind,
MEDIA_AUTO_LOAD_POLICY,
NOTIFICATION_LIST_STYLE,
+ NSFW_DISPLAY_POLICY,
StorageKey,
TPrimaryColor
} from '@/constants'
@@ -19,6 +20,7 @@ import {
TMediaAutoLoadPolicy,
TMediaUploadServiceConfig,
TNoteListMode,
+ TNsfwDisplayPolicy,
TNotificationStyle,
TRelaySet,
TThemeSetting,
@@ -46,7 +48,6 @@ class LocalStorageService {
private hideUntrustedNotes: boolean = false
private translationServiceConfigMap: Record = {}
private mediaUploadServiceConfigMap: Record = {}
- private defaultShowNsfw: boolean = false
private dismissedTooManyRelaysAlert: boolean = false
private showKinds: number[] = []
private hideContentMentioningMutedUsers: boolean = false
@@ -60,6 +61,7 @@ class LocalStorageService {
private filterOutOnionRelays: boolean = !isTorBrowser()
private quickReaction: boolean = false
private quickReactionEmoji: string | TEmoji = '+'
+ private nsfwDisplayPolicy: TNsfwDisplayPolicy = NSFW_DISPLAY_POLICY.HIDE_CONTENT
constructor() {
if (!LocalStorageService.instance) {
@@ -161,7 +163,20 @@ class LocalStorageService {
this.mediaUploadServiceConfigMap = JSON.parse(mediaUploadServiceConfigMapStr)
}
- this.defaultShowNsfw = window.localStorage.getItem(StorageKey.DEFAULT_SHOW_NSFW) === 'true'
+ // Migrate old boolean setting to new policy
+ const nsfwDisplayPolicyStr = window.localStorage.getItem(StorageKey.NSFW_DISPLAY_POLICY)
+ if (
+ nsfwDisplayPolicyStr &&
+ Object.values(NSFW_DISPLAY_POLICY).includes(nsfwDisplayPolicyStr as TNsfwDisplayPolicy)
+ ) {
+ this.nsfwDisplayPolicy = nsfwDisplayPolicyStr as TNsfwDisplayPolicy
+ } else {
+ // Migration: convert old boolean to new policy
+ const defaultShowNsfwStr = window.localStorage.getItem(StorageKey.DEFAULT_SHOW_NSFW)
+ this.nsfwDisplayPolicy =
+ defaultShowNsfwStr === 'true' ? NSFW_DISPLAY_POLICY.SHOW : NSFW_DISPLAY_POLICY.HIDE_CONTENT
+ window.localStorage.setItem(StorageKey.NSFW_DISPLAY_POLICY, this.nsfwDisplayPolicy)
+ }
this.dismissedTooManyRelaysAlert =
window.localStorage.getItem(StorageKey.DISMISSED_TOO_MANY_RELAYS_ALERT) === 'true'
@@ -458,15 +473,6 @@ class LocalStorageService {
return config
}
- getDefaultShowNsfw() {
- return this.defaultShowNsfw
- }
-
- setDefaultShowNsfw(defaultShowNsfw: boolean) {
- this.defaultShowNsfw = defaultShowNsfw
- window.localStorage.setItem(StorageKey.DEFAULT_SHOW_NSFW, defaultShowNsfw.toString())
- }
-
getDismissedTooManyRelaysAlert() {
return this.dismissedTooManyRelaysAlert
}
@@ -592,6 +598,15 @@ class LocalStorageService {
typeof emoji === 'string' ? emoji : JSON.stringify(emoji)
)
}
+
+ getNsfwDisplayPolicy() {
+ return this.nsfwDisplayPolicy
+ }
+
+ setNsfwDisplayPolicy(policy: TNsfwDisplayPolicy) {
+ this.nsfwDisplayPolicy = policy
+ window.localStorage.setItem(StorageKey.NSFW_DISPLAY_POLICY, policy)
+ }
}
const instance = new LocalStorageService()
diff --git a/src/types/index.d.ts b/src/types/index.d.ts
index f005789d..408b112e 100644
--- a/src/types/index.d.ts
+++ b/src/types/index.d.ts
@@ -1,5 +1,5 @@
import { Event, Filter, VerifiedEvent } from 'nostr-tools'
-import { MEDIA_AUTO_LOAD_POLICY, NOTIFICATION_LIST_STYLE, POLL_TYPE } from '../constants'
+import { MEDIA_AUTO_LOAD_POLICY, NOTIFICATION_LIST_STYLE, NSFW_DISPLAY_POLICY, POLL_TYPE } from '../constants'
export type TSubRequestFilter = Omit & { limit: number }
@@ -205,3 +205,6 @@ export type TAwesomeRelayCollection = {
export type TMediaAutoLoadPolicy =
(typeof MEDIA_AUTO_LOAD_POLICY)[keyof typeof MEDIA_AUTO_LOAD_POLICY]
+
+export type TNsfwDisplayPolicy =
+ (typeof NSFW_DISPLAY_POLICY)[keyof typeof NSFW_DISPLAY_POLICY]