Skip to content

Commit 989a7f4

Browse files
authored
Merge pull request #611 from Sped0n/fix-432
Fix 432
2 parents dbbc063 + f25b71a commit 989a7f4

20 files changed

+1223
-903
lines changed

assets/ts/configState.tsx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
createContext,
3+
createMemo,
4+
createSignal,
5+
useContext,
6+
type Accessor,
7+
type JSX
8+
} from 'solid-js'
9+
import invariant from 'tiny-invariant'
10+
11+
import { getThresholdSessionIndex } from './utils'
12+
13+
export interface ThresholdRelated {
14+
threshold: number
15+
trailLength: number
16+
}
17+
18+
export interface ConfigState {
19+
thresholdIndex: number
20+
threshold: number
21+
trailLength: number
22+
}
23+
24+
export type ConfigStateContextType = readonly [
25+
Accessor<ConfigState>,
26+
{
27+
readonly incThreshold: () => void
28+
readonly decThreshold: () => void
29+
}
30+
]
31+
32+
const thresholds: ThresholdRelated[] = [
33+
{ threshold: 20, trailLength: 20 },
34+
{ threshold: 40, trailLength: 10 },
35+
{ threshold: 80, trailLength: 5 },
36+
{ threshold: 140, trailLength: 5 },
37+
{ threshold: 200, trailLength: 5 }
38+
]
39+
40+
const ConfigStateContext = createContext<ConfigStateContextType>()
41+
42+
function getSafeThresholdIndex(): number {
43+
const index = getThresholdSessionIndex()
44+
if (index < 0 || index >= thresholds.length) return 2
45+
return index
46+
}
47+
48+
export function ConfigStateProvider(props: { children?: JSX.Element }): JSX.Element {
49+
const [thresholdIndex, setThresholdIndex] = createSignal(getSafeThresholdIndex())
50+
51+
const state = createMemo<ConfigState>(() => {
52+
const current = thresholds[thresholdIndex()]
53+
54+
return {
55+
thresholdIndex: thresholdIndex(),
56+
threshold: current.threshold,
57+
trailLength: current.trailLength
58+
}
59+
})
60+
61+
const updateThreshold = (stride: number): void => {
62+
const nextIndex = thresholdIndex() + stride
63+
if (nextIndex < 0 || nextIndex >= thresholds.length) return
64+
sessionStorage.setItem('thresholdsIndex', nextIndex.toString())
65+
setThresholdIndex(nextIndex)
66+
}
67+
68+
return (
69+
<ConfigStateContext.Provider
70+
value={[
71+
state,
72+
{
73+
incThreshold: () => {
74+
updateThreshold(1)
75+
},
76+
decThreshold: () => {
77+
updateThreshold(-1)
78+
}
79+
}
80+
]}
81+
>
82+
{props.children}
83+
</ConfigStateContext.Provider>
84+
)
85+
}
86+
87+
export function useConfigState(): ConfigStateContextType {
88+
const context = useContext(ConfigStateContext)
89+
invariant(context, 'undefined config context')
90+
return context
91+
}

