From 376164cbf48a72ad5b55202b47f1a050e07c3d4f Mon Sep 17 00:00:00 2001 From: enes Date: Wed, 27 Nov 2024 19:56:19 +0100 Subject: [PATCH] refactor: add repost tag if missing --- src/hooks/useCuratedSet.tsx | 15 +++++++++++++++ src/pages/mod/index.tsx | 9 ++++++--- src/pages/mod/loader.ts | 27 ++++++++++++++++++++++++++- src/pages/mods.tsx | 17 +++++++++++++++-- src/pages/profile/index.tsx | 21 ++++++++++++++------- src/pages/profile/loader.ts | 30 ++++++++++++++++++++++++++---- src/utils/curationSets.ts | 32 ++++++++++++++++++++++++++++++-- 7 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 src/hooks/useCuratedSet.tsx diff --git a/src/hooks/useCuratedSet.tsx b/src/hooks/useCuratedSet.tsx new file mode 100644 index 0000000..85ecaab --- /dev/null +++ b/src/hooks/useCuratedSet.tsx @@ -0,0 +1,15 @@ +import { useState } from 'react' +import { useNDKContext } from './useNDKContext' +import { useDidMount } from './useDidMount' +import { CurationSetIdentifiers, getReportingSet } from 'utils' + +export const useCuratedSet = (type: CurationSetIdentifiers) => { + const ndkContext = useNDKContext() + const [curatedSet, setCuratedSet] = useState([]) + + useDidMount(async () => { + setCuratedSet(await getReportingSet(type, ndkContext)) + }) + + return curatedSet +} diff --git a/src/pages/mod/index.tsx b/src/pages/mod/index.tsx index 53d2944..9581c3f 100644 --- a/src/pages/mod/index.tsx +++ b/src/pages/mod/index.tsx @@ -514,9 +514,12 @@ const Body = ({ {repost && (

- REPOST. Original Author:{' '} - {!!originalAuthor && ( - + REPOST + {originalAuthor && originalAuthor !== '' && ( + <> + . Original Author:{' '} + + )}

diff --git a/src/pages/mod/loader.ts b/src/pages/mod/loader.ts index 81f4a1d..22476f1 100644 --- a/src/pages/mod/loader.ts +++ b/src/pages/mod/loader.ts @@ -12,10 +12,12 @@ import { NSFWFilter } from 'types' import { + CurationSetIdentifiers, DEFAULT_FILTER_OPTIONS, extractBlogCardDetails, extractModData, getLocalStorageItem, + getReportingSet, log, LogType } from 'utils' @@ -83,7 +85,8 @@ export const modRouteLoader = ndkContext.fetchEvent(modFilter), ndkContext.fetchEvents(latestFilter), ndkContext.getMuteLists(loggedInUserPubkey), // Pass pubkey for logged-in users - ndkContext.getNSFWList() + getReportingSet(CurationSetIdentifiers.NSFW, ndkContext), + getReportingSet(CurationSetIdentifiers.Repost, ndkContext) ]) const result: ModPageLoaderResult = { @@ -205,6 +208,28 @@ export const modRouteLoader = log(true, LogType.Error, 'Issue fetching nsfw list', nsfwList.reason) } + const repostList = settled[4] + if (repostList.status === 'fulfilled' && repostList.value) { + // Check if the mod is marked as Repost + // Mark it as Repost only if it's missing the tag + if (result.mod) { + const isMissingRepostTag = + !result.mod.repost && + result.mod.aTag && + repostList.value.includes(result.mod.aTag) + + if (isMissingRepostTag) { + result.mod.repost = true + } + + if (result.mod.aTag && repostList.value.includes(result.mod.aTag)) { + result.isRepost = true + } + } + } else if (repostList.status === 'rejected') { + log(true, LogType.Error, 'Issue fetching nsfw list', repostList.reason) + } + // Filter latest, sort and take only three result.latest = result.latest .filter( diff --git a/src/pages/mods.tsx b/src/pages/mods.tsx index 31dd301..72c8c7a 100644 --- a/src/pages/mods.tsx +++ b/src/pages/mods.tsx @@ -19,8 +19,13 @@ import '../styles/pagination.css' import '../styles/search.css' import '../styles/styles.css' import { FilterOptions, ModDetails } from '../types' -import { DEFAULT_FILTER_OPTIONS, scrollIntoView } from 'utils' +import { + CurationSetIdentifiers, + DEFAULT_FILTER_OPTIONS, + scrollIntoView +} from 'utils' import { SearchInput } from 'components/SearchInput' +import { useCuratedSet } from 'hooks/useCuratedSet' export const ModsPage = () => { const scrollTargetRef = useRef(null) @@ -97,6 +102,14 @@ export const ModsPage = () => { muteLists ) + // Add repost tag to mods included in repostList + const repostList = useCuratedSet(CurationSetIdentifiers.Repost) + const filteredModListRepost = filteredModList.map((mod) => { + return !mod.repost && repostList.includes(mod.aTag) + ? { ...mod, repost: true } + : mod + }) + return ( <> {isFetching && } @@ -111,7 +124,7 @@ export const ModsPage = () => {
- {filteredModList.map((mod) => ( + {filteredModListRepost.map((mod) => ( ))}
diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 56758a6..83dfa51 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -10,9 +10,7 @@ import { useAppSelector, useFilteredMods, useLocalStorage, - useMuteLists, - useNDKContext, - useNSFWList + useNDKContext } from 'hooks' import { kinds, UnsignedEvent } from 'nostr-tools' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' @@ -47,7 +45,10 @@ export const ProfilePage = () => { profilePubkey, profile, isBlocked: _isBlocked, - isOwnProfile + isOwnProfile, + repostList, + muteLists, + nsfwList } = useLoaderData() as ProfilePageLoaderResult const scrollTargetRef = useRef(null) const { ndk, publish, fetchEventFromUserRelays, fetchMods } = useNDKContext() @@ -200,8 +201,6 @@ export const ProfilePage = () => { const [filterOptions] = useLocalStorage(filterKey, { ...DEFAULT_FILTER_OPTIONS }) - const muteLists = useMuteLists() - const nsfwList = useNSFWList() const handleNext = useCallback(() => { setIsLoading(true) @@ -263,6 +262,7 @@ export const ProfilePage = () => { break } }, [filterOptions.source, tab, fetchMods, profilePubkey]) + const filteredModList = useFilteredMods( mods, userState, @@ -272,6 +272,13 @@ export const ProfilePage = () => { profilePubkey ) + // Add repost tag to mods included in repostList + const filteredModListRepost = filteredModList.map((mod) => { + return !mod.repost && repostList.includes(mod.aTag) + ? { ...mod, repost: true } + : mod + }) + return (
@@ -422,7 +429,7 @@ export const ProfilePage = () => {
- {filteredModList.map((mod) => ( + {filteredModListRepost.map((mod) => ( ))}
diff --git a/src/pages/profile/loader.ts b/src/pages/profile/loader.ts index f3ac4c0..b9c13e9 100644 --- a/src/pages/profile/loader.ts +++ b/src/pages/profile/loader.ts @@ -4,7 +4,13 @@ import { LoaderFunctionArgs, redirect } from 'react-router-dom' import { appRoutes, getProfilePageRoute } from 'routes' import { store } from 'store' import { MuteLists, UserProfile } from 'types' -import { log, LogType, npubToHex } from 'utils' +import { + CurationSetIdentifiers, + getReportingSet, + log, + LogType, + npubToHex +} from 'utils' export interface ProfilePageLoaderResult { profilePubkey: string @@ -16,6 +22,7 @@ export interface ProfilePageLoaderResult { user: MuteLists } nsfwList: string[] + repostList: string[] } export const profileRouteLoader = @@ -87,7 +94,8 @@ export const profileRouteLoader = replaceableEvents: [] } }, - nsfwList: [] + nsfwList: [], + repostList: [] } // Check if user the user is logged in @@ -98,7 +106,8 @@ export const profileRouteLoader = const settled = await Promise.allSettled([ ndkContext.findMetadata(profilePubkey), ndkContext.getMuteLists(userPubkey), - ndkContext.getNSFWList() + getReportingSet(CurationSetIdentifiers.NSFW, ndkContext), + getReportingSet(CurationSetIdentifiers.Repost, ndkContext) ]) // Check the profile event result @@ -138,10 +147,23 @@ export const profileRouteLoader = log( true, LogType.Error, - 'Failed to fetch mutelist.', + 'Failed to fetch nsfwlist.', nsfwListResult.reason ) } + // Check the profile event result + const repostListResult = settled[3] + if (repostListResult.status === 'fulfilled' && repostListResult.value) { + result.repostList = repostListResult.value + } else if (repostListResult.status === 'rejected') { + log( + true, + LogType.Error, + 'Failed to fetch repost list.', + repostListResult.reason + ) + } + return result } diff --git a/src/utils/curationSets.ts b/src/utils/curationSets.ts index 2ddb153..e117789 100644 --- a/src/utils/curationSets.ts +++ b/src/utils/curationSets.ts @@ -1,9 +1,9 @@ -import { NDKFilter } from '@nostr-dev-kit/ndk' +import { NDKFilter, NDKList } from '@nostr-dev-kit/ndk' import { NDKContextType } from 'contexts/NDKContext' import { UnsignedEvent, kinds } from 'nostr-tools' import { toast } from 'react-toastify' import { UserRelaysType } from 'types' -import { now, signAndPublish } from './nostr' +import { now, npubToHex, signAndPublish } from './nostr' interface CurationSetArgs { dTag: CurationSetIdentifiers @@ -54,6 +54,34 @@ export async function createCurationSet( return isUpdated } +export async function getReportingSet( + dTag: CurationSetIdentifiers, + ndkContext: NDKContextType +) { + const result: string[] = [] + const reportingNpub = import.meta.env.VITE_REPORTING_NPUB + const hexKey = npubToHex(reportingNpub) + + if (hexKey) { + const event = await ndkContext.fetchEvent({ + kinds: [kinds.Curationsets], + authors: [hexKey], + '#d': [dTag] + }) + + if (event) { + const list = NDKList.from(event) + list.items.forEach((item) => { + if (item[0] === 'a') { + result.push(item[1]) + } + }) + } + } + + return result +} + export async function getCurationSet({ dTag, pubkey,