diff --git a/public/index.html b/public/index.html index 7dc762a1..40479a86 100644 --- a/public/index.html +++ b/public/index.html @@ -42,6 +42,13 @@ name="msapplication-config" content="%PUBLIC_URL%/clients/%REACT_APP_CLIENT%/favicon/browserconfig.xml" /> <% } %> + + + @@ -59,18 +66,11 @@ - - - - + diff --git a/src/config/procedures.tsx b/src/config/procedures.tsx index 834ef537..de9aa619 100644 --- a/src/config/procedures.tsx +++ b/src/config/procedures.tsx @@ -21,7 +21,6 @@ export const PROCEDURES = { get_user_agreemens: 'get_user_agreemens', get_user_favorites: 'get_user_favorites', get_user_info: 'get_user_info', - get_user_match_second: 'get_user_match_second', get_user_payments: 'get_user_payments', get_user_preferences: 'get_user_preferences', get_user_subscribes: 'get_user_subscribes', @@ -37,7 +36,6 @@ export const PROCEDURES = { save_user_custom_subscription: 'save_user_custom_subscription', save_user_favorite: 'save_user_favorite', save_user_info: 'save_user_info', - save_user_match_second: 'save_user_match_second', save_user_page: 'save_user_page', save_user_preferences: 'save_user_preferences', save_user_subscription: 'save_user_subscription', diff --git a/src/features/AddCardForm/components/Form/hooks/index.tsx b/src/features/AddCardForm/components/Form/hooks/index.tsx index b1f96bd5..6516d7be 100644 --- a/src/features/AddCardForm/components/Form/hooks/index.tsx +++ b/src/features/AddCardForm/components/Form/hooks/index.tsx @@ -104,6 +104,8 @@ export const useFormSubmit = ({ const [inputStates, setInputStates] = useObjectState(initialState) const [errorMessage, setErrorMessage] = useState('') const [loader, setLoader] = useState(false) + const [typedCountry, setTypedCountry] = useState('') + const dataHighlights = useRecoilValue(dataForPayHighlights) const { @@ -161,7 +163,7 @@ export const useFormSubmit = ({ } } - const onCountryChange = useCallback((country: SelectedCountry) => { + const onCountrySelect = useCallback((country: SelectedCountry) => { resetErrors() if (country?.id === selectedCountry?.id) return setSelectedCountry(country) @@ -178,6 +180,10 @@ export const useFormSubmit = ({ setSelectedState, ]) + const onChangeCountry = (e: ChangeEvent) => { + setTypedCountry(e.target.value) + } + const onStateSelect = useCallback((state: SelectedState) => { resetErrors() if (state?.id === selectedState?.id) return @@ -334,8 +340,9 @@ export const useFormSubmit = ({ loader, name, onAddressChange, + onChangeCountry, onCityChange, - onCountryChange, + onCountrySelect, onInputsBlur, onInputsChange, onInputsFocus, @@ -344,6 +351,7 @@ export const useFormSubmit = ({ onStateSelect, selectedCountry, selectedState, + typedCountry, usaStateValue, usaStates, } diff --git a/src/features/AddCardForm/components/Form/hooks/useCountries.tsx b/src/features/AddCardForm/components/Form/hooks/useCountries.tsx index 6a54a716..8e568d1f 100644 --- a/src/features/AddCardForm/components/Form/hooks/useCountries.tsx +++ b/src/features/AddCardForm/components/Form/hooks/useCountries.tsx @@ -19,6 +19,8 @@ export type SelectedState = (UsaStateType & { name: string, }) | null +export const USA_ID = 194 + const useCountriesList = () => { const [countries, setCountries] = useState([]) @@ -47,7 +49,7 @@ export const useCountries = () => { ) useEffect(() => { - if (selectedCountry?.id === 194) { + if (selectedCountry?.id === USA_ID) { (async () => { const states = await getUsaStates() setUsaStates(states) diff --git a/src/features/AddCardForm/components/Form/index.tsx b/src/features/AddCardForm/components/Form/index.tsx index 339df9ad..2242886a 100644 --- a/src/features/AddCardForm/components/Form/index.tsx +++ b/src/features/AddCardForm/components/Form/index.tsx @@ -1,8 +1,8 @@ import { useRouteMatch } from 'react-router-dom' import { - CardNumberElement, - CardExpiryElement, CardCvcElement, + CardExpiryElement, + CardNumberElement, } from '@stripe/react-stripe-js' import { isMobileDevice } from 'config/userAgent' @@ -16,7 +16,8 @@ import { SolidButton } from 'features/UserAccount/styled' import { ElementContainer } from '../ElementContainer' import type { Props } from './hooks' -import { useFormSubmit, ElementTypes } from './hooks' +import { ElementTypes, useFormSubmit } from './hooks' +import { USA_ID } from './hooks/useCountries' import { Form, @@ -81,8 +82,9 @@ export const AddCardFormInner = (props: Props) => { loader, name, onAddressChange, + onChangeCountry, onCityChange, - onCountryChange, + onCountrySelect, onInputsBlur, onInputsChange, onInputsFocus, @@ -91,11 +93,12 @@ export const AddCardFormInner = (props: Props) => { onStateSelect, selectedCountry, selectedState, + typedCountry, usaStates, usaStateValue, } = useFormSubmit(props) - const isUsaCountry = selectedCountry?.id === 194 + const isUsaCountry = selectedCountry?.id === USA_ID return (
@@ -166,14 +169,20 @@ export const AddCardFormInner = (props: Props) => { {isUsaCountry && ( diff --git a/src/features/AddCardForm/styled.tsx b/src/features/AddCardForm/styled.tsx index 40cffe8e..6adfba47 100644 --- a/src/features/AddCardForm/styled.tsx +++ b/src/features/AddCardForm/styled.tsx @@ -133,5 +133,11 @@ export const CustomCombobox = styled(Combobox)` ${PopOver}{ top: 55px; max-height: 300px; + + ${isMobileDevice + ? css` + top: 30px; + ` + : ''}; } ` as typeof Combobox diff --git a/src/features/Combobox/hooks/index.tsx b/src/features/Combobox/hooks/index.tsx index 70d11b37..2b6a05c8 100644 --- a/src/features/Combobox/hooks/index.tsx +++ b/src/features/Combobox/hooks/index.tsx @@ -32,6 +32,7 @@ export const useCombobox = ({ noSearch, onBlur, onChange, + onFocus, onSelect, options, selected, @@ -104,6 +105,11 @@ export const useCombobox = ({ onBlur?.(event) } + const onInputFocus = (event: FocusEvent) => { + open() + onFocus?.(event) + } + useEffect(() => { const selectedIndex = findIndex(filteredOptions, ({ name }) => name === query) setIndex(selectedIndex) @@ -138,6 +144,7 @@ export const useCombobox = ({ inputFieldRef, isOpen, onInputBlur, + onInputFocus, onKeyDown, onOptionSelect, onOutsideClick, diff --git a/src/features/Combobox/index.tsx b/src/features/Combobox/index.tsx index 3590f4d7..653750e7 100644 --- a/src/features/Combobox/index.tsx +++ b/src/features/Combobox/index.tsx @@ -61,6 +61,7 @@ export const Combobox = (props: Props) => { inputFieldRef, isOpen, onInputBlur, + onInputFocus, onKeyDown, onOptionSelect, onOutsideClick, @@ -102,7 +103,7 @@ export const Combobox = (props: Props) => { ({ padding-left: 24px; color: ${({ theme }) => theme.colors.white70}; background-color: transparent; - text-transform: capitalize; ${({ isHighlighted }) => isHighlighted && css` color: ${({ theme }) => theme.colors.white}; @@ -74,10 +73,6 @@ export const WrapperIcon = styled.span` : ''}; ` -export const ScAudioWrap = styled.div` - margin-left: 20px; -` - export const ScLoaderWrapper = styled.div` border-radius: 10px; display: flex; diff --git a/src/features/Combobox/types.tsx b/src/features/Combobox/types.tsx index 301d9c48..9a6bbe65 100644 --- a/src/features/Combobox/types.tsx +++ b/src/features/Combobox/types.tsx @@ -18,6 +18,7 @@ export type Props = Pick, ( | 'title' | 'placeholder' | 'onBlur' + | 'onFocus' )> & { className?: string, customListStyles?: CustomStyles, diff --git a/src/features/Common/Input/styled.tsx b/src/features/Common/Input/styled.tsx index 38fa2d07..09a00744 100644 --- a/src/features/Common/Input/styled.tsx +++ b/src/features/Common/Input/styled.tsx @@ -129,7 +129,6 @@ const inputStyles = css` export const InputStyled = styled.input` ${inputStyles} opacity: ${({ disabled }) => (disabled ? 0.5 : 1)}; - text-transform: capitalize; ::placeholder { opacity: 0; diff --git a/src/features/Landings/styled.tsx b/src/features/Landings/styled.tsx index 9cee03a1..c70d530b 100644 --- a/src/features/Landings/styled.tsx +++ b/src/features/Landings/styled.tsx @@ -182,6 +182,7 @@ export const SliderImg = styled.img` 100% { transform: scale(1.1); } + } ` export const SliderSwitch = styled.div` @@ -276,9 +277,10 @@ export const TournamentTitle = styled.div` ` export const TournamentButton = styled(ButtonSolid)` - width: 320px; + min-width: 320px; + width: fit-content; height: fit-content; - font-size: 1.13rem;; + font-size: 1.13rem; font-weight: 600; border-radius: 5px; margin-bottom: 4.25rem; @@ -290,6 +292,7 @@ export const TournamentButton = styled(ButtonSolid)` ${isMobileDevice ? css` width: 100%; + min-width: 100%; font-size: 17px; padding: 10px 0; margin-bottom: 0; diff --git a/src/features/MatchPage/components/LiveMatch/hooks/index.tsx b/src/features/MatchPage/components/LiveMatch/hooks/index.tsx index e41669e7..1f3a5919 100644 --- a/src/features/MatchPage/components/LiveMatch/hooks/index.tsx +++ b/src/features/MatchPage/components/LiveMatch/hooks/index.tsx @@ -4,11 +4,11 @@ import { API_ROOT } from 'config' import { readToken } from 'helpers/token' -import { usePageParams } from 'hooks/usePageParams' +import { usePageParams } from 'hooks' import { useMatchPageStore } from 'features/MatchPage/store' -import { usePlayerProgressReporter } from './usePlayerProgressReporter' +import { MatchSecondType, usePlayerProgressReporter } from './usePlayerProgressReporter' import { useResumeUrlParam } from './useResumeUrlParam' import { useChapters } from './useChapters' import { usePlaylistLogger } from './usePlaylistLogger' @@ -21,15 +21,17 @@ export const useLiveMatch = () => { setFullMatchPlaylistDuration, } = useMatchPageStore() const { profileId: matchId, sportType } = usePageParams() - const resume = useResumeUrlParam() + const resumeFromParam = useResumeUrlParam() - const fromStartIfStreamPaused = useMemo( - () => (profile && !profile.live ? 0 : undefined), - // deps намеренно оставляем пустым, - // не нужно реагировать на изменение live когда пользователь смотрит матч - // eslint-disable-next-line react-hooks/exhaustive-deps - [], - ) + const resumeFromLocalStorage = useMemo(() => { + const lastSecondLS = localStorage.getItem('matchLastWatchSecond') + const matchesLastWatchSecond: MatchSecondType | null = lastSecondLS && JSON.parse(lastSecondLS) + // undefined означает, что юзер будет смотреть лайв + return profile && !profile.live + ? matchesLastWatchSecond?.[sportType]?.[matchId]?.lastWatchSecond || 0 + : undefined + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [profile]) const { chapters } = useChapters({ profile, @@ -69,7 +71,7 @@ export const useLiveMatch = () => { onPlayerProgressChange, onPlayingChange, onPlaylistSelect, - resume: resume ?? fromStartIfStreamPaused, + resume: resumeFromParam ?? resumeFromLocalStorage, streamUrl: `${API_ROOT}/video/stream/${sportType}/${matchId}.m3u8`, } } diff --git a/src/features/MatchPage/components/LiveMatch/hooks/useLastPlayPosition.tsx b/src/features/MatchPage/components/LiveMatch/hooks/useLastPlayPosition.tsx deleted file mode 100644 index 885f0470..00000000 --- a/src/features/MatchPage/components/LiveMatch/hooks/useLastPlayPosition.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { useEffect, useState } from 'react' - -import type { LastPlayPosition } from 'requests' -import { getMatchLastWatchSeconds } from 'requests' - -import { usePageParams } from 'hooks/usePageParams' -import { useRequest } from 'hooks/useRequest' - -const initialPosition = { - half: 0, - second: 0, -} - -export const useLastPlayPosition = () => { - const { profileId: matchId, sportType } = usePageParams() - const [ - lastPlayPosition, - setPosition, - ] = useState(initialPosition) - const { - isFetching: isLastPlayPositionFetching, - request: requestLastPlayPosition, - } = useRequest(getMatchLastWatchSeconds) - - useEffect(() => { - requestLastPlayPosition(sportType, matchId).then(setPosition) - }, [ - sportType, - matchId, - requestLastPlayPosition, - ]) - - return { - isLastPlayPositionFetching, - lastPlayPosition, - } -} diff --git a/src/features/MatchPage/components/LiveMatch/hooks/usePlayerProgressReporter.tsx b/src/features/MatchPage/components/LiveMatch/hooks/usePlayerProgressReporter.tsx index b393f8f3..52272ad9 100644 --- a/src/features/MatchPage/components/LiveMatch/hooks/usePlayerProgressReporter.tsx +++ b/src/features/MatchPage/components/LiveMatch/hooks/usePlayerProgressReporter.tsx @@ -1,25 +1,41 @@ import { useCallback, useRef } from 'react' -import { reportPlayerProgress } from 'requests' - import { usePageParams } from 'hooks/usePageParams' import { useInterval } from 'hooks/useInterval' const reportRequestInterval = 30000 +export type MatchSecondType = { + [sportType: number]: { + [matchId: number]: { + lastWatchSecond: number, + period: number, + }, + }, +} + export const usePlayerProgressReporter = () => { const { profileId: matchId, sportType } = usePageParams() const playerData = useRef({ period: 0, seconds: 0 }) const intervalCallback = () => { const { period, seconds } = playerData.current - reportPlayerProgress({ - half: period, - matchId, - seconds, - sport: sportType, - }) + + const matchSecond = localStorage.getItem('matchLastWatchSecond') + const matchSecondParsed: MatchSecondType = matchSecond ? JSON.parse(matchSecond) : {} + + localStorage.setItem('matchLastWatchSecond', JSON.stringify({ + ...matchSecondParsed, + [sportType]: { + ...matchSecondParsed?.[sportType], + [matchId]: { + lastWatchSecond: seconds, + period, + }, + }, + })) } + const { start, stop } = useInterval({ callback: intervalCallback, intervalDuration: reportRequestInterval, diff --git a/src/features/MatchPage/components/LiveMatch/hooks/useUrlParam.tsx b/src/features/MatchPage/components/LiveMatch/hooks/useUrlParam.tsx deleted file mode 100644 index 158b1fba..00000000 --- a/src/features/MatchPage/components/LiveMatch/hooks/useUrlParam.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { useMemo } from 'react' -import { useLocation } from 'react-router' - -import isNumber from 'lodash/isNumber' - -export const RESUME_KEY = 'resume' - -const readResumeParam = (search: string) => { - const params = new URLSearchParams(search) - const rawValue = params.get(RESUME_KEY) - if (!rawValue) return undefined - - const value = JSON.parse(rawValue) - return isNumber(value) ? value : 0 -} - -export const useUrlParam = () => { - const { search } = useLocation() - - const resume = useMemo(() => readResumeParam(search), [search]) - - return resume -} diff --git a/src/features/MatchPage/components/MatchDescription/styled.tsx b/src/features/MatchPage/components/MatchDescription/styled.tsx index ad509d97..1b2eaceb 100644 --- a/src/features/MatchPage/components/MatchDescription/styled.tsx +++ b/src/features/MatchPage/components/MatchDescription/styled.tsx @@ -11,7 +11,7 @@ export const Description = styled.div<{isHidden?: boolean}>` ${isMobileDevice ? css` - padding: 0 5px; + padding: 0 15px; align-items: baseline; ` : ''}; @@ -24,8 +24,6 @@ export const Description = styled.div<{isHidden?: boolean}>` ` export const DescriptionInnerBlock = styled.div` - margin-right: 10px; - ${isMobileDevice ? css` width: 100%; ` : ''} diff --git a/src/features/MatchPage/store/hooks/useTournamentData.tsx b/src/features/MatchPage/store/hooks/useTournamentData.tsx index 5dca4d7c..e2450632 100644 --- a/src/features/MatchPage/store/hooks/useTournamentData.tsx +++ b/src/features/MatchPage/store/hooks/useTournamentData.tsx @@ -11,6 +11,7 @@ import sortBy from 'lodash/sortBy' import type { Match } from 'features/Matches' import { prepareMatches } from 'features/Matches/helpers/prepareMatches' +import { useAuthStore } from 'features/AuthStore' import type { MatchInfo } from 'requests' import { getTournamentMatches } from 'requests' @@ -23,6 +24,7 @@ import { TournamentData } from '../../types' export const useTournamentData = (matchProfile: MatchInfo) => { const { sportType } = usePageParams() + const { user } = useAuthStore() const [tournamentMatches, setTournamentMatches] = useState>([]) const [matchDates, setMatchDates] = useState>([]) @@ -44,7 +46,7 @@ export const useTournamentData = (matchProfile: MatchInfo) => { )).sort((a, b) => a.getTime() - b.getTime()) setMatchDates(sortedUniq(matchDateList.map((date) => format(date, 'yyyy-MM-dd')))) - setTournamentMatches(sortBy(prepareMatches(matchesBySection.broadcast), ['date'])) + setTournamentMatches(sortBy(prepareMatches(matchesBySection.broadcast, user), ['date'])) })() } }, [ @@ -52,6 +54,7 @@ export const useTournamentData = (matchProfile: MatchInfo) => { sportType, matchProfile?.live, matchProfile?.c_match_calc_status, + user, ]) const tournamentData: TournamentData = useMemo(() => ({ diff --git a/src/features/MatchPopup/components/LiveMatchPlaylist/index.tsx b/src/features/MatchPopup/components/LiveMatchPlaylist/index.tsx index 9a8ea2c7..2995def6 100644 --- a/src/features/MatchPopup/components/LiveMatchPlaylist/index.tsx +++ b/src/features/MatchPopup/components/LiveMatchPlaylist/index.tsx @@ -3,22 +3,38 @@ import { useState, useEffect } from 'react' import { PAGES } from 'config' import { isMobileDevice } from 'config/userAgent' import { getSportLexic } from 'helpers' -import { getMatchLastWatchSeconds, LastPlayPosition } from 'requests' import { useMatchPopupStore } from 'features/MatchPopup/store' +import type { MatchSecondType } from 'features/MatchPage/components/LiveMatch/hooks/usePlayerProgressReporter' + +import { useLocalStore } from 'hooks' import { SimplePlaylistButton } from '../SimplePlaylistButton' import { List, Item } from './styled' +type LastPlayPosition = { + half: number, + second: number, +} + export const LiveMatchPlaylist = () => { const [lastPlayPosition, setLastPlayPosition] = useState(null) const { match } = useMatchPopupStore() + const [lastWatchSecond] = useLocalStore({ + key: 'matchLastWatchSecond', + }) + useEffect(() => { if (match) { - getMatchLastWatchSeconds(match?.sportType, match?.id) - .then((lastPlayPositionSecond) => setLastPlayPosition(lastPlayPositionSecond)) + const matchTime = lastWatchSecond?.[match.sportType]?.[match.id] + + setLastPlayPosition({ + half: matchTime?.period || 0, + second: matchTime?.lastWatchSecond || 0, + }) } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [match]) if (!match) return null diff --git a/src/features/MatchPopup/components/LiveMatchPopup/styled.tsx b/src/features/MatchPopup/components/LiveMatchPopup/styled.tsx index 08055a9e..1072d709 100644 --- a/src/features/MatchPopup/components/LiveMatchPopup/styled.tsx +++ b/src/features/MatchPopup/components/LiveMatchPopup/styled.tsx @@ -11,7 +11,6 @@ export const Modal = styled(BaseModal)` ${ModalWindow} { width: 27.22rem; - min-height: 14.859rem; padding: 1.416rem 0.71rem; border-radius: 5px; diff --git a/src/features/MatchSidePlaylists/styled.tsx b/src/features/MatchSidePlaylists/styled.tsx index 9c582b10..0e0d1de5 100644 --- a/src/features/MatchSidePlaylists/styled.tsx +++ b/src/features/MatchSidePlaylists/styled.tsx @@ -30,9 +30,11 @@ export const Wrapper = styled.div` ? css` overflow-y: auto; width: 100%; - padding-right: 0; + padding: 10px 10px 0; - ${customScrollbar} + ::-webkit-scrollbar { + display: none; + } ` : ''}; diff --git a/src/features/MultiSourcePlayer/components/ProgressBar/index.tsx b/src/features/MultiSourcePlayer/components/ProgressBar/index.tsx index 20bd3624..bc41a2ed 100644 --- a/src/features/MultiSourcePlayer/components/ProgressBar/index.tsx +++ b/src/features/MultiSourcePlayer/components/ProgressBar/index.tsx @@ -41,7 +41,6 @@ export const ProgressBar = (props: ProgressBarProps) => { {isScrubberVisible && ( diff --git a/src/features/StreamPlayer/components/Controls/Components/ControlsMobile/styled.tsx b/src/features/StreamPlayer/components/Controls/Components/ControlsMobile/styled.tsx index 88abe78b..51d2a481 100644 --- a/src/features/StreamPlayer/components/Controls/Components/ControlsMobile/styled.tsx +++ b/src/features/StreamPlayer/components/Controls/Components/ControlsMobile/styled.tsx @@ -15,7 +15,7 @@ export const Controls = styled.div` flex-direction: column; align-items: center; filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25)); - bottom: ${({ isFullscreen }) => (isFullscreen ? '20px' : 0)}; + bottom: ${({ isFullscreen }) => (isFullscreen ? '20px' : '-3px')}; @media (orientation: landscape){ width: 100%; diff --git a/src/features/StreamPlayer/components/ProgressBar/index.tsx b/src/features/StreamPlayer/components/ProgressBar/index.tsx index e124ab41..21bb14ca 100644 --- a/src/features/StreamPlayer/components/ProgressBar/index.tsx +++ b/src/features/StreamPlayer/components/ProgressBar/index.tsx @@ -2,8 +2,6 @@ import { useSlider } from 'features/StreamPlayer/hooks/useSlider' import { TimeTooltip } from 'features/StreamPlayer/components/TimeTooltip' import { Scrubber, ScrubberContainer } from 'features/StreamPlayer/components/ProgressBar/styled' -import { isIOS } from 'config/userAgent' - import { Chapters } from '../Chapters' import type { Props } from './hooks' import { useProgressBar } from './hooks' @@ -20,13 +18,11 @@ export const ProgressBar = (props: Props) => { return ( {isScrubberVisible && ( diff --git a/src/features/StreamPlayer/components/ProgressBar/styled.tsx b/src/features/StreamPlayer/components/ProgressBar/styled.tsx index 298e37f7..da04f648 100644 --- a/src/features/StreamPlayer/components/ProgressBar/styled.tsx +++ b/src/features/StreamPlayer/components/ProgressBar/styled.tsx @@ -4,7 +4,7 @@ import { isMobileDevice } from 'config/userAgent' import { Wrapper } from '../TimeTooltip/styled' -export const ProgressBarList = styled.div<{isIOS?: boolean}>` +export const ProgressBarList = styled.div` flex-grow: 1; height: 4px; position: relative; @@ -13,16 +13,12 @@ export const ProgressBarList = styled.div<{isIOS?: boolean}>` ${isMobileDevice ? css` - height: 1px; + height: 3px; + margin: 0 15px; ` : ''} - - ${({ isIOS }) => (isIOS && isMobileDevice - && css` - height: 3px; - margin: 0 24px; - `)} ` + export const ScrubberContainer = styled.div` ${isMobileDevice ? css` @@ -30,10 +26,9 @@ export const ScrubberContainer = styled.div` margin: 0 7px; ` : ''} - ` -export const Scrubber = styled.div<{isIOS?: boolean}>` +export const Scrubber = styled.div` border: none; outline: none; position: absolute; @@ -54,18 +49,10 @@ export const Scrubber = styled.div<{isIOS?: boolean}>` ${isMobileDevice ? css` - width: 14px; - height: 14px; background-color: #FFFFFF; - transform: translate(-50%, -48%); - ` - : ''} - - ${({ isIOS }) => (isIOS && isMobileDevice - ? css` - width: 30px; - height: 30px; + width: 27px; + height: 27px; transform: translate(-50%, -53%); ` - : '')} + : ''} ` diff --git a/src/features/StreamPlayer/hooks/index.tsx b/src/features/StreamPlayer/hooks/index.tsx index 784a5a8e..21945a0a 100644 --- a/src/features/StreamPlayer/hooks/index.tsx +++ b/src/features/StreamPlayer/hooks/index.tsx @@ -1,5 +1,6 @@ -import type { MouseEvent } from 'react' import { + MouseEvent, + useMemo, useRef, useCallback, useEffect, @@ -11,6 +12,7 @@ import { useTour } from '@reactour/tour' import size from 'lodash/size' import isNumber from 'lodash/isNumber' import isEmpty from 'lodash/isEmpty' +import isUndefined from 'lodash/isUndefined' import Hls from 'hls.js' @@ -111,14 +113,23 @@ export const useVideoPlayer = ({ /** время для сохранения статистики просмотра матча */ const timeForStatistics = useRef(0) + const resumeTimeWithOffset = useMemo(() => { + const chapterWithOffset = chapters[0].startOffsetMs / 1000 + return !isUndefined(resumeFrom) && isLive && chapters[0].isFullMatchChapter + ? resumeFrom + chapterWithOffset + : resumeFrom + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [resumeFrom]) + const { url } = chapters[0] ?? { url: '' } const numberOfChapters = size(chapters) const { hls, videoRef } = useHlsPlayer({ isLive, - resumeFrom, + resumeFrom: resumeTimeWithOffset, src: url, }) - const [isLivePlaying, setIsLivePlaying] = useState(false) + // временно закоментил, если ничего не сломается, удалю + // const [isLivePlaying, setIsLivePlaying] = useState(false) const [isPausedTime, setIsPausedTime] = useState(false) const [pausedProgress, setPausedProgress] = useState(0) @@ -253,12 +264,12 @@ export const useVideoPlayer = ({ if (selectedPlaylist?.id !== FULL_GAME_KEY) { restartVideo() - setIsLivePlaying(true) + // setIsLivePlaying(true) } const liveProgressMs = Math.max(fullMatchDuration - BUFFERING_TIME, 0) setPlayerState({ playedProgress: liveProgressMs, seek: liveProgressMs / 1000 }) - if (liveProgressMs > 0) setIsLivePlaying(false) + // if (liveProgressMs > 0) setIsLivePlaying(false) // eslint-disable-next-line react-hooks/exhaustive-deps }, [ duration, @@ -296,11 +307,11 @@ export const useVideoPlayer = ({ }, [selectedPlaylist]) useEffect(() => { - if (duration && isLivePlaying && chapters[0]?.isFullMatchChapter) { + if (duration && isUndefined(resumeFrom) && chaptersProps[0]?.isFullMatchChapter) { backToLive() } // eslint-disable-next-line - }, [duration, isLivePlaying]) + }, []) useEffect(() => { if (duration @@ -328,12 +339,16 @@ export const useVideoPlayer = ({ }, [seek, setPlayerState]) useEffect(() => { - onPlayingChange(playing) + onPlayingChange(selectedPlaylist?.id === FULL_GAME_KEY ? playing : false) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [playing, selectedPlaylist]) + + useEffect(() => { if (playing) { setPlayerState({ buffering: false }) } // eslint-disable-next-line - }, [playing, onPlayingChange]) + }, [playing]) const regURL = /\d{6,20}/gi @@ -353,6 +368,16 @@ export const useVideoPlayer = ({ && chapters[0]?.url.match(regURL)?.[0] === chaptersProps[0]?.url.match(regURL)?.[0]) || (isEmpty(chapters) || isEmpty(chaptersProps))) return + if (!isUndefined(resumeFrom) && chaptersProps[0].isFullMatchChapter) { + setPlayerState({ + ...initialState, + chapters: chaptersProps, + playing: true, + seek: resumeFrom + chaptersProps[0].startOffsetMs / 1000, + }) + return + } + setPlayerState({ ...initialState, chapters: chaptersProps, diff --git a/src/requests/getMatchLastWatchSeconds.tsx b/src/requests/getMatchLastWatchSeconds.tsx deleted file mode 100644 index 6f976130..00000000 --- a/src/requests/getMatchLastWatchSeconds.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { - DATA_URL, - PROCEDURES, - -} from 'config' -import { callApi } from 'helpers' - -const proc = PROCEDURES.get_user_match_second - -type Response = { - _p_half: number | null, - _p_second: number | null, -} - -export type LastPlayPosition = { - half: number, - second: number, -} - -export const getMatchLastWatchSeconds = async ( - sportType: number, - matchId: number, -) => { - const config = { - body: { - params: { - _p_match_id: matchId, - _p_sport: sportType, - }, - proc, - }, - } - - const response: Response = await callApi({ - config, - url: DATA_URL, - }) - - return { - half: response?._p_half ?? 0, - second: response?._p_second ?? 0, - } -} diff --git a/src/requests/index.tsx b/src/requests/index.tsx index c9d79f20..0613c71a 100644 --- a/src/requests/index.tsx +++ b/src/requests/index.tsx @@ -14,10 +14,8 @@ export * from './getUserInfo' export * from './getMatchInfo' export * from './getVideos' export * from './getUnauthenticatedMatch' -export * from './reportPlayerProgress' export * from './saveUserInfo' export * from './getPlayerInfo' -export * from './getMatchLastWatchSeconds' export * from './getMatchesPreviewImages' export * from './getSportActions' export * from './getMatchEvents' diff --git a/src/requests/reportPlayerProgress.tsx b/src/requests/reportPlayerProgress.tsx deleted file mode 100644 index 48155428..00000000 --- a/src/requests/reportPlayerProgress.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { - DATA_URL, - PROCEDURES, -} from 'config' -import { callApi } from 'helpers' - -const proc = PROCEDURES.save_user_match_second - -type Args = { - half?: number, - matchId: number, - seconds: number, - sport: number, -} - -export const reportPlayerProgress = ({ - half, - matchId, - seconds, - sport, -}: Args) => { - const config = { - body: { - params: { - _p_half: half, - _p_match_id: matchId, - _p_second: seconds, - _p_sport: sport, - }, - proc, - }, - } - - callApi({ - config, - url: DATA_URL, - }) -}