use super::{input, render, state};
pub(crate) fn key_viewports(
terminal_area: ratatui::layout::Rect,
state: &state::MissionControlState,
) -> input::KeyViewports {
let layout = render::layout_for(terminal_area, state);
let prompt_viewport = layout.pane_area(render::TuiPane::Prompt).map(|area| {
let text_area = render::content_text_area_for_pane(render::TuiPane::Prompt, area);
input::PromptViewport {
visible_rows: text_area.height.max(1),
wrap_width: render::scroll_view_content_width(text_area).max(1),
}
});
let transcript_viewport = layout.pane_area(render::TuiPane::Transcript).map(|area| {
let text_area = render::content_text_area_for_pane(render::TuiPane::Transcript, area);
input::TranscriptViewport {
visible_rows: text_area.height.max(1),
wrap_width: render::transcript_scroll_view_content_width(text_area).max(1),
}
});
let activity_tree_viewport = layout.pane_area(render::TuiPane::ActivityTree).map(|area| {
let text_area = render::content_text_area_for_pane(render::TuiPane::ActivityTree, area);
input::ActivityTreeViewport {
visible_rows: text_area.height.max(1),
}
});
let detail_viewport = layout.pane_area(render::TuiPane::Detail).map(|area| {
let text_area = render::content_text_area_for_pane(render::TuiPane::Detail, area);
let visible_rows = state.detail_body_viewport_rows(
text_area.height,
render::scroll_view_content_width(text_area).max(1),
);
input::DetailViewport {
visible_rows,
wrap_width: render::scroll_view_content_width(text_area).max(1),
}
});
let system_prompt_viewport =
render::system_prompt_text_area(terminal_area).map(|area| input::SystemPromptViewport {
visible_rows: area.height.max(1),
wrap_width: render::scroll_view_content_width(area).max(1),
});
let subagent_viewer_viewport =
render::subagent_viewer_timeline_area(terminal_area).map(|area| {
input::SystemPromptViewport {
visible_rows: area.height.max(1),
wrap_width: render::scroll_view_content_width(area).max(1),
}
});
let connect_provider_modal_visible = render::connect_provider_modal_visible(terminal_area);
let connect_provider_custom_field_visible =
render::connect_provider_custom_field_visible(terminal_area);
let connect_provider_oauth_controls_visible =
render::connect_provider_oauth_controls_visible(terminal_area);
let connect_provider_oauth_fallback_visible =
render::connect_provider_oauth_fallback_visible(terminal_area);
let logout_confirmation_action_row =
state
.modals
.logout_confirmation
.as_ref()
.and_then(|confirmation| {
render::logout_confirmation_action_row_area(
terminal_area,
&confirmation.label,
&confirmation.provider_id,
)
});
let connect_provider_viewport = state.modals.connect_provider.as_ref().and_then(|connect| {
if connect.stage == state::ConnectProviderStage::ChooseProvider {
picker_viewport(render::connect_provider_choice_list_area(terminal_area))
} else {
None
}
});
let logout_picker_viewport = state.modals.logout_picker.as_ref().and_then(|picker| {
picker_viewport(render::logout_picker_list_area(
terminal_area,
picker.notice.is_some(),
))
});
let model_picker_viewport = state.modals.model_picker.as_ref().and_then(|picker| {
picker_viewport(render::model_picker_list_area(
terminal_area,
picker.notice.is_some(),
))
});
let skills_modal_viewport = picker_viewport(render::skills_modal_list_area(terminal_area));
let skills_scope_visible = render::settings_scope_visible(terminal_area);
let mcp_modal_viewport = picker_viewport(render::mcp_modal_list_area(terminal_area));
let tools_modal_viewport = picker_viewport(render::tools_modal_list_area(terminal_area));
let tools_scope_visible = render::settings_scope_visible(terminal_area);
let subagents_modal_viewport =
picker_viewport(render::subagents_modal_list_area(terminal_area));
let subagents_scope_visible = render::settings_scope_visible(terminal_area);
let session_picker_viewport_value = session_picker_viewport(terminal_area);
let models_modal_viewport = picker_viewport(render::models_modal_list_area(terminal_area));
let models_scope_visible = render::settings_scope_visible(terminal_area);
let theme_picker_viewport = picker_viewport(render::theme_picker_list_area(terminal_area));
let theme_query_visible = render::theme_picker_query_visible(terminal_area);
input::KeyViewports {
prompt: prompt_viewport,
transcript: transcript_viewport,
activity_tree: activity_tree_viewport,
detail: detail_viewport,
summary: layout
.summary
.map(|area| render::summary_section_body(area, state.session_files.focused)),
system_prompt: system_prompt_viewport,
rewind_modal: render::rewind_modal_text_area(terminal_area).map(|area| {
input::SystemPromptViewport {
visible_rows: area.height.max(1),
wrap_width: render::scroll_view_content_width(area).max(1),
}
}),
usage_modal: render::usage_modal_text_area(terminal_area).map(|area| {
input::SystemPromptViewport {
visible_rows: area.height.max(1),
wrap_width: render::scroll_view_content_width(area).max(1),
}
}),
connect_provider: connect_provider_viewport,
connect_provider_modal_visible,
connect_provider_custom_field_visible,
connect_provider_oauth_controls_visible,
connect_provider_oauth_fallback_visible,
logout_picker: logout_picker_viewport,
logout_confirmation_action_row,
model_picker: model_picker_viewport,
sessions_modal: session_picker_viewport_value,
subagent_viewer: subagent_viewer_viewport,
skills_modal: skills_modal_viewport,
skills_scope_visible,
mcp_modal: mcp_modal_viewport,
tools_modal: tools_modal_viewport,
tools_scope_visible,
subagents_modal: subagents_modal_viewport,
subagents_scope_visible,
models_modal: models_modal_viewport,
models_scope_visible,
theme_picker: theme_picker_viewport,
theme_query_visible,
}
}
pub(crate) fn paste_viewports(
terminal_area: ratatui::layout::Rect,
state: &state::MissionControlState,
) -> input::KeyViewports {
key_viewports(terminal_area, state)
}
fn picker_viewport(list_area: Option<ratatui::layout::Rect>) -> Option<input::PickerViewport> {
list_area.map(|area| input::PickerViewport {
visible_rows: area.height.max(1),
})
}
fn session_picker_viewport(
terminal_area: ratatui::layout::Rect,
) -> Option<input::SessionPickerViewport> {
render::sessions_modal_areas(terminal_area).map(|areas| input::SessionPickerViewport {
list_rows: areas.list.height.max(1),
preview_rows: areas.preview.map(|area| area.height.max(1)).unwrap_or(1),
preview_width: areas
.preview
.map(|area| render::scroll_view_content_width(area).max(1))
.unwrap_or(1),
preview_visible: areas.preview.is_some(),
})
}