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/index.tsx

404 lines
10 KiB

import {
useEffect,
useState,
useMemo,
} from 'react'
import includes from 'lodash/includes'
import filter from 'lodash/filter'
import isEmpty from 'lodash/isEmpty'
import { useAuthStore } from 'features/AuthStore'
import { Tabs } from 'features/MatchSidePlaylists/config'
import { initialCircleAnimation } from 'features/CircleAnimationBar'
import type { TCircleAnimation } from 'features/CircleAnimationBar'
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'
import { PAGES } from 'config/pages'
import type { MatchInfo } from 'requests/getMatchInfo'
import { getMatchInfo } from 'requests/getMatchInfo'
import { getViewMatchDuration } from 'requests/getViewMatchDuration'
import { getLandingStatus } from 'requests/getLandingStatus'
import { usePageParams, useToggle } from 'hooks'
import { redirectToUrl } from 'helpers/redirectToUrl'
import { parseDate } from 'helpers/parseDate'
import { useTournamentData } from './useTournamentData'
import { useMatchData } from './useMatchData'
import { useFiltersPopup } from './useFitersPopup'
import { useTabEvents } from './useTabEvents'
import { useTeamsStats } from './useTeamsStats'
import { useStatsTab } from './useStatsTab'
import { usePlayersStats } from './usePlayersStats'
type PlayingData = {
player: {
id: number | null,
paramId: number | null,
},
team: {
id: number | null,
paramId: number | null,
},
}
const initPlayingData: PlayingData = {
player: {
id: null,
paramId: null,
},
team: {
id: null,
paramId: null,
},
}
const ACCESS_TIME = 60
export const useMatchPage = () => {
const [matchProfile, setMatchProfile] = useState<MatchInfo>(null)
const [watchAllEpisodesTimer, setWatchAllEpisodesTimer] = useState(false)
const [access, setAccess] = useState(true)
const [playingProgress, setPlayingProgress] = useState(0)
const [playingData, setPlayingData] = useState<PlayingData>(initPlayingData)
const [plaingOrder, setPlaingOrder] = useState(0)
const [isPlayFilterEpisodes, setIsPlayingFiltersEpisodes] = useState(false)
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH)
const [circleAnimation, setCircleAnimation] = useState<TCircleAnimation>(initialCircleAnimation)
const isStatsTab = selectedTab === Tabs.STATS
const { profileId: matchId, sportType } = usePageParams()
useEffect(() => {
sessionStorage.removeItem('isFromLanding')
}, [])
const {
isFromLanding,
setIsFromLanding,
user,
userInfo,
} = useAuthStore()
const {
close: hideProfileCard,
isOpen: profileCardShown,
open: showProfileCard,
} = useToggle(true)
const {
events,
handlePlaylistClick,
matchPlaylists,
selectedPlaylist,
setFullMatchPlaylistDuration,
} = useMatchData(matchProfile)
const profile = matchProfile
const {
activeEvents,
activeFirstTeamPlayers,
activeSecondTeamPlayers,
allActionsToggle,
allPlayersToggle,
applyFilters,
close: closePopup,
countOfFilters,
filters,
isAllActionsChecked,
isEmptyFilters,
isFirstTeamPlayersChecked,
isOpen: isOpenFiltersPopup,
isSecondTeamPlayersChecked,
toggle: togglePopup,
toggleActiveEvents,
toggleActivePlayers,
uniqEvents,
} = useFiltersPopup({
events,
matchPlaylists,
})
const getMatchViewDuration = (id: number) => (getViewMatchDuration({
matchId,
sportType,
userId: id,
}).then(({
duration,
error,
}) => {
if (error || (duration && Number(duration) > ACCESS_TIME)) {
setAccess(false)
}
}))
useEffect(() => {
if (user || isFromLanding) return
getLandingStatus({ matchId, sportType })
.then(({ landing_id }) => {
setIsFromLanding(false)
if (landing_id) redirectToUrl(`${PAGES.landing}/${landing_id}`)
})
}, [
isFromLanding,
matchId,
setIsFromLanding,
sportType,
user,
])
useEffect(() => {
getMatchInfo(sportType, matchId).then(setMatchProfile)
}, [sportType, matchId])
useEffect(() => {
let getIntervalMatch: ReturnType<typeof setInterval>
if (matchProfile?.live && !matchProfile.youtube_link) {
getIntervalMatch = setInterval(
() => getMatchInfo(sportType, matchId).then(setMatchProfile), 1000 * 60 * 3,
)
}
return () => clearInterval(getIntervalMatch)
}, [
matchProfile,
sportType,
matchId])
useEffect(() => {
if (user || !userInfo?.email) return
const counter = setInterval(
() => getMatchViewDuration(Number(userInfo?.email)), 1000 * 30,
)
// eslint-disable-next-line
return () => clearInterval(counter)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
sportType,
matchId,
userInfo,
])
const disablePlayingEpisodes = () => {
setIsPlayingFiltersEpisodes(false)
setWatchAllEpisodesTimer(false)
setCircleAnimation(initialCircleAnimation)
}
const {
circleAnimation: statsCircleAnimation,
filteredEvents: statsFilteredEvents,
isExpanded,
isPlayersStatsFetching,
isPlayFilterEpisodes: isStatsPlayFilterEpisodes,
isTeamsStatsFetching,
plaingOrder: statsPlaingOrder,
playEpisodes: playStatsEpisodes,
playNextEpisode: playStatsNextEpisode,
reduceTable,
selectedStatsTable,
setCircleAnimation: setStatsCircleAnimation,
setIsPlayersStatsFetching,
setIsPlayingFiltersEpisodes: setStatsIsPlayinFiltersEpisodes,
setIsTeamsStatsFetching,
setPlaingOrder: setStatsPlaingOrder,
setSelectedStatsTable,
setStatsType,
setWatchAllEpisodesTimer: setStatsWatchAllEpisodesTimer,
statsType,
toggleIsExpanded,
toggleStatsType,
watchAllEpisodesTimer: statsWatchAllEpisodesTimer,
} = useStatsTab({
disablePlayingEpisodes,
handlePlaylistClick,
matchProfile,
selectedPlaylist,
})
const {
beforeCloseTourCallback: beforeCloseTourCallbackTeams,
getFirstClickableParam,
isClickable,
teamsStats,
} = useTeamsStats({
matchProfile,
playingProgress,
selectedPlaylist,
setIsTeamsStatsFetching,
statsType,
})
const {
beforeCloseTourCallback: beforeCloseTourCallbackPlayers,
getParams,
isEmptyPlayersStats,
playersData,
playersStats,
} = usePlayersStats({
matchProfile,
playingProgress,
selectedPlaylist,
setIsPlayersStatsFetching,
statsType,
})
const beforeCloseTourCallback = () => {
beforeCloseTourCallbackPlayers()
beforeCloseTourCallbackTeams()
setStatsType(profile?.live ? StatsType.CURRENT_STATS : StatsType.FINAL_STATS)
isExpanded && toggleIsExpanded()
}
const isStarted = useMemo(() => (
profile?.date
? parseDate(profile.date) < new Date()
: true
), [profile?.date])
const { tournamentData } = useTournamentData(matchProfile)
const filteredEvents = useMemo(() => {
switch (true) {
case (!isEmpty(filters.events) && !isEmpty(filters.players)):
return filter(events, (event) => includes(filters.players, event.p)
&& includes(filters.events, event.l))
case (!isEmpty(filters.players)):
return filter(events, (event) => includes(filters.players, event.p))
case (!isEmpty(filters.events)):
return filter(events, (event) => includes(filters.events, event.l))
default: return events
}
}, [events, filters])
const {
activeStatus,
episodesToPlay,
isLiveMatch,
likeImage,
likeToggle,
reversedGroupEvents,
setReversed,
setUnreversed,
} = useTabEvents({ events: filteredEvents, profile })
const playNextEpisode = (order?: number) => {
const isLastEpisode = plaingOrder === episodesToPlay.length
const currentOrder = order === 0 ? order : plaingOrder
if (isLastEpisode) {
setIsPlayingFiltersEpisodes(false)
return
}
handlePlaylistClick(episodesToPlay[currentOrder])
setPlaingOrder(currentOrder + 1)
}
const playEpisodes = () => {
setPlayingData(initPlayingData)
setStatsWatchAllEpisodesTimer(true)
setStatsIsPlayinFiltersEpisodes(false)
setStatsCircleAnimation(initialCircleAnimation)
if (!watchAllEpisodesTimer) {
setWatchAllEpisodesTimer(true)
}
setIsPlayingFiltersEpisodes(true)
if (matchProfile?.live) {
handlePlaylistClick({
episodes: episodesToPlay.map((el) => el.episodes[0]),
id: 1,
type: episodesToPlay[0].type,
})
} else {
playNextEpisode(0)
}
}
return {
access,
activeEvents,
activeFirstTeamPlayers,
activeSecondTeamPlayers,
activeStatus,
allActionsToggle,
allPlayersToggle,
applyFilters,
beforeCloseTourCallback,
circleAnimation: isStatsTab ? statsCircleAnimation : circleAnimation,
closePopup,
countOfFilters,
disablePlayingEpisodes,
events,
filteredEvents: isStatsTab ? statsFilteredEvents : filteredEvents,
getFirstClickableParam,
getParams,
handlePlaylistClick,
hideProfileCard,
isAllActionsChecked,
isClickable,
isEmptyFilters,
isEmptyPlayersStats,
isExpanded,
isFirstTeamPlayersChecked,
isLiveMatch,
isOpenFiltersPopup,
isPlayFilterEpisodes: isStatsTab ? isStatsPlayFilterEpisodes : isPlayFilterEpisodes,
isPlayersStatsFetching,
isSecondTeamPlayersChecked,
isStarted,
isTeamsStatsFetching,
likeImage,
likeToggle,
matchPlaylists,
plaingOrder: isStatsTab ? statsPlaingOrder : plaingOrder,
playEpisodes,
playNextEpisode: isStatsTab ? playStatsNextEpisode : playNextEpisode,
playStatsEpisodes,
playersData,
playersStats,
playingData,
playingProgress,
profile,
profileCardShown,
reduceTable,
reversedGroupEvents,
selectedPlaylist,
selectedStatsTable,
selectedTab,
setCircleAnimation: isStatsTab ? setStatsCircleAnimation : setCircleAnimation,
setFullMatchPlaylistDuration,
setIsPlayingFiltersEpisodes: isStatsTab
? setStatsIsPlayinFiltersEpisodes
: setIsPlayersStatsFetching,
setPlaingOrder: isStatsTab ? setStatsPlaingOrder : setPlaingOrder,
setPlayingData,
setPlayingProgress,
setReversed,
setSelectedStatsTable,
setSelectedTab,
setStatsType,
setUnreversed,
setWatchAllEpisodesTimer: isStatsTab ? setStatsWatchAllEpisodesTimer : setWatchAllEpisodesTimer,
showProfileCard,
statsType,
teamsStats,
toggleActiveEvents,
toggleActivePlayers,
toggleIsExpanded,
togglePopup,
toggleStatsType,
tournamentData,
uniqEvents,
user,
watchAllEpisodesTimer: isStatsTab ? statsWatchAllEpisodesTimer : watchAllEpisodesTimer,
}
}