diff --git a/src/components/panels/MorseTransmissionPanel.tsx b/src/components/panels/MorseTransmissionPanel.tsx new file mode 100644 index 0000000..535d46d --- /dev/null +++ b/src/components/panels/MorseTransmissionPanel.tsx @@ -0,0 +1,122 @@ +'use client'; +import React, { useEffect, useRef, useState } from 'react'; +import ROSLIB from 'roslib'; +import { useROS } from '@/ros/ROSContext'; + +const MorseTransmissionPanel: React.FC = () => { + const { ros } = useROS(); + + const [message, setMessage] = useState(''); + const [lastSent, setLastSent] = useState(null); + + const topicRef = useRef(null); + + useEffect(() => { + if (!ros) { + topicRef.current = null; + return; + } + + topicRef.current = new ROSLIB.Topic({ + ros, + name: '/morse_transmission', + messageType: 'std_msgs/msg/String', + }); + + return () => { + try { + topicRef.current?.unadvertise(); + } catch { + // ignore + } + topicRef.current = null; + }; + }, [ros]); + + const send = () => { + if (!topicRef.current || !message) return; + topicRef.current.publish(new ROSLIB.Message({ data: message })); + setLastSent(message); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') send(); + }; + + const disabled = !ros; + + return ( +
+
+ setMessage(e.target.value)} + onKeyDown={handleKeyDown} + /> + +
+ + {lastSent &&
Last sent: {lastSent}
} + + +
+ ); +}; + +export default MorseTransmissionPanel; diff --git a/src/components/panels/MosaicDashboard.tsx b/src/components/panels/MosaicDashboard.tsx index 83dfb90..7a3468b 100644 --- a/src/components/panels/MosaicDashboard.tsx +++ b/src/components/panels/MosaicDashboard.tsx @@ -27,6 +27,7 @@ import ArmControlPanel from './ArmControlPanel'; import WebRTCClient from './WebRTCClient'; import TimerPanel from './TimerPanel'; import HeadlightControlPanel from './HeadlightControlPanel'; +import MorseTransmissionPanel from './MorseTransmissionPanel'; import { ROVER_IP } from '@/constants'; @@ -49,6 +50,7 @@ type TileType = | 'webRTCClient' | 'timerPanel' | 'headlightControlPanel' + | 'morseTransmissionPanel' ; type TileId = `${TileType}:${number}`; @@ -72,6 +74,7 @@ const TILE_DISPLAY_NAMES: Record = { webRTCClient: 'WebRTC Client', timerPanel: 'Multi-Timer', headlightControlPanel: 'Headlights', + morseTransmissionPanel: 'Morse Transmission', }; const ALL_TILE_TYPES: TileType[] = [ @@ -93,6 +96,7 @@ const ALL_TILE_TYPES: TileType[] = [ 'webRTCClient', 'timerPanel', 'headlightControlPanel', + 'morseTransmissionPanel', ]; function tileTypeOf(id: TileId): TileType { @@ -465,6 +469,13 @@ const MosaicDashboard: React.FC = () => { ); + + case 'morseTransmissionPanel': + return ( + + + + ); default: return
Unknown tile
; }