fix(#720): fix timeline scroll #297

Merged
roman.rakov merged 1 commits from in-720-fix-scroll into develop 2 years ago
  1. 12
      src/features/MatchesSlider/hooks.tsx
  2. 40
      src/features/MatchesSlider/index.tsx
  3. 2
      src/features/MatchesSlider/styled.tsx
  4. 65
      src/features/MatchesTimeline/hooks.tsx
  5. 7
      src/features/MatchesTimeline/index.tsx
  6. 4
      src/features/MatchesTimeline/styled.tsx

@ -71,11 +71,19 @@ export const useMatchesSlider = (matches: Array<Match>) => {
}
const slideLeft = useMemo(() => throttle(() => {
slidesRef.current!.scrollBy(-((MATCH_CARD_WIDTH + MATCH_CARD_GAP) * MATCHES_TO_SCROLL), 0)
slidesRef.current!.scrollBy({
behavior: 'smooth',
left: -((MATCH_CARD_WIDTH + MATCH_CARD_GAP) * MATCHES_TO_SCROLL),
top: 0,
})
}, SCROLLING_DELAY), [])
const slideRight = useMemo(() => throttle(() => {
slidesRef.current!.scrollBy((MATCH_CARD_WIDTH + MATCH_CARD_GAP) * MATCHES_TO_SCROLL, 0)
slidesRef.current!.scrollBy({
behavior: 'smooth',
left: (MATCH_CARD_WIDTH + MATCH_CARD_GAP) * MATCHES_TO_SCROLL,
top: 0,
})
}, SCROLLING_DELAY), [])
return {

@ -1,18 +1,11 @@
import { useEffect } from 'react'
import { useQuery } from 'react-query'
import map from 'lodash/map'
import isEmpty from 'lodash/isEmpty'
import type { Match } from 'helpers'
import { querieKeys } from 'config'
import { MatchCard } from 'features/MatchCard'
import { useMatchSwitchesStore } from 'features/MatchSwitches'
import { LiveScore, getLiveScores } from 'requests'
import { useMatchesSlider } from './hooks'
import {
@ -40,27 +33,18 @@ export const MatchesSlider = ({ matches }: MatchesSliderProps) => {
slidesRef,
} = useMatchesSlider(matches)
const { isScoreHidden } = useMatchSwitchesStore()
const { data: liveMatchScores } = useQuery({
queryFn: async () => {
if (!isScoreHidden && matches.filter(({ live }) => live)?.length > 0) {
const scores = await getLiveScores()
return scores
}
return []
},
queryKey: querieKeys.liveMatchScores,
refetchInterval: 5000,
})
const scrollToMatchByIndex = (index: number) => {
const offsetLeftCount = slidesRef.current!.querySelectorAll('li')[index].offsetLeft
const match = slidesRef.current!.querySelectorAll('li')[index]
const offsetLeftCount = match.offsetLeft
const PADDING_PARENT = 10
const offsetLeft = offsetLeftCount - PADDING_PARENT
slidesRef.current!.scrollBy(offsetLeft, 0)
slidesRef.current!.scrollBy({
// @ts-ignore
behavior: 'instant',
left: offsetLeft,
})
}
// скролл к лайв матчам или сегодняшней дате
@ -79,7 +63,11 @@ export const MatchesSlider = ({ matches }: MatchesSliderProps) => {
const slidesRefClientWidth = slidesRef.current!.clientWidth
const slidesRefScrollWidth = slidesRef.current!.scrollWidth
slidesRef.current!.scrollBy(slidesRefScrollWidth - slidesRefClientWidth, 0)
slidesRef.current!.scrollBy({
// @ts-ignore
behavior: 'instant',
left: slidesRefScrollWidth - slidesRefClientWidth,
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
@ -107,10 +95,6 @@ export const MatchesSlider = ({ matches }: MatchesSliderProps) => {
<MatchCard
match={match}
key={match.id}
score={liveMatchScores?.find(
({ match_id, sport_id }: LiveScore) => match_id === match.id
&& sport_id === match.sportType,
)}
/>
))}
</Slides>

@ -14,7 +14,7 @@ export const Slides = styled.ul`
overflow-x: auto;
gap: 0.9rem;
padding: 10px 10px 10px 7px;
&::-webkit-scrollbar {
display: none;
}

@ -1,3 +1,4 @@
/* eslint-disable no-param-reassign */
import {
useCallback,
useEffect,
@ -5,11 +6,16 @@ import {
useState,
} from 'react'
import { useQuery } from 'react-query'
import { querieKeys, PAGES } from 'config'
import { useRouteMatch } from 'react-router-dom'
import {
MatchDto,
MatchesTimeline,
TimelineTournamentDto,
getLiveScores,
getTimelineMatches,
} from 'requests'
@ -17,8 +23,7 @@ import { Match, prepareMatches } from 'helpers'
import { useAuthStore } from 'features/AuthStore'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { PAGES } from 'config'
import { useMatchSwitchesStore } from 'features/MatchSwitches'
export type TimelineTournamentList = Array<Omit<TimelineTournamentDto, 'matches'> & {
matches: Array<Match>,
@ -35,10 +40,12 @@ export const useTimeline = () => {
selectedSport,
setSportIds,
} = useHeaderFiltersStore()
const { isScoreHidden } = useMatchSwitchesStore()
const [isTimelineFetching, setIsTimelineFetching] = useState(true)
const [onlineUpcomingMatches, setOnlineUpcomingMatches] = useState<Array<Match>>([])
const [tournamentList, setTournamentList] = useState<TimelineTournamentList>([])
const [timeline, setTimeline] = useState<MatchesTimeline>()
const prepareMatchesDto = useCallback((matches: Array<MatchDto>) => prepareMatches(
matches,
@ -50,21 +57,22 @@ export const useTimeline = () => {
(async () => {
setIsTimelineFetching(true)
try {
const timeline = await getTimelineMatches()
const convertedMatches = timeline.online_upcoming[0].matches
const timelineFetched = await getTimelineMatches()
setTimeline(timelineFetched)
const convertedMatches = timelineFetched.online_upcoming[0].matches
const preparedMatches = prepareMatchesDto(convertedMatches)
setOnlineUpcomingMatches(preparedMatches)
setTournamentList([
...timeline.favorite.map((item) => ({
...timelineFetched.favorite.map((item) => ({
...item,
matches: prepareMatchesDto(item.matches),
})),
...timeline.promo.map((item) => ({
...timelineFetched.promo.map((item) => ({
...item,
matches: prepareMatchesDto(item.matches),
})),
...timeline.others.map((item) => ({
...timelineFetched.others.map((item) => ({
...item,
matches: prepareMatchesDto(item.matches),
})),
@ -76,6 +84,49 @@ export const useTimeline = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useQuery({
queryFn: async () => {
let isLiveMatch = false
if (timeline) {
for (const [, value] of Object.entries(timeline)) {
if (isLiveMatch) break
// eslint-disable-next-line no-loop-func
value.forEach((t) => {
const liveMatch = t.matches.find((match) => match.live)
if (liveMatch) {
isLiveMatch = true
}
})
}
}
if (!isScoreHidden && isLiveMatch) {
const scores = await getLiveScores()
tournamentList.forEach((tournament) => {
tournament.matches.forEach((match) => {
const score = scores.find((s) => (
s.match_id === match.id && s.sport_id === match.sportType
))
if (score) {
match.team1.score = score?.team1.score ?? match.team1.score
match.team2.score = score?.team2.score ?? match.team2.score
}
})
})
onlineUpcomingMatches.forEach((upcomingMatch) => {
const score = scores.find((s) => (
s.match_id === upcomingMatch.id && s.sport_id === upcomingMatch.sportType
))
if (score) {
upcomingMatch.team1.score = score?.team1.score ?? upcomingMatch.team1.score
upcomingMatch.team2.score = score?.team2.score ?? upcomingMatch.team2.score
}
})
}
},
queryKey: querieKeys.liveMatchScores,
refetchInterval: 30000,
})
const filteredTournamentsBySport = useMemo(() => {
if (isHomePage && selectedSport) {
return tournamentList.filter((t) => compareSport(t.sport_id, selectedSport))

@ -23,7 +23,7 @@ import {
TournamentSubtitleWrapper,
} from './styled'
const TOURNAMENT_LIMIT = 6
const TOURNAMENT_LIMIT = 10
export const MatchesTimeline = () => {
const {
@ -60,7 +60,8 @@ export const MatchesTimeline = () => {
useEffect(() => {
if (tournamentList.length) {
pageRef.current = 0
tournamentList.length && setTournaments(getTournaments())
isLastPageRef.current = false
tournamentList.length > 0 && setTournaments(getTournaments())
pageRef.current = 1
}
}, [getTournaments, tournamentList])
@ -88,7 +89,7 @@ export const MatchesTimeline = () => {
tournament,
tournament_id,
}) => (
<RowWrapper key={tournament_id}>
<RowWrapper key={`${tournament_id}_${sport_id}`}>
<TournamentSubtitleWrapper>
<TournamentSubtitle
sportInfo={matches[0].sportInfo}

@ -71,8 +71,10 @@ export const Tournament = styled.div<{
export const TournamentLogo = styled(ProfileLogo)`
position: absolute;
max-height: 100%;
padding: 20px;
width: 100%;
height: 100%;
object-fit: scale-down;
`
export const Loading = styled.div`

Loading…
Cancel
Save