mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
fix chat typing stuff and alert feeder
This commit is contained in:
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
@@ -78,8 +78,8 @@
|
||||
<script defer src="https://analytics.otter.land/script.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land"></script>
|
||||
<script defer src="https://analytics.otter.land/recorder.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land" data-sample-rate="0.15" data-mask-level="moderate" data-max-duration="300000"></script>
|
||||
<title>Roomba Rover</title>
|
||||
<script type="module" crossorigin src="/assets/index-CZg2vwtM.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CflZqP0e.css">
|
||||
<script type="module" crossorigin src="/assets/index-CsI4p8Hs.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B_VrMPCY.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
1. make google tts the default everywhere but roverd
|
||||
2. fix rover request spam queue cheat
|
||||
3. make alert feed.jsx show more alerts at once
|
||||
4. unify typing row and chat row, should be simple
|
||||
5. fix google TTS speeds
|
||||
6. fix this:
|
||||
1. fix rover request spam queue cheat
|
||||
2. fix this:
|
||||
`Jun 18 15:14:18 roombaserver.local node[216731]: /home/daniel/MultiRoombaRover/server/src/services/roverManager/socketHandlers.js:92
|
||||
Jun 18 15:14:18 roombaserver.local node[216731]: cb({ error: err.message });
|
||||
Jun 18 15:14:18 roombaserver.local node[216731]: ^
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useEffect, useMemo, useState } from 'react';
|
||||
import { useSessionActions, useSessionSelector } from '../../context/SessionContext.jsx';
|
||||
import { useSocket } from '../../context/SocketContext.jsx';
|
||||
import ChatMessageRow from '../ChatMessageRow/index.jsx';
|
||||
import ChatTypingRow from '../ChatTypingRow/index.jsx';
|
||||
import ButtonBoxTile from '../ButtonBoxTile/index.jsx';
|
||||
|
||||
const LIFETIME_MS = 3000;
|
||||
@@ -104,7 +103,7 @@ export default function AlertFeed({ scale = 1 }) {
|
||||
});
|
||||
|
||||
return {
|
||||
visible: Array.from(visibleByKey.values()).slice(-3),
|
||||
visible: Array.from(visibleByKey.values()).slice(-6),
|
||||
nextExpiryAt: soonestExpiryAt,
|
||||
};
|
||||
}, [latest, now]);
|
||||
@@ -234,7 +233,7 @@ function AlertToast({ alert }) {
|
||||
return <ChatMessageRow message={alert.payload} />;
|
||||
}
|
||||
if (alert.kind === 'chat-typing' && alert.payload) {
|
||||
return <ChatTypingRow message={alert.payload} />;
|
||||
return <ChatMessageRow message={alert.payload} variant="typing" />;
|
||||
}
|
||||
if (alert.kind === 'barcode-scan' && alert.payload) {
|
||||
return <BarcodeScanToast payload={alert.payload} />;
|
||||
|
||||
@@ -138,7 +138,15 @@ export function ChatIdentity({ message, toolsToggle = null }) {
|
||||
);
|
||||
}
|
||||
|
||||
function chatRowClass(message) {
|
||||
function chatRowClass(message, variant = 'message') {
|
||||
// Typing indicators intentionally reuse the normal chat row shell so avatar,
|
||||
// nickname, rover identity, and Discord identity all stay visually aligned
|
||||
// with real chat messages. The darker slate treatment separates the temporary
|
||||
// "typing..." state without requiring a second component with duplicated
|
||||
// identity markup.
|
||||
if (variant === 'typing') {
|
||||
return 'flex flex-col gap-0.5 rounded-md border border-slate-600/40 bg-slate-900/40 px-0.5 py-0.5 text-sm text-neutral-100 italic opacity-80';
|
||||
}
|
||||
if (isBotMessage(message)) {
|
||||
return 'flex flex-col gap-0.5 rounded-md border border-emerald-500/40 bg-emerald-950 px-0.5 py-0.5 text-sm text-neutral-100';
|
||||
}
|
||||
@@ -153,12 +161,17 @@ function chatRowClass(message) {
|
||||
}`;
|
||||
}
|
||||
|
||||
export default function ChatMessageRow({ message }) {
|
||||
export default function ChatMessageRow({ message, variant = 'message' }) {
|
||||
const isBot = isBotMessage(message);
|
||||
const isTyping = variant === 'typing';
|
||||
const role = useSessionSelector((state) => state.session?.role || null);
|
||||
const isSpectator = role === 'spectator';
|
||||
const [open, setOpen] = useState(false);
|
||||
const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
||||
// Typing payloads are transient presence events, not persisted chat messages.
|
||||
// Treating them as a row variant prevents tool expansion and message-specific
|
||||
// controls from appearing if a future typing payload happens to carry fields
|
||||
// that overlap with stored chat message data.
|
||||
const toolCalls = !isTyping && Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
||||
const hasToolCalls = toolCalls.length > 0;
|
||||
// Spectator chat should expose tool details without requiring interaction, but
|
||||
// only rows that actually contain tools need the expanded two-section layout.
|
||||
@@ -167,6 +180,7 @@ export default function ChatMessageRow({ message }) {
|
||||
// row open even when there is no dropdown content to show.
|
||||
const isOpen = hasToolCalls && (isSpectator || open);
|
||||
const hasText = Boolean(String(message?.text || '').trim());
|
||||
const rowText = isTyping ? 'typing...' : message.text;
|
||||
const toolsToggle =
|
||||
hasToolCalls ? (
|
||||
<button
|
||||
@@ -181,17 +195,19 @@ export default function ChatMessageRow({ message }) {
|
||||
</button>
|
||||
) : null;
|
||||
return (
|
||||
<div className={chatRowClass(message)}>
|
||||
<div className={chatRowClass(message, variant)}>
|
||||
<div className="flex w-full items-start gap-0.5">
|
||||
<span
|
||||
className={`min-w-0 flex-1 break-words leading-tight whitespace-pre-wrap ${isBot ? 'text-emerald-100' : 'text-slate-100'}`}
|
||||
>
|
||||
<ChatIdentity message={message} toolsToggle={toolsToggle} />
|
||||
{!isOpen && hasText ? ` ${message.text}` : ''}
|
||||
</span>
|
||||
<span className="shrink-0 text-[0.65rem] text-slate-400/60">
|
||||
{formatTime(message.ts)}
|
||||
{!isOpen && (hasText || isTyping) ? ` ${rowText}` : ''}
|
||||
</span>
|
||||
{!isTyping ? (
|
||||
<span className="shrink-0 text-[0.65rem] text-slate-400/60">
|
||||
{formatTime(message.ts)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
{isOpen && hasToolCalls ? (
|
||||
<div className="w-full rounded border border-slate-700/70 bg-slate-900/70 p-0.5 text-[0.68rem] text-slate-200">
|
||||
@@ -216,5 +232,3 @@ export default function ChatMessageRow({ message }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { chatRowClass };
|
||||
|
||||
@@ -7,7 +7,6 @@ import { useChatActions, useChatTimeline } from '../../context/ChatContext.jsx';
|
||||
import { useSessionSelector } from '../../context/SessionContext.jsx';
|
||||
import { useSettingsNamespace } from '../../settings/index.js';
|
||||
import ChatMessageRow from '../ChatMessageRow/index.jsx';
|
||||
import ChatTypingRow from '../ChatTypingRow/index.jsx';
|
||||
import CardFrame from '../CardFrame/index.jsx';
|
||||
import NicknameForm from '../NicknameForm/index.jsx';
|
||||
|
||||
@@ -88,7 +87,7 @@ function ChatMessageList({ fillHeight = false }) {
|
||||
sorted.map((msg) => <ChatMessageRow key={msg.id} message={msg} />)
|
||||
)}
|
||||
{typingRows.map((entry) => (
|
||||
<ChatTypingRow key={`typing-${entry.typingId || entry.id}`} message={entry} />
|
||||
<ChatMessageRow key={`typing-${entry.typingId || entry.id}`} message={entry} variant="typing" />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Chat Typing Row
|
||||
// Purpose: Defines the Chat Typing Row module and the local helpers/components used in this file.
|
||||
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
|
||||
import { ChatIdentity, chatRowClass } from '../ChatMessageRow/index.jsx';
|
||||
|
||||
export default function ChatTypingRow({ message }) {
|
||||
return (
|
||||
<div className={`${chatRowClass(message)} !flex-row items-center italic opacity-80 border-slate-600/40 bg-slate-900/40`}>
|
||||
<ChatIdentity message={message} />
|
||||
<span className="text-slate-300">typing...</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user