Ott 839 settings players playlists (#319)

* feat: 🎸 OTT-839

useMatchPopupStore

* feat: 🎸 OTT-839

add settings

* feat: 🎸 OTT-839

add settings

* feat: 🎸 OTT-839

fix comments

* feat: 🎸 OTT-839-settings-players-playlists

fix after code review

* feat: 🎸 OTT-839

fix line

* feat: 🎸 OTT-839

fix pr comments

* feat: 🎸 OTT-839

fix pr comments

Co-authored-by: Zoia <zizi2405@yandex.ru>
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Zoia 5 years ago committed by GitHub
parent bec9a081f0
commit a2b2299492
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/config/lexics/indexLexics.tsx
  2. 94
      src/features/MatchPage/components/SettingsDesktop/index.tsx
  3. 37
      src/features/MatchPage/components/SettingsDesktop/useDesktopSettings.tsx
  4. 103
      src/features/MatchPage/components/SettingsPopup/index.tsx
  5. 8
      src/features/MatchPage/hooks/useEpisodes.tsx
  6. 65
      src/features/MatchPage/hooks/useMatchPage.tsx
  7. 12
      src/features/MatchPage/hooks/usePlaylists.tsx
  8. 28
      src/features/MatchPage/index.tsx
  9. 24
      src/features/MatchPage/styled.tsx
  10. 4
      src/features/MatchPopup/components/PlaylistFormats/index.tsx
  11. 8
      src/features/MatchPopup/components/PlaylistFormats/styled.tsx
  12. 3
      src/features/MatchPopup/store/hooks/index.tsx
  13. 1
      src/features/MatchPopup/store/hooks/useSettingsState.tsx
  14. 7
      src/features/MatchSidePlaylists/index.tsx
  15. 10
      src/features/MatchSidePlaylists/styled.tsx
  16. 1
      src/requests/getPlayerPlaylists.tsx

@ -73,6 +73,7 @@ export const indexLexics = {
player: 630,
players_video: 13032,
round_highilights: 13050,
save: 828,
search_results: 9014,
select_language: 1005,
sport: 12993,

@ -0,0 +1,94 @@
import { Fragment } from 'react'
import styled from 'styled-components/macro'
import type { Actions } from 'requests'
import {
EpisodeDuration,
PlayerPlaylistFormats,
SelectedActions,
Settings,
} from 'features/MatchPopup'
import { ButtonSolid } from 'features/Common'
import { T9n } from 'features/T9n'
import { PlaylistFormats } from 'features/MatchPopup/components/PlaylistFormats'
import { EpisodeDurationInputs } from 'features/MatchPopup/components/EpisodeDurationInputs'
import { PlayerActions } from 'features/MatchPopup/components/PlayerActions'
import { useSettingsDesktop } from './useDesktopSettings'
const ButtonsWrapper = styled.div`
display: flex;
justify-content: center;
margin: 45px 0 15px 0;
`
const WatchButton = styled(ButtonSolid)`
width: auto;
padding: 0 20px;
`
type Props = {
actions: Actions,
episodeDuration: EpisodeDuration,
isMatchPlaylist?: boolean,
onWatchEpisodesClick: (values: Settings) => void,
selectedActions: SelectedActions,
selectedPlaylistFormat: PlayerPlaylistFormats,
}
export const SettingsDesktop = ({
actions,
episodeDuration,
isMatchPlaylist,
onWatchEpisodesClick,
selectedActions,
selectedPlaylistFormat,
}: Props) => {
const {
actionsValue,
episodeDurationValue,
selectedPlaylistFormatValue,
setActionsValue,
setEpisodeDurationValue,
setSelectedPlaylistFormatValue,
} = useSettingsDesktop({
episodeDuration,
selectedActions,
selectedPlaylistFormat,
})
const marginTop = isMatchPlaylist ? 0 : 62
return (
<Fragment>
<PlaylistFormats
marginTop={marginTop}
selectedFormat={selectedPlaylistFormatValue}
onFormatSelect={setSelectedPlaylistFormatValue}
/>
<EpisodeDurationInputs
value={episodeDurationValue}
onChange={setEpisodeDurationValue}
/>
{selectedPlaylistFormatValue === PlayerPlaylistFormats.SELECTED_ACTIONS && (
<PlayerActions
actions={actions}
onActionClick={setActionsValue}
selectedActions={actionsValue}
/>
)}
<ButtonsWrapper>
<WatchButton onClick={() => onWatchEpisodesClick({
episodeDuration: episodeDurationValue,
selectedActions: actionsValue,
selectedFormat: selectedPlaylistFormatValue,
})}
>
{isMatchPlaylist
? <T9n t='save' />
: <T9n t='watch_players_episodes' />}
</WatchButton>
</ButtonsWrapper>
</Fragment>
)
}

@ -0,0 +1,37 @@
import { useState } from 'react'
import type {
EpisodeDuration,
PlayerPlaylistFormats,
SelectedActions,
} from 'features/MatchPopup'
type Args = {
episodeDuration: EpisodeDuration,
selectedActions: SelectedActions,
selectedPlaylistFormat: PlayerPlaylistFormats,
}
export const useSettingsDesktop = ({
episodeDuration,
selectedActions,
selectedPlaylistFormat,
}: Args) => {
const [actionsValue, setActionsValue] = useState<SelectedActions>(selectedActions)
const [
episodeDurationValue,
setEpisodeDurationValue] = useState<EpisodeDuration>(episodeDuration)
const [
selectedPlaylistFormatValue,
setSelectedPlaylistFormatValue,
] = useState<PlayerPlaylistFormats>(selectedPlaylistFormat)
return {
actionsValue,
episodeDurationValue,
selectedPlaylistFormatValue,
setActionsValue,
setEpisodeDurationValue,
setSelectedPlaylistFormatValue,
}
}

@ -0,0 +1,103 @@
import { MDASH } from 'config'
import styled from 'styled-components/macro'
import type { Actions, MatchInfo } from 'requests'
import type { PlaylistOption } from 'features/MatchPage/types'
import type { Settings } from 'features/MatchPopup'
import { PlaylistTypes } from 'features/MatchPage/types'
import { MediaQuery } from 'features/MediaQuery'
import { Name } from 'features/Name'
import { T9n } from 'features/T9n'
import {
CloseButton,
Header,
HeaderActions,
HeaderTitle,
} from 'features/PopupComponents'
import { SettingsDesktop } from '../SettingsDesktop'
const TitleWrapper = styled(HeaderTitle)`
display: flex;
flex-direction: column;
line-height: 32px;
`
const TeamNames = styled.span`
font-weight: normal;
`
type ContentProps = {
height?: number,
}
const Content = styled.div<ContentProps>`
width: 100%;
`
type Props = {
actions: Actions,
closePopup: () => void,
onWatchEpisodesClick: (values: Settings) => void,
profile: MatchInfo,
selectedPlaylist?: PlaylistOption,
settings: Settings,
}
export const SettingsPopup = ({
actions,
closePopup,
onWatchEpisodesClick,
profile,
selectedPlaylist,
settings,
}: Props) => {
if (!profile || !selectedPlaylist) return null
const isMatchPlaylist = selectedPlaylist.type === PlaylistTypes.MATCH
return (
<Content>
{!isMatchPlaylist
? (
<Header>
<MediaQuery maxDevice='mobile'>
<HeaderTitle>
<T9n t='match_settings' />
</HeaderTitle>
</MediaQuery>
<MediaQuery minDevice='tablet'>
<HeaderActions position='right'>
<CloseButton onClick={closePopup} />
</HeaderActions>
<TitleWrapper>
{selectedPlaylist && <Name nameObj={selectedPlaylist} />}
<TeamNames>
<Name nameObj={profile.team1} />
{` ${MDASH} `}
<Name nameObj={profile.team2} />
</TeamNames>
</TitleWrapper>
</MediaQuery>
</Header>
)
: (
<Header>
<HeaderActions position='right'>
<CloseButton onClick={closePopup} />
</HeaderActions>
</Header>
)}
<MediaQuery minDevice='tablet'>
<SettingsDesktop
actions={actions}
episodeDuration={settings.episodeDuration}
onWatchEpisodesClick={onWatchEpisodesClick}
isMatchPlaylist={isMatchPlaylist}
selectedActions={settings.selectedActions}
selectedPlaylistFormat={settings.selectedFormat}
/>
</MediaQuery>
</Content>
)
}

@ -4,6 +4,8 @@ import {
useEffect,
} from 'react'
import type { Settings } from 'features/MatchPopup'
import { getPlayerPlaylists, Episodes } from 'requests'
import { usePageId, useSportNameParam } from 'hooks'
@ -20,13 +22,17 @@ export const useEpisodes = ({ initialEpisodes, initialSelectedPlaylist }: Args)
const { sportType } = useSportNameParam()
const matchId = usePageId()
const fetchEpisodes = useCallback((selectedPlaylist: PlaylistOption) => {
const fetchEpisodes = useCallback((
selectedPlaylist: PlaylistOption,
settings?: Settings,
) => {
if (!selectedPlaylist) return
if (selectedPlaylist.type === PlaylistTypes.PLAYER) {
getPlayerPlaylists({
matchId,
playerId: selectedPlaylist.id,
settings,
sportType,
}).then(setEpisodes)
} else if (selectedPlaylist.type === PlaylistTypes.MATCH) {

@ -1,24 +1,61 @@
import { useEffect, useState } from 'react'
import isEqual from 'lodash/isEqual'
import type { LiveVideos } from 'requests'
import { getLiveVideos } from 'requests'
import { useSportNameParam, usePageId } from 'hooks'
import { useMatchPopupStore } from 'features/MatchPopup'
import {
useSportNameParam,
usePageId,
useToggle,
} from 'hooks'
import { Settings, useMatchPopupStore } from 'features/MatchPopup'
import { useLastPlayPosition } from './useLastPlayPosition'
import { usePlaylists } from './usePlaylists'
import { useChapters } from './useChapters'
import { useRouteState } from './useRouteState'
import { useMatchProfile } from './useMatchProfile'
export const useMatchPage = () => {
const { closePopup } = useMatchPopupStore()
const { initialEpisodes, initialSelectedPlaylist } = useRouteState()
const [isFinishedMatch, setFinishedMatch] = useState(Boolean(initialSelectedPlaylist))
const [liveVideos, setLiveVideos] = useState<LiveVideos>([])
const profile = useMatchProfile()
const { sportType } = useSportNameParam()
const matchId = usePageId()
const {
actions,
closePopup,
setMatch,
setSettings,
settings,
} = useMatchPopupStore()
const {
close,
isOpen,
open,
} = useToggle()
useEffect(() => {
if (profile) {
const match = {
calc: false,
id: matchId,
live: false,
sportType,
team1: profile.team1,
team2: profile.team2,
}
setMatch(match)
}
}, [
matchId,
profile,
setMatch,
sportType,
])
const {
episodes,
@ -31,6 +68,17 @@ export const useMatchPage = () => {
isFinishedMatch,
})
const setEpisodesSettings = (values: Settings) => {
const isSettingsChanged = !isEqual(values, settings)
if (isSettingsChanged) {
setSettings({
episodeDuration: values.episodeDuration,
selectedActions: values.selectedActions,
selectedFormat: values.selectedFormat,
})
}
close()
}
useEffect(() => {
if (!isFinishedMatch) {
getLiveVideos(sportType, matchId)
@ -49,9 +97,16 @@ export const useMatchPage = () => {
}, [closePopup])
return {
actions,
closeSettingsPopup: close,
isOpen,
onPlaylistSelect,
openSettingsPopup: open,
playlists,
profile,
selectedPlaylist,
setEpisodesSettings,
settings,
url: liveVideos[0] || '',
...useChapters({
episodes,

@ -9,6 +9,7 @@ import { usePageId, useSportNameParam } from 'hooks'
import type { PlaylistOption, Playlists } from 'features/MatchPage/types'
import { usePlaylistLexics } from 'features/MatchPopup/store/hooks/usePlaylistLexics'
import { useMatchPopupStore } from 'features/MatchPopup'
import { buildPlaylists } from '../helpers/buildPlaylists'
import { useEpisodes } from './useEpisodes'
@ -37,6 +38,7 @@ export const usePlaylists = ({
const { sportType } = useSportNameParam()
const { fetchLexics } = usePlaylistLexics()
const matchId = usePageId()
const { settings } = useMatchPopupStore()
const {
episodes,
@ -45,6 +47,15 @@ export const usePlaylists = ({
initialEpisodes,
initialSelectedPlaylist,
})
useEffect(() => {
if (selectedPlaylist) {
fetchEpisodes(selectedPlaylist, settings)
}
}, [
fetchEpisodes,
selectedPlaylist,
settings,
])
useEffect(() => {
if (isFinishedMatch) {
@ -72,7 +83,6 @@ export const usePlaylists = ({
const onPlaylistSelect = (option: PlaylistOption) => {
if (option === selectedPlaylist) return
setSelectedPlaylist(option)
fetchEpisodes(option)
}
return {

@ -9,26 +9,35 @@ import { MultiSourcePlayer } from 'features/MultiSourcePlayer'
import { StreamPlayer } from 'features/StreamPlayer'
import { MatchProfileCard } from './components/MatchProfileCard'
import { useMatchProfile } from './hooks/useMatchProfile'
import {
MainWrapper as Wrapper,
Modal,
Container,
} from './styled'
import { useMatchPage } from './hooks/useMatchPage'
import { usePlayerProgressReporter } from './hooks/usePlayerProgressReporter'
import { SettingsPopup } from './components/SettingsPopup'
const MatchPage = () => {
const profile = useMatchProfile()
const {
actions,
chapters,
closeSettingsPopup,
isLastPlayPositionFetching,
isOpen,
lastPlayPosition,
onPlaylistSelect,
openSettingsPopup,
playlists,
profile,
selectedPlaylist,
setEpisodesSettings,
settings,
url,
} = useMatchPage()
const { onPlayerProgressChange, onPlayingChange } = usePlayerProgressReporter()
const isLiveMatch = Boolean(url) && !isLastPlayPositionFetching
@ -36,6 +45,20 @@ const MatchPage = () => {
return (
<MainWrapper>
<Modal
close={closeSettingsPopup}
isOpen={isOpen}
withCloseButton={false}
>
<SettingsPopup
actions={actions}
onWatchEpisodesClick={setEpisodesSettings}
settings={settings}
closePopup={closeSettingsPopup}
profile={profile}
selectedPlaylist={selectedPlaylist}
/>
</Modal>
<MediaQuery minDevice='laptop'>
<UserFavorites />
</MediaQuery>
@ -69,6 +92,7 @@ const MatchPage = () => {
selectedPlaylist={selectedPlaylist}
onSelect={onPlaylistSelect}
profile={profile}
openPopup={openSettingsPopup}
/>
</Wrapper>
</MainWrapper>

@ -2,6 +2,9 @@ import styled from 'styled-components/macro'
import { devices } from 'config/devices'
import { Modal as BaseModal } from 'features/Modal'
import { ModalWindow } from 'features/Modal/styled'
export const MainWrapper = styled.div`
margin: 63px 0px 0 22px;
display: flex;
@ -35,3 +38,24 @@ export const Container = styled.div`
max-width: 100%;
}
`
export const Modal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7);
${ModalWindow} {
width: 1222px;
padding: 20px 0;
background-color: #3F3F3F;
border-radius: 5px;
@media ${devices.tablet} {
width: 100vw;
}
@media ${devices.mobile} {
height: 100vh;
padding: 0;
background-color: transparent;
}
}
`

@ -10,15 +10,17 @@ import {
} from './styled'
type Props = {
marginTop?: number,
onFormatSelect: (format: PlayerPlaylistFormats) => void,
selectedFormat: PlayerPlaylistFormats,
}
export const PlaylistFormats = ({
marginTop,
onFormatSelect,
selectedFormat,
}: Props) => (
<Wrapper>
<Wrapper marginTop={marginTop}>
<BlockTitle>
<T9n t='playlist_format' />
</BlockTitle>

@ -6,19 +6,23 @@ import { Radio as BaseRadio } from 'features/Common'
import { Label } from 'features/Common/Radio/styled'
import { RadioSvg } from 'features/Common/Radio/Icon'
export const Wrapper = styled.div`
type Props = {
marginTop?: number,
}
export const Wrapper = styled.div<Props>`
display: flex;
flex-direction: column;
margin-top: 62px;
padding-left: 35px;
padding-right: 20px;
margin-top: ${({ marginTop }) => `${marginTop ?? 62}px`};
@media ${devices.mobile} {
margin-top: 14px;
padding: 0 12px;
}
`
export const List = styled.ul`
display: flex;
flex-direction: column;

@ -36,6 +36,7 @@ export const useMatchPopup = () => {
setEpisodeDuration,
setSelectedActions,
setSelectedPlaylistFormat,
setSettings,
settings,
} = useSettingsState(match?.sportType)
@ -112,6 +113,8 @@ export const useMatchPopup = () => {
selectedActions,
selectedPlaylistFormat,
setMatch,
setSettings,
settings,
...usePlayerClickHandler({
goTo,
match,

@ -66,6 +66,7 @@ export const useSettingsState = (sportType?: SportTypes) => {
setEpisodeDuration,
setSelectedActions,
setSelectedPlaylistFormat,
setSettings,
settings,
}
}

@ -10,14 +10,17 @@ import { SideInterviews } from './components/SideInterviews'
import { PlayersPlaylists } from './components/PlayersPlaylists'
import {
ButtonBox,
Container,
DropdownWrapper,
List,
SettingsButton,
Wrapper,
} from './styled'
type Props = {
onSelect: (option: PlaylistOption) => void,
openPopup: () => void,
playlists: Playlists,
profile: MatchInfo,
selectedPlaylist?: PlaylistOption,
@ -29,6 +32,7 @@ export const isEqual = (target: PlaylistOption, selected?: PlaylistOption) => (
export const MatchSidePlaylists = ({
onSelect,
openPopup,
playlists,
profile,
selectedPlaylist,
@ -54,6 +58,9 @@ export const MatchSidePlaylists = ({
onSelect={onSelect}
/>
</DropdownSection>
<ButtonBox>
<SettingsButton onClick={openPopup} />
</ButtonBox>
<DropdownSection
isOpen={selectedPlaylist?.type === PlaylistTypes.PLAYER}
itemsCount={playersCount}

@ -2,6 +2,7 @@ import styled, { css } from 'styled-components/macro'
import { customScrollbar } from 'features/Common'
import { buttonStyles } from 'features/MatchPopup/components/PlaylistButton'
import { BaseButton } from 'features/PopupComponents'
export const Wrapper = styled.div`
margin-top: 42px;
@ -60,3 +61,12 @@ export const Title = styled.span`
white-space: nowrap;
text-overflow:ellipsis;
`
export const ButtonBox = styled.div`
text-align: right;
`
export const SettingsButton = styled(BaseButton)`
display: inline-block;;
background-image: url(/images/settings.svg);
`

@ -33,6 +33,7 @@ export const getPlayerPlaylists = async ({
sportType,
}: Args) => {
const actions = isEmpty(settings.selectedActions) ? null : settings.selectedActions
const config = {
body: {
params: {

Loading…
Cancel
Save