Ott 717 match popup changes (#310)

* fix(717): popup player settings (#308)

* Ott 717 part 2 (#309)

* fix(717): component changes

* fix(717): empty episodes

* fix(717): style fix

* refactor(717): renamed playlistData to episodes
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 474e1da8fb
commit 9bf368080c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/config/lexics/indexLexics.tsx
  2. 5
      src/features/Common/Button/styled.tsx
  3. 25
      src/features/MatchPage/helpers/buildChapters.tsx
  4. 6
      src/features/MatchPage/helpers/buildPlaylists.tsx
  5. 27
      src/features/MatchPage/hooks/useChapters.tsx
  6. 20
      src/features/MatchPage/hooks/useEpisodes.tsx
  7. 12
      src/features/MatchPage/hooks/useMatchPage.tsx
  8. 20
      src/features/MatchPage/hooks/usePlaylists.tsx
  9. 6
      src/features/MatchPage/hooks/useRouteState.tsx
  10. 4
      src/features/MatchPage/types.tsx
  11. 24
      src/features/MatchPopup/components/FinishedMatchPopup/index.tsx
  12. 1
      src/features/MatchPopup/components/FinishedMatchPopup/styled.tsx
  13. 2
      src/features/MatchPopup/components/FinishedPlaylistPage/index.tsx
  14. 38
      src/features/MatchPopup/components/MatchSettingsPage/index.tsx
  15. 2
      src/features/MatchPopup/components/PlayerActions/styled.tsx
  16. 39
      src/features/MatchPopup/components/PlayerSettingsPage/index.tsx
  17. 13
      src/features/MatchPopup/components/PlayerSettingsPage/styled.tsx
  18. 2
      src/features/MatchPopup/components/PlayersList/index.tsx
  19. 6
      src/features/MatchPopup/components/SettingsButton/index.tsx
  20. 22
      src/features/MatchPopup/components/SettingsDesktop/index.tsx
  21. 1
      src/features/MatchPopup/index.tsx
  22. 36
      src/features/MatchPopup/store/hooks/index.tsx
  23. 42
      src/features/MatchPopup/store/hooks/usePlayerClickHandler.tsx
  24. 54
      src/features/MatchPopup/store/hooks/usePopupNavigation.tsx
  25. 5
      src/features/MatchPopup/types.tsx
  26. 2
      src/features/MatchSidePlaylists/components/PlayersPlaylists/index.tsx
  27. 4
      src/features/PopupComponents/Header/index.tsx
  28. 4
      src/requests/getMatchPlaylists.tsx
  29. 4
      src/requests/getPlayerPlaylists.tsx

@ -17,6 +17,7 @@ const matchPopupLexics = {
team_players: 13398, team_players: 13398,
watch_from: 13022, watch_from: 13022,
watch_live_stream: 13020, watch_live_stream: 13020,
watch_players_episodes: 14052,
} }
const buyMatchPopupLexics = { const buyMatchPopupLexics = {

@ -4,7 +4,7 @@ import { devices } from 'config/devices'
const baseButtonStyles = css` const baseButtonStyles = css`
width: 272px; width: 272px;
height: 48px; height: 50px;
border-width: 0.7px; border-width: 0.7px;
border-style: solid; border-style: solid;
border-radius: 2px; border-radius: 2px;
@ -37,7 +37,8 @@ export const solidButtonStyles = css`
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;
border-color: transparent; border-color: transparent;
background: ${({ theme: { colors } }) => colors.primary}; background-color: #294FC4;
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
/* TODO: удалить медиа запросы из стайледа, /* TODO: удалить медиа запросы из стайледа,
добавить специфичные юз кейсу правила добавить специфичные юз кейсу правила

@ -10,12 +10,15 @@ import groupBy from 'lodash/groupBy'
import type { import type {
Videos, Videos,
PlaylistData, Episodes,
Episode, Episode,
} from 'requests' } from 'requests'
import type { Chapters, Urls } from 'features/MultiSourcePlayer/types' import type { Chapters, Urls } from 'features/MultiSourcePlayer/types'
import type { PlaylistOption } from '../types'
import { FULL_GAME_KEY } from './buildPlaylists'
const getUniquePeriods = (videos: Videos) => uniq(map(videos, ({ period }) => period)) const getUniquePeriods = (videos: Videos) => uniq(map(videos, ({ period }) => period))
type Video = { type Video = {
@ -88,10 +91,10 @@ const getEpisodeUrls = (urls: Urls, episode: Episode) => reduce(
{}, {},
) )
const getPlaylistChapters = (videos: Array<Video>, playlists: PlaylistData) => { const getPlaylistChapters = (videos: Array<Video>, episodes: Episodes) => {
const groupedByPeriods = groupBy(videos, ({ period }) => period) const groupedByPeriods = groupBy(videos, ({ period }) => period)
return reduce( return reduce(
playlists, episodes,
(acc: Chapters, episode) => { (acc: Chapters, episode) => {
const video = groupedByPeriods[episode.h]?.[0] const video = groupedByPeriods[episode.h]?.[0]
if (!video || episode.s >= episode.e) return acc if (!video || episode.s >= episode.e) return acc
@ -112,10 +115,20 @@ const getPlaylistChapters = (videos: Array<Video>, playlists: PlaylistData) => {
) )
} }
export const buildChapters = (videos: Videos, playlists: PlaylistData) => { type Args = {
episodes: Episodes,
selectedPlaylist?: PlaylistOption,
videos: Videos,
}
export const buildChapters = ({
episodes,
selectedPlaylist,
videos,
}: Args) => {
const periods = getUniquePeriods(videos) const periods = getUniquePeriods(videos)
const highQualityVideos = getVideoByPeriods(videos, periods) const highQualityVideos = getVideoByPeriods(videos, periods)
return isEmpty(playlists) return selectedPlaylist?.id === FULL_GAME_KEY
? getFullMatchChapters(highQualityVideos) ? getFullMatchChapters(highQualityVideos)
: getPlaylistChapters(highQualityVideos, playlists) : getPlaylistChapters(highQualityVideos, episodes)
} }

@ -10,17 +10,19 @@ import type {
} from 'features/MatchPage/types' } from 'features/MatchPage/types'
import { PlaylistTypes } from 'features/MatchPage/types' import { PlaylistTypes } from 'features/MatchPage/types'
const matchKeys = [ const MATCH_KEYS = [
'full_game', 'full_game',
'highlights', 'highlights',
'ball_in_play', 'ball_in_play',
'goals', 'goals',
] as const ] as const
export const FULL_GAME_KEY = MATCH_KEYS[0]
const getMatchPlaylists = (matchPlaylists: MatchPlaylists | null): MatchPlaylistOptions => { const getMatchPlaylists = (matchPlaylists: MatchPlaylists | null): MatchPlaylistOptions => {
if (!matchPlaylists) return [] if (!matchPlaylists) return []
return map(matchKeys, (key) => { return map(MATCH_KEYS, (key) => {
const playlist = matchPlaylists[key] const playlist = matchPlaylists[key]
const lexic = matchPlaylists.lexics[key] const lexic = matchPlaylists.lexics[key]
return { return {

@ -4,14 +4,25 @@ import {
useState, useState,
} from 'react' } from 'react'
import type { PlaylistData, Videos } from 'requests' import type { Episodes, Videos } from 'requests'
import { getVideos } from 'requests' import { getVideos } from 'requests'
import { usePageId, useSportNameParam } from 'hooks' import { usePageId, useSportNameParam } from 'hooks'
import type { PlaylistOption } from '../types'
import { buildChapters } from '../helpers/buildChapters' import { buildChapters } from '../helpers/buildChapters'
export const useChapters = (isFinishedMatch: boolean, playlist: PlaylistData) => { type Args = {
episodes: Episodes,
isFinishedMatch: boolean,
selectedPlaylist?: PlaylistOption,
}
export const useChapters = ({
episodes,
isFinishedMatch,
selectedPlaylist,
}: Args) => {
const [videos, setVideos] = useState<Videos>([]) const [videos, setVideos] = useState<Videos>([])
const { sportType } = useSportNameParam() const { sportType } = useSportNameParam()
const matchId = usePageId() const matchId = usePageId()
@ -27,8 +38,16 @@ export const useChapters = (isFinishedMatch: boolean, playlist: PlaylistData) =>
]) ])
const chapters = useMemo( const chapters = useMemo(
() => buildChapters(videos, playlist), () => buildChapters({
[playlist, videos], episodes,
selectedPlaylist,
videos,
}),
[
selectedPlaylist,
episodes,
videos,
],
) )
return { chapters } return { chapters }

@ -4,23 +4,23 @@ import {
useEffect, useEffect,
} from 'react' } from 'react'
import { getPlayerPlaylists, PlaylistData } from 'requests' import { getPlayerPlaylists, Episodes } from 'requests'
import { usePageId, useSportNameParam } from 'hooks' import { usePageId, useSportNameParam } from 'hooks'
import { PlaylistOption, PlaylistTypes } from 'features/MatchPage/types' import { PlaylistOption, PlaylistTypes } from 'features/MatchPage/types'
type Args = { type Args = {
initialPlaylistData?: PlaylistData, initialEpisodes?: Episodes,
initialSelectedPlaylist?: PlaylistOption, initialSelectedPlaylist?: PlaylistOption,
} }
export const usePlaylistsData = ({ initialPlaylistData, initialSelectedPlaylist }: Args) => { export const useEpisodes = ({ initialEpisodes, initialSelectedPlaylist }: Args) => {
const [playlistData, setPlaylistData] = useState(initialPlaylistData || []) const [episodes, setEpisodes] = useState(initialEpisodes || [])
const { sportType } = useSportNameParam() const { sportType } = useSportNameParam()
const matchId = usePageId() const matchId = usePageId()
const fetchPlaylists = useCallback((selectedPlaylist: PlaylistOption) => { const fetchEpisodes = useCallback((selectedPlaylist: PlaylistOption) => {
if (!selectedPlaylist) return if (!selectedPlaylist) return
if (selectedPlaylist.type === PlaylistTypes.PLAYER) { if (selectedPlaylist.type === PlaylistTypes.PLAYER) {
@ -28,17 +28,17 @@ export const usePlaylistsData = ({ initialPlaylistData, initialSelectedPlaylist
matchId, matchId,
playerId: selectedPlaylist.id, playerId: selectedPlaylist.id,
sportType, sportType,
}).then(setPlaylistData) }).then(setEpisodes)
} else if (selectedPlaylist.type === PlaylistTypes.MATCH) { } else if (selectedPlaylist.type === PlaylistTypes.MATCH) {
setPlaylistData(selectedPlaylist.data) setEpisodes(selectedPlaylist.data)
} }
}, [matchId, sportType]) }, [matchId, sportType])
useEffect(() => { useEffect(() => {
if (initialSelectedPlaylist?.type === PlaylistTypes.MATCH) { if (initialSelectedPlaylist?.type === PlaylistTypes.MATCH) {
fetchPlaylists(initialSelectedPlaylist) fetchEpisodes(initialSelectedPlaylist)
} }
}, [initialSelectedPlaylist, fetchPlaylists]) }, [initialSelectedPlaylist, fetchEpisodes])
return { fetchPlaylists, playlistData } return { episodes, fetchEpisodes }
} }

@ -14,19 +14,19 @@ import { useRouteState } from './useRouteState'
export const useMatchPage = () => { export const useMatchPage = () => {
const { closePopup } = useMatchPopupStore() const { closePopup } = useMatchPopupStore()
const { initialPlaylistData, initialSelectedPlaylist } = useRouteState() const { initialEpisodes, initialSelectedPlaylist } = useRouteState()
const [isFinishedMatch, setFinishedMatch] = useState(Boolean(initialSelectedPlaylist)) const [isFinishedMatch, setFinishedMatch] = useState(Boolean(initialSelectedPlaylist))
const [liveVideos, setLiveVideos] = useState<LiveVideos>([]) const [liveVideos, setLiveVideos] = useState<LiveVideos>([])
const { sportType } = useSportNameParam() const { sportType } = useSportNameParam()
const matchId = usePageId() const matchId = usePageId()
const { const {
episodes,
onPlaylistSelect, onPlaylistSelect,
playlistData,
playlists, playlists,
selectedPlaylist, selectedPlaylist,
} = usePlaylists({ } = usePlaylists({
initialPlaylistData, initialEpisodes,
initialSelectedPlaylist, initialSelectedPlaylist,
isFinishedMatch, isFinishedMatch,
}) })
@ -53,7 +53,11 @@ export const useMatchPage = () => {
playlists, playlists,
selectedPlaylist, selectedPlaylist,
url: liveVideos[0] || '', url: liveVideos[0] || '',
...useChapters(isFinishedMatch, playlistData), ...useChapters({
episodes,
isFinishedMatch,
selectedPlaylist,
}),
...useLastPlayPosition(), ...useLastPlayPosition(),
} }
} }

@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
import { getMatchPlaylists, PlaylistData } from 'requests' import { getMatchPlaylists, Episodes } from 'requests'
import { usePageId, useSportNameParam } from 'hooks' import { usePageId, useSportNameParam } from 'hooks'
@ -10,7 +10,7 @@ import type { PlaylistOption, Playlists } from 'features/MatchPage/types'
import { usePlaylistLexics } from 'features/MatchPopup/store/hooks/usePlaylistLexics' import { usePlaylistLexics } from 'features/MatchPopup/store/hooks/usePlaylistLexics'
import { buildPlaylists } from '../helpers/buildPlaylists' import { buildPlaylists } from '../helpers/buildPlaylists'
import { usePlaylistsData } from './usePlaylistData' import { useEpisodes } from './useEpisodes'
const initialPlaylists: Playlists = { const initialPlaylists: Playlists = {
interview: [], interview: [],
@ -22,13 +22,13 @@ const initialPlaylists: Playlists = {
} }
type Args = { type Args = {
initialPlaylistData?: PlaylistData, initialEpisodes?: Episodes,
initialSelectedPlaylist?: PlaylistOption, initialSelectedPlaylist?: PlaylistOption,
isFinishedMatch: boolean, isFinishedMatch: boolean,
} }
export const usePlaylists = ({ export const usePlaylists = ({
initialPlaylistData, initialEpisodes,
initialSelectedPlaylist, initialSelectedPlaylist,
isFinishedMatch, isFinishedMatch,
}: Args) => { }: Args) => {
@ -39,10 +39,10 @@ export const usePlaylists = ({
const matchId = usePageId() const matchId = usePageId()
const { const {
fetchPlaylists, episodes,
playlistData, fetchEpisodes,
} = usePlaylistsData({ } = useEpisodes({
initialPlaylistData, initialEpisodes,
initialSelectedPlaylist, initialSelectedPlaylist,
}) })
@ -72,12 +72,12 @@ export const usePlaylists = ({
const onPlaylistSelect = (option: PlaylistOption) => { const onPlaylistSelect = (option: PlaylistOption) => {
if (option === selectedPlaylist) return if (option === selectedPlaylist) return
setSelectedPlaylist(option) setSelectedPlaylist(option)
fetchPlaylists(option) fetchEpisodes(option)
} }
return { return {
episodes,
onPlaylistSelect, onPlaylistSelect,
playlistData,
playlists, playlists,
selectedPlaylist, selectedPlaylist,
} }

@ -1,7 +1,7 @@
import { useEffect } from 'react' import { useEffect } from 'react'
import { useHistory, useLocation } from 'react-router' import { useHistory, useLocation } from 'react-router'
import type { PlaylistData } from 'requests' import type { Episodes } from 'requests'
import type { PlaylistOption } from 'features/MatchPage/types' import type { PlaylistOption } from 'features/MatchPage/types'
@ -9,7 +9,7 @@ export type RouteState = {
/** /**
* Данные плейлиста если был выбран игрок * Данные плейлиста если был выбран игрок
*/ */
playlistData?: PlaylistData, episodes?: Episodes,
/** /**
* Выбранный плейлист на попапе матчей * Выбранный плейлист на попапе матчей
@ -31,7 +31,7 @@ export const useRouteState = () => {
}, [history]) }, [history])
return { return {
initialPlaylistData: state?.playlistData, initialEpisodes: state?.episodes,
initialSelectedPlaylist: state?.selectedPlaylist, initialSelectedPlaylist: state?.selectedPlaylist,
} }
} }

@ -1,4 +1,4 @@
import type { Lexics, PlaylistData } from 'requests' import type { Lexics, Episodes } from 'requests'
export enum PlaylistTypes { export enum PlaylistTypes {
MATCH, MATCH,
@ -7,7 +7,7 @@ export enum PlaylistTypes {
} }
export type MatchPlaylistOption = { export type MatchPlaylistOption = {
data: PlaylistData, data: Episodes,
duration?: number, duration?: number,
id: string, id: string,
lexic: number, lexic: number,

@ -2,13 +2,20 @@ import { Fragment } from 'react'
import { Background } from 'features/Background' import { Background } from 'features/Background'
import { MediaQuery } from 'features/MediaQuery' import { MediaQuery } from 'features/MediaQuery'
import { useMatchPopupStore } from 'features/MatchPopup'
import { SettingsPage } from '../../components/SettingsPage' import { useMatchPopupStore } from '../../store'
import { FinishedPlaylistPage } from '../../components/FinishedPlaylistPage' import { MatchSettingsPage } from '../MatchSettingsPage'
import { PlayerSettingsPage } from '../PlayerSettingsPage'
import { FinishedPlaylistPage } from '../FinishedPlaylistPage'
import { PopupPages } from '../../types' import { PopupPages } from '../../types'
import { Modal } from './styled' import { Modal } from './styled'
const components = {
[PopupPages.PLAYLIST]: FinishedPlaylistPage,
[PopupPages.PLAYER_SETTINGS]: PlayerSettingsPage,
[PopupPages.MATCH_SETTINGS]: MatchSettingsPage,
}
export const FinishedMatchPopup = () => { export const FinishedMatchPopup = () => {
const { const {
closePopup, closePopup,
@ -17,11 +24,10 @@ export const FinishedMatchPopup = () => {
page, page,
} = useMatchPopupStore() } = useMatchPopupStore()
const showPopup = isOpen && Boolean(matchPlaylists) if (!page) return null
const pageElement = page === PopupPages.PLAYLIST const showPopup = isOpen && Boolean(matchPlaylists)
? <FinishedPlaylistPage /> const Component = components[page]
: <SettingsPage />
return ( return (
<Fragment> <Fragment>
@ -31,7 +37,7 @@ export const FinishedMatchPopup = () => {
isOpen={showPopup} isOpen={showPopup}
withCloseButton={false} withCloseButton={false}
> >
{pageElement} <Component />
</Modal> </Modal>
</MediaQuery> </MediaQuery>
@ -41,7 +47,7 @@ export const FinishedMatchPopup = () => {
withCloseButton={false} withCloseButton={false}
> >
<Background> <Background>
{pageElement} <Component />
</Background> </Background>
</Modal> </Modal>
</MediaQuery> </MediaQuery>

@ -10,7 +10,6 @@ export const Modal = styled(BaseModal)`
${ModalWindow} { ${ModalWindow} {
width: 1222px; width: 1222px;
height: 818px;
padding: 20px 0; padding: 20px 0;
background-color: #3F3F3F; background-color: #3F3F3F;
border-radius: 5px; border-radius: 5px;

@ -39,7 +39,7 @@ export const FinishedPlaylistPage = () => {
&& !isEmpty(matchPlaylists?.players.team2) && !isEmpty(matchPlaylists?.players.team2)
) )
return ( return (
<Content> <Content height={778}>
<Header> <Header>
<MediaQuery maxDevice='mobile'> <MediaQuery maxDevice='mobile'>
<HeaderActions position='left'> <HeaderActions position='left'>

@ -0,0 +1,38 @@
import { MediaQuery } from 'features/MediaQuery'
import { T9n } from 'features/T9n'
import {
CloseButton,
Header,
HeaderActions,
HeaderTitle,
} from 'features/PopupComponents'
import { useMatchPopupStore } from '../../store'
import { BackButton } from '../BackButton'
import { Content } from '../../styled'
export const MatchSettingsPage = () => {
const { closePopup } = useMatchPopupStore()
return (
<Content height={778}>
<Header>
<HeaderActions position='left'>
<BackButton />
</HeaderActions>
<MediaQuery maxDevice='mobile'>
<HeaderTitle>
<T9n t='match_settings' />
</HeaderTitle>
</MediaQuery>
<MediaQuery minDevice='tablet'>
<HeaderActions position='right'>
<CloseButton onClick={closePopup} />
</HeaderActions>
</MediaQuery>
</Header>
</Content>
)
}

@ -44,7 +44,7 @@ export const List = styled.ul`
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 20px; margin-top: 20px;
height: 262px; height: 264px;
overflow-y: auto; overflow-y: auto;
@media ${devices.mobile} { @media ${devices.mobile} {

@ -1,6 +1,7 @@
import styled from 'styled-components/macro' import { MDASH } from 'config'
import { MediaQuery } from 'features/MediaQuery' import { MediaQuery } from 'features/MediaQuery'
import { Name } from 'features/Name'
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { import {
CloseButton, CloseButton,
@ -14,30 +15,22 @@ import { BackButton } from '../BackButton'
import { SettingsDesktop } from '../SettingsDesktop' import { SettingsDesktop } from '../SettingsDesktop'
import { SettingsMobile } from '../SettingsMobile' import { SettingsMobile } from '../SettingsMobile'
import { Content } from '../../styled' import { Content } from '../../styled'
import { TitleWrapper, TeamNames } from './styled'
const ButtonLabel = styled(T9n)` export const PlayerSettingsPage = () => {
display: flex; const {
align-items: center; closePopup,
font-weight: normal; match,
font-size: 18px; selectedPlayer,
line-height: 21px; } = useMatchPopupStore()
color: rgba(255, 255, 255, 0.5);
`
export const SettingsPage = () => { if (!match) return null
const { closePopup } = useMatchPopupStore()
return ( return (
<Content height={818}> <Content>
<Header> <Header>
<HeaderActions <HeaderActions position='left'>
position='left'
marginLeft={15}
>
<BackButton /> <BackButton />
<MediaQuery minDevice='tablet'>
<ButtonLabel t='go_back_to_match' />
</MediaQuery>
</HeaderActions> </HeaderActions>
<MediaQuery maxDevice='mobile'> <MediaQuery maxDevice='mobile'>
@ -50,6 +43,14 @@ export const SettingsPage = () => {
<HeaderActions position='right'> <HeaderActions position='right'>
<CloseButton onClick={closePopup} /> <CloseButton onClick={closePopup} />
</HeaderActions> </HeaderActions>
<TitleWrapper>
{selectedPlayer && <Name nameObj={selectedPlayer} />}
<TeamNames>
<Name nameObj={match.team1} />
{` ${MDASH} `}
<Name nameObj={match.team2} />
</TeamNames>
</TitleWrapper>
</MediaQuery> </MediaQuery>
</Header> </Header>

@ -0,0 +1,13 @@
import styled from 'styled-components/macro'
import { HeaderTitle } from 'features/PopupComponents'
export const TitleWrapper = styled(HeaderTitle)`
display: flex;
flex-direction: column;
line-height: 32px;
`
export const TeamNames = styled.span`
font-weight: normal;
`

@ -41,7 +41,7 @@ export const PlayersList = ({
{ {
map(players, (player) => ( map(players, (player) => (
<Item key={player.id} isReady={allLoaded}> <Item key={player.id} isReady={allLoaded}>
<Button onClick={() => handlePlayerClick(player)}> <Button onClick={(e) => handlePlayerClick(player, e)}>
<PlayerPhoto> <PlayerPhoto>
<Logo <Logo
id={player.id} id={player.id}

@ -1,6 +1,6 @@
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { useMatchPopupStore } from 'features/MatchPopup' import { useMatchPopupStore, PopupPages } from 'features/MatchPopup'
import { BaseButton } from 'features/PopupComponents' import { BaseButton } from 'features/PopupComponents'
const Button = styled(BaseButton)` const Button = styled(BaseButton)`
@ -8,8 +8,8 @@ const Button = styled(BaseButton)`
` `
export const SettingsButton = () => { export const SettingsButton = () => {
const { goToSettings } = useMatchPopupStore() const { goTo } = useMatchPopupStore()
return ( return (
<Button onClick={goToSettings} /> <Button onClick={(e) => goTo(PopupPages.MATCH_SETTINGS, e)} />
) )
} }

@ -1,16 +1,32 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import styled from 'styled-components/macro'
import { useMatchPopupStore } from 'features/MatchPopup' import { useMatchPopupStore } from 'features/MatchPopup'
import { ButtonSolid } from 'features/Common'
import { T9n } from 'features/T9n'
import { PlaylistFormats } from '../PlaylistFormats' import { PlaylistFormats } from '../PlaylistFormats'
import { EpisodeDurationInputs } from '../EpisodeDurationInputs' import { EpisodeDurationInputs } from '../EpisodeDurationInputs'
import { PlayerActions } from '../PlayerActions' import { PlayerActions } from '../PlayerActions'
import { PlayerPlaylistFormats } from '../../types' import { PlayerPlaylistFormats } from '../../types'
const ButtonsWrapper = styled.div`
display: flex;
justify-content: center;
margin: 45px 0 15px 0;
`
const WatchButton = styled(ButtonSolid)`
width: auto;
padding: 0 20px;
`
export const SettingsDesktop = () => { export const SettingsDesktop = () => {
const { const {
actions, actions,
episodeDuration, episodeDuration,
handleWatchEpisodesClick,
onActionClick, onActionClick,
onDurationChange, onDurationChange,
onFormatSelect, onFormatSelect,
@ -34,6 +50,12 @@ export const SettingsDesktop = () => {
selectedActions={selectedActions} selectedActions={selectedActions}
/> />
)} )}
<ButtonsWrapper>
<WatchButton onClick={handleWatchEpisodesClick}>
<T9n t='watch_players_episodes' />
</WatchButton>
</ButtonsWrapper>
</Fragment> </Fragment>
) )
} }

@ -4,6 +4,7 @@ import { FinishedMatchPopup } from './components/FinishedMatchPopup'
import { LiveMatchPopup } from './components/LiveMatchPopup' import { LiveMatchPopup } from './components/LiveMatchPopup'
export * from './store' export * from './store'
export * from './types'
export const MatchPopup = () => { export const MatchPopup = () => {
const { match } = useMatchPopupStore() const { match } = useMatchPopupStore()

@ -1,7 +1,6 @@
import { import {
useState, useState,
useEffect, useEffect,
useCallback,
} from 'react' } from 'react'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
@ -22,11 +21,12 @@ import { usePlaylistLexics } from './usePlaylistLexics'
export const useMatchPopup = () => { export const useMatchPopup = () => {
const [match, setMatch] = useState<MatchData>(null) const [match, setMatch] = useState<MatchData>(null)
const [matchPlaylists, setMatchPlaylists] = useState<Playlists | null>(null) const [matchPlaylists, setMatchPlaylists] = useState<Playlists | null>(null)
const { const {
closePopup, closePopup,
goBack, goBack,
goToSettings, goTo,
isOpen, isOpen,
openPopup, openPopup,
page, page,
@ -49,17 +49,16 @@ export const useMatchPopup = () => {
const { fetchLexics } = usePlaylistLexics() const { fetchLexics } = usePlaylistLexics()
const onFormatSelect = useCallback((format: PlayerPlaylistFormats) => { useEffect(() => {
setSelectedPlaylistFormat(format) if (selectedPlaylistFormat === PlayerPlaylistFormats.SELECTED_ACTIONS) {
if (format === PlayerPlaylistFormats.SELECTED_ACTIONS) {
fetchSportActions() fetchSportActions()
} else { } else {
setSelectedActions([]) setSelectedActions([])
} }
}, [ }, [
selectedPlaylistFormat,
fetchSportActions, fetchSportActions,
setSelectedActions, setSelectedActions,
setSelectedPlaylistFormat,
]) ])
useEffect(() => { useEffect(() => {
@ -78,50 +77,45 @@ export const useMatchPopup = () => {
setSelectedPlaylistFormat(PlayerPlaylistFormats.ALL_MATCH_TIME) setSelectedPlaylistFormat(PlayerPlaylistFormats.ALL_MATCH_TIME)
} }
}, [ }, [
actions,
selectedActions, selectedActions,
selectedPlaylistFormat, selectedPlaylistFormat,
match,
page, page,
fetchSportActions,
setSelectedPlaylistFormat, setSelectedPlaylistFormat,
]) ])
useEffect(() => { useEffect(() => {
if (!match || !isOpen || page !== PopupPages.PLAYLIST) return if (!match) return
getMatchPlaylists({ getMatchPlaylists({
matchId: match.id, matchId: match.id,
selectedActions, selectedActions: [],
sportType: match.sportType, sportType: match.sportType,
}).then(fetchLexics) }).then(fetchLexics)
.then(buildPlaylists) .then(buildPlaylists)
.then(setMatchPlaylists) .then(setMatchPlaylists)
}, [ }, [match, fetchLexics])
isOpen,
match,
page,
selectedActions,
fetchLexics,
])
return { return {
actions, actions,
closePopup, closePopup,
episodeDuration, episodeDuration,
goBack, goBack,
goToSettings, goTo,
isOpen, isOpen,
match, match,
matchPlaylists, matchPlaylists,
onActionClick: setSelectedActions, onActionClick: setSelectedActions,
onDurationChange: setEpisodeDuration, onDurationChange: setEpisodeDuration,
onFormatSelect, onFormatSelect: setSelectedPlaylistFormat,
openPopup, openPopup,
page, page,
selectedActions, selectedActions,
selectedPlaylistFormat, selectedPlaylistFormat,
setMatch, setMatch,
...usePlayerClickHandler(match, settings), ...usePlayerClickHandler({
goTo,
match,
settings,
}),
} }
} }

@ -1,4 +1,5 @@
import { useCallback } from 'react' import type { MouseEvent } from 'react'
import { useCallback, useState } from 'react'
import { useHistory } from 'react-router' import { useHistory } from 'react-router'
import { ProfileTypes } from 'config' import { ProfileTypes } from 'config'
@ -7,15 +8,33 @@ import { getPlayerPlaylists } from 'requests'
import type { PlayerPlaylistOption } from 'features/MatchPage/types' import type { PlayerPlaylistOption } from 'features/MatchPage/types'
import type { MatchData, Settings } from 'features/MatchPopup/types' import type { MatchData, Settings } from 'features/MatchPopup/types'
import type { RouteState } from 'features/MatchPage/hooks/useRouteState' import type { RouteState } from 'features/MatchPage/hooks/useRouteState'
import { PopupPages } from 'features/MatchPopup/types'
import { getProfileUrl } from 'features/ProfileLink/helpers' import { getProfileUrl } from 'features/ProfileLink/helpers'
export const usePlayerClickHandler = (match: MatchData, settings: Settings) => { type Args = {
goTo: (page: PopupPages) => void,
match: MatchData,
settings: Settings,
}
export const usePlayerClickHandler = ({
goTo,
match,
settings,
}: Args) => {
const history = useHistory() const history = useHistory()
const handlePlayerClick = useCallback(async (player: PlayerPlaylistOption) => { const [selectedPlayer, setSelectedPlayer] = useState<PlayerPlaylistOption | null>(null)
if (!match) return const handlePlayerClick = (player: PlayerPlaylistOption, e: MouseEvent) => {
const playlistData = await getPlayerPlaylists({ e.stopPropagation()
setSelectedPlayer(player)
goTo(PopupPages.PLAYER_SETTINGS)
}
const handleWatchEpisodesClick = useCallback(async () => {
if (!match || !selectedPlayer) return
const episodes = await getPlayerPlaylists({
matchId: match.id, matchId: match.id,
playerId: player.id, playerId: selectedPlayer.id,
settings, settings,
sportType: match.sportType, sportType: match.sportType,
}) })
@ -27,15 +46,20 @@ export const usePlayerClickHandler = (match: MatchData, settings: Settings) => {
}) })
const routeState: RouteState = { const routeState: RouteState = {
playlistData, episodes,
selectedPlaylist: player, selectedPlaylist: selectedPlayer,
} }
history.push(matchLink, routeState) history.push(matchLink, routeState)
}, [ }, [
match, match,
selectedPlayer,
settings, settings,
history, history,
]) ])
return { handlePlayerClick } return {
handlePlayerClick,
handleWatchEpisodesClick,
selectedPlayer,
}
} }

@ -1,44 +1,46 @@
import type { MouseEvent } from 'react' import type { MouseEvent } from 'react'
import { useState, useCallback } from 'react' import { useState, useCallback } from 'react'
import { useToggle } from 'hooks' import last from 'lodash/last'
import { PopupPages } from '../../types' import { PopupPages } from '../../types'
export const usePopupNavigation = () => { export const usePopupNavigation = () => {
const { const [pages, setPages] = useState<Array<PopupPages>>([])
close,
isOpen,
open,
} = useToggle()
const [page, setPage] = useState<PopupPages>(PopupPages.PLAYLIST) const goTo = useCallback(
(step: PopupPages, e?: MouseEvent<HTMLButtonElement>) => setPages((state) => {
e?.stopPropagation()
return [...state, step]
}),
[],
)
const closePopup = useCallback(() => { const goBack = useCallback((e?: MouseEvent) => {
close()
setPage(PopupPages.PLAYLIST)
}, [close])
const goBack = useCallback((e?: MouseEvent<HTMLElement>) => {
e?.stopPropagation() e?.stopPropagation()
if (page === PopupPages.PLAYLIST) { setPages((state) => {
closePopup() const newState = [...state]
} else { newState.pop()
setPage(PopupPages.PLAYLIST) return newState
} })
}, [page, closePopup]) }, [])
const goToSettings = useCallback((e: MouseEvent<HTMLElement>) => { const openPopup = () => {
e.stopPropagation() setPages([PopupPages.PLAYLIST])
setPage(PopupPages.SETTINGS) }
const closePopup = useCallback(() => {
setPages([])
}, []) }, [])
const page = last(pages)
return { return {
closePopup, closePopup,
goBack, goBack,
goToSettings, goTo,
isOpen, isOpen: Boolean(page),
openPopup: open, openPopup,
page, page,
} }
} }

@ -12,8 +12,9 @@ export type MatchData = Pick<Match, (
)> | null )> | null
export enum PopupPages { export enum PopupPages {
PLAYLIST, MATCH_SETTINGS = 'MATCH_SETTINGS',
SETTINGS, PLAYER_SETTINGS = 'PLAYER_SETTINGS',
PLAYLIST = 'PLAYLIST',
} }
export enum PlayerPlaylistFormats { export enum PlayerPlaylistFormats {

@ -63,7 +63,7 @@ export const PlayersPlaylists = ({
(player) => isEqual(player, selectedMathPlaylist), (player) => isEqual(player, selectedMathPlaylist),
) )
if (found) { if (found) {
listRef.current?.scrollIntoView() listRef.current?.scrollIntoView({ behavior: 'smooth' })
} }
}, [players, selectedMathPlaylist]) }, [players, selectedMathPlaylist])

@ -21,7 +21,6 @@ export const Header = styled.div<HeaderProps>`
` `
type HeaderActionsProps = { type HeaderActionsProps = {
marginLeft?: number,
position: 'left' | 'right', position: 'left' | 'right',
} }
@ -29,9 +28,8 @@ export const HeaderActions = styled.div<HeaderActionsProps>`
position: absolute; position: absolute;
display: flex; display: flex;
${({ marginLeft = 0, position }) => css` ${({ position }) => css`
${position}: 20px; ${position}: 20px;
margin-left: ${marginLeft}px;
`} `}
@media ${devices.mobile} { @media ${devices.mobile} {

@ -28,10 +28,10 @@ export type Episode = {
s: number, s: number,
} }
export type PlaylistData = Array<Episode> export type Episodes = Array<Episode>
type PlaylistWithDuration = { type PlaylistWithDuration = {
data?: PlaylistData, data?: Episodes,
dur?: number, dur?: number,
} }

@ -11,7 +11,7 @@ import { callApi, getSportLexic } from 'helpers'
import type { Settings } from 'features/MatchPopup/types' import type { Settings } from 'features/MatchPopup/types'
import { defaultSettings } from 'features/MatchPopup/types' import { defaultSettings } from 'features/MatchPopup/types'
import type { PlaylistData } from './getMatchPlaylists' import type { Episodes } from './getMatchPlaylists'
const proc = PROCEDURES.ott_match_popup_player_playlist const proc = PROCEDURES.ott_match_popup_player_playlist
@ -23,7 +23,7 @@ type Args = {
} }
type Response = { type Response = {
data?: PlaylistData, data?: Episodes,
} }
export const getPlayerPlaylists = async ({ export const getPlayerPlaylists = async ({

Loading…
Cancel
Save