refactor: split monolithic state into context-based modules

Extract image, desktop, mobile, and config state into separate context
providers to improve modularity and reduce unnecessary re-renders.

Signed-off-by: Sped0n <hi@sped0n.com>
This commit is contained in:
Sped0n
2026-03-22 19:45:05 +08:00
parent 1c386386f3
commit f25b71a858
20 changed files with 1165 additions and 894 deletions

View File

@@ -1,8 +1,10 @@
import { createMemo, type Accessor, type JSX, type Setter } from 'solid-js'
import { createMemo, type JSX } from 'solid-js'
import { useState } from '../state'
import { useImageState } from '../imageState'
import { expand } from '../utils'
import { useMobileState } from './state'
export function capitalizeFirstLetter(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1)
}
@@ -10,17 +12,16 @@ export function capitalizeFirstLetter(str: string): string {
export default function GalleryNav(props: {
children?: JSX.Element
closeText: string
isAnimating: Accessor<boolean>
setIsOpen: Setter<boolean>
}): JSX.Element {
// states
const [state] = useState()
const indexValue = createMemo(() => expand(state().index + 1))
const indexLength = createMemo(() => expand(state().length))
const imageState = useImageState()
const [mobile, { setIsOpen }] = useMobileState()
const indexValue = createMemo(() => expand(mobile.index() + 1))
const indexLength = createMemo(() => expand(imageState().length))
const onClick: () => void = () => {
if (props.isAnimating()) return
props.setIsOpen(false)
if (mobile.isAnimating()) return
setIsOpen(false)
}
return (
@@ -37,7 +38,14 @@ export default function GalleryNav(props: {
<span class="num">{indexLength()[2]}</span>
<span class="num">{indexLength()[3]}</span>
</div>
<div class="navClose" onClick={onClick} onKeyDown={onClick}>
<div
class="navClose"
onClick={onClick}
onTouchEnd={onClick}
onKeyDown={onClick}
role="button"
tabIndex="0"
>
{capitalizeFirstLetter(props.closeText)}
</div>
</div>