diff --git a/web/pages/activity.tsx b/web/components/activity-feed.tsx
similarity index 74%
rename from web/pages/activity.tsx
rename to web/components/activity-feed.tsx
index bab58328..bfd4cc1c 100644
--- a/web/pages/activity.tsx
+++ b/web/components/activity-feed.tsx
@@ -1,9 +1,12 @@
import _ from 'lodash'
-import { ContractFeed, ContractSummaryFeed } from '../components/contract-feed'
-import { Page } from '../components/page'
+import {
+ ContractActivityFeed,
+ ContractFeed,
+ ContractSummaryFeed,
+} from './contract-feed'
import { Contract } from '../lib/firebase/contracts'
import { Comment } from '../lib/firebase/comments'
-import { Col } from '../components/layout/col'
+import { Col } from './layout/col'
import { Bet } from '../../common/bet'
const MAX_ACTIVE_CONTRACTS = 75
@@ -72,30 +75,44 @@ export function findActiveContracts(
export function ActivityFeed(props: {
contracts: Contract[]
- contractBets: Bet[][]
- contractComments: Comment[][]
+ recentBets: Bet[]
+ recentComments: Comment[]
+ loadBetAndCommentHistory?: boolean
}) {
- const { contracts, contractBets, contractComments } = props
+ const { contracts, recentBets, recentComments, loadBetAndCommentHistory } =
+ props
- return contracts.length > 0 ? (
+ const groupedBets = _.groupBy(recentBets, (bet) => bet.contractId)
+ const groupedComments = _.groupBy(
+ recentComments,
+ (comment) => comment.contractId
+ )
+
+ return (
-
+
- {contracts.map((contract, i) => (
+ {contracts.map((contract) => (
-
+ {loadBetAndCommentHistory ? (
+
+ ) : (
+
+ )}
))}
- ) : (
- <>>
)
}
@@ -116,11 +133,3 @@ export function SummaryActivityFeed(props: { contracts: Contract[] }) {
)
}
-
-export default function ActivityPage() {
- return (
-
-
-
- )
-}
diff --git a/web/components/contract-feed.tsx b/web/components/contract-feed.tsx
index bf5885b5..766ba94b 100644
--- a/web/components/contract-feed.tsx
+++ b/web/components/contract-feed.tsx
@@ -290,7 +290,10 @@ function TruncatedComment(props: {
}
return (
-
+
{truncated != comment && (
@@ -301,8 +304,11 @@ function TruncatedComment(props: {
)
}
-function FeedQuestion(props: { contract: Contract }) {
- const { contract } = props
+function FeedQuestion(props: {
+ contract: Contract
+ showDescription?: boolean
+}) {
+ const { contract, showDescription } = props
const { creatorName, creatorUsername, question, resolution, outcomeType } =
contract
const { truePool } = contractMetrics(contract)
@@ -337,22 +343,34 @@ function FeedQuestion(props: { contract: Contract }) {
{closeMessage}
-
-
- {question}
-
+
+
+
+ {question}
+
+ {!showDescription && (
+
+ See more...
+
+ )}
+
{(isBinary || resolution) && (
)}
-
+ {showDescription && (
+
+ )}
>
)
@@ -681,6 +699,7 @@ type ActivityItem = {
| 'close'
| 'resolve'
| 'expand'
+ | undefined
}
type FeedType =
@@ -691,64 +710,24 @@ type FeedType =
// Grouped for a multi-category outcome
| 'multi'
-export function ContractFeed(props: {
+function FeedItems(props: {
contract: Contract
- bets: Bet[]
- comments: Comment[]
+ items: ActivityItem[]
feedType: FeedType
+ setExpanded: (expanded: boolean) => void
outcome?: string // Which multi-category outcome to filter
betRowClassName?: string
}) {
- const { contract, feedType, outcome, betRowClassName } = props
- const { id, outcomeType } = contract
+ const { contract, items, feedType, outcome, setExpanded, betRowClassName } =
+ props
+ const { outcomeType } = contract
const isBinary = outcomeType === 'BINARY'
- const [expanded, setExpanded] = useState(false)
- const user = useUser()
-
- let bets = useBets(contract.id) ?? props.bets
- bets = isBinary
- ? bets.filter((bet) => !bet.isAnte)
- : bets.filter((bet) => !(bet.isAnte && (bet.outcome as string) === '0'))
-
- if (feedType === 'multi') {
- bets = bets.filter((bet) => bet.outcome === outcome)
- }
-
- const comments = useComments(id) ?? props.comments
-
- const groupWindow = feedType == 'activity' ? 10 * DAY_IN_MS : DAY_IN_MS
-
- const allItems = [
- { type: 'start', id: 0 },
- ...groupBets(bets, comments, groupWindow, user?.id),
- ]
- if (contract.closeTime && contract.closeTime <= Date.now()) {
- allItems.push({ type: 'close', id: `${contract.closeTime}` })
- }
- if (contract.resolution) {
- allItems.push({ type: 'resolve', id: `${contract.resolutionTime}` })
- }
- if (feedType === 'multi') {
- // Hack to add some more padding above the 'multi' feedType, by adding a null item
- allItems.unshift({ type: '', id: -1 })
- }
-
- // If there are more than 5 items, only show the first, an expand item, and last 3
- let items = allItems
- if (!expanded && allItems.length > 5 && feedType == 'activity') {
- items = [
- allItems[0],
- { type: 'expand', id: 'expand' },
- ...allItems.slice(-3),
- ]
- }
-
return (
-
+
{items.map((activityItem, activityItemIdx) => (
-
+
{activityItemIdx !== items.length - 1 ? (
!bet.isAnte)
+ : bets.filter((bet) => !(bet.isAnte && (bet.outcome as string) === '0'))
+
+ if (feedType === 'multi') {
+ bets = bets.filter((bet) => bet.outcome === outcome)
+ }
+
+ const comments = useComments(id) ?? props.comments
+
+ const groupWindow = feedType == 'activity' ? 10 * DAY_IN_MS : DAY_IN_MS
+
+ const allItems: ActivityItem[] = [
+ { type: 'start', id: '0' },
+ ...groupBets(bets, comments, groupWindow, user?.id),
+ ]
+ if (contract.closeTime && contract.closeTime <= Date.now()) {
+ allItems.push({ type: 'close', id: `${contract.closeTime}` })
+ }
+ if (contract.resolution) {
+ allItems.push({ type: 'resolve', id: `${contract.resolutionTime}` })
+ }
+ if (feedType === 'multi') {
+ // Hack to add some more padding above the 'multi' feedType, by adding a null item
+ allItems.unshift({ type: undefined, id: '-1' })
+ }
+
+ // If there are more than 5 items, only show the first, an expand item, and last 3
+ let items = allItems
+ if (!expanded && allItems.length > 5 && feedType == 'activity') {
+ items = [
+ allItems[0],
+ { type: 'expand', id: 'expand' },
+ ...allItems.slice(-3),
+ ]
+ }
+
+ return (
+
+ )
+}
+
+export function ContractActivityFeed(props: {
+ contract: Contract
+ bets: Bet[]
+ comments: Comment[]
+ betRowClassName?: string
+}) {
+ const { contract, betRowClassName, bets, comments } = props
+
+ const user = useUser()
+
+ bets.sort((b1, b2) => b1.createdTime - b2.createdTime)
+ comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
+
+ const allItems: ActivityItem[] = [
+ { type: 'start', id: '0' },
+ ...groupBets(bets, comments, DAY_IN_MS, user?.id),
+ ]
+ if (contract.closeTime && contract.closeTime <= Date.now()) {
+ allItems.push({ type: 'close', id: `${contract.closeTime}` })
+ }
+ if (contract.resolution) {
+ allItems.push({ type: 'resolve', id: `${contract.resolutionTime}` })
+ }
+
+ // Remove all but last bet group.
+ const betGroups = allItems.filter((item) => item.type === 'betgroup')
+ const lastBetGroup = betGroups[betGroups.length - 1]
+ const filtered = allItems.filter(
+ (item) => item.type !== 'betgroup' || item.id === lastBetGroup?.id
+ )
+
+ // Only show the first item plus the last three items.
+ const items =
+ filtered.length > 3 ? [filtered[0], ...filtered.slice(-3)] : filtered
+
+ return (
+ {}}
+ betRowClassName={betRowClassName}
+ />
+ )
+}
+
export function ContractSummaryFeed(props: {
contract: Contract
betRowClassName?: string
@@ -805,7 +895,7 @@ export function ContractSummaryFeed(props: {
diff --git a/web/hooks/use-find-active-contracts.ts b/web/hooks/use-find-active-contracts.ts
index f8aa5627..2a6a3b47 100644
--- a/web/hooks/use-find-active-contracts.ts
+++ b/web/hooks/use-find-active-contracts.ts
@@ -4,11 +4,11 @@ import { useMemo, useRef } from 'react'
import { Fold } from '../../common/fold'
import { User } from '../../common/user'
import { filterDefined } from '../../common/util/array'
-import { Bet, getRecentBets } from '../lib/firebase/bets'
+import { Bet } from '../lib/firebase/bets'
import { Comment, getRecentComments } from '../lib/firebase/comments'
import { Contract, getActiveContracts } from '../lib/firebase/contracts'
import { listAllFolds } from '../lib/firebase/folds'
-import { findActiveContracts } from '../pages/activity'
+import { findActiveContracts } from '../components/activity-feed'
import { useInactiveContracts } from './use-contracts'
import { useFollowedFolds } from './use-fold'
import { useUserBetContracts } from './use-user-bets'
@@ -20,12 +20,9 @@ export const getAllContractInfo = async () => {
listAllFolds().catch(() => []),
])
- const [recentBets, recentComments] = await Promise.all([
- getRecentBets(),
- getRecentComments(),
- ])
+ const recentComments = await getRecentComments()
- return { contracts, recentBets, recentComments, folds }
+ return { contracts, recentComments, folds }
}
export const useFilterYourContracts = (
diff --git a/web/pages/fold/[...slugs]/index.tsx b/web/pages/fold/[...slugs]/index.tsx
index 1d77444b..757fe325 100644
--- a/web/pages/fold/[...slugs]/index.tsx
+++ b/web/pages/fold/[...slugs]/index.tsx
@@ -12,7 +12,10 @@ import {
getFoldBySlug,
getFoldContracts,
} from '../../../lib/firebase/folds'
-import { ActivityFeed, findActiveContracts } from '../../activity'
+import {
+ ActivityFeed,
+ findActiveContracts,
+} from '../../../components/activity-feed'
import { TagsList } from '../../../components/tags-list'
import { Row } from '../../../components/layout/row'
import { UserLink } from '../../../components/user-page'
@@ -36,6 +39,9 @@ import { SEO } from '../../../components/SEO'
import { useTaggedContracts } from '../../../hooks/use-contracts'
import { Linkify } from '../../../components/linkify'
import { filterDefined } from '../../../../common/util/array'
+import { useRecentBets } from '../../../hooks/use-bets'
+import { useRecentComments } from '../../../hooks/use-comments'
+import { LoadingIndicator } from '../../../components/loading-indicator'
export async function getStaticProps(props: { params: { slugs: string[] } }) {
const { slugs } = props.params
@@ -48,7 +54,6 @@ export async function getStaticProps(props: { params: { slugs: string[] } }) {
const bets = await Promise.all(
contracts.map((contract) => listAllBets(contract.id))
)
- const betsByContract = _.fromPairs(contracts.map((c, i) => [c.id, bets[i]]))
let activeContracts = findActiveContracts(contracts, [], _.flatten(bets))
const [resolved, unresolved] = _.partition(
@@ -57,10 +62,6 @@ export async function getStaticProps(props: { params: { slugs: string[] } }) {
)
activeContracts = [...unresolved, ...resolved]
- const activeContractBets = activeContracts.map(
- (contract) => betsByContract[contract.id] ?? []
- )
-
const creatorScores = scoreCreators(contracts, bets)
const traderScores = scoreTraders(contracts, bets)
const [topCreators, topTraders] = await Promise.all([
@@ -76,8 +77,6 @@ export async function getStaticProps(props: { params: { slugs: string[] } }) {
curator,
contracts,
activeContracts,
- activeContractBets,
- activeContractComments: activeContracts.map(() => []),
traderScores,
topTraders,
creatorScores,
@@ -117,15 +116,8 @@ export default function FoldPage(props: {
creatorScores: { [userId: string]: number }
topCreators: User[]
}) {
- const {
- curator,
- activeContractBets,
- activeContractComments,
- traderScores,
- topTraders,
- creatorScores,
- topCreators,
- } = props
+ const { curator, traderScores, topTraders, creatorScores, topCreators } =
+ props
const router = useRouter()
const { slugs } = router.query as { slugs: string[] }
@@ -151,6 +143,9 @@ export default function FoldPage(props: {
props.activeContracts.map((contract) => contractsMap[contract.id])
)
+ const recentBets = useRecentBets()
+ const recentComments = useRecentComments()
+
if (fold === null || !foldSubpages.includes(page) || slugs[2]) {
return
}
@@ -233,19 +228,24 @@ export default function FoldPage(props: {
/>
)}
{page === 'activity' ? (
- <>
-
- {activeContracts.length === 0 && (
-
- No activity from matching markets.{' '}
- {isCurator && 'Try editing to add more tags!'}
-
- )}
- >
+ recentBets && recentComments ? (
+ <>
+
+ {activeContracts.length === 0 && (
+
+ No activity from matching markets.{' '}
+ {isCurator && 'Try editing to add more tags!'}
+
+ )}
+ >
+ ) : (
+
+ )
) : (
{
- const { folds, recentComments } = props
+ const { folds } = props
const user = useUser()
const contracts = useActiveContracts() ?? props.contracts
@@ -51,13 +50,15 @@ const Home = (props: {
contracts
)
- const recentBets = useGetRecentBets()
- const { activeContracts, activeBets, activeComments } =
- useFindActiveContracts({
- contracts: yourContracts,
- recentBets: recentBets ?? [],
- recentComments,
- })
+ const initialRecentBets = useGetRecentBets()
+ const recentBets = useRecentBets() ?? initialRecentBets
+ const recentComments = useRecentComments() ?? props.recentComments
+
+ const { activeContracts } = useFindActiveContracts({
+ contracts: yourContracts,
+ recentBets: initialRecentBets ?? [],
+ recentComments: props.recentComments,
+ })
const exploreContracts = useExploreContracts()
@@ -71,7 +72,7 @@ const Home = (props: {
return (
-
+
@@ -116,8 +117,8 @@ const Home = (props: {
(recentBets ? (
) : (