1"use client"
2
3import { useEffect, useReducer } from "react"
4
5import { allFilled, useBoothStore } from "@/stores/booth"
6
7import {
8 COUNTDOWN_STEP_MS,
9 FLASH_MS,
10 INITIAL_CAPTURE_STATE,
11 PAUSE_MS,
12 reduce,
13 type CaptureEvent,
14 type CaptureState,
15} from "./machine"
16
17/* ARCHITECTURE §5: timer yang menggerakkan mesin keadaan.
18 Satu detik per angka hitung mundur; jeda singkat setelah jepret supaya
19 indikator tidak langsung siap lagi (dipakai gesture di M3); kilat 160 ms.
20 Setiap timer membaca store saat berbunyi, jadi nilainya selalu segar. */
21export function useCaptureMachine(): [CaptureState, (event: CaptureEvent) => void] {
22 const [state, dispatch] = useReducer(reduce, INITIAL_CAPTURE_STATE)
23 const { phase, countdownValue, flash } = state
24
25 useEffect(() => {
26 if (phase === "countdown") {
27 const timer = setTimeout(() => dispatch({ type: "TICK" }), COUNTDOWN_STEP_MS)
28 return () => clearTimeout(timer)
29 }
30 if (phase === "pause") {
31 const timer = setTimeout(
32 () =>
33 dispatch({
34 type: "PAUSE_DONE",
35 allFilled: allFilled(useBoothStore.getState().shots),
36 }),
37 PAUSE_MS
38 )
39 return () => clearTimeout(timer)
40 }
41 }, [phase, countdownValue])
42
43 /* Timer kilat terpisah: fase berganti lebih dulu dari kilatnya, jadi efek ini
44 tidak boleh ikut dibersihkan saat fase berubah. */
45 useEffect(() => {
46 if (!flash) {
47 return
48 }
49 const timer = setTimeout(() => dispatch({ type: "FLASH_DONE" }), FLASH_MS)
50 return () => clearTimeout(timer)
51 }, [flash])
52
53 return [state, dispatch]
54}
55