diff --git a/src/components/ContentPreview/index.tsx b/src/components/ContentPreview/index.tsx
index f0e28e91..662cbdbc 100644
--- a/src/components/ContentPreview/index.tsx
+++ b/src/components/ContentPreview/index.tsx
@@ -1,5 +1,7 @@
import { ExtendedKind } from '@/constants'
+import { isMentioningMutedUsers } from '@/lib/event'
import { cn } from '@/lib/utils'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { Event, kinds } from 'nostr-tools'
import { useMemo } from 'react'
@@ -22,10 +24,18 @@ export default function ContentPreview({
className?: string
}) {
const { t } = useTranslation()
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const isMuted = useMemo(
- () => (event ? mutePubkeys.includes(event.pubkey) : false),
- [mutePubkeys, event]
+ () => (event ? mutePubkeySet.has(event.pubkey) : false),
+ [mutePubkeySet, event]
+ )
+ const isMentioningMuted = useMemo(
+ () =>
+ hideContentMentioningMutedUsers && event
+ ? isMentioningMutedUsers(event, mutePubkeySet)
+ : false,
+ [event, mutePubkeySet]
)
if (!event) {
@@ -38,6 +48,14 @@ export default function ContentPreview({
)
}
+ if (isMentioningMuted) {
+ return (
+
+ [{t('This note mentions a user you muted')}]
+
+ )
+ }
+
if (
[
kinds.ShortTextNote,
diff --git a/src/components/MuteButton/index.tsx b/src/components/MuteButton/index.tsx
index 3a8ae4dc..651c3a9d 100644
--- a/src/components/MuteButton/index.tsx
+++ b/src/components/MuteButton/index.tsx
@@ -18,10 +18,10 @@ export default function MuteButton({ pubkey }: { pubkey: string }) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { pubkey: accountPubkey, checkLogin } = useNostr()
- const { mutePubkeys, changing, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } =
+ const { mutePubkeySet, changing, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } =
useMuteList()
const [updating, setUpdating] = useState(false)
- const isMuted = useMemo(() => mutePubkeys.includes(pubkey), [mutePubkeys, pubkey])
+ const isMuted = useMemo(() => mutePubkeySet.has(pubkey), [mutePubkeySet, pubkey])
if (!accountPubkey || (pubkey && pubkey === accountPubkey)) return null
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx
index 1d4b70e0..211ca611 100644
--- a/src/components/Note/index.tsx
+++ b/src/components/Note/index.tsx
@@ -54,7 +54,7 @@ export default function Note({
const usingClient = useMemo(() => getUsingClient(event), [event])
const { defaultShowNsfw } = useContentPolicy()
const [showNsfw, setShowNsfw] = useState(false)
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
const [showMuted, setShowMuted] = useState(false)
let content: React.ReactNode
@@ -67,7 +67,7 @@ export default function Note({
].includes(event.kind)
) {
content =
- } else if (mutePubkeys.includes(event.pubkey) && !showMuted) {
+ } else if (mutePubkeySet.has(event.pubkey) && !showMuted) {
content = setShowMuted(true)} />
} else if (!defaultShowNsfw && isNsfwEvent(event) && !showNsfw) {
content = setShowNsfw(true)} />
diff --git a/src/components/NoteCard/RepostNoteCard.tsx b/src/components/NoteCard/RepostNoteCard.tsx
index ccf5582d..ed8ed401 100644
--- a/src/components/NoteCard/RepostNoteCard.tsx
+++ b/src/components/NoteCard/RepostNoteCard.tsx
@@ -1,8 +1,10 @@
+import { isMentioningMutedUsers } from '@/lib/event'
import { tagNameEquals } from '@/lib/tag'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import client from '@/services/client.service'
import { Event, kinds, nip19, verifyEvent } from 'nostr-tools'
-import { useEffect, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
import MainNoteCard from './MainNoteCard'
export default function RepostNoteCard({
@@ -14,8 +16,19 @@ export default function RepostNoteCard({
className?: string
filterMutedNotes?: boolean
}) {
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const [targetEvent, setTargetEvent] = useState(null)
+ const shouldHide = useMemo(() => {
+ if (!targetEvent) return true
+ if (filterMutedNotes && mutePubkeySet.has(targetEvent.pubkey)) {
+ return true
+ }
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(targetEvent, mutePubkeySet)) {
+ return true
+ }
+ return false
+ }, [targetEvent, filterMutedNotes, hideContentMentioningMutedUsers, mutePubkeySet])
useEffect(() => {
const fetch = async () => {
try {
@@ -56,10 +69,7 @@ export default function RepostNoteCard({
fetch()
}, [event])
- if (!targetEvent) return null
- if (filterMutedNotes && mutePubkeys.includes(targetEvent.pubkey)) {
- return null
- }
+ if (!targetEvent || shouldHide) return null
return
}
diff --git a/src/components/NoteCard/index.tsx b/src/components/NoteCard/index.tsx
index b8bde9d3..9d4c70fc 100644
--- a/src/components/NoteCard/index.tsx
+++ b/src/components/NoteCard/index.tsx
@@ -1,6 +1,9 @@
import { Skeleton } from '@/components/ui/skeleton'
+import { isMentioningMutedUsers } from '@/lib/event'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { Event, kinds } from 'nostr-tools'
+import { useMemo } from 'react'
import MainNoteCard from './MainNoteCard'
import RepostNoteCard from './RepostNoteCard'
@@ -13,10 +16,18 @@ export default function NoteCard({
className?: string
filterMutedNotes?: boolean
}) {
- const { mutePubkeys } = useMuteList()
- if (filterMutedNotes && mutePubkeys.includes(event.pubkey)) {
- return null
- }
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
+ const shouldHide = useMemo(() => {
+ if (filterMutedNotes && mutePubkeySet.has(event.pubkey)) {
+ return true
+ }
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(event, mutePubkeySet)) {
+ return true
+ }
+ return false
+ }, [event, filterMutedNotes, mutePubkeySet])
+ if (shouldHide) return null
if (event.kind === kinds.Repost) {
return (
diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx
index a4448fba..cf0f6e61 100644
--- a/src/components/NoteList/index.tsx
+++ b/src/components/NoteList/index.tsx
@@ -2,9 +2,11 @@ import NewNotesButton from '@/components/NewNotesButton'
import { Button } from '@/components/ui/button'
import {
getReplaceableCoordinateFromEvent,
+ isMentioningMutedUsers,
isReplaceableEvent,
isReplyNoteEvent
} from '@/lib/event'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useDeletedEvent } from '@/providers/DeletedEventProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
@@ -13,7 +15,15 @@ import client from '@/services/client.service'
import { TFeedSubRequest } from '@/types'
import dayjs from 'dayjs'
import { Event } from 'nostr-tools'
-import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
+import {
+ forwardRef,
+ useCallback,
+ useEffect,
+ useImperativeHandle,
+ useMemo,
+ useRef,
+ useState
+} from 'react'
import { useTranslation } from 'react-i18next'
import PullToRefresh from 'react-simple-pull-to-refresh'
import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard'
@@ -44,7 +54,8 @@ const NoteList = forwardRef(
const { t } = useTranslation()
const { startLogin } = useNostr()
const { isUserTrusted } = useUserTrust()
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const { isEventDeleted } = useDeletedEvent()
const [events, setEvents] = useState([])
const [newEvents, setNewEvents] = useState([])
@@ -56,13 +67,30 @@ const NoteList = forwardRef(
const bottomRef = useRef(null)
const topRef = useRef(null)
+ const shouldHideEvent = useCallback(
+ (evt: Event) => {
+ if (isEventDeleted(evt)) return true
+ if (hideReplies && isReplyNoteEvent(evt)) return true
+ if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return true
+ if (filterMutedNotes && mutePubkeySet.has(evt.pubkey)) return true
+ if (
+ filterMutedNotes &&
+ hideContentMentioningMutedUsers &&
+ isMentioningMutedUsers(evt, mutePubkeySet)
+ ) {
+ return true
+ }
+
+ return false
+ },
+ [hideReplies, hideUntrustedNotes, mutePubkeySet, isEventDeleted]
+ )
+
const filteredEvents = useMemo(() => {
const idSet = new Set()
return events.slice(0, showCount).filter((evt) => {
- if (isEventDeleted(evt)) return false
- if (hideReplies && isReplyNoteEvent(evt)) return false
- if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return false
+ if (shouldHideEvent(evt)) return false
const id = isReplaceableEvent(evt.kind) ? getReplaceableCoordinateFromEvent(evt) : evt.id
if (idSet.has(id)) {
@@ -71,16 +99,13 @@ const NoteList = forwardRef(
idSet.add(id)
return true
})
- }, [events, hideReplies, hideUntrustedNotes, showCount, isEventDeleted])
+ }, [events, showCount, shouldHideEvent])
const filteredNewEvents = useMemo(() => {
const idSet = new Set()
return newEvents.filter((event: Event) => {
- if (isEventDeleted(event)) return false
- if (hideReplies && isReplyNoteEvent(event)) return false
- if (hideUntrustedNotes && !isUserTrusted(event.pubkey)) return false
- if (filterMutedNotes && mutePubkeys.includes(event.pubkey)) return false
+ if (shouldHideEvent(event)) return false
const id = isReplaceableEvent(event.kind)
? getReplaceableCoordinateFromEvent(event)
@@ -91,7 +116,7 @@ const NoteList = forwardRef(
idSet.add(id)
return true
})
- }, [newEvents, hideReplies, hideUntrustedNotes, filterMutedNotes, mutePubkeys, isEventDeleted])
+ }, [events, showCount, shouldHideEvent])
const scrollToTop = (behavior: ScrollBehavior = 'instant') => {
setTimeout(() => {
diff --git a/src/components/NoteOptions/useMenuActions.tsx b/src/components/NoteOptions/useMenuActions.tsx
index e3792fb9..c4b69573 100644
--- a/src/components/NoteOptions/useMenuActions.tsx
+++ b/src/components/NoteOptions/useMenuActions.tsx
@@ -47,8 +47,8 @@ export function useMenuActions({
const { t } = useTranslation()
const { pubkey, attemptDelete } = useNostr()
const { relaySets, favoriteRelays } = useFavoriteRelays()
- const { mutePubkeyPublicly, mutePubkeyPrivately, unmutePubkey, mutePubkeys } = useMuteList()
- const isMuted = useMemo(() => mutePubkeys.includes(event.pubkey), [mutePubkeys, event])
+ const { mutePubkeyPublicly, mutePubkeyPrivately, unmutePubkey, mutePubkeySet } = useMuteList()
+ const isMuted = useMemo(() => mutePubkeySet.has(event.pubkey), [mutePubkeySet, event])
const broadcastSubMenu: SubMenuAction[] = useMemo(() => {
const items = []
diff --git a/src/components/NoteStats/ReplyButton.tsx b/src/components/NoteStats/ReplyButton.tsx
index 0b449c19..de8406fa 100644
--- a/src/components/NoteStats/ReplyButton.tsx
+++ b/src/components/NoteStats/ReplyButton.tsx
@@ -1,4 +1,7 @@
+import { isMentioningMutedUsers } from '@/lib/event'
import { cn } from '@/lib/utils'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
+import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { useReply } from '@/providers/ReplyProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
@@ -14,18 +17,29 @@ export default function ReplyButton({ event }: { event: Event }) {
const { pubkey, checkLogin } = useNostr()
const { repliesMap } = useReply()
const { hideUntrustedInteractions, isUserTrusted } = useUserTrust()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const { replyCount, hasReplied } = useMemo(() => {
const hasReplied = pubkey
? repliesMap.get(event.id)?.events.some((evt) => evt.pubkey === pubkey)
: false
- if (hideUntrustedInteractions) {
- return {
- replyCount:
- repliesMap.get(event.id)?.events.filter((evt) => isUserTrusted(evt.pubkey)).length ?? 0,
- hasReplied
- }
+
+ return {
+ replyCount:
+ repliesMap.get(event.id)?.events.filter((evt) => {
+ if (hideUntrustedInteractions && !isUserTrusted(evt.pubkey)) {
+ return false
+ }
+ if (mutePubkeySet.has(evt.pubkey)) {
+ return false
+ }
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(evt, mutePubkeySet)) {
+ return false
+ }
+ return true
+ }).length ?? 0,
+ hasReplied
}
- return { replyCount: repliesMap.get(event.id)?.events.length ?? 0, hasReplied }
}, [repliesMap, event.id, hideUntrustedInteractions])
const [open, setOpen] = useState(false)
diff --git a/src/components/NotificationList/NotificationItem/index.tsx b/src/components/NotificationList/NotificationItem/index.tsx
index b86c8e86..d0caf42c 100644
--- a/src/components/NotificationList/NotificationItem/index.tsx
+++ b/src/components/NotificationList/NotificationItem/index.tsx
@@ -1,6 +1,9 @@
import { ExtendedKind } from '@/constants'
+import { isMentioningMutedUsers } from '@/lib/event'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { Event, kinds } from 'nostr-tools'
+import { useMemo } from 'react'
import { MentionNotification } from './MentionNotification'
import { PollResponseNotification } from './PollResponseNotification'
import { ReactionNotification } from './ReactionNotification'
@@ -14,10 +17,19 @@ export function NotificationItem({
notification: Event
isNew?: boolean
}) {
- const { mutePubkeys } = useMuteList()
- if (mutePubkeys.includes(notification.pubkey)) {
- return null
- }
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
+ const shouldHide = useMemo(() => {
+ if (mutePubkeySet.has(notification.pubkey)) {
+ return true
+ }
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(notification, mutePubkeySet)) {
+ return true
+ }
+ return false
+ }, [])
+ if (shouldHide) return null
+
if (notification.kind === kinds.Reaction) {
return
}
diff --git a/src/components/PostEditor/Mentions.tsx b/src/components/PostEditor/Mentions.tsx
index 4a6baa15..5463003e 100644
--- a/src/components/PostEditor/Mentions.tsx
+++ b/src/components/PostEditor/Mentions.tsx
@@ -23,7 +23,7 @@ export default function Mentions({
}) {
const { t } = useTranslation()
const { pubkey } = useNostr()
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
const [potentialMentions, setPotentialMentions] = useState([])
const [parentEventPubkey, setParentEventPubkey] = useState()
const [removedPubkeys, setRemovedPubkeys] = useState([])
@@ -43,13 +43,13 @@ export default function Mentions({
pubkeys
.filter((p) => potentialMentions.includes(p))
.concat(
- potentialMentions.filter((p) => mutePubkeys.includes(p) && p !== _parentEventPubkey)
+ potentialMentions.filter((p) => mutePubkeySet.has(p) && p !== _parentEventPubkey)
)
)
)
})
})
- }, [content, parentEvent, pubkey])
+ }, [content, parentEvent, pubkey, mutePubkeySet])
useEffect(() => {
const newMentions = potentialMentions.filter((pubkey) => !removedPubkeys.includes(pubkey))
diff --git a/src/components/Profile/ProfileFeed.tsx b/src/components/Profile/ProfileFeed.tsx
index 8e5e4db4..0162493a 100644
--- a/src/components/Profile/ProfileFeed.tsx
+++ b/src/components/Profile/ProfileFeed.tsx
@@ -108,6 +108,7 @@ export default function ProfileFeed({
subRequests={subRequests}
showKinds={temporaryShowKinds}
hideReplies={listMode === 'posts'}
+ filterMutedNotes={false}
/>
>
)
diff --git a/src/components/Profile/index.tsx b/src/components/Profile/index.tsx
index 66ae035f..fbab966d 100644
--- a/src/components/Profile/index.tsx
+++ b/src/components/Profile/index.tsx
@@ -31,7 +31,7 @@ export default function Profile({ id }: { id?: string }) {
const { push } = useSecondaryPage()
const { profile, isFetching } = useFetchProfile(id)
const { pubkey: accountPubkey } = useNostr()
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
const { followings } = useFetchFollowings(profile?.pubkey)
const isFollowingYou = useMemo(() => {
return (
@@ -176,7 +176,7 @@ export default function Profile({ id }: { id?: string }) {
{isSelf && (
- {mutePubkeys.length}
+ {mutePubkeySet.size}
{t('Muted')}
)}
diff --git a/src/components/ProfileOptions/index.tsx b/src/components/ProfileOptions/index.tsx
index 95462dc5..9004d4d2 100644
--- a/src/components/ProfileOptions/index.tsx
+++ b/src/components/ProfileOptions/index.tsx
@@ -9,17 +9,17 @@ import { pubkeyToNpub } from '@/lib/pubkey'
import { useMuteList } from '@/providers/MuteListProvider'
import { useNostr } from '@/providers/NostrProvider'
import { Bell, BellOff, Copy, Ellipsis } from 'lucide-react'
+import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
export default function ProfileOptions({ pubkey }: { pubkey: string }) {
const { t } = useTranslation()
const { pubkey: accountPubkey } = useNostr()
- const { mutePubkeys, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } = useMuteList()
+ const { mutePubkeySet, mutePubkeyPrivately, mutePubkeyPublicly, unmutePubkey } = useMuteList()
+ const isMuted = useMemo(() => mutePubkeySet.has(pubkey), [mutePubkeySet, pubkey])
if (pubkey === accountPubkey) return null
- const isMuted = mutePubkeys.includes(pubkey)
-
return (
diff --git a/src/components/ReplyNote/index.tsx b/src/components/ReplyNote/index.tsx
index eaa563ed..ac7c3352 100644
--- a/src/components/ReplyNote/index.tsx
+++ b/src/components/ReplyNote/index.tsx
@@ -1,8 +1,9 @@
import { useSecondaryPage } from '@/PageManager'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
-import { getUsingClient } from '@/lib/event'
+import { getUsingClient, isMentioningMutedUsers } from '@/lib/event'
import { toNote } from '@/lib/link'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { Event } from 'nostr-tools'
@@ -33,12 +34,21 @@ export default function ReplyNote({
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
const { push } = useSecondaryPage()
- const { mutePubkeys } = useMuteList()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const [showMuted, setShowMuted] = useState(false)
- const show = useMemo(
- () => showMuted || !mutePubkeys.includes(event.pubkey),
- [showMuted, mutePubkeys, event]
- )
+ const show = useMemo(() => {
+ if (showMuted) {
+ return true
+ }
+ if (mutePubkeySet.has(event.pubkey)) {
+ return false
+ }
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(event, mutePubkeySet)) {
+ return false
+ }
+ return true
+ }, [showMuted, mutePubkeySet, event, hideContentMentioningMutedUsers])
const usingClient = useMemo(() => getUsingClient(event), [event])
return (
diff --git a/src/components/ReplyNoteList/index.tsx b/src/components/ReplyNoteList/index.tsx
index 6eabf3e0..ce1cba17 100644
--- a/src/components/ReplyNoteList/index.tsx
+++ b/src/components/ReplyNoteList/index.tsx
@@ -5,11 +5,15 @@ import {
getRootATag,
getRootETag,
getRootEventHexId,
+ isMentioningMutedUsers,
isReplaceableEvent,
isReplyNoteEvent
} from '@/lib/event'
+import { toNote } from '@/lib/link'
import { generateBech32IdFromETag, tagNameEquals } from '@/lib/tag'
import { useSecondaryPage } from '@/PageManager'
+import { useContentPolicy } from '@/providers/ContentPolicyProvider'
+import { useMuteList } from '@/providers/MuteListProvider'
import { useReply } from '@/providers/ReplyProvider'
import { useUserTrust } from '@/providers/UserTrustProvider'
import client from '@/services/client.service'
@@ -29,8 +33,10 @@ const SHOW_COUNT = 10
export default function ReplyNoteList({ index, event }: { index?: number; event: NEvent }) {
const { t } = useTranslation()
- const { currentIndex } = useSecondaryPage()
+ const { push, currentIndex } = useSecondaryPage()
const { hideUntrustedInteractions, isUserTrusted } = useUserTrust()
+ const { mutePubkeySet } = useMuteList()
+ const { hideContentMentioningMutedUsers } = useContentPolicy()
const [rootInfo, setRootInfo] = useState(undefined)
const { repliesMap, addReplies } = useReply()
const replies = useMemo(() => {
@@ -44,6 +50,9 @@ export default function ReplyNoteList({ index, event }: { index?: number; event:
const events = parentEventKeys.flatMap((id) => repliesMap.get(id)?.events || [])
events.forEach((evt) => {
if (replyIdSet.has(evt.id)) return
+ if (mutePubkeySet.has(evt.pubkey)) return
+ if (hideContentMentioningMutedUsers && isMentioningMutedUsers(evt, mutePubkeySet)) return
+
replyIdSet.add(evt.id)
replyEvents.push(evt)
})
@@ -309,7 +318,14 @@ export default function ReplyNoteList({ index, event }: { index?: number; event:
parentEventHexId && highlightReply(parentEventHexId)}
+ onClickParent={() => {
+ if (!parentEventHexId) return
+ if (replies.every((r) => r.id !== parentEventHexId)) {
+ push(toNote(parentEventId ?? parentEventHexId))
+ return
+ }
+ highlightReply(parentEventHexId)
+ }}
highlight={highlightReplyId === reply.id}
/>
diff --git a/src/constants.ts b/src/constants.ts
index 32a5f692..768f7eb9 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -40,6 +40,7 @@ export const StorageKey = {
DISMISSED_TOO_MANY_RELAYS_ALERT: 'dismissedTooManyRelaysAlert',
SHOW_KINDS: 'showKinds',
SHOW_KINDS_VERSION: 'showKindsVersion',
+ HIDE_CONTENT_MENTIONING_MUTED_USERS: 'hideContentMentioningMutedUsers',
MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
ACCOUNT_RELAY_LIST_EVENT_MAP: 'accountRelayListEventMap', // deprecated
diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts
index 9ebea88c..cd8cbd72 100644
--- a/src/i18n/locales/ar.ts
+++ b/src/i18n/locales/ar.ts
@@ -372,6 +372,8 @@ export default {
'Deletion request sent to {{count}} relays': 'تم إرسال طلب الحذف إلى {{count}} ريلايات',
'Suitable Relays': 'الريلايات المناسبة',
'Type searching for people, keywords, or relays':
- 'اكتب للبحث عن أشخاص، كلمات مفتاحية، أو ريلايات'
+ 'اكتب للبحث عن أشخاص، كلمات مفتاحية، أو ريلايات',
+ 'Hide content mentioning muted users': 'إخفاء المحتوى الذي يذكر المستخدمين المكتومين',
+ 'This note mentions a user you muted': 'هذه الملاحظة تذكر مستخدماً قمت بكتمه'
}
}
diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts
index 08cf39a3..5161610d 100644
--- a/src/i18n/locales/de.ts
+++ b/src/i18n/locales/de.ts
@@ -380,6 +380,9 @@ export default {
'Deletion request sent to {{count}} relays': 'Löschanfrage an {{count}} Relays gesendet',
'Suitable Relays': 'Geeignete Relays',
'Type searching for people, keywords, or relays':
- 'Gib ein, um nach Personen, Schlüsselwörtern oder Relays zu suchen'
+ 'Gib ein, um nach Personen, Schlüsselwörtern oder Relays zu suchen',
+ 'Hide content mentioning muted users': 'Inhalte ausblenden, die stumme Benutzer erwähnen',
+ 'This note mentions a user you muted':
+ 'Diese Notiz erwähnt einen Benutzer, den Sie stumm geschaltet haben'
}
}
diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts
index cfc47f70..83ef1974 100644
--- a/src/i18n/locales/en.ts
+++ b/src/i18n/locales/en.ts
@@ -371,6 +371,8 @@ export default {
'Deletion request sent to {{count}} relays': 'Deletion request sent to {{count}} relays',
'Suitable Relays': 'Suitable Relays',
'Type searching for people, keywords, or relays':
- 'Type searching for people, keywords, or relays'
+ 'Type searching for people, keywords, or relays',
+ 'Hide content mentioning muted users': 'Hide content mentioning muted users',
+ 'This note mentions a user you muted': 'This note mentions a user you muted'
}
}
diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts
index 97d13882..0dc535be 100644
--- a/src/i18n/locales/es.ts
+++ b/src/i18n/locales/es.ts
@@ -377,6 +377,8 @@ export default {
'Solicitud de eliminación enviada a {{count}} relés',
'Suitable Relays': 'Relés adecuados',
'Type searching for people, keywords, or relays':
- 'Escribe para buscar personas, palabras clave o relés'
+ 'Escribe para buscar personas, palabras clave o relés',
+ 'Hide content mentioning muted users': 'Ocultar contenido que mencione usuarios silenciados',
+ 'This note mentions a user you muted': 'Esta nota menciona a un usuario que silenciaste'
}
}
diff --git a/src/i18n/locales/fa.ts b/src/i18n/locales/fa.ts
index 159e7776..c668b3cc 100644
--- a/src/i18n/locales/fa.ts
+++ b/src/i18n/locales/fa.ts
@@ -373,6 +373,8 @@ export default {
'Deletion request sent to {{count}} relays': 'درخواست حذف به {{count}} رله ارسال شد',
'Suitable Relays': 'رلههای مناسب',
'Type searching for people, keywords, or relays':
- 'برای جستجو افراد، کلمات کلیدی یا رلهها تایپ کنید'
+ 'برای جستجو افراد، کلمات کلیدی یا رلهها تایپ کنید',
+ 'Hide content mentioning muted users': 'مخفی کردن محتوای اشاره کننده به کاربران بیصدا شده',
+ 'This note mentions a user you muted': 'این یادداشت به کاربری که بیصدا کردهاید اشاره میکند'
}
}
diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts
index 27b368c3..0cd4840e 100644
--- a/src/i18n/locales/fr.ts
+++ b/src/i18n/locales/fr.ts
@@ -379,6 +379,10 @@ export default {
'Demande de suppression envoyée à {{count}} relais',
'Suitable Relays': 'Relais adaptés',
'Type searching for people, keywords, or relays':
- 'Tapez pour rechercher des personnes, des mots-clés ou des relais'
+ 'Tapez pour rechercher des personnes, des mots-clés ou des relais',
+ 'Hide content mentioning muted users':
+ 'Masquer le contenu mentionnant des utilisateurs masqués',
+ 'This note mentions a user you muted':
+ 'Cette note mentionne un utilisateur que vous avez masqué'
}
}
diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts
index 76fe4e0e..156813b4 100644
--- a/src/i18n/locales/it.ts
+++ b/src/i18n/locales/it.ts
@@ -377,6 +377,8 @@ export default {
'Richiesta di eliminazione inviata a {{count}} relays',
'Suitable Relays': 'Relays adatti',
'Type searching for people, keywords, or relays':
- 'Digita per cercare persone, parole chiave o relays'
+ 'Digita per cercare persone, parole chiave o relays',
+ 'Hide content mentioning muted users': 'Nascondi contenuto che menziona utenti silenziati',
+ 'This note mentions a user you muted': 'Questa nota menziona un utente che hai silenziato'
}
}
diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts
index 7d44d334..ee21f7a2 100644
--- a/src/i18n/locales/ja.ts
+++ b/src/i18n/locales/ja.ts
@@ -374,6 +374,8 @@ export default {
'削除リクエストが{{count}}個のリレーに送信されました',
'Suitable Relays': '適切なリレー',
'Type searching for people, keywords, or relays':
- '人、キーワード、またはリレーを検索するために入力してください'
+ '人、キーワード、またはリレーを検索するために入力してください',
+ 'Hide content mentioning muted users': 'ミュートしたユーザーを言及するコンテンツを非表示',
+ 'This note mentions a user you muted': 'このノートはミュートしたユーザーを言及しています'
}
}
diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts
index 76625ea8..4ec7539e 100644
--- a/src/i18n/locales/ko.ts
+++ b/src/i18n/locales/ko.ts
@@ -374,6 +374,8 @@ export default {
'삭제 요청이 {{count}}개의 릴레이로 전송되었습니다',
'Suitable Relays': '적합한 릴레이',
'Type searching for people, keywords, or relays':
- '사람, 키워드 또는 릴레이를 검색하려면 입력하세요'
+ '사람, 키워드 또는 릴레이를 검색하려면 입력하세요',
+ 'Hide content mentioning muted users': '뮤트된 사용자를 언급하는 콘텐츠 숨기기',
+ 'This note mentions a user you muted': '이 노트는 뮤트한 사용자를 언급합니다'
}
}
diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts
index 51e7d5e5..d2ccb5e6 100644
--- a/src/i18n/locales/pl.ts
+++ b/src/i18n/locales/pl.ts
@@ -378,6 +378,8 @@ export default {
'Żądanie usunięcia wysłane do {{count}} przekaźników',
'Suitable Relays': 'Odpowiednie przekaźniki',
'Type searching for people, keywords, or relays':
- 'Wpisz, aby wyszukać osoby, słowa kluczowe lub przekaźniki'
+ 'Wpisz, aby wyszukać osoby, słowa kluczowe lub przekaźniki',
+ 'Hide content mentioning muted users': 'Ukryj treści wspominające wyciszonych użytkowników',
+ 'This note mentions a user you muted': 'Ten wpis wspomina użytkownika, którego wyciszyłeś'
}
}
diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts
index ea3147f2..67534904 100644
--- a/src/i18n/locales/pt-BR.ts
+++ b/src/i18n/locales/pt-BR.ts
@@ -374,6 +374,8 @@ export default {
'Deletion request sent to {{count}} relays': 'Pedido de exclusão enviado para {{count}} relays',
'Suitable Relays': 'Relays adequados',
'Type searching for people, keywords, or relays':
- 'Digite para buscar pessoas, palavras-chave ou relays'
+ 'Digite para buscar pessoas, palavras-chave ou relays',
+ 'Hide content mentioning muted users': 'Ocultar conteúdo que menciona usuários silenciados',
+ 'This note mentions a user you muted': 'Esta nota menciona um usuário que você silenciou'
}
}
diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts
index 7aa6bc21..a2743567 100644
--- a/src/i18n/locales/pt-PT.ts
+++ b/src/i18n/locales/pt-PT.ts
@@ -377,6 +377,8 @@ export default {
'Pedido de eliminação enviado para {{count}} relays',
'Suitable Relays': 'Relays adequados',
'Type searching for people, keywords, or relays':
- 'Digite para buscar pessoas, palavras-chave ou relays'
+ 'Digite para buscar pessoas, palavras-chave ou relays',
+ 'Hide content mentioning muted users': 'Ocultar conteúdo que menciona utilizadores silenciados',
+ 'This note mentions a user you muted': 'Esta nota menciona um utilizador que silenciou'
}
}
diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts
index fc41f89f..462e7dc6 100644
--- a/src/i18n/locales/ru.ts
+++ b/src/i18n/locales/ru.ts
@@ -377,6 +377,9 @@ export default {
'Deletion request sent to {{count}} relays': 'Запрос на удаление отправлен на {{count}} релеев',
'Suitable Relays': 'Подходящие релея',
'Type searching for people, keywords, or relays':
- 'Начните ввод для поиска людей, ключевых слов или релеев'
+ 'Начните ввод для поиска людей, ключевых слов или релеев',
+ 'Hide content mentioning muted users': 'Скрыть контент, упоминающий заглушённых пользователей',
+ 'This note mentions a user you muted':
+ 'Эта заметка упоминает пользователя, которого вы заглушили'
}
}
diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts
index b1f0897b..5de44407 100644
--- a/src/i18n/locales/th.ts
+++ b/src/i18n/locales/th.ts
@@ -369,6 +369,8 @@ export default {
'Try deleting this note': 'ลองลบโน้ตนี้ดู',
'Deletion request sent to {{count}} relays': 'คำขอลบถูกส่งไปยังรีเลย์ {{count}} รายการ',
'Suitable Relays': 'รีเลย์ที่เหมาะสม',
- 'Type searching for people, keywords, or relays': 'พิมพ์เพื่อค้นหาผู้คน คีย์เวิร์ด หรือรีเลย์'
+ 'Type searching for people, keywords, or relays': 'พิมพ์เพื่อค้นหาผู้คน คีย์เวิร์ด หรือรีเลย์',
+ 'Hide content mentioning muted users': 'ซ่อนเนื้อหาที่กล่าวถึงผู้ใช้ที่ปิดเสียง',
+ 'This note mentions a user you muted': 'โน้ตนี้กล่าวถึงผู้ใช้ที่คุณปิดเสียง'
}
}
diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts
index c2802e0c..d42dce96 100644
--- a/src/i18n/locales/zh.ts
+++ b/src/i18n/locales/zh.ts
@@ -367,6 +367,8 @@ export default {
'Try deleting this note': '尝试删除此笔记',
'Deletion request sent to {{count}} relays': '删除请求已发送到 {{count}} 个服务器',
'Suitable Relays': '适合的服务器',
- 'Type searching for people, keywords, or relays': '输入以搜索用户、关键词或服务器'
+ 'Type searching for people, keywords, or relays': '输入以搜索用户、关键词或服务器',
+ 'Hide content mentioning muted users': '隐藏提及已屏蔽用户的内容',
+ 'This note mentions a user you muted': '此笔记提及了您已屏蔽的用户'
}
}
diff --git a/src/lib/event.ts b/src/lib/event.ts
index 729ea78e..73b68088 100644
--- a/src/lib/event.ts
+++ b/src/lib/event.ts
@@ -47,6 +47,15 @@ export function isProtectedEvent(event: Event) {
return event.tags.some(([tagName]) => tagName === '-')
}
+export function isMentioningMutedUsers(event: Event, mutePubkeySet: Set) {
+ for (const [tagName, pubkey] of event.tags) {
+ if (tagName === 'p' && mutePubkeySet.has(pubkey)) {
+ return true
+ }
+ }
+ return false
+}
+
export function getParentETag(event?: Event) {
if (!event) return undefined
diff --git a/src/pages/secondary/GeneralSettingsPage/index.tsx b/src/pages/secondary/GeneralSettingsPage/index.tsx
index 6da326e8..e4a8215b 100644
--- a/src/pages/secondary/GeneralSettingsPage/index.tsx
+++ b/src/pages/secondary/GeneralSettingsPage/index.tsx
@@ -16,7 +16,14 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
const { t, i18n } = useTranslation()
const [language, setLanguage] = useState(i18n.language as TLanguage)
const { themeSetting, setThemeSetting } = useTheme()
- const { autoplay, setAutoplay, defaultShowNsfw, setDefaultShowNsfw } = useContentPolicy()
+ const {
+ autoplay,
+ setAutoplay,
+ defaultShowNsfw,
+ setDefaultShowNsfw,
+ hideContentMentioningMutedUsers,
+ setHideContentMentioningMutedUsers
+ } = useContentPolicy()
const { hideUntrustedNotes, updateHideUntrustedNotes } = useUserTrust()
const handleLanguageChange = (value: TLanguage) => {
@@ -76,6 +83,16 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
onCheckedChange={updateHideUntrustedNotes}
/>
+
+
+
+