mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-06-04 05:18:13 +02:00
v0.9.5: The Voltron Update — modular architecture, stable IDs, parallelized boot
- Parallelized startup (60s → 15s) via ThreadPoolExecutor - Adaptive polling engine with ETag caching (no more bbox interrupts) - useCallback optimization for interpolation functions - Sliding LAYERS/INTEL edge panels replace bulky Record Panel - Modular fetcher architecture (flights, geo, infrastructure, financial, earth_observation) - Stable entity IDs for GDELT & News popups (PR #63, credit @csysp) - Admin auth (X-Admin-Key), rate limiting (slowapi), auto-updater - Docker Swarm secrets support, env_check.py validation - 85+ vitest tests, CI pipeline, geoJSON builder extraction - Server-side viewport bbox filtering reduces payloads 80%+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Former-commit-id: f2883150b5bc78ebc139d89cc966a76f7d7c0408
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import React, { createContext, useContext } from "react";
|
||||
import type { DashboardData } from "@/types/dashboard";
|
||||
|
||||
interface DashboardDataContextValue {
|
||||
data: any;
|
||||
data: DashboardData;
|
||||
selectedEntity: { id: string | number; type: string; extra?: any } | null;
|
||||
setSelectedEntity: (entity: { id: string | number; type: string; extra?: any } | null) => void;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,23 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from "react";
|
||||
|
||||
type Theme = "dark" | "light";
|
||||
type HudColor = "cyan" | "matrix";
|
||||
|
||||
const ThemeContext = createContext<{ theme: Theme; toggleTheme: () => void }>({
|
||||
const ThemeContext = createContext<{
|
||||
theme: Theme;
|
||||
toggleTheme: () => void;
|
||||
hudColor: HudColor;
|
||||
cycleHudColor: () => void;
|
||||
}>({
|
||||
theme: "dark",
|
||||
toggleTheme: () => {},
|
||||
hudColor: "cyan",
|
||||
cycleHudColor: () => {},
|
||||
});
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [theme, setTheme] = useState<Theme>("dark");
|
||||
const [hudColor, setHudColor] = useState<HudColor>("cyan");
|
||||
|
||||
useEffect(() => {
|
||||
const saved = localStorage.getItem("sb-theme") as Theme | null;
|
||||
@@ -18,6 +27,11 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
setTheme(saved);
|
||||
document.documentElement.setAttribute("data-theme", saved);
|
||||
}
|
||||
const savedHud = localStorage.getItem("sb-hud-color") as HudColor | null;
|
||||
if (savedHud === "cyan" || savedHud === "matrix") {
|
||||
setHudColor(savedHud);
|
||||
document.documentElement.setAttribute("data-hud", savedHud);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const toggleTheme = () => {
|
||||
@@ -27,8 +41,15 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
document.documentElement.setAttribute("data-theme", next);
|
||||
};
|
||||
|
||||
const cycleHudColor = () => {
|
||||
const next = hudColor === "cyan" ? "matrix" : "cyan";
|
||||
setHudColor(next);
|
||||
localStorage.setItem("sb-hud-color", next);
|
||||
document.documentElement.setAttribute("data-hud", next);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
||||
<ThemeContext.Provider value={{ theme, toggleTheme, hudColor, cycleHudColor }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// ─── ShadowBroker Frontend Constants ────────────────────────────────────────
|
||||
// Centralized magic numbers. Import from here instead of hardcoding.
|
||||
|
||||
// ─── Data Polling ───────────────────────────────────────────────────────────
|
||||
export const POLL_FAST_STARTUP_MS = 3000;
|
||||
export const POLL_FAST_STEADY_MS = 15000;
|
||||
export const POLL_SLOW_STARTUP_MS = 5000;
|
||||
export const POLL_SLOW_STEADY_MS = 120000;
|
||||
|
||||
// ─── Reverse Geocoding ──────────────────────────────────────────────────────
|
||||
export const GEOCODE_THROTTLE_MS = 1500;
|
||||
export const GEOCODE_DISTANCE_THRESHOLD = 0.05; // ~5km in degrees
|
||||
export const GEOCODE_CACHE_SIZE = 500;
|
||||
export const NOMINATIM_DEBOUNCE_MS = 350;
|
||||
|
||||
// ─── Map Interpolation ─────────────────────────────────────────────────────
|
||||
export const INTERP_TICK_MS = 1000;
|
||||
|
||||
// ─── News/Alert Layout ──────────────────────────────────────────────────────
|
||||
export const ALERT_BOX_WIDTH_PX = 180;
|
||||
export const ALERT_MAX_OFFSET_PX = 350;
|
||||
Reference in New Issue
Block a user