mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
oips
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-D4ntwpBT.js"></script>
|
<script type="module" crossorigin src="/assets/index-Ci2FjtMy.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CFFHeBRz.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CFFHeBRz.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
|
|||||||
import { useSession } from '../context/SessionContext.jsx';
|
import { useSession } from '../context/SessionContext.jsx';
|
||||||
import RoverRoster from './RoverRoster.jsx';
|
import RoverRoster from './RoverRoster.jsx';
|
||||||
import ChatMessageRow from './ChatMessageRow.jsx';
|
import ChatMessageRow from './ChatMessageRow.jsx';
|
||||||
|
import { roverNameChromeStyle } from '../lib/roverColor.js';
|
||||||
|
|
||||||
const MODES = [
|
const MODES = [
|
||||||
{ key: 'open', label: 'Open' },
|
{ key: 'open', label: 'Open' },
|
||||||
@@ -340,7 +341,7 @@ export default function AdminPanel() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<ReplaySnapshotHealth health={health} />
|
<ReplaySnapshotHealth health={health} roster={roster} />
|
||||||
<LlmCommentaryPanel
|
<LlmCommentaryPanel
|
||||||
state={llmCommentaryState}
|
state={llmCommentaryState}
|
||||||
onClearHistory={handleClearLlmHistory}
|
onClearHistory={handleClearLlmHistory}
|
||||||
@@ -603,10 +604,12 @@ function buildLlmConversationRowsFromMessages(modelMessages, rawOutput) {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReplaySnapshotHealth({ health }) {
|
function ReplaySnapshotHealth({ health, roster = [] }) {
|
||||||
if (!health) return null;
|
if (!health) return null;
|
||||||
const replay = health.replay || { sources: [], readyCount: 0, totalCount: 0 };
|
const replay = health.replay || { sources: [], readyCount: 0, totalCount: 0 };
|
||||||
const snapshots = health.snapshots || { rovers: [], rooms: [] };
|
const snapshots = health.snapshots || { rovers: [], rooms: [] };
|
||||||
|
const roverColorFor = (id) =>
|
||||||
|
roster.find((entry) => String(entry.id) === String(id))?.color || null;
|
||||||
const replaySummary = `${replay.readyCount}/${replay.totalCount} sources ready`;
|
const replaySummary = `${replay.readyCount}/${replay.totalCount} sources ready`;
|
||||||
const roverStale = snapshots.rovers.filter((entry) => entry.stale).length;
|
const roverStale = snapshots.rovers.filter((entry) => entry.stale).length;
|
||||||
const roomStale = snapshots.rooms.filter((entry) => entry.stale).length;
|
const roomStale = snapshots.rooms.filter((entry) => entry.stale).length;
|
||||||
@@ -634,7 +637,16 @@ function ReplaySnapshotHealth({ health }) {
|
|||||||
<div className="space-y-0.5 text-xs text-slate-300">
|
<div className="space-y-0.5 text-xs text-slate-300">
|
||||||
{replay.sources.map((source) => (
|
{replay.sources.map((source) => (
|
||||||
<div key={`${source.type}:${source.id}`} className="flex items-center justify-between">
|
<div key={`${source.type}:${source.id}`} className="flex items-center justify-between">
|
||||||
<span>{source.label}</span>
|
<span
|
||||||
|
className={`${source.type === 'rover' ? 'rounded px-1 py-[1px] border border-transparent' : ''}`}
|
||||||
|
style={
|
||||||
|
source.type === 'rover'
|
||||||
|
? roverNameChromeStyle(roverColorFor(source.id), 0.16)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{source.label}
|
||||||
|
</span>
|
||||||
<span className={source.ready ? 'text-emerald-300' : 'text-amber-300'}>
|
<span className={source.ready ? 'text-emerald-300' : 'text-amber-300'}>
|
||||||
{source.recentCount}/{source.neededCount}
|
{source.recentCount}/{source.neededCount}
|
||||||
</span>
|
</span>
|
||||||
@@ -644,7 +656,12 @@ function ReplaySnapshotHealth({ health }) {
|
|||||||
<div className="space-y-0.5 text-xs text-slate-300">
|
<div className="space-y-0.5 text-xs text-slate-300">
|
||||||
{snapshots.rovers.map((entry) => (
|
{snapshots.rovers.map((entry) => (
|
||||||
<div key={`rover:${entry.id}`} className="flex items-center justify-between">
|
<div key={`rover:${entry.id}`} className="flex items-center justify-between">
|
||||||
<span>{entry.name}</span>
|
<span
|
||||||
|
className="rounded px-1 py-[1px] border border-transparent"
|
||||||
|
style={roverNameChromeStyle(roverColorFor(entry.id), 0.16)}
|
||||||
|
>
|
||||||
|
{entry.name}
|
||||||
|
</span>
|
||||||
<span className={entry.stale ? 'text-amber-300' : 'text-emerald-300'}>
|
<span className={entry.stale ? 'text-amber-300' : 'text-emerald-300'}>
|
||||||
{entry.stale ? 'stale' : 'ok'}
|
{entry.stale ? 'stale' : 'ok'}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useSession } from '../context/SessionContext.jsx';
|
import { useSession } from '../context/SessionContext.jsx';
|
||||||
import { useSettingsNamespace } from '../settings/index.js';
|
import { useSettingsNamespace } from '../settings/index.js';
|
||||||
import { roverSwatchStyle } from '../lib/roverColor.js';
|
import { roverNameChromeStyle, roverSwatchStyle } from '../lib/roverColor.js';
|
||||||
|
|
||||||
function normalizeSources(list = []) {
|
function normalizeSources(list = []) {
|
||||||
return list
|
return list
|
||||||
@@ -152,7 +152,12 @@ function GroupList({ title, items, selected, onToggle }) {
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<span className="truncate">{item.label}</span>
|
<span
|
||||||
|
className={`truncate ${item.type === 'rover' ? 'rounded px-1 py-[1px] border border-transparent' : ''}`}
|
||||||
|
style={item.type === 'rover' ? roverNameChromeStyle(item.color, 0.16) : undefined}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user