tiny toasts!

This commit is contained in:
legop3
2026-01-15 17:44:26 -05:00
parent d4ce6e9092
commit f129449d5a
6 changed files with 25 additions and 19 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
+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-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-DAR128uo.js"></script> <script type="module" crossorigin src="/assets/index-D-77ZqXZ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BiAFhEoZ.css"> <link rel="stylesheet" crossorigin href="/assets/index-Cc3cNOzE.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+10 -7
View File
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
import { useSession } from '../context/SessionContext.jsx'; import { useSession } from '../context/SessionContext.jsx';
import ChatMessageRow from './ChatMessageRow.jsx'; import ChatMessageRow from './ChatMessageRow.jsx';
const LIFETIME_MS = 5000; const LIFETIME_MS = 3000;
const DEFAULT_COLOR = '#2196f3'; const DEFAULT_COLOR = '#2196f3';
function buildKey(alert) { function buildKey(alert) {
@@ -14,7 +14,7 @@ function buildKey(alert) {
export default function AlertFeed() { export default function AlertFeed() {
const { alerts } = useSession(); const { alerts } = useSession();
const [now, setNow] = useState(() => Date.now()); const [now, setNow] = useState(() => Date.now());
const latest = useMemo(() => alerts.slice(-5).map((alert) => ({ alert, key: buildKey(alert) })), [alerts]); const latest = useMemo(() => alerts.slice(-3).map((alert) => ({ alert, key: buildKey(alert) })), [alerts]);
useEffect(() => { useEffect(() => {
if (!latest.length) return undefined; if (!latest.length) return undefined;
@@ -57,15 +57,18 @@ function AlertToast({ alert }) {
return <ChatMessageRow message={alert.payload} />; return <ChatMessageRow message={alert.payload} />;
} }
const rgb = hexToRgb(alert.color) || hexToRgb(DEFAULT_COLOR); const rgb = hexToRgb(alert.color) || hexToRgb(DEFAULT_COLOR);
const backgroundColor = rgb ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.25)` : 'rgba(33, 150, 243, 0.25)'; const backgroundColor = rgb ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.18)` : 'rgba(33, 150, 243, 0.18)';
const borderColor = rgb ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.7)` : 'rgba(33, 150, 243, 0.7)'; const borderColor = rgb ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.45)` : 'rgba(33, 150, 243, 0.45)';
return ( return (
<div <div
className="pointer-events-auto px-0.5 py-0.5 text-[0.85rem] text-slate-100" className="pointer-events-auto max-w-[80vw] rounded-full border px-2 py-0.5 text-[0.7rem] leading-tight text-slate-100 shadow-sm shadow-black/30"
style={{ backgroundColor, border: `1px solid ${borderColor}` }} style={{ backgroundColor, border: `1px solid ${borderColor}` }}
> >
<p className="text-xs text-slate-200">{alert.title || 'Alert'}</p> <p className="truncate text-slate-100">
<p className="text-sm text-white">{alert.message}</p> <span className="text-slate-300">{alert.title || 'Alert'}</span>
<span className="text-slate-500"> · </span>
<span className="text-white">{alert.message}</span>
</p>
</div> </div>
); );
} }
+3
View File
@@ -710,6 +710,7 @@ function HudChatInput({ compact = false }) {
const [draft, setDraft] = useState(''); const [draft, setDraft] = useState('');
const [sending, setSending] = useState(false); const [sending, setSending] = useState(false);
const canChat = session?.role !== 'spectator'; const canChat = session?.role !== 'spectator';
const hideHudChat = session?.role === 'spectator';
const currentRoverId = session?.assignment?.roverId || null; const currentRoverId = session?.assignment?.roverId || null;
const rover = useMemo( const rover = useMemo(
() => session?.roster?.find((entry) => String(entry.id) === String(currentRoverId)) || null, () => session?.roster?.find((entry) => String(entry.id) === String(currentRoverId)) || null,
@@ -756,6 +757,8 @@ function HudChatInput({ compact = false }) {
} }
} }
if (hideHudChat) return null;
return ( return (
<form onSubmit={handleSend} className={containerClass}> <form onSubmit={handleSend} className={containerClass}>
<input <input