use super::{AppState, Model};
use crate::app::view::*;
use crate::components::common::ComponentId;
use crate::components::help_bar::HelpBar;
use crate::error::{AppError, AppResult};
use std::io::{self, Write};
use tuirealm::ratatui::layout::{Constraint, Direction, Layout};
use tuirealm::terminal::TerminalAdapter;
impl<T> Model<T>
where
T: TerminalAdapter,
{
pub fn view(&mut self) -> AppResult<()> {
let mut view_result: AppResult<()> = Ok(());
let current_app_state = self.state_manager.app_state.clone();
let active_component = match current_app_state {
AppState::NamespacePicker => ComponentId::NamespacePicker,
AppState::QueuePicker => ComponentId::QueuePicker,
AppState::MessagePicker => ComponentId::Messages,
AppState::MessageDetails => ComponentId::MessageDetails,
AppState::Loading => ComponentId::LoadingIndicator,
AppState::HelpScreen => ComponentId::HelpScreen,
AppState::ThemePicker => ComponentId::ThemePicker,
AppState::ConfigScreen => ComponentId::ConfigScreen,
AppState::PasswordPopup => ComponentId::PasswordPopup,
AppState::AzureDiscovery => {
if self.app.mounted(&ComponentId::NamespacePicker) {
ComponentId::NamespacePicker
} else if self.app.mounted(&ComponentId::ResourceGroupPicker) {
ComponentId::ResourceGroupPicker
} else if self.app.mounted(&ComponentId::SubscriptionPicker) {
ComponentId::SubscriptionPicker
} else {
ComponentId::SubscriptionPicker
}
}
};
log::debug!("View called - AppState: {current_app_state:?}, Active: {active_component:?}");
self.set_active_component(active_component.clone());
let queue_state = &self.queue_manager.queue_state;
let (queue_type, bulk_mode, selected_count) = if active_component == ComponentId::Messages {
(
Some(queue_state.current_queue_type.clone()),
Some(queue_state.bulk_selection.selection_mode),
Some(queue_state.bulk_selection.selection_count()),
)
} else {
(None, None, None)
};
if let Err(e) = self.terminal.draw(|f| {
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints(
[
Constraint::Length(1),
Constraint::Length(1), Constraint::Length(2),
Constraint::Min(16), Constraint::Length(1), ]
.as_ref(),
)
.split(f.area());
self.app.view(&ComponentId::TextLabel, f, chunks[1]);
view_result = match current_app_state {
AppState::NamespacePicker => {
with_popup(&mut self.app, f, &chunks, view_namespace_picker)
}
AppState::QueuePicker => with_popup(&mut self.app, f, &chunks, view_queue_picker),
AppState::MessagePicker => {
with_popup(&mut self.app, f, &chunks, view_message_picker)
}
AppState::MessageDetails => {
with_popup(&mut self.app, f, &chunks, view_message_details)
}
AppState::Loading => with_popup(&mut self.app, f, &chunks, view_loading),
AppState::HelpScreen => with_popup(&mut self.app, f, &chunks, view_help_screen),
AppState::ThemePicker => view_theme_picker(&mut self.app, f, &chunks),
AppState::ConfigScreen => view_config_screen(&mut self.app, f, &chunks),
AppState::PasswordPopup => view_password_popup(&mut self.app, f),
AppState::AzureDiscovery => {
with_popup(&mut self.app, f, &chunks, view_azure_discovery)
}
};
if !self.app.mounted(&ComponentId::ErrorPopup)
&& !self.app.mounted(&ComponentId::SuccessPopup)
&& !self.app.mounted(&ComponentId::ConfirmationPopup)
&& !self.app.mounted(&ComponentId::NumberInputPopup)
&& !self.app.mounted(&ComponentId::PageSizePopup)
&& !self.app.mounted(&ComponentId::ThemePicker)
&& !self.app.mounted(&ComponentId::AuthPopup)
{
let mut help_bar = HelpBar::new();
help_bar.view_with_active_and_queue_type(
f,
chunks[4],
&active_component,
queue_type.as_ref(),
bulk_mode,
selected_count,
);
}
}) {
log::error!("Terminal draw error: {e:?}");
return Err(AppError::Component(format!(
"Failed to draw to terminal: {e}"
)));
}
if let Err(e) = io::stdout().flush() {
log::error!("Failed to flush stdout: {e:?}");
}
view_result
}
}