fix(tui): sync token loading card in transcript overlay

This commit is contained in:
Felipe Coury
2026-05-30 17:39:34 -03:00
parent ef23a80eed
commit bca77e2bd0
3 changed files with 22 additions and 8 deletions

View File

@@ -1871,12 +1871,12 @@ impl ChatWidget {
self.current_rollout_path.clone()
}
/// Returns a cache key describing the current in-flight active cell for the transcript overlay.
/// Returns a cache key describing the current in-flight cells for the transcript overlay.
///
/// `Ctrl+T` renders committed transcript cells plus a render-only live tail derived from the
/// current active cell, and the overlay caches that tail; this key is what it uses to decide
/// whether it must recompute. When there is no active cell, this returns `None` so the overlay
/// can drop the tail entirely.
/// current active, hook, and token activity cells, and the overlay caches that tail; this key is
/// what it uses to decide whether it must recompute. When there are no live cells, this returns
/// `None` so the overlay can drop the tail entirely.
///
/// If callers mutate the active cell's transcript output without bumping the revision (or
/// providing an appropriate animation tick), the overlay will keep showing a stale tail while
@@ -1884,7 +1884,8 @@ impl ChatWidget {
pub(crate) fn active_cell_transcript_key(&self) -> Option<ActiveCellTranscriptKey> {
let cell = self.transcript.active_cell.as_ref();
let hook_cell = self.active_hook_cell.as_ref();
if cell.is_none() && hook_cell.is_none() {
let token_activity_cell = self.pending_token_activity_output();
if cell.is_none() && hook_cell.is_none() && token_activity_cell.is_none() {
return None;
}
Some(ActiveCellTranscriptKey {
@@ -1922,6 +1923,13 @@ impl ChatWidget {
}
lines.extend(hook_lines);
}
if let Some(token_activity_cell) = self.pending_token_activity_output() {
let token_activity_lines = token_activity_cell.transcript_hyperlink_lines(width);
if !token_activity_lines.is_empty() && !lines.is_empty() {
lines.push(HyperlinkLine::from(""));
}
lines.extend(token_activity_lines);
}
(!lines.is_empty()).then_some(lines)
}

View File

@@ -1190,6 +1190,11 @@ async fn clearing_pending_token_activity_refreshes_discards_late_result() {
.map(|cell| lines_to_single_string(&cell.display_lines(u16::MAX))),
Some("/tokens daily\n\n Token activity\n Loading...\n".to_string()),
);
assert_eq!(
chat.active_cell_transcript_lines(u16::MAX)
.map(|lines| lines_to_single_string(&lines)),
Some("/tokens daily\n\n Token activity\n Loading...\n".to_string()),
);
chat.clear_pending_token_activity_refreshes();

View File

@@ -647,6 +647,7 @@ impl ChatWidget {
cell,
handle,
});
self.bump_active_cell_revision();
self.request_redraw();
self.app_event_tx
.send(AppEvent::RefreshTokenActivity { request_id });
@@ -663,20 +664,20 @@ impl ChatWidget {
request_id: u64,
result: Result<GetAccountTokenUsageResponse, String>,
) -> Option<CompositeHistoryCell> {
let Some(output) = self.refreshing_token_activity_output.take() else {
return None;
};
let output = self.refreshing_token_activity_output.take()?;
if output.request_id != request_id {
self.refreshing_token_activity_output = Some(output);
return None;
}
output.handle.finish(result);
self.bump_active_cell_revision();
self.request_redraw();
Some(output.cell)
}
pub(crate) fn clear_pending_token_activity_refreshes(&mut self) {
if self.refreshing_token_activity_output.take().is_some() {
self.bump_active_cell_revision();
self.request_redraw();
}
}