@@ -151,7 +141,6 @@ export const SearchPage = () => {
filterOptions={filterOptions}
muteLists={muteLists}
nsfwList={nsfwList}
- el={scrollTargetRef.current}
/>
)}
{searchKind === SearchKindEnum.Users && (
@@ -274,15 +263,13 @@ type ModsResultProps = {
user: MuteLists
}
nsfwList: string[]
- el: HTMLElement | null
}
const ModsResult = ({
filterOptions,
searchTerm,
muteLists,
- nsfwList,
- el
+ nsfwList
}: ModsResultProps) => {
const { ndk } = useNDKContext()
const [mods, setMods] = useState([])
@@ -318,9 +305,7 @@ const ModsResult = ({
}, [ndk])
useEffect(() => {
- scrollIntoView(el)
setPage(1)
- // eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchTerm])
const filteredMods = useMemo(() => {
@@ -349,12 +334,10 @@ const ModsResult = ({
)
const handleNext = () => {
- scrollIntoView(el)
setPage((prev) => prev + 1)
}
const handlePrev = () => {
- scrollIntoView(el)
setPage((prev) => prev - 1)
}
@@ -409,7 +392,7 @@ const UsersResult = ({
}
setIsFetching(true)
- fetchEvents(filter)
+ fetchEvents(filter, ['wss://purplepag.es', 'wss://user.kindpag.es'])
.then((events) => {
const results = events.map((event) => {
const ndkEvent = new NDKEvent(undefined, event)
diff --git a/src/pages/settings/index.tsx b/src/pages/settings/index.tsx
index 4c0f618..60aa2c8 100644
--- a/src/pages/settings/index.tsx
+++ b/src/pages/settings/index.tsx
@@ -1,4 +1,5 @@
import { AdminSVG, PreferenceSVG, ProfileSVG, RelaySVG } from 'components/SVGs'
+import { MetadataController } from 'controllers'
import { useAppSelector } from 'hooks'
import { logout } from 'nostr-login'
import { useEffect, useState } from 'react'
@@ -56,12 +57,15 @@ const SettingTabs = () => {
const userState = useAppSelector((state) => state.user)
useEffect(() => {
- const adminNpubs = import.meta.env.VITE_ADMIN_NPUBS.split(',')
- if (userState.auth && userState.user?.npub) {
- setIsAdmin(adminNpubs.includes(userState.user.npub as string))
- } else {
- setIsAdmin(false)
- }
+ MetadataController.getInstance().then((controller) => {
+ if (userState.auth && userState.user?.npub) {
+ setIsAdmin(
+ controller.adminNpubs.includes(userState.user.npub as string)
+ )
+ } else {
+ setIsAdmin(false)
+ }
+ })
}, [userState])
const handleSignOut = () => {
diff --git a/src/pages/settings/profile.tsx b/src/pages/settings/profile.tsx
index 907d0f0..52f69f7 100644
--- a/src/pages/settings/profile.tsx
+++ b/src/pages/settings/profile.tsx
@@ -1,6 +1,6 @@
import { InputField } from 'components/Inputs'
import { ProfileQRButtonWithPopUp } from 'components/ProfileSection'
-import { useAppDispatch, useAppSelector, useNDKContext } from 'hooks'
+import { useAppDispatch, useAppSelector } from 'hooks'
import { kinds, nip19, UnsignedEvent, Event } from 'nostr-tools'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
@@ -14,6 +14,7 @@ import {
profileFromEvent,
serializeProfile
} from '@nostr-dev-kit/ndk'
+import { RelayController } from 'controllers'
import { LoadingSpinner } from 'components/LoadingSpinner'
import { setUser } from 'store/reducers/user'
import placeholderMod from '../../assets/img/DEGMods Placeholder Img.png'
@@ -42,7 +43,6 @@ const defaultFormState: FormState = {
export const ProfileSettings = () => {
const dispatch = useAppDispatch()
const userState = useAppSelector((state) => state.user)
- const { ndk, publish } = useNDKContext()
const [isPublishing, setIsPublishing] = useState(false)
const [formState, setFormState] = useState(defaultFormState)
@@ -163,8 +163,9 @@ export const ProfileSettings = () => {
return
}
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ const publishedOnRelays = await RelayController.getInstance().publish(
+ signedEvent as Event
+ )
// Handle cases where publishing failed or succeeded
if (publishedOnRelays.length === 0) {
diff --git a/src/pages/settings/relay.tsx b/src/pages/settings/relay.tsx
index 1a32d28..ee79d94 100644
--- a/src/pages/settings/relay.tsx
+++ b/src/pages/settings/relay.tsx
@@ -1,23 +1,21 @@
-import {
- getRelayListForUser,
- NDKEvent,
- NDKRelayList,
- NDKRelayStatus
-} from '@nostr-dev-kit/ndk'
+import { NDKRelayList } from '@nostr-dev-kit/ndk'
import { InputField } from 'components/Inputs'
import { LoadingSpinner } from 'components/LoadingSpinner'
-import { useAppSelector, useDidMount, useNDKContext } from 'hooks'
+import {
+ MetadataController,
+ RelayController,
+ UserRelaysType
+} from 'controllers'
+import { useAppSelector, useDidMount } from 'hooks'
import { Event, kinds, UnsignedEvent } from 'nostr-tools'
import { useEffect, useState } from 'react'
import { toast } from 'react-toastify'
-import { UserRelaysType } from 'types'
import { log, LogType, normalizeWebSocketURL, now } from 'utils'
const READ_MARKER = 'read'
const WRITE_MARKER = 'write'
export const RelaySettings = () => {
- const { ndk, publish } = useNDKContext()
const userState = useAppSelector((state) => state.user)
const [ndkRelayList, setNDKRelayList] = useState(null)
const [isPublishing, setIsPublishing] = useState(false)
@@ -25,8 +23,10 @@ export const RelaySettings = () => {
const [inputValue, setInputValue] = useState('')
useEffect(() => {
- if (userState.auth && userState.user?.pubkey) {
- getRelayListForUser(userState.user.pubkey as string, ndk)
+ const fetchRelayList = async (pubkey: string) => {
+ const metadataController = await MetadataController.getInstance()
+ metadataController
+ .getNDKRelayList(pubkey)
.then((res) => {
setNDKRelayList(res)
})
@@ -38,10 +38,14 @@ export const RelaySettings = () => {
)
setNDKRelayList(null)
})
+ }
+
+ if (userState.auth && userState.user?.pubkey) {
+ fetchRelayList(userState.user.pubkey as string)
} else {
setNDKRelayList(null)
}
- }, [userState, ndk])
+ }, [userState])
const handleAdd = async (relayUrl: string) => {
if (!ndkRelayList) return
@@ -74,8 +78,11 @@ export const RelaySettings = () => {
return
}
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ const publishedOnRelays =
+ await RelayController.getInstance().publishOnRelays(
+ signedEvent,
+ ndkRelayList.writeRelayUrls
+ )
// Handle cases where publishing failed or succeeded
if (publishedOnRelays.length === 0) {
@@ -133,8 +140,11 @@ export const RelaySettings = () => {
return
}
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ const publishedOnRelays =
+ await RelayController.getInstance().publishOnRelays(
+ signedEvent,
+ ndkRelayList.writeRelayUrls
+ )
// Handle cases where publishing failed or succeeded
if (publishedOnRelays.length === 0) {
@@ -204,8 +214,11 @@ export const RelaySettings = () => {
return
}
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ const publishedOnRelays =
+ await RelayController.getInstance().publishOnRelays(
+ signedEvent,
+ ndkRelayList.writeRelayUrls
+ )
// Handle cases where publishing failed or succeeded
if (publishedOnRelays.length === 0) {
@@ -369,29 +382,17 @@ const RelayListItem = ({
changeRelayType
}: RelayItemProps) => {
const [isConnected, setIsConnected] = useState(false)
- const { ndk } = useNDKContext()
useDidMount(() => {
- const ndkPool = ndk.pool
-
- ndkPool.on('relay:connect', (relay) => {
- if (relay.url === relayUrl) {
- setIsConnected(true)
- }
- })
-
- ndkPool.on('relay:disconnect', (relay) => {
- if (relay.url === relayUrl) {
- setIsConnected(false)
- }
- })
-
- const relay = ndkPool.relays.get(relayUrl)
- if (relay && relay.status >= NDKRelayStatus.CONNECTED) {
- setIsConnected(true)
- } else {
- setIsConnected(false)
- }
+ RelayController.getInstance()
+ .connectRelay(relayUrl)
+ .then((relay) => {
+ if (relay && relay.connected) {
+ setIsConnected(true)
+ } else {
+ setIsConnected(false)
+ }
+ })
})
return (
diff --git a/src/pages/submitMod.tsx b/src/pages/submitMod.tsx
index ba79874..226b896 100644
--- a/src/pages/submitMod.tsx
+++ b/src/pages/submitMod.tsx
@@ -29,7 +29,7 @@ export const SubmitModPage = () => {
useDidMount(async () => {
if (naddr) {
const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
- const { identifier, kind, pubkey } = decoded.data
+ const { identifier, kind, pubkey, relays = [] } = decoded.data
const filter: NDKFilter = {
'#a': [identifier],
@@ -39,7 +39,7 @@ export const SubmitModPage = () => {
setIsFetching(true)
- fetchEvent(filter)
+ fetchEvent(filter, relays)
.then((event) => {
if (event) {
const extracted = extractModData(event)
diff --git a/src/styles/cardMod.css b/src/styles/cardMod.css
index 3250d41..3028908 100644
--- a/src/styles/cardMod.css
+++ b/src/styles/cardMod.css
@@ -96,7 +96,6 @@
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2;
- line-clamp: 2;
font-size: 20px;
line-height: 1.25;
color: rgba(255, 255, 255, 0.75);
@@ -108,7 +107,6 @@
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2;
- line-clamp: 2;
color: rgba(255, 255, 255, 0.5);
font-size: 15px;
line-height: 1.5;
@@ -121,12 +119,11 @@
justify-content: start;
align-items: center;
font-size: 14px;
- background: rgba(255, 255, 255, 0.05);
+ background: rgba(255,255,255,0.05);
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 1;
- line-clamp: 1;
}
.cMMFootReactions {
@@ -146,12 +143,3 @@
align-items: center;
color: rgba(255, 255, 255, 0.25);
}
-
-.IBMSMSMBSSTagsTag.IBMSMSMBSSTagsTagNSFW.IBMSMSMBSSTagsTagNSFWCard {
- position: absolute;
- bottom: 10px;
- right: 10px;
- -webkit-backdrop-filter: blur(10px);
- backdrop-filter: blur(10px);
- background: rgba(35, 35, 35, 0.85);
-}
diff --git a/src/types/user.ts b/src/types/user.ts
index 059ba84..551bd1f 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -1,9 +1,3 @@
import { NDKUserProfile } from '@nostr-dev-kit/ndk'
export type UserProfile = NDKUserProfile | null
-
-export enum UserRelaysType {
- Read = 'readRelayUrls',
- Write = 'writeRelayUrls',
- Both = 'bothRelayUrls'
-}
diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts
index 130d023..f3711b0 100644
--- a/src/utils/nostr.ts
+++ b/src/utils/nostr.ts
@@ -9,8 +9,9 @@ import {
UnsignedEvent
} from 'nostr-tools'
import { toast } from 'react-toastify'
+import { RelayController } from '../controllers'
import { log, LogType } from './utils'
-import NDK, { NDKEvent } from '@nostr-dev-kit/ndk'
+import { NDKEvent } from '@nostr-dev-kit/ndk'
/**
* Get the current time in seconds since the Unix epoch (January 1, 1970).
@@ -122,11 +123,7 @@ export const extractZapAmount = (event: Event): number => {
* @param unsignedEvent - The event object which needs to be signed before publishing.
* @returns - A promise that resolves to boolean indicating whether the event was successfully signed and published
*/
-export const signAndPublish = async (
- unsignedEvent: UnsignedEvent,
- ndk: NDK,
- publish: (event: NDKEvent) => Promise
-) => {
+export const signAndPublish = async (unsignedEvent: UnsignedEvent) => {
// Sign the event. This returns a signed event or null if signing fails.
const signedEvent = await window.nostr
?.signEvent(unsignedEvent)
@@ -141,10 +138,11 @@ export const signAndPublish = async (
// If the event couldn't be signed, exit the function and return null.
if (!signedEvent) return false
- // Publish the signed event to the relays.
+ // Publish the signed event to the relays using the RelayController.
// This returns an array of relay URLs where the event was successfully published.
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ const publishedOnRelays = await RelayController.getInstance().publish(
+ signedEvent as Event
+ )
// Handle cases where publishing to the relays failed
if (publishedOnRelays.length === 0) {
@@ -172,9 +170,7 @@ export const signAndPublish = async (
*/
export const sendDMUsingRandomKey = async (
message: string,
- receiver: string,
- ndk: NDK,
- publish: (event: NDKEvent) => Promise
+ receiver: string
) => {
// Generate a random secret key for encrypting the message
const secretKey = generateSecretKey()
@@ -205,8 +201,11 @@ export const sendDMUsingRandomKey = async (
// Finalize and sign the event using the generated secret key
const signedEvent = finalizeEvent(unsignedEvent, secretKey)
- const ndkEvent = new NDKEvent(ndk, signedEvent)
- const publishedOnRelays = await publish(ndkEvent)
+ // Publish the signed event (the encrypted DM) to the relays
+ const publishedOnRelays = await RelayController.getInstance().publishDM(
+ signedEvent,
+ receiver
+ )
// Handle cases where publishing to the relays failed
if (publishedOnRelays.length === 0) {
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 6c904e0..b321c91 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -135,14 +135,3 @@ export const handleModImageError = (
) => {
e.currentTarget.src = import.meta.env.VITE_FALLBACK_MOD_IMAGE
}
-
-export const scrollIntoView = (el: HTMLElement | null) => {
- if (el) {
- setTimeout(() => {
- el.scrollIntoView({
- behavior: 'smooth',
- block: 'start'
- })
- }, 100)
- }
-}