Skip to content

Commit 5461929

Browse files
tui(voice): simplify spinner lifecycle; rely on placeholder disappearance and 60s cap
- Remove explicit spinner stop flags and stop calls - Spinner tasks auto-expire after 60s; UI ignores updates once placeholder is gone - Keep Drop minimal: stop capture and clear placeholder All TUI tests pass.
1 parent 67c7969 commit 5461929

1 file changed

Lines changed: 7 additions & 29 deletions

File tree

codex-rs/tui/src/bottom_pane/chat_composer.rs

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use crate::tui::FrameRequester;
3434
use codex_file_search::FileMatch;
3535
use std::cell::RefCell;
3636
use std::collections::VecDeque;
37-
use std::collections::HashMap;
3837
use std::sync::Arc;
3938
use std::sync::Mutex;
4039
use std::sync::atomic::AtomicBool;
@@ -90,7 +89,6 @@ pub(crate) struct ChatComposer {
9089
space_hold_element_id: Option<String>,
9190
space_hold_trigger: Option<Arc<AtomicBool>>,
9291
// Spinner control flags keyed by placeholder id; set to true to stop.
93-
spinner_stop_flags: HashMap<String, Arc<AtomicBool>>,
9492
}
9593

9694
/// Popup state – at most one can be visible at any time.
@@ -130,7 +128,6 @@ impl ChatComposer {
130128
space_hold_started_at: None,
131129
space_hold_element_id: None,
132130
space_hold_trigger: None,
133-
spinner_stop_flags: HashMap::new(),
134131
}
135132
}
136133

@@ -880,10 +877,8 @@ impl ChatComposer {
880877
});
881878
}
882879

883-
fn spawn_transcribing_spinner(&mut self, id: String) {
880+
fn spawn_transcribing_spinner(&self, id: String) {
884881
let tx = self.app_event_tx.clone();
885-
let stop = Arc::new(AtomicBool::new(false));
886-
self.spinner_stop_flags.insert(id.clone(), stop.clone());
887882
tokio::spawn(async move {
888883
use std::time::Duration;
889884
let frames: Vec<&'static str> = vec![
@@ -893,9 +888,6 @@ impl ChatComposer {
893888
// Safety stop after ~60s to avoid a runaway task if events are lost.
894889
let max_ticks = 600usize; // 600 * 100ms = 60s
895890
for _ in 0..max_ticks {
896-
if stop.load(Ordering::Relaxed) {
897-
break;
898-
}
899891
let text = frames[i % frames.len()].to_string();
900892
tx.send(crate::app_event::AppEvent::RecordingMeter {
901893
id: id.clone(),
@@ -907,17 +899,10 @@ impl ChatComposer {
907899
});
908900
}
909901

910-
fn stop_spinner_if_any(&mut self, id: &str) {
911-
if let Some(flag) = self.spinner_stop_flags.remove(id) {
912-
flag.store(true, Ordering::Relaxed);
913-
}
914-
}
915-
916902
pub fn replace_transcription(&mut self, id: &str, text: &str) {
917903
// Only replace if the placeholder still exists; otherwise do nothing.
918904
let replaced = self.textarea.replace_element_by_id(id, text);
919905
if replaced {
920-
self.stop_spinner_if_any(id);
921906
self.sync_command_popup();
922907
self.sync_file_search_popup();
923908
}
@@ -929,9 +914,6 @@ impl ChatComposer {
929914
if updated {
930915
self.sync_command_popup();
931916
self.sync_file_search_popup();
932-
} else {
933-
// If placeholder disappeared, proactively stop spinner task.
934-
self.stop_spinner_if_any(id);
935917
}
936918
updated
937919
}
@@ -941,7 +923,6 @@ impl ChatComposer {
941923
pub fn remove_transcription_placeholder(&mut self, id: &str) {
942924
// Replace with empty string to delete the placeholder if present.
943925
if self.textarea.replace_element_by_id(id, "") {
944-
self.stop_spinner_if_any(id);
945926
self.sync_command_popup();
946927
self.sync_file_search_popup();
947928
}
@@ -1141,16 +1122,13 @@ impl WidgetRef for &ChatComposer {
11411122

11421123
impl Drop for ChatComposer {
11431124
fn drop(&mut self) {
1144-
// Stop any running spinner tasks.
1145-
for (_id, flag) in self.spinner_stop_flags.drain() {
1146-
flag.store(true, Ordering::Relaxed);
1147-
}
11481125
// If recording is active, stop capture and clean up placeholder.
1149-
if let Some(vc) = self.voice.take()
1150-
&& let Ok(_audio) = vc.stop()
1151-
&& let Some(id) = self.recording_placeholder_id.take() {
1152-
let _ = self.textarea.replace_element_by_id(&id, "");
1153-
}
1126+
if let Some(vc) = self.voice.take() {
1127+
let _ = vc.stop();
1128+
}
1129+
if let Some(id) = self.recording_placeholder_id.take() {
1130+
let _ = self.textarea.replace_element_by_id(&id, "");
1131+
}
11541132
}
11551133
}
11561134

0 commit comments

Comments
 (0)