Ott 697 popup imprv (#268)

* Ott 697 part 1 (#266)

* fix(591): request lexics

* fix(591): style and bug fixes

* fix(591): match page style and bug fixes (#267)
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent d2a2727b42
commit bc277fa65d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/config/lexics/indexLexics.tsx
  2. 3
      src/features/Common/Checkbox/Icon.tsx
  3. 2
      src/features/MatchPage/helpers/buildChapters.tsx
  4. 8
      src/features/MatchPage/helpers/buildPlaylists.tsx
  5. 7
      src/features/MatchPage/hooks/useMatchPage.tsx
  6. 2
      src/features/MatchPage/index.tsx
  7. 2
      src/features/MatchPage/styled.tsx
  8. 2
      src/features/MatchPage/types.tsx
  9. 4
      src/features/MatchPopup/components/MatchPlaylist/index.tsx
  10. 20
      src/features/MatchPopup/components/PlaylistButton/index.tsx
  11. 12
      src/features/MatchPopup/components/PlaylistPage/index.tsx
  12. 2
      src/features/MatchPopup/components/SettingsPage/index.tsx
  13. 7
      src/features/MatchPopup/index.tsx
  14. 48
      src/features/MatchPopup/store/hooks/index.tsx
  15. 21
      src/features/MatchPopup/store/hooks/usePlaylistLexics.tsx
  16. 5
      src/features/MatchPopup/store/hooks/useSettingsState.tsx
  17. 13
      src/features/MatchPopup/styled.tsx
  18. 12
      src/features/MatchSidePlaylists/index.tsx
  19. 24
      src/requests/getMatchPlaylists.tsx
  20. 7
      src/requests/getPlayerPlaylists.tsx

@ -5,10 +5,6 @@ const matchPopupLexics = {
episode_duration: 13410, episode_duration: 13410,
go_back_to_match: 13405, go_back_to_match: 13405,
match_interviews: 13031, match_interviews: 13031,
match_playlist_ball_in_play: 2489,
match_playlist_full_match: 13028,
match_playlist_goals: 3559,
match_playlist_highlights: 13033,
match_settings: 13490, match_settings: 13490,
playlist_format: 13406, playlist_format: 13406,
playlist_format_all_actions: 13408, playlist_format_all_actions: 13408,

@ -15,7 +15,10 @@ export const svgColorStyles = css<SvgColorStylesProps>`
` `
export const CheckboxSvg = styled.svg` export const CheckboxSvg = styled.svg`
min-width: 24px;
min-height: 24px;
margin-right: 22px; margin-right: 22px;
align-self: flex-start;
${svgColorStyles} ${svgColorStyles}
` `

@ -112,7 +112,7 @@ const getPlaylistChapters = (videos: Array<Video>, playlists: PlaylistData) => {
) )
} }
export const buildChapters = (videos: Videos, playlists: PlaylistData = []) => { export const buildChapters = (videos: Videos, playlists: PlaylistData) => {
const periods = getUniquePeriods(videos) const periods = getUniquePeriods(videos)
const highQualityVideos = getVideoByPeriods(videos, periods) const highQualityVideos = getVideoByPeriods(videos, periods)
return isEmpty(playlists) return isEmpty(playlists)

@ -1,4 +1,5 @@
import map from 'lodash/map' import map from 'lodash/map'
import sortBy from 'lodash/sortBy'
import type { MatchPlaylists, Players } from 'requests' import type { MatchPlaylists, Players } from 'requests'
@ -10,7 +11,7 @@ import type {
import { PlaylistTypes } from 'features/MatchPage/types' import { PlaylistTypes } from 'features/MatchPage/types'
const matchKeys = [ const matchKeys = [
'full_match', 'full_game',
'highlights', 'highlights',
'ball_in_play', 'ball_in_play',
'goals', 'goals',
@ -21,11 +22,12 @@ const getMatchPlaylists = (matchPlaylists: MatchPlaylists | null): MatchPlaylist
return map(matchKeys, (key) => { return map(matchKeys, (key) => {
const playlist = matchPlaylists[key] const playlist = matchPlaylists[key]
const lexic = matchPlaylists.lexics[key]
return { return {
data: playlist.data, data: sortBy(playlist.data, ['h', 's']),
duration: playlist.dur, duration: playlist.dur,
id: key, id: key,
lexic: `match_playlist_${key}`, lexic,
type: PlaylistTypes.MATCH, type: PlaylistTypes.MATCH,
} }
}) })

@ -5,12 +5,15 @@ import { getLiveVideos } from 'requests'
import { useSportNameParam, usePageId } from 'hooks' import { useSportNameParam, usePageId } from 'hooks'
import { useMatchPopupStore } from 'features/MatchPopup'
import { useLastPlayPosition } from './useLastPlayPosition' import { useLastPlayPosition } from './useLastPlayPosition'
import { usePlaylists } from './usePlaylists' import { usePlaylists } from './usePlaylists'
import { useChapters } from './useChapters' import { useChapters } from './useChapters'
import { useRouteState } from './useRouteState' import { useRouteState } from './useRouteState'
export const useMatchPage = () => { export const useMatchPage = () => {
const { closePopup } = useMatchPopupStore()
const { initialSelectedPlaylist } = useRouteState() const { initialSelectedPlaylist } = useRouteState()
const [isFinishedMatch, setFinishedMatch] = useState(Boolean(initialSelectedPlaylist)) const [isFinishedMatch, setFinishedMatch] = useState(Boolean(initialSelectedPlaylist))
const [liveVideos, setLiveVideos] = useState<LiveVideos>([]) const [liveVideos, setLiveVideos] = useState<LiveVideos>([])
@ -37,6 +40,10 @@ export const useMatchPage = () => {
matchId, matchId,
]) ])
useEffect(() => {
closePopup()
}, [closePopup])
return { return {
isFinishedMatch, isFinishedMatch,
onPlaylistSelect, onPlaylistSelect,

@ -4,6 +4,7 @@ import { ProfileHeader } from 'features/ProfileHeader'
import { MainWrapper } from 'features/MainWrapper' import { MainWrapper } from 'features/MainWrapper'
import { UserFavorites } from 'features/UserFavorites' import { UserFavorites } from 'features/UserFavorites'
import { MediaQuery } from 'features/MediaQuery' import { MediaQuery } from 'features/MediaQuery'
import { MatchSidePlaylists } from 'features/MatchSidePlaylists'
import { MultiSourcePlayer } from 'features/MultiSourcePlayer' import { MultiSourcePlayer } from 'features/MultiSourcePlayer'
import { StreamPlayer } from 'features/StreamPlayer' import { StreamPlayer } from 'features/StreamPlayer'
@ -60,6 +61,7 @@ export const MatchPage = () => {
) )
} }
</Container> </Container>
<MatchSidePlaylists />
</Wrapper> </Wrapper>
</MainWrapper> </MainWrapper>
) )

@ -17,7 +17,7 @@ export const MainWrapper = styled.div`
` `
export const Container = styled.div` export const Container = styled.div`
max-width: 2360px; max-width: 2090px;
max-height: 896px; max-height: 896px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

@ -10,7 +10,7 @@ export type MatchPlaylistOption = {
data: PlaylistData, data: PlaylistData,
duration?: number, duration?: number,
id: string, id: string,
lexic: string, lexic: number,
type: PlaylistTypes.MATCH, type: PlaylistTypes.MATCH,
} }

@ -16,6 +16,10 @@ const List = styled.ul`
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
:last-child {
margin-bottom: 0;
}
@media ${devices.mobile} { @media ${devices.mobile} {
width: 100%; width: 100%;
margin: 12px auto; margin: 12px auto;

@ -9,10 +9,13 @@ import { secondsToHms } from 'helpers'
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { MatchPlaylistOption } from 'features/MatchPage/types' import { MatchPlaylistOption } from 'features/MatchPage/types'
export const buttonStyles = css` type ButtonsStypesProps = {
disabled?: boolean,
}
export const buttonStyles = css<ButtonsStypesProps>`
border: none; border: none;
cursor: pointer;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -28,6 +31,17 @@ export const buttonStyles = css`
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3); box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
border-radius: 2px; border-radius: 2px;
${({ disabled }) => (
disabled
? css`
pointer-events: none;
opacity: 0.5;
`
: css`
cursor: pointer;
`
)}
:hover { :hover {
background-color: #555555; background-color: #555555;
} }
@ -91,6 +105,8 @@ export const PlaylistButton = ({
state: { selectedPlaylist: playlist }, state: { selectedPlaylist: playlist },
}} }}
onClick={stopPropagation} onClick={stopPropagation}
disabled={!playlist.duration}
tabIndex={!playlist.duration ? -1 : 0}
> >
<Title> <Title>
<T9n t={playlist.lexic} /> <T9n t={playlist.lexic} />

