feat(#168): add video download process

andreidekterev 3 years ago
parent d07278d785
commit 54f12db5b7
  1. 4
      src/config/lexics/matchDownload.tsx
  2. 1
      src/config/queries.tsx
  3. 98
      src/features/MatchPage/components/MatchDownloadPopup/index.tsx
  4. 23
      src/features/MatchPage/components/MatchDownloadPopup/styled.tsx
  5. 59
      src/features/MatchSidePlaylists/components/DownloadNotification/DownloadNotification.tsx
  6. 49
      src/features/MatchSidePlaylists/components/DownloadNotification/styled.tsx
  7. 6
      src/features/MatchSidePlaylists/components/MatchDownloadButton/index.tsx
  8. 17
      src/features/MatchSidePlaylists/components/MatchPlaylists/index.tsx
  9. 17
      src/features/MatchSidePlaylists/styled.tsx
  10. 38
      src/requests/downloadPlaylist.tsx

@ -1,8 +1,12 @@
export const matchDownload = {
can_close: 20238,
choose_what_to_download: 20193,
download_files_for_periods: 20197,
download_full_match: 20198,
download_single_file: 20196,
entire_record: 20195,
error_message: 20240,
in_game_time_only: 20194,
processed: 20200,
will_notified: 20239,
}

@ -1,4 +1,5 @@
export const querieKeys = {
downloadPlaylist: 'downloadPlaylist',
liveMatchScores: 'liveMatchScores',
matchScore: 'matchScore',
sportsList: 'sportsList',

@ -1,7 +1,18 @@
import { useState } from 'react'
import { useQuery } from 'react-query'
import { T9n } from 'features/T9n'
import { usePageParams } from 'hooks'
import { querieKeys } from 'config'
import {
downloadPlaylist,
type DownloadPlaylistProps,
} from 'requests/downloadPlaylist'
import { Radio } from 'features/Common'
import {
Header,
Footer,
@ -13,20 +24,73 @@ import {
FirstTitle,
SecondTitle,
RadioButtonsWrapper,
Input,
Label,
} from './styled'
type Props = {
closePopup: () => void,
isModalOpen: boolean,
openDownloadNotification: () => void,
}
const fileType: Record<'download_single_file'| 'download_files_for_periods', string> = {
download_files_for_periods: 'download_files_for_periods',
download_single_file: 'download_single_file',
}
const initialRadioBtns: Record<string, boolean> = {
// надо именно такую сортировку
in_game_time_only: true,
// eslint-disable-next-line sort-keys
entire_record: false,
}
export const MatchDownloadPopup = ({
closePopup,
isModalOpen,
openDownloadNotification,
}: Props) => {
const [selected, setSelected] = useState(true)
const [downloadConfig, setDownloadConfig] = useState<typeof initialRadioBtns>(initialRadioBtns)
const { profileId: match_id, sportType: sport_id } = usePageParams()
useQuery(
querieKeys.downloadPlaylist,
() => handleDownload(fileType.download_files_for_periods),
{
enabled: false, // disable this query from automatically running
refetchOnWindowFocus: false,
},
)
const handleDownload = async (id = fileType.download_single_file) => {
const config: DownloadPlaylistProps = {
ball_in_play: downloadConfig.entire_record,
match_id,
sport_id,
}
if (downloadConfig.entire_record) {
config.concat = fileType.download_single_file === id
}
try {
const links = await downloadPlaylist(config)
closePopup()
openDownloadNotification()
return links
} catch (e) {
return null
}
}
const handleChange = (id: string) => {
setDownloadConfig((prev) => Object.keys(prev)
.reduce((result: typeof initialRadioBtns, key: keyof typeof initialRadioBtns) => ({
...result,
[key]: id === key,
}), {} as typeof initialRadioBtns))
}
return (
<Modal
@ -42,28 +106,28 @@ export const MatchDownloadPopup = ({
</HeaderTitle>
</Header>
<RadioButtonsWrapper>
{Object.entries(downloadConfig).map(([id, checked], index) => (
<Label>
<Input
defaultChecked={selected}
name='in_game_time_only'
onClick={() => setSelected(true)}
<Radio
name={id}
key={id}
checked={checked}
onChange={(e) => handleChange(e.target.name)}
/>
<T9n t='in_game_time_only' />
</Label>
<Label>
<Input
name='entire_record'
defaultChecked={!selected}
onClick={() => setSelected(false)}
/>
<T9n t='entire_record' />
<T9n t={id} />
</Label>
))}
</RadioButtonsWrapper>
<Footer>
<ScApplyButton>
<ScApplyButton
onClick={() => handleDownload(fileType.download_single_file)}
>
<T9n t='download_single_file' />
</ScApplyButton>
<ScApplyButton disabled={!selected}>
<ScApplyButton
disabled={!downloadConfig.entire_record}
onClick={() => handleDownload(fileType.download_files_for_periods)}
>
<T9n t='download_files_for_periods' />
</ScApplyButton>
</Footer>

@ -100,29 +100,6 @@ export const Label = styled.label`
font-size: 14px;`
: ''};
`
export const Input = styled.input.attrs(() => ({
type: 'radio',
}))`
margin: 0 25px 0 0;
appearance: none;
width: 25px;
height: 25px;
cursor: pointer;
background-image: url(/images/${({ defaultChecked }) => (
defaultChecked
? 'checkedRadiobutton.png'
: 'radiobutton.png'
)});
${isMobileDevice
? css`
margin-right: 10px;`
: ''};
`
export const Footer = styled.div``
export const ScApplyButton = styled(ApplyButton)`

@ -0,0 +1,59 @@
import { useQueryClient } from 'react-query'
import { T9n } from 'features/T9n'
import { querieKeys } from 'config'
import { DownloadResponse } from 'requests/downloadPlaylist'
import {
Container,
Description,
Title,
CloseBtn,
Header,
MainContainer,
LinkToDownload,
Error,
} from './styled'
type TDownloadNotification = {
close: () => void,
}
export const DownloadNotification = ({ close }:TDownloadNotification) => {
const client = useQueryClient()
const data = client.getQueryData<DownloadResponse>(querieKeys.downloadPlaylist)
return (
<Container>
<Header>
<CloseBtn
onClick={close}
/>
</Header>
<MainContainer>
<Title>
<T9n t='processed' />
</Title>
<Description>
{data?.status === 'ERROR'
? (
<>
<T9n t='can_close' />&nbsp;
<T9n t='will_notified' />&nbsp;
<LinkToDownload href='/useraccount/downloads'>
My Videos
</LinkToDownload>
</>
) : (
<Error>
<T9n t='error_message' />
</Error>
)}
</Description>
</MainContainer>
</Container>
)
}

@ -0,0 +1,49 @@
import styled from 'styled-components/macro'
import { CloseButton } from 'features/PopupComponents'
export const Container = styled.section`
width: 100%;
border-radius: 0.125rem;
background: #333;
padding: 0.5rem 0.5rem ;
color: #FFF;
font-weight: 400;
line-height: normal;
font-size: 0.75rem;
margin-bottom: 0.45rem;
`
export const Title = styled.h3`
font-size: 0.875rem;
font-style: normal;
font-weight: 700;
line-height: 1.875rem;
margin-bottom: 0.56rem;
`
export const Description = styled.span`
`
export const CloseBtn = styled(CloseButton)`
padding: 4px;
`
export const Header = styled.header`
display: flex;
justify-content: end;
`
export const MainContainer = styled.main`
padding: 0.4rem 1.1rem 2rem 1.3rem;
`
export const LinkToDownload = styled.a`
text-decoration: underline;
cursor: pointer;
color: white;
font-weight: 600;
`
export const Error = styled.span`
color: red;
`

@ -14,7 +14,10 @@ import { usePageParams } from 'hooks/usePageParams'
import { Item } from '../MatchPlaylists'
import { DownloadButton, Title } from '../../styled'
export const MatchDownloadButton = () => {
type TMatchDownloadButton = {
open: () => void,
}
export const MatchDownloadButton = ({ open: openDownloadNotification }:TMatchDownloadButton) => {
const { user, userInfo } = useAuthStore()
const { profile } = useMatchPageStore()
const { sportType } = usePageParams()
@ -56,6 +59,7 @@ export const MatchDownloadButton = () => {
<MatchDownloadPopup
isModalOpen={isOpen}
closePopup={close}
openDownloadNotification={openDownloadNotification}
/>
<DownloadButton onClick={open}>
<Title>

@ -19,6 +19,8 @@ import { T9n } from 'features/T9n'
import { useMatchPageStore } from 'features/MatchPage/store'
import { useLexicsStore } from 'features/LexicsStore'
import { DownloadNotification } from 'features/MatchSidePlaylists/components/DownloadNotification/DownloadNotification'
import { useToggle } from 'hooks'
import { PlayButton } from '../PlayButton'
import { MatchDownloadButton } from '../MatchDownloadButton'
@ -64,6 +66,11 @@ export const MatchPlaylists = forwardRef(
) => {
const { setEpisodeInfo } = useMatchPageStore()
const { translate } = useLexicsStore()
const {
close,
isOpen,
open,
} = useToggle()
const handleButtonClick = (playlist: MatchPlaylistOption) => {
onSelect?.(playlist)
@ -77,8 +84,9 @@ export const MatchPlaylists = forwardRef(
return (
<List ref={ref}>
{
map(playlists, (playlist) => (
{isOpen
? (<DownloadNotification close={close} />)
: map(playlists, (playlist) => (
<Item
key={playlist.id}
id={`match_watch_${playlist.id}${live ? '_live' : ''}`}
@ -93,9 +101,8 @@ export const MatchPlaylists = forwardRef(
<T9n t={playlist.lexic} />
</PlayButton>
</Item>
))
}
<MatchDownloadButton />
))}
<MatchDownloadButton open={open} />
</List>
)
},

@ -6,7 +6,7 @@ import {
devices,
} from 'config'
import { customScrollbar } from 'features/Common'
import { ButtonOutline, customScrollbar } from 'features/Common'
import { T9n } from 'features/T9n'
type WrapperProps = {
@ -219,19 +219,16 @@ export const Button = styled.button<ButtonProps>`
}}
`
export const DownloadButton = styled(Button)`
export const DownloadButton = styled(ButtonOutline)`
width: 100%;
height: 2.25rem;
font-size: 0.875rem;
font-weight: 600;
line-height: 1rem;
:hover {
background-color: ${({ theme }) => theme.colors.buttonHover};
}
${({ active }) => (active
? css`
border: 1px solid #FFFFFF;
border-radius: 2px;
background-color: black;
`
: '')}
`
export const Title = styled.span`

@ -0,0 +1,38 @@
import { API_ROOT } from 'config'
import { callApi } from 'helpers'
export type DownloadPlaylistProps = {
ball_in_play: boolean,
concat?: boolean,
match_id: number,
sport_id: number,
}
type Status = 'COMPLETED' | 'IN PROGRESS' | 'ERROR'
export type DownloadResponse = {
status:Status,
urls?: Array<string>,
}
export const downloadPlaylist = async (
{
ball_in_play,
concat,
match_id,
sport_id,
}: DownloadPlaylistProps,
)
: Promise<DownloadResponse> => {
const config = {
body: {
ball_in_play,
concat,
},
}
return callApi({
config,
url: `${API_ROOT}/v1/matches/${sport_id}/${match_id}/download`,
})
}
Loading…
Cancel
Save