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

493 lines
13 KiB

import {
useEffect,
useState,
useMemo,
} from 'react'
import { useHistory } from 'react-router'
import includes from 'lodash/includes'
import filter from 'lodash/filter'
import isEmpty from 'lodash/isEmpty'
import { PAGES } from 'config'
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 { PlaylistTypes } from 'features/MatchPage/types'
import { FULL_GAME_KEY } from 'features/MatchPage/helpers/buildPlaylists'
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 { useAds } from 'components/Ads/hooks'
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'
import { useLexicsStore } from '../../../LexicsStore'
type PlayingData = {
player: {
id: number | null,
paramId: number | null,
},
team: {
id: number | null,
paramId: number | null,
},
}
type EpisodeInfo = {
episodesCount?: number,
paramName?: string,
playerOrTeamName?: string,
}
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 [isFullscreen, setIsFullScreen] = useState(false)
const [access, setAccess] = useState(true)
const [playingProgress, setPlayingProgress] = useState(0)
const [playingData, setPlayingData] = useState<PlayingData>(initPlayingData)
const [playingOrder, setPlaingOrder] = useState(0)
const [isPlayFilterEpisodes, setIsPlayingFiltersEpisodes] = useState(false)
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH)
const [circleAnimation, setCircleAnimation] = useState<TCircleAnimation>(initialCircleAnimation)
const [episodeInfo, setEpisodeInfo] = useState<EpisodeInfo>({
episodesCount: 0,
paramName: '',
playerOrTeamName: '',
})
const { suffix } = useLexicsStore()
const { profileId: matchId, sportType } = usePageParams()
const { ads } = useAds({
matchId,
sportType,
tournamentId: matchProfile?.tournament?.id,
})
useEffect(() => {
sessionStorage.removeItem('isFromLanding')
}, [])
const {
isFromLanding,
landingUrlFrom,
setIsFromLanding,
setLandingUrlFrom,
user,
userInfo,
} = useAuthStore()
const history = useHistory()
const {
close: hideProfileCard,
isOpen: profileCardShown,
open: showProfileCard,
} = useToggle(true)
const {
events,
handlePlaylistClick,
matchPlaylists,
selectedPlaylist,
setFullMatchPlaylistDuration,
} = useMatchData({ matchProfile, selectedTab })
const profile = matchProfile
const isPlayingEpisode = selectedPlaylist.id !== FULL_GAME_KEY
const isStatsPlaylist = selectedPlaylist.tab === Tabs.STATS
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 || history.length > 1) return
setLandingUrlFrom(window.location.pathname)
getLandingStatus({ matchId, sportType })
.then((data) => {
sessionStorage.setItem(
'landingData',
JSON.stringify({ ...data, defaultLanding: false }),
)
setIsFromLanding(false)
if (data.landing_id) redirectToUrl(`${PAGES.landing}/${data.landing_id}`)
})
.catch(() => {
getMatchInfo(sportType, matchId).then((data) => {
sessionStorage.setItem('landingData', JSON.stringify({
defaultLanding: true,
sportType,
tournamentId: data?.tournament.id,
}))
redirectToUrl(`
${PAGES.landing}/default
?season=${data?.season.name}
&tournament=${data?.tournament[`name_${suffix}`]}`)
})
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
setLandingUrlFrom,
isFromLanding,
landingUrlFrom,
matchId,
setIsFromLanding,
sportType,
user,
])
useEffect(() => {
getMatchInfo(sportType, matchId).then(
(info) => (info?.sport
// проверяем именно какой-то ключ в объекте,
// потому что, когда матча не существует, приходит - []
? setMatchProfile(info) : window.location.replace(PAGES.home)),
)
}, [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 disablePlayingStatsEpisodes = () => {
setStatsIsPlayinFiltersEpisodes(false)
setStatsWatchAllEpisodesTimer(false)
setStatsCircleAnimation(initialCircleAnimation)
setStatsPlaingOrder(0)
}
const disablePlayingPlaysEpisodes = () => {
setIsPlayingFiltersEpisodes(false)
setWatchAllEpisodesTimer(false)
setCircleAnimation(initialCircleAnimation)
setPlaingOrder(0)
}
const disablePlayingEpisodes = () => {
isStatsPlaylist ? disablePlayingStatsEpisodes() : disablePlayingPlaysEpisodes()
}
useEffect(() => {
if (selectedPlaylist.type !== PlaylistTypes.EVENT) {
disablePlayingStatsEpisodes()
disablePlayingPlaysEpisodes()
} else {
!isStatsPlaylist ? disablePlayingStatsEpisodes() : disablePlayingPlaysEpisodes()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedPlaylist])
const {
circleAnimation: statsCircleAnimation,
filteredEvents: statsFilteredEvents,
isExpanded,
isPlayersStatsFetching,
isPlayFilterEpisodes: isStatsPlayFilterEpisodes,
isTeamsStatsFetching,
playEpisodes: playStatsEpisodes,
playingOrder: statsPlaingOrder,
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,
selectedStatsTable,
selectedTab,
setIsTeamsStatsFetching,
statsType,
})
const {
beforeCloseTourCallback: beforeCloseTourCallbackPlayers,
getParams,
playersData,
playersStats,
} = usePlayersStats({
matchProfile,
playingProgress,
selectedStatsTable,
selectedTab,
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 = playingOrder === episodesToPlay.length
const currentOrder = order === 0 ? order : playingOrder
if (isLastEpisode || !episodesToPlay[currentOrder]) {
setIsPlayingFiltersEpisodes(false)
setPlaingOrder(0)
return
}
handlePlaylistClick({
playlist: episodesToPlay[currentOrder],
tab: Tabs.EVENTS,
})
setPlaingOrder(currentOrder + 1)
}
const playEpisodes = () => {
setPlayingData(initPlayingData)
setStatsWatchAllEpisodesTimer(true)
setStatsIsPlayinFiltersEpisodes(false)
setStatsCircleAnimation(initialCircleAnimation)
if (!watchAllEpisodesTimer) {
setWatchAllEpisodesTimer(true)
}
setIsPlayingFiltersEpisodes(true)
playNextEpisode(0)
}
return {
access,
activeEvents,
activeFirstTeamPlayers,
activeSecondTeamPlayers,
activeStatus,
ads,
allActionsToggle,
allPlayersToggle,
applyFilters,
beforeCloseTourCallback,
circleAnimation: isStatsPlaylist ? statsCircleAnimation : circleAnimation,
closePopup,
countOfFilters,
disablePlayingEpisodes,
episodeInfo,
events,
filteredEvents: isStatsPlaylist ? statsFilteredEvents : filteredEvents,
getFirstClickableParam,
getParams,
handlePlaylistClick,
hideProfileCard,
isAllActionsChecked,
isClickable,
isEmptyFilters,
isExpanded,
isFirstTeamPlayersChecked,
isFullscreen,
isLiveMatch,
isOpenFiltersPopup,
isPlayFilterEpisodes: isStatsPlaylist ? isStatsPlayFilterEpisodes : isPlayFilterEpisodes,
isPlayersStatsFetching,
isPlayingEpisode,
isSecondTeamPlayersChecked,
isStarted,
isTeamsStatsFetching,
likeImage,
likeToggle,
matchPlaylists,
playEpisodes,
playNextEpisode: isStatsPlaylist ? playStatsNextEpisode : playNextEpisode,
playStatsEpisodes,
playersData,
playersStats,
playingData,
playingOrder: isStatsPlaylist ? statsPlaingOrder : playingOrder,
playingProgress,
profile,
profileCardShown,
reduceTable,
reversedGroupEvents,
selectedPlaylist,
selectedStatsTable,
selectedTab,
setCircleAnimation: isStatsPlaylist ? setStatsCircleAnimation : setCircleAnimation,
setEpisodeInfo,
setFullMatchPlaylistDuration,
setIsFullScreen,
setIsPlayingFiltersEpisodes: isStatsPlaylist
? setStatsIsPlayinFiltersEpisodes
: setIsPlayersStatsFetching,
setMatchProfile,
setPlaingOrder: isStatsPlaylist ? setStatsPlaingOrder : setPlaingOrder,
setPlayingData,
setPlayingProgress,
setReversed,
setSelectedStatsTable,
setSelectedTab,
setStatsType,
setUnreversed,
setWatchAllEpisodesTimer: isStatsPlaylist
? setStatsWatchAllEpisodesTimer
: setWatchAllEpisodesTimer,
showProfileCard,
statsType,
teamsStats,
toggleActiveEvents,
toggleActivePlayers,
toggleIsExpanded,
togglePopup,
toggleStatsType,
tournamentData,
uniqEvents,
user,
watchAllEpisodesTimer: isStatsPlaylist ? statsWatchAllEpisodesTimer : watchAllEpisodesTimer,
}
}