chore: move each view used in BottomPane into its own file (#928)

`BottomPane` was getting a bit unwieldy because it maintained a
`PaneState` enum with three variants and many of its methods had `match`
statements to handle each variant. To replace the enum, this PR:

* Introduces a `trait BottomPaneView` that has two implementations:
`StatusIndicatorView` and `ApprovalModalView`.
* Migrates `PaneState::TextInput` into its own struct, `ChatComposer`,
that does **not** implement `BottomPaneView`.
* Updates `BottomPane` so it has `composer: ChatComposer` and
`active_view: Option<Box<dyn BottomPaneView<'a> + 'a>>`. The idea is
that `active_view` takes priority and is displayed when it is `Some`;
otherwise, `ChatComposer` is displayed.
* While methods of `BottomPane` often have to check whether
`active_view` is present to decide which component to delegate to, the
code is more straightforward than before and introducing new
implementations of `BottomPaneView` should be less painful.

Because we want to retain the `TextArea` owned by `ChatComposer` even
when another view is displayed, to keep the ownership logic simple, it
seemed best to keep `ChatComposer` distinct from `BottomPaneView`.
This commit is contained in:
Michael Bolin
2025-05-14 10:13:29 -07:00
committed by GitHub
parent 399e819c9b
commit 0402aef126
8 changed files with 490 additions and 358 deletions

View File

@@ -1,10 +1,5 @@
//! A live status indicator that shows the *latest* log line emitted by the
//! application while the agent is processing a longrunning task.
//!
//! It replaces the old spinner animation with real log feedback so users can
//! watch Codex “think” in realtime. Whenever new text is provided via
//! [`StatusIndicatorWidget::update_text`], the parent widget triggers a
//! redraw so the change is visible immediately.
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
@@ -14,7 +9,6 @@ use std::sync::mpsc::Sender;
use std::thread;
use std::time::Duration;
use crossterm::event::KeyEvent;
use ratatui::buffer::Buffer;
use ratatui::layout::Alignment;
use ratatui::layout::Rect;
@@ -45,8 +39,8 @@ pub(crate) struct StatusIndicatorWidget {
/// input mode and loading mode.
height: u16,
frame_idx: std::sync::Arc<AtomicUsize>,
running: std::sync::Arc<AtomicBool>,
frame_idx: Arc<AtomicUsize>,
running: Arc<AtomicBool>,
// Keep one sender alive to prevent the channel from closing while the
// animation thread is still running. The field itself is currently not
// accessed anywhere, therefore the leading underscore silences the
@@ -87,14 +81,6 @@ impl StatusIndicatorWidget {
}
}
pub(crate) fn handle_key_event(
&mut self,
_key: KeyEvent,
) -> Result<bool, std::sync::mpsc::SendError<AppEvent>> {
// The indicator does not handle any input always return `false`.
Ok(false)
}
/// Preferred height in terminal rows.
pub(crate) fn get_height(&self) -> u16 {
self.height