Ott 1731 live match procs polling (#519)
* refactor(1731): added SubscriptionGuard component (#516) * Ott 1731 part 2 (#518) * refactor(1731): events and playlists polling, wip * fix(1731): 0 duration on playlist buttonkeep-around/af30b88d367751c9e05a735e4a0467a96238ef47
parent
c63149f34f
commit
e467cd64d1
@ -1,41 +0,0 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { devices, MATCH_SIDE_PLAYLIST_WIDTH } from 'config' |
||||
|
||||
import { T9n } from 'features/T9n' |
||||
import { Tab, TabsGroup } from 'features/Common' |
||||
|
||||
const Wrapper = styled.div`` |
||||
|
||||
const Container = styled.div` |
||||
margin-left: 14px; |
||||
margin-right: 18px; |
||||
|
||||
@media ${devices.tablet} { |
||||
width: 80%; |
||||
margin: 0 auto; |
||||
padding: 18px 12px 20px 12px; |
||||
} |
||||
|
||||
@media ${devices.mobile} { |
||||
width: 100%; |
||||
} |
||||
` |
||||
|
||||
export const LiveMatchSidePlaylists = () => ( |
||||
<Wrapper> |
||||
<Container> |
||||
<TabsGroup buttons={3}> |
||||
<Tab width={MATCH_SIDE_PLAYLIST_WIDTH[0]} selected> |
||||
<T9n t='watch' /> |
||||
</Tab> |
||||
<Tab width={MATCH_SIDE_PLAYLIST_WIDTH[1]}> |
||||
<T9n t='actions' /> |
||||
</Tab> |
||||
<Tab width={MATCH_SIDE_PLAYLIST_WIDTH[2]}> |
||||
<T9n t='commentators' /> |
||||
</Tab> |
||||
</TabsGroup> |
||||
</Container> |
||||
</Wrapper> |
||||
) |
||||
@ -0,0 +1,42 @@ |
||||
import type { ReactNode } from 'react' |
||||
import { Fragment, useEffect } from 'react' |
||||
|
||||
import type { MatchInfo } from 'requests/getMatchInfo' |
||||
|
||||
import { usePageParams } from 'hooks/usePageParams' |
||||
|
||||
import { useBuyMatchPopupStore } from 'features/BuyMatchPopup' |
||||
|
||||
import { prepareMatchProfile } from '../../helpers/prepareMatchProfile' |
||||
|
||||
type Props = { |
||||
children: ReactNode, |
||||
matchProfile: MatchInfo, |
||||
} |
||||
|
||||
export const SubscriptionGuard = ({ children, matchProfile }: Props) => { |
||||
const { open: openBuyMatchPopup } = useBuyMatchPopupStore() |
||||
const { profileId: matchId, sportType } = usePageParams() |
||||
|
||||
useEffect(() => { |
||||
if (matchProfile && !matchProfile.sub) { |
||||
const profile = prepareMatchProfile({ |
||||
matchId, |
||||
profile: matchProfile, |
||||
sportType, |
||||
}) |
||||
openBuyMatchPopup(profile) |
||||
} |
||||
}, [ |
||||
matchId, |
||||
openBuyMatchPopup, |
||||
matchProfile, |
||||
sportType, |
||||
]) |
||||
|
||||
return ( |
||||
<Fragment> |
||||
{matchProfile?.sub ? children : null} |
||||
</Fragment> |
||||
) |
||||
} |
||||
@ -1 +0,0 @@ |
||||
export const MATCH_UPDATE_INTERVAL = 20000 |
||||
@ -0,0 +1,64 @@ |
||||
import { useEffect, useMemo } from 'react' |
||||
|
||||
import debounce from 'lodash/debounce' |
||||
|
||||
import { usePageParams } from 'hooks/usePageParams' |
||||
import { useInterval } from 'hooks/useInterval' |
||||
|
||||
import { useMatchPopupStore } from 'features/MatchPopup' |
||||
|
||||
import { useEvents } from './useEvents' |
||||
|
||||
const MATCH_DATA_POLL_INTERVAL = 60000 |
||||
const MATCH_PLAYLISTS_DELAY = 5000 |
||||
|
||||
export const useMatchData = (live: boolean = false) => { |
||||
const { profileId: matchId, sportType } = usePageParams() |
||||
const { fetchMatchPlaylists, matchPlaylists } = useMatchPopupStore() |
||||
const { events, fetchMatchEvents } = useEvents() |
||||
|
||||
const fetchPlaylistsDebounced = useMemo( |
||||
() => debounce(fetchMatchPlaylists, MATCH_PLAYLISTS_DELAY), |
||||
[fetchMatchPlaylists], |
||||
) |
||||
|
||||
useEffect(() => { |
||||
fetchMatchPlaylists({ |
||||
id: matchId, |
||||
sportType, |
||||
withFullMatchDuration: !live, |
||||
}) |
||||
fetchMatchEvents() |
||||
}, [ |
||||
live, |
||||
matchId, |
||||
sportType, |
||||
fetchMatchPlaylists, |
||||
fetchMatchEvents, |
||||
]) |
||||
|
||||
const intervalCallback = () => { |
||||
fetchPlaylistsDebounced({ |
||||
id: matchId, |
||||
sportType, |
||||
withFullMatchDuration: !live, |
||||
}) |
||||
fetchMatchEvents() |
||||
} |
||||
|
||||
const { start, stop } = useInterval({ |
||||
callback: intervalCallback, |
||||
intervalDuration: MATCH_DATA_POLL_INTERVAL, |
||||
startImmediate: false, |
||||
}) |
||||
|
||||
useEffect(() => { |
||||
if (live) { |
||||
start() |
||||
} else { |
||||
stop() |
||||
} |
||||
}, [live, start, stop]) |
||||
|
||||
return { events, matchPlaylists } |
||||
} |
||||
@ -1,44 +1,53 @@ |
||||
import { |
||||
useCallback, |
||||
useEffect, |
||||
useState, |
||||
useMemo, |
||||
} from 'react' |
||||
|
||||
import type { MatchInfo } from 'requests' |
||||
import { getMatchInfo } from 'requests' |
||||
|
||||
import { usePageParams } from 'hooks/usePageParams' |
||||
import { useInterval } from 'hooks/useInterval' |
||||
|
||||
import { MATCH_UPDATE_INTERVAL } from '../config' |
||||
import type { Playlists } from '../types' |
||||
import { useMatchData } from './useMatchData' |
||||
|
||||
const addScoresFromPlaylists = ( |
||||
profile: MatchInfo, |
||||
playlists: Playlists, |
||||
): MatchInfo => ( |
||||
profile |
||||
? { |
||||
...profile, |
||||
team1: { |
||||
...profile?.team1, |
||||
score: playlists.score1, |
||||
}, |
||||
team2: { |
||||
...profile?.team2, |
||||
score: playlists.score2, |
||||
}, |
||||
} |
||||
: null |
||||
) |
||||
|
||||
export const useMatchProfile = () => { |
||||
const [matchProfile, setMatchProfile] = useState<MatchInfo>(null) |
||||
const { profileId: matchId, sportType } = usePageParams() |
||||
|
||||
const fetchMatchProfile = useCallback(() => { |
||||
useEffect(() => { |
||||
getMatchInfo(sportType, matchId).then(setMatchProfile) |
||||
}, |
||||
[sportType, matchId]) |
||||
}, [sportType, matchId]) |
||||
|
||||
const { start, stop } = useInterval({ |
||||
callback: fetchMatchProfile, |
||||
intervalDuration: MATCH_UPDATE_INTERVAL, |
||||
startImmediate: false, |
||||
}) |
||||
const { events, matchPlaylists } = useMatchData(matchProfile?.live) |
||||
|
||||
useEffect(fetchMatchProfile, [fetchMatchProfile]) |
||||
useEffect(() => { |
||||
if (matchProfile?.live) { |
||||
start() |
||||
} else { |
||||
stop() |
||||
} |
||||
}, [ |
||||
matchProfile, |
||||
start, |
||||
stop, |
||||
]) |
||||
const profile = useMemo( |
||||
() => addScoresFromPlaylists(matchProfile, matchPlaylists), |
||||
[matchProfile, matchPlaylists], |
||||
) |
||||
|
||||
return matchProfile |
||||
return { |
||||
events, |
||||
profile, |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue