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.
 
 
 
 
spa_instat_tv/src/features/MatchPage/store/hooks/usePlayersStats.tsx

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,
}
}