Separate free response answers & comments (#100)
* Just for playing with, bad code * Whiten answer cards * Separate answers and comments in FR markets * Highlight FR answer in bet w/ comment * Darken answer text and move classname * Normalcase Comment
This commit is contained in:
		
							parent
							
								
									9270d48e12
								
							
						
					
					
						commit
						7722c723c4
					
				|  | @ -68,7 +68,7 @@ export type BetGroupItem = BaseActivityItem & { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export type AnswerGroupItem = BaseActivityItem & { | export type AnswerGroupItem = BaseActivityItem & { | ||||||
|   type: 'answergroup' |   type: 'answergroup' | 'answer' | ||||||
|   answer: Answer |   answer: Answer | ||||||
|   items: ActivityItem[] |   items: ActivityItem[] | ||||||
| } | } | ||||||
|  | @ -256,6 +256,38 @@ function getAnswerGroups( | ||||||
|   return answerGroups |   return answerGroups | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function getAnswers( | ||||||
|  |   contract: FullContract<DPM, FreeResponse>, | ||||||
|  |   bets: Bet[], | ||||||
|  |   user: User | undefined | null | ||||||
|  | ) { | ||||||
|  |   let outcomes = _.uniq(bets.map((bet) => bet.outcome)).filter( | ||||||
|  |     (outcome) => getOutcomeProbability(contract, outcome) > 0.0001 | ||||||
|  |   ) | ||||||
|  |   outcomes = _.sortBy(outcomes, (outcome) => | ||||||
|  |     getOutcomeProbability(contract, outcome) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   const answerGroups = outcomes | ||||||
|  |     .map((outcome) => { | ||||||
|  |       const answer = contract.answers?.find( | ||||||
|  |         (answer) => answer.id === outcome | ||||||
|  |       ) as Answer | ||||||
|  | 
 | ||||||
|  |       return { | ||||||
|  |         id: outcome, | ||||||
|  |         type: 'answer' as const, | ||||||
|  |         contract, | ||||||
|  |         answer, | ||||||
|  |         items: [] as ActivityItem[], | ||||||
|  |         user, | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     .filter((group) => group.answer) | ||||||
|  | 
 | ||||||
|  |   return answerGroups | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function groupBetsAndComments( | function groupBetsAndComments( | ||||||
|   bets: Bet[], |   bets: Bet[], | ||||||
|   comments: Comment[], |   comments: Comment[], | ||||||
|  | @ -328,19 +360,37 @@ export function getAllContractActivityItems( | ||||||
|     : [{ type: 'description', id: '0', contract }] |     : [{ type: 'description', id: '0', contract }] | ||||||
| 
 | 
 | ||||||
|   if (outcomeType === 'FREE_RESPONSE') { |   if (outcomeType === 'FREE_RESPONSE') { | ||||||
|  |     const onlyUsersBetsOrBetsWithComments = bets.filter((bet) => | ||||||
|  |       comments.some( | ||||||
|  |         (comment) => comment.betId === bet.id || bet.userId === user?.id | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|     items.push( |     items.push( | ||||||
|       ...getAnswerGroups( |       ...groupBetsAndComments( | ||||||
|         contract as FullContract<DPM, FreeResponse>, |         onlyUsersBetsOrBetsWithComments, | ||||||
|         bets, |  | ||||||
|         comments, |         comments, | ||||||
|         user, |         contract, | ||||||
|  |         user?.id, | ||||||
|         { |         { | ||||||
|           sortByProb: true, |           hideOutcome: false, | ||||||
|           abbreviated, |           abbreviated, | ||||||
|  |           smallAvatar: false, | ||||||
|           reversed, |           reversed, | ||||||
|         } |         } | ||||||
|       ) |       ) | ||||||
|     ) |     ) | ||||||
|  |     const commentsByBetId = mapCommentsByBetId(comments) | ||||||
|  |     items.push({ | ||||||
|  |       type: 'commentInput', | ||||||
|  |       id: 'commentInput', | ||||||
|  |       bets, | ||||||
|  |       commentsByBetId, | ||||||
|  |       contract, | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     items.push( | ||||||
|  |       ...getAnswers(contract as FullContract<DPM, FreeResponse>, bets, user) | ||||||
|  |     ) | ||||||
|   } else { |   } else { | ||||||
|     items.push( |     items.push( | ||||||
|       ...groupBetsAndComments(bets, comments, contract, user?.id, { |       ...groupBetsAndComments(bets, comments, contract, user?.id, { | ||||||
|  | @ -359,14 +409,16 @@ export function getAllContractActivityItems( | ||||||
|     items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract }) |     items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const commentsByBetId = mapCommentsByBetId(comments) |   if (outcomeType === 'BINARY') { | ||||||
|   items.push({ |     const commentsByBetId = mapCommentsByBetId(comments) | ||||||
|     type: 'commentInput', |     items.push({ | ||||||
|     id: 'commentInput', |       type: 'commentInput', | ||||||
|     bets, |       id: 'commentInput', | ||||||
|     commentsByBetId, |       bets, | ||||||
|     contract, |       commentsByBetId, | ||||||
|   }) |       contract, | ||||||
|  |     }) | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   if (reversed) items.reverse() |   if (reversed) items.reverse() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // From https://tailwindui.com/components/application-ui/lists/feeds
 | // From https://tailwindui.com/components/application-ui/lists/feeds
 | ||||||
| import { Fragment, useRef, useState } from 'react' | import React, { Fragment, useRef, useState } from 'react' | ||||||
| import * as _ from 'lodash' | import * as _ from 'lodash' | ||||||
| import { | import { | ||||||
|   BanIcon, |   BanIcon, | ||||||
|  | @ -67,7 +67,12 @@ export function FeedItems(props: { | ||||||
|     <div className={clsx('flow-root pr-2 md:pr-0', className)} ref={ref}> |     <div className={clsx('flow-root pr-2 md:pr-0', className)} ref={ref}> | ||||||
|       <div className={clsx(tradingAllowed(contract) ? '' : '-mb-6')}> |       <div className={clsx(tradingAllowed(contract) ? '' : '-mb-6')}> | ||||||
|         {items.map((item, activityItemIdx) => ( |         {items.map((item, activityItemIdx) => ( | ||||||
|           <div key={item.id} className="relative pb-6"> |           <div | ||||||
|  |             key={item.id} | ||||||
|  |             className={ | ||||||
|  |               item.type === 'answer' ? 'relative pb-2' : 'relative pb-6' | ||||||
|  |             } | ||||||
|  |           > | ||||||
|             {activityItemIdx !== items.length - 1 || |             {activityItemIdx !== items.length - 1 || | ||||||
|             item.type === 'answergroup' ? ( |             item.type === 'answergroup' ? ( | ||||||
|               <span |               <span | ||||||
|  | @ -104,6 +109,8 @@ function FeedItem(props: { item: ActivityItem }) { | ||||||
|       return <FeedBetGroup {...item} /> |       return <FeedBetGroup {...item} /> | ||||||
|     case 'answergroup': |     case 'answergroup': | ||||||
|       return <FeedAnswerGroup {...item} /> |       return <FeedAnswerGroup {...item} /> | ||||||
|  |     case 'answer': | ||||||
|  |       return <FeedAnswerGroup {...item} /> | ||||||
|     case 'close': |     case 'close': | ||||||
|       return <FeedClose {...item} /> |       return <FeedClose {...item} /> | ||||||
|     case 'resolve': |     case 'resolve': | ||||||
|  | @ -195,10 +202,6 @@ export function CommentInput(props: { | ||||||
|   const user = useUser() |   const user = useUser() | ||||||
|   const [comment, setComment] = useState('') |   const [comment, setComment] = useState('') | ||||||
| 
 | 
 | ||||||
|   if (outcomeType === 'FREE_RESPONSE') { |  | ||||||
|     return <div /> |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   let canCommentOnABet = false |   let canCommentOnABet = false | ||||||
|   bets.some((bet) => { |   bets.some((bet) => { | ||||||
|     // make sure there is not already a comment with a matching bet id:
 |     // make sure there is not already a comment with a matching bet id:
 | ||||||
|  | @ -224,34 +227,38 @@ export function CommentInput(props: { | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <div> |       <Row className={'flex w-full gap-2 pt-5'}> | ||||||
|         <Avatar avatarUrl={user?.avatarUrl} username={user?.username} /> |         <div> | ||||||
|       </div> |           <Avatar avatarUrl={user?.avatarUrl} username={user?.username} /> | ||||||
|       <div className={'min-w-0 flex-1 py-1.5'}> |         </div> | ||||||
|         <div className="text-sm text-gray-500"> |         <div className={'min-w-0 flex-1 py-1.5'}> | ||||||
|           <div className="mt-2"> |           <div className="text-sm text-gray-500"> | ||||||
|             <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={3} |                 placeholder="Add a comment..." | ||||||
|               maxLength={MAX_COMMENT_LENGTH} |                 rows={3} | ||||||
|               onKeyDown={(e) => { |                 maxLength={MAX_COMMENT_LENGTH} | ||||||
|                 if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { |                 onKeyDown={(e) => { | ||||||
|                   submitComment() |                   if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { | ||||||
|  |                     submitComment() | ||||||
|  |                   } | ||||||
|  |                 }} | ||||||
|  |               /> | ||||||
|  |               <button | ||||||
|  |                 className={ | ||||||
|  |                   'btn btn-outline btn-sm text-transform: mt-1 capitalize' | ||||||
|                 } |                 } | ||||||
|               }} |                 onClick={submitComment} | ||||||
|             /> |               > | ||||||
|             <button |                 {user ? 'Comment' : 'Sign in to comment'} | ||||||
|               className="btn btn-outline btn-sm mt-1" |               </button> | ||||||
|               onClick={submitComment} |             </div> | ||||||
|             > |  | ||||||
|               Comment |  | ||||||
|             </button> |  | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </Row> | ||||||
|     </> |     </> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | @ -644,8 +651,9 @@ function FeedAnswerGroup(props: { | ||||||
|   contract: FullContract<any, FreeResponse> |   contract: FullContract<any, FreeResponse> | ||||||
|   answer: Answer |   answer: Answer | ||||||
|   items: ActivityItem[] |   items: ActivityItem[] | ||||||
|  |   type: string | ||||||
| }) { | }) { | ||||||
|   const { answer, items, contract } = props |   const { answer, items, contract, type } = props | ||||||
|   const { username, avatarUrl, name, text } = answer |   const { username, avatarUrl, name, text } = answer | ||||||
| 
 | 
 | ||||||
|   const prob = getDpmOutcomeProbability(contract.totalShares, answer.id) |   const prob = getDpmOutcomeProbability(contract.totalShares, answer.id) | ||||||
|  | @ -653,7 +661,13 @@ function FeedAnswerGroup(props: { | ||||||
|   const [open, setOpen] = useState(false) |   const [open, setOpen] = useState(false) | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Col className="flex-1 gap-2"> |     <Col | ||||||
|  |       className={ | ||||||
|  |         type === 'answer' | ||||||
|  |           ? 'border-base-200 bg-base-200 flex-1 rounded-md p-3' | ||||||
|  |           : 'flex-1 gap-2' | ||||||
|  |       } | ||||||
|  |     > | ||||||
|       <Modal open={open} setOpen={setOpen}> |       <Modal open={open} setOpen={setOpen}> | ||||||
|         <AnswerBetPanel |         <AnswerBetPanel | ||||||
|           answer={answer} |           answer={answer} | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ export function OutcomeLabel(props: { | ||||||
|       contract={contract as FullContract<DPM, FreeResponse>} |       contract={contract as FullContract<DPM, FreeResponse>} | ||||||
|       resolution={outcome} |       resolution={outcome} | ||||||
|       truncate={truncate} |       truncate={truncate} | ||||||
|  |       answerClassName={'font-bold text-base-400'} | ||||||
|     /> |     /> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user