feat(in-142): match stats tab

pull/11/head
Ruslan Khayrullin 3 years ago
parent ee3b93c622
commit 49403a6746
  1. 7
      src/features/MatchPage/components/FinishedMatch/index.tsx
  2. 8
      src/features/MatchPage/components/LiveMatch/hooks/index.tsx
  3. 8
      src/features/MatchPage/store/hooks/index.tsx
  4. 12
      src/features/MatchPage/store/hooks/useMatchData.tsx
  5. 57
      src/features/MatchPage/store/hooks/useTeamsStats.tsx
  6. 39
      src/features/MatchSidePlaylists/components/MatchPlaylists/index.tsx
  7. 0
      src/features/MatchSidePlaylists/components/Matches/components/VideoDate/index.tsx
  8. 0
      src/features/MatchSidePlaylists/components/Matches/components/VideoDate/styled.tsx
  9. 12
      src/features/MatchSidePlaylists/components/Matches/index.tsx
  10. 9
      src/features/MatchSidePlaylists/components/Matches/styled.tsx
  11. 2
      src/features/MatchSidePlaylists/components/PlayersPlaylists/styled.tsx
  12. 3
      src/features/MatchSidePlaylists/components/TabStats/hooks.tsx
  13. 4
      src/features/MatchSidePlaylists/components/TabStats/index.tsx
  14. 77
      src/features/MatchSidePlaylists/components/TabWatch/index.tsx
  15. 276
      src/features/MatchSidePlaylists/components/TeamsStats/index.tsx
  16. 30
      src/features/MatchSidePlaylists/components/TeamsStatsTable/hooks.tsx
  17. 93
      src/features/MatchSidePlaylists/components/TeamsStatsTable/index.tsx
  18. 17
      src/features/MatchSidePlaylists/components/TeamsStatsTable/styled.tsx
  19. 28
      src/features/MatchSidePlaylists/hooks.tsx
  20. 3
      src/features/MatchSidePlaylists/index.tsx
  21. 6
      src/features/MatchSidePlaylists/styled.tsx
  22. 3
      src/features/MultiSourcePlayer/hooks/index.tsx
  23. 4
      src/requests/getTeamsStats.tsx

