Simple bet fill notification
This commit is contained in:
parent
e2e59b5726
commit
9e7b3c0887
|
@ -62,3 +62,4 @@ export type notification_reason_types =
|
|||
| 'unique_bettors_on_your_contract'
|
||||
| 'on_group_you_are_member_of'
|
||||
| 'tip_received'
|
||||
| 'bet_fill'
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Contract } from '../../common/contract'
|
|||
import { getUserByUsername, getValues } from './utils'
|
||||
import { Comment } from '../../common/comment'
|
||||
import { uniq } from 'lodash'
|
||||
import { Bet } from '../../common/bet'
|
||||
import { Bet, LimitBet } from '../../common/bet'
|
||||
import { Answer } from '../../common/answer'
|
||||
import { getContractBetMetrics } from '../../common/calculate'
|
||||
import { removeUndefinedProps } from '../../common/util/object'
|
||||
|
@ -382,3 +382,37 @@ export const createTipNotification = async (
|
|||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
}
|
||||
|
||||
export const createBetFillNotification = async (
|
||||
fromUser: User,
|
||||
toUser: User,
|
||||
bet: Bet,
|
||||
userBet: LimitBet,
|
||||
contract: Contract,
|
||||
idempotencyKey: string
|
||||
) => {
|
||||
const fill = userBet.fills.find((fill) => fill.matchedBetId === bet.id)
|
||||
const fillAmount = fill?.amount ?? 0
|
||||
|
||||
const notificationRef = firestore
|
||||
.collection(`/users/${toUser.id}/notifications`)
|
||||
.doc(idempotencyKey)
|
||||
const notification: Notification = {
|
||||
id: idempotencyKey,
|
||||
userId: toUser.id,
|
||||
reason: 'bet_fill',
|
||||
createdTime: Date.now(),
|
||||
isSeen: false,
|
||||
sourceId: userBet.id,
|
||||
sourceType: 'bet',
|
||||
sourceUpdateType: 'updated',
|
||||
sourceUserName: fromUser.name,
|
||||
sourceUserUsername: fromUser.username,
|
||||
sourceUserAvatarUrl: fromUser.avatarUrl,
|
||||
sourceText: fillAmount.toString(),
|
||||
sourceContractCreatorUsername: contract.creatorUsername,
|
||||
sourceContractTitle: contract.question,
|
||||
sourceContractSlug: contract.slug,
|
||||
}
|
||||
return await notificationRef.set(removeUndefinedProps(notification))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import * as functions from 'firebase-functions'
|
||||
import * as admin from 'firebase-admin'
|
||||
import { keyBy } from 'lodash'
|
||||
|
||||
import { Bet } from '../../common/bet'
|
||||
import { Bet, LimitBet } from '../../common/bet'
|
||||
import { getContract, getUser, getValues } from './utils'
|
||||
import { createBetFillNotification } from './create-notification'
|
||||
import { filterDefined } from '../../common/util/array'
|
||||
|
||||
const firestore = admin.firestore()
|
||||
|
||||
|
@ -11,6 +15,8 @@ export const onCreateBet = functions.firestore
|
|||
const { contractId } = context.params as {
|
||||
contractId: string
|
||||
}
|
||||
const { eventId } = context
|
||||
|
||||
const bet = change.data() as Bet
|
||||
const lastBetTime = bet.createdTime
|
||||
|
||||
|
@ -18,4 +24,47 @@ export const onCreateBet = functions.firestore
|
|||
.collection('contracts')
|
||||
.doc(contractId)
|
||||
.update({ lastBetTime, lastUpdatedTime: Date.now() })
|
||||
|
||||
await notifyFills(bet, contractId, eventId)
|
||||
})
|
||||
|
||||
const notifyFills = async (bet: Bet, contractId: string, eventId: string) => {
|
||||
if (!bet.fills) return
|
||||
|
||||
const user = await getUser(bet.userId)
|
||||
if (!user) return
|
||||
const contract = await getContract(contractId)
|
||||
if (!contract) return
|
||||
|
||||
const matchedFills = bet.fills.filter((fill) => fill.matchedBetId !== null)
|
||||
const matchedBets = (
|
||||
await Promise.all(
|
||||
matchedFills.map((fill) =>
|
||||
getValues<LimitBet>(
|
||||
firestore.collectionGroup('bets').where('id', '==', fill.matchedBetId)
|
||||
)
|
||||
)
|
||||
)
|
||||
).flat()
|
||||
|
||||
const betUsers = await Promise.all(
|
||||
matchedBets.map((bet) => getUser(bet.userId))
|
||||
)
|
||||
const betUsersById = keyBy(filterDefined(betUsers), 'id')
|
||||
|
||||
await Promise.all(
|
||||
matchedBets.map((matchedBet) => {
|
||||
const matchedUser = betUsersById[matchedBet.userId]
|
||||
if (!matchedUser) return
|
||||
|
||||
return createBetFillNotification(
|
||||
user,
|
||||
matchedUser,
|
||||
bet,
|
||||
matchedBet,
|
||||
contract,
|
||||
eventId
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -795,6 +795,8 @@ function getSourceIdForLinkComponent(
|
|||
return sourceId
|
||||
case 'contract':
|
||||
return ''
|
||||
case 'bet':
|
||||
return ''
|
||||
default:
|
||||
return sourceId
|
||||
}
|
||||
|
@ -861,8 +863,17 @@ function NotificationTextLabel(props: {
|
|||
{'+' + formatMoney(parseInt(sourceText))}
|
||||
</span>
|
||||
)
|
||||
} else if (sourceType === 'bet' && sourceText) {
|
||||
return (
|
||||
<>
|
||||
Filled{' '}
|
||||
<span className="text-primary">
|
||||
{formatMoney(parseInt(sourceText))}
|
||||
</span>{' '}
|
||||
<span>of your limit bet</span>
|
||||
</>
|
||||
)
|
||||
}
|
||||
// return default text
|
||||
return (
|
||||
<div className={className ? className : 'line-clamp-4 whitespace-pre-line'}>
|
||||
<Linkify text={defaultText} />
|
||||
|
@ -913,6 +924,9 @@ function getReasonForShowingNotification(
|
|||
else if (sourceSlug) reasonText = 'joined because you shared'
|
||||
else reasonText = 'joined because of you'
|
||||
break
|
||||
case 'bet':
|
||||
reasonText = 'bet against you'
|
||||
break
|
||||
default:
|
||||
reasonText = ''
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user