Use react query for portfolio history

This commit is contained in:
James Grugett 2022-08-28 16:32:48 -05:00
parent 8b1874e7bb
commit f8888ab5e5
3 changed files with 51 additions and 37 deletions

View File

@ -1,43 +1,26 @@
import { PortfolioMetrics } from 'common/user'
import { formatMoney } from 'common/util/format' import { formatMoney } from 'common/util/format'
import { last } from 'lodash' import { last } from 'lodash'
import { memo, useEffect, useState } from 'react' import { memo, useRef, useState } from 'react'
import { Period, getPortfolioHistory } from 'web/lib/firebase/users' import { usePortfolioHistory } from 'web/hooks/use-portfolio-history'
import { Period } from 'web/lib/firebase/users'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { PortfolioValueGraph } from './portfolio-value-graph' import { PortfolioValueGraph } from './portfolio-value-graph'
import { DAY_MS } from 'common/util/time'
const periodToCutoff = (now: number, period: Period) => {
switch (period) {
case 'daily':
return now - 1 * DAY_MS
case 'weekly':
return now - 7 * DAY_MS
case 'monthly':
return now - 30 * DAY_MS
case 'allTime':
default:
return new Date(0)
}
}
export const PortfolioValueSection = memo( export const PortfolioValueSection = memo(
function PortfolioValueSection(props: { userId: string }) { function PortfolioValueSection(props: { userId: string }) {
const { userId } = props const { userId } = props
const [portfolioPeriod, setPortfolioPeriod] = useState<Period>('weekly') const [portfolioPeriod, setPortfolioPeriod] = useState<Period>('weekly')
const [portfolioHistory, setUsersPortfolioHistory] = useState< const portfolioHistory = usePortfolioHistory(userId, portfolioPeriod)
PortfolioMetrics[]
>([])
useEffect(() => { // Remember the last defined portfolio history.
const cutoff = periodToCutoff(Date.now(), portfolioPeriod).valueOf() const portfolioRef = useRef(portfolioHistory)
getPortfolioHistory(userId, cutoff).then(setUsersPortfolioHistory) if (portfolioHistory) portfolioRef.current = portfolioHistory
}, [portfolioPeriod, userId]) const currPortfolioHistory = portfolioRef.current
const lastPortfolioMetrics = last(portfolioHistory) const lastPortfolioMetrics = last(currPortfolioHistory)
if (portfolioHistory.length === 0 || !lastPortfolioMetrics) { if (!currPortfolioHistory || !lastPortfolioMetrics) {
return <></> return <></>
} }
@ -64,7 +47,7 @@ export const PortfolioValueSection = memo(
</select> </select>
</Row> </Row>
<PortfolioValueGraph <PortfolioValueGraph
portfolioHistory={portfolioHistory} portfolioHistory={currPortfolioHistory}
includeTime={portfolioPeriod == 'daily'} includeTime={portfolioPeriod == 'daily'}
/> />
</> </>

View File

@ -0,0 +1,32 @@
import { useFirestoreQueryData } from '@react-query-firebase/firestore'
import { DAY_MS, HOUR_MS } from 'common/util/time'
import { getPortfolioHistoryQuery, Period } from 'web/lib/firebase/users'
export const usePortfolioHistory = (userId: string, period: Period) => {
const nowRounded = Math.round(Date.now() / HOUR_MS) * HOUR_MS
const cutoff = periodToCutoff(nowRounded, period).valueOf()
const result = useFirestoreQueryData(
['portfolio-history', userId, cutoff],
getPortfolioHistoryQuery(userId, cutoff),
{ subscribe: true, includeMetadataChanges: true },
// Temporary workaround for react-query bug:
// https://github.com/invertase/react-query-firebase/issues/25
{ refetchOnMount: 'always' }
)
return result.data
}
const periodToCutoff = (now: number, period: Period) => {
switch (period) {
case 'daily':
return now - 1 * DAY_MS
case 'weekly':
return now - 7 * DAY_MS
case 'monthly':
return now - 30 * DAY_MS
case 'allTime':
default:
return new Date(0)
}
}

View File

@ -12,6 +12,7 @@ import {
deleteDoc, deleteDoc,
collectionGroup, collectionGroup,
onSnapshot, onSnapshot,
Query,
} from 'firebase/firestore' } from 'firebase/firestore'
import { getAuth } from 'firebase/auth' import { getAuth } from 'firebase/auth'
import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth' import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth'
@ -252,15 +253,13 @@ export async function unfollow(userId: string, unfollowedUserId: string) {
await deleteDoc(followDoc) await deleteDoc(followDoc)
} }
export async function getPortfolioHistory(userId: string, since: number) { export function getPortfolioHistoryQuery(userId: string, since: number) {
return getValues<PortfolioMetrics>( return query(
query( collectionGroup(db, 'portfolioHistory'),
collectionGroup(db, 'portfolioHistory'), where('userId', '==', userId),
where('userId', '==', userId), where('timestamp', '>=', since),
where('timestamp', '>=', since), orderBy('timestamp', 'asc')
orderBy('timestamp', 'asc') ) as Query<PortfolioMetrics>
)
)
} }
export function listenForFollows( export function listenForFollows(