From 2a050b383bcafefb8fc378531d6f15f352fdb5a5 Mon Sep 17 00:00:00 2001
From: Yuval Adam <_@yuv.al>
Date: Wed, 24 Sep 2025 10:52:38 +0200
Subject: Override all files with v8 implementation

---
 src/components/Slider.tsx | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 src/components/Slider.tsx

(limited to 'src/components/Slider.tsx')

diff --git a/src/components/Slider.tsx b/src/components/Slider.tsx
new file mode 100644
index 0000000..22a8f8f
--- /dev/null
+++ b/src/components/Slider.tsx
@@ -0,0 +1,86 @@
+import React, { useCallback, useRef, useState } from "react";
+import { PLAYBACK_SLOTS } from "../config";
+
+interface SliderProps {
+  playback?: string;
+  slider: number;
+  setSlider: React.Dispatch<React.SetStateAction<number>>;
+}
+
+export function Slider({ playback, slider, setSlider }: SliderProps) {
+  const sliderRef = useRef<HTMLDivElement>(null);
+  const [isDragging, setIsDragging] = useState(false);
+
+  const max = playback ? PLAYBACK_SLOTS : 9;
+
+  const handleStart = useCallback((e: React.MouseEvent | React.TouchEvent) => {
+    setIsDragging(true);
+    updateSliderValue(e);
+  }, []);
+
+  const updateSliderValue = useCallback((e: MouseEvent | React.MouseEvent | TouchEvent | React.TouchEvent) => {
+    if (!sliderRef.current) return;
+
+    const rect = sliderRef.current.getBoundingClientRect();
+    let clientX: number;
+    
+    if ('touches' in e) {
+      clientX = e.touches?.[0]?.clientX || (e as TouchEvent).changedTouches?.[0]?.clientX || 0;
+    } else {
+      clientX = e.clientX;
+    }
+    
+    const percentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
+    const value = Math.round(percentage * max);
+    setSlider(value);
+  }, [max, setSlider]);
+
+  const handleMove = useCallback((e: MouseEvent | TouchEvent) => {
+    if (isDragging) {
+      e.preventDefault();
+      updateSliderValue(e);
+    }
+  }, [isDragging, updateSliderValue]);
+
+  const handleEnd = useCallback(() => {
+    setIsDragging(false);
+  }, []);
+
+  React.useEffect(() => {
+    if (isDragging) {
+      document.addEventListener('mousemove', handleMove);
+      document.addEventListener('mouseup', handleEnd);
+      document.addEventListener('touchmove', handleMove, { passive: false });
+      document.addEventListener('touchend', handleEnd);
+
+      return () => {
+        document.removeEventListener('mousemove', handleMove);
+        document.removeEventListener('mouseup', handleEnd);
+        document.removeEventListener('touchmove', handleMove);
+        document.removeEventListener('touchend', handleEnd);
+      };
+    }
+  }, [isDragging, handleMove, handleEnd]);
+
+  const percentage = (slider / max) * 100;
+
+  return (
+    <div id="slider" className="py-2.5 fixed bottom-[8vh] w-[30vw] ml-[35vw] max-[812px]:w-[80vw] max-[812px]:ml-[8vw] max-[812px]:z-10">
+      <div
+        ref={sliderRef}
+        className="relative h-5 bg-blue-500 rounded-full cursor-pointer touch-none"
+        onMouseDown={handleStart}
+        onTouchStart={handleStart}
+      >
+        <div
+          className={`absolute -top-2.5 w-10 h-10 bg-white rounded-full shadow-md z-[1] ${
+            isDragging ? 'cursor-grabbing' : 'cursor-grab'
+          }`}
+          style={{
+            left: `calc(${percentage}% - 20px)`
+          }}
+        />
+      </div>
+    </div>
+  );
+}
\ No newline at end of file
-- 
cgit v1.3.1

