From 3e976eadaceaf3bcbefd029b51d26da38126cb48 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Sat, 27 Aug 2022 01:09:01 -0700 Subject: [PATCH] Make portfolio graph loading more efficient (#805) * Make portfolio graph on profile not load extra data * Clean up unused props * Tidy up markup * Enable "daily" option again on portfolio history picker --- .../portfolio/portfolio-value-graph.tsx | 26 +----- .../portfolio/portfolio-value-section.tsx | 88 +++++++++---------- web/lib/firebase/users.ts | 3 +- 3 files changed, 49 insertions(+), 68 deletions(-) diff --git a/web/components/portfolio/portfolio-value-graph.tsx b/web/components/portfolio/portfolio-value-graph.tsx index d1dae0bd..61a1ce8b 100644 --- a/web/components/portfolio/portfolio-value-graph.tsx +++ b/web/components/portfolio/portfolio-value-graph.tsx @@ -1,7 +1,6 @@ import { ResponsiveLine } from '@nivo/line' import { PortfolioMetrics } from 'common/user' import { formatMoney } from 'common/util/format' -import { DAY_MS } from 'common/util/time' import { last } from 'lodash' import { memo } from 'react' import { useWindowSize } from 'web/hooks/use-window-size' @@ -10,28 +9,12 @@ import { formatTime } from 'web/lib/util/time' export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: { portfolioHistory: PortfolioMetrics[] height?: number - period?: string + includeTime?: boolean }) { - const { portfolioHistory, height, period } = props - + const { portfolioHistory, height, includeTime } = props const { width } = useWindowSize() - const portfolioHistoryFiltered = portfolioHistory.filter((p) => { - switch (period) { - case 'daily': - return p.timestamp > Date.now() - 1 * DAY_MS - case 'weekly': - return p.timestamp > Date.now() - 7 * DAY_MS - case 'monthly': - return p.timestamp > Date.now() - 30 * DAY_MS - case 'allTime': - return true - default: - return true - } - }) - - const points = portfolioHistoryFiltered.map((p) => { + const points = portfolioHistory.map((p) => { return { x: new Date(p.timestamp), y: p.balance + p.investmentValue, @@ -41,7 +24,6 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: { const numXTickValues = !width || width < 800 ? 2 : 5 const numYTickValues = 4 const endDate = last(points)?.x - const includeTime = period === 'daily' return (
formatTime(+time, includeTime), + format: (time) => formatTime(+time, !!includeTime), }} pointBorderColor="#fff" pointSize={points.length > 100 ? 0 : 6} diff --git a/web/components/portfolio/portfolio-value-section.tsx b/web/components/portfolio/portfolio-value-section.tsx index 604873e9..706630b2 100644 --- a/web/components/portfolio/portfolio-value-section.tsx +++ b/web/components/portfolio/portfolio-value-section.tsx @@ -6,70 +6,68 @@ import { Period, getPortfolioHistory } from 'web/lib/firebase/users' import { Col } from '../layout/col' import { Row } from '../layout/row' 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( - function PortfolioValueSection(props: { - userId: string - disableSelector?: boolean - }) { - const { disableSelector, userId } = props + function PortfolioValueSection(props: { userId: string }) { + const { userId } = props const [portfolioPeriod, setPortfolioPeriod] = useState('weekly') const [portfolioHistory, setUsersPortfolioHistory] = useState< PortfolioMetrics[] >([]) - useEffect(() => { - getPortfolioHistory(userId).then(setUsersPortfolioHistory) - }, [userId]) - const lastPortfolioMetrics = last(portfolioHistory) + useEffect(() => { + const cutoff = periodToCutoff(Date.now(), portfolioPeriod).valueOf() + getPortfolioHistory(userId, cutoff).then(setUsersPortfolioHistory) + }, [portfolioPeriod, userId]) + + const lastPortfolioMetrics = last(portfolioHistory) if (portfolioHistory.length === 0 || !lastPortfolioMetrics) { return <> } - // PATCH: If portfolio history started on June 1st, then we label it as "Since June" - // instead of "All time" - const allTimeLabel = - lastPortfolioMetrics.timestamp < Date.parse('2022-06-20T00:00:00.000Z') - ? 'Since June' - : 'All time' + const { balance, investmentValue } = lastPortfolioMetrics + const totalValue = balance + investmentValue return ( -
+ <> -
- -
Portfolio value
-
- {formatMoney( - lastPortfolioMetrics.balance + - lastPortfolioMetrics.investmentValue - )} -
- -
- {!disableSelector && ( - - )} + +
Portfolio value
+
{formatMoney(totalValue)}
+ +
-
+ ) } ) diff --git a/web/lib/firebase/users.ts b/web/lib/firebase/users.ts index 6cfee163..bad13c8c 100644 --- a/web/lib/firebase/users.ts +++ b/web/lib/firebase/users.ts @@ -252,11 +252,12 @@ export async function unfollow(userId: string, unfollowedUserId: string) { await deleteDoc(followDoc) } -export async function getPortfolioHistory(userId: string) { +export async function getPortfolioHistory(userId: string, since: number) { return getValues( query( collectionGroup(db, 'portfolioHistory'), where('userId', '==', userId), + where('timestamp', '>=', since), orderBy('timestamp', 'asc') ) )