use crate::tui::app::{App, SidebarRowAction};
use crate::tui::views::ModalKind;
use super::model::WorkRowId;
pub fn claim_focus(app: &mut App) {
let was_focused = app.work_surface.focused;
app.work_surface.focused = true;
crate::tui::mouse_ui::clear_transcript_selection(app);
if !was_focused {
app.needs_redraw = true;
}
}
pub fn release_focus(app: &mut App) {
if !app.work_surface.focused && app.work_surface.hovered.is_none() {
return;
}
app.work_surface.focused = false;
app.work_surface.hovered = None;
app.needs_redraw = true;
}
pub fn activate_primary(
app: &mut App,
row_id: &WorkRowId,
primary: Option<SidebarRowAction>,
) -> Option<SidebarRowAction> {
if app.work_surface.opened.as_ref() == Some(row_id) {
let detail_on_screen = app.view_stack.top_kind() == Some(ModalKind::Pager);
close_opened(app);
if detail_on_screen {
return None;
}
}
app.work_surface.selected = Some(row_id.clone());
let action = primary?;
if !matches!(action, SidebarRowAction::ShowSubagentsPanel) {
app.work_surface.opened = Some(row_id.clone());
}
Some(action)
}
pub fn close_opened(app: &mut App) {
if app.work_surface.opened.take().is_none() {
return;
}
if app.view_stack.top_kind() == Some(ModalKind::Pager) {
app.view_stack.pop();
}
app.needs_redraw = true;
}
pub(crate) fn agent_details_closed(app: &mut App, agent_id: &str) {
let owner = WorkRowId(format!("worker:{agent_id}"));
if app.work_surface.opened.as_ref() == Some(&owner) {
app.work_surface.opened = None;
app.needs_redraw = true;
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::tui::app::TuiOptions;
use std::path::PathBuf;
fn app() -> App {
let options = TuiOptions {
use_mouse_capture: true,
max_subagents: 4,
..crate::test_support::test_tui_options(PathBuf::from("."))
};
App::new(options, &Config::default())
}
#[test]
fn primary_toggles_opened_closed() {
let mut app = app();
let row = WorkRowId("worker:a1".into());
let open = SidebarRowAction::OpenAgentDetail {
agent_id: "a1".into(),
};
assert!(activate_primary(&mut app, &row, Some(open.clone())).is_some());
assert_eq!(app.work_surface.opened.as_ref(), Some(&row));
app.view_stack.push(crate::tui::pager::PagerView::from_text(
"Agent".to_string(),
"body",
40,
));
assert!(activate_primary(&mut app, &row, Some(open.clone())).is_none());
assert!(app.work_surface.opened.is_none());
assert!(activate_primary(&mut app, &row, Some(open.clone())).is_some());
assert_eq!(app.work_surface.opened.as_ref(), Some(&row));
assert!(activate_primary(&mut app, &row, Some(open)).is_some());
assert_eq!(app.work_surface.opened.as_ref(), Some(&row));
}
#[test]
fn claim_focus_clears_transcript_selection() {
use crate::tui::selection::TranscriptSelectionPoint;
let mut app = app();
app.viewport.transcript_selection.anchor = Some(TranscriptSelectionPoint {
line_index: 0,
column: 0,
});
app.viewport.transcript_selection.head = app.viewport.transcript_selection.anchor;
claim_focus(&mut app);
assert!(app.work_surface.focused);
assert!(!app.viewport.transcript_selection.is_active());
assert!(app.needs_redraw);
}
}