index.tsx raw
1 import SearchBar, { TSearchBarRef } from '@/components/SearchBar'
2 import SearchResult from '@/components/SearchResult'
3 import { Button } from '@/components/ui/button'
4 import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
5 import { toSearch } from '@/lib/link'
6 import { parseNakReqCommand } from '@/lib/nak-parser'
7 import { useSecondaryPage } from '@/PageManager'
8 import { TSearchParams } from '@/types'
9 import { ChevronLeft } from 'lucide-react'
10 import { forwardRef, useEffect, useMemo, useRef, useState } from 'react'
11
12 const SearchPage = forwardRef(({ index }: { index?: number }, ref) => {
13 const { push, pop } = useSecondaryPage()
14 const [input, setInput] = useState('')
15 const searchBarRef = useRef<TSearchBarRef>(null)
16 const searchParams = useMemo(() => {
17 const params = new URLSearchParams(window.location.search)
18 const type = params.get('t')
19 if (
20 type !== 'profile' &&
21 type !== 'profiles' &&
22 type !== 'notes' &&
23 type !== 'hashtag' &&
24 type !== 'relay' &&
25 type !== 'nak'
26 ) {
27 return null
28 }
29 const search = params.get('q')
30 if (!search) {
31 return null
32 }
33 const input = params.get('i') ?? ''
34 let request = undefined
35 if (type === 'nak') {
36 try {
37 request = parseNakReqCommand(input)
38 } catch {
39 // ignore invalid request param
40 }
41 }
42 setInput(input || search)
43 return { type, search, input, request } as TSearchParams
44 }, [])
45
46 useEffect(() => {
47 if (!window.location.search) {
48 searchBarRef.current?.focus()
49 }
50 }, [])
51
52 const onSearch = (params: TSearchParams | null) => {
53 if (params) {
54 push(toSearch(params))
55 }
56 }
57
58 return (
59 <SecondaryPageLayout
60 ref={ref}
61 index={index}
62 titlebar={
63 <div className="flex items-center gap-1 h-full">
64 <Button variant="ghost" size="titlebar-icon" onClick={() => pop()}>
65 <ChevronLeft />
66 </Button>
67 <SearchBar ref={searchBarRef} input={input} setInput={setInput} onSearch={onSearch} />
68 </div>
69 }
70 displayScrollToTopButton
71 >
72 <SearchResult searchParams={searchParams} />
73 </SecondaryPageLayout>
74 )
75 })
76 SearchPage.displayName = 'SearchPage'
77 export default SearchPage
78