better big button

This commit is contained in:
legop3
2026-01-15 18:43:46 -05:00
parent 705b38ea7b
commit e34d838d41
7 changed files with 169 additions and 133 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -11,8 +11,8 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-CJBHX9So.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D46FE2Sk.css">
<script type="module" crossorigin src="/assets/index-ZuH-jWBy.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-hvTkRjRF.css">
</head>
<body>
<div id="root"></div>
+9 -2
View File
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import TelemetryPanel from './components/TelemetryPanel.jsx';
import ControlSummary, { RoverRosterPanel } from './components/ControlSummary.jsx';
import ReplaySourcesPanel from './components/ReplaySourcesPanel.jsx';
import AlertFeed from './components/AlertFeed.jsx';
import MobileControls, {
MobileLandscapeAuxColumn,
@@ -128,7 +129,10 @@ function MobilePortraitLayout({ onOpenHelpOverlay }) {
<div className="flex flex-col gap-0.5">
<DriverVideoPanel layoutFormat="mobile-portrait" />
<MobileControls />
<RoverRosterPanel />
<div className="grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]">
<ReplaySourcesPanel panelId="replay-sources-mobile-portrait" />
<RoverRosterPanel />
</div>
{/* <ControlSummary /> */}
<MobileFeatureTabs
layout="mobile-portrait"
@@ -146,7 +150,10 @@ function MobileLandscapeLayout({ onOpenHelpOverlay }) {
<MobileLandscapeAuxColumn />
<div>
<DriverVideoPanel layoutFormat="mobile-landscape" />
<RoverRosterPanel />
<div className="grid gap-0.5 grid-cols-[minmax(0,1fr)_minmax(0,1.4fr)]">
<ReplaySourcesPanel panelId="replay-sources-mobile-landscape" />
<RoverRosterPanel />
</div>
{/* <TelemetryPanel /> */}
</div>
<MobileLandscapeControlColumn />
+38 -9
View File
@@ -24,7 +24,7 @@ export function useDriveDockState(roverId) {
function StatusPill({ label, active }) {
return (
<span
className={`rounded px-1.5 py-0.5 text-[0.75rem] font-semibold ${
className={`rounded-xl px-1.5 py-0.5 text-[0.75rem] font-semibold ${
active ? 'bg-emerald-600 text-white' : 'bg-red-600 text-white'
}`}
>
@@ -38,6 +38,22 @@ function KeyPill({ label }) {
return <span className="rounded border border-white/40 px-1 text-[0.7rem] text-white">{label}</span>;
}
function ActionPill({ label, tone }) {
const toneClasses =
tone === 'emerald'
? 'border-emerald-200/70 bg-emerald-600/70 text-emerald-50'
: tone === 'amber'
? 'border-amber-200/70 bg-amber-600/70 text-amber-50'
: 'border-indigo-200/70 bg-indigo-600/70 text-indigo-50';
return (
<span
className={`rounded-full border px-0.5 py-0.15 text-[0.7rem] font-semibold ${toneClasses}`}
>
{label}
</span>
);
}
function DockModal({ instructions, onConfirm, onCancel, pending }) {
return (
<div className="fixed inset-0 z-40 flex items-center justify-center bg-black/70 p-1">
@@ -149,7 +165,17 @@ export default function DriveDockAction({ layout = 'desktop', expand = false, dr
};
const baseCardClasses =
'flex w-full flex-col gap-0.5 border border-slate-700 px-0.75 py-0.75 text-slate-100 shadow';
'flex w-full flex-col gap-0.5 overflow-hidden rounded-xl border-2 px-0.75 py-0.75 text-slate-100 shadow-md transition hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60';
const ctaText = 'text-center';
const ctaLayout = 'items-center justify-between';
const ctaTextAndLayout = `${ctaText} ${ctaLayout}`;
const ctaSize = isMobile ? 'text-sm font-semibold' : '';
const emeraldCta =
'border-emerald-300/70 bg-emerald-800 text-emerald-50 hover:bg-emerald-700 focus-visible:ring-emerald-300';
const amberCta =
'border-amber-300/70 bg-amber-900 text-amber-50 hover:bg-amber-800 focus-visible:ring-amber-300';
const indigoCta =
'border-indigo-300/70 bg-indigo-900 text-indigo-50 hover:bg-indigo-800 focus-visible:ring-indigo-300';
const filledHeight = expand ? 'h-full flex-1' : '';
if (!driving && !dockingInProgress) {
@@ -158,12 +184,13 @@ export default function DriveDockAction({ layout = 'desktop', expand = false, dr
type="button"
onClick={handleStartDrive}
disabled={driveDisabled}
className={`${baseCardClasses} ${filledHeight} items-center justify-between bg-emerald-800 hover:bg-emerald-700 text-center transition disabled:cursor-not-allowed disabled:opacity-60`}
className={`${baseCardClasses} ${filledHeight} ${ctaTextAndLayout} ${ctaSize} ${emeraldCta}`}
>
<div className="space-y-0.25 w-full">
<div className="flex items-center justify-center gap-0.5">
<div className="flex flex-wrap items-center justify-center gap-0.5">
<span className="text-base font-semibold text-emerald-50">Start Driving</span>
{!isMobile && driveKeyLabel ? <KeyPill label={driveKeyLabel} /> : null}
{!isMobile ? <ActionPill label="Click to start" tone="emerald" /> : null}
</div>
<p className="text-sm text-emerald-50/90">{startDriveInstructions.summary}</p>
<StepList steps={startDriveInstructions.steps} tone="emerald" />
@@ -188,11 +215,12 @@ export default function DriveDockAction({ layout = 'desktop', expand = false, dr
type="button"
disabled={driveDisabled}
onClick={handleReturnToDrive}
className={`${baseCardClasses} ${filledHeight} items-center bg-amber-900 text-center transition hover:bg-amber-800 disabled:cursor-not-allowed disabled:opacity-50`}
className={`${baseCardClasses} ${filledHeight} ${ctaTextAndLayout} ${ctaSize} ${amberCta}`}
>
<div className="space-y-0.25 w-full">
<div className="flex items-center justify-center gap-0.5">
<div className="flex flex-wrap items-center justify-center gap-0.5">
<span className="text-base font-semibold text-amber-50">Docking in Progress</span>
{!isMobile ? <ActionPill label="Click to return to driving mode" tone="amber" /> : null}
</div>
<p className="text-sm text-amber-50/90">{inProgressCopy.summary}</p>
</div>
@@ -213,13 +241,14 @@ export default function DriveDockAction({ layout = 'desktop', expand = false, dr
onClick={handleOpenDock}
className={
isMobile
? 'flex w-full items-center justify-center border border-slate-700 bg-indigo-900 px-0.75 py-0.75 text-sm font-semibold text-indigo-50 shadow transition hover:bg-indigo-800 disabled:cursor-not-allowed disabled:opacity-50'
: `${baseCardClasses} ${filledHeight} items-center bg-indigo-900 text-center transition hover:bg-indigo-800 disabled:cursor-not-allowed disabled:opacity-50`
? `flex w-full items-center justify-center ${baseCardClasses} ${ctaTextAndLayout} ${ctaSize} ${indigoCta}`
: `${baseCardClasses} ${filledHeight} ${ctaTextAndLayout} ${ctaSize} ${indigoCta}`
}
>
<div className="flex items-center justify-center gap-0.5 w-full">
<div className="flex flex-wrap items-center justify-center gap-0.5 w-full">
<span className="text-base font-semibold text-indigo-50">Dock and Charge</span>
{!isMobile && dockKeyLabel ? <KeyPill label={dockKeyLabel} /> : null}
{!isMobile ? <ActionPill label="Click to begin docking" tone="indigo" /> : null}
</div>
{!isMobile && (
<>