fix: esc w/ queued messages overwrites draft in composer (#4237)
Instead of overwriting the contents of the composer when pressing <kbd>Esc</kbd> when there's a queued message, prepend the queued message(s) to the composer draft.
This commit is contained in:
@@ -264,7 +264,6 @@ impl ChatComposer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current composer text.
|
/// Get the current composer text.
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) fn current_text(&self) -> String {
|
pub(crate) fn current_text(&self) -> String {
|
||||||
self.textarea.text().to_string()
|
self.textarea.text().to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,7 +262,6 @@ impl BottomPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current composer text (for tests and programmatic checks).
|
/// Get the current composer text (for tests and programmatic checks).
|
||||||
#[cfg(test)]
|
|
||||||
pub(crate) fn composer_text(&self) -> String {
|
pub(crate) fn composer_text(&self) -> String {
|
||||||
self.composer.current_text()
|
self.composer.current_text()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -427,12 +427,20 @@ impl ChatWidget {
|
|||||||
|
|
||||||
// If any messages were queued during the task, restore them into the composer.
|
// If any messages were queued during the task, restore them into the composer.
|
||||||
if !self.queued_user_messages.is_empty() {
|
if !self.queued_user_messages.is_empty() {
|
||||||
let combined = self
|
let queued_text = self
|
||||||
.queued_user_messages
|
.queued_user_messages
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| m.text.clone())
|
.map(|m| m.text.clone())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
let existing_text = self.bottom_pane.composer_text();
|
||||||
|
let combined = if existing_text.is_empty() {
|
||||||
|
queued_text
|
||||||
|
} else if queued_text.is_empty() {
|
||||||
|
existing_text
|
||||||
|
} else {
|
||||||
|
format!("{queued_text}\n{existing_text}")
|
||||||
|
};
|
||||||
self.bottom_pane.set_composer_text(combined);
|
self.bottom_pane.set_composer_text(combined);
|
||||||
// Clear the queue and update the status indicator list.
|
// Clear the queue and update the status indicator list.
|
||||||
self.queued_user_messages.clear();
|
self.queued_user_messages.clear();
|
||||||
|
|||||||
@@ -1299,6 +1299,40 @@ fn interrupt_restores_queued_messages_into_composer() {
|
|||||||
let _ = drain_insert_history(&mut rx);
|
let _ = drain_insert_history(&mut rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn interrupt_prepends_queued_messages_before_existing_composer_text() {
|
||||||
|
let (mut chat, mut rx, mut op_rx) = make_chatwidget_manual();
|
||||||
|
|
||||||
|
chat.bottom_pane.set_task_running(true);
|
||||||
|
chat.bottom_pane
|
||||||
|
.set_composer_text("current draft".to_string());
|
||||||
|
|
||||||
|
chat.queued_user_messages
|
||||||
|
.push_back(UserMessage::from("first queued".to_string()));
|
||||||
|
chat.queued_user_messages
|
||||||
|
.push_back(UserMessage::from("second queued".to_string()));
|
||||||
|
chat.refresh_queued_user_messages();
|
||||||
|
|
||||||
|
chat.handle_codex_event(Event {
|
||||||
|
id: "turn-1".into(),
|
||||||
|
msg: EventMsg::TurnAborted(codex_core::protocol::TurnAbortedEvent {
|
||||||
|
reason: TurnAbortReason::Interrupted,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
chat.bottom_pane.composer_text(),
|
||||||
|
"first queued\nsecond queued\ncurrent draft"
|
||||||
|
);
|
||||||
|
assert!(chat.queued_user_messages.is_empty());
|
||||||
|
assert!(
|
||||||
|
op_rx.try_recv().is_err(),
|
||||||
|
"unexpected outbound op after interrupt"
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = drain_insert_history(&mut rx);
|
||||||
|
}
|
||||||
|
|
||||||
// Snapshot test: ChatWidget at very small heights (idle)
|
// Snapshot test: ChatWidget at very small heights (idle)
|
||||||
// Ensures overall layout behaves when terminal height is extremely constrained.
|
// Ensures overall layout behaves when terminal height is extremely constrained.
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user