fix(#2639): bug fixing for match page mobile
parent
d5c7379b1b
commit
7d3185dc1d
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@ -1,34 +0,0 @@ |
|||||||
import { useMemo } from 'react' |
|
||||||
|
|
||||||
import { format, parseISO } from 'date-fns' |
|
||||||
|
|
||||||
import { MatchInfo } from 'requests' |
|
||||||
|
|
||||||
import { ScDate, ScDateMonth } from './styled' |
|
||||||
|
|
||||||
type Props = { |
|
||||||
profile: MatchInfo, |
|
||||||
} |
|
||||||
|
|
||||||
export const MatchDate = ({ profile }: Props) => { |
|
||||||
const { |
|
||||||
date, |
|
||||||
} = { ...profile! } |
|
||||||
|
|
||||||
const month = useMemo(() => ( |
|
||||||
format(parseISO(date), 'MMM dd,') |
|
||||||
), [date]) |
|
||||||
|
|
||||||
const hour = useMemo(() => ( |
|
||||||
format(parseISO(date), ' HH:mm') |
|
||||||
), [date]) |
|
||||||
|
|
||||||
return ( |
|
||||||
<ScDate> |
|
||||||
<ScDateMonth> |
|
||||||
{month} |
|
||||||
</ScDateMonth> |
|
||||||
{hour} |
|
||||||
</ScDate> |
|
||||||
) |
|
||||||
} |
|
||||||
@ -1,10 +0,0 @@ |
|||||||
import styled from 'styled-components' |
|
||||||
|
|
||||||
export const ScDate = styled.div` |
|
||||||
font-size: 10px; |
|
||||||
color: rgba(255, 255, 255, 0.7); |
|
||||||
` |
|
||||||
|
|
||||||
export const ScDateMonth = styled.span` |
|
||||||
font-weight: 600; |
|
||||||
` |
|
||||||
@ -1,73 +0,0 @@ |
|||||||
import { useCallback } from 'react' |
|
||||||
|
|
||||||
import { ProfileTypes } from 'config' |
|
||||||
|
|
||||||
import { getName } from 'features/Name' |
|
||||||
import { useMatchSwitchesStore } from 'features/MatchSwitches' |
|
||||||
import { useLexicsStore } from 'features/LexicsStore' |
|
||||||
|
|
||||||
import { usePageParams } from 'hooks/usePageParams' |
|
||||||
|
|
||||||
import { MatchInfo, Team } from 'requests' |
|
||||||
|
|
||||||
import { |
|
||||||
Score, |
|
||||||
ScoreWrapper, |
|
||||||
StyledLink, |
|
||||||
ScTeam, |
|
||||||
Wrapper, |
|
||||||
} from './styled' |
|
||||||
|
|
||||||
type Props = { |
|
||||||
profile: MatchInfo, |
|
||||||
teamNameLimit?: number, |
|
||||||
} |
|
||||||
|
|
||||||
export const TeamsDetails = ({ profile, teamNameLimit }: Props) => { |
|
||||||
const { sportType } = usePageParams() |
|
||||||
const { isScoreHidden } = useMatchSwitchesStore() |
|
||||||
const { suffix } = useLexicsStore() |
|
||||||
|
|
||||||
const { |
|
||||||
team1, |
|
||||||
team2, |
|
||||||
} = { ...profile! } |
|
||||||
|
|
||||||
const getTeamName = useCallback((team: Team) => { |
|
||||||
let name = getName({ nameObj: team, suffix }) |
|
||||||
if (!!teamNameLimit && name.length > teamNameLimit) name = name.substring(0, teamNameLimit).concat('...') |
|
||||||
return name |
|
||||||
}, [suffix, teamNameLimit]) |
|
||||||
|
|
||||||
return ( |
|
||||||
<Wrapper> |
|
||||||
<ScTeam> |
|
||||||
<StyledLink |
|
||||||
id={team1.id} |
|
||||||
profileType={ProfileTypes.TEAMS} |
|
||||||
sportType={sportType} |
|
||||||
> |
|
||||||
{getTeamName(team1)} |
|
||||||
</StyledLink> |
|
||||||
</ScTeam> |
|
||||||
<ScoreWrapper> |
|
||||||
<Score> |
|
||||||
{ |
|
||||||
isScoreHidden |
|
||||||
? '-' |
|
||||||
: `${team1.score} - ${team2.score}` |
|
||||||
} |
|
||||||
</Score> |
|
||||||
</ScoreWrapper> |
|
||||||
<ScTeam> |
|
||||||
<StyledLink |
|
||||||
id={team2.id} |
|
||||||
profileType={ProfileTypes.TEAMS} |
|
||||||
sportType={sportType} |
|
||||||
> |
|
||||||
{getTeamName(team2)} |
|
||||||
</StyledLink> |
|
||||||
</ScTeam> |
|
||||||
</Wrapper> |
|
||||||
) |
|
||||||
} |
|
||||||
@ -1,70 +0,0 @@ |
|||||||
import styled, { css } from 'styled-components' |
|
||||||
|
|
||||||
import { isMobileDevice } from 'config/userAgent' |
|
||||||
|
|
||||||
import { ProfileLink } from 'features/ProfileLink' |
|
||||||
import { ProfileLogo } from 'features/ProfileLogo' |
|
||||||
|
|
||||||
export const Wrapper = styled.div` |
|
||||||
display: flex; |
|
||||||
font-weight: 600; |
|
||||||
margin-bottom: 5px; |
|
||||||
` |
|
||||||
|
|
||||||
export const ScTeam = styled.div` |
|
||||||
font-size: 21px; |
|
||||||
|
|
||||||
${isMobileDevice |
|
||||||
? css` |
|
||||||
font-size: 16px; |
|
||||||
` |
|
||||||
: ''}; |
|
||||||
` |
|
||||||
|
|
||||||
export const StyledLink = styled(ProfileLink)` |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
color: white; |
|
||||||
font-size: 14px; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
text-decoration: underline; |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
export const ScoreWrapper = styled.div` |
|
||||||
margin: 0 10px; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
` |
|
||||||
|
|
||||||
export const Score = styled.span` |
|
||||||
font-size: 14px; |
|
||||||
white-space: nowrap; |
|
||||||
` |
|
||||||
|
|
||||||
export const MatchStatus = styled.span` |
|
||||||
text-align: center; |
|
||||||
background-color: #CC0000; |
|
||||||
border-radius: 1.3px; |
|
||||||
font-weight: 600; |
|
||||||
font-size: 13px; |
|
||||||
line-height: 16px; |
|
||||||
letter-spacing: 0.05em; |
|
||||||
text-transform: uppercase; |
|
||||||
padding: 2.5px 14px; |
|
||||||
margin-top: 6px; |
|
||||||
` |
|
||||||
|
|
||||||
export const Logo = styled(ProfileLogo)` |
|
||||||
width: 41px; |
|
||||||
height: 41px; |
|
||||||
margin: 0 9px; |
|
||||||
${isMobileDevice |
|
||||||
? css` |
|
||||||
width: 30px; |
|
||||||
height: 30px; |
|
||||||
` |
|
||||||
: ''}; |
|
||||||
` |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
import { MatchInfo } from 'requests' |
|
||||||
import { TournamentSubtitle } from 'features/TournamentSubtitle' |
|
||||||
|
|
||||||
import { Wrapper, WrapperTop } from './styled' |
|
||||||
|
|
||||||
import { TeamsDetails } from './components/TeamsDetails' |
|
||||||
import { MatchDate } from './components/MatchDate' |
|
||||||
import { useMatchPageStore } from '../../store' |
|
||||||
|
|
||||||
type Props = { |
|
||||||
profile: MatchInfo, |
|
||||||
} |
|
||||||
|
|
||||||
export const MatchProfileCardMobile = ({ profile }: Props) => { |
|
||||||
const { profileCardShown } = useMatchPageStore() |
|
||||||
|
|
||||||
if (!profile) return null |
|
||||||
|
|
||||||
return ( |
|
||||||
<Wrapper isHidden={!profileCardShown}> |
|
||||||
<WrapperTop> |
|
||||||
<TeamsDetails profile={profile} teamNameLimit={14} /> |
|
||||||
<MatchDate profile={profile} /> |
|
||||||
</WrapperTop> |
|
||||||
<TournamentSubtitle countryId={profile!.country_id} tournament={profile!.tournament} /> |
|
||||||
</Wrapper> |
|
||||||
) |
|
||||||
} |
|
||||||
@ -1,19 +0,0 @@ |
|||||||
import styled, { css } from 'styled-components/macro' |
|
||||||
|
|
||||||
export const Wrapper = styled.div<{isHidden?: boolean}>` |
|
||||||
transition: 0.3s linear;
|
|
||||||
padding: 0 5px; |
|
||||||
color: white; |
|
||||||
margin-bottom: 15px; |
|
||||||
|
|
||||||
${({ isHidden }) => (isHidden ? css` |
|
||||||
height: 0; |
|
||||||
opacity: 0; |
|
||||||
margin-bottom: 0; |
|
||||||
` : '')}
|
|
||||||
` |
|
||||||
|
|
||||||
export const WrapperTop = styled.div` |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
` |
|
||||||
@ -1,15 +0,0 @@ |
|||||||
import { useToggle } from 'hooks' |
|
||||||
|
|
||||||
export const useMatchPage = () => { |
|
||||||
const { |
|
||||||
close: hideProfileCard, |
|
||||||
isOpen: profileCardShown, |
|
||||||
open: showProfileCard, |
|
||||||
} = useToggle(true) |
|
||||||
|
|
||||||
return { |
|
||||||
hideProfileCard, |
|
||||||
profileCardShown, |
|
||||||
showProfileCard, |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
import { useCallback, useState } from 'react' |
|
||||||
|
|
||||||
import type { Events } from 'requests' |
|
||||||
import { getMatchEvents } from 'requests' |
|
||||||
|
|
||||||
import { usePageParams } from 'hooks/usePageParams' |
|
||||||
|
|
||||||
import { useEventsLexics } from './useEventsLexics' |
|
||||||
|
|
||||||
export const useEvents = () => { |
|
||||||
const [events, setEvents] = useState<Events>([]) |
|
||||||
const { fetchLexics } = useEventsLexics() |
|
||||||
const { profileId: matchId, sportType } = usePageParams() |
|
||||||
|
|
||||||
const fetchMatchEvents = useCallback(() => { |
|
||||||
getMatchEvents({ |
|
||||||
matchId, |
|
||||||
sportType, |
|
||||||
}).then(fetchLexics) |
|
||||||
.then(setEvents) |
|
||||||
}, [ |
|
||||||
fetchLexics, |
|
||||||
matchId, |
|
||||||
sportType, |
|
||||||
]) |
|
||||||
|
|
||||||
return { events, fetchMatchEvents } |
|
||||||
} |
|
||||||
@ -1,25 +0,0 @@ |
|||||||
import { useCallback } from 'react' |
|
||||||
|
|
||||||
import isEmpty from 'lodash/isEmpty' |
|
||||||
import map from 'lodash/map' |
|
||||||
import uniq from 'lodash/uniq' |
|
||||||
|
|
||||||
import type { Events } from 'requests' |
|
||||||
|
|
||||||
import { useLexicsStore } from 'features/LexicsStore' |
|
||||||
|
|
||||||
export const useEventsLexics = () => { |
|
||||||
const { addLexicsConfig } = useLexicsStore() |
|
||||||
|
|
||||||
const fetchLexics = useCallback((events: Events) => { |
|
||||||
const lexics = uniq(map(events, ({ l }) => l)) |
|
||||||
|
|
||||||
if (!isEmpty(lexics)) { |
|
||||||
addLexicsConfig(lexics) |
|
||||||
} |
|
||||||
|
|
||||||
return events |
|
||||||
}, [addLexicsConfig]) |
|
||||||
|
|
||||||
return { fetchLexics } |
|
||||||
} |
|
||||||
@ -1,64 +0,0 @@ |
|||||||
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,76 +0,0 @@ |
|||||||
import { |
|
||||||
useEffect, |
|
||||||
useState, |
|
||||||
useMemo, |
|
||||||
} from 'react' |
|
||||||
|
|
||||||
import type { MatchInfo } from 'requests' |
|
||||||
import { getMatchInfo } from 'requests' |
|
||||||
|
|
||||||
import { usePageParams } from 'hooks/usePageParams' |
|
||||||
|
|
||||||
import { parseDate } from 'helpers/parseDate' |
|
||||||
|
|
||||||
import type { Playlists } from '../types' |
|
||||||
import { useMatchData } from './useMatchData' |
|
||||||
import { useTournamentData } from './useTournamentData' |
|
||||||
|
|
||||||
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() |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
getMatchInfo(sportType, matchId).then(setMatchProfile) |
|
||||||
}, [sportType, matchId]) |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
let getIntervalMatch: ReturnType<typeof setInterval> |
|
||||||
if (matchProfile?.live && !matchProfile.youtube_link) { |
|
||||||
getIntervalMatch = setInterval( |
|
||||||
() => getMatchInfo(sportType, matchId).then(setMatchProfile), 1000 * 60 * 3, |
|
||||||
) |
|
||||||
} |
|
||||||
return () => clearInterval(getIntervalMatch) |
|
||||||
}, [matchProfile, sportType, matchId]) |
|
||||||
|
|
||||||
const { events, matchPlaylists } = useMatchData(matchProfile?.live) |
|
||||||
|
|
||||||
const profile = useMemo( |
|
||||||
() => addScoresFromPlaylists(matchProfile, matchPlaylists), |
|
||||||
[matchProfile, matchPlaylists], |
|
||||||
) |
|
||||||
|
|
||||||
const { tournamentData } = useTournamentData(matchProfile?.tournament.id ?? null) |
|
||||||
|
|
||||||
const isStarted = useMemo(() => ( |
|
||||||
profile?.date |
|
||||||
? parseDate(profile.date) < new Date() |
|
||||||
: true |
|
||||||
), [profile?.date]) |
|
||||||
|
|
||||||
return { |
|
||||||
events, |
|
||||||
isStarted, |
|
||||||
profile, |
|
||||||
tournamentData, |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,14 +1,20 @@ |
|||||||
import styled from 'styled-components/macro' |
import styled, { css } from 'styled-components/macro' |
||||||
import { customScrollbar } from 'features/Common' |
import { customScrollbar } from 'features/Common' |
||||||
|
import { isMobileDevice } from '../../../../config/userAgent' |
||||||
|
|
||||||
export const MatchesWrapper = styled.div` |
export const MatchesWrapper = styled.div` |
||||||
overflow-y: scroll; |
overflow-y: auto; |
||||||
max-height: calc(100vh - 170px); |
max-height: calc(100vh - 170px); |
||||||
|
padding-right: 5px; |
||||||
|
|
||||||
> * { |
> * { |
||||||
margin-bottom: 15px; |
margin-bottom: 15px; |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
${customScrollbar} |
${customScrollbar} |
||||||
|
|
||||||
|
${isMobileDevice ? css` |
||||||
|
overflow: hidden; |
||||||
|
max-height: initial; |
||||||
|
` : ''}
|
||||||
` |
` |
||||||
|
|||||||
@ -1,3 +1,5 @@ |
|||||||
export const REWIND_SECONDS = 5 |
import { isMobileDevice } from 'config/userAgent' |
||||||
|
|
||||||
|
export const REWIND_SECONDS = isMobileDevice ? 10 : 5 |
||||||
|
|
||||||
export const HOUR_IN_MILLISECONDS = 60 * 60 * 1000 |
export const HOUR_IN_MILLISECONDS = 60 * 60 * 1000 |
||||||
|
|||||||
@ -0,0 +1,67 @@ |
|||||||
|
import { |
||||||
|
useCallback, |
||||||
|
useMemo, |
||||||
|
useState, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import debounce from 'lodash/debounce' |
||||||
|
|
||||||
|
import { |
||||||
|
Background, |
||||||
|
RewindIcon, |
||||||
|
Time, |
||||||
|
} from './styled' |
||||||
|
|
||||||
|
export type RewindProps = { |
||||||
|
isBackward?: boolean, |
||||||
|
isForward?: boolean, |
||||||
|
rewindCallback: () => void, |
||||||
|
} |
||||||
|
|
||||||
|
const RewindMobile = ({ |
||||||
|
isBackward, |
||||||
|
isForward, |
||||||
|
rewindCallback, |
||||||
|
}: RewindProps) => { |
||||||
|
const [isActive, setIsActive] = useState(false) |
||||||
|
const [time, setTime] = useState(0) |
||||||
|
|
||||||
|
const resetData = useCallback(() => { |
||||||
|
setIsActive(false) |
||||||
|
setTime(0) |
||||||
|
}, []) |
||||||
|
|
||||||
|
const resetDataDebounced = useMemo(() => ( |
||||||
|
debounce(resetData, 1500) |
||||||
|
), [resetData]) |
||||||
|
|
||||||
|
const handleDoubleClick = useCallback(() => { |
||||||
|
setIsActive(true) |
||||||
|
rewindCallback() |
||||||
|
setTime(time + 10) |
||||||
|
resetDataDebounced() |
||||||
|
}, [resetDataDebounced, rewindCallback, time]) |
||||||
|
|
||||||
|
const TimeContent = useMemo(() => ( |
||||||
|
<Time |
||||||
|
isBackward={isBackward} |
||||||
|
isForward={isForward} |
||||||
|
> |
||||||
|
<span>{isBackward ? '-' : '+'}{time}</span> |
||||||
|
<RewindIcon src={`/images/rewind-${isBackward ? 'left' : 'right'}.svg`} /> |
||||||
|
</Time> |
||||||
|
), [isBackward, isForward, time]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<Background |
||||||
|
isActive={isActive} |
||||||
|
isBackward={isBackward} |
||||||
|
isForward={isForward} |
||||||
|
onDoubleClick={handleDoubleClick} |
||||||
|
> |
||||||
|
{isActive && TimeContent} |
||||||
|
</Background> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default RewindMobile |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
import styled, { css } from 'styled-components/macro' |
||||||
|
|
||||||
|
type RewindProps = { |
||||||
|
isActive?: boolean, |
||||||
|
isBackward?: boolean, |
||||||
|
isForward?: boolean, |
||||||
|
} |
||||||
|
|
||||||
|
export const Background = styled.div<RewindProps>` |
||||||
|
width: 920px; |
||||||
|
height: 920px; |
||||||
|
border-radius: 50%; |
||||||
|
background-color: ${({ isActive }) => (isActive ? 'rgba(0, 0, 0, 0.4)' : 'rgba(0, 0, 0, 0)')}; |
||||||
|
position: absolute; |
||||||
|
${({ isBackward }) => isBackward && css`right: 60%;`} |
||||||
|
${({ isForward }) => isForward && css`left: 60%;`} |
||||||
|
transition: all 0.3s ease-in-out; |
||||||
|
` |
||||||
|
|
||||||
|
export const Time = styled.div<RewindProps>` |
||||||
|
position: absolute; |
||||||
|
color: #FFFFFF; |
||||||
|
top: 50%; |
||||||
|
font-size: 20px; |
||||||
|
transform: translate(0, -50%); |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
user-select: none; |
||||||
|
|
||||||
|
${({ isBackward }) => isBackward && css`right: 2%;`} |
||||||
|
${({ isForward }) => isForward && css`left: 2%;`} |
||||||
|
|
||||||
|
> :first-child { |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const RewindIcon = styled.img` |
||||||
|
width: 43px; |
||||||
|
height: 28px; |
||||||
|
` |
||||||
@ -1,40 +1,56 @@ |
|||||||
import { |
import { useCallback, useMemo } from 'react' |
||||||
useMemo, |
|
||||||
useState, |
|
||||||
useCallback, |
|
||||||
} from 'react' |
|
||||||
|
|
||||||
import debounce from 'lodash/debounce' |
import debounce from 'lodash/debounce' |
||||||
|
|
||||||
export const useControlsVisibility = (isFullscreen: boolean) => { |
import { useToggle } from 'hooks' |
||||||
const [controlsVisible, setControlsVisibility] = useState(true) |
|
||||||
|
|
||||||
const show = useCallback(() => { |
export const useControlsVisibility = (isFullscreen: boolean, playing: boolean) => { |
||||||
setControlsVisibility(true) |
const { |
||||||
}, []) |
close: hideCenterControls, |
||||||
|
isOpen: centerControlsVisible, |
||||||
|
open: showCenterControls, |
||||||
|
} = useToggle(playing) |
||||||
|
|
||||||
const hide = useCallback(() => { |
const hideCenterDebounced = useMemo(() => ( |
||||||
setControlsVisibility(false) |
debounce(hideCenterControls, 2000) |
||||||
}, []) |
), [hideCenterControls]) |
||||||
|
|
||||||
|
const showCenter = useCallback(() => { |
||||||
|
if (playing) { |
||||||
|
showCenterControls() |
||||||
|
hideCenterDebounced() |
||||||
|
} else { |
||||||
|
showCenterControls() |
||||||
|
} |
||||||
|
}, [hideCenterDebounced, playing, showCenterControls]) |
||||||
|
|
||||||
|
const { |
||||||
|
close: hideMainControls, |
||||||
|
isOpen: mainControlsVisible, |
||||||
|
open: showMainControls, |
||||||
|
} = useToggle(true) |
||||||
|
|
||||||
const hideDebounced = useMemo( |
const hideDebounced = useMemo( |
||||||
() => debounce(hide, 3000), |
() => debounce(hideMainControls, 3000), |
||||||
[hide], |
[hideMainControls], |
||||||
) |
) |
||||||
|
|
||||||
const onMouseMove = () => { |
const onMouseMove = () => { |
||||||
show() |
showMainControls() |
||||||
if (isFullscreen) { |
if (isFullscreen) { |
||||||
hideDebounced() |
hideDebounced() |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
return { |
return { |
||||||
controlsVisible, |
centerControlsVisible, |
||||||
onMouseEnter: show, |
hideCenterControls, |
||||||
onMouseLeave: hide, |
mainControlsVisible, |
||||||
|
onMouseEnter: showMainControls, |
||||||
|
onMouseLeave: hideMainControls, |
||||||
onMouseMove, |
onMouseMove, |
||||||
onTouchEnd: hideDebounced, |
onTouchEnd: hideDebounced, |
||||||
onTouchStart: show, |
onTouchStart: showMainControls, |
||||||
|
showCenterControls: showCenter, |
||||||
} |
} |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue