From 6e4872e25b4100a8be7af452a2c81fc00c2caade Mon Sep 17 00:00:00 2001 From: Jack Kingsman Date: Mon, 16 Feb 2026 22:08:25 -0800 Subject: [PATCH] Full screen mesh visualizer view --- frontend/src/components/VisualizerView.tsx | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/VisualizerView.tsx b/frontend/src/components/VisualizerView.tsx index 2b7d90e..d95c689 100644 --- a/frontend/src/components/VisualizerView.tsx +++ b/frontend/src/components/VisualizerView.tsx @@ -1,4 +1,5 @@ -import { useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { Maximize2, Minimize2 } from 'lucide-react'; import type { Contact, RawPacket, RadioConfig } from '../types'; import { PacketVisualizer3D } from './PacketVisualizer3D'; import { RawPacketList } from './RawPacketList'; @@ -13,12 +14,40 @@ interface VisualizerViewProps { export function VisualizerView({ packets, contacts, config }: VisualizerViewProps) { const [fullScreen, setFullScreen] = useState(false); + const [paneFullScreen, setPaneFullScreen] = useState(false); + const containerRef = useRef(null); + + // Sync state when browser exits fullscreen (Escape, F11, etc.) + useEffect(() => { + const handler = () => { + if (!document.fullscreenElement) setPaneFullScreen(false); + }; + document.addEventListener('fullscreenchange', handler); + return () => document.removeEventListener('fullscreenchange', handler); + }, []); + + const toggleFullScreen = useCallback(() => { + if (!document.fullscreenElement) { + containerRef.current?.requestFullscreen(); + setPaneFullScreen(true); + } else { + document.exitFullscreen(); + // State synced via fullscreenchange handler + } + }, []); return ( -
+
{/* Header */}
Mesh Visualizer +
{/* Mobile: Tabbed interface */}