diff --git a/src/components/RelayInfo/index.tsx b/src/components/RelayInfo/index.tsx
index 30a8c68f..6d12802f 100644
--- a/src/components/RelayInfo/index.tsx
+++ b/src/components/RelayInfo/index.tsx
@@ -80,7 +80,7 @@ function formatSoftware(software: string) {
return parts[parts.length - 1]
}
-function RelayBadges({ relayInfo }: { relayInfo: TRelayInfo }) {
+export function RelayBadges({ relayInfo }: { relayInfo: TRelayInfo }) {
return (
{relayInfo.supported_nips?.includes(42) && (
diff --git a/src/components/SearchDialog/index.tsx b/src/components/SearchDialog/index.tsx
index 2499ed25..c1faba17 100644
--- a/src/components/SearchDialog/index.tsx
+++ b/src/components/SearchDialog/index.tsx
@@ -2,10 +2,11 @@ import { SecondaryPageLink } from '@/PageManager'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { CommandDialog, CommandInput, CommandItem, CommandList } from '@/components/ui/command'
import { useSearchProfiles } from '@/hooks'
-import { toNote, toNoteList, toProfile, toProfileList } from '@/lib/link'
+import { toNote, toNoteList, toProfile, toProfileList, toRelay } from '@/lib/link'
import { generateImageByPubkey } from '@/lib/pubkey'
+import { normalizeUrl } from '@/lib/url'
import { TProfile } from '@/types'
-import { Hash, Notebook, UserRound } from 'lucide-react'
+import { Hash, Notebook, Server, UserRound } from 'lucide-react'
import { nip19 } from 'nostr-tools'
import { Dispatch, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
@@ -15,6 +16,13 @@ export function SearchDialog({ open, setOpen }: { open: boolean; setOpen: Dispat
const [input, setInput] = useState('')
const [debouncedInput, setDebouncedInput] = useState(input)
const { profiles } = useSearchProfiles(debouncedInput, 10)
+ const normalizedUrl = useMemo(() => {
+ try {
+ return normalizeUrl(debouncedInput)
+ } catch {
+ return undefined
+ }
+ }, [debouncedInput])
const list = useMemo(() => {
const search = input.trim()
@@ -47,6 +55,7 @@ export function SearchDialog({ open, setOpen }: { open: boolean; setOpen: Dispat
return (
<>
+ {!!normalizedUrl &&
setOpen(false)} />}
setOpen(false)} />
setOpen(false)} />
{profiles.map((profile) => (
@@ -61,7 +70,7 @@ export function SearchDialog({ open, setOpen }: { open: boolean; setOpen: Dispat
)}
>
)
- }, [input, profiles, setOpen])
+ }, [input, debouncedInput, profiles, setOpen])
useEffect(() => {
const handler = setTimeout(() => {
@@ -146,3 +155,14 @@ function ProfileItem({ profile, onClick }: { profile: TProfile; onClick?: () =>
)
}
+
+function RelayItem({ url, onClick }: { url: string; onClick?: () => void }) {
+ return (
+
+
+
+ {url}
+
+
+ )
+}
diff --git a/src/hooks/useFetchRelayInfo.tsx b/src/hooks/useFetchRelayInfo.tsx
index b515eca8..cb09cd70 100644
--- a/src/hooks/useFetchRelayInfo.tsx
+++ b/src/hooks/useFetchRelayInfo.tsx
@@ -2,11 +2,12 @@ import client from '@/services/client.service'
import { TRelayInfo } from '@/types'
import { useEffect, useState } from 'react'
-export function useFetchRelayInfo(url: string) {
+export function useFetchRelayInfo(url?: string) {
const [isFetching, setIsFetching] = useState(true)
const [relayInfo, setRelayInfo] = useState(undefined)
useEffect(() => {
+ if (!url) return
const fetchRelayInfos = async () => {
setIsFetching(true)
const timer = setTimeout(() => {
diff --git a/src/providers/DeepBrowsingProvider.tsx b/src/providers/DeepBrowsingProvider.tsx
index 8348f233..d6951b8f 100644
--- a/src/providers/DeepBrowsingProvider.tsx
+++ b/src/providers/DeepBrowsingProvider.tsx
@@ -1,4 +1,4 @@
-import { createContext, useContext, useEffect, useState } from 'react'
+import { createContext, useContext, useEffect, useRef, useState } from 'react'
type TDeepBrowsingContext = {
deepBrowsing: boolean
@@ -25,9 +25,12 @@ export function DeepBrowsingProvider({
scrollAreaRef?: React.RefObject
}) {
const [deepBrowsing, setDeepBrowsing] = useState(false)
- const [lastScrollTop, setLastScrollTop] = useState(0)
+ const lastScrollTopRef = useRef(
+ (!scrollAreaRef ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
+ )
useEffect(() => {
+ setDeepBrowsing(false)
if (!active) return
const handleScroll = () => {
@@ -43,19 +46,17 @@ export function DeepBrowsingProvider({
}
const scrollTop = (!scrollAreaRef ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
- const diff = scrollTop - lastScrollTop
+ const diff = scrollTop - lastScrollTopRef.current
+ lastScrollTopRef.current = scrollTop
if (scrollTop <= 800) {
setDeepBrowsing(false)
- setLastScrollTop(scrollTop)
return
}
if (diff > 20) {
setDeepBrowsing(true)
- setLastScrollTop(scrollTop)
} else if (diff < -20) {
setDeepBrowsing(false)
- setLastScrollTop(scrollTop)
}
}
@@ -70,10 +71,10 @@ export function DeepBrowsingProvider({
return () => {
scrollAreaRef.current?.removeEventListener('scroll', handleScroll)
}
- }, [lastScrollTop, active])
+ }, [active])
return (
-
+
{children}
)