horn button light up

This commit is contained in:
legop3
2026-01-31 15:37:46 -05:00
parent 7eeb9d13e4
commit 5916520b1a
9 changed files with 159 additions and 131 deletions
+2 -1
View File
@@ -13,7 +13,7 @@ function formatDegrees(value) {
export default function CameraServoPanel() {
const {
state: { roverId, camera, keymap },
state: { roverId, camera, keymap, horn },
pipeline,
actions: { setServoAngle, nudgeServo, goServoHome, setNightVision, startHorn, stopHorn },
} = useControlSystem();
@@ -110,6 +110,7 @@ export default function CameraServoPanel() {
onStart={startHorn}
onStop={stopHorn}
keyLabel={hornKey}
active={horn?.active}
/>
)}
{enabled && (
+8 -2
View File
@@ -75,7 +75,7 @@ export default function ControlSummary() {
export function InlineCameraTilt({ keymap }) {
const {
state: { roverId, camera },
state: { roverId, camera, horn },
pipeline,
actions: { setServoAngle, setNightVision, startHorn, stopHorn },
} = useControlSystem();
@@ -132,7 +132,13 @@ export function InlineCameraTilt({ keymap }) {
/>
)}
{hornAvailable && (
<HornControl disabled={!roverId} onStart={startHorn} onStop={stopHorn} keyLabel={hornLabel} />
<HornControl
disabled={!roverId}
onStart={startHorn}
onStop={stopHorn}
keyLabel={hornLabel}
active={horn?.active}
/>
)}
{enabled && (
<div className="space-y-0.5 px-1 py-1">
+6 -4
View File
@@ -14,6 +14,7 @@ export default function HornControl({
onStart,
onStop,
keyLabel,
active,
className = '',
}) {
const [pressed, setPressed] = useState(false);
@@ -34,15 +35,16 @@ export default function HornControl({
}
}, [hornSettings?.freqs, hornSettings?.waveform]);
const isActive = Boolean(active);
const buttonClasses = useMemo(() => {
const base =
'group flex w-full flex-col gap-0.5 rounded-xl border-2 px-1 py-1.5 text-xs font-semibold';
const active = 'border-fuchsia-300/70 bg-fuchsia-700 text-fuchsia-50';
const inactive = 'border-cyan-300/70 bg-cyan-900 text-cyan-50 hover:bg-cyan-800';
return [base, pressed ? active : inactive, 'disabled:opacity-50', className]
return [base, isActive ? active : inactive, 'disabled:opacity-50', className]
.filter(Boolean)
.join(' ');
}, [className, pressed]);
}, [className, isActive]);
const start = () => {
if (disabled) return;
@@ -120,10 +122,10 @@ export default function HornControl({
</span>
<span
className={`rounded px-1 py-0.5 text-[0.65rem] font-semibold ${
pressed ? 'bg-fuchsia-200 text-fuchsia-900' : 'bg-slate-800 text-slate-200'
isActive ? 'bg-fuchsia-200 text-fuchsia-900' : 'bg-slate-800 text-slate-200'
}`}
>
{pressed ? 'Honk' : 'Hold'}
{isActive ? 'Honk' : 'Hold'}
</span>
</div>
<div className="grid grid-cols-[minmax(0,1.2fr)_repeat(4,minmax(0,1fr))] items-center gap-0.5 text-[0.65rem]">
+2 -2
View File
@@ -134,7 +134,7 @@ function FloatingJoystick({ disabled, layout, radius, onMove, onStop }) {
function MobileJoystickPanel({ layout }) {
const {
state: { roverId, camera },
state: { roverId, camera, horn },
pipeline,
actions: { setDriveVector, registerInputState, setServoAngle, setNightVision, startHorn, stopHorn },
} = useControlSystem();
@@ -226,7 +226,7 @@ function MobileJoystickPanel({ layout }) {
/>
)}
{hornAvailable && (
<HornControl disabled={disabled} onStart={startHorn} onStop={stopHorn} />
<HornControl disabled={disabled} onStart={startHorn} onStop={stopHorn} active={horn?.active} />
)}
{cameraEnabled && (
<div className="bg-zinc-950 p-0.5 text-xs">