@@ -1,9 +1,8 @@
1import cn from 'classnames';
1import cn from 'classnames';
2−import React, { useCallback, useEffect, useRef, useState } from 'react';
2+import React, { useCallback, useRef, useState } from 'react';
3import debounce from 'lodash.debounce';
3import debounce from 'lodash.debounce';
4−import { useMutation, useQuery, useQueryClient } from 'react-query';
4+import { useMutation, useQueryClient } from 'react-query';
5import { useNavigate, useParams } from 'react-router-dom';
5import { useNavigate, useParams } from 'react-router-dom';
6−import { stringToTa } from '@urbit/api';
7import { SearchInput } from '../components/SearchInput';
6import { SearchInput } from '../components/SearchInput';
8import { Listings } from '../components/Listings';
7import { Listings } from '../components/Listings';
9import { PostFilter, Remove, Search as SearchType } from '../types/sphinx';
8import { PostFilter, Remove, Search as SearchType } from '../types/sphinx';
@@ -12,6 +11,10 @@ import { Paginator } from '../components/Paginator';
12import { Filter } from '../components/Filter';
11import { Filter } from '../components/Filter';
13import { PlusSmIcon } from '@heroicons/react/solid';
12import { PlusSmIcon } from '@heroicons/react/solid';
14import { usePals } from '../state/pals';
13import { 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';
16interface RouteParams extends Record<string, string | undefined> {
19interface RouteParams extends Record<string, string | undefined> {
17 lookup?: string;
20 lookup?: string;
@@ -19,14 +22,6 @@ interface RouteParams extends Record<string, string | undefined> {
19 page?: string;
22 page?: string;
22−function encodeLookup(value: string | undefined) {
27− return stringToTa(value).replace('~.', '~~');
30export const Search = () => {
25export const Search = () => {
31 const navigate = useNavigate();
26 const navigate = useNavigate();
@@ -37,16 +32,26 @@ export const Search = () => {
37 const [selected, setSelected] = useState<PostFilter>('all')
32 const [selected, setSelected] = useState<PostFilter>('all')
38 const [rawSearch, setRawSearch] = useState(lookup || '');
33 const [rawSearch, setRawSearch] = useState(lookup || '');
39 const { installed: palsInstalled } = usePals();
34 const { installed: palsInstalled } = usePals();
40− const size = parseInt(limit || '10', 10);
35+
41− const pageInt = parseInt(page || '1', 10) - 1;
36+ const {
42− const start = pageInt * size;
39+ pageInt,
43− const { data } = useQuery<unknown, unknown, SearchType>(`lookup-${selected}-${size}-${start}-${lookup}`, () => api.scry<SearchType>({
44+ key: (start, size) => `lookup-${selected}-${size}-${start}-${lookup}`,
45+ fetcher: (start, size) => api.scry<SearchType>({
44− app: 'sphinx',
46+ app: 'sphinx',
45− path: `/lookup/${selected}/${start}/${size}/${encodeLookup(lookup)}`
47+ path: `/lookup/${selected}/${start}/${size}/${encodeLookup(lookup)}`
47 enabled: !!lookup,
49 enabled: !!lookup,
48− keepPreviousData: true
50+ limit,
52+ linkPrefix: `/search/${lookup}`
54+ const tags = useTags();
50 const queryClient = useQueryClient();
55 const queryClient = useQueryClient();
51 const { mutate } = useMutation((hash: string) => {
56 const { mutate } = useMutation((hash: string) => {
52 return api.poke<Remove>({
57 return api.poke<Remove>({
@@ -60,12 +65,6 @@ export const Search = () => {
63− const total = data?.total || 0;
67− : Math.floor(total / size) + 1;
69 const update = useRef(debounce((value: string) => {
68 const update = useRef(debounce((value: string) => {
70 if (!value) {
69 if (!value) {
@@ -79,16 +78,8 @@ export const Search = () => {
79 update.current(value);
78 update.current(value);
82− const linkBuild = useCallback((page) => {
87− return `/search/${lookup}/${size}/${page || 1}`
91− <>
82+ <div className={cn('w-full space-y-6', !lookup && 'm-auto')}>
92 <header className='flex items-center space-x-2'>
83 <header className='flex items-center space-x-2'>
93 <SearchInput className='flex-1' lookup={rawSearch} onChange={onChange} />
84 <SearchInput className='flex-1' lookup={rawSearch} onChange={onChange} />
94 <Filter selected={selected} onSelect={setSelected} className="min-w-0 sm:w-20" />
85 <Filter selected={selected} onSelect={setSelected} className="min-w-0 sm:w-20" />
@@ -102,13 +93,19 @@ export const Search = () => {
102 to see listings from others
93 to see listings from others
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'>
106 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />
97 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />
108− {lookup && <Listings listings={data?.listings || []} remove={mutate} />}
99+ {lookup && <Listings listings={results.listings} remove={mutate} />}
101+ <div className='space-y-2'>
102+ <h2 className='font-semibold'>top tags</h2>
103+ <TagCloud tags={tags.slice(0,12)} />
109− {data && pages > 1 && <div className='flex justify-end border-t border-zinc-300'>
106+ {results && pages > 1 && <div className='flex justify-end border-t border-zinc-300'>
110 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />
107 <Paginator pages={pages} currentPage={pageInt} linkBuilder={linkBuild} />