porridger/front/src/hooks/useStoryIndex.ts

87 lines
2.2 KiB
TypeScript

import { useEffect, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { SetState } from '../utils/types'
function useStoryIndex(annLength: number | undefined) {
const [index, setIndex] = useState(0)
const [searchParams, setSearchParams] = useSearchParams()
const withReset =
<T>(f: SetState<T>) =>
(...args: Parameters<SetState<T>>) => {
setIndex(0)
setSearchParams(
(prev) => ({
...Object.fromEntries(prev),
storyIndex: '0',
}),
{ replace: true }
)
f(...args)
}
useEffect(() => {
setIndex(
annLength
? Number.parseInt(searchParams.get('storyIndex') || '0')
: 0
)
// searchParams have actual query string at first render
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [annLength])
const increment = () =>
setIndex((prev) => {
const newIndex = (prev + 1) % (annLength || 1)
setSearchParams(
(prev) => ({
...Object.fromEntries(prev),
storyIndex: newIndex.toString(),
}),
{ replace: true }
)
return newIndex
})
const decrement = () =>
setIndex((prev) => {
const newIndex = prev > 0 ? prev - 1 : 0
setSearchParams(
(prev) => ({
...Object.fromEntries(prev),
storyIndex: newIndex.toString(),
}),
{ replace: true }
)
return newIndex
})
const set = (n: number) =>
setIndex(() => {
const newIndex = n % (annLength || 1)
setSearchParams(
(prev) => ({
...Object.fromEntries(prev),
storyIndex: newIndex.toString(),
}),
{ replace: true }
)
return newIndex
})
return {
n: index,
withReset,
increment,
decrement,
set,
}
}
export default useStoryIndex