diff --git a/assets/ts/configState.tsx b/assets/ts/configState.tsx new file mode 100644 index 0000000..f7fdbbe --- /dev/null +++ b/assets/ts/configState.tsx @@ -0,0 +1,91 @@ +import { + createContext, + createMemo, + createSignal, + useContext, + type Accessor, + type JSX +} from 'solid-js' +import invariant from 'tiny-invariant' + +import { getThresholdSessionIndex } from './utils' + +export interface ThresholdRelated { + threshold: number + trailLength: number +} + +export interface ConfigState { + thresholdIndex: number + threshold: number + trailLength: number +} + +export type ConfigStateContextType = readonly [ + Accessor, + { + readonly incThreshold: () => void + readonly decThreshold: () => void + } +] + +const thresholds: ThresholdRelated[] = [ + { threshold: 20, trailLength: 20 }, + { threshold: 40, trailLength: 10 }, + { threshold: 80, trailLength: 5 }, + { threshold: 140, trailLength: 5 }, + { threshold: 200, trailLength: 5 } +] + +const ConfigStateContext = createContext() + +function getSafeThresholdIndex(): number { + const index = getThresholdSessionIndex() + if (index < 0 || index >= thresholds.length) return 2 + return index +} + +export function ConfigStateProvider(props: { children?: JSX.Element }): JSX.Element { + const [thresholdIndex, setThresholdIndex] = createSignal(getSafeThresholdIndex()) + + const state = createMemo(() => { + const current = thresholds[thresholdIndex()] + + return { + thresholdIndex: thresholdIndex(), + threshold: current.threshold, + trailLength: current.trailLength + } + }) + + const updateThreshold = (stride: number): void => { + const nextIndex = thresholdIndex() + stride + if (nextIndex < 0 || nextIndex >= thresholds.length) return + sessionStorage.setItem('thresholdsIndex', nextIndex.toString()) + setThresholdIndex(nextIndex) + } + + return ( + { + updateThreshold(1) + }, + decThreshold: () => { + updateThreshold(-1) + } + } + ]} + > + {props.children} + + ) +} + +export function useConfigState(): ConfigStateContextType { + const context = useContext(ConfigStateContext) + invariant(context, 'undefined config context') + return context +} diff --git a/assets/ts/desktop/customCursor.tsx b/assets/ts/desktop/customCursor.tsx index 2894bcb..16f1e74 100644 --- a/assets/ts/desktop/customCursor.tsx +++ b/assets/ts/desktop/customCursor.tsx @@ -4,7 +4,6 @@ export default function CustomCursor(props: { children?: JSX.Element active: Accessor cursorText: Accessor - isOpen: Accessor }): JSX.Element { // types interface XY { diff --git a/assets/ts/desktop/layout.tsx b/assets/ts/desktop/layout.tsx index 0b56683..abf92e3 100644 --- a/assets/ts/desktop/layout.tsx +++ b/assets/ts/desktop/layout.tsx @@ -1,12 +1,12 @@ -import { Show, createMemo, createSignal, type JSX } from 'solid-js' +import { Show, createMemo, type JSX } from 'solid-js' -import type { ImageJSON } from '../resources' -import type { Vector } from '../utils' +import { useImageState } from '../imageState' import CustomCursor from './customCursor' import Nav from './nav' import Stage from './stage' import StageNav from './stageNav' +import { useDesktopState } from './state' /** * interfaces and types @@ -23,65 +23,36 @@ export interface DesktopImage extends HTMLImageElement { } } -export interface HistoryItem { - i: number - x: number - y: number -} - /** * components */ export default function Desktop(props: { children?: JSX.Element - ijs: ImageJSON[] prevText: string closeText: string nextText: string loadingText: string }): JSX.Element { - const [cordHist, setCordHist] = createSignal([]) - const [isLoading, setIsLoading] = createSignal(false) - const [isOpen, setIsOpen] = createSignal(false) - const [isAnimating, setIsAnimating] = createSignal(false) - const [hoverText, setHoverText] = createSignal('') - const [navVector, setNavVector] = createSignal('none') + const imageState = useImageState() + const [desktop] = useDesktopState() - const active = createMemo(() => isOpen() && !isAnimating()) - const cursorText = createMemo(() => (isLoading() ? props.loadingText : hoverText())) + const active = createMemo(() => desktop.isOpen() && !desktop.isAnimating()) + const cursorText = createMemo(() => + desktop.isLoading() ? props.loadingText : desktop.hoverText() + ) return ( <>