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.
248 lines
6.4 KiB
248 lines
6.4 KiB
import type { Dispatch, SetStateAction } from 'react'
|
|
import {
|
|
useMemo,
|
|
useEffect,
|
|
useState,
|
|
useCallback,
|
|
} from 'react'
|
|
import { useQueryClient } from 'react-query'
|
|
|
|
import throttle from 'lodash/throttle'
|
|
import isEmpty from 'lodash/isEmpty'
|
|
import includes from 'lodash/includes'
|
|
import find from 'lodash/find'
|
|
import isUndefined from 'lodash/isUndefined'
|
|
import flatMapDepth from 'lodash/flatMapDepth'
|
|
import uniqBy from 'lodash/uniqBy'
|
|
import values from 'lodash/values'
|
|
import size from 'lodash/size'
|
|
|
|
import { querieKeys } from 'config'
|
|
|
|
import type {
|
|
DataItem,
|
|
MatchScore,
|
|
PlayerParam,
|
|
} from 'requests'
|
|
import {
|
|
MatchInfo,
|
|
PlayersStats,
|
|
Player,
|
|
getPlayersStats,
|
|
getMatchParticipants,
|
|
} from 'requests'
|
|
|
|
import { getLocalStorageItem } from 'helpers/getLocalStorage'
|
|
|
|
import { useObjectState, usePageParams } from 'hooks'
|
|
|
|
import { StatsType, Tabs as StatsTabs } from 'features/MatchSidePlaylists/components/TabStats/config'
|
|
import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime'
|
|
import { TOUR_COMPLETED_STORAGE_KEY } from 'features/MatchTour'
|
|
import { Tabs } from 'features/MatchSidePlaylists/config'
|
|
|
|
import { DISPLAYED_PARAMS_COLUMNS } from 'features/MatchSidePlaylists/components/PlayersTable/config'
|
|
import { useFakeData } from './useFakeData'
|
|
|
|
const REQUEST_DELAY = 5000
|
|
const STATS_POLL_INTERVAL = 30000
|
|
|
|
type UsePlayersStatsArgs = {
|
|
matchProfile: MatchInfo,
|
|
playingProgress: number,
|
|
selectedStatsTable: StatsTabs,
|
|
selectedTab: Tabs,
|
|
setIsPlayersStatsFetching: Dispatch<SetStateAction<boolean>>,
|
|
statsType: StatsType,
|
|
}
|
|
|
|
type PlayersData = {
|
|
team1: Array<Player>,
|
|
team2: Array<Player>,
|
|
}
|
|
|
|
export const usePlayersStats = ({
|
|
matchProfile,
|
|
playingProgress,
|
|
selectedStatsTable,
|
|
selectedTab,
|
|
setIsPlayersStatsFetching,
|
|
statsType,
|
|
}: UsePlayersStatsArgs) => {
|
|
const [playersStats, setPlayersStats] = useObjectState<Record<string, PlayersStats>>({})
|
|
const [playersData, setPlayersData] = useState<PlayersData>({ team1: [], team2: [] })
|
|
|
|
const {
|
|
profileId: matchId,
|
|
sportName,
|
|
sportType,
|
|
} = usePageParams()
|
|
|
|
const fakeData = useFakeData(matchProfile)
|
|
|
|
const client = useQueryClient()
|
|
|
|
const matchScore = client.getQueryData<MatchScore>(querieKeys.matchScore)
|
|
|
|
const isCurrentStats = statsType === StatsType.CURRENT_STATS
|
|
|
|
const getParams = useCallback((stats: PlayersStats) => (
|
|
uniqBy(flatMapDepth(stats, values), 'id') as Array<PlayerParam>
|
|
), [])
|
|
|
|
const fetchPlayers = useMemo(() => throttle(async (second?: number) => {
|
|
const videoBounds = matchScore?.video_bounds || matchProfile?.video_bounds
|
|
|
|
if (
|
|
!matchProfile?.team1.id
|
|
|| !matchProfile?.team2.id
|
|
|| !videoBounds
|
|
) return null
|
|
|
|
try {
|
|
return getMatchParticipants({
|
|
matchId,
|
|
sportType,
|
|
...(!isUndefined(second) && getHalfTime(videoBounds, second)),
|
|
})
|
|
} catch (e) {
|
|
return Promise.reject(e)
|
|
}
|
|
}, REQUEST_DELAY), [
|
|
matchId,
|
|
matchProfile?.team1.id,
|
|
matchProfile?.team2.id,
|
|
matchProfile?.video_bounds,
|
|
matchScore?.video_bounds,
|
|
sportType,
|
|
])
|
|
|
|
const fetchPlayersStats = useMemo(() => (async (team: 'team1' | 'team2', second?: number) => {
|
|
const videoBounds = matchScore?.video_bounds || matchProfile?.video_bounds
|
|
|
|
if (!sportName || !matchProfile?.[team].id || !videoBounds) return null
|
|
|
|
try {
|
|
return getPlayersStats({
|
|
matchId,
|
|
sportName,
|
|
teamId: matchProfile[team].id,
|
|
...(!isUndefined(second) && getHalfTime(videoBounds, second)),
|
|
})
|
|
} catch (e) {
|
|
return Promise.reject(e)
|
|
}
|
|
}), [
|
|
matchScore?.video_bounds,
|
|
matchProfile,
|
|
sportName,
|
|
matchId,
|
|
])
|
|
|
|
const fetchData = useMemo(() => throttle(async (second?: number) => {
|
|
const isTeam1Selected = selectedStatsTable === StatsTabs.TEAM1
|
|
|
|
if (
|
|
selectedTab !== Tabs.STATS
|
|
|| !includes([StatsTabs.TEAM1, StatsTabs.TEAM2], selectedStatsTable)
|
|
|| !matchProfile?.team1.id
|
|
|| !matchProfile?.team2.id
|
|
|| (!matchProfile?.live && !isCurrentStats && !isEmpty(playersStats[isTeam1Selected
|
|
? matchProfile.team1.id
|
|
: matchProfile.team2.id]))
|
|
) return
|
|
|
|
const [res1, res2] = await Promise.all([
|
|
fetchPlayers(second),
|
|
isTeam1Selected
|
|
? fetchPlayersStats('team1', second)
|
|
: fetchPlayersStats('team2', second),
|
|
]) as [Array<DataItem> | null, PlayersStats | null]
|
|
|
|
const team1Players = find(res1, { team_id: matchProfile?.team1.id })?.players || []
|
|
const team2Players = find(res1, { team_id: matchProfile?.team2.id })?.players || []
|
|
|
|
const needUseFakeData = getLocalStorageItem(TOUR_COMPLETED_STORAGE_KEY) !== 'true'
|
|
&& (
|
|
isEmpty(team1Players)
|
|
|| isEmpty(res2)
|
|
|| size(getParams(res2)) <= DISPLAYED_PARAMS_COLUMNS
|
|
)
|
|
|
|
setPlayersData({
|
|
team1: needUseFakeData ? fakeData.playersData[0].players : team1Players,
|
|
team2: needUseFakeData ? fakeData.playersData[1].players : team2Players,
|
|
})
|
|
|
|
setPlayersStats({
|
|
...(isTeam1Selected && res2 && {
|
|
[matchProfile.team1.id]: needUseFakeData
|
|
? fakeData.playersStats as unknown as PlayersStats
|
|
: res2,
|
|
}),
|
|
...(!isTeam1Selected && res2 && {
|
|
[matchProfile.team2.id]: needUseFakeData
|
|
? fakeData.playersStats as unknown as PlayersStats
|
|
: res2,
|
|
}),
|
|
})
|
|
|
|
setIsPlayersStatsFetching(false)
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, REQUEST_DELAY), [
|
|
fetchPlayers,
|
|
fetchPlayersStats,
|
|
setPlayersStats,
|
|
matchProfile?.team1.id,
|
|
matchProfile?.team2.id,
|
|
matchProfile?.live,
|
|
setIsPlayersStatsFetching,
|
|
getParams,
|
|
fakeData,
|
|
selectedTab,
|
|
selectedStatsTable,
|
|
isCurrentStats,
|
|
])
|
|
|
|
const beforeCloseTourCallback = () => {
|
|
isCurrentStats ? fetchData(playingProgress) : fetchData()
|
|
}
|
|
|
|
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(playingProgress)
|
|
}
|
|
}, [
|
|
fetchData,
|
|
playingProgress,
|
|
isCurrentStats,
|
|
matchProfile?.live,
|
|
])
|
|
|
|
return {
|
|
beforeCloseTourCallback,
|
|
getParams,
|
|
playersData,
|
|
playersStats,
|
|
}
|
|
}
|
|
|