You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
spa_instat_tv/src/features/Matches/hooks.tsx

97 lines
2.3 KiB

import {
useCallback,
useEffect,
useState,
useMemo,
useRef,
} from 'react'
import type { MatchesBySection } from 'requests'
import { useRequest } from 'hooks'
import { usePreferencesStore } from 'features/PreferencesPopup'
import { isMobileDevice } from 'config/userAgent'
import { prepareMatches } from 'helpers'
import { useAuthStore } from '../AuthStore'
export type Props = {
fetch: (limit: number, offset: number) => Promise<MatchesBySection>,
}
const MATCHES_LIMIT = 1000
const initialState = {
broadcast: [],
features: [],
hasNextPage: true,
highlights: [],
isVideoSections: false,
}
export const useMatches = ({ fetch }: Props) => {
const { userPreferences } = usePreferencesStore()
const { user } = useAuthStore()
const {
isFetching,
request: requestMatches,
} = useRequest(fetch)
const pageRef = useRef(0)
const [matches, setMatches] = useState<MatchesBySection>(initialState)
const { hasNextPage } = matches
const fetchMatches = useCallback((page: number) => (
requestMatches(MATCHES_LIMIT, page * MATCHES_LIMIT)
), [requestMatches])
const fetchMoreMatches = useCallback(async () => {
if (!hasNextPage || isFetching) return
const newMatches = await fetchMatches(pageRef.current)
setMatches((oldMatches) => {
const broadcast = [...oldMatches.broadcast, ...newMatches.broadcast]
return {
...oldMatches,
broadcast,
hasNextPage: newMatches.hasNextPage,
}
})
pageRef.current += 1
}, [
fetchMatches,
hasNextPage,
isFetching,
])
useEffect(() => {
const isDefaultUrl = window.location.href.slice(0, -1) === window.location.origin
if (!isDefaultUrl) {
fetchMatches(0).then(setMatches)
pageRef.current = 1
}
return () => {
setMatches(initialState)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fetchMatches, userPreferences])
const preparedMatches = useMemo(() => ({
broadcast: prepareMatches(matches.broadcast, user),
features: prepareMatches(matches.features, user),
highlights: prepareMatches(matches.highlights, user),
isVideoSections: matches.isVideoSections,
// eslint-disable-next-line react-hooks/exhaustive-deps
}), [matches])
return {
fetchMoreMatches: isMobileDevice ? fetchMoreMatches : () => {},
isFetching,
matches: preparedMatches,
}
}