diff options
| author | Yuval Adam <_@yuv.al> | 2024-09-23 10:29:53 +0200 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2024-09-23 10:29:53 +0200 |
| commit | 8a6ff5a2c15422badf0bc9c8166787dc23a71072 (patch) | |
| tree | da45cc6fc598520102260da87c3733107ef4e980 /geshem/app | |
| parent | 51370d591d4f2ac4eddd8b2ea2f9c5118fbf9ab1 (diff) | |
Move all geshem/ files to root
Diffstat (limited to 'geshem/app')
| -rw-r--r-- | geshem/app/components/Datetime.tsx | 28 | ||||
| -rw-r--r-- | geshem/app/components/Geshem.tsx | 80 | ||||
| -rw-r--r-- | geshem/app/components/Map.tsx | 99 | ||||
| -rw-r--r-- | geshem/app/components/Slider.tsx | 45 | ||||
| -rw-r--r-- | geshem/app/components/config.tsx | 19 | ||||
| -rw-r--r-- | geshem/app/favicon.ico | bin | 32038 -> 0 bytes | |||
| -rw-r--r-- | geshem/app/fonts/GeistMonoVF.woff | bin | 67864 -> 0 bytes | |||
| -rw-r--r-- | geshem/app/fonts/GeistVF.woff | bin | 66268 -> 0 bytes | |||
| -rw-r--r-- | geshem/app/globals.css | 58 | ||||
| -rw-r--r-- | geshem/app/layout.tsx | 35 | ||||
| -rw-r--r-- | geshem/app/page.tsx | 6 | ||||
| -rw-r--r-- | geshem/app/public/apple-touch-icon.png | bin | 1059 -> 0 bytes | |||
| -rw-r--r-- | geshem/app/public/manifest.json | 15 | ||||
| -rw-r--r-- | geshem/app/public/privacy.html | 30 | ||||
| -rw-r--r-- | geshem/app/public/screenshot.png | bin | 382294 -> 0 bytes |
15 files changed, 0 insertions, 415 deletions
diff --git a/geshem/app/components/Datetime.tsx b/geshem/app/components/Datetime.tsx deleted file mode 100644 index 0a8fbcf..0000000 --- a/geshem/app/components/Datetime.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; -import { DateTime as LuxonDateTime } from "luxon"; - -interface DateTimeProps { - images: string[], - slider: number -} - -export function DateTime({ images, slider }: DateTimeProps) { - let datetime = null; - - if (images.length > 0) { - const ds = images[slider].substring(5, 18); - datetime = LuxonDateTime.fromFormat(ds, "yyyyMMdd/HHmm", { - zone: "utc", - }).setZone("Asia/Jerusalem"); - } - - const date = datetime ? datetime.toFormat("dd/MM/y") : ""; - const time = datetime ? datetime.toFormat("HH:mm") : ""; - - return ( - <div id="datetime"> - <div id="date">{date}</div> - <div id="time">{time}</div> - </div> - ); -} diff --git a/geshem/app/components/Geshem.tsx b/geshem/app/components/Geshem.tsx deleted file mode 100644 index 50659be..0000000 --- a/geshem/app/components/Geshem.tsx +++ /dev/null @@ -1,80 +0,0 @@ -"use client" - -import React, { useState, useEffect } from "react"; -// import { BrowserRouter, Route, Routes } from "react-router-dom"; - -import { Map } from "./Map"; -import { Slider } from "./Slider"; -import { DateTime } from "./Datetime"; -import { IMAGES_BASE_URL, PLAYBACK_HOURS, PLAYBACK_SLOTS } from "./config"; - -// import "./Geshem.css"; -import "rc-slider/assets/index.css"; - -// export function App() { -// return ( -// <BrowserRouter> -// <Routes> -// <Route path="/" element={<Geshem />} /> -// <Route path="/history/:date" element={<Geshem />} /> -// </Routes> -// </BrowserRouter> -// ); -// } - -interface GeshemProps { - date?: string -} - -export function Geshem({ date }: GeshemProps) { - const [images, setImages] = useState<string[]>([]); - const [playback] = useState( - date || - new URL(window.location.toString()).searchParams.get("history") || - undefined - ); - const [slider, setSlider] = useState(playback ? PLAYBACK_SLOTS : 9); - - useEffect(() => { - const fetchImages = async () => - fetch(`${IMAGES_BASE_URL}/imgs.json`) - .then(res => res.json()) - .then(imgs => imgs["280"]) - .then(setImages); - - const buildPlayback = async () => { - const date = playback; - const hours = Array.from(Array(PLAYBACK_HOURS).keys()).map( - h => `${String(h).padStart(2, "0")}` - ); - const minutes = Array.from(Array(6).keys()).map( - m => `${String(m * 10).padStart(2, "0")}` - ); - const paths = hours.reduce<string[]>( - (acc, h) => - acc.concat(minutes.map(m => `imgs/${date}/${h}${m}/280.png`)), - [] - ); - setImages(paths); - }; - - let timer: number; - if (playback) buildPlayback(); - else { - fetchImages(); - timer = window.setInterval(fetchImages, 60 * 1000); - } - - return () => { - if (timer !== undefined) clearInterval(timer); - }; - }, [playback]); - - return ( - <> - <Map images={images} slider={slider} /> - <DateTime images={images} slider={slider} /> - <Slider slider={slider} playback={playback} setSlider={setSlider} /> - </> - ); -} diff --git a/geshem/app/components/Map.tsx b/geshem/app/components/Map.tsx deleted file mode 100644 index 39f28fa..0000000 --- a/geshem/app/components/Map.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React, { useState, useEffect, useRef } from "react"; -// @ts-ignore -import mapboxgl from '!mapbox-gl'; // eslint-disable-line import/no-webpack-loader-syntax - -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(null); - const map = useRef<mapboxgl.Map>(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) 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); - }); - }); - - useEffect(() => { - if (!loaded) return; - - // remove old layers - prevImages.forEach((img) => { - if (!images.includes(img)) { - map.current.removeLayer(`layer-${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) return; - images[slider] && map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0.85); - return () => { - // callback will hide the previous layer with the previous slider value - map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0); - } - }, [loaded, slider, images]); - - return ( - <div> - <div ref={mapContainer} className="map-container" style={{ - height: "100vh", - width: "100vw" - }} /> - </div> - ); -} diff --git a/geshem/app/components/Slider.tsx b/geshem/app/components/Slider.tsx deleted file mode 100644 index 50223fc..0000000 --- a/geshem/app/components/Slider.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from "react"; -import RcSlider, { SliderProps, SliderRef } from 'rc-slider/lib/Slider'; -import { PLAYBACK_SLOTS } from "./config"; - -// use workaround from: https://github.com/react-component/slider/issues/835#issuecomment-1201805736 -const CustomSlider = RcSlider as React.ForwardRefExoticComponent<SliderProps<number> & React.RefAttributes<SliderRef>>; - -interface GeshemSliderProps { - playback?: string, - slider: number, - setSlider: React.Dispatch<React.SetStateAction<number>> -} - -export function Slider({ playback, slider, setSlider }: GeshemSliderProps) { - const handleStyle = { - height: 40, - width: 40, - border: 0, - marginTop: -10, - boxShadow: ".5px .5px 2px 1px rgba(0,0,0,.32)" - }; - - const railStyle = { - height: 20, - backgroundColor: "#3498db" - }; - - const trackStyle = { - display: "none" - }; - - return ( - <div id="slider"> - <CustomSlider - min={0} - max={playback ? PLAYBACK_SLOTS : 9} - defaultValue={slider} - handleStyle={handleStyle} - railStyle={railStyle} - trackStyle={trackStyle} - onChange={val => setSlider(val)} - /> - </div> - ); -} diff --git a/geshem/app/components/config.tsx b/geshem/app/components/config.tsx deleted file mode 100644 index 4dc3d6a..0000000 --- a/geshem/app/components/config.tsx +++ /dev/null @@ -1,19 +0,0 @@ -const hostname = window !== undefined && window.location && window.location.hostname; - -const PRODUCTION = hostname && hostname.includes("geshem"); - -export const IMAGES_BASE_URL = PRODUCTION ? "https://imgs.geshem.space" : ""; - -export const MAPBOX_ACCESS_TOKEN = - "pk.eyJ1IjoieXV2YWRtIiwiYSI6ImNpcnMxbzBuaTAwZWdoa25oczlzZmkwbHcifQ.UHtLngbKm9O8945pJm23Nw"; - -export const IMAGE_COORDINATES = [ - [31.7503896894, 34.4878044232], - [37.8574239563, 34.5078463729], - [37.7157066403, 29.4538271687], - [31.9347389087, 29.4373462909] -]; - -export const PLAYBACK_HOURS = 2; - -export const PLAYBACK_SLOTS = (PLAYBACK_HOURS * 6) - 1;
\ No newline at end of file diff --git a/geshem/app/favicon.ico b/geshem/app/favicon.ico Binary files differdeleted file mode 100644 index a97277e..0000000 --- a/geshem/app/favicon.ico +++ /dev/null diff --git a/geshem/app/fonts/GeistMonoVF.woff b/geshem/app/fonts/GeistMonoVF.woff Binary files differdeleted file mode 100644 index f2ae185..0000000 --- a/geshem/app/fonts/GeistMonoVF.woff +++ /dev/null diff --git a/geshem/app/fonts/GeistVF.woff b/geshem/app/fonts/GeistVF.woff Binary files differdeleted file mode 100644 index 1b62daa..0000000 --- a/geshem/app/fonts/GeistVF.woff +++ /dev/null diff --git a/geshem/app/globals.css b/geshem/app/globals.css deleted file mode 100644 index 62b9a76..0000000 --- a/geshem/app/globals.css +++ /dev/null @@ -1,58 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; -} - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} - -#datetime { - position: absolute; - top: 20px; - left: 20px; - color: white; - font-family: monospace; -} - -#date { - font-size: 1.4em; -} - -#time { - font-size: 2.8em; -} - -#slider { - position: fixed; - bottom: 8vh; - width: 30vw; - margin-left: 35vw; -} - -@media only screen and (max-device-width: 812px) { - #slider { - width: 80vw; - margin-left: 8vw; - z-index: 10; - } -}
\ No newline at end of file diff --git a/geshem/app/layout.tsx b/geshem/app/layout.tsx deleted file mode 100644 index 14a4e0c..0000000 --- a/geshem/app/layout.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import type { Metadata } from "next"; -import localFont from "next/font/local"; -import "./globals.css"; - -const geistSans = localFont({ - src: "./fonts/GeistVF.woff", - variable: "--font-geist-sans", - weight: "100 900", -}); -const geistMono = localFont({ - src: "./fonts/GeistMonoVF.woff", - variable: "--font-geist-mono", - weight: "100 900", -}); - -export const metadata: Metadata = { - title: "Geshem.space | Real-Time Israel Rain Radar Visualization", - description: "Track Israel's rainfall in real-time with Geshem.space's advanced radar visualizer. Get accurate, up-to-date precipitation data and forecasts for precise weather monitoring across Israel.", -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - <html lang="en"> - <body - className={`${geistSans.variable} ${geistMono.variable} antialiased`} - > - {children} - </body> - </html> - ); -} diff --git a/geshem/app/page.tsx b/geshem/app/page.tsx deleted file mode 100644 index a44da7b..0000000 --- a/geshem/app/page.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { Geshem } from "@/app/components/Geshem"; -export default function Home() { - return ( - <Geshem /> - ); -} diff --git a/geshem/app/public/apple-touch-icon.png b/geshem/app/public/apple-touch-icon.png Binary files differdeleted file mode 100644 index 7c93f47..0000000 --- a/geshem/app/public/apple-touch-icon.png +++ /dev/null diff --git a/geshem/app/public/manifest.json b/geshem/app/public/manifest.json deleted file mode 100644 index 20d2b0d..0000000 --- a/geshem/app/public/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "Geshem", - "name": "Geshem.space Rain Radar", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/geshem/app/public/privacy.html b/geshem/app/public/privacy.html deleted file mode 100644 index 3976c2c..0000000 --- a/geshem/app/public/privacy.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> - <meta name="apple-mobile-web-app-title" content="Geshem"> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="theme-color" content="#000000"> - <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> - <link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png"> - <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> - <title>Privacy Policy | geshem.space</title> - <script src="https://turtle.geshem.space/script.js" site="MBXPLVRM" defer></script> - <style> - body{ - overflow: hidden; - position: absolute; - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - font-family: sans-serif; - } - </style> - </head> - <body> - <h1>We do not collect any data.</h1> - </body> -</html> diff --git a/geshem/app/public/screenshot.png b/geshem/app/public/screenshot.png Binary files differdeleted file mode 100644 index 7fd104c..0000000 --- a/geshem/app/public/screenshot.png +++ /dev/null |
