Make prefetching correctly use context cache (#835)
This commit is contained in:
parent
dca7205a47
commit
4406e53121
|
@ -2,9 +2,9 @@ import clsx from 'clsx'
|
||||||
import { PencilIcon } from '@heroicons/react/outline'
|
import { PencilIcon } from '@heroicons/react/outline'
|
||||||
|
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { useEffect, useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useFollowers, useFollows } from 'web/hooks/use-follows'
|
import { useFollowers, useFollows } from 'web/hooks/use-follows'
|
||||||
import { prefetchUsers, useUser } from 'web/hooks/use-user'
|
import { usePrefetchUsers, useUser } from 'web/hooks/use-user'
|
||||||
import { FollowList } from './follow-list'
|
import { FollowList } from './follow-list'
|
||||||
import { Col } from './layout/col'
|
import { Col } from './layout/col'
|
||||||
import { Modal } from './layout/modal'
|
import { Modal } from './layout/modal'
|
||||||
|
@ -105,16 +105,9 @@ function FollowsDialog(props: {
|
||||||
const { user, followingIds, followerIds, defaultTab, isOpen, setIsOpen } =
|
const { user, followingIds, followerIds, defaultTab, isOpen, setIsOpen } =
|
||||||
props
|
props
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
prefetchUsers([...followingIds, ...followerIds])
|
|
||||||
}, [followingIds, followerIds])
|
|
||||||
|
|
||||||
const currentUser = useUser()
|
const currentUser = useUser()
|
||||||
|
|
||||||
const discoverUserIds = useDiscoverUsers(user?.id)
|
const discoverUserIds = useDiscoverUsers(user?.id)
|
||||||
useEffect(() => {
|
usePrefetchUsers([...followingIds, ...followerIds, ...discoverUserIds])
|
||||||
prefetchUsers(discoverUserIds)
|
|
||||||
}, [discoverUserIds])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={isOpen} setOpen={setIsOpen}>
|
<Modal open={isOpen} setOpen={setIsOpen}>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { prefetchUsers, useUserById } from 'web/hooks/use-user'
|
import { usePrefetchUsers, useUserById } from 'web/hooks/use-user'
|
||||||
import { Col } from './layout/col'
|
import { Col } from './layout/col'
|
||||||
import { Modal } from './layout/modal'
|
import { Modal } from './layout/modal'
|
||||||
import { Tabs } from './layout/tabs'
|
import { Tabs } from './layout/tabs'
|
||||||
|
@ -56,9 +56,7 @@ function ReferralsDialog(props: {
|
||||||
}
|
}
|
||||||
}, [isOpen, referredByUser, user.referredByUserId])
|
}, [isOpen, referredByUser, user.referredByUserId])
|
||||||
|
|
||||||
useEffect(() => {
|
usePrefetchUsers(referralIds)
|
||||||
prefetchUsers(referralIds)
|
|
||||||
}, [referralIds])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={isOpen} setOpen={setIsOpen}>
|
<Modal open={isOpen} setOpen={setIsOpen}>
|
||||||
|
|
|
@ -9,9 +9,10 @@ import {
|
||||||
listenForHotContracts,
|
listenForHotContracts,
|
||||||
listenForInactiveContracts,
|
listenForInactiveContracts,
|
||||||
listenForNewContracts,
|
listenForNewContracts,
|
||||||
|
getUserBetContracts,
|
||||||
getUserBetContractsQuery,
|
getUserBetContractsQuery,
|
||||||
} from 'web/lib/firebase/contracts'
|
} from 'web/lib/firebase/contracts'
|
||||||
import { QueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
|
|
||||||
export const useContracts = () => {
|
export const useContracts = () => {
|
||||||
const [contracts, setContracts] = useState<Contract[] | undefined>()
|
const [contracts, setContracts] = useState<Contract[] | undefined>()
|
||||||
|
@ -93,12 +94,12 @@ export const useUpdatedContracts = (contracts: Contract[] | undefined) => {
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryClient = new QueryClient()
|
export const usePrefetchUserBetContracts = (userId: string) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
export const prefetchUserBetContracts = (userId: string) =>
|
return queryClient.prefetchQuery(['contracts', 'bets', userId], () =>
|
||||||
queryClient.prefetchQuery(['contracts', 'bets', userId], () =>
|
getUserBetContracts(userId)
|
||||||
getUserBetContractsQuery(userId)
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const useUserBetContracts = (userId: string) => {
|
export const useUserBetContracts = (userId: string) => {
|
||||||
const result = useFirestoreQueryData(
|
const result = useFirestoreQueryData(
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
import { QueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
|
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
|
||||||
import { DAY_MS, HOUR_MS } from 'common/util/time'
|
import { DAY_MS, HOUR_MS } from 'common/util/time'
|
||||||
import { getPortfolioHistoryQuery, Period } from 'web/lib/firebase/users'
|
import {
|
||||||
|
getPortfolioHistory,
|
||||||
const queryClient = new QueryClient()
|
getPortfolioHistoryQuery,
|
||||||
|
Period,
|
||||||
|
} from 'web/lib/firebase/users'
|
||||||
|
|
||||||
const getCutoff = (period: Period) => {
|
const getCutoff = (period: Period) => {
|
||||||
const nowRounded = Math.round(Date.now() / HOUR_MS) * HOUR_MS
|
const nowRounded = Math.round(Date.now() / HOUR_MS) * HOUR_MS
|
||||||
return periodToCutoff(nowRounded, period).valueOf()
|
return periodToCutoff(nowRounded, period).valueOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const prefetchPortfolioHistory = (userId: string, period: Period) => {
|
export const usePrefetchPortfolioHistory = (userId: string, period: Period) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
const cutoff = getCutoff(period)
|
const cutoff = getCutoff(period)
|
||||||
return queryClient.prefetchQuery(['portfolio-history', userId, cutoff], () =>
|
return queryClient.prefetchQuery(['portfolio-history', userId, cutoff], () =>
|
||||||
getPortfolioHistoryQuery(userId, cutoff)
|
getPortfolioHistory(userId, cutoff)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { prefetchUserBetContracts } from './use-contracts'
|
import { usePrefetchUserBetContracts } from './use-contracts'
|
||||||
import { prefetchPortfolioHistory } from './use-portfolio-history'
|
import { usePrefetchPortfolioHistory } from './use-portfolio-history'
|
||||||
import { prefetchUserBets } from './use-user-bets'
|
import { usePrefetchUserBets } from './use-user-bets'
|
||||||
|
|
||||||
export function usePrefetch(userId: string | undefined) {
|
export function usePrefetch(userId: string | undefined) {
|
||||||
const maybeUserId = userId ?? ''
|
const maybeUserId = userId ?? ''
|
||||||
|
return Promise.all([
|
||||||
prefetchUserBets(maybeUserId)
|
usePrefetchUserBets(maybeUserId),
|
||||||
prefetchUserBetContracts(maybeUserId)
|
usePrefetchUserBetContracts(maybeUserId),
|
||||||
prefetchPortfolioHistory(maybeUserId, 'weekly')
|
usePrefetchPortfolioHistory(maybeUserId, 'weekly'),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { QueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
|
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Bet,
|
Bet,
|
||||||
|
getUserBets,
|
||||||
getUserBetsQuery,
|
getUserBetsQuery,
|
||||||
listenForUserContractBets,
|
listenForUserContractBets,
|
||||||
} from 'web/lib/firebase/bets'
|
} from 'web/lib/firebase/bets'
|
||||||
|
|
||||||
const queryClient = new QueryClient()
|
export const usePrefetchUserBets = (userId: string) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
export const prefetchUserBets = (userId: string) =>
|
return queryClient.prefetchQuery(['bets', userId], () => getUserBets(userId))
|
||||||
queryClient.prefetchQuery(['bets', userId], () => getUserBetsQuery(userId))
|
}
|
||||||
|
|
||||||
export const useUserBets = (userId: string) => {
|
export const useUserBets = (userId: string) => {
|
||||||
const result = useFirestoreQueryData(
|
const result = useFirestoreQueryData(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useContext } from 'react'
|
import { useContext } from 'react'
|
||||||
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
||||||
import { QueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
|
|
||||||
import { doc, DocumentData } from 'firebase/firestore'
|
import { doc, DocumentData } from 'firebase/firestore'
|
||||||
import { getUser, User, users } from 'web/lib/firebase/users'
|
import { getUser, User, users } from 'web/lib/firebase/users'
|
||||||
|
@ -28,12 +28,13 @@ export const useUserById = (userId = '_') => {
|
||||||
return result.isLoading ? undefined : result.data
|
return result.isLoading ? undefined : result.data
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryClient = new QueryClient()
|
export const usePrefetchUser = (userId: string) => {
|
||||||
|
return usePrefetchUsers([userId])[0]
|
||||||
|
}
|
||||||
|
|
||||||
export const prefetchUser = (userId: string) => {
|
export const usePrefetchUsers = (userIds: string[]) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
return userIds.map((userId) =>
|
||||||
queryClient.prefetchQuery(['users', userId], () => getUser(userId))
|
queryClient.prefetchQuery(['users', userId], () => getUser(userId))
|
||||||
}
|
)
|
||||||
|
|
||||||
export const prefetchUsers = (userIds: string[]) => {
|
|
||||||
userIds.forEach(prefetchUser)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,20 +70,16 @@ export function listenForBets(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserBets(
|
export async function getUserBets(userId: string) {
|
||||||
userId: string,
|
return getValues<Bet>(getUserBetsQuery(userId))
|
||||||
options: { includeRedemptions: boolean }
|
}
|
||||||
) {
|
|
||||||
const { includeRedemptions } = options
|
export function getUserBetsQuery(userId: string) {
|
||||||
return getValues<Bet>(
|
return query(
|
||||||
query(collectionGroup(db, 'bets'), where('userId', '==', userId))
|
collectionGroup(db, 'bets'),
|
||||||
)
|
where('userId', '==', userId),
|
||||||
.then((bets) =>
|
orderBy('createdTime', 'desc')
|
||||||
bets.filter(
|
) as Query<Bet>
|
||||||
(bet) => (includeRedemptions || !bet.isRedemption) && !bet.isAnte
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.catch((reason) => reason)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBets(options: {
|
export async function getBets(options: {
|
||||||
|
@ -124,22 +120,16 @@ export async function getBets(options: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getContractsOfUserBets(userId: string) {
|
export async function getContractsOfUserBets(userId: string) {
|
||||||
const bets: Bet[] = await getUserBets(userId, { includeRedemptions: false })
|
const bets = await getUserBets(userId)
|
||||||
const contractIds = uniq(bets.map((bet) => bet.contractId))
|
const contractIds = uniq(
|
||||||
|
bets.filter((b) => !b.isAnte).map((bet) => bet.contractId)
|
||||||
|
)
|
||||||
const contracts = await Promise.all(
|
const contracts = await Promise.all(
|
||||||
contractIds.map((contractId) => getContractFromId(contractId))
|
contractIds.map((contractId) => getContractFromId(contractId))
|
||||||
)
|
)
|
||||||
return filterDefined(contracts)
|
return filterDefined(contracts)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUserBetsQuery(userId: string) {
|
|
||||||
return query(
|
|
||||||
collectionGroup(db, 'bets'),
|
|
||||||
where('userId', '==', userId),
|
|
||||||
orderBy('createdTime', 'desc')
|
|
||||||
) as Query<Bet>
|
|
||||||
}
|
|
||||||
|
|
||||||
export function listenForUserContractBets(
|
export function listenForUserContractBets(
|
||||||
userId: string,
|
userId: string,
|
||||||
contractId: string,
|
contractId: string,
|
||||||
|
|
|
@ -157,6 +157,10 @@ export function listenForUserContracts(
|
||||||
return listenForValues<Contract>(q, setContracts)
|
return listenForValues<Contract>(q, setContracts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getUserBetContracts(userId: string) {
|
||||||
|
return getValues<Contract>(getUserBetContractsQuery(userId))
|
||||||
|
}
|
||||||
|
|
||||||
export function getUserBetContractsQuery(userId: string) {
|
export function getUserBetContractsQuery(userId: string) {
|
||||||
return query(
|
return query(
|
||||||
contracts,
|
contracts,
|
||||||
|
|
|
@ -254,6 +254,10 @@ export async function unfollow(userId: string, unfollowedUserId: string) {
|
||||||
await deleteDoc(followDoc)
|
await deleteDoc(followDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getPortfolioHistory(userId: string, since: number) {
|
||||||
|
return getValues<PortfolioMetrics>(getPortfolioHistoryQuery(userId, since))
|
||||||
|
}
|
||||||
|
|
||||||
export function getPortfolioHistoryQuery(userId: string, since: number) {
|
export function getPortfolioHistoryQuery(userId: string, since: number) {
|
||||||
return query(
|
return query(
|
||||||
collectionGroup(db, 'portfolioHistory'),
|
collectionGroup(db, 'portfolioHistory'),
|
||||||
|
|
|
@ -18,8 +18,9 @@ export default async function handler(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const bets = await getUserBets(user.id, { includeRedemptions: false })
|
const bets = await getUserBets(user.id)
|
||||||
|
const visibleBets = bets.filter((b) => !b.isRedemption && !b.isAnte)
|
||||||
|
|
||||||
res.setHeader('Cache-Control', 'max-age=0')
|
res.setHeader('Cache-Control', 'max-age=0')
|
||||||
return res.status(200).json(bets)
|
return res.status(200).json(visibleBets)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user