Compare commits

...

3 Commits

Author SHA1 Message Date
Austin Chen
2b71e299d3 Support Firestore search over a reduced set of contracts 2022-09-02 18:50:17 -07:00
Austin Chen
9a101601fb Also support lowest % first 2022-09-02 18:27:26 -07:00
Austin Chen
1f6cab8cb4 Allow sorting by highest % 2022-09-02 18:26:26 -07:00
3 changed files with 52 additions and 5 deletions

View File

@ -3,11 +3,18 @@ import { Answer } from 'common/answer'
import { searchInAny } from 'common/util/parse' import { searchInAny } from 'common/util/parse'
import { sortBy } from 'lodash' import { sortBy } from 'lodash'
import { ContractsGrid } from 'web/components/contract/contracts-grid' import { ContractsGrid } from 'web/components/contract/contracts-grid'
import { useContracts } from 'web/hooks/use-contracts'
import { import {
usePersistentState, usePersistentState,
urlParamStore, urlParamStore,
} from 'web/hooks/use-persistent-state' } from 'web/hooks/use-persistent-state'
import { getProbability } from 'common/calculate'
import {
BinaryContract,
Contract,
PseudoNumericContract,
} from 'common/contract'
import { useEffect, useState } from 'react'
import { listAllContracts } from 'web/lib/firebase/contracts'
const MAX_CONTRACTS_RENDERED = 100 const MAX_CONTRACTS_RENDERED = 100
@ -18,13 +25,27 @@ export default function ContractSearchFirestore(props: {
excludeContractIds?: string[] excludeContractIds?: string[]
groupSlug?: string groupSlug?: string
} }
defaultSort?: string
getContracts?: () => Promise<Contract[]>
}) { }) {
const { additionalFilter } = props const { additionalFilter, getContracts } = props
const contracts = useContracts() const [contracts, setContracts] = useState<Contract[]>([])
const router = useRouter() const router = useRouter()
const store = urlParamStore(router) const store = urlParamStore(router)
const [query, setQuery] = usePersistentState('', { key: 'q', store }) const [query, setQuery] = usePersistentState('', { key: 'q', store })
const [sort, setSort] = usePersistentState('score', { key: 'sort', store }) const [sort, setSort] = usePersistentState(props.defaultSort ?? 'score', {
key: 'sort',
store,
})
useEffect(() => {
// Either set contracts from getContracts, or fallback to getting all of them
if (getContracts) {
getContracts().then(setContracts)
} else {
listAllContracts(100000).then(setContracts)
}
}, [getContracts])
let matches = (contracts ?? []).filter((c) => let matches = (contracts ?? []).filter((c) =>
searchInAny( searchInAny(
@ -51,6 +72,14 @@ export default function ContractSearchFirestore(props: {
// Use lodash for stable sort, so previous sort breaks all ties. // Use lodash for stable sort, so previous sort breaks all ties.
matches = sortBy(matches, ({ volume7Days }) => -1 * volume7Days) matches = sortBy(matches, ({ volume7Days }) => -1 * volume7Days)
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours) matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
} else if (sort === 'highest-percent') {
matches = sortBy(matches, (c) =>
getProbability(c as BinaryContract | PseudoNumericContract)
).reverse()
} else if (sort === 'lowest-percent') {
matches = sortBy(matches, (c) =>
getProbability(c as BinaryContract | PseudoNumericContract)
)
} }
if (additionalFilter) { if (additionalFilter) {
@ -104,6 +133,8 @@ export default function ContractSearchFirestore(props: {
<option value="most-traded">Most traded</option> <option value="most-traded">Most traded</option>
<option value="24-hour-vol">24h volume</option> <option value="24-hour-vol">24h volume</option>
<option value="close-date">Closing soon</option> <option value="close-date">Closing soon</option>
<option value="highest-percent">Highest %</option>
<option value="lowest-percent">Lowest %</option>
</select> </select>
</div> </div>
<ContractsGrid contracts={matches} showTime={showTime} /> <ContractsGrid contracts={matches} showTime={showTime} />

View File

@ -52,6 +52,8 @@ import { Post } from 'common/post'
import { Spacer } from 'web/components/layout/spacer' import { Spacer } from 'web/components/layout/spacer'
import { usePost } from 'web/hooks/use-post' import { usePost } from 'web/hooks/use-post'
import { useAdmin } from 'web/hooks/use-admin' import { useAdmin } from 'web/hooks/use-admin'
import { isTournament } from 'web/pages/tournaments'
import ContractSearchFirestore from 'web/pages/contract-search-firestore'
export const getStaticProps = fromPropz(getStaticPropz) export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: { params: { slugs: string[] } }) { export async function getStaticPropz(props: { params: { slugs: string[] } }) {
@ -220,7 +222,17 @@ export default function GroupPage(props: {
</Col> </Col>
) )
const questionsTab = ( // Use Firestore search for Tournament groups, so they can sort by highest
const questionsTab = isTournament(group.id) ? (
<ContractSearchFirestore
additionalFilter={{ groupSlug: group.slug }}
defaultSort="highest-percent"
getContracts={async () => {
const contracts = await listContractsByGroupSlug(group.slug)
return contracts.filter((c) => !c.isResolved)
}}
/>
) : (
<ContractSearch <ContractSearch
user={user} user={user}
defaultSort={'newest'} defaultSort={'newest'}

View File

@ -107,6 +107,10 @@ const tourneys: Tourney[] = [
// }, // },
] ]
export function isTournament(groupId: string) {
return tourneys.map((t) => t.groupId).includes(groupId)
}
export async function getStaticProps() { export async function getStaticProps() {
const groupIds = tourneys const groupIds = tourneys
.map((data) => data.groupId) .map((data) => data.groupId)