From 203e27b19d2d7dae7f7566b9997fe2ce80abfce8 Mon Sep 17 00:00:00 2001 From: daniyal Date: Thu, 29 Aug 2024 18:26:06 +0500 Subject: [PATCH] feat: added the ability to unblock the posts --- src/pages/innerMod.tsx | 172 +++++++++++++++++++++++++++++++++++++++-- src/utils/nostr.ts | 2 +- 2 files changed, 166 insertions(+), 8 deletions(-) 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. -- 2.34.1