use-roll.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. "use client";
  2. import { useState, useCallback, useRef, useEffect } from "react";
  3. import type { Movie } from "@/types/movie";
  4. import { selectRandomMovie } from "@/lib/dice/randomizer";
  5. export type RollState = "idle" | "rolling" | "complete";
  6. const ANIMATION_DURATION_MS = 2500;
  7. export interface UseRollReturn {
  8. result: Movie | null;
  9. rollState: RollState;
  10. roll: (eligibleMovies: Movie[]) => void;
  11. reset: () => void;
  12. }
  13. export function useRoll(): UseRollReturn {
  14. const [result, setResult] = useState<Movie | null>(null);
  15. const [rollState, setRollState] = useState<RollState>("idle");
  16. const timerRef = useRef<ReturnType<typeof setTimeout>>(null);
  17. useEffect(() => {
  18. return () => {
  19. if (timerRef.current) clearTimeout(timerRef.current);
  20. };
  21. }, []);
  22. const roll = useCallback((eligibleMovies: Movie[]) => {
  23. if (timerRef.current) clearTimeout(timerRef.current);
  24. const winner = selectRandomMovie(eligibleMovies);
  25. setRollState("rolling");
  26. setResult(winner);
  27. timerRef.current = setTimeout(() => {
  28. setRollState("complete");
  29. }, ANIMATION_DURATION_MS);
  30. }, []);
  31. const reset = useCallback(() => {
  32. if (timerRef.current) clearTimeout(timerRef.current);
  33. setResult(null);
  34. setRollState("idle");
  35. }, []);
  36. return { result, rollState, roll, reset };
  37. }