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
					
				
							
								
								
									
										2
									
								
								functions/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								functions/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -16,4 +16,4 @@ package-lock.json | |||
| ui-debug.log | ||||
| firebase-debug.log | ||||
| firestore-debug.log | ||||
| firestore_export/ | ||||
| firestore_export/ | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ export type BetGroupItem = BaseActivityItem & { | |||
| } | ||||
| 
 | ||||
| export type AnswerGroupItem = BaseActivityItem & { | ||||
|   type: 'answergroup' | ||||
|   type: 'answergroup' | 'answer' | ||||
|   answer: Answer | ||||
|   items: ActivityItem[] | ||||
| } | ||||
|  | @ -256,6 +256,38 @@ function getAnswerGroups( | |||
|   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( | ||||
|   bets: Bet[], | ||||
|   comments: Comment[], | ||||
|  | @ -328,19 +360,37 @@ export function getAllContractActivityItems( | |||
|     : [{ type: 'description', id: '0', contract }] | ||||
| 
 | ||||
|   if (outcomeType === 'FREE_RESPONSE') { | ||||
|     const onlyUsersBetsOrBetsWithComments = bets.filter((bet) => | ||||
|       comments.some( | ||||
|         (comment) => comment.betId === bet.id || bet.userId === user?.id | ||||
|       ) | ||||
|     ) | ||||
|     items.push( | ||||
|       ...getAnswerGroups( | ||||
|         contract as FullContract<DPM, FreeResponse>, | ||||
|         bets, | ||||
|       ...groupBetsAndComments( | ||||
|         onlyUsersBetsOrBetsWithComments, | ||||
|         comments, | ||||
|         user, | ||||
|         contract, | ||||
|         user?.id, | ||||
|         { | ||||
|           sortByProb: true, | ||||
|           hideOutcome: false, | ||||
|           abbreviated, | ||||
|           smallAvatar: false, | ||||
|           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 { | ||||
|     items.push( | ||||
|       ...groupBetsAndComments(bets, comments, contract, user?.id, { | ||||
|  | @ -359,14 +409,16 @@ export function getAllContractActivityItems( | |||
|     items.push({ type: 'resolve', id: `${contract.resolutionTime}`, contract }) | ||||
|   } | ||||
| 
 | ||||
|   const commentsByBetId = mapCommentsByBetId(comments) | ||||
|   items.push({ | ||||
|     type: 'commentInput', | ||||
|     id: 'commentInput', | ||||
|     bets, | ||||
|     commentsByBetId, | ||||
|     contract, | ||||
|   }) | ||||
|   if (outcomeType === 'BINARY') { | ||||
|     const commentsByBetId = mapCommentsByBetId(comments) | ||||
|     items.push({ | ||||
|       type: 'commentInput', | ||||
|       id: 'commentInput', | ||||
|       bets, | ||||
|       commentsByBetId, | ||||
|       contract, | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   if (reversed) items.reverse() | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| // 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 { | ||||
|   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(tradingAllowed(contract) ? '' : '-mb-6')}> | ||||
|         {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 || | ||||
|             item.type === 'answergroup' ? ( | ||||
|               <span | ||||
|  | @ -104,6 +109,8 @@ function FeedItem(props: { item: ActivityItem }) { | |||
|       return <FeedBetGroup {...item} /> | ||||
|     case 'answergroup': | ||||
|       return <FeedAnswerGroup {...item} /> | ||||
|     case 'answer': | ||||
|       return <FeedAnswerGroup {...item} /> | ||||
|     case 'close': | ||||
|       return <FeedClose {...item} /> | ||||
|     case 'resolve': | ||||
|  | @ -195,10 +202,6 @@ export function CommentInput(props: { | |||
|   const user = useUser() | ||||
|   const [comment, setComment] = useState('') | ||||
| 
 | ||||
|   if (outcomeType === 'FREE_RESPONSE') { | ||||
|     return <div /> | ||||
|   } | ||||
| 
 | ||||
|   let canCommentOnABet = false | ||||
|   bets.some((bet) => { | ||||
|     // make sure there is not already a comment with a matching bet id:
 | ||||
|  | @ -224,34 +227,38 @@ export function CommentInput(props: { | |||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <div> | ||||
|         <Avatar avatarUrl={user?.avatarUrl} username={user?.username} /> | ||||
|       </div> | ||||
|       <div className={'min-w-0 flex-1 py-1.5'}> | ||||
|         <div className="text-sm text-gray-500"> | ||||
|           <div className="mt-2"> | ||||
|             <Textarea | ||||
|               value={comment} | ||||
|               onChange={(e) => setComment(e.target.value)} | ||||
|               className="textarea textarea-bordered w-full resize-none" | ||||
|               placeholder="Add a comment..." | ||||
|               rows={3} | ||||
|               maxLength={MAX_COMMENT_LENGTH} | ||||
|               onKeyDown={(e) => { | ||||
|                 if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { | ||||
|                   submitComment() | ||||
|       <Row className={'flex w-full gap-2 pt-5'}> | ||||
|         <div> | ||||
|           <Avatar avatarUrl={user?.avatarUrl} username={user?.username} /> | ||||
|         </div> | ||||
|         <div className={'min-w-0 flex-1 py-1.5'}> | ||||
|           <div className="text-sm text-gray-500"> | ||||
|             <div className="mt-2"> | ||||
|               <Textarea | ||||
|                 value={comment} | ||||
|                 onChange={(e) => setComment(e.target.value)} | ||||
|                 className="textarea textarea-bordered w-full resize-none" | ||||
|                 placeholder="Add a comment..." | ||||
|                 rows={3} | ||||
|                 maxLength={MAX_COMMENT_LENGTH} | ||||
|                 onKeyDown={(e) => { | ||||
|                   if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { | ||||
|                     submitComment() | ||||
|                   } | ||||
|                 }} | ||||
|               /> | ||||
|               <button | ||||
|                 className={ | ||||
|                   'btn btn-outline btn-sm text-transform: mt-1 capitalize' | ||||
|                 } | ||||
|               }} | ||||
|             /> | ||||
|             <button | ||||
|               className="btn btn-outline btn-sm mt-1" | ||||
|               onClick={submitComment} | ||||
|             > | ||||
|               Comment | ||||
|             </button> | ||||
|                 onClick={submitComment} | ||||
|               > | ||||
|                 {user ? 'Comment' : 'Sign in to comment'} | ||||
|               </button> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       </Row> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|  | @ -644,8 +651,9 @@ function FeedAnswerGroup(props: { | |||
|   contract: FullContract<any, FreeResponse> | ||||
|   answer: Answer | ||||
|   items: ActivityItem[] | ||||
|   type: string | ||||
| }) { | ||||
|   const { answer, items, contract } = props | ||||
|   const { answer, items, contract, type } = props | ||||
|   const { username, avatarUrl, name, text } = answer | ||||
| 
 | ||||
|   const prob = getDpmOutcomeProbability(contract.totalShares, answer.id) | ||||
|  | @ -653,7 +661,13 @@ function FeedAnswerGroup(props: { | |||
|   const [open, setOpen] = useState(false) | ||||
| 
 | ||||
|   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}> | ||||
|         <AnswerBetPanel | ||||
|           answer={answer} | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ export function OutcomeLabel(props: { | |||
|       contract={contract as FullContract<DPM, FreeResponse>} | ||||
|       resolution={outcome} | ||||
|       truncate={truncate} | ||||
|       answerClassName={'font-bold text-base-400'} | ||||
|     /> | ||||
|   ) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user