commit 24747d7bdc38ba1feb67ada5faed070d5842bd72
parent bfa3c342d1f0c68a1fe9c0162a767a0d10e03d88
Author: William Casarin <jb55@jb55.com>
Date: Tue, 24 Feb 2026 11:45:33 -0800
dave: add queued indicator for messages sent while working
Show a subtle "queued" label on user messages that haven't been
dispatched yet (trailing user messages while the session is working).
The indicator appears on both local and remote sessions and
disappears once Claude finishes the current turn and picks up the
queued message.
Also adds a tracing::info log when a message is queued.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs
@@ -2190,6 +2190,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
// needs_redispatch_after_stream_end() will dispatch it when the
// current turn finishes.
if session.is_streaming() {
+ tracing::info!("message queued, will dispatch after current turn");
return;
}
}
diff --git a/crates/notedeck_dave/src/ui/dave.rs b/crates/notedeck_dave/src/ui/dave.rs
@@ -402,13 +402,25 @@ impl<'a> DaveUi<'a> {
let mut response = DaveResponse::default();
let is_agentic = self.ai_mode == AiMode::Agentic;
- for message in self.chat {
+ // Find where queued (not-yet-dispatched) user messages start:
+ // trailing User messages while the session is working.
+ let queued_from = if self.flags.contains(DaveUiFlags::IsWorking) {
+ self.chat
+ .iter()
+ .rposition(|m| !matches!(m, Message::User(_)))
+ .map(|i| i + 1)
+ } else {
+ None
+ };
+
+ for (i, message) in self.chat.iter().enumerate() {
match message {
Message::Error(err) => {
self.error_chat(ctx.i18n, err, ui);
}
Message::User(msg) => {
- self.user_chat(msg, ui);
+ let is_queued = queued_from.is_some_and(|qi| i >= qi);
+ self.user_chat(msg, is_queued, ui);
}
Message::Assistant(msg) => {
self.assistant_chat(msg, ui);
@@ -1181,7 +1193,7 @@ impl<'a> DaveUi<'a> {
.inner
}
- fn user_chat(&self, msg: &str, ui: &mut egui::Ui) {
+ fn user_chat(&self, msg: &str, is_queued: bool, ui: &mut egui::Ui) {
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
let r = egui::Frame::new()
.inner_margin(10.0)
@@ -1193,6 +1205,13 @@ impl<'a> DaveUi<'a> {
.wrap_mode(egui::TextWrapMode::Wrap)
.selectable(true),
);
+ if is_queued {
+ ui.label(
+ egui::RichText::new("queued")
+ .small()
+ .color(ui.visuals().weak_text_color()),
+ );
+ }
});
r.response.context_menu(|ui| {
if ui.button("Copy").clicked() {