@@ -34,7 +34,6 @@ use crate::tui::FrameRequester;
3434use codex_file_search:: FileMatch ;
3535use std:: cell:: RefCell ;
3636use std:: collections:: VecDeque ;
37- use std:: collections:: HashMap ;
3837use std:: sync:: Arc ;
3938use std:: sync:: Mutex ;
4039use 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
11421123impl 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