You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
3.9 KiB
170 lines
3.9 KiB
import type { Dispatch, SetStateAction } from 'react'
|
|
import {
|
|
useMemo,
|
|
useEffect,
|
|
useState,
|
|
} from 'react'
|
|
|
|
import throttle from 'lodash/throttle'
|
|
import isEmpty from 'lodash/isEmpty'
|
|
import every from 'lodash/every'
|
|
import find from 'lodash/find'
|
|
|
|
import type {
|
|
MatchInfo,
|
|
PlayersStats,
|
|
Player,
|
|
} from 'requests'
|
|
import { getPlayersStats, getMatchParticipants } from 'requests'
|
|
|
|
import { useObjectState, usePageParams } from 'hooks'
|
|
|
|
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'
|
|
|
|
const REQUEST_DELAY = 3000
|
|
const STATS_POLL_INTERVAL = 30000
|
|
|
|
type UsePlayersStatsArgs = {
|
|
matchProfile: MatchInfo,
|
|
playingProgress: number,
|
|
setIsPlayersStatsFetching: Dispatch<SetStateAction<boolean>>,
|
|
statsType: StatsType,
|
|
}
|
|
|
|
type PlayersData = {
|
|
team1: Array<Player>,
|
|
team2: Array<Player>,
|
|
}
|
|
|
|
export const usePlayersStats = ({
|
|
matchProfile,
|
|
playingProgress,
|
|
setIsPlayersStatsFetching,
|
|
statsType,
|
|
}: UsePlayersStatsArgs) => {
|
|
const [playersStats, setPlayersStats] = useObjectState<Record<string, PlayersStats>>({})
|
|
const [playersData, setPlayersData] = useState<PlayersData>({ team1: [], team2: [] })
|
|
|
|
const {
|
|
profileId: matchId,
|
|
sportName,
|
|
sportType,
|
|
} = usePageParams()
|
|
|
|
const isCurrentStats = statsType === StatsType.CURRENT_STATS
|
|
|
|
const progressSec = Math.floor(playingProgress / 1000)
|
|
|
|
const isEmptyPlayersStats = (teamId: number) => (
|
|
isEmpty(playersStats[teamId])
|
|
|| every(playersStats[teamId], isEmpty)
|
|
|| isEmpty(playersData[matchProfile?.team1.id === teamId ? 'team1' : 'team2'])
|
|
)
|
|
|
|
const fetchPlayers = useMemo(() => throttle(async (second?: number) => {
|
|
if (!matchProfile?.team1.id || !matchProfile?.team2.id) return null
|
|
|
|
try {
|
|
return getMatchParticipants({
|
|
matchId,
|
|
second,
|
|
sportType,
|
|
})
|
|
} catch (e) {
|
|
return Promise.reject(e)
|
|
}
|
|
}, REQUEST_DELAY), [
|
|
matchId,
|
|
matchProfile?.team1.id,
|
|
matchProfile?.team2.id,
|
|
sportType,
|
|
])
|
|
|
|
const fetchPlayersStats = useMemo(() => (async (team: 'team1' | 'team2', second?: number) => {
|
|
if (!sportName || !matchProfile?.[team].id) return null
|
|
|
|
try {
|
|
return getPlayersStats({
|
|
matchId,
|
|
second,
|
|
sportName,
|
|
teamId: matchProfile[team].id,
|
|
})
|
|
} catch (e) {
|
|
return Promise.reject(e)
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}), [
|
|
matchId,
|
|
sportName,
|
|
matchProfile?.team1.id,
|
|
matchProfile?.team2.id,
|
|
])
|
|
|
|
const fetchData = useMemo(() => throttle(async (second?: number) => {
|
|
const [res1, res2, res3] = await Promise.all([
|
|
fetchPlayers(second),
|
|
fetchPlayersStats('team1', second),
|
|
fetchPlayersStats('team2', second),
|
|
])
|
|
|
|
const team1Players = find(res1, { team_id: matchProfile?.team1.id })?.players || []
|
|
const team2Players = find(res1, { team_id: matchProfile?.team2.id })?.players || []
|
|
|
|
setPlayersData({
|
|
team1: team1Players,
|
|
team2: team2Players,
|
|
})
|
|
|
|
setPlayersStats({
|
|
...(matchProfile?.team1.id && res2 && { [matchProfile.team1.id]: res2 }),
|
|
...(matchProfile?.team2.id && res3 && { [matchProfile.team2.id]: res3 }),
|
|
})
|
|
|
|
setIsPlayersStatsFetching(false)
|
|
}, REQUEST_DELAY), [
|
|
fetchPlayers,
|
|
fetchPlayersStats,
|
|
setPlayersStats,
|
|
matchProfile?.team1.id,
|
|
matchProfile?.team2.id,
|
|
setIsPlayersStatsFetching,
|
|
])
|
|
|
|
useEffect(() => {
|
|
let interval: NodeJS.Timeout
|
|
|
|
if (!isCurrentStats) {
|
|
fetchData()
|
|
}
|
|
|
|
if (matchProfile?.live && !isCurrentStats) {
|
|
interval = setInterval(() => {
|
|
fetchData()
|
|
}, STATS_POLL_INTERVAL)
|
|
}
|
|
|
|
return () => clearInterval(interval)
|
|
}, [
|
|
fetchData,
|
|
isCurrentStats,
|
|
matchProfile?.live,
|
|
])
|
|
|
|
useEffect(() => {
|
|
if (isCurrentStats) {
|
|
fetchData(progressSec)
|
|
}
|
|
}, [
|
|
fetchData,
|
|
progressSec,
|
|
isCurrentStats,
|
|
matchProfile?.live,
|
|
])
|
|
|
|
return {
|
|
isEmptyPlayersStats,
|
|
playersData,
|
|
playersStats,
|
|
}
|
|
}
|
|
|