@@ -1,9 +1,8 @@
11import cn from 'classnames';
2−import React, { useCallback, useEffect, useRef, useState } from 'react';
2+import React, { useCallback, useRef, useState } from 'react';
33import debounce from 'lodash.debounce';
4−import { useMutation, useQuery, useQueryClient } from 'react-query';
4+import { useMutation, useQueryClient } from 'react-query';
55import { useNavigate, useParams } from 'react-router-dom';
6−import { stringToTa } from '@urbit/api';
76import { SearchInput } from '../components/SearchInput';
87import { Listings } from '../components/Listings';
98import { PostFilter, Remove, Search as SearchType } from '../types/sphinx';
@@ -12,6 +11,10 @@ import { Paginator } from '../components/Paginator';
1211import { Filter } from '../components/Filter';
1312import { PlusSmIcon } from '@heroicons/react/solid';
1413import { usePals } from '../state/pals';
14+import { TagCloud } from '../components/TagCloud';
15+import { useTags } from '../state/tags';
16+import { useSearch } from '../state/search';
17+import { encodeLookup } from '../utils';
1518
1619interface RouteParams extends Record<string, string | undefined> {
1720 lookup?: string;
@@ -19,14 +22,6 @@ interface RouteParams extends Record<string, string | undefined> {
1922 page?: string;
2023}
2124
22−function encodeLookup(value: string | undefined) {
23− if (!value) {
24− return '';
25− }
26−
27− return stringToTa(value).replace('~.', '~~');
28−}
29−
3025export const Search = () => {
3126 const navigate = useNavigate();
3227 const {
@@ -37,16 +32,26 @@ export const Search = () => {
3732 const [selected, setSelected] = useState<PostFilter>('all')
3833 const [rawSearch, setRawSearch] = useState(lookup || '');
3934 const { installed: palsInstalled } = usePals();
40− const size = parseInt(limit || '10', 10);
41− const pageInt = parseInt(page || '1', 10) - 1;
42− const start = pageInt * size;
43− const { data } = useQuery<unknown, unknown, SearchType>(`lookup-${selected}-${size}-${start}-${lookup}`, () => api.scry<SearchType>({
44− app: 'sphinx',
45− path: `/lookup/${selected}/${start}/${size}/${encodeLookup(lookup)}`
46− }), {
35+
36+ const {
37+ size,
38+ start,
39+ pageInt,
40+ pages,
41+ results,
42+ linkBuild
43+ } = useSearch({
44+ key: (start, size) => `lookup-${selected}-${size}-${start}-${lookup}`,
45+ fetcher: (start, size) => api.scry<SearchType>({
46+ app: 'sphinx',
47+ path: `/lookup/${selected}/${start}/${size}/${encodeLookup(lookup)}`
48+ }),
4749 enabled: !!lookup,
48− keepPreviousData: true
50+ limit,
51+ page,
52+ linkPrefix: `/search/${lookup}`
4953 });
54+ const tags = useTags();
5055 const queryClient = useQueryClient();
5156 const { mutate } = useMutation((hash: string) => {
5257 return api.poke<Remove>({
@@ -60,12 +65,6 @@ export const Search = () => {
6065 }
6166 });
6267
63− const total = data?.total || 0;
64− const pages =
65− total % size === 0
66− ? total / size
67− : Math.floor(total / size) + 1;
68−
6968 const update = useRef(debounce((value: string) => {
7069 if (!value) {
7170 return;
@@ -79,16 +78,8 @@ export const Search = () => {
7978 update.current(value);
8079 }, []);
8180
82− const linkBuild = useCallback((page) => {
83− if (!page) {
84− return null;
85− }
86−
87− return `/search/${lookup}/${size}/${page || 1}`
88− }, [lookup, size]);
89−
9081 return (
91− <>
82+ <div className={cn('w-full space-y-6', !lookup && 'm-auto')}>
9283 <header className='flex items-center space-x-2'>
9384 <SearchInput className='flex-1' lookup={rawSearch} onChange={onChange} />
9485 <Filter selected={selected} onSelect={setSelected} className="min-w-0 sm:w-20" />
@@ -102,13 +93,19 @@ export const Search = () => {
10293 to see listings from others
10394 </div>
10495 )}
105− {lookup && data && <div className='flex justify-end border-t border-zinc-300'>
96+ {lookup && results && <div className='flex justify-end border-t border-zinc-300'>
10697 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />
10798 </div>}
108− {lookup && <Listings listings={data?.listings || []} remove={mutate} />}
109− {data && pages > 1 && <div className='flex justify-end border-t border-zinc-300'>
99+ {lookup && <Listings listings={results.listings} remove={mutate} />}
100+ {!lookup && (
101+ <div className='space-y-2'>
102+ <h2 className='font-semibold'>top tags</h2>
103+ <TagCloud tags={tags.slice(0,12)} />
104+ </div>
105+ )}
106+ {results && pages > 1 && <div className='flex justify-end border-t border-zinc-300'>
110107 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />
111108 </div>}
112− </>
109+ </div>
113110 )
114111}