diff --git a/src/pages/innerMod.tsx b/src/pages/innerMod.tsx
index 49c6df8..b3b401d 100644
--- a/src/pages/innerMod.tsx
+++ b/src/pages/innerMod.tsx
@@ -3,7 +3,14 @@ import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { formatDate } from 'date-fns'
import { Filter, kinds, nip19, UnsignedEvent } from 'nostr-tools'
-import { Dispatch, SetStateAction, useCallback, useRef, useState } from 'react'
+import {
+ Dispatch,
+ SetStateAction,
+ useCallback,
+ useEffect,
+ useRef,
+ useState
+} from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { toast } from 'react-toastify'
import { BlogCard } from '../components/BlogCard'
@@ -212,6 +219,63 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
const [isLoading, setIsLoading] = useState(false)
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
const [showReportPopUp, setShowReportPopUp] = useState(false)
+ const [isBlocked, setIsBlocked] = useState(false)
+ const [isAddedToNSFW, setIsAddedToNSFW] = useState(false)
+
+ useEffect(() => {
+ if (userState.auth && userState.user?.pubkey) {
+ const pubkey = userState.user.pubkey as string
+
+ const muteListFilter: Filter = {
+ kinds: [kinds.Mutelist],
+ authors: [pubkey]
+ }
+
+ RelayController.getInstance()
+ .fetchEventFromUserRelays(muteListFilter, pubkey, UserRelaysType.Write)
+ .then((event) => {
+ if (event) {
+ // get a list of tags
+ const tags = event.tags
+ const blocked =
+ tags.findIndex((item) => item[0] === 'a' && item[1] === aTag) !==
+ -1
+
+ setIsBlocked(blocked)
+ }
+ })
+
+ if (
+ userState.user.npub &&
+ userState.user.npub === import.meta.env.VITE_REPORTING_NPUB
+ ) {
+ const nsfwListFilter: Filter = {
+ kinds: [kinds.Curationsets],
+ authors: [pubkey],
+ '#d': ['nsfw']
+ }
+
+ RelayController.getInstance()
+ .fetchEventFromUserRelays(
+ nsfwListFilter,
+ pubkey,
+ UserRelaysType.Write
+ )
+ .then((event) => {
+ if (event) {
+ // get a list of tags
+ const tags = event.tags
+ const existsInNSFWList =
+ tags.findIndex(
+ (item) => item[0] === 'a' && item[1] === aTag
+ ) !== -1
+
+ setIsAddedToNSFW(existsInNSFWList)
+ }
+ })
+ }
+ }
+ }, [userState, aTag])
const handleBlock = async () => {
let hexPubkey: string
@@ -258,6 +322,7 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
if (alreadyExists) {
setIsLoading(false)
+ setIsBlocked(true)
return toast.warn(`Mod reference is already in user's mute list`)
}
@@ -282,7 +347,53 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
setLoadingSpinnerDesc('Updating mute list event')
- await signAndPublish(unsignedEvent)
+ const isUpdated = await signAndPublish(unsignedEvent)
+ if (isUpdated) {
+ setIsBlocked(true)
+ }
+ setIsLoading(false)
+ }
+
+ const handleUnblock = async () => {
+ const pubkey = userState.user?.pubkey as string
+
+ const filter: Filter = {
+ kinds: [kinds.Mutelist],
+ authors: [pubkey]
+ }
+
+ setIsLoading(true)
+ setLoadingSpinnerDesc(`Finding user's mute list`)
+
+ // Fetch the mute list event from the relays. This returns the event containing the user's mute list.
+ const muteListEvent =
+ await RelayController.getInstance().fetchEventFromUserRelays(
+ filter,
+ pubkey,
+ UserRelaysType.Write
+ )
+
+ if (!muteListEvent) {
+ toast.error(`Couldn't get user's mute list event from relays`)
+ return
+ }
+
+ const tags = muteListEvent.tags
+
+ const unsignedEvent: UnsignedEvent = {
+ pubkey: muteListEvent.pubkey,
+ kind: muteListEvent.kind,
+ content: muteListEvent.content,
+ created_at: now(),
+ tags: tags.filter((item) => item[0] !== 'a' || item[1] !== aTag)
+ }
+
+ setLoadingSpinnerDesc('Updating mute list event')
+ const isUpdated = await signAndPublish(unsignedEvent)
+ if (isUpdated) {
+ setIsBlocked(false)
+ }
+
setIsLoading(false)
}
@@ -317,6 +428,7 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
if (alreadyExists) {
setIsLoading(false)
+ setIsAddedToNSFW(true)
return toast.warn(`Mod reference is already in user's nsfw list`)
}
@@ -344,7 +456,53 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
setLoadingSpinnerDesc('Updating nsfw list event')
- await signAndPublish(unsignedEvent)
+ const isUpdated = await signAndPublish(unsignedEvent)
+ if (isUpdated) {
+ setIsAddedToNSFW(true)
+ }
+ setIsLoading(false)
+ }
+
+ const handleUnblockNSFW = async () => {
+ const pubkey = userState.user?.pubkey as string
+
+ const filter: Filter = {
+ kinds: [kinds.Curationsets],
+ authors: [pubkey],
+ '#d': ['nsfw']
+ }
+
+ setIsLoading(true)
+ setLoadingSpinnerDesc('Finding NSFW list')
+
+ const nsfwListEvent =
+ await RelayController.getInstance().fetchEventFromUserRelays(
+ filter,
+ pubkey,
+ UserRelaysType.Write
+ )
+
+ if (!nsfwListEvent) {
+ toast.error(`Couldn't get nsfw list event from relays`)
+ return
+ }
+
+ const tags = nsfwListEvent.tags
+
+ const unsignedEvent: UnsignedEvent = {
+ pubkey: nsfwListEvent.pubkey,
+ kind: nsfwListEvent.kind,
+ content: nsfwListEvent.content,
+ created_at: now(),
+ tags: tags.filter((item) => item[0] !== 'a' || item[1] !== aTag)
+ }
+
+ setLoadingSpinnerDesc('Updating nsfw list event')
+ const isUpdated = await signAndPublish(unsignedEvent)
+ if (isUpdated) {
+ setIsAddedToNSFW(false)
+ }
+
setIsLoading(false)
}
@@ -456,7 +614,7 @@ const Game = ({ naddr, game, author, aTag }: GameProps) => {
- Block Post
+ {isBlocked ? 'Unblock' : 'Block'} Post
{isAdmin && (
- Block Post NSFW
+ {isAddedToNSFW ? 'Un-mark' : 'Mark'} as NSFW
)}
diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts
index 95f78dd..ef03678 100644
--- a/src/utils/nostr.ts
+++ b/src/utils/nostr.ts
@@ -138,7 +138,7 @@ export const extractZapAmount = (event: Event): number => {
* Signs and publishes an event to user's relays.
*
* @param unsignedEvent - The event object which needs to be signed before publishing.
- * @returns - A promise that resolves to an array of relay URLs where the event was successfully published, or null if the operation failed.
+ * @returns - A promise that resolves to boolean indicating whether the event was successfully signed and published
*/
export const signAndPublish = async (unsignedEvent: UnsignedEvent) => {
// Sign the event. This returns a signed event or null if signing fails.