assets/ts/desktop/customCursor.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export default function CustomCursor(props: {
44
children?: JSX.Element
55
active: Accessor<boolean>
66
cursorText: Accessor<string>
7-
isOpen: Accessor<boolean>
87
}): JSX.Element {
98
// types
109
interface XY {

assets/ts/desktop/layout.tsx

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { Show, createMemo, createSignal, type JSX } from 'solid-js'
1+
import { Show, createMemo, type JSX } from 'solid-js'
22

3-
import type { ImageJSON } from '../resources'
4-
import type { Vector } from '../utils'
3+
import { useImageState } from '../imageState'
54

65
import CustomCursor from './customCursor'
76
import Nav from './nav'
87
import Stage from './stage'
98
import StageNav from './stageNav'
9+
import { useDesktopState } from './state'
1010

1111
/**
1212
* interfaces and types
@@ -23,65 +23,36 @@ export interface DesktopImage extends HTMLImageElement {
2323
}
2424
}
2525

26-
export interface HistoryItem {
27-
i: number
28-
x: number
29-
y: number
30-
}
31-
3226
/**
3327
* components
3428
*/
3529

3630
export default function Desktop(props: {
3731
children?: JSX.Element
38-
ijs: ImageJSON[]
3932
prevText: string
4033
closeText: string
4134
nextText: string
4235
loadingText: string
4336
}): JSX.Element {
44-
const [cordHist, setCordHist] = createSignal<HistoryItem[]>([])
45-
const [isLoading, setIsLoading] = createSignal(false)
46-
const [isOpen, setIsOpen] = createSignal(false)
47-
const [isAnimating, setIsAnimating] = createSignal(false)
48-
const [hoverText, setHoverText] = createSignal('')
49-
const [navVector, setNavVector] = createSignal<Vector>('none')
37+
const imageState = useImageState()
38+
const [desktop] = useDesktopState()
5039

51-
const active = createMemo(() => isOpen() && !isAnimating())
52-
const cursorText = createMemo(() => (isLoading() ? props.loadingText : hoverText()))
40+
const active = createMemo(() => desktop.isOpen() && !desktop.isAnimating())
41+
const cursorText = createMemo(() =>
42+
desktop.isLoading() ? props.loadingText : desktop.hoverText()
43+
)
5344

5445
return (
5546
<>
5647
<Nav />
57-
<Show when={props.ijs.length > 0}>
58-
<Stage
59-
ijs={props.ijs}
60-
setIsLoading={setIsLoading}
61-
isOpen={isOpen}
62-
setIsOpen={setIsOpen}
63-
isAnimating={isAnimating}
64-
setIsAnimating={setIsAnimating}
65-
cordHist={cordHist}
66-
setCordHist={setCordHist}
67-
navVector={navVector}
68-
setNavVector={setNavVector}
69-
/>
70-
<Show when={isOpen()}>
71-
<CustomCursor cursorText={cursorText} active={active} isOpen={isOpen} />
48+
<Show when={imageState().length > 0}>
49+
<Stage />
50+
<Show when={desktop.isOpen()}>
51+
<CustomCursor cursorText={cursorText} active={active} />
7252
<StageNav
7353
prevText={props.prevText}
7454
closeText={props.closeText}
7555
nextText={props.nextText}
76-
loadingText={props.loadingText}
77-
active={active}
78-
isAnimating={isAnimating}
79-
setCordHist={setCordHist}
80-
isOpen={isOpen}
81-
setIsOpen={setIsOpen}
82-
setHoverText={setHoverText}
83-
navVector={navVector}
84-
setNavVector={setNavVector}
8556
/>
8657
</Show>
8758
</Show>

assets/ts/desktop/nav.tsx

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,68 @@
1-
import { createEffect } from 'solid-js'
1+
import { createEffect, onCleanup, onMount } from 'solid-js'
22

3-
import { useState } from '../state'
3+
import { useConfigState } from '../configState'
4+
import { useImageState } from '../imageState'
45
import { expand } from '../utils'
56

6-
/**
7-
* constants
8-
*/
7+
import { useDesktopState } from './state'
98

10-
// threshold div
11-
const thresholdDiv = document.getElementsByClassName('threshold')[0] as HTMLDivElement
12-
// threshold nums span
13-
const thresholdDispNums = Array.from(
14-
thresholdDiv.getElementsByClassName('num')
15-
) as HTMLSpanElement[]
16-
// threshold buttons
17-
const decButton = thresholdDiv
18-
.getElementsByClassName('dec')
19-
.item(0) as HTMLButtonElement
20-
const incButton = thresholdDiv
21-
.getElementsByClassName('inc')
22-
.item(0) as HTMLButtonElement
23-
// index div
24-
const indexDiv = document.getElementsByClassName('index').item(0) as HTMLDivElement
25-
// index nums span
26-
const indexDispNums = Array.from(
27-
indexDiv.getElementsByClassName('num')
28-
) as HTMLSpanElement[]
9+
export default function Nav(): null {
10+
let thresholdNums: HTMLSpanElement[] = []
11+
let indexNums: HTMLSpanElement[] = []
12+
let decButton: HTMLButtonElement | undefined
13+
let incButton: HTMLButtonElement | undefined
14+
let controller: AbortController | undefined
2915

30-
/**
31-
* helper functions
32-
*/
16+
const imageState = useImageState()
17+
const [config, { incThreshold, decThreshold }] = useConfigState()
18+
const [desktop] = useDesktopState()
3319

34-
function updateThresholdText(thresholdValue: string): void {
35-
thresholdDispNums.forEach((e: HTMLSpanElement, i: number) => {
36-
e.innerText = thresholdValue[i]
37-
})
38-
}
20+
const updateThresholdText = (thresholdValue: string): void => {
21+
thresholdNums.forEach((element, i) => {
22+
element.innerText = thresholdValue[i]
23+
})
24+
}
3925

40-
function updateIndexText(indexValue: string, indexLength: string): void {
41-
indexDispNums.forEach((e: HTMLSpanElement, i: number) => {
42-
if (i < 4) {
43-
e.innerText = indexValue[i]
44-
} else {
45-
e.innerText = indexLength[i - 4]
46-
}
47-
})
48-
}
26+
const updateIndexText = (indexValue: string, indexLength: string): void => {
27+
indexNums.forEach((element, i) => {
28+
if (i < 4) {
29+
element.innerText = indexValue[i]
30+
} else {
31+
element.innerText = indexLength[i - 4]
32+
}
33+
})
34+
}
4935

50-
/**
51-
* Nav component
52-
*/
36+
onMount(() => {
37+
const thresholdDiv = document.getElementsByClassName(
38+
'threshold'
39+
)[0] as HTMLDivElement
40+
const indexDiv = document.getElementsByClassName('index').item(0) as HTMLDivElement
5341

54-
export default function Nav(): null {
55-
const [state, { incThreshold, decThreshold }] = useState()
42+
thresholdNums = Array.from(
43+
thresholdDiv.getElementsByClassName('num')
44+
) as HTMLSpanElement[]
45+
indexNums = Array.from(indexDiv.getElementsByClassName('num')) as HTMLSpanElement[]
46+
decButton = thresholdDiv.getElementsByClassName('dec').item(0) as HTMLButtonElement
47+
incButton = thresholdDiv.getElementsByClassName('inc').item(0) as HTMLButtonElement
48+
49+
controller = new AbortController()
50+
const signal = controller.signal
51+
52+
decButton.addEventListener('click', decThreshold, { signal })
53+
incButton.addEventListener('click', incThreshold, { signal })
54+
})
5655

5756
createEffect(() => {
58-
updateIndexText(expand(state().index + 1), expand(state().length))
59-
updateThresholdText(expand(state().threshold))
57+
if (thresholdNums.length === 0 || indexNums.length === 0) return
58+
59+
updateIndexText(expand(desktop.index() + 1), expand(imageState().length))
60+
updateThresholdText(expand(config().threshold))
6061
})
6162

62-
decButton.onclick = decThreshold
63-
incButton.onclick = incThreshold
63+
onCleanup(() => {
64+
controller?.abort()
65+
})
6466

6567
return null
6668
}

0 commit comments

Comments
 (0)