Use firestore-based search for private instances
This commit is contained in:
parent
16ac25bb77
commit
fee36a378c
|
@ -19,7 +19,7 @@ import { ContractsGrid } from './contract/contracts-list'
|
|||
import { Row } from './layout/row'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Spacer } from './layout/spacer'
|
||||
import { ENV } from 'common/envs/constants'
|
||||
import { ENV, IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { useFollows } from 'web/hooks/use-follows'
|
||||
import { EditCategoriesButton } from './feed/category-selector'
|
||||
|
@ -28,6 +28,7 @@ import { Tabs } from './layout/tabs'
|
|||
import { EditFollowingButton } from './following-button'
|
||||
import { track } from '@amplitude/analytics-browser'
|
||||
import { trackCallback } from 'web/lib/service/analytics'
|
||||
import { ContractSearchFirestore } from 'web/pages/contract-search-firestore'
|
||||
|
||||
const searchClient = algoliasearch(
|
||||
'GJQPAYENIF',
|
||||
|
@ -121,6 +122,10 @@ export function ContractSearch(props: {
|
|||
|
||||
const indexName = `${indexPrefix}contracts-${sort}`
|
||||
|
||||
if (IS_PRIVATE_MANIFOLD) {
|
||||
return <ContractSearchFirestore querySortOptions={querySortOptions} />
|
||||
}
|
||||
|
||||
return (
|
||||
<InstantSearch searchClient={searchClient} indexName={indexName}>
|
||||
<Row className="gap-1 sm:gap-2">
|
||||
|
|
101
web/pages/contract-search-firestore.tsx
Normal file
101
web/pages/contract-search-firestore.tsx
Normal file
|
@ -0,0 +1,101 @@
|
|||
import { Answer } from 'common/answer'
|
||||
import { sortBy } from 'lodash'
|
||||
import { useState } from 'react'
|
||||
import { ContractsGrid } from 'web/components/contract/contracts-list'
|
||||
import { LoadingIndicator } from 'web/components/loading-indicator'
|
||||
import { useContracts } from 'web/hooks/use-contracts'
|
||||
import {
|
||||
Sort,
|
||||
useInitialQueryAndSort,
|
||||
} from 'web/hooks/use-sort-and-query-params'
|
||||
|
||||
export function ContractSearchFirestore(props: {
|
||||
querySortOptions?: {
|
||||
defaultSort: Sort
|
||||
shouldLoadFromStorage?: boolean
|
||||
}
|
||||
}) {
|
||||
const contracts = useContracts()
|
||||
const { querySortOptions } = props
|
||||
|
||||
const { initialSort, initialQuery } = useInitialQueryAndSort(querySortOptions)
|
||||
const [sort, setSort] = useState(initialSort || 'newest')
|
||||
const [query, setQuery] = useState(initialQuery)
|
||||
|
||||
const queryWords = query.toLowerCase().split(' ')
|
||||
function check(corpus: string) {
|
||||
return queryWords.every((word) => corpus.toLowerCase().includes(word))
|
||||
}
|
||||
|
||||
let matches = (contracts ?? []).filter(
|
||||
(c) =>
|
||||
check(c.question) ||
|
||||
check(c.description) ||
|
||||
check(c.creatorName) ||
|
||||
check(c.creatorUsername) ||
|
||||
check(c.lowercaseTags.map((tag) => `#${tag}`).join(' ')) ||
|
||||
check(
|
||||
((c as any).answers ?? [])
|
||||
.map((answer: Answer) => answer.text)
|
||||
.join(' ')
|
||||
)
|
||||
)
|
||||
|
||||
if (sort === 'newest') {
|
||||
matches.sort((a, b) => b.createdTime - a.createdTime)
|
||||
} else if (sort === 'resolve-date') {
|
||||
matches = sortBy(matches, (contract) => -1 * (contract.resolutionTime ?? 0))
|
||||
} else if (sort === 'oldest') {
|
||||
matches.sort((a, b) => a.createdTime - b.createdTime)
|
||||
} else if (sort === 'close-date') {
|
||||
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
|
||||
matches = sortBy(
|
||||
matches,
|
||||
(contract) =>
|
||||
(sort === 'close-date' ? -1 : 1) * (contract.closeTime ?? Infinity)
|
||||
)
|
||||
} else if (sort === 'most-traded') {
|
||||
matches.sort((a, b) => b.volume - a.volume)
|
||||
} else if (sort === '24-hour-vol') {
|
||||
// Use lodash for stable sort, so previous sort breaks all ties.
|
||||
matches = sortBy(matches, ({ volume7Days }) => -1 * volume7Days)
|
||||
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Show a search input next to a sort dropdown */}
|
||||
<div className="mt-2 mb-8 flex justify-between gap-2">
|
||||
<input
|
||||
type="text"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Search markets"
|
||||
className="input input-bordered w-full"
|
||||
/>
|
||||
<select
|
||||
className="select select-bordered"
|
||||
value={sort}
|
||||
onChange={(e) => setSort(e.target.value as Sort)}
|
||||
>
|
||||
<option value="newest">Newest</option>
|
||||
<option value="oldest">Oldest</option>
|
||||
<option value="most-traded">Most traded</option>
|
||||
<option value="24-hour-vol">24h volume</option>
|
||||
<option value="close-date">Closing soon</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{contracts === undefined ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<ContractsGrid
|
||||
contracts={matches}
|
||||
loadMore={() => {}}
|
||||
hasMore={false}
|
||||
showCloseTime={['close-date', 'closed'].includes(sort)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user