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.
97 lines
2.3 KiB
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,
|
|
}
|
|
}
|
|
|