diff --git a/App.tsx b/App.tsx index b00a118..3a55b87 100644 --- a/App.tsx +++ b/App.tsx @@ -15,7 +15,7 @@ const App: React.FC = () => { // State for Configuration const [isDualMode, setIsDualMode] = useState(false); const [isAttached, setIsAttached] = useState(false); - + // Refs for State Access inside Callbacks (Fixes stale closures) const isAttachedRef = useRef(isAttached); const isDualModeRef = useRef(isDualMode); @@ -44,8 +44,8 @@ const App: React.FC = () => { // Check if Web Serial is supported const nav = navigator as unknown as { serial: NavigatorSerial }; if (!nav.serial) { - setIsSupported(false); - console.warn("Web Serial API is not supported in this browser."); + setIsSupported(false); + console.warn("Web Serial API is not supported in this browser."); } return () => { @@ -104,10 +104,10 @@ const App: React.FC = () => { // --- Log Saving Logic --- const handleSaveLogs = (portName: string, logs: SerialLogEntry[]) => { if (logs.length === 0) { - alert(`No logs to save for ${portName}.`); - return; + alert(`No logs to save for ${portName}.`); + return; } - + // Header let content = `SerialNexus Log - Port ${portName}\n`; content += `Exported at: ${new Date().toLocaleString()}\n`; @@ -117,18 +117,18 @@ const App: React.FC = () => { // Data content += logs.map(log => { - const time = formatTime(log.timestamp).padEnd(23, ' '); - const dir = log.direction.padEnd(3, ' '); - const hex = uInt8ArrayToHex(log.data).padEnd(40, ' '); // simple padding - const ascii = uInt8ArrayToAscii(log.data); - return `${time} | ${dir} | ${hex} | ${ascii}`; + const time = formatTime(log.timestamp).padEnd(23, ' '); + const dir = log.direction.padEnd(3, ' '); + const hex = uInt8ArrayToHex(log.data).padEnd(40, ' '); // simple padding + const ascii = uInt8ArrayToAscii(log.data); + return `${time} | ${dir} | ${hex} | ${ascii}`; }).join('\n'); const blob = new Blob([content], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; - a.download = `serial-log-${portName.toLowerCase()}-${new Date().toISOString().slice(0,19).replace(/[:T]/g,'-')}.txt`; + a.download = `serial-log-${portName.toLowerCase()}-${new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-')}.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); @@ -140,16 +140,17 @@ const App: React.FC = () => { const handleConnectA = async () => { try { console.log("Connect A Clicked"); + setLogsA([]); await serialA.current.connect(baudRateA); setIsConnectedA(true); serialA.current.startReading((data) => { // Log RX on A addLog('A', 'RX', data); - + // Visual Feedback for Bridge: If Attached, we assume it was sent to B // Note: The actual sending happens in SerialManager, here we just update the UI if (isAttachedRef.current && isDualModeRef.current && serialB.current.port) { - addLog('B', 'TX', data); + addLog('B', 'TX', data); } }); } catch (err) { @@ -166,15 +167,16 @@ const App: React.FC = () => { const handleConnectB = async () => { try { console.log("Connect B Clicked"); + setLogsB([]); await serialB.current.connect(baudRateB); setIsConnectedB(true); serialB.current.startReading((data) => { // Log RX on B addLog('B', 'RX', data); - + // Visual Feedback for Bridge: If Attached, we assume it was sent to A if (isAttachedRef.current && isDualModeRef.current && serialA.current.port) { - addLog('A', 'TX', data); + addLog('A', 'TX', data); } }); } catch (err) { @@ -204,7 +206,7 @@ const App: React.FC = () => { // --- Helper Component for Controls --- const renderControls = ( - baud: number, + baud: number, setBaud: (r: number) => void, connected: boolean, onConnect: () => void, @@ -213,54 +215,52 @@ const App: React.FC = () => { setViewMode: (v: ViewMode) => void ) => ( <> -
- Baud - -
+
+ Baud + +
- {connected ? ( - - ) : ( - - )} + {connected ? ( + + ) : ( + + )} - {/* View Mode Toggles */} -
- - + -
+ > + HEX + + ); @@ -277,7 +277,7 @@ const App: React.FC = () => {
- + {!isSupported && (
⚠️ Your browser does not support the Web Serial API. Please use Chrome, Edge, or Opera. @@ -286,14 +286,13 @@ const App: React.FC = () => { {/* Main Content Area */}
- + {/* Port A Terminal */} -
- + { onSave={() => handleSaveLogs("A", logsA)} className="flex-1" headerControls={renderControls( - baudRateA, setBaudRateA, isConnectedA, handleConnectA, handleDisconnectA, viewModeA, setViewModeA + baudRateA, setBaudRateA, isConnectedA, handleConnectA, handleDisconnectA, viewModeA, setViewModeA )} />
-
@@ -316,7 +315,7 @@ const App: React.FC = () => { {/* Port B Terminal (Only if Dual Mode) */} {isDualMode && (
- { )} />
-
@@ -342,9 +341,9 @@ const App: React.FC = () => {
© 2026 SIMP - {isDualMode - ? (isAttached ? "MODE: DUAL MONITOR (ATTACHED: A <-> B)" : "MODE: DUAL MONITOR (INDEPENDENT)") - : "MODE: SINGLE MONITOR (A)"} + {isDualMode + ? (isAttached ? "MODE: DUAL MONITOR (ATTACHED: A <-> B)" : "MODE: DUAL MONITOR (INDEPENDENT)") + : "MODE: SINGLE MONITOR (A)"}