Enrich limit order notification
This commit is contained in:
parent
69c2570ff9
commit
8c6a40bab7
|
@ -92,11 +92,6 @@ export type notification_reason_types =
|
|||
| 'your_contract_closed'
|
||||
| 'subsidized_your_market'
|
||||
|
||||
export type BettingStreakData = {
|
||||
streak: number
|
||||
bonusAmount: number
|
||||
}
|
||||
|
||||
type notification_descriptions = {
|
||||
[key in notification_preference]: {
|
||||
simple: string
|
||||
|
@ -241,3 +236,15 @@ export const NOTIFICATION_DESCRIPTIONS: notification_descriptions = {
|
|||
detailed: `Answers on markets that you're watching and that you're invested in`,
|
||||
},
|
||||
}
|
||||
|
||||
export type BettingStreakData = {
|
||||
streak: number
|
||||
bonusAmount: number
|
||||
}
|
||||
|
||||
export type BetFillData = {
|
||||
betOutcome: string
|
||||
creatorOutcome: string
|
||||
probability: number
|
||||
fillAmount: number
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as admin from 'firebase-admin'
|
||||
import {
|
||||
BetFillData,
|
||||
BettingStreakData,
|
||||
Notification,
|
||||
notification_reason_types,
|
||||
|
@ -542,6 +543,12 @@ export const createBetFillNotification = async (
|
|||
sourceContractTitle: contract.question,
|
||||
sourceContractSlug: contract.slug,
|
||||
sourceContractId: contract.id,
|
||||
data: {
|
||||
betOutcome: bet.outcome,
|
||||
creatorOutcome: userBet.outcome,
|
||||
fillAmount,
|
||||
probability: userBet.limitProb,
|
||||
} as BetFillData,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
|
||||
|
|
|
@ -4,14 +4,14 @@ import { initAdmin } from './script-init'
|
|||
initAdmin()
|
||||
|
||||
import { getValues } from '../utils'
|
||||
import { Contract } from 'common/lib/contract'
|
||||
import { Comment } from 'common/lib/comment'
|
||||
import { Contract } from 'common/contract'
|
||||
import { Comment } from 'common/comment'
|
||||
import { uniq } from 'lodash'
|
||||
import { Bet } from 'common/lib/bet'
|
||||
import { Bet } from 'common/bet'
|
||||
import {
|
||||
DEV_HOUSE_LIQUIDITY_PROVIDER_ID,
|
||||
HOUSE_LIQUIDITY_PROVIDER_ID,
|
||||
} from 'common/lib/antes'
|
||||
} from 'common/antes'
|
||||
|
||||
const firestore = admin.firestore()
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import { ControlledTabs } from 'web/components/layout/tabs'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import Router, { useRouter } from 'next/router'
|
||||
import { Notification, notification_source_types } from 'common/notification'
|
||||
import {
|
||||
BetFillData,
|
||||
Notification,
|
||||
notification_source_types,
|
||||
} from 'common/notification'
|
||||
import { Avatar, EmptyAvatar } from 'web/components/avatar'
|
||||
import { Row } from 'web/components/layout/row'
|
||||
import { Page } from 'web/components/page'
|
||||
|
@ -141,6 +145,7 @@ function RenderNotificationGroups(props: {
|
|||
<NotificationItem
|
||||
notification={notification.notifications[0]}
|
||||
key={notification.notifications[0].id}
|
||||
justSummary={false}
|
||||
/>
|
||||
) : (
|
||||
<NotificationGroupItem
|
||||
|
@ -697,20 +702,11 @@ function NotificationGroupItem(props: {
|
|||
|
||||
function NotificationItem(props: {
|
||||
notification: Notification
|
||||
justSummary?: boolean
|
||||
justSummary: boolean
|
||||
isChildOfGroup?: boolean
|
||||
}) {
|
||||
const { notification, justSummary, isChildOfGroup } = props
|
||||
const {
|
||||
sourceType,
|
||||
sourceUserName,
|
||||
sourceUserAvatarUrl,
|
||||
sourceUpdateType,
|
||||
reasonText,
|
||||
reason,
|
||||
sourceUserUsername,
|
||||
sourceText,
|
||||
} = notification
|
||||
const { sourceType, reason } = notification
|
||||
|
||||
const [highlighted] = useState(!notification.isSeen)
|
||||
|
||||
|
@ -718,39 +714,103 @@ function NotificationItem(props: {
|
|||
setNotificationsAsSeen([notification])
|
||||
}, [notification])
|
||||
|
||||
const questionNeedsResolution = sourceUpdateType == 'closed'
|
||||
// TODO Any new notification should be its own component
|
||||
if (reason === 'bet_fill') {
|
||||
return (
|
||||
<BetFillNotification
|
||||
notification={notification}
|
||||
isChildOfGroup={isChildOfGroup}
|
||||
highlighted={highlighted}
|
||||
justSummary={justSummary}
|
||||
/>
|
||||
)
|
||||
}
|
||||
// TODO Add new notification components here
|
||||
|
||||
if (justSummary) {
|
||||
return (
|
||||
<Row className={'items-center text-sm text-gray-500 sm:justify-start'}>
|
||||
<div className={'line-clamp-1 flex-1 overflow-hidden sm:flex'}>
|
||||
<div className={'flex pl-1 sm:pl-0'}>
|
||||
<UserLink
|
||||
name={sourceUserName || ''}
|
||||
username={sourceUserUsername || ''}
|
||||
className={'mr-0 flex-shrink-0'}
|
||||
short={true}
|
||||
/>
|
||||
<div className={'inline-flex overflow-hidden text-ellipsis pl-1'}>
|
||||
<span className={'flex-shrink-0'}>
|
||||
{sourceType &&
|
||||
reason &&
|
||||
getReasonForShowingNotification(notification, true)}
|
||||
</span>
|
||||
<div className={'ml-1 text-black'}>
|
||||
<NotificationTextLabel
|
||||
className={'line-clamp-1'}
|
||||
notification={notification}
|
||||
justSummary={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
<NotificationSummaryFrame
|
||||
notification={notification}
|
||||
subtitle={
|
||||
(sourceType &&
|
||||
reason &&
|
||||
getReasonForShowingNotification(notification, true)) ??
|
||||
''
|
||||
}
|
||||
>
|
||||
<NotificationTextLabel
|
||||
className={'line-clamp-1'}
|
||||
notification={notification}
|
||||
justSummary={true}
|
||||
/>
|
||||
</NotificationSummaryFrame>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<NotificationFrame
|
||||
notification={notification}
|
||||
subtitle={getReasonForShowingNotification(
|
||||
notification,
|
||||
isChildOfGroup ?? false
|
||||
)}
|
||||
highlighted={highlighted}
|
||||
>
|
||||
<div className={'mt-1 ml-1 md:text-base'}>
|
||||
<NotificationTextLabel notification={notification} />
|
||||
</div>
|
||||
</NotificationFrame>
|
||||
)
|
||||
}
|
||||
|
||||
function NotificationSummaryFrame(props: {
|
||||
notification: Notification
|
||||
subtitle: string
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const { notification, subtitle, children } = props
|
||||
const { sourceUserName, sourceUserUsername } = notification
|
||||
return (
|
||||
<Row className={'items-center text-sm text-gray-500 sm:justify-start'}>
|
||||
<div className={'line-clamp-1 flex-1 overflow-hidden sm:flex'}>
|
||||
<div className={'flex pl-1 sm:pl-0'}>
|
||||
<UserLink
|
||||
name={sourceUserName || ''}
|
||||
username={sourceUserUsername || ''}
|
||||
className={'mr-0 flex-shrink-0'}
|
||||
short={true}
|
||||
/>
|
||||
<div className={'inline-flex overflow-hidden text-ellipsis pl-1'}>
|
||||
<span className={'flex-shrink-0'}>{subtitle}</span>
|
||||
<div className={'line-clamp-1 ml-1 text-black'}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
function NotificationFrame(props: {
|
||||
notification: Notification
|
||||
highlighted: boolean
|
||||
subtitle: string
|
||||
children: React.ReactNode
|
||||
isChildOfGroup?: boolean
|
||||
}) {
|
||||
const { notification, isChildOfGroup, highlighted, subtitle, children } =
|
||||
props
|
||||
const {
|
||||
sourceType,
|
||||
sourceUserName,
|
||||
sourceUserAvatarUrl,
|
||||
sourceUpdateType,
|
||||
reason,
|
||||
reasonText,
|
||||
sourceUserUsername,
|
||||
sourceText,
|
||||
} = notification
|
||||
const questionNeedsResolution = sourceUpdateType == 'closed'
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
|
@ -796,18 +856,13 @@ function NotificationItem(props: {
|
|||
}
|
||||
>
|
||||
<div>
|
||||
{!questionNeedsResolution && (
|
||||
<UserLink
|
||||
name={sourceUserName || ''}
|
||||
username={sourceUserUsername || ''}
|
||||
className={'relative mr-1 flex-shrink-0'}
|
||||
short={true}
|
||||
/>
|
||||
)}
|
||||
{getReasonForShowingNotification(
|
||||
notification,
|
||||
isChildOfGroup ?? false
|
||||
)}
|
||||
<UserLink
|
||||
name={sourceUserName || ''}
|
||||
username={sourceUserUsername || ''}
|
||||
className={'relative mr-1 flex-shrink-0'}
|
||||
short={true}
|
||||
/>
|
||||
{subtitle}
|
||||
{isChildOfGroup ? (
|
||||
<RelativeTimestamp time={notification.createdTime} />
|
||||
) : (
|
||||
|
@ -822,9 +877,7 @@ function NotificationItem(props: {
|
|||
)}
|
||||
</div>
|
||||
</Row>
|
||||
<div className={'mt-1 ml-1 md:text-base'}>
|
||||
<NotificationTextLabel notification={notification} />
|
||||
</div>
|
||||
<div className={'mt-1 ml-1 md:text-base'}>{children}</div>
|
||||
|
||||
<div className={'mt-6 border-b border-gray-300'} />
|
||||
</div>
|
||||
|
@ -832,6 +885,66 @@ function NotificationItem(props: {
|
|||
)
|
||||
}
|
||||
|
||||
function BetFillNotification(props: {
|
||||
notification: Notification
|
||||
highlighted: boolean
|
||||
justSummary: boolean
|
||||
isChildOfGroup?: boolean
|
||||
}) {
|
||||
const { notification, isChildOfGroup, highlighted, justSummary } = props
|
||||
const { sourceText, data } = notification
|
||||
const { creatorOutcome, probability } = (data as BetFillData) ?? {}
|
||||
const subtitle = 'bet against you'
|
||||
const amount = formatMoney(parseInt(sourceText ?? '0'))
|
||||
const description =
|
||||
creatorOutcome && probability ? (
|
||||
<span>
|
||||
of your{' '}
|
||||
<span
|
||||
className={
|
||||
creatorOutcome === 'YES'
|
||||
? 'text-primary'
|
||||
: creatorOutcome === 'NO'
|
||||
? 'text-red-500'
|
||||
: 'text-blue-500'
|
||||
}
|
||||
>
|
||||
{creatorOutcome}{' '}
|
||||
</span>
|
||||
limit order at {Math.round(probability * 100)}% was filled
|
||||
</span>
|
||||
) : (
|
||||
<span>of your limit order was filled</span>
|
||||
)
|
||||
|
||||
if (justSummary) {
|
||||
return (
|
||||
<NotificationSummaryFrame notification={notification} subtitle={subtitle}>
|
||||
<Row className={'line-clamp-1'}>
|
||||
<span className={'text-primary mr-1'}>{amount}</span>
|
||||
<span>{description}</span>
|
||||
</Row>
|
||||
</NotificationSummaryFrame>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<NotificationFrame
|
||||
notification={notification}
|
||||
isChildOfGroup={isChildOfGroup}
|
||||
highlighted={highlighted}
|
||||
subtitle={subtitle}
|
||||
>
|
||||
<Row>
|
||||
<span>
|
||||
<span className="text-primary mr-1">{amount}</span>
|
||||
{description}
|
||||
</span>
|
||||
</Row>
|
||||
</NotificationFrame>
|
||||
)
|
||||
}
|
||||
|
||||
export const setNotificationsAsSeen = async (notifications: Notification[]) => {
|
||||
const unseenNotifications = notifications.filter((n) => !n.isSeen)
|
||||
return await Promise.all(
|
||||
|
@ -1002,15 +1115,6 @@ function NotificationTextLabel(props: {
|
|||
return (
|
||||
<span className="text-blue-400">{formatMoney(parseInt(sourceText))}</span>
|
||||
)
|
||||
} else if (sourceType === 'bet' && sourceText) {
|
||||
return (
|
||||
<>
|
||||
<span className="text-primary">
|
||||
{formatMoney(parseInt(sourceText))}
|
||||
</span>{' '}
|
||||
<span>of your limit order was filled</span>
|
||||
</>
|
||||
)
|
||||
} else if (sourceType === 'challenge' && sourceText) {
|
||||
return (
|
||||
<>
|
||||
|
@ -1074,9 +1178,6 @@ function getReasonForShowingNotification(
|
|||
else if (sourceSlug) reasonText = 'joined because you shared'
|
||||
else reasonText = 'joined because of you'
|
||||
break
|
||||
case 'bet':
|
||||
reasonText = 'bet against you'
|
||||
break
|
||||
case 'challenge':
|
||||
reasonText = 'accepted your challenge'
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue
Block a user