feat(ott-1761): check internet connection (#551)

Co-authored-by: boyvanov <boyvanov.sergey@gmail.com>
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
boyvanov 4 years ago committed by Mirlan
parent 77daf294b8
commit 94977f3df1
  1. 2
      src/config/lexics/indexLexics.tsx
  2. 54
      src/features/App/AuthenticatedApp.tsx
  3. 5
      src/features/Background/index.tsx
  4. 13
      src/features/MultiSourcePlayer/hooks/index.tsx
  5. 32
      src/features/NoNetworkPopup/index.tsx
  6. 23
      src/features/NoNetworkPopup/store/hooks/index.tsx
  7. 20
      src/features/NoNetworkPopup/store/index.tsx
  8. 81
      src/features/NoNetworkPopup/styled.tsx
  9. 20
      src/features/StreamPlayer/hooks/index.tsx

@ -75,6 +75,7 @@ export const indexLexics = {
available_matches_shown: 13385,
basketball: 6960,
broadcast: 13049,
check_connection: 15700,
cm: 817,
features: 13051,
football: 6958,
@ -96,6 +97,7 @@ export const indexLexics = {
live: 13024,
loading: 3527,
logout: 4306,
lost_connection: 15699,
match_status_finished: 12985,
match_status_live: 12984,
match_status_soon: 12986,

@ -20,6 +20,7 @@ import { MatchPopup, MatchPopupStore } from 'features/MatchPopup'
import { BuyMatchPopup, BuyMatchPopupStore } from 'features/BuyMatchPopup'
import { PreferencesPopup, PreferencesPopupStore } from 'features/PreferencesPopup'
import { CardsStore } from 'features/CardsStore'
import { NoNetworkPopup, NoNetworkPopupStore } from 'features/NoNetworkPopup'
const HomePage = lazy(() => import('features/HomePage'))
const UserAccount = lazy(() => import('features/UserAccount'))
@ -40,32 +41,35 @@ export const AuthenticatedApp = () => {
<PreferencesPopupStore>
<MatchPopupStore>
<BuyMatchPopupStore>
<MatchPopup />
<BuyMatchPopup />
<PreferencesPopup />
<NoNetworkPopupStore>
<MatchPopup />
<BuyMatchPopup />
<PreferencesPopup />
<NoNetworkPopup />
{/* в Switch как прямой children можно рендерить только Route или Redirect */}
<Switch>
<Route path={PAGES.useraccount}>
<UserAccount />
</Route>
<Route exact path={PAGES.home}>
<HomePage />
</Route>
<Route path={`/:sportName${PAGES.tournament}/:pageId`}>
<TournamentPage />
</Route>
<Route path={`/:sportName${PAGES.team}/:pageId`}>
<TeamPage />
</Route>
<Route path={`/:sportName${PAGES.player}/:pageId`}>
<PlayerPage />
</Route>
<Route path={`/:sportName${PAGES.match}/:pageId`}>
<MatchPage />
</Route>
<Redirect to={PAGES.home} />
</Switch>
{/* в Switch как прямой children можно рендерить только Route или Redirect */}
<Switch>
<Route path={PAGES.useraccount}>
<UserAccount />
</Route>
<Route exact path={PAGES.home}>
<HomePage />
</Route>
<Route path={`/:sportName${PAGES.tournament}/:pageId`}>
<TournamentPage />
</Route>
<Route path={`/:sportName${PAGES.team}/:pageId`}>
<TeamPage />
</Route>
<Route path={`/:sportName${PAGES.player}/:pageId`}>
<PlayerPage />
</Route>
<Route path={`/:sportName${PAGES.match}/:pageId`}>
<MatchPage />
</Route>
<Redirect to={PAGES.home} />
</Switch>
</NoNetworkPopupStore>
</BuyMatchPopupStore>
</MatchPopupStore>
</PreferencesPopupStore>

@ -1,5 +1,7 @@
import { ReactNode } from 'react'
import { FakeArrowLoader } from 'features/NoNetworkPopup/styled'
import { GradientBackground, ImageBackground } from './styled'
type Props = {
@ -9,6 +11,9 @@ type Props = {
export const Background = ({ children }: Props) => (
<ImageBackground>
<GradientBackground>
{/* FakeArrowLoader пришлось добавить, чтобы при отсутствии интернета
всегда была доступена svg arrowGroup для отображения лоадера в NoNetwork */}
<FakeArrowLoader />
{children}
</GradientBackground>
</ImageBackground>

@ -10,6 +10,7 @@ import size from 'lodash/size'
import { useControlsVisibility } from 'features/StreamPlayer/hooks/useControlsVisibility'
import { useFullscreen } from 'features/StreamPlayer/hooks/useFullscreen'
import { useVolume } from 'features/VideoPlayer/hooks/useVolume'
import { useNoNetworkPopupStore } from 'features/NoNetworkPopup'
import { useObjectState } from 'hooks'
@ -70,6 +71,7 @@ export const useMultiSourcePlayer = ({
onReady,
playNextChapter,
playPrevChapter,
stopPlaying,
togglePlaying,
} = usePlayingHandlers(setPlayerState, numberOfChapters)
@ -203,6 +205,17 @@ export const useMultiSourcePlayer = ({
playNextChapter,
])
const { isOnline } = useNoNetworkPopupStore()
useEffect(() => {
if (!isOnline) {
stopPlaying()
}
}, [
isOnline,
stopPlaying,
])
return {
activeChapterIndex,
activePlayer,

@ -0,0 +1,32 @@
import { useNoNetworkPopupStore } from 'features/NoNetworkPopup'
import { Background } from 'features/Background'
import {
ArrowLoader,
Container,
Logo,
SubTitle,
Title,
Wrapper,
} from './styled'
export * from './store'
export const NoNetworkPopup = () => {
const { isOnline } = useNoNetworkPopupStore()
if (isOnline) return null
return (
<Wrapper>
<Background>
<Container>
<Logo />
<ArrowLoader />
<Title t='lost_connection' />
<SubTitle t='check_connection' />
</Container>
</Background>
</Wrapper>
)
}

@ -0,0 +1,23 @@
import { useState } from 'react'
import { useEventListener } from 'hooks'
export const useNetwork = () => {
const [isOnline, setNetwork] = useState(window.navigator.onLine)
const updateNetwork = () => {
setNetwork(window.navigator.onLine)
}
useEventListener({
callback: updateNetwork,
event: 'offline',
})
useEventListener({
callback: updateNetwork,
event: 'online',
})
return { isOnline }
}

@ -0,0 +1,20 @@
import type { ReactNode } from 'react'
import { createContext, useContext } from 'react'
import { useNetwork } from './hooks'
type Context = ReturnType<typeof useNetwork>
type Props = { children: ReactNode }
const NoNetworkPopupContext = createContext({} as Context)
export const NoNetworkPopupStore = ({ children }: Props) => {
const value = useNetwork()
return (
<NoNetworkPopupContext.Provider value={value}>
{children}
</NoNetworkPopupContext.Provider>
)
}
export const useNoNetworkPopupStore = () => useContext(NoNetworkPopupContext)

@ -0,0 +1,81 @@
import styled from 'styled-components/macro'
import { Arrows } from 'features/ArrowLoader/styled'
import { T9n } from 'features/T9n'
export const Wrapper = styled.div`
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
z-index: 1000;
`
export const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #FFFFFF;
`
export const Logo = styled.div`
width: 234px;
height: 54px;
background-size: contain;
background-repeat: no-repeat;
background-image: url(/images/logo.svg);
margin-bottom: 87px;
@media (max-width: 850px) {
width: 144px;
height: 33px;
margin-bottom: 54px;
}
`
export const FakeArrowLoader = styled.div`
width: 0;
height: 0;
visibility: hidden;
background-image: url(/images/arrowGroup.svg);
`
export const ArrowLoader = styled(Arrows)`
width: 94px;
height: 87px;
@media (max-width: 850px) {
width: 58px;
height: 54px;
}
`
export const Title = styled(T9n)`
font-weight: bold;
font-size: 24px;
line-height: 24px;
margin-top: 87px;
@media (max-width: 850px) {
font-size: 14px;
line-height: 15px;
margin-top: 54px;
}
`
export const SubTitle = styled(T9n)`
font-weight: 500;
font-size: 16px;
line-height: 20px;
letter-spacing: 0.03em;
opacity: 0.8;
margin-top: 12px;
@media (max-width: 850px) {
font-size: 10px;
line-height: 12px;
margin-top: 7px;
}
`

@ -1,10 +1,15 @@
import type { MouseEvent } from 'react'
import { useCallback, useMemo } from 'react'
import {
useCallback,
useEffect,
useMemo,
} from 'react'
import once from 'lodash/once'
import { useVolume } from 'features/VideoPlayer/hooks/useVolume'
import { REWIND_SECONDS } from 'features/MultiSourcePlayer/config'
import { useNoNetworkPopupStore } from 'features/NoNetworkPopup'
import { useObjectState } from 'hooks'
@ -112,6 +117,19 @@ export const useVideoPlayer = ({
setPlayerState({ playedProgress: liveProgressMs, seek: liveProgressMs / 1000 })
}, [duration, setPlayerState])
const { isOnline } = useNoNetworkPopupStore()
useEffect(() => {
if (!isOnline) {
setPlayerState({ playing: false })
onPlayingChange(false)
}
}, [
isOnline,
onPlayingChange,
setPlayerState,
])
return {
backToLive,
duration,

Loading…
Cancel
Save