@ -1,5 +1,7 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import isEmpty from 'lodash/isEmpty'
import { Name } from 'features/Name' import { Name } from 'features/Name'
import { MediaQuery } from 'features/MediaQuery' import { MediaQuery } from 'features/MediaQuery'
import { useMatchPopupStore } from 'features/MatchPopup' import { useMatchPopupStore } from 'features/MatchPopup'
@ -23,6 +25,10 @@ export const PlaylistPage = () => {
const { team1, team2 } = match const { team1, team2 } = match
const score = ` ${team1.score}:${team2.score} ` const score = ` ${team1.score}:${team2.score} `
const hasPlayers = (
!isEmpty(matchPlaylists?.players.team1)
&& !isEmpty(matchPlaylists?.players.team2)
)
return ( return (
<Content> <Content>
<Header> <Header>
@ -46,11 +52,11 @@ export const PlaylistPage = () => {
</HeaderActions> </HeaderActions>
</Header> </Header>
<MatchPlaylist />
{ {
matchPlaylists && ( hasPlayers && (
<Fragment> <Fragment>
<MatchPlaylist />
<MediaQuery maxDevice='mobile'> <MediaQuery maxDevice='mobile'>
<PlayersListMobile /> <PlayersListMobile />
</MediaQuery> </MediaQuery>

@ -24,7 +24,7 @@ const ButtonLabel = styled(T9n)`
` `
export const SettingsPage = () => ( export const SettingsPage = () => (
<Content> <Content height={818}>
<Header> <Header>
<HeaderActions <HeaderActions
position='left' position='left'

@ -15,9 +15,12 @@ export const MatchPopup = () => {
const { const {
closePopup, closePopup,
isOpen, isOpen,
matchPlaylists,
page, page,
} = useMatchPopupStore() } = useMatchPopupStore()
const showPopup = isOpen && Boolean(matchPlaylists)
const pageElement = page === PopupPages.PLAYLIST const pageElement = page === PopupPages.PLAYLIST
? <PlaylistPage /> ? <PlaylistPage />
: <SettingsPage /> : <SettingsPage />
@ -27,7 +30,7 @@ export const MatchPopup = () => {
<MediaQuery minDevice='tablet'> <MediaQuery minDevice='tablet'>
<Modal <Modal
close={closePopup} close={closePopup}
isOpen={isOpen} isOpen={showPopup}
withCloseButton={false} withCloseButton={false}
> >
{pageElement} {pageElement}
@ -36,7 +39,7 @@ export const MatchPopup = () => {
<MediaQuery maxDevice='mobile'> <MediaQuery maxDevice='mobile'>
<Modal <Modal
isOpen={isOpen} isOpen={showPopup}
withCloseButton={false} withCloseButton={false}
> >
<Background> <Background>

@ -1,4 +1,8 @@
import { useState, useEffect } from 'react' import {
useState,
useEffect,
useCallback,
} from 'react'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
@ -14,6 +18,7 @@ import { usePopupNavigation } from './usePopupNavigation'
import type { MatchData } from '../../types' import type { MatchData } from '../../types'
import { PopupPages, PlayerPlaylistFormats } from '../../types' import { PopupPages, PlayerPlaylistFormats } from '../../types'
import { usePlayerClickHandler } from './usePlayerClickHandler' import { usePlayerClickHandler } from './usePlayerClickHandler'
import { usePlaylistLexics } from './usePlaylistLexics'
export const useMatchPopup = () => { export const useMatchPopup = () => {
const [match, setMatch] = useState<MatchData>(null) const [match, setMatch] = useState<MatchData>(null)
@ -28,7 +33,6 @@ export const useMatchPopup = () => {
} = usePopupNavigation() } = usePopupNavigation()
const { const {
resetSelectedActions,
setEpisodeDuration, setEpisodeDuration,
setSelectedActions, setSelectedActions,
setSelectedPlaylistFormat, setSelectedPlaylistFormat,
@ -43,6 +47,21 @@ export const useMatchPopup = () => {
const { actions, fetchSportActions } = useSportActions(match?.sportType) const { actions, fetchSportActions } = useSportActions(match?.sportType)
const { fetchLexics } = usePlaylistLexics()
const onFormatSelect = useCallback((format: PlayerPlaylistFormats) => {
setSelectedPlaylistFormat(format)
if (format === PlayerPlaylistFormats.SELECTED_ACTIONS) {
fetchSportActions()
} else {
setSelectedActions([])
}
}, [
fetchSportActions,
setSelectedActions,
setSelectedPlaylistFormat,
])
useEffect(() => { useEffect(() => {
if (!isOpen) { if (!isOpen) {
setMatch(null) setMatch(null)
@ -51,25 +70,21 @@ export const useMatchPopup = () => {
}, [isOpen]) }, [isOpen])
useEffect(() => { useEffect(() => {
if (selectedPlaylistFormat !== PlayerPlaylistFormats.SELECTED_ACTIONS) { const isPlaylistPage = page === PopupPages.PLAYLIST
resetSelectedActions()
}
}, [selectedPlaylistFormat, resetSelectedActions])
useEffect(() => {
const isSettingsPage = page === PopupPages.SETTINGS
const actionsFormatSelected = ( const actionsFormatSelected = (
selectedPlaylistFormat === PlayerPlaylistFormats.SELECTED_ACTIONS selectedPlaylistFormat === PlayerPlaylistFormats.SELECTED_ACTIONS
) )
if (isSettingsPage && actionsFormatSelected) { if (isPlaylistPage && actionsFormatSelected && isEmpty(selectedActions)) {
fetchSportActions() setSelectedPlaylistFormat(PlayerPlaylistFormats.ALL_MATCH_TIME)
} }
}, [ }, [
actions,
selectedActions,
selectedPlaylistFormat, selectedPlaylistFormat,
match, match,
page, page,
fetchSportActions, fetchSportActions,
resetSelectedActions, setSelectedPlaylistFormat,
]) ])
useEffect(() => { useEffect(() => {
@ -77,16 +92,17 @@ export const useMatchPopup = () => {
getMatchPlaylists({ getMatchPlaylists({
matchId: match.id, matchId: match.id,
// запрос с экшнами [1, 2, 3] временный selectedActions,
selectedActions: isEmpty(selectedActions) ? [1, 2, 3] : selectedActions,
sportType: match.sportType, sportType: match.sportType,
}).then(buildPlaylists) }).then(fetchLexics)
.then(buildPlaylists)
.then(setMatchPlaylists) .then(setMatchPlaylists)
}, [ }, [
isOpen, isOpen,
match, match,
page, page,
selectedActions, selectedActions,
fetchLexics,
]) ])
return { return {
@ -100,7 +116,7 @@ export const useMatchPopup = () => {
matchPlaylists, matchPlaylists,
onActionClick: setSelectedActions, onActionClick: setSelectedActions,
onDurationChange: setEpisodeDuration, onDurationChange: setEpisodeDuration,
onFormatSelect: setSelectedPlaylistFormat, onFormatSelect,
openPopup, openPopup,
page, page,
selectedActions, selectedActions,

@ -0,0 +1,21 @@
import { useCallback } from 'react'
import isEmpty from 'lodash/isEmpty'
import values from 'lodash/values'
import type { MatchPlaylists } from 'requests'
import { useLexicsStore } from 'features/LexicsStore'
export const usePlaylistLexics = () => {
const { addLexicsConfig } = useLexicsStore()
const fetchLexics = useCallback((playlist: MatchPlaylists | null) => {
const lexics = values(playlist?.lexics)
if (!isEmpty(lexics)) {
addLexicsConfig(lexics)
}
return playlist
}, [addLexicsConfig])
return { fetchLexics }
}

@ -60,14 +60,9 @@ export const useSettingsState = (sportType?: SportTypes) => {
[setSettings], [setSettings],
) )
const resetSelectedActions = useCallback(() => {
setSelectedActions([])
}, [setSelectedActions])
const settings = useMemo(getSettings, [getSettings]) const settings = useMemo(getSettings, [getSettings])
return { return {
resetSelectedActions,
setEpisodeDuration, setEpisodeDuration,
setSelectedActions, setSelectedActions,
setSelectedPlaylistFormat, setSelectedPlaylistFormat,

@ -11,7 +11,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;
@ -51,9 +50,17 @@ export const BaseButton = styled.button`
} }
` `
export const Content = styled.div` type ContentProps = {
height?: number,
}
export const Content = styled.div<ContentProps>`
width: 100%; width: 100%;
height: 100%; height: ${({ height }) => (
height
? `${height}px`
: 'auto'
)};
overflow-y: auto; overflow-y: auto;
${customScrollbar} ${customScrollbar}

@ -0,0 +1,12 @@
import React from 'react'
import styled from 'styled-components/macro'
const Wrapper = styled.div`
width: 288px;
height: 100px;
margin-top: 42px;
margin-left: 14px;
`
export const MatchSidePlaylists = () => <Wrapper />

@ -1,3 +1,5 @@
import isEmpty from 'lodash/isEmpty'
import { import {
DATA_URL, DATA_URL,
PROCEDURES, PROCEDURES,
@ -29,8 +31,8 @@ export type Episode = {
export type PlaylistData = Array<Episode> export type PlaylistData = Array<Episode>
type PlaylistWithDuration = { type PlaylistWithDuration = {
data: PlaylistData, data?: PlaylistData,
dur: number, dur?: number,
} }
type Player = { type Player = {
@ -42,11 +44,19 @@ type Player = {
export type Players = Array<Player> export type Players = Array<Player>
type Lexics = {
ball_in_play: number,
full_game: number,
goals: number,
highlights: number,
}
export type MatchPlaylists = { export type MatchPlaylists = {
ball_in_play: PlaylistWithDuration, ball_in_play: PlaylistWithDuration,
full_match: PlaylistWithDuration, full_game: PlaylistWithDuration,
goals: PlaylistWithDuration, goals: PlaylistWithDuration,
highlights: PlaylistWithDuration, highlights: PlaylistWithDuration,
lexics: Lexics,
players1: Players, players1: Players,
players2: Players, players2: Players,
} }
@ -60,10 +70,12 @@ export const getMatchPlaylists = async ({
selectedActions, selectedActions,
sportType, sportType,
}: Args) => { }: Args) => {
const actions = isEmpty(selectedActions) ? null : selectedActions
const config = { const config = {
body: { body: {
params: { params: {
_p_actions: selectedActions, _p_actions: actions,
_p_match_id: matchId, _p_match_id: matchId,
}, },
proc, proc,
@ -81,12 +93,12 @@ export const getMatchPlaylists = async ({
[playlistPromise, matchDurationPromise], [playlistPromise, matchDurationPromise],
) )
const full_match: PlaylistWithDuration = { const full_game: PlaylistWithDuration = {
data: [], data: [],
dur: fullMatchDuration, dur: fullMatchDuration,
} }
return playlist.data return playlist.data
? { ...playlist.data, full_match } ? { ...playlist.data, full_game }
: null : null
} }

@ -1,3 +1,5 @@
import isEmpty from 'lodash/isEmpty'
import { import {
DATA_URL, DATA_URL,
PROCEDURES, PROCEDURES,
@ -30,13 +32,14 @@ export const getPlayerPlaylists = async ({
settings = defaultSettings, settings = defaultSettings,
sportType, sportType,
}: Args) => { }: Args) => {
const actions = isEmpty(settings.selectedActions) ? null : settings.selectedActions
const config = { const config = {
body: { body: {
params: { params: {
_p_actions: settings.selectedActions, _p_actions: actions,
_p_match_id: matchId, _p_match_id: matchId,
_p_offset_end: settings.episodeDuration.after, _p_offset_end: settings.episodeDuration.after,
_p_offset_start: settings.episodeDuration.before, _p_offset_start: -settings.episodeDuration.before,
_p_player_id: playerId, _p_player_id: playerId,
_p_type: settings.selectedFormat, _p_type: settings.selectedFormat,
}, },

Loading…
Cancel
Save