diff --git a/client/src/components/handlers/buffer_list.rs b/client/src/components/handlers/buffer_list.rs index 6df0c40..75aa040 100644 --- a/client/src/components/handlers/buffer_list.rs +++ b/client/src/components/handlers/buffer_list.rs @@ -2,7 +2,8 @@ use crate::config::colors::themes::Theme; use crate::state::app::state::AppState; -use ratatui::{ +use crate::state::app::buffer::{BufferState, AppView}; +use ratatui::buffer::{ layout::{Alignment, Rect}, style::{Style, Stylize}, text::{Line, Span}, @@ -15,7 +16,7 @@ pub fn render_buffer_list( f: &mut Frame, area: Rect, theme: &Theme, - app_state: &AppState, + buffer_state: &BufferState, ) { // --- Style Definitions --- let active_style = Style::default() @@ -28,11 +29,10 @@ pub fn render_buffer_list( // --- Create Spans --- let mut spans = Vec::new(); - let history = &app_state.ui.buffer_history; let mut current_width = 0; - for (i, view) in history.iter().enumerate() { - let is_active = i == app_state.ui.active_buffer_index; + for (i, view) in buffer_state.history.iter().enumerate() { + let is_active = i == buffer_state.active_index; let buffer_name = view.display_name(); let buffer_text = format!(" {} ", buffer_name); let text_width = UnicodeWidthStr::width(buffer_text.as_str()); diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index a2917a8..89ce2de 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -13,6 +13,7 @@ use crate::state::pages::auth::RegisterState; use crate::state::pages::intro::IntroState; use crate::state::pages::admin::AdminState; use crate::state::app::state::AppState; +use crate::state::app::buffer::{AppView, BufferState}; use crate::state::pages::canvas_state::CanvasState; use crate::ui::handlers::rat_state::UiStateHandler; use crate::ui::handlers::context::UiContext; @@ -94,7 +95,7 @@ impl EventHandler { } else { AppView::Scratch } }; - app_state.ui.update_buffer_history(current_view); + buffer_state.update_history(current_view); // --- DIALOG MODALITY --- if app_state.ui.dialog.dialog_show { diff --git a/client/src/state/app.rs b/client/src/state/app.rs index 2551055..bf37c84 100644 --- a/client/src/state/app.rs +++ b/client/src/state/app.rs @@ -1,3 +1,4 @@ // src/state/app.rs pub mod state; +pub mod buffer; diff --git a/client/src/state/app/buffer.rs b/client/src/state/app/buffer.rs new file mode 100644 index 0000000..4ff59c6 --- /dev/null +++ b/client/src/state/app/buffer.rs @@ -0,0 +1,67 @@ +// src/state/app/buffer.rs + +/// Represents the distinct views or "buffers" the user can navigate. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum AppView { + Intro, + Login, + Register, + Admin, + Form(String), + Scratch, +} + +impl AppView { + /// Returns the display name for the view. + pub fn display_name(&self) -> &str { + match self { + AppView::Intro => "Intro", + AppView::Login => "Login", + AppView::Register => "Register", + AppView::Admin => "Admin Panel", + AppView::Form(name) => name.as_str(), + AppView::Scratch => "*scratch*", + } + } +} + +/// Holds the state related to buffer management (navigation history). +#[derive(Debug, Clone)] +pub struct BufferState { + pub history: Vec, + pub active_index: usize, +} + +impl Default for BufferState { + fn default() -> Self { + Self { + history: vec![AppView::Intro], // Start with Intro view + active_index: 0, + } + } +} + +impl BufferState { + /// Updates the buffer history and active index. + /// If the view already exists, it sets it as active. + /// Otherwise, it adds the new view and makes it active. + pub fn update_history(&mut self, view: AppView) { + let existing_pos = self.history.iter().position(|v| v == &view); + + match existing_pos { + Some(pos) => { + self.active_index = pos; + } + None => { + self.history.push(view.clone()); + self.active_index = self.history.len() - 1; + } + } + } + + /// Gets the currently active view. + pub fn get_active_view(&self) -> Option<&AppView> { + self.history.get(self.active_index) + } +} + diff --git a/client/src/state/app/state.rs b/client/src/state/app/state.rs index a81d2e1..cf27ea6 100644 --- a/client/src/state/app/state.rs +++ b/client/src/state/app/state.rs @@ -2,34 +2,10 @@ use std::env; use common::proto::multieko2::table_definition::ProfileTreeResponse; +use crate::state::app::buffer::BufferState; use crate::modes::handlers::mode_manager::AppMode; use crate::ui::handlers::context::DialogPurpose; -/// Represents the distinct views or "buffers" the user can navigate. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum AppView { - Intro, - Login, - Register, - Admin, - Form(String), - Scratch, -} - -impl AppView { - /// Returns the display name for the view. - pub fn display_name(&self) -> &str { - match self { - AppView::Intro => "Intro", - AppView::Login => "Login", - AppView::Register => "Register", - AppView::Admin => "Admin Panel", - AppView::Form(name) => name.as_str(), - AppView::Scratch => "*scratch*", - } - } -} - pub struct DialogState { pub dialog_show: bool, pub dialog_title: String, @@ -48,8 +24,6 @@ pub struct UiState { pub show_login: bool, pub show_register: bool, pub focus_outside_canvas: bool, - pub buffer_history: Vec, - pub active_buffer_index: usize, pub dialog: DialogState, } @@ -166,8 +140,6 @@ impl Default for UiState { show_register: false, show_buffer_list: false, focus_outside_canvas: false, - buffer_history: vec![AppView::Intro], - active_buffer_index: 0, dialog: DialogState::default(), } } @@ -186,20 +158,3 @@ impl Default for DialogState { } } } - -impl UiState { - /// Updates the buffer history and active index. - pub fn update_buffer_history(&mut self, view: AppView) { - let existing_pos = self.buffer_history.iter().position(|v| v == &view); - - match existing_pos { - Some(pos) => { - self.active_buffer_index = pos; - } - None => { - self.buffer_history.push(view.clone()); - self.active_buffer_index = self.buffer_history.len() - 1; - } - } - } -} diff --git a/client/src/ui/handlers/render.rs b/client/src/ui/handlers/render.rs index 3379832..15fcd0c 100644 --- a/client/src/ui/handlers/render.rs +++ b/client/src/ui/handlers/render.rs @@ -18,6 +18,7 @@ use crate::state::pages::auth::AuthState; use crate::state::pages::auth::LoginState; use crate::state::pages::auth::RegisterState; use crate::state::pages::intro::IntroState; +use crate::state::app::buffer::BufferState; use crate::state::app::state::AppState; use crate::state::pages::admin::AdminState; @@ -29,6 +30,7 @@ pub fn render_ui( register_state: &RegisterState, intro_state: &IntroState, admin_state: &mut AdminState, + buffer_state: &BufferState, theme: &Theme, is_edit_mode: bool, total_count: u64, @@ -170,7 +172,7 @@ pub fn render_ui( // Render buffer list if enabled and area is available if let Some(area) = buffer_list_area { if app_state.ui.show_buffer_list { - render_buffer_list(f, area, theme, app_state); + render_buffer_list(f, area, theme, buffer_state); } } render_status_line(f, status_line_area, current_dir, theme, is_edit_mode); diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index f607976..0eafdd6 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -2,11 +2,11 @@ use crate::config::binds::config::Config; use crate::config::colors::themes::Theme; -use crate::modes::common::commands::CommandHandler; -use crate::modes::handlers::event::{EventHandler, EventOutcome}; // Import EventOutcome -use crate::modes::handlers::mode_manager::{AppMode, ModeManager}; use crate::services::grpc_client::GrpcClient; use crate::services::ui_service::UiService; +use crate::modes::common::commands::CommandHandler; +use crate::modes::handlers::event::{EventHandler, EventOutcome}; +use crate::modes::handlers::mode_manager::{AppMode, ModeManager}; use crate::state::pages::canvas_state::CanvasState; use crate::state::pages::form::FormState; use crate::state::pages::auth::AuthState; @@ -14,6 +14,7 @@ use crate::state::pages::auth::LoginState; use crate::state::pages::auth::RegisterState; use crate::state::pages::admin::AdminState; use crate::state::pages::intro::IntroState; +use crate::state::app::buffer::BufferState; use crate::state::app::state::AppState; // Import SaveOutcome use crate::tui::terminal::{EventReader, TerminalCore}; @@ -35,6 +36,7 @@ pub async fn run_ui() -> Result<(), Box> { let mut register_state = RegisterState::default(); let mut intro_state = IntroState::default(); let mut admin_state = AdminState::default(); + let mut buffer_state = BufferState::default(); let mut app_state = AppState::new()?; // Initialize app state with profile tree and table structure @@ -60,6 +62,7 @@ pub async fn run_ui() -> Result<(), Box> { &login_state, ®ister_state, &intro_state, + &buffer_state, &mut admin_state, &theme, is_edit_mode, @@ -121,6 +124,7 @@ pub async fn run_ui() -> Result<(), Box> { &mut login_state, &mut register_state, &mut intro_state, + &mut buffer_state, &mut admin_state, &mut app_state, total_count,