diff --git a/web/components/answers/answers-panel.tsx b/web/components/answers/answers-panel.tsx index d8928c49..61dfec61 100644 --- a/web/components/answers/answers-panel.tsx +++ b/web/components/answers/answers-panel.tsx @@ -1,7 +1,6 @@ import _ from 'lodash' import { useLayoutEffect, useState } from 'react' -import { Answer } from '../../../common/answer' import { DPM, FreeResponse, FullContract } from '../../../common/contract' import { Col } from '../layout/col' import { formatPercent } from '../../../common/util/format' @@ -15,12 +14,11 @@ import { AnswerResolvePanel } from './answer-resolve-panel' export function AnswersPanel(props: { contract: FullContract - answers: Answer[] }) { const { contract } = props const { creatorId, resolution, resolutions, totalBets } = contract - const answers = useAnswers(contract.id) ?? props.answers + const answers = useAnswers(contract.id) ?? contract.answers const [winningAnswers, otherAnswers] = _.partition( answers.filter( (answer) => answer.id !== '0' && totalBets[answer.id] > 0.000000001 diff --git a/web/components/feed/activity-feed.tsx b/web/components/feed/activity-feed.tsx index 92d1c5dc..d7e3ab99 100644 --- a/web/components/feed/activity-feed.tsx +++ b/web/components/feed/activity-feed.tsx @@ -1,13 +1,10 @@ import _ from 'lodash' -import clsx from 'clsx' -import { Contract, tradingAllowed } from '../../lib/firebase/contracts' +import { Contract } from '../../lib/firebase/contracts' import { Comment } from '../../lib/firebase/comments' import { Col } from '../layout/col' import { Bet } from '../../../common/bet' import { useUser } from '../../hooks/use-user' -import BetRow from '../bet-row' -import { FeedQuestion } from './feed-items' import { ContractActivity } from './contract-activity' export function ActivityFeed(props: { @@ -15,8 +12,9 @@ export function ActivityFeed(props: { recentBets: Bet[] recentComments: Comment[] mode: 'only-recent' | 'abbreviated' | 'all' + getContractPath?: (contract: Contract) => string }) { - const { contracts, recentBets, recentComments, mode } = props + const { contracts, recentBets, recentComments, mode, getContractPath } = props const user = useUser() @@ -36,23 +34,13 @@ export function ActivityFeed(props: { bets={groupedBets[contract.id] ?? []} comments={groupedComments[contract.id] ?? []} mode={mode} + contractPath={getContractPath ? getContractPath(contract) : undefined} /> )} /> ) } -export function SummaryActivityFeed(props: { contracts: Contract[] }) { - const { contracts } = props - - return ( - } - /> - ) -} - function FeedContainer(props: { contracts: Contract[] renderContract: (contract: Contract) => any @@ -73,27 +61,3 @@ function FeedContainer(props: { ) } - -function ContractSummary(props: { - contract: Contract - betRowClassName?: string -}) { - const { contract, betRowClassName } = props - const { outcomeType } = contract - const isBinary = outcomeType === 'BINARY' - - return ( -
-
-
-
- -
-
-
- {isBinary && tradingAllowed(contract) && ( - - )} -
- ) -} diff --git a/web/components/feed/activity-items.ts b/web/components/feed/activity-items.ts index 39322ca4..92cfe016 100644 --- a/web/components/feed/activity-items.ts +++ b/web/components/feed/activity-items.ts @@ -36,6 +36,7 @@ export type DescriptionItem = BaseActivityItem & { export type QuestionItem = BaseActivityItem & { type: 'question' showDescription: boolean + contractPath?: string } export type BetItem = BaseActivityItem & { @@ -280,7 +281,14 @@ export function getAllContractActivityItems( filterToOutcome && answer ? [{ type: 'createanswer', id: answer.id, contract, answer }] : abbreviated - ? [{ type: 'question', id: '0', contract, showDescription: false }] + ? [ + { + type: 'question', + id: '0', + contract, + showDescription: false, + }, + ] : [{ type: 'description', id: '0', contract }] items.push( @@ -325,8 +333,12 @@ export function getRecentContractActivityItems( contract: Contract, bets: Bet[], comments: Comment[], - user: User | null | undefined + user: User | null | undefined, + options: { + contractPath?: string + } ) { + const { contractPath } = options bets = bets .filter((bet) => !bet.isRedemption) .sort((b1, b2) => b1.createdTime - b2.createdTime) @@ -337,6 +349,7 @@ export function getRecentContractActivityItems( id: '0', contract, showDescription: false, + contractPath, } const items = diff --git a/web/components/feed/contract-activity.tsx b/web/components/feed/contract-activity.tsx index 7430356f..7962134a 100644 --- a/web/components/feed/contract-activity.tsx +++ b/web/components/feed/contract-activity.tsx @@ -19,11 +19,19 @@ export function ContractActivity(props: { user: User | null | undefined mode: 'only-recent' | 'abbreviated' | 'all' filterToOutcome?: string // Which multi-category outcome to filter + contractPath?: string className?: string betRowClassName?: string }) { - const { contract, user, filterToOutcome, mode, className, betRowClassName } = - props + const { + contract, + user, + filterToOutcome, + mode, + contractPath, + className, + betRowClassName, + } = props const updatedComments = // eslint-disable-next-line react-hooks/rules-of-hooks @@ -36,7 +44,9 @@ export function ContractActivity(props: { const items = mode === 'only-recent' - ? getRecentContractActivityItems(contract, bets, comments, user) + ? getRecentContractActivityItems(contract, bets, comments, user, { + contractPath, + }) : getAllContractActivityItems( contract, bets, diff --git a/web/components/feed/feed-items.tsx b/web/components/feed/feed-items.tsx index fbb9ea11..bb064671 100644 --- a/web/components/feed/feed-items.tsx +++ b/web/components/feed/feed-items.tsx @@ -295,7 +295,8 @@ function TruncatedComment(props: { export function FeedQuestion(props: { contract: Contract - showDescription?: boolean + showDescription: boolean + contractPath?: string }) { const { contract, showDescription } = props const { creatorName, creatorUsername, question, resolution, outcomeType } = @@ -335,7 +336,9 @@ export function FeedQuestion(props: { {question} diff --git a/web/components/page.tsx b/web/components/page.tsx index fb8b6628..6ee84875 100644 --- a/web/components/page.tsx +++ b/web/components/page.tsx @@ -6,9 +6,10 @@ export function Page(props: { margin?: boolean assertUser?: 'signed-in' | 'signed-out' rightSidebar?: React.ReactNode + suspend?: boolean children?: any }) { - const { margin, assertUser, children, rightSidebar } = props + const { margin, assertUser, children, rightSidebar, suspend } = props return (
@@ -17,6 +18,7 @@ export function Page(props: { 'mx-auto w-full pb-14 lg:grid lg:grid-cols-12 lg:gap-8 lg:pt-6 xl:max-w-7xl', margin && 'px-4' )} + style={suspend ? visuallyHiddenStyle : undefined} >
@@ -41,3 +43,15 @@ export function Page(props: {
) } + +const visuallyHiddenStyle = { + clip: 'rect(0 0 0 0)', + clipPath: 'inset(50%)', + height: 1, + margin: -1, + overflow: 'hidden', + padding: 0, + position: 'absolute', + width: 1, + whiteSpace: 'nowrap', +} as const diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index 9d85991d..4a9a67be 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -28,6 +28,10 @@ export function contractPath(contract: Contract) { return `/${contract.creatorUsername}/${contract.slug}` } +export function homeContractPath(contract: Contract) { + return `/home?c=${contract.slug}` +} + export function contractMetrics(contract: Contract) { const { createdTime, resolutionTime, isResolved } = contract diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx index 2fcf0430..e4e4a67e 100644 --- a/web/pages/[username]/[contractSlug].tsx +++ b/web/pages/[username]/[contractSlug].tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' +import { ArrowLeftIcon } from '@heroicons/react/outline' import { useContractWithPreload } from '../../hooks/use-contract' import { ContractOverview } from '../../components/contract/contract-overview' @@ -21,10 +22,6 @@ import { contractTextDetails } from '../../components/contract/contract-card' import { Bet, listAllBets } from '../../lib/firebase/bets' import { Comment, listAllComments } from '../../lib/firebase/comments' import Custom404 from '../404' -import { getFoldsByTags } from '../../lib/firebase/folds' -import { Fold } from '../../../common/fold' -import { listAllAnswers } from '../../lib/firebase/answers' -import { Answer } from '../../../common/answer' import { AnswersPanel } from '../../components/answers/answers-panel' import { fromPropz, usePropz } from '../../hooks/use-propz' import { Leaderboard } from '../../components/leaderboard' @@ -34,6 +31,8 @@ import { formatMoney } from '../../../common/util/format' import { FeedBet, FeedComment } from '../../components/feed/feed-items' import { useUserById } from '../../hooks/use-users' import { ContractTabs } from '../../components/contract/contract-tabs' +import { FirstArgument } from '../../../common/util/types' +import { DPM, FreeResponse, FullContract } from '../../../common/contract' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz(props: { @@ -43,18 +42,11 @@ export async function getStaticPropz(props: { const contract = (await getContractFromSlug(contractSlug)) || null const contractId = contract?.id - const foldsPromise = getFoldsByTags(contract?.tags ?? []) - - const [bets, comments, answers] = await Promise.all([ + const [bets, comments] = await Promise.all([ contractId ? listAllBets(contractId) : [], contractId ? listAllComments(contractId) : [], - contractId && contract.outcomeType === 'FREE_RESPONSE' - ? listAllAnswers(contractId) - : [], ]) - const folds = await foldsPromise - return { props: { contract, @@ -62,8 +54,6 @@ export async function getStaticPropz(props: { slug: contractSlug, bets, comments, - answers, - folds, }, revalidate: 60, // regenerate after a minute @@ -79,19 +69,22 @@ export default function ContractPage(props: { username: string bets: Bet[] comments: Comment[] - answers: Answer[] slug: string - folds: Fold[] + backToHome?: () => void }) { props = usePropz(props, getStaticPropz) ?? { contract: null, username: '', comments: [], - answers: [], bets: [], slug: '', - folds: [], } + return +} + +export function ContractPageContent(props: FirstArgument) { + const { backToHome } = props + const user = useUser() const contract = useContractWithPreload(props.contract) @@ -136,6 +129,16 @@ export default function ContractPage(props: { )} + {backToHome && ( + + )} + } /> diff --git a/web/pages/home.tsx b/web/pages/home.tsx index bc21f9b6..cf097d54 100644 --- a/web/pages/home.tsx +++ b/web/pages/home.tsx @@ -1,5 +1,5 @@ -import React from 'react' -import Router from 'next/router' +import React, { useEffect } from 'react' +import Router, { useRouter } from 'next/router' import _ from 'lodash' import { Page } from '../components/page' @@ -13,6 +13,7 @@ import { useRecentBets } from '../hooks/use-bets' import { useActiveContracts } from '../hooks/use-contracts' import { useRecentComments } from '../hooks/use-comments' import { useAlgoFeed } from '../hooks/use-algo-feed' +import { ContractPageContent } from './[username]/[contractSlug]' const Home = () => { const user = useUser() @@ -29,33 +30,55 @@ const Home = () => { (contract) => contractsDict[contract.id] ?? contract ) + const router = useRouter() + const slug = router.query.c as string | undefined + const contract = feedContracts.find((c) => c.slug === slug) + + useEffect(() => { + if (slug && !contract) { + delete router.query.c + router.replace(router, undefined, { shallow: true }) + } + }) + if (user === null) { Router.replace('/') return <> } - const activityContent = - contracts && recentBets && recentComments ? ( - - ) : ( - - ) - return ( - - - - - - {activityContent} + <> + + + + + + {contracts && recentBets && recentComments ? ( + `home?c=${c.slug}`} + /> + ) : ( + + )} + - - + + + {contract && ( + + )} + ) }