fix(odin): clear composer on send + readable selection in user bubble

- the sent message now leaves the input the moment the optimistic bubble
  appears (restored along with attachments if the request fails)
- text selected in the primary-filled user bubble inverts to
  white-on-primary instead of vanishing into the global ::selection style

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-11 00:11:31 +02:00
parent 9496944ad2
commit 10c8454c9b
2 changed files with 18 additions and 3 deletions

View File

@@ -216,6 +216,8 @@ export default function OdinChat() {
// tools over system data); attachments keep the invoice-extract path.
setBusy(true);
const prevTurns = turns;
const prevInput = input;
const prevAttachments = attachments;
const userContent = [
text,
@@ -228,6 +230,10 @@ export default function OdinChat() {
{ role: "user", content: userContent },
];
setTurns(optimistic);
// Clear the composer immediately — the message now lives in the thread
// as the optimistic bubble; a failure restores both below.
setInput("");
setAttachments([]);
try {
if (files.length > 0) {
@@ -268,8 +274,6 @@ export default function OdinChat() {
setReview((prev) => [...prev, ...reviews]);
const note = summaryNote(reviews);
setTurns((t) => [...t, { role: "assistant", content: note }]);
setInput("");
setAttachments([]);
// Create the conversation now (first successful message) and persist.
const convId = await ensureActive();
if (convId != null)
@@ -293,7 +297,6 @@ export default function OdinChat() {
? body.data.tool_trace
: undefined;
setTurns((t) => [...t, { role: "assistant", content: reply, tools }]);
setInput("");
// Create the conversation now (first successful message) and persist.
const convId = await ensureActive();
if (convId != null)
@@ -305,6 +308,9 @@ export default function OdinChat() {
}
} catch (e) {
setTurns(prevTurns);
// Give the user their message back to retry/edit.
setInput(prevInput);
setAttachments(prevAttachments);
const fallback = files.length > 0 ? "Chyba čtení faktur" : "Chyba AI";
alert.error(e instanceof Error ? e.message : fallback);
} finally {

View File

@@ -196,6 +196,15 @@ export default function OdinThread({
borderRadius: 2,
boxShadow: 1,
bgcolor: isUser ? "primary.main" : "background.paper",
// The global ::selection is primary-on-white — invisible on
// this primary-filled bubble; invert it so selected/copied
// text stays readable.
...(isUser && {
"& ::selection": {
backgroundColor: "common.white",
color: "primary.main",
},
}),
}}
>
{/* Tools the assistant consulted for this turn (Phase 2a). */}