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/Map.tsx | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 src/components/Map.tsx

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

diff --git a/src/components/Map.tsx b/src/components/Map.tsx
new file mode 100644
index 0000000..070dc5c
--- /dev/null
+++ b/src/components/Map.tsx
@@ -0,0 +1,105 @@
+import React, { useState, useEffect, useRef } from "react";
+import mapboxgl from 'mapbox-gl';
+
+import {
+  MAPBOX_ACCESS_TOKEN,
+  IMAGE_COORDINATES,
+  IMAGES_BASE_URL
+} from "../config";
+
+import "mapbox-gl/dist/mapbox-gl.css";
+
+interface MapProps {
+  slider: number;
+  images: string[];
+}
+
+export function Map({ slider, images }: MapProps) {
+  const mapContainer = useRef<HTMLDivElement>(null);
+  const map = useRef<mapboxgl.Map | null>(null);
+
+  const [lng] = useState(35);
+  const [lat] = useState(31.9);
+  const [zoom] = useState(6.3);
+  const [loaded, setLoaded] = useState(false);
+
+  const prevImages = useRef(images).current;
+
+  useEffect(() => {
+    if (map.current || !mapContainer.current) return;
+
+    map.current = new mapboxgl.Map({
+      accessToken: MAPBOX_ACCESS_TOKEN,
+      container: mapContainer.current,
+      style: "mapbox://styles/mapbox/dark-v9",
+      center: [lng, lat],
+      zoom: zoom,
+      minZoom: 5,
+      maxZoom: 10,
+      hash: false,
+    });
+
+    map.current.on("style.load", () => {
+      setLoaded(true);
+    });
+  }, [lng, lat, zoom]);
+
+  useEffect(() => {
+    if (!loaded || !map.current) return;
+
+    // remove old layers
+    prevImages.forEach((img) => {
+      if (!images.includes(img)) {
+        if (map.current?.getLayer(`layer-${img}`)) {
+          map.current.removeLayer(`layer-${img}`);
+        }
+        if (map.current?.getSource(`source-${img}`)) {
+          map.current.removeSource(`source-${img}`);
+        }
+      }
+    });
+
+    // add new layers
+    images.forEach((img, i) => {
+      if (!prevImages.includes(img) && !map.current?.getSource(`source-${img}`)) {
+        map.current?.addSource(`source-${img}`, {
+          type: "image",
+          url: `${IMAGES_BASE_URL}/${img}`,
+          coordinates: IMAGE_COORDINATES
+        });
+        map.current?.addLayer({
+          id: `layer-${img}`,
+          source: `source-${img}`,
+          type: "raster",
+          paint: {
+            "raster-opacity": 0,
+            "raster-opacity-transition": {
+              duration: 0
+            }
+          }
+        });
+      }
+    });
+  }, [loaded, prevImages, images]);
+
+  useEffect(() => {
+    if (!loaded || !images.length || !map.current) return;
+
+    if (images[slider]) {
+      map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0.85);
+    }
+
+    return () => {
+      // callback will hide the previous layer with the previous slider value
+      if (images[slider] && map.current?.getLayer(`layer-${images[slider]}`)) {
+        map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0);
+      }
+    };
+  }, [loaded, slider, images]);
+
+  return (
+    <div>
+      <div ref={mapContainer} className="map-container h-screen w-screen" />
+    </div>
+  );
+}
\ No newline at end of file
-- 
cgit v1.3.1