@ -17,7 +17,11 @@ import { useMatchPageStore } from '../../store'
export const FinishedMatch = () => {
const [circleAnimation, setCircleAnimation] = useState<TCircleAnimation>(initialCircleAnimation)
const { isOpenPopup, profile } = useMatchPageStore()
const {
isOpenPopup,
profile,
setPlayingProgress,
} = useMatchPageStore()
const {
chapters,
closeSettingsPopup,
@ -51,6 +55,7 @@ export const FinishedMatch = () => {
isOpenPopup={isOpenPopup}
chapters={chapters}
onPlayingChange={onPlayingChange}
onPlayerProgressChange={setPlayingProgress}
profile={profile}
/>
<MatchDescription />

@ -21,6 +21,7 @@ export const useLiveMatch = () => {
profile,
selectedPlaylist,
setFullMatchPlaylistDuration,
setPlayingProgress,
} = useMatchPageStore()
const { profileId: matchId, sportType } = usePageParams()
const resume = useResumeUrlParam()
@ -45,7 +46,7 @@ export const useLiveMatch = () => {
} = usePlaylistLogger()
const {
onPlayerProgressChange,
onPlayerProgressChange: playerProgressChange,
onPlayingChange: notifyProgressLogger,
} = usePlayerProgressReporter()
@ -66,6 +67,11 @@ export const useLiveMatch = () => {
handlePlaylistClick(playlist, e)
}
const onPlayerProgressChange = (seconds: number, period = 0) => {
playerProgressChange(seconds, period)
setPlayingProgress(seconds * 1000)
}
return {
chapters,
isPlayFilterEpisodes,

@ -68,8 +68,12 @@ export const useMatchPage = () => {
fetchTeamsStats,
handlePlaylistClick,
matchPlaylists,
playingProgress,
selectedPlaylist,
setFullMatchPlaylistDuration,
setPlayingProgress,
setStatsType,
statsType,
teamsStats,
} = useMatchData(matchProfile)
@ -173,6 +177,7 @@ export const useMatchPage = () => {
plaingOrder,
playEpisodes,
playNextEpisode,
playingProgress,
profile,
profileCardShown,
resetEvents,
@ -182,10 +187,13 @@ export const useMatchPage = () => {
setFullMatchPlaylistDuration,
setIsPlayinFiltersEpisodes,
setPlaingOrder,
setPlayingProgress,
setReversed,
setStatsType,
setUnreversed,
setWatchAllEpisodesTimer,
showProfileCard,
statsType,
teamsStats,
toggleActiveEvents,
toggleActivePlayers,

@ -25,6 +25,7 @@ export const useMatchData = (profile: MatchInfo) => {
const { profileId: matchId, sportType } = usePageParams()
const { chapters } = useMatchPopupStore()
const [matchDuration, setMatchDuration] = useState(0)
const [playingProgress, setPlayingProgress] = useState(0)
const {
fetchMatchPlaylists,
handlePlaylistClick,
@ -34,7 +35,12 @@ export const useMatchData = (profile: MatchInfo) => {
setSelectedPlaylist,
} = useMatchPlaylists(profile)
const { events, fetchMatchEvents } = useEvents()
const { fetchTeamsStats, teamsStats } = useTeamsStats(profile)
const {
fetchTeamsStats,
setStatsType,
statsType,
teamsStats,
} = useTeamsStats(profile, playingProgress)
const fetchPlaylistsDebounced = useMemo(
() => debounce(fetchMatchPlaylists, MATCH_PLAYLISTS_DELAY),
@ -97,8 +103,12 @@ export const useMatchData = (profile: MatchInfo) => {
fetchTeamsStats,
handlePlaylistClick,
matchPlaylists,
playingProgress,
selectedPlaylist,
setFullMatchPlaylistDuration,
setPlayingProgress,
setStatsType,
statsType,
teamsStats,
}
}

@ -2,42 +2,33 @@ import {
useEffect,
useState,
useMemo,
useCallback,
} from 'react'
import flatMap from 'lodash/flatMap'
import reduce from 'lodash/reduce'
import includes from 'lodash/includes'
import throttle from 'lodash/throttle'
import type { MatchInfo } from 'requests'
import { getTeamsStats, TeamStatItem } from 'requests'
import { usePageParams } from 'hooks/usePageParams'
import { useLexicsConfig } from 'features/LexicsStore'
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'
export const useTeamsStats = (matchProfile: MatchInfo) => {
const REQUEST_DELAY = 3000
const STATS_POLL_INTERVAL = 30000
export const useTeamsStats = (matchProfile: MatchInfo, playingProgress: number) => {
const [statsType, setStatsType] = useState<StatsType>(StatsType.FINAL_STATS)
const [teamsStats, setTeamsStats] = useState<{
[teamId: string]: Array<TeamStatItem>,
}>({})
const { profileId: matchId, sportName } = usePageParams()
const lexics = useMemo(() => reduce<TeamStatItem, Array<number>>(
flatMap(teamsStats),
(acc, curr) => {
if (curr.param1?.lexic && !includes(acc, curr.param1.lexic)) {
acc.push(curr.param1.lexic)
}
return acc
},
[],
), [teamsStats])
const progressSec = Math.floor(playingProgress / 1000)
useLexicsConfig(lexics)
const isCurrentStats = statsType === StatsType.CURRENT_STATS
const fetchTeamsStats = useCallback((second?: number) => {
const fetchTeamsStats = useMemo(() => throttle((second?: number) => {
if (!sportName) return
getTeamsStats({
@ -45,14 +36,36 @@ export const useTeamsStats = (matchProfile: MatchInfo) => {
second,
sportName,
}).then(setTeamsStats)
}, [matchId, sportName])
}, REQUEST_DELAY), [matchId, sportName])
useEffect(() => {
let timer: ReturnType<typeof setInterval>
if (!isCurrentStats) {
fetchTeamsStats()
}
if (matchProfile?.live) {
timer = setInterval(() => {
if (isCurrentStats) return
fetchTeamsStats()
}, STATS_POLL_INTERVAL)
}
return () => clearInterval(timer)
}, [fetchTeamsStats, matchProfile?.live, isCurrentStats])
useEffect(() => {
fetchTeamsStats()
}, [fetchTeamsStats])
if (isCurrentStats) {
fetchTeamsStats(progressSec)
}
}, [fetchTeamsStats, progressSec, isCurrentStats])
return {
fetchTeamsStats,
setStatsType,
statsType,
teamsStats,
}
}

@ -1,8 +1,8 @@
import { useMemo } from 'react'
import type { ForwardedRef } from 'react'
import { forwardRef } from 'react'
import styled, { css } from 'styled-components/macro'
import filter from 'lodash/filter'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
@ -15,6 +15,8 @@ import { T9n } from 'features/T9n'
import { PlayButton } from '../PlayButton'
export const LIST_ITEM_INDENT = 12
type Props = {
live?: boolean,
onSelect?: (selectedMathPlaylist: PlaylistOption) => void,
@ -25,7 +27,7 @@ type Props = {
const List = styled.ul``
const Item = styled.li`
margin-bottom: 12px;
margin-bottom: ${LIST_ITEM_INDENT}px;
width: 100%;
height: 36px;
${isMobileDevice
@ -36,24 +38,17 @@ const Item = styled.li`
: ''};
`
export const MatchPlaylists = ({
live,
onSelect,
playlists,
selectedMathPlaylist,
}: Props) => {
const filteredPlayListByDuration = useMemo(() => (
filter(playlists, (playlist) => (
live
? Boolean(playlist.duration) || (playlist.id === 'full_game')
: Boolean(playlist.duration)
))
), [playlists, live])
return (
<List>
export const MatchPlaylists = forwardRef(
({
live,
onSelect,
playlists,
selectedMathPlaylist,
}: Props,
ref: ForwardedRef<HTMLUListElement>) => (
<List ref={ref}>
{
map(filteredPlayListByDuration, (playlist) => (
map(playlists, (playlist) => (
<Item key={playlist.id}>
<PlayButton
duration={playlist.duration}
@ -68,5 +63,5 @@ export const MatchPlaylists = ({
))
}
</List>
)
}
),
)

@ -23,13 +23,15 @@ import { VideoDate } from './components/VideoDate'
import { MatchesWrapper } from './styled'
type Props = {
additionalScrollHeight: number,
profile: MatchInfo,
tournamentData: TournamentData,
}
const formatDate = (date: Date) => format(date, 'yyyy-MM-dd')
export const TabVideo = ({
export const Matches = ({
additionalScrollHeight,
profile,
tournamentData,
}: Props) => {
@ -75,7 +77,7 @@ export const TabVideo = ({
const hasScroll = scrollHeight > clientHeight
setOverflow(hasScroll)
}, [ref, selectedDate])
}, [ref.current?.clientHeight, selectedDate])
if (tournamentData.matches.length <= 1) return null
@ -88,7 +90,11 @@ export const TabVideo = ({
profileDate={profileDate}
onDateClick={setSelectedDate}
/>
<MatchesWrapper ref={ref} hasScroll={overflow}>
<MatchesWrapper
ref={ref}
hasScroll={overflow}
additionalScrollHeight={additionalScrollHeight}
>
{
map(sortBy(matches, ({ live }) => !live), (match) => (
<MatchCard

@ -2,9 +2,14 @@ import styled, { css } from 'styled-components/macro'
import { customScrollbar } from 'features/Common'
import { isMobileDevice } from '../../../../config/userAgent'
export const MatchesWrapper = styled.div<{hasScroll?: boolean}>`
type MatchesWrapperProps = {
additionalScrollHeight: number,
hasScroll?: boolean,
}
export const MatchesWrapper = styled.div<MatchesWrapperProps>`
overflow-y: auto;
max-height: calc(100vh - 170px);
max-height: calc(100vh - 165px - ${({ additionalScrollHeight }) => additionalScrollHeight}px);
padding-right: ${({ hasScroll }) => (hasScroll ? '10px' : '')};
> * {

@ -28,6 +28,7 @@ export const PlayerAvatar = styled(ProfileLogo)`
`
export const Tabs = styled.div`
margin-top: -10px;
margin-bottom: 23px;
`
@ -38,6 +39,7 @@ type TabProps = {
export const Tab = styled.button<TabProps>`
position: relative;
border: none;
height: 34px;
padding: 0;
background-color: transparent;
font-size: 12px;

@ -5,10 +5,9 @@ import { useMatchPageStore } from 'features/MatchPage/store'
import { StatsType, Tabs } from './config'
export const useTabStats = () => {
const [statsType, setStatsType] = useState<StatsType>(StatsType.FINAL_STATS)
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.TEAMS)
const { fetchTeamsStats, teamsStats } = useMatchPageStore()
const { setStatsType, statsType } = useMatchPageStore()
const isFinalStatsType = statsType === StatsType.FINAL_STATS

@ -4,7 +4,7 @@ import { T9n } from 'features/T9n'
import { Tabs } from './config'
import { useTabStats } from './hooks'
import { PlayersTable } from '../PlayersTable'
import { TeamsStats } from '../TeamsStats'
import { TeamsStatsTable } from '../TeamsStatsTable'
import {
Container,
@ -17,7 +17,7 @@ import {
} from './styled'
const tabPanes = {
[Tabs.TEAMS]: TeamsStats,
[Tabs.TEAMS]: TeamsStatsTable,
[Tabs.TEAM1]: PlayersTable,
[Tabs.TEAM2]: PlayersTable,
}

@ -1,6 +1,11 @@
import { Fragment } from 'react'
import {
Fragment,
useMemo,
useRef,
} from 'react'
import size from 'lodash/size'
import filter from 'lodash/filter'
import type {
PlaylistOption,
@ -10,12 +15,13 @@ import type {
import type { MatchInfo } from 'requests'
import { DropdownSection } from '../DropdownSection'
import { MatchPlaylists } from '../MatchPlaylists'
import { MatchPlaylists, LIST_ITEM_INDENT } from '../MatchPlaylists'
import { SideInterviews } from '../SideInterviews'
import { TabVideo } from '../../components/TabVideo'
import { Matches } from '../Matches'
type Props = {
onSelect: (option: PlaylistOption) => void,
playListFilter: number,
playlists: Playlists,
profile: MatchInfo,
selectedPlaylist?: PlaylistOption,
@ -24,31 +30,50 @@ type Props = {
export const TabWatch = ({
onSelect,
playListFilter,
playlists,
profile,
selectedPlaylist,
tournamentData,
}: Props) => (
<Fragment>
<MatchPlaylists
playlists={playlists.match}
selectedMathPlaylist={selectedPlaylist}
onSelect={onSelect}
live={profile?.live}
/>
<DropdownSection
itemsCount={size(playlists.interview)}
title={playlists.lexics?.interview}
>
<SideInterviews
interviews={playlists.interview}
selectedMathPlaylist={selectedPlaylist}
onSelect={onSelect}
}: Props) => {
const matchPlaylistsRef = useRef<HTMLUListElement>(null)
const additionalScrollHeight = (matchPlaylistsRef.current?.clientHeight || 0) + LIST_ITEM_INDENT
const filteredPlayListByDuration = useMemo(() => (
filter(playlists.match, (playlist) => (
profile?.live
? Boolean(playlist.duration) || (playlist.id === 'full_game')
: Boolean(playlist.duration)
))
), [playlists.match, profile?.live])
return (
<Fragment>
{playListFilter > 1 && (
<MatchPlaylists
ref={matchPlaylistsRef}
playlists={filteredPlayListByDuration}
selectedMathPlaylist={selectedPlaylist}
onSelect={onSelect}
live={profile?.live}
/>
)}
<DropdownSection
itemsCount={size(playlists.interview)}
title={playlists.lexics?.interview}
>
<SideInterviews
interviews={playlists.interview}
selectedMathPlaylist={selectedPlaylist}
onSelect={onSelect}
/>
</DropdownSection>
<Matches
profile={profile}
tournamentData={tournamentData}
additionalScrollHeight={additionalScrollHeight}
/>
</DropdownSection>
<TabVideo
profile={profile}
tournamentData={tournamentData}
/>
</Fragment>
)
</Fragment>
)
}

@ -1,276 +0,0 @@
import {
Container,
Row,
TeamShortName,
ParamValueContainer,
ParamValue,
ParamTitle,
} from './styled'
export const TeamsStats = () => (
<Container>
<Row>
<TeamShortName>DIN</TeamShortName>
<TeamShortName>SPA</TeamShortName>
</Row>
<Row>
<ParamValueContainer>
<ParamValue clickable>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue clickable>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
<Row>
<ParamValueContainer>
<ParamValue>90</ParamValue>
</ParamValueContainer>
<ParamTitle>Points</ParamTitle>
<ParamValue>123</ParamValue>
</Row>
</Container>
)

@ -0,0 +1,30 @@
import isNumber from 'lodash/isNumber'
import find from 'lodash/find'
import type { Param } from 'requests'
import { useMatchPageStore } from 'features/MatchPage/store'
export const useTeamsStatsTable = () => {
const { profile, teamsStats } = useMatchPageStore()
const getDisplayedValue = (val: any) => (
isNumber(val) ? val : '-'
)
const getStatItemById = (paramId: number) => {
if (!profile) return null
return find(teamsStats[profile?.team2.id], ({ param1 }) => param1.id === paramId) || null
}
const isClickable = (param: Param) => (
isNumber(param.val) && param.clickable
)
return {
getDisplayedValue,
getStatItemById,
isClickable,
}
}

@ -0,0 +1,93 @@
import { Fragment } from 'react'
import map from 'lodash/map'
import { useMatchPageStore } from 'features/MatchPage/store'
import { useLexicsStore } from 'features/LexicsStore'
import { useTeamsStatsTable } from './hooks'
import {
Container,
Row,
TeamShortName,
ParamValueContainer,
ParamValue,
StatItemTitle,
Divider,
} from './styled'
export const TeamsStatsTable = () => {
const { profile, teamsStats } = useMatchPageStore()
const {
getDisplayedValue,
getStatItemById,
isClickable,
} = useTeamsStatsTable()
const { lang } = useLexicsStore()
if (!profile) return null
return (
<Container>
<Row>
<TeamShortName
nameObj={profile.team1}
prefix='abbrev_'
/>
<TeamShortName
nameObj={profile.team2}
prefix='abbrev_'
/>
</Row>
{map(teamsStats[profile.team1.id], (team1StatItem) => {
const team2StatItem = getStatItemById(team1StatItem.param1.id)
const statItemTitle = team1StatItem[`name_${lang === 'ru' ? 'ru' : 'en'}`]
return (
<Row key={team1StatItem.param1.id}>
<ParamValueContainer>
<ParamValue
clickable={isClickable(team1StatItem.param1)}
>
{getDisplayedValue(team1StatItem.param1.val)}
</ParamValue>
{team1StatItem.param2 && (
<Fragment>
<Divider>/</Divider>
<ParamValue
clickable={isClickable(team1StatItem.param2)}
>
{getDisplayedValue(team1StatItem.param2.val)}
</ParamValue>
</Fragment>
)}
</ParamValueContainer>
<StatItemTitle>{statItemTitle}</StatItemTitle>
{team2StatItem && (
<ParamValueContainer>
<ParamValue
clickable={isClickable(team2StatItem.param1)}
>
{getDisplayedValue(team2StatItem.param1.val)}
</ParamValue>
{team2StatItem.param2 && (
<Fragment>
<Divider>/</Divider>
<ParamValue
clickable={isClickable(team2StatItem.param2)}
>
{getDisplayedValue(team2StatItem.param2.val)}
</ParamValue>
</Fragment>
)}
</ParamValueContainer>
)}
</Row>
)
})}
</Container>
)
}

@ -1,11 +1,13 @@
import styled, { css } from 'styled-components/macro'
import { Name } from 'features/Name'
export const Container = styled.div`
width: 100%;
font-size: 11px;
`
export const TeamShortName = styled.span`
export const TeamShortName = styled(Name)`
color: ${({ theme }) => theme.colors.white};
letter-spacing: -0.078px;
text-transform: uppercase;
@ -33,7 +35,10 @@ type TParamValue = {
clickable?: boolean,
}
export const ParamValue = styled.span<TParamValue>`
export const ParamValue = styled.span.attrs(({ clickable }: TParamValue) => ({
...clickable && { tabIndex: 0 },
}))<TParamValue>`
font-weight: 600;
color: ${({ clickable, theme }) => (clickable ? '#5EB2FF' : theme.colors.white)};
${({ clickable }) => (clickable
@ -43,10 +48,16 @@ export const ParamValue = styled.span<TParamValue>`
: '')}
`
export const ParamTitle = styled.span`
export const StatItemTitle = styled.span`
color: ${({ theme }) => theme.colors.white};
letter-spacing: -0.078px;
text-transform: uppercase;
font-weight: 600;
opacity: 0.5;
`
export const Divider = styled.span`
color: ${({ theme }) => theme.colors.white};
opacity: 0.5;
font-weight: 600;
`

@ -18,20 +18,23 @@ export const useMatchSidePlaylists = () => {
events,
matchPlaylists: playlists,
teamsStats,
tournamentData,
} = useMatchPageStore()
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH)
const isWatchTabVisible = useMemo(() => {
const playListFilter = reduce(
playlists.match,
(acc, item) => {
let result = acc
if (item.duration) result++
return result
},
0,
)
return playListFilter > 1
}, [playlists])
const playListFilter = useMemo(() => reduce(
playlists.match,
(acc, item) => {
let result = acc
if (item.duration) result++
return result
},
0,
), [playlists.match])
const isWatchTabVisible = useMemo(() => (
playListFilter > 1 || tournamentData.matchDates.length > 1
), [playListFilter, tournamentData.matchDates.length])
const isEventTabVisible = useMemo(() => (
events.length > 0
@ -85,6 +88,7 @@ export const useMatchSidePlaylists = () => {
isStatsTabVisible,
isWatchTabVisible,
onTabClick: setSelectedTab,
playListFilter,
selectedTab,
}
}

@ -63,6 +63,7 @@ export const MatchSidePlaylists = ({
isStatsTabVisible,
isWatchTabVisible,
onTabClick,
playListFilter,
selectedTab,
} = useMatchSidePlaylists()
@ -148,6 +149,7 @@ export const MatchSidePlaylists = ({
<Container
hasScroll={hasTabPaneScroll}
ref={tabPaneContainerRef}
forWatchTab={selectedTab === Tabs.WATCH}
>
<TabPane
setCircleAnimation={setCircleAnimation}
@ -157,6 +159,7 @@ export const MatchSidePlaylists = ({
playlists={playlists}
profile={profile}
selectedPlaylist={selectedPlaylist}
playListFilter={playListFilter}
/>
</Container>
</Wrapper>

@ -98,7 +98,7 @@ export const TabTitle = styled(T9n)`
`
type TContainer = {
forVideoTab?: boolean,
forWatchTab?: boolean,
hasScroll: boolean,
}
@ -106,8 +106,8 @@ export const Container = styled.div<TContainer>`
width: 320px;
margin-top: 23px;
max-height: calc(100vh - 130px);
overflow-y: ${({ forVideoTab }) => (forVideoTab ? 'hidden' : 'auto')};
padding-right: ${({ forVideoTab }) => (forVideoTab ? '0' : '')};
overflow-y: ${({ forWatchTab }) => (forWatchTab ? 'hidden' : 'auto')};
padding-right: ${({ forWatchTab }) => (forWatchTab ? '0' : '')};
padding-left: 14px;
padding-right: ${({ hasScroll }) => (hasScroll ? '10px' : '')};

@ -56,6 +56,7 @@ export type Props = {
chapters: Chapters,
isOpenPopup?: boolean,
onError?: () => void,
onPlayerProgressChange?: (ms: number) => void,
onPlayingChange: (playing: boolean) => void,
profile: MatchInfo,
setCircleAnimation: TSetCircleAnimation,
@ -64,6 +65,7 @@ export type Props = {
export const useMultiSourcePlayer = ({
chapters,
onError,
onPlayerProgressChange,
onPlayingChange,
setCircleAnimation,
}: Props) => {
@ -201,6 +203,7 @@ export const useMultiSourcePlayer = ({
timeForStatistics.current = (value + chapter.startMs) / 1000
setPlayerState({ playedProgress: value })
onPlayerProgressChange?.(playedMs + chapter.startMs)
}
const onEnded = () => {

@ -2,7 +2,7 @@ import isUndefined from 'lodash/isUndefined'
import { callApi } from 'helpers'
type Param = {
export type Param = {
clickable: boolean,
data_type: string,
id: number,
@ -10,7 +10,7 @@ type Param = {
markers: Array<number>,
name_en: string,
name_ru: string,
val: number,
val: number | null,
}
export type TeamStatItem = {

Loading…
Cancel
Save