Custom feed (#43)
* Show custom feed of contracts from folds your follow or have bet on. * Add tw-elements UI library * Add loading spinner while feed loads * Switch from onSnapshot to our listenForValues, which doesn't set with partial cached values * Change home tags to communities * Remove tw-elements for now
This commit is contained in:
parent
55aa2db553
commit
552e6e6c3a
3
common/util/array.ts
Normal file
3
common/util/array.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function filterDefined<T>(array: (T | null | undefined)[]) {
|
||||||
|
return array.filter((item) => item) as T[]
|
||||||
|
}
|
|
@ -52,5 +52,9 @@ service cloud.firestore {
|
||||||
allow read;
|
allow read;
|
||||||
allow write: if request.auth.uid == userId;
|
allow write: if request.auth.uid == userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match /{somePath=**}/followers/{userId} {
|
||||||
|
allow read;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,12 +32,12 @@ import { OutcomeLabel, YesLabel, NoLabel, MarketLabel } from './outcome-label'
|
||||||
|
|
||||||
export function BetsList(props: { user: User }) {
|
export function BetsList(props: { user: User }) {
|
||||||
const { user } = props
|
const { user } = props
|
||||||
const bets = useUserBets(user?.id ?? '')
|
const bets = useUserBets(user.id)
|
||||||
|
|
||||||
const [contracts, setContracts] = useState<Contract[]>([])
|
const [contracts, setContracts] = useState<Contract[]>([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadedBets = bets === 'loading' ? [] : bets
|
const loadedBets = bets ? bets : []
|
||||||
const contractIds = _.uniq(loadedBets.map((bet) => bet.contractId))
|
const contractIds = _.uniq(loadedBets.map((bet) => bet.contractId))
|
||||||
|
|
||||||
let disposed = false
|
let disposed = false
|
||||||
|
@ -52,7 +52,7 @@ export function BetsList(props: { user: User }) {
|
||||||
}
|
}
|
||||||
}, [bets])
|
}, [bets])
|
||||||
|
|
||||||
if (bets === 'loading') {
|
if (!bets) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
web/components/loading-indicator.tsx
Normal file
14
web/components/loading-indicator.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import clsx from 'clsx'
|
||||||
|
|
||||||
|
export function LoadingIndicator(props: { className?: string }) {
|
||||||
|
const { className } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx('flex justify-center items-center', className)}>
|
||||||
|
<div
|
||||||
|
className="spinner-border animate-spin inline-block w-8 h-8 border-4 border-solid border-r-transparent rounded-full border-indigo-500"
|
||||||
|
role="status"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { Row } from './layout/row'
|
import { Row } from './layout/row'
|
||||||
import { SiteLink } from './site-link'
|
import { SiteLink } from './site-link'
|
||||||
import { Fold } from '../../common/fold'
|
|
||||||
|
|
||||||
function Hashtag(props: { tag: string; noLink?: boolean }) {
|
function Hashtag(props: { tag: string; noLink?: boolean }) {
|
||||||
const { tag, noLink } = props
|
const { tag, noLink } = props
|
||||||
|
@ -45,11 +44,11 @@ export function TagsList(props: {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FoldTag(props: { fold: Fold }) {
|
export function FoldTag(props: { fold: { slug: string; name: string } }) {
|
||||||
const { fold } = props
|
const { fold } = props
|
||||||
const { name } = fold
|
const { slug, name } = fold
|
||||||
return (
|
return (
|
||||||
<SiteLink href={`/fold/${fold.slug}`} className="flex items-center">
|
<SiteLink href={`/fold/${slug}`} className="flex items-center">
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'bg-white border-2 px-4 py-1 rounded-full shadow-md',
|
'bg-white border-2 px-4 py-1 rounded-full shadow-md',
|
||||||
|
@ -62,7 +61,10 @@ export function FoldTag(props: { fold: Fold }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FoldTagList(props: { folds: Fold[]; className?: string }) {
|
export function FoldTagList(props: {
|
||||||
|
folds: { slug: string; name: string }[]
|
||||||
|
className?: string
|
||||||
|
}) {
|
||||||
const { folds, className } = props
|
const { folds, className } = props
|
||||||
return (
|
return (
|
||||||
<Row className={clsx('flex-wrap gap-2 items-center', className)}>
|
<Row className={clsx('flex-wrap gap-2 items-center', className)}>
|
||||||
|
@ -70,7 +72,7 @@ export function FoldTagList(props: { folds: Fold[]; className?: string }) {
|
||||||
<>
|
<>
|
||||||
<div className="text-gray-500 mr-1">Communities</div>
|
<div className="text-gray-500 mr-1">Communities</div>
|
||||||
{folds.map((fold) => (
|
{folds.map((fold) => (
|
||||||
<FoldTag key={fold.id} fold={fold} />
|
<FoldTag key={fold.slug} fold={fold} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Bet, listenForUserBets } from '../lib/firebase/bets'
|
import { Bet, listenForUserBets } from '../lib/firebase/bets'
|
||||||
|
|
||||||
export const useUserBets = (userId: string) => {
|
export const useUserBets = (userId: string | undefined) => {
|
||||||
const [bets, setBets] = useState<Bet[] | 'loading'>('loading')
|
const [bets, setBets] = useState<Bet[] | undefined>(undefined)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return listenForUserBets(userId, setBets)
|
if (userId) return listenForUserBets(userId, setBets)
|
||||||
}, [userId])
|
}, [userId])
|
||||||
|
|
||||||
return bets
|
return bets
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {
|
||||||
collection,
|
collection,
|
||||||
collectionGroup,
|
collectionGroup,
|
||||||
query,
|
query,
|
||||||
onSnapshot,
|
|
||||||
where,
|
where,
|
||||||
orderBy,
|
orderBy,
|
||||||
} from 'firebase/firestore'
|
} from 'firebase/firestore'
|
||||||
|
@ -11,7 +10,7 @@ import _ from 'lodash'
|
||||||
import { db } from './init'
|
import { db } from './init'
|
||||||
import { Bet } from '../../../common/bet'
|
import { Bet } from '../../../common/bet'
|
||||||
import { Contract } from '../../../common/contract'
|
import { Contract } from '../../../common/contract'
|
||||||
import { getValues } from './utils'
|
import { getValues, listenForValues } from './utils'
|
||||||
export type { Bet }
|
export type { Bet }
|
||||||
|
|
||||||
function getBetsCollection(contractId: string) {
|
function getBetsCollection(contractId: string) {
|
||||||
|
@ -51,11 +50,8 @@ export function listenForBets(
|
||||||
contractId: string,
|
contractId: string,
|
||||||
setBets: (bets: Bet[]) => void
|
setBets: (bets: Bet[]) => void
|
||||||
) {
|
) {
|
||||||
return onSnapshot(getBetsCollection(contractId), (snap) => {
|
return listenForValues<Bet>(getBetsCollection(contractId), (bets) => {
|
||||||
const bets = snap.docs.map((doc) => doc.data() as Bet)
|
|
||||||
|
|
||||||
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
||||||
|
|
||||||
setBets(bets)
|
setBets(bets)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -68,9 +64,7 @@ export function listenForUserBets(
|
||||||
collectionGroup(db, 'bets'),
|
collectionGroup(db, 'bets'),
|
||||||
where('userId', '==', userId)
|
where('userId', '==', userId)
|
||||||
)
|
)
|
||||||
|
return listenForValues<Bet>(userQuery, (bets) => {
|
||||||
return onSnapshot(userQuery, (snap) => {
|
|
||||||
const bets = snap.docs.map((doc) => doc.data() as Bet)
|
|
||||||
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
|
||||||
setBets(bets)
|
setBets(bets)
|
||||||
})
|
})
|
||||||
|
@ -88,5 +82,5 @@ export function withoutAnteBets(contract: Contract, bets?: Bet[]) {
|
||||||
return bets.slice(2)
|
return bets.slice(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bets ?? []
|
return bets?.filter((bet) => !bet.isAnte) ?? []
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {
|
import {
|
||||||
doc,
|
doc,
|
||||||
collection,
|
collection,
|
||||||
onSnapshot,
|
|
||||||
setDoc,
|
setDoc,
|
||||||
query,
|
query,
|
||||||
collectionGroup,
|
collectionGroup,
|
||||||
|
@ -46,13 +45,13 @@ export function listenForComments(
|
||||||
contractId: string,
|
contractId: string,
|
||||||
setComments: (comments: Comment[]) => void
|
setComments: (comments: Comment[]) => void
|
||||||
) {
|
) {
|
||||||
return onSnapshot(getCommentsCollection(contractId), (snap) => {
|
return listenForValues<Comment>(
|
||||||
const comments = snap.docs.map((doc) => doc.data() as Comment)
|
getCommentsCollection(contractId),
|
||||||
|
(comments) => {
|
||||||
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
||||||
|
setComments(comments)
|
||||||
setComments(comments)
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a map of betId -> comment
|
// Return a map of betId -> comment
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
collection,
|
collection,
|
||||||
query,
|
query,
|
||||||
getDocs,
|
getDocs,
|
||||||
onSnapshot,
|
|
||||||
orderBy,
|
orderBy,
|
||||||
getDoc,
|
getDoc,
|
||||||
updateDoc,
|
updateDoc,
|
||||||
|
@ -116,9 +115,7 @@ export function listenForContracts(
|
||||||
setContracts: (contracts: Contract[]) => void
|
setContracts: (contracts: Contract[]) => void
|
||||||
) {
|
) {
|
||||||
const q = query(contractCollection, orderBy('createdTime', 'desc'))
|
const q = query(contractCollection, orderBy('createdTime', 'desc'))
|
||||||
return onSnapshot(q, (snap) => {
|
return listenForValues<Contract>(q, setContracts)
|
||||||
setContracts(snap.docs.map((doc) => doc.data() as Contract))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listenForContract(
|
export function listenForContract(
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import {
|
import {
|
||||||
collection,
|
collection,
|
||||||
|
collectionGroup,
|
||||||
deleteDoc,
|
deleteDoc,
|
||||||
doc,
|
doc,
|
||||||
|
getDocs,
|
||||||
query,
|
query,
|
||||||
setDoc,
|
setDoc,
|
||||||
updateDoc,
|
updateDoc,
|
||||||
|
@ -12,7 +14,7 @@ import { Fold } from '../../../common/fold'
|
||||||
import { Contract, contractCollection } from './contracts'
|
import { Contract, contractCollection } from './contracts'
|
||||||
import { db } from './init'
|
import { db } from './init'
|
||||||
import { User } from './users'
|
import { User } from './users'
|
||||||
import { getValues, listenForValue, listenForValues } from './utils'
|
import { getValue, getValues, listenForValue, listenForValues } from './utils'
|
||||||
|
|
||||||
const foldCollection = collection(db, 'folds')
|
const foldCollection = collection(db, 'folds')
|
||||||
|
|
||||||
|
@ -39,6 +41,10 @@ export function listenForFolds(setFolds: (folds: Fold[]) => void) {
|
||||||
return listenForValues(foldCollection, setFolds)
|
return listenForValues(foldCollection, setFolds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFold(foldId: string) {
|
||||||
|
return getValue<Fold>(doc(foldCollection, foldId))
|
||||||
|
}
|
||||||
|
|
||||||
export async function getFoldBySlug(slug: string) {
|
export async function getFoldBySlug(slug: string) {
|
||||||
const q = query(foldCollection, where('slug', '==', slug))
|
const q = query(foldCollection, where('slug', '==', slug))
|
||||||
const folds = await getValues<Fold>(q)
|
const folds = await getValues<Fold>(q)
|
||||||
|
@ -147,3 +153,13 @@ export async function getFoldsByTags(tags: string[]) {
|
||||||
|
|
||||||
return _.sortBy(folds, (fold) => -1 * fold.followCount)
|
return _.sortBy(folds, (fold) => -1 * fold.followCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getFollowedFolds(userId: string) {
|
||||||
|
const snapshot = await getDocs(
|
||||||
|
query(collectionGroup(db, 'followers'), where('userId', '==', userId))
|
||||||
|
)
|
||||||
|
const foldIds = snapshot.docs.map(
|
||||||
|
(doc) => doc.ref.parent.parent?.id as string
|
||||||
|
)
|
||||||
|
return foldIds
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import {
|
||||||
doc,
|
doc,
|
||||||
setDoc,
|
setDoc,
|
||||||
getDoc,
|
getDoc,
|
||||||
onSnapshot,
|
|
||||||
collection,
|
collection,
|
||||||
query,
|
query,
|
||||||
where,
|
where,
|
||||||
|
@ -22,7 +21,7 @@ import {
|
||||||
import { app } from './init'
|
import { app } from './init'
|
||||||
import { PrivateUser, User } from '../../../common/user'
|
import { PrivateUser, User } from '../../../common/user'
|
||||||
import { createUser } from './api-call'
|
import { createUser } from './api-call'
|
||||||
import { getValues, listenForValues } from './utils'
|
import { getValues, listenForValue, listenForValues } from './utils'
|
||||||
export type { User }
|
export type { User }
|
||||||
|
|
||||||
const db = getFirestore(app)
|
const db = getFirestore(app)
|
||||||
|
@ -46,11 +45,12 @@ export async function setUser(userId: string, user: User) {
|
||||||
await setDoc(doc(db, 'users', userId), user)
|
await setDoc(doc(db, 'users', userId), user)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listenForUser(userId: string, setUser: (user: User) => void) {
|
export function listenForUser(
|
||||||
|
userId: string,
|
||||||
|
setUser: (user: User | null) => void
|
||||||
|
) {
|
||||||
const userRef = doc(db, 'users', userId)
|
const userRef = doc(db, 'users', userId)
|
||||||
return onSnapshot(userRef, (userSnap) => {
|
return listenForValue<User>(userRef, setUser)
|
||||||
setUser(userSnap.data() as User)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
||||||
|
|
|
@ -100,7 +100,7 @@ export function ActivityFeed(props: {
|
||||||
<div key={contract.id} className="py-6 px-2 sm:px-4">
|
<div key={contract.id} className="py-6 px-2 sm:px-4">
|
||||||
<ContractFeed
|
<ContractFeed
|
||||||
contract={contract}
|
contract={contract}
|
||||||
bets={contractBets[i] ?? []}
|
bets={contractBets[i]}
|
||||||
comments={contractComments[i]}
|
comments={contractComments[i]}
|
||||||
feedType="activity"
|
feedType="activity"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,72 +1,125 @@
|
||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import Router from 'next/router'
|
import Router from 'next/router'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import { Contract, listAllContracts } from '../lib/firebase/contracts'
|
import { Contract, listAllContracts } from '../lib/firebase/contracts'
|
||||||
import { Page } from '../components/page'
|
import { Page } from '../components/page'
|
||||||
import { ActivityFeed, findActiveContracts } from './activity'
|
import { ActivityFeed, findActiveContracts } from './activity'
|
||||||
import {
|
import { Comment, listAllComments } from '../lib/firebase/comments'
|
||||||
getRecentComments,
|
import { Bet, listAllBets } from '../lib/firebase/bets'
|
||||||
Comment,
|
|
||||||
listAllComments,
|
|
||||||
} from '../lib/firebase/comments'
|
|
||||||
import { Bet, getRecentBets, listAllBets } from '../lib/firebase/bets'
|
|
||||||
import FeedCreate from '../components/feed-create'
|
import FeedCreate from '../components/feed-create'
|
||||||
import { Spacer } from '../components/layout/spacer'
|
import { Spacer } from '../components/layout/spacer'
|
||||||
import { Col } from '../components/layout/col'
|
import { Col } from '../components/layout/col'
|
||||||
import { useUser } from '../hooks/use-user'
|
import { useUser } from '../hooks/use-user'
|
||||||
import { useContracts } from '../hooks/use-contracts'
|
import { useContracts } from '../hooks/use-contracts'
|
||||||
import { FoldTag, TagsList } from '../components/tags-list'
|
import { getFollowedFolds, listAllFolds } from '../lib/firebase/folds'
|
||||||
import { Row } from '../components/layout/row'
|
import { Fold } from '../../common/fold'
|
||||||
|
import { filterDefined } from '../../common/util/array'
|
||||||
|
import { useUserBets } from '../hooks/use-user-bets'
|
||||||
|
import { LoadingIndicator } from '../components/loading-indicator'
|
||||||
|
import { FoldTagList } from '../components/tags-list'
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
const [contracts, recentComments, recentBets] = await Promise.all([
|
const [contracts, folds] = await Promise.all([
|
||||||
listAllContracts().catch((_) => []),
|
listAllContracts().catch((_) => []),
|
||||||
getRecentComments().catch(() => []),
|
listAllFolds().catch(() => []),
|
||||||
getRecentBets().catch(() => []),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
const activeContracts = findActiveContracts(
|
|
||||||
contracts,
|
|
||||||
recentComments,
|
|
||||||
recentBets
|
|
||||||
)
|
|
||||||
const activeContractBets = await Promise.all(
|
|
||||||
activeContracts.map((contract) => listAllBets(contract.id).catch((_) => []))
|
|
||||||
)
|
|
||||||
const activeContractComments = await Promise.all(
|
|
||||||
activeContracts.map((contract) =>
|
|
||||||
listAllComments(contract.id).catch((_) => [])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
activeContracts,
|
contracts,
|
||||||
activeContractBets,
|
folds,
|
||||||
activeContractComments,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
revalidate: 60, // regenerate after a minute
|
revalidate: 60, // regenerate after a minute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Home = (props: {
|
const Home = (props: { contracts: Contract[]; folds: Fold[] }) => {
|
||||||
activeContracts: Contract[]
|
const { folds } = props
|
||||||
activeContractBets: Bet[][]
|
|
||||||
activeContractComments: Comment[][]
|
|
||||||
}) => {
|
|
||||||
const { activeContracts, activeContractBets, activeContractComments } = props
|
|
||||||
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
|
|
||||||
const contracts = useContracts() ?? activeContracts
|
const contracts = useContracts() ?? props.contracts
|
||||||
const contractsMap = _.fromPairs(
|
|
||||||
contracts.map((contract) => [contract.id, contract])
|
const [followedFoldIds, setFollowedFoldIds] = useState<string[] | undefined>(
|
||||||
|
undefined
|
||||||
)
|
)
|
||||||
const updatedContracts = activeContracts.map(
|
|
||||||
(contract) => contractsMap[contract.id]
|
useEffect(() => {
|
||||||
|
if (user) {
|
||||||
|
getFollowedFolds(user.id).then((foldIds) => setFollowedFoldIds(foldIds))
|
||||||
|
}
|
||||||
|
}, [user])
|
||||||
|
|
||||||
|
const followedFolds = filterDefined(
|
||||||
|
(followedFoldIds ?? []).map((id) => folds.find((fold) => fold.id === id))
|
||||||
)
|
)
|
||||||
|
const tagSet = new Set(
|
||||||
|
_.flatten(followedFolds.map((fold) => fold.lowercaseTags))
|
||||||
|
)
|
||||||
|
|
||||||
|
const yourBets = useUserBets(user?.id)
|
||||||
|
const yourBetContracts = new Set(
|
||||||
|
(yourBets ?? []).map((bet) => bet.contractId)
|
||||||
|
)
|
||||||
|
|
||||||
|
const feedContracts =
|
||||||
|
followedFoldIds && yourBets
|
||||||
|
? contracts.filter(
|
||||||
|
(contract) =>
|
||||||
|
contract.lowercaseTags.some((tag) => tagSet.has(tag)) ||
|
||||||
|
yourBetContracts.has(contract.id)
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
const feedContractsKey = feedContracts?.map(({ id }) => id).join(',')
|
||||||
|
|
||||||
|
const [feedBets, setFeedBets] = useState<Bet[][] | undefined>()
|
||||||
|
const [feedComments, setFeedComments] = useState<Comment[][] | undefined>()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (feedContracts) {
|
||||||
|
Promise.all(
|
||||||
|
feedContracts.map((contract) => listAllBets(contract.id))
|
||||||
|
).then(setFeedBets)
|
||||||
|
Promise.all(
|
||||||
|
feedContracts.map((contract) => listAllComments(contract.id))
|
||||||
|
).then(setFeedComments)
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [feedContractsKey])
|
||||||
|
|
||||||
|
const oneDayMS = 24 * 60 * 60 * 1000
|
||||||
|
const recentBets =
|
||||||
|
feedBets &&
|
||||||
|
feedBets.flat().filter((bet) => bet.createdTime > Date.now() - oneDayMS)
|
||||||
|
|
||||||
|
const activeContracts =
|
||||||
|
feedContracts &&
|
||||||
|
feedComments &&
|
||||||
|
recentBets &&
|
||||||
|
findActiveContracts(feedContracts, feedComments.flat(), recentBets, 365)
|
||||||
|
|
||||||
|
const contractBets = activeContracts
|
||||||
|
? activeContracts.map(
|
||||||
|
(contract) => feedBets[feedContracts.indexOf(contract)]
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
const contractComments = activeContracts
|
||||||
|
? activeContracts.map(
|
||||||
|
(contract) => feedComments[feedContracts.indexOf(contract)]
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
|
||||||
|
console.log({
|
||||||
|
followedFoldIds,
|
||||||
|
followedFolds,
|
||||||
|
yourBetContracts,
|
||||||
|
feedContracts,
|
||||||
|
feedBets,
|
||||||
|
feedComments,
|
||||||
|
})
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
Router.replace('/')
|
Router.replace('/')
|
||||||
|
@ -76,28 +129,32 @@ const Home = (props: {
|
||||||
return (
|
return (
|
||||||
<Page assertUser="signed-in">
|
<Page assertUser="signed-in">
|
||||||
<Col className="items-center">
|
<Col className="items-center">
|
||||||
<Col className="max-w-3xl">
|
<Col className="max-w-3xl w-full">
|
||||||
<FeedCreate user={user ?? undefined} />
|
<FeedCreate user={user ?? undefined} />
|
||||||
<Spacer h={4} />
|
<Spacer h={6} />
|
||||||
|
<FoldTagList
|
||||||
<TagsList
|
|
||||||
className="mx-2"
|
className="mx-2"
|
||||||
tags={[
|
folds={[
|
||||||
'#politics',
|
{ name: 'Politics', slug: 'politics' },
|
||||||
'#crypto',
|
{ name: 'Crypto', slug: 'crypto' },
|
||||||
'#covid',
|
{ name: 'Sports', slug: 'sports' },
|
||||||
'#sports',
|
{ name: 'Science', slug: 'science' },
|
||||||
'#meta',
|
{
|
||||||
'#science',
|
name: 'Manifold Markets',
|
||||||
|
slug: 'manifold-markets',
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<Spacer h={4} />
|
<Spacer h={6} />
|
||||||
|
{activeContracts ? (
|
||||||
<ActivityFeed
|
<ActivityFeed
|
||||||
contracts={updatedContracts}
|
contracts={activeContracts}
|
||||||
contractBets={activeContractBets}
|
contractBets={contractBets}
|
||||||
contractComments={activeContractComments}
|
contractComments={contractComments}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<LoadingIndicator className="mt-4" />
|
||||||
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Col>
|
</Col>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
@ -22,7 +22,6 @@ module.exports = {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [require('@tailwindcss/forms'), require('daisyui')],
|
plugins: [require('@tailwindcss/forms'), require('daisyui')],
|
||||||
|
|
||||||
daisyui: {
|
daisyui: {
|
||||||
themes: [
|
themes: [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user