Ott 693 popup live mathes copy (#269)
* feat: 🎸 OTT-693 add popup * feat: 🎸 OTT-693 fix style * feat: 🎸 OTT-693 fix style * feat: 🎸 OTT-693 some fix Co-authored-by: Zoia <zizi2405@yandex.ru>keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
parent
bc277fa65d
commit
f6fe9d217b
@ -0,0 +1,52 @@ |
||||
import { Fragment } from 'react' |
||||
|
||||
import { Background } from 'features/Background' |
||||
import { MediaQuery } from 'features/MediaQuery' |
||||
import { useMatchPopupStore } from 'features/MatchPopup' |
||||
|
||||
import { SettingsPage } from '../../components/SettingsPage' |
||||
import { FinishedPlaylistPage } from '../../components/FinishedPlaylistPage' |
||||
import { PopupPages } from '../../types' |
||||
import { Modal } from './styled' |
||||
|
||||
export * from '../../store' |
||||
|
||||
export const FinishedMatchPopup = () => { |
||||
const { |
||||
closePopup, |
||||
isOpen, |
||||
matchPlaylists, |
||||
page, |
||||
} = useMatchPopupStore() |
||||
|
||||
const showPopup = isOpen && Boolean(matchPlaylists) |
||||
|
||||
const pageElement = page === PopupPages.PLAYLIST |
||||
? <FinishedPlaylistPage /> |
||||
: <SettingsPage /> |
||||
|
||||
return ( |
||||
<Fragment> |
||||
<MediaQuery minDevice='tablet'> |
||||
<Modal |
||||
close={closePopup} |
||||
isOpen={showPopup} |
||||
withCloseButton={false} |
||||
> |
||||
{pageElement} |
||||
</Modal> |
||||
</MediaQuery> |
||||
|
||||
<MediaQuery maxDevice='mobile'> |
||||
<Modal |
||||
isOpen={showPopup} |
||||
withCloseButton={false} |
||||
> |
||||
<Background> |
||||
{pageElement} |
||||
</Background> |
||||
</Modal> |
||||
</MediaQuery> |
||||
</Fragment> |
||||
) |
||||
} |
||||
@ -0,0 +1,25 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { devices } from 'config' |
||||
|
||||
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; |
||||
height: 818px; |
||||
padding: 20px 0; |
||||
background-color: #3F3F3F; |
||||
border-radius: 5px; |
||||
|
||||
@media ${devices.mobile} { |
||||
width: 100vw; |
||||
height: 100vh; |
||||
padding: 0; |
||||
background-color: transparent; |
||||
} |
||||
} |
||||
` |
||||
@ -0,0 +1,73 @@ |
||||
import { useState, useEffect } from 'react' |
||||
|
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { devices, PAGES } from 'config' |
||||
import { getSportLexic } from 'helpers' |
||||
import { getMatchLastWatchSeconds, LastPlayPosition } from 'requests' |
||||
|
||||
import { useMatchPopupStore } from 'features/MatchPopup/store' |
||||
|
||||
import { SimplePlaylistButton } from '../SimplePlaylistButton' |
||||
|
||||
const List = styled.ul` |
||||
margin: 40px auto 0px auto; |
||||
width: 100%; |
||||
|
||||
@media ${devices.mobile} { |
||||
margin: 12px auto; |
||||
padding: 0 12px; |
||||
} |
||||
` |
||||
const Item = styled.li` |
||||
margin-bottom: 15px; |
||||
width: 100%; |
||||
height: 50px; |
||||
|
||||
@media ${devices.mobile} { |
||||
height: 36px; |
||||
margin-bottom: 12px; |
||||
} |
||||
` |
||||
export const LiveMatchPlaylist = () => { |
||||
const [lastPlayPosition, setLastPlayPosition] = useState<LastPlayPosition | null>(null) |
||||
const { match, matchPlaylists } = useMatchPopupStore() |
||||
|
||||
useEffect(() => { |
||||
if (match) { |
||||
getMatchLastWatchSeconds(match?.sportType, match?.id) |
||||
.then((lastPlayPositionSecond) => setLastPlayPosition(lastPlayPositionSecond)) |
||||
} |
||||
}, [match]) |
||||
|
||||
if (!match || !matchPlaylists) return null |
||||
|
||||
const sport = getSportLexic(match.sportType) |
||||
return ( |
||||
<List> |
||||
<Item> |
||||
<SimplePlaylistButton |
||||
to={`${sport}${PAGES.match}/${match.id}`} |
||||
title='watch_live_stream' |
||||
/> |
||||
</Item> |
||||
<Item> |
||||
<SimplePlaylistButton |
||||
to={`${sport}${PAGES.match}/${match.id}`} |
||||
title='watch_from_beginning' |
||||
/> |
||||
</Item> |
||||
{lastPlayPosition?.second |
||||
? ( |
||||
<Item> |
||||
<SimplePlaylistButton |
||||
to={`${sport}${PAGES.match}/${match.id}`} |
||||
title='watch_from' |
||||
startWatch={lastPlayPosition?.second} |
||||
/> |
||||
</Item> |
||||
) |
||||
: null} |
||||
</List> |
||||
) |
||||
} |
||||
@ -0,0 +1,41 @@ |
||||
import { Fragment } from 'react' |
||||
|
||||
import { Background } from 'features/Background' |
||||
import { MediaQuery } from 'features/MediaQuery' |
||||
import { useMatchPopupStore } from 'features/MatchPopup' |
||||
|
||||
import { LivePlaylistPage } from '../LivePlaylistPage' |
||||
|
||||
import { Modal } from './styled' |
||||
|
||||
export const LiveMatchPopup = () => { |
||||
const { |
||||
closePopup, |
||||
isOpen, |
||||
} = useMatchPopupStore() |
||||
|
||||
return ( |
||||
<Fragment> |
||||
<MediaQuery minDevice='tablet'> |
||||
<Modal |
||||
close={closePopup} |
||||
isOpen={isOpen} |
||||
withCloseButton={false} |
||||
> |
||||
<LivePlaylistPage /> |
||||
</Modal> |
||||
</MediaQuery> |
||||
|
||||
<MediaQuery maxDevice='mobile'> |
||||
<Modal |
||||
isOpen={isOpen} |
||||
withCloseButton={false} |
||||
> |
||||
<Background> |
||||
<LivePlaylistPage /> |
||||
</Background> |
||||
</Modal> |
||||
</MediaQuery> |
||||
</Fragment> |
||||
) |
||||
} |
||||
@ -0,0 +1,25 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { devices } from 'config' |
||||
|
||||
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: 565px; |
||||
min-height: 310px; |
||||
padding: 20px 35px; |
||||
background-color: #3F3F3F; |
||||
border-radius: 5px; |
||||
|
||||
@media ${devices.mobile} { |
||||
width: 100vw; |
||||
height: 100vh; |
||||
padding: 0; |
||||
background-color: transparent; |
||||
} |
||||
} |
||||
` |
||||
@ -0,0 +1,39 @@ |
||||
import { Name } from 'features/Name' |
||||
import { useMatchPopupStore } from 'features/MatchPopup' |
||||
|
||||
import { CloseButton } from '../CloseButton' |
||||
import { LiveMatchPlaylist } from '../LiveMatchPlaylist' |
||||
|
||||
import { |
||||
Content, |
||||
Header, |
||||
HeaderActions, |
||||
HeaderTitle, |
||||
} from './styled' |
||||
|
||||
export const LivePlaylistPage = () => { |
||||
const { match, matchPlaylists } = useMatchPopupStore() |
||||
if (!match) return null |
||||
|
||||
const { team1, team2 } = match |
||||
|
||||
return ( |
||||
<Content> |
||||
<Header> |
||||
<HeaderTitle> |
||||
<Name nameObj={team1} /> |
||||
{' '} — {' '} |
||||
<Name nameObj={team2} /> |
||||
</HeaderTitle> |
||||
|
||||
<HeaderActions> |
||||
<CloseButton /> |
||||
</HeaderActions> |
||||
</Header> |
||||
|
||||
{ |
||||
matchPlaylists && <LiveMatchPlaylist /> |
||||
} |
||||
</Content> |
||||
) |
||||
} |
||||
@ -0,0 +1,39 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { customScrollbar } from 'features/Common' |
||||
|
||||
export const Content = styled.div` |
||||
width: 495px; |
||||
height: 100%; |
||||
overflow-y: auto; |
||||
${customScrollbar} |
||||
` |
||||
|
||||
export const Header = styled.div` |
||||
display: flex; |
||||
align-items: center; |
||||
` |
||||
|
||||
export const HeaderActions = styled.div` |
||||
position: absolute; |
||||
display: flex; |
||||
top: 20px; |
||||
right: 20px; |
||||
` |
||||
|
||||
export const HeaderTitle = styled.h2` |
||||
margin: 0 auto; |
||||
width: 70%; |
||||
font-weight: 600; |
||||
font-size: 24px; |
||||
line-height: 42px; |
||||
color: #FFFFFF; |
||||
text-align: center; |
||||
` |
||||
|
||||
export const BlockTitle = styled.h3` |
||||
font-weight: normal; |
||||
font-size: 24px; |
||||
line-height: 50px; |
||||
text-transform: capitalize; |
||||
` |
||||
@ -0,0 +1,88 @@ |
||||
import type { MouseEvent } from 'react' |
||||
import { Link } from 'react-router-dom' |
||||
|
||||
import styled from 'styled-components/macro' |
||||
|
||||
import { devices } from 'config' |
||||
import { secondsToHms } from 'helpers' |
||||
|
||||
import { T9n } from 'features/T9n' |
||||
|
||||
const StyledLink = styled(Link)` |
||||
border: none; |
||||
cursor: pointer; |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
width: 100%; |
||||
height: 100%; |
||||
padding: 0 25px; |
||||
background: linear-gradient( |
||||
180deg, |
||||
rgba(255, 255, 255, 0.1) 0%, |
||||
rgba(255, 255, 255, 0) 100% |
||||
), |
||||
#5c5c5c; |
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3); |
||||
border-radius: 2px; |
||||
|
||||
:hover { |
||||
background-color: #555555; |
||||
} |
||||
|
||||
@media ${devices.mobile} { |
||||
justify-content: center; |
||||
border-radius: 5px; |
||||
} |
||||
` |
||||
|
||||
const Title = styled.span` |
||||
font-weight: 500; |
||||
font-size: 20px; |
||||
line-height: 50px; |
||||
letter-spacing: 0.03em; |
||||
color: #ffffff; |
||||
|
||||
@media ${devices.mobile} { |
||||
font-size: 17px; |
||||
line-height: 16px; |
||||
margin-right: 16px; |
||||
text-transform: none; |
||||
} |
||||
` |
||||
|
||||
const Duration = styled(Title)` |
||||
font-weight: 300; |
||||
font-size: 24px; |
||||
letter-spacing: 0.05em; |
||||
|
||||
@media ${devices.mobile} { |
||||
font-size: 17px; |
||||
line-height: 16px; |
||||
text-transform: none; |
||||
} |
||||
` |
||||
|
||||
const stopPropagation = (e: MouseEvent<HTMLAnchorElement>) => e.stopPropagation() |
||||
|
||||
type Props = { |
||||
duration?: number, |
||||
startWatch?: number, |
||||
title: string, |
||||
to: string, |
||||
} |
||||
|
||||
export const SimplePlaylistButton = ({ |
||||
duration, |
||||
startWatch, |
||||
title, |
||||
to, |
||||
}: Props) => ( |
||||
<StyledLink to={to} onClick={stopPropagation}> |
||||
<Title> |
||||
<T9n t={title} /> {startWatch && secondsToHms(startWatch)} |
||||
</Title> |
||||
{duration && <Duration>{secondsToHms(duration)}</Duration>} |
||||
</StyledLink> |
||||
) |
||||
@ -1,52 +1,12 @@ |
||||
import { Fragment } from 'react' |
||||
|
||||
import { Background } from 'features/Background' |
||||
import { MediaQuery } from 'features/MediaQuery' |
||||
import { useMatchPopupStore } from 'features/MatchPopup' |
||||
|
||||
import { SettingsPage } from './components/SettingsPage' |
||||
import { PlaylistPage } from './components/PlaylistPage' |
||||
import { PopupPages } from './types' |
||||
import { Modal } from './styled' |
||||
import { FinishedMatchPopup } from './components/FinishedMatchPopup' |
||||
import { LiveMatchPopup } from './components/LiveMatchPopup' |
||||
|
||||
export * from './store' |
||||
|
||||
export const MatchPopup = () => { |
||||
const { |
||||
closePopup, |
||||
isOpen, |
||||
matchPlaylists, |
||||
page, |
||||
} = useMatchPopupStore() |
||||
|
||||
const showPopup = isOpen && Boolean(matchPlaylists) |
||||
|
||||
const pageElement = page === PopupPages.PLAYLIST |
||||
? <PlaylistPage /> |
||||
: <SettingsPage /> |
||||
|
||||
return ( |
||||
<Fragment> |
||||
<MediaQuery minDevice='tablet'> |
||||
<Modal |
||||
close={closePopup} |
||||
isOpen={showPopup} |
||||
withCloseButton={false} |
||||
> |
||||
{pageElement} |
||||
</Modal> |
||||
</MediaQuery> |
||||
const { match } = useMatchPopupStore() |
||||
|
||||
<MediaQuery maxDevice='mobile'> |
||||
<Modal |
||||
isOpen={showPopup} |
||||
withCloseButton={false} |
||||
> |
||||
<Background> |
||||
{pageElement} |
||||
</Background> |
||||
</Modal> |
||||
</MediaQuery> |
||||
</Fragment> |
||||
) |
||||
return match?.live ? <LiveMatchPopup /> : <FinishedMatchPopup /> |
||||
} |
||||
|
||||
Loading…
Reference in new issue