From 2dba409aa7a40aec91062dc9d88ce924dfe6ca36 Mon Sep 17 00:00:00 2001 From: Rakov Date: Thu, 14 Sep 2023 15:45:05 +0300 Subject: [PATCH] fix(#720): fix timeline scroll --- src/features/MatchesSlider/hooks.tsx | 12 ++++- src/features/MatchesSlider/index.tsx | 40 +++++---------- src/features/MatchesSlider/styled.tsx | 2 +- src/features/MatchesTimeline/hooks.tsx | 65 ++++++++++++++++++++++--- src/features/MatchesTimeline/index.tsx | 7 +-- src/features/MatchesTimeline/styled.tsx | 4 +- 6 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/features/MatchesSlider/hooks.tsx b/src/features/MatchesSlider/hooks.tsx index dfd2ce02..6b293dcd 100644 --- a/src/features/MatchesSlider/hooks.tsx +++ b/src/features/MatchesSlider/hooks.tsx @@ -71,11 +71,19 @@ export const useMatchesSlider = (matches: Array) => { } 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 { diff --git a/src/features/MatchesSlider/index.tsx b/src/features/MatchesSlider/index.tsx index 311352e7..5ab29c86 100644 --- a/src/features/MatchesSlider/index.tsx +++ b/src/features/MatchesSlider/index.tsx @@ -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) => { match_id === match.id - && sport_id === match.sportType, - )} /> ))} diff --git a/src/features/MatchesSlider/styled.tsx b/src/features/MatchesSlider/styled.tsx index 50869c53..4f9840a7 100644 --- a/src/features/MatchesSlider/styled.tsx +++ b/src/features/MatchesSlider/styled.tsx @@ -14,7 +14,7 @@ export const Slides = styled.ul` overflow-x: auto; gap: 0.9rem; padding: 10px 10px 10px 7px; - + &::-webkit-scrollbar { display: none; } diff --git a/src/features/MatchesTimeline/hooks.tsx b/src/features/MatchesTimeline/hooks.tsx index 2f63f593..2ecc1649 100644 --- a/src/features/MatchesTimeline/hooks.tsx +++ b/src/features/MatchesTimeline/hooks.tsx @@ -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 & { matches: Array, @@ -35,10 +40,12 @@ export const useTimeline = () => { selectedSport, setSportIds, } = useHeaderFiltersStore() + const { isScoreHidden } = useMatchSwitchesStore() const [isTimelineFetching, setIsTimelineFetching] = useState(true) const [onlineUpcomingMatches, setOnlineUpcomingMatches] = useState>([]) const [tournamentList, setTournamentList] = useState([]) + const [timeline, setTimeline] = useState() const prepareMatchesDto = useCallback((matches: Array) => 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)) diff --git a/src/features/MatchesTimeline/index.tsx b/src/features/MatchesTimeline/index.tsx index a1ec701f..c522ec17 100644 --- a/src/features/MatchesTimeline/index.tsx +++ b/src/features/MatchesTimeline/index.tsx @@ -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, }) => ( - +