-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
445bede
commit e91b4b0
Showing
17 changed files
with
543 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { type APIHandler } from './helpers/endpoint' | ||
import { createSupabaseDirectClient } from 'shared/supabase/init' | ||
import { removeNullOrUndefinedProps } from 'common/util/object' | ||
|
||
export const getUsersByIds: APIHandler<'users/by-id'> = async (props) => { | ||
const pg = createSupabaseDirectClient() | ||
const users = await pg.manyOrNone( | ||
`select id, name, username, data->>'avatarUrl' as "avatarUrl", data->'isBannedFromPosting' as "isBannedFromPosting" | ||
from users | ||
where id = any($1)`, | ||
[props.ids] | ||
) | ||
return users.map((user) => removeNullOrUndefinedProps(user)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import { APIParams, APIPath, APIResponse } from 'common/api/schema' | ||
import { usePersistentInMemoryState } from './use-persistent-in-memory-state' | ||
import { Bet } from 'common/bet' | ||
import { useEffect } from 'react' | ||
import { useApiSubscription } from './use-api-subscription' | ||
import { sortBy, uniqBy } from 'lodash' | ||
import { LimitBet } from 'common/bet' | ||
|
||
export const useContractBets = ( | ||
contractId: string, | ||
opts: APIParams<'bets'> & { enabled?: boolean }, | ||
useIsPageVisible: () => boolean, | ||
api: (params: APIParams<'bets'>) => Promise<APIResponse<'bets'>> | ||
) => { | ||
const { enabled = true, ...apiOptions } = { | ||
contractId, | ||
...opts, | ||
} | ||
const optionsKey = JSON.stringify(apiOptions) | ||
|
||
const [newBets, setNewBets] = usePersistentInMemoryState<Bet[]>( | ||
[], | ||
`${optionsKey}-bets` | ||
) | ||
|
||
const addBets = (bets: Bet[]) => { | ||
setNewBets((currentBets) => { | ||
const uniqueBets = sortBy( | ||
uniqBy([...currentBets, ...bets], 'id'), | ||
'createdTime' | ||
) | ||
return uniqueBets.filter((b) => !betShouldBeFiltered(b, apiOptions)) | ||
}) | ||
} | ||
|
||
const isPageVisible = useIsPageVisible() | ||
|
||
useEffect(() => { | ||
if (isPageVisible && enabled) { | ||
api(apiOptions).then(addBets) | ||
} | ||
}, [optionsKey, enabled, isPageVisible]) | ||
|
||
useApiSubscription({ | ||
topics: [`contract/${contractId}/new-bet`], | ||
onBroadcast: (msg) => { | ||
addBets(msg.data.bets as Bet[]) | ||
}, | ||
enabled, | ||
}) | ||
|
||
// We have to listen to cancels as well, since we don't get them in the `new-bet` topic. | ||
useApiSubscription({ | ||
topics: [`contract/${contractId}/orders`], | ||
onBroadcast: (msg) => { | ||
const betUpdates = msg.data.bets as LimitBet[] | ||
const cancelledBets = betUpdates.filter( | ||
(bet: LimitBet) => bet.isCancelled | ||
) | ||
setNewBets((currentBets) => { | ||
return currentBets.map((bet) => { | ||
const cancelledBet = cancelledBets.find( | ||
(cancelledBet) => cancelledBet.id === bet.id | ||
) | ||
return cancelledBet ? { ...bet, isCancelled: true } : bet | ||
}) | ||
}) | ||
}, | ||
enabled, | ||
}) | ||
|
||
return newBets | ||
} | ||
|
||
export function betShouldBeFiltered(bet: Bet, options?: APIParams<'bets'>) { | ||
if (!options) { | ||
return false | ||
} | ||
const shouldBeFiltered = | ||
// if contract filter exists, and bet doesn't match contract | ||
(options.contractId && bet.contractId != options.contractId) || | ||
// if user filter exists, and bet doesn't match user | ||
(options.userId && bet.userId != options.userId) || | ||
// if afterTime filter exists, and bet is before that time | ||
(options.afterTime && bet.createdTime <= options.afterTime) || | ||
// if beforeTime filter exists, and bet is after that time | ||
(options.beforeTime !== undefined && | ||
bet.createdTime >= options.beforeTime) || | ||
// if redemption filter is true, and bet is redemption | ||
(options.filterRedemptions && bet.isRedemption) || | ||
// if open-limit kind exists, and bet is not filled/cancelled | ||
(options.kinds === 'open-limit' && (bet.isFilled || bet.isCancelled)) | ||
|
||
return shouldBeFiltered | ||
} | ||
|
||
export const useSubscribeGlobalBets = (options?: APIParams<'bets'>) => { | ||
const [newBets, setNewBets] = usePersistentInMemoryState<Bet[]>( | ||
[], | ||
'global-new-bets' | ||
) | ||
|
||
const addBets = (bets: Bet[]) => { | ||
setNewBets((currentBets) => { | ||
const uniqueBets = sortBy( | ||
uniqBy([...currentBets, ...bets], 'id'), | ||
'createdTime' | ||
) | ||
return uniqueBets.filter((b) => !betShouldBeFiltered(b, options)) | ||
}) | ||
} | ||
|
||
useApiSubscription({ | ||
topics: [`global/new-bet`], | ||
onBroadcast: (msg) => { | ||
addBets(msg.data.bets as Bet[]) | ||
}, | ||
}) | ||
|
||
return newBets | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Bet } from 'common/bet' | ||
import { groupBy, mapValues } from 'lodash' | ||
|
||
export const getMultiBetPointsFromBets = (bets: Bet[]) => { | ||
return mapValues(groupBy(bets, 'answerId'), (bets) => | ||
bets.map((bet) => ({ x: bet.createdTime, y: bet.probAfter })) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.