Skip to content

fix: skip fade-in animation for history-restored messages#4120

Merged
esengine merged 1 commit into
esengine:main-v2from
Diarica:fix/message-flicker-on-restore
Jun 12, 2026
Merged

fix: skip fade-in animation for history-restored messages#4120
esengine merged 1 commit into
esengine:main-v2from
Diarica:fix/message-flicker-on-restore

Conversation

@Diarica

@Diarica Diarica commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Session restore loads every message with animation: graphite-message-in 340ms ease-out both. The both fill-mode means ALL messages start at opacity:0 and animate in simultaneously — on a session with dozens of turns this causes visible text flickering / flashing on startup.

Diagnosis: Historical messages are reloaded all at once during session restore. Each .msg element has a CSS graphite-message-in keyframe animation (opacity 0→1 + translateY 10px→0, 340ms). With animation-fill-mode: both, all elements start invisible, then simultaneously fade in — the user sees a flash.

Live-streamed messages should keep the entrance animation; only static history items need to skip it. History items are reliably identified by their "h"-prefixed IDs (set by historyMessagesToItems in useController).

Fix: Add a data-history-restore attribute on .msg elements whose id starts with "h", and disable the animation via CSS:

.msg[data-history-restore] { animation: none; }
  • Message.tsx: accept id prop on UserMessage; set data-history-restore on both UserMessage and AssistantMessage when id starts with "h"
  • Transcript.tsx: pass id to UserMessage (hot zone + warm zone)
  • styles.css: add override rule after the .msg animation definition

Session restore loads every message with `animation: graphite-message-in
340ms ease-out both`. The `both` fill-mode means ALL messages start at
opacity:0 and animate in simultaneously — on a session with dozens of
turns this causes visible text flickering / flashing on startup.

Live-streamed messages should keep the entrance animation; only static
history items need to skip it. History items are reliably identified by
their "h"-prefixed IDs (set by historyMessagesToItems in useController).

Fix: add a `data-history-restore` attribute on .msg elements whose id
starts with "h", and disable the animation via CSS:

    .msg[data-history-restore] { animation: none; }

- Message.tsx: accept `id` prop on UserMessage; set data-history-restore
  on both UserMessage and AssistantMessage when id starts with "h"
- Transcript.tsx: pass `id` to UserMessage (hot zone + warm zone)
- styles.css: add override rule after the .msg animation definition
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) labels Jun 12, 2026
@esengine

Copy link
Copy Markdown
Owner

Verified the fix where it matters: the modified UserMessage call site is the hot zone (for i := hotStartIdx..items.length), which is exactly what renders all of the recent turns at once on restore and produces the simultaneous fade-in flash — so the reported flicker is fixed. The "h"-prefix check is reliable too: history items are h*/hp*, live items are a/u/n/p/c/s/e, so it never catches a live message, and the [data-history-restore] override has higher specificity than the base .msg animation. Nice, targeted fix — merging.

Minor follow-up (not blocking): the warm-zone UserMessage (the second call site, for an expanded older turn) doesn't get id, so on manual expand the user bubble still animates while the assistant bubble doesn't (AssistantMessage reads item.id directly). One-line id={it.id} there would make it fully consistent — I'll tidy that up separately.

@esengine esengine merged commit 49ce820 into esengine:main-v2 Jun 12, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants