1 file changed
+26
-4
src/chat.rs
+26
-4
@@ -199,6 +199,11 @@ impl App {
199
self.is_streaming() || self.thinking || self.switching_model
200
}
201
202
+ fn switching_frame(&self) -> &'static str {
203
+ let idx = (self.thinking_tick as usize) % THINKING_FRAMES.len();
204
+ THINKING_FRAMES[idx]
205
+ }
206
+
207
fn is_streaming(&self) -> bool {
208
self.stream_rx.is_some()
209
}
@@ -334,8 +339,8 @@ impl App {
339
if !self.stream_buf.is_empty() {
340
lines += wrapped_line_count(&self.stream_buf, Role::Assistant, w);
341
}
337
- // thinking indicator
338
- if self.thinking {
342
+ // thinking / switching indicator
343
+ if self.thinking || self.switching_model {
344
lines += 1;
345
}
346
lines
@@ -769,6 +774,23 @@ fn render_messages(frame: &mut Frame, app: &mut App, area: ratatui::layout::Rect
774
lines.push(Line::from(spans));
775
}
776
777
+ // switching-model indicator (animated spinner)
778
+ if app.switching_model {
779
+ let frame_char = app.switching_frame();
780
+ lines.push(Line::from(vec![
781
+ Span::styled(
782
+ "siGit > ",
783
+ Style::default()
784
+ .fg(Color::Green)
785
+ .add_modifier(Modifier::BOLD),
786
+ ),
787
+ Span::styled(
788
+ format!("{frame_char} loading model…"),
789
+ Style::default().fg(Color::Cyan).add_modifier(Modifier::DIM),
790
+ ),
791
+ ]));
792
+ }
793
+
794
// thinking indicator (animated spinner)
795
if app.thinking {
796
let frame_char = app.thinking_frame();
@@ -1408,9 +1430,9 @@ async fn event_loop<B: ratatui::backend::Backend>(
1430
}
1431
}
1432
1411
- // ── thinking spinner tick (100ms) ────────────────────────────
1433
+ // ── thinking / switching spinner tick (100ms) ────────────────
1434
_ = async {
1413
- if app.thinking {
1435
+ if app.thinking || app.switching_model {
1436
tokio::time::sleep(Duration::from_millis(100)).await
1437
} else {
1438
pending().await