render user messages as a distinct card in the conversation (T-143)
test / unit + widget + golden + a11y (push) Failing after 30s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 32s

User turns rendered flat (a "you" label + text on the canvas), the same
shape as Claude's responses, so prompts were hard to pick out when
scanning. UserMessage now renders in a card: a left accent stripe
(focus colour) and a filled background distinct from the panel canvas.
Claude's text responses stay flat markdown — better for reading long
answers, and the asymmetry makes "what I asked" easy to spot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 00:34:19 +02:00
co-authored by Claude Opus 4.7
parent ce5996f869
commit 9783e6bd2c
4 changed files with 48 additions and 1 deletions
+41 -1
View File
@@ -105,7 +105,7 @@ class _ConversationTurn extends StatelessWidget {
Widget build(BuildContext context) {
final i = item;
return switch (i) {
UserMessage() => _labelled('you', tokens.globalForeground, ClideMarkdown(i.text)),
UserMessage() => _userCard(i),
AssistantTextMessage() => _labelled('claude', tokens.globalFocus, ClideMarkdown(i.text)),
AssistantThinkingMessage() => _labelled(
'thinking',
@@ -117,6 +117,46 @@ class _ConversationTurn extends StatelessWidget {
};
}
/// The user's own message — a distinct card (accent stripe + fill) so
/// it reads apart from Claude's flat-markdown responses.
Widget _userCard(UserMessage m) {
return Padding(
padding: const EdgeInsets.only(bottom: 14),
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: ColoredBox(
color: tokens.globalBackground,
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(width: 3, color: tokens.globalFocus),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClideText(
'you',
fontSize: clideFontSmall,
color: tokens.globalFocus,
fontFamily: clideMonoFamily,
),
const SizedBox(height: 4),
ClideMarkdown(m.text),
],
),
),
),
],
),
),
),
),
);
}
/// A labelled turn: a small role tag above the body.
Widget _labelled(String label, Color labelColor, Widget body) {
return Padding(