fix(#1701): fix conflicts
parent
ad7d8f9530
commit
d32c37b336
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
@ -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, |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue