Simplify general comments logic, toggle comment boxes

This commit is contained in:
Ian Philips 2022-05-03 15:51:43 -04:00
parent 4f54225e16
commit d57eecb0c0
4 changed files with 88 additions and 98 deletions

View File

@ -7,6 +7,7 @@ import { ContractActivity } from '../feed/contract-activity'
import { ContractBetsTable, MyBetsSummary } from '../bets-list' import { ContractBetsTable, MyBetsSummary } from '../bets-list'
import { Spacer } from '../layout/spacer' import { Spacer } from '../layout/spacer'
import { Tabs } from '../layout/tabs' import { Tabs } from '../layout/tabs'
import { Col } from '../layout/col'
export function ContractTabs(props: { export function ContractTabs(props: {
contract: Contract contract: Contract
@ -33,18 +34,34 @@ export function ContractTabs(props: {
) )
const commentActivity = ( const commentActivity = (
<ContractActivity <>
contract={contract} <ContractActivity
bets={bets} contract={contract}
comments={comments} bets={bets}
user={user} comments={comments}
mode={ user={user}
contract.outcomeType === 'FREE_RESPONSE' mode={
? 'free-response-comments' contract.outcomeType === 'FREE_RESPONSE'
: 'comments' ? 'free-response-comment-answer-groups'
} : 'comments'
betRowClassName="!mt-0 xl:hidden" }
/> betRowClassName="!mt-0 xl:hidden"
/>
{contract.outcomeType === 'FREE_RESPONSE' && (
<Col className={'mt-8 flex w-full '}>
<div className={'text-md mt-8 mb-2 text-left'}>General Comments</div>
<div className={'mb-4 w-full border-b border-gray-200'} />
<ContractActivity
contract={contract}
bets={bets}
comments={comments}
user={user}
mode={'comments'}
betRowClassName="!mt-0 xl:hidden"
/>
</Col>
)}
</>
) )
const yourTrades = ( const yourTrades = (

View File

@ -23,7 +23,6 @@ export type ActivityItem =
| CloseItem | CloseItem
| ResolveItem | ResolveItem
| CommentInputItem | CommentInputItem
| GeneralCommentsItem
type BaseActivityItem = { type BaseActivityItem = {
id: string id: string
@ -76,11 +75,6 @@ export type AnswerGroupItem = BaseActivityItem & {
items: ActivityItem[] items: ActivityItem[]
} }
export type GeneralCommentsItem = BaseActivityItem & {
type: 'generalcomments'
items: ActivityItem[]
}
export type CloseItem = BaseActivityItem & { export type CloseItem = BaseActivityItem & {
type: 'close' type: 'close'
} }
@ -330,16 +324,6 @@ function getAnswerAndCommentInputGroups(
} }
}) })
.filter((group) => group.answer) as ActivityItem[] .filter((group) => group.answer) as ActivityItem[]
const outcome = GENERAL_COMMENTS_OUTCOME_ID
const items = collateCommentsSectionForOutcome(outcome)
answerGroups.unshift({
id: outcome,
type: 'generalcomments' as const,
contract,
items,
})
return answerGroups return answerGroups
} }
@ -559,7 +543,7 @@ export function getSpecificContractActivityItems(
comments: Comment[], comments: Comment[],
user: User | null | undefined, user: User | null | undefined,
options: { options: {
mode: 'comments' | 'bets' | 'free-response-comments' mode: 'comments' | 'bets' | 'free-response-comment-answer-groups'
} }
) { ) {
const { mode } = options const { mode } = options
@ -581,19 +565,30 @@ export function getSpecificContractActivityItems(
break break
case 'comments': case 'comments':
items.push(...getCommentsWithPositions(bets, comments, contract)) const nonFreeResponseComments = comments.filter(
(comment) => comment.answerOutcome === undefined
)
const nonFreeResponseBets =
contract.outcomeType === 'FREE_RESPONSE' ? [] : bets
items.push(
...getCommentsWithPositions(
nonFreeResponseBets,
nonFreeResponseComments,
contract
)
)
items.push({ items.push({
type: 'commentInput', type: 'commentInput',
id: 'commentInput', id: 'commentInput',
contract, contract,
betsByCurrentUser: user betsByCurrentUser: user
? bets.filter((bet) => bet.userId === user.id) ? nonFreeResponseBets.filter((bet) => bet.userId === user.id)
: [], : [],
comments: comments, comments: nonFreeResponseComments,
}) })
break break
case 'free-response-comments': case 'free-response-comment-answer-groups':
items.push( items.push(
...getAnswerAndCommentInputGroups( ...getAnswerAndCommentInputGroups(
contract as FullContract<DPM, FreeResponse>, contract as FullContract<DPM, FreeResponse>,

View File

@ -22,7 +22,7 @@ export function ContractActivity(props: {
| 'all' | 'all'
| 'comments' | 'comments'
| 'bets' | 'bets'
| 'free-response-comments' | 'free-response-comment-answer-groups'
contractPath?: string contractPath?: string
className?: string className?: string
betRowClassName?: string betRowClassName?: string
@ -46,7 +46,7 @@ export function ContractActivity(props: {
}) })
: mode === 'comments' || : mode === 'comments' ||
mode === 'bets' || mode === 'bets' ||
mode === 'free-response-comments' mode === 'free-response-comment-answer-groups'
? getSpecificContractActivityItems(contract, bets, comments, user, { ? getSpecificContractActivityItems(contract, bets, comments, user, {
mode, mode,
}) })

View File

@ -123,8 +123,6 @@ function FeedItem(props: { item: ActivityItem }) {
return <FeedResolve {...item} /> return <FeedResolve {...item} />
case 'commentInput': case 'commentInput':
return <CommentInput {...item} /> return <CommentInput {...item} />
case 'generalcomments':
return <FeedGeneralComments {...item} />
} }
} }
@ -268,11 +266,11 @@ export function CommentInput(props: {
return ( return (
<> <>
<Row className={'flex w-full gap-2 pt-3'}> <Row className={'flex w-full gap-2'}>
<div> <div>
<Avatar avatarUrl={user?.avatarUrl} username={user?.username} /> <Avatar avatarUrl={user?.avatarUrl} username={user?.username} />
</div> </div>
<div className={'min-w-0 flex-1 py-1.5'}> <div className={'min-w-0 flex-1'}>
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
{mostRecentCommentableBet && ( {mostRecentCommentableBet && (
<BetStatusText <BetStatusText
@ -294,35 +292,46 @@ export function CommentInput(props: {
</> </>
</> </>
)} )}
<div className="mt-2"> {(answerOutcome === undefined || focused) && (
<Textarea <div className="mt-2">
value={comment} <Textarea
onChange={(e) => setComment(e.target.value)} value={comment}
className="textarea textarea-bordered w-full resize-none" onChange={(e) => setComment(e.target.value)}
placeholder="Add a comment..." className="textarea textarea-bordered w-full resize-none"
rows={answerOutcome == undefined || focused ? 3 : 1} placeholder="Add a comment..."
onFocus={() => setFocused(true)} autoFocus={true}
onBlur={() => !comment && setFocused(false)} rows={answerOutcome == undefined || focused ? 3 : 1}
maxLength={MAX_COMMENT_LENGTH} onFocus={() => setFocused(true)}
onKeyDown={(e) => { onBlur={() => !comment && setFocused(false)}
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { maxLength={MAX_COMMENT_LENGTH}
submitComment(id) onKeyDown={(e) => {
} if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
}} submitComment(id)
/> }
<button }}
className={ />
'btn btn-outline btn-sm text-transform: mt-1 capitalize' </div>
} )}
onClick={() => {
submitComment(id)
setFocused(false)
}}
>
{user ? 'Comment' : 'Sign in to comment'}
</button>
</div>
</div> </div>
<button
className={'btn btn-outline btn-sm text-transform: mt-1 capitalize'}
onClick={() => {
if (answerOutcome === undefined) {
submitComment(id)
} else if (!focused) {
setFocused(true)
} else {
submitComment(id)
setFocused(false)
}
}}
>
{user
? !focused && answerOutcome !== undefined
? 'Add Comment'
: 'Comment'
: 'Sign in to comment'}
</button>
</div> </div>
</Row> </Row>
</> </>
@ -853,37 +862,6 @@ function FeedAnswerGroup(props: {
) )
} }
function FeedGeneralComments(props: {
contract: FullContract<any, FreeResponse>
items: ActivityItem[]
type: string
}) {
const { items } = props
return (
<Col className={'mt-8 flex w-full '}>
<div className={'text-md mt-8 mb-2 text-left'}>General Comments</div>
<div className={'w-full border-b border-gray-200'} />
{items.map((item, index) => (
<div
key={item.id}
className={clsx('relative', index !== items.length - 1 && 'pb-4')}
>
{index !== items.length - 1 ? (
<span
className="absolute top-5 left-5 -ml-px h-[calc(100%-1rem)] w-0.5 bg-gray-200"
aria-hidden="true"
/>
) : null}
<div className="relative flex items-start space-x-3">
<FeedItem item={item} />
</div>
</div>
))}
</Col>
)
}
// TODO: Should highlight the entire Feed segment // TODO: Should highlight the entire Feed segment
function FeedExpand(props: { setExpanded: (expanded: boolean) => void }) { function FeedExpand(props: { setExpanded: (expanded: boolean) => void }) {
const { setExpanded } = props const { setExpanded } = props