Query hot contracts from volume24Hours field.
This commit is contained in:
parent
6b4417d8b8
commit
16ab0e0c37
|
@ -1,10 +1,9 @@
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Bet, listenForRecentBets } from '../lib/firebase/bets'
|
|
||||||
import {
|
import {
|
||||||
computeHotContracts,
|
|
||||||
Contract,
|
Contract,
|
||||||
listenForContracts,
|
listenForContracts,
|
||||||
|
listenForHotContracts,
|
||||||
} from '../lib/firebase/contracts'
|
} from '../lib/firebase/contracts'
|
||||||
|
|
||||||
export const useContracts = () => {
|
export const useContracts = () => {
|
||||||
|
@ -18,14 +17,9 @@ export const useContracts = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useHotContracts = () => {
|
export const useHotContracts = () => {
|
||||||
const [recentBets, setRecentBets] = useState<Bet[] | 'loading'>('loading')
|
const [hotContracts, setHotContracts] = useState<Contract[] | undefined>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => listenForHotContracts(setHotContracts), [])
|
||||||
const oneDay = 1000 * 60 * 60 * 24
|
|
||||||
return listenForRecentBets(oneDay, setRecentBets)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
if (recentBets === 'loading') return 'loading'
|
return hotContracts
|
||||||
|
|
||||||
return computeHotContracts(recentBets)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
query,
|
query,
|
||||||
onSnapshot,
|
onSnapshot,
|
||||||
where,
|
where,
|
||||||
getDocs,
|
|
||||||
} from 'firebase/firestore'
|
} from 'firebase/firestore'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { db } from './init'
|
import { db } from './init'
|
||||||
|
@ -64,34 +63,3 @@ export function listenForUserBets(
|
||||||
setBets(bets)
|
setBets(bets)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listenForRecentBets(
|
|
||||||
timePeriodMs: number,
|
|
||||||
setBets: (bets: Bet[]) => void
|
|
||||||
) {
|
|
||||||
const recentQuery = query(
|
|
||||||
collectionGroup(db, 'bets'),
|
|
||||||
where('createdTime', '>', Date.now() - timePeriodMs)
|
|
||||||
)
|
|
||||||
return onSnapshot(recentQuery, (snap) => {
|
|
||||||
const bets = snap.docs.map((doc) => doc.data() as Bet)
|
|
||||||
|
|
||||||
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
|
||||||
|
|
||||||
setBets(bets)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getRecentBets(timePeriodMs: number) {
|
|
||||||
const recentQuery = query(
|
|
||||||
collectionGroup(db, 'bets'),
|
|
||||||
where('createdTime', '>', Date.now() - timePeriodMs)
|
|
||||||
)
|
|
||||||
|
|
||||||
const snapshot = await getDocs(recentQuery)
|
|
||||||
const bets = snapshot.docs.map((doc) => doc.data() as Bet)
|
|
||||||
|
|
||||||
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
|
||||||
|
|
||||||
return bets
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ import {
|
||||||
orderBy,
|
orderBy,
|
||||||
getDoc,
|
getDoc,
|
||||||
updateDoc,
|
updateDoc,
|
||||||
|
limit,
|
||||||
} from 'firebase/firestore'
|
} from 'firebase/firestore'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { Bet, getRecentBets } from './bets'
|
import { getValues, listenForValues } from './utils'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
export type Contract = {
|
export type Contract = {
|
||||||
id: string
|
id: string
|
||||||
|
@ -145,16 +145,19 @@ export function listenForContract(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeHotContracts(recentBets: Bet[]) {
|
const hotContractsQuery = query(
|
||||||
const contractBets = _.groupBy(recentBets, (bet) => bet.contractId)
|
contractCollection,
|
||||||
const hotContractIds = _.sortBy(Object.keys(contractBets), (contractId) =>
|
where('isResolved', '==', false),
|
||||||
_.sumBy(contractBets[contractId], (bet) => -1 * bet.amount)
|
orderBy('volume24Hours', 'desc'),
|
||||||
)
|
limit(4)
|
||||||
return hotContractIds
|
)
|
||||||
|
|
||||||
|
export function listenForHotContracts(
|
||||||
|
setHotContracts: (contracts: Contract[]) => void
|
||||||
|
) {
|
||||||
|
return listenForValues<Contract>(hotContractsQuery, setHotContracts)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getHotContracts() {
|
export function getHotContracts() {
|
||||||
const oneDay = 1000 * 60 * 60 * 24
|
return getValues<Contract>(hotContractsQuery)
|
||||||
const recentBets = await getRecentBets(oneDay)
|
|
||||||
return computeHotContracts(recentBets)
|
|
||||||
}
|
}
|
||||||
|
|
39
web/lib/firebase/utils.ts
Normal file
39
web/lib/firebase/utils.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { db } from './init'
|
||||||
|
import {
|
||||||
|
doc,
|
||||||
|
getDoc,
|
||||||
|
getDocs,
|
||||||
|
onSnapshot,
|
||||||
|
Query,
|
||||||
|
DocumentReference,
|
||||||
|
} from 'firebase/firestore'
|
||||||
|
|
||||||
|
export const getValue = async <T>(collectionName: string, docName: string) => {
|
||||||
|
const snap = await getDoc(doc(db, collectionName, docName))
|
||||||
|
return snap.exists() ? (snap.data() as T) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getValues = async <T>(query: Query) => {
|
||||||
|
const snap = await getDocs(query)
|
||||||
|
return snap.docs.map((doc) => doc.data() as T)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listenForValue<T>(
|
||||||
|
docRef: DocumentReference,
|
||||||
|
setValue: (value: T | null) => void
|
||||||
|
) {
|
||||||
|
return onSnapshot(docRef, (snapshot) => {
|
||||||
|
const value = snapshot.exists() ? (snapshot.data() as T) : null
|
||||||
|
setValue(value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listenForValues<T>(
|
||||||
|
query: Query,
|
||||||
|
setValues: (values: T[]) => void
|
||||||
|
) {
|
||||||
|
return onSnapshot(query, (snapshot) => {
|
||||||
|
const values = snapshot.docs.map((doc) => doc.data() as T)
|
||||||
|
setValues(values)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import _ from 'lodash'
|
||||||
import { useUser } from '../hooks/use-user'
|
import { useUser } from '../hooks/use-user'
|
||||||
import Markets from './markets'
|
import Markets from './markets'
|
||||||
import LandingPage from './landing-page'
|
import LandingPage from './landing-page'
|
||||||
|
@ -8,10 +8,9 @@ import {
|
||||||
getHotContracts,
|
getHotContracts,
|
||||||
listAllContracts,
|
listAllContracts,
|
||||||
} from '../lib/firebase/contracts'
|
} from '../lib/firebase/contracts'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
const [contracts, hotContractIds] = await Promise.all([
|
const [contracts, hotContracts] = await Promise.all([
|
||||||
listAllContracts().catch((_) => []),
|
listAllContracts().catch((_) => []),
|
||||||
getHotContracts().catch(() => []),
|
getHotContracts().catch(() => []),
|
||||||
])
|
])
|
||||||
|
@ -19,26 +18,22 @@ export async function getStaticProps() {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
contracts,
|
contracts,
|
||||||
hotContractIds,
|
hotContracts,
|
||||||
},
|
},
|
||||||
|
|
||||||
revalidate: 60, // regenerate after a minute
|
revalidate: 60, // regenerate after a minute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Home = (props: { contracts: Contract[]; hotContractIds: string[] }) => {
|
const Home = (props: { contracts: Contract[]; hotContracts: Contract[] }) => {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
|
||||||
if (user === undefined) return <></>
|
if (user === undefined) return <></>
|
||||||
|
|
||||||
const { contracts, hotContractIds } = props
|
const { contracts, hotContracts } = props
|
||||||
const hotContracts = hotContractIds
|
|
||||||
.map((id) => contracts.find((contract) => contract.id === id) as Contract)
|
|
||||||
.filter((contract) => !contract.isResolved)
|
|
||||||
.slice(0, 4)
|
|
||||||
|
|
||||||
return user ? (
|
return user ? (
|
||||||
<Markets contracts={contracts} hotContractIds={hotContractIds} />
|
<Markets contracts={contracts} hotContracts={hotContracts} />
|
||||||
) : (
|
) : (
|
||||||
<LandingPage hotContracts={hotContracts} />
|
<LandingPage hotContracts={hotContracts} />
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
} from '../lib/firebase/contracts'
|
} from '../lib/firebase/contracts'
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
const [contracts, hotContractIds] = await Promise.all([
|
const [contracts, hotContracts] = await Promise.all([
|
||||||
listAllContracts().catch((_) => []),
|
listAllContracts().catch((_) => []),
|
||||||
getHotContracts().catch(() => []),
|
getHotContracts().catch(() => []),
|
||||||
])
|
])
|
||||||
|
@ -20,7 +20,7 @@ export async function getStaticProps() {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
contracts,
|
contracts,
|
||||||
hotContractIds,
|
hotContracts,
|
||||||
},
|
},
|
||||||
|
|
||||||
revalidate: 60, // regenerate after a minute
|
revalidate: 60, // regenerate after a minute
|
||||||
|
@ -29,29 +29,20 @@ export async function getStaticProps() {
|
||||||
|
|
||||||
export default function Markets(props: {
|
export default function Markets(props: {
|
||||||
contracts: Contract[]
|
contracts: Contract[]
|
||||||
hotContractIds: string[]
|
hotContracts: Contract[]
|
||||||
}) {
|
}) {
|
||||||
const contracts = useContracts()
|
const contracts = useContracts()
|
||||||
|
const hotContracts = useHotContracts()
|
||||||
const { query, setQuery, sort, setSort } = useQueryAndSortParams()
|
const { query, setQuery, sort, setSort } = useQueryAndSortParams()
|
||||||
const hotContractIds = useHotContracts()
|
|
||||||
|
|
||||||
const readyHotContractIds =
|
const readyHotContracts = hotContracts ?? props.hotContracts
|
||||||
hotContractIds === 'loading' ? props.hotContractIds : hotContractIds
|
|
||||||
const readyContracts = contracts === 'loading' ? props.contracts : contracts
|
const readyContracts = contracts === 'loading' ? props.contracts : contracts
|
||||||
|
|
||||||
const hotContracts = readyHotContractIds
|
|
||||||
.map(
|
|
||||||
(hotId) =>
|
|
||||||
_.find(readyContracts, (contract) => contract.id === hotId) as Contract
|
|
||||||
)
|
|
||||||
.filter((contract) => !contract.isResolved)
|
|
||||||
.slice(0, 4)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<div className="w-full bg-indigo-50 border-2 border-indigo-100 p-6 rounded-lg shadow-md">
|
<div className="w-full bg-indigo-50 border-2 border-indigo-100 p-6 rounded-lg shadow-md">
|
||||||
<Title className="mt-0" text="🔥 Markets" />
|
<Title className="mt-0" text="🔥 Markets" />
|
||||||
<ContractsGrid contracts={hotContracts} />
|
<ContractsGrid contracts={readyHotContracts} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Spacer h={10} />
|
<Spacer h={10} />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user