fix(#1701): fix conflicts

keep-around/fdb88b04b32b9392e76795099e2ec47c9856b38b
Andrei Dekterev 4 years ago committed by Andrei Dekterev
parent ad7d8f9530
commit d32c37b336
  1. 137
      src/features/MatchPage/components/FinishedMatch/helpers.tsx
  2. 53
      src/features/MatchPage/components/FinishedMatch/hooks/index.tsx
  3. 46
      src/features/MatchPage/components/FinishedMatch/hooks/useChapters.tsx
  4. 69
      src/features/MatchPage/components/FinishedMatch/hooks/useEpisodes.tsx
  5. 27
      src/features/MatchPage/components/FinishedMatch/styled.tsx
  6. 1
      src/features/MatchPage/components/LiveMatch/index.tsx
  7. 5
      src/features/MatchPage/index.tsx
  8. 25
      src/features/MatchPopup/store/hooks/usePlayerClickHandler.tsx
  9. 8
      src/features/StreamPlayer/hooks/index.tsx
  10. 2
      src/features/TournamentsPopup/index.tsx
  11. 15
      src/requests/getMatchPlaylists.tsx
  12. 1
      src/requests/index.tsx

@ -1,137 +0,0 @@
import map from 'lodash/map'
import last from 'lodash/last'
import uniq from 'lodash/uniq'
import filter from 'lodash/filter'
import reduce from 'lodash/reduce'
import concat from 'lodash/concat'
import orderBy from 'lodash/orderBy'
import isEmpty from 'lodash/isEmpty'
import groupBy from 'lodash/groupBy'
import type {
Videos,
Episodes,
Episode,
} from 'requests'
import type { Chapters, Urls } from 'features/MultiSourcePlayer/types'
import type { PlaylistOption } from '../../types'
import { FULL_GAME_KEY } from '../../helpers/buildPlaylists'
const getUniquePeriods = (videos: Videos) => uniq(map(videos, ({ period }) => period))
type Video = {
duration: number,
period: number,
urls: Urls,
}
const getVideoByPeriod = (videos: Videos, period: number) => {
const videosWithSamePeriod = filter(videos, { period })
if (isEmpty(videosWithSamePeriod)) return null
const urls = reduce(
videosWithSamePeriod,
(acc: Urls, video) => ({
...acc,
[video.quality]: video.url,
}),
{},
)
const [video] = videosWithSamePeriod
return {
duration: video.duration,
period: video.period,
urls,
}
}
const getVideoByPeriods = (videos: Videos, periods: Array<number>) => (
reduce(
periods,
(acc: Array<Video>, period) => {
const video = getVideoByPeriod(videos, period)
return video ? concat(acc, video) : acc
},
[],
)
)
const getFullMatchChapters = (videos: Array<Video>) => {
const sortedVideos = orderBy(videos, ({ period }) => period)
return reduce(
sortedVideos,
(acc: Chapters, video) => {
const prevVideoEndMs = last(acc)?.endMs || 0
const endMs = prevVideoEndMs + video.duration
const nextChapter = {
duration: video.duration,
endMs,
endOffsetMs: endMs,
period: video.period,
startMs: prevVideoEndMs,
startOffsetMs: 0,
urls: video.urls,
}
return concat(acc, nextChapter)
},
[],
)
}
const getEpisodeUrls = (urls: Urls, episode: Episode) => reduce(
urls,
(
acc: Urls,
url,
qulaity,
) => {
acc[qulaity] = `${url}#t=${episode.s},${episode.e}`
return acc
},
{},
)
const getPlaylistChapters = (videos: Array<Video>, episodes: Episodes) => {
const groupedByPeriods = groupBy(videos, ({ period }) => period)
return reduce(
episodes,
(acc: Chapters, episode) => {
const video = groupedByPeriods[episode.h]?.[0]
if (!video || episode.s >= episode.e) return acc
const episodeDuration = (episode.e - episode.s) * 1000
const prevVideoEndMs = last(acc)?.endMs || 0
const nextChapter = {
duration: episodeDuration,
endMs: prevVideoEndMs + episodeDuration,
endOffsetMs: episode.e * 1000,
period: video.period,
startMs: prevVideoEndMs,
startOffsetMs: episode.s * 1000,
urls: getEpisodeUrls(video.urls, episode),
}
return concat(acc, nextChapter)
},
[],
)
}
type Args = {
episodes: Episodes,
selectedPlaylist?: PlaylistOption,
videos: Videos,
}
export const buildChapters = ({
episodes,
selectedPlaylist,
videos,
}: Args) => {
const periods = getUniquePeriods(videos)
const highQualityVideos = getVideoByPeriods(videos, periods)
return selectedPlaylist?.id === FULL_GAME_KEY
? getFullMatchChapters(highQualityVideos)
: getPlaylistChapters(highQualityVideos, episodes)
}

@ -1,53 +0,0 @@
import { useToggle } from 'hooks/useToggle'
import type { Settings } from 'features/MatchPopup'
import { useMatchPopupStore } from 'features/MatchPopup'
import { usePlayerLogger } from './usePlayerLogger'
import { useEpisodes } from './useEpisodes'
import { useChapters } from './useChapters'
export const useFinishedMatch = () => {
const {
handlePlaylistClick,
matchPlaylists,
selectedPlaylist,
setSettings,
} = useMatchPopupStore()
const {
close: closeSettingsPopup,
isOpen: isSettingsPopupOpen,
open: openSettingsPopup,
} = useToggle()
const { episodes } = useEpisodes()
const { logPlaylistChange, onPlayingChange } = usePlayerLogger()
const setEpisodesSettings = (newSettings: Settings) => {
setSettings(newSettings)
closeSettingsPopup()
}
const onPlaylistSelect: typeof handlePlaylistClick = (playlist, e) => {
if (selectedPlaylist) {
logPlaylistChange(selectedPlaylist)
}
handlePlaylistClick(playlist, e)
}
return {
closeSettingsPopup,
isSettingsPopupOpen,
onPlayingChange,
onPlaylistSelect,
openSettingsPopup,
playlists: matchPlaylists,
selectedPlaylist,
setEpisodesSettings,
...useChapters({
episodes,
selectedPlaylist,
}),
}
}

@ -1,46 +0,0 @@
import {
useEffect,
useMemo,
useState,
} from 'react'
import type { Episodes, Videos } from 'requests'
import { getVideos } from 'requests'
import { usePageParams } from 'hooks/usePageParams'
import type { PlaylistOption } from 'features/MatchPage/types'
import { buildChapters } from '../helpers'
type Args = {
episodes: Episodes,
selectedPlaylist?: PlaylistOption,
}
export const useChapters = ({
episodes,
selectedPlaylist,
}: Args) => {
const [videos, setVideos] = useState<Videos>([])
const { profileId: matchId, sportType } = usePageParams()
useEffect(() => {
getVideos(sportType, matchId).then(setVideos)
}, [sportType, matchId])
const chapters = useMemo(
() => buildChapters({
episodes,
selectedPlaylist,
videos,
}),
[
selectedPlaylist,
episodes,
videos,
],
)
return { chapters }
}

@ -1,69 +0,0 @@
import {
useCallback,
useEffect,
useState,
} from 'react'
import isEmpty from 'lodash/isEmpty'
import type { Episodes } from 'requests'
import { getPlayerPlaylists } from 'requests'
import { usePageParams } from 'hooks/usePageParams'
import { PlaylistOption, PlaylistTypes } from 'features/MatchPage/types'
import {
defaultSettings,
Settings,
useMatchPopupStore,
} from 'features/MatchPopup'
export const useEpisodes = () => {
const {
handlePlaylistClick,
matchPlaylists: playlists,
selectedPlaylist,
settings,
} = useMatchPopupStore()
const [episodes, setEpisodes] = useState<Episodes>([])
const { profileId: matchId, sportType } = usePageParams()
const fetchEpisodes = useCallback((
playlistOption: PlaylistOption,
popupSettings: Settings = defaultSettings,
) => {
if (playlistOption.type === PlaylistTypes.PLAYER) {
getPlayerPlaylists({
matchId,
playerId: playlistOption.id,
settings: popupSettings,
sportType,
}).then(setEpisodes)
} else if (playlistOption.type === PlaylistTypes.MATCH
|| playlistOption.type === PlaylistTypes.EVENT) {
setEpisodes(playlistOption.episodes)
}
}, [matchId, sportType])
useEffect(() => {
if (!selectedPlaylist && playlists && !isEmpty(playlists.match)) {
handlePlaylistClick(playlists.match[0])
}
}, [
selectedPlaylist,
playlists,
handlePlaylistClick,
])
useEffect(() => {
if (selectedPlaylist) {
fetchEpisodes(selectedPlaylist, settings)
}
}, [
settings,
selectedPlaylist,
fetchEpisodes,
])
return { episodes }
}

@ -1,27 +0,0 @@
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 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;
}
}
`

@ -45,6 +45,7 @@ export const LiveMatch = ({
<Container> <Container>
{profile?.youtube_link ? ( {profile?.youtube_link ? (
<YoutubePlayer <YoutubePlayer
chapters={chapters}
onPlayingChange={onPlayingChange} onPlayingChange={onPlayingChange}
onProgressChange={onPlayerProgressChange} onProgressChange={onPlayerProgressChange}
profile={profile} profile={profile}

@ -19,7 +19,6 @@ import { MatchPageStore } from './store'
import { SubscriptionGuard } from './components/SubscriptionGuard' import { SubscriptionGuard } from './components/SubscriptionGuard'
import { MatchProfileCard } from './components/MatchProfileCard' import { MatchProfileCard } from './components/MatchProfileCard'
import { LiveMatch } from './components/LiveMatch' import { LiveMatch } from './components/LiveMatch'
import { FinishedMatch } from './components/FinishedMatch'
import { useMatchProfile } from './hooks/useMatchProfile' import { useMatchProfile } from './hooks/useMatchProfile'
import { Wrapper } from './styled' import { Wrapper } from './styled'
@ -29,7 +28,6 @@ const MatchPageComponent = () => {
const { addRemoveFavorite, userFavorites } = useUserFavoritesStore() const { addRemoveFavorite, userFavorites } = useUserFavoritesStore()
const { const {
events,
isStarted, isStarted,
profile, profile,
tournamentData, tournamentData,
@ -61,9 +59,6 @@ const MatchPageComponent = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [profile, profileType]) }, [profile, profileType])
const playFromScout = profile?.has_video && !profile?.live
const playFromOTT = !profile?.has_video && (profile?.live || profile?.storage)
// TODO Добавить попап 'Данный матч ещё не начался' // TODO Добавить попап 'Данный матч ещё не начался'
if (!isStarted && profile?.live === false) { if (!isStarted && profile?.live === false) {
const sportName = history.location.pathname.split('/')[1] const sportName = history.location.pathname.split('/')[1]

@ -0,0 +1,25 @@
import type { MouseEvent } from 'react'
import { useState, useEffect } from 'react'
import { useLocation } from 'react-router'
import type { PlaylistOption } from 'features/MatchPage/types'
export const usePlayerClickHandler = () => {
const { pathname } = useLocation()
const [selectedPlaylist, setSelectedPlaylist] = useState<PlaylistOption>()
const handlePlaylistClick = (playlist: PlaylistOption, e?: MouseEvent) => {
e?.stopPropagation()
if (playlist !== selectedPlaylist) {
setSelectedPlaylist(playlist)
}
}
useEffect(() => {
setSelectedPlaylist(undefined)
}, [pathname])
return {
handlePlaylistClick,
selectedPlaylist,
}
}

@ -19,6 +19,8 @@ import { useNoNetworkPopupStore } from 'features/NoNetworkPopup'
import type { Chapters } from 'features/StreamPlayer/types' import type { Chapters } from 'features/StreamPlayer/types'
import { MatchInfo } from 'requests/getMatchInfo'
import { REWIND_SECONDS } from '../config' import { REWIND_SECONDS } from '../config'
import { useHlsPlayer } from './useHlsPlayer' import { useHlsPlayer } from './useHlsPlayer'
import { useFullscreen } from './useFullscreen' import { useFullscreen } from './useFullscreen'
@ -51,7 +53,9 @@ export type Props = {
onDurationChange?: (duration: number) => void, onDurationChange?: (duration: number) => void,
onPlayingChange: (playing: boolean) => void, onPlayingChange: (playing: boolean) => void,
onProgressChange: (seconds: number) => void, onProgressChange: (seconds: number) => void,
profile?: MatchInfo,
resumeFrom?: number, resumeFrom?: number,
url?: string,
} }
export const useVideoPlayer = ({ export const useVideoPlayer = ({
@ -101,6 +105,7 @@ export const useVideoPlayer = ({
onFullscreenClick, onFullscreenClick,
wrapperRef, wrapperRef,
} = useFullscreen() } = useFullscreen()
const [sizeOptions, setSizeOptions] = useState({ const [sizeOptions, setSizeOptions] = useState({
height: wrapperRef.current?.clientHeight, height: wrapperRef.current?.clientHeight,
width: wrapperRef.current?.clientWidth, width: wrapperRef.current?.clientWidth,
@ -190,7 +195,7 @@ export const useVideoPlayer = ({
const onPlayedProgress = (playedMs: number) => { const onPlayedProgress = (playedMs: number) => {
const chapter = getActiveChapter() const chapter = getActiveChapter()
const value = Math.max(playedMs - chapter.startOffsetMs, 0) const value = Math.max(playedMs - chapter.startOffsetMs, 0)
setPlayerState({ buffering: false, playedProgress: value }) setPlayerState({ playedProgress: value })
progressChangeCallback(value / 1000) progressChangeCallback(value / 1000)
} }
@ -308,7 +313,6 @@ export const useVideoPlayer = ({
rewindForward, rewindForward,
seek, seek,
sizeOptions, sizeOptions,
startPlaying,
togglePlaying, togglePlaying,
url, url,
videoRef, videoRef,

@ -31,7 +31,7 @@ export const TournamentsPopup = () => {
<Wrapper> <Wrapper>
<ScBody>{ <ScBody>{
isFetching ? ( isFetching ? (
<LoaderWrapper> <LoaderWrapper buffering={false}>
<Loader color='#515151' /> <Loader color='#515151' />
</LoaderWrapper> </LoaderWrapper>
) : ( ) : (

@ -7,12 +7,10 @@ import {
} from 'config' } from 'config'
import { callApi, getSportLexic } from 'helpers' import { callApi, getSportLexic } from 'helpers'
import { getFullMatchDuration } from './getFullMatchDuration'
const proc = PROCEDURES.ott_match_popup const proc = PROCEDURES.ott_match_popup
type Args = { type Args = {
fullMatchDuration: number, fullMatchDuration?: number,
matchId: number, matchId: number,
selectedActions: Array<number>, selectedActions: Array<number>,
sportType: SportTypes, sportType: SportTypes,
@ -80,7 +78,6 @@ export const getMatchPlaylists = async ({
matchId, matchId,
selectedActions, selectedActions,
sportType, sportType,
withFullMatchDuration,
}: Args): Promise<MatchPlaylists> => { }: Args): Promise<MatchPlaylists> => {
const actions = isEmpty(selectedActions) ? null : selectedActions const actions = isEmpty(selectedActions) ? null : selectedActions
@ -94,19 +91,11 @@ export const getMatchPlaylists = async ({
}, },
} }
const playlistPromise: Promise<Response> = callApi({ const playlist: Response = await callApi({
config, config,
url: `${DATA_URL}/${getSportLexic(sportType)}`, url: `${DATA_URL}/${getSportLexic(sportType)}`,
}) })
const matchDurationPromise = withFullMatchDuration
? getFullMatchDuration(sportType, matchId)
: Promise.resolve(undefined)
const [playlist, fullMatchDuration] = await Promise.all(
[playlistPromise, matchDurationPromise],
)
const full_game: PlaylistWithDuration = { const full_game: PlaylistWithDuration = {
data: [], data: [],
dur: fullMatchDuration, dur: fullMatchDuration,

@ -13,7 +13,6 @@ export * from './getUserInfo'
export * from './getMatchInfo' export * from './getMatchInfo'
export * from './getUnauthenticatedMatch' export * from './getUnauthenticatedMatch'
export * from './reportPlayerProgress' export * from './reportPlayerProgress'
export * from './getVideos'
export * from './saveUserInfo' export * from './saveUserInfo'
export * from './getPlayerInfo' export * from './getPlayerInfo'
export * from './getMatchLastWatchSeconds' export * from './getMatchLastWatchSeconds'

Loading…
Cancel
Save