feat(gui): add GuiViewState three-panel split view model (GH-29) #58
No files matched your search
@@ -2,16 +2,19 @@
|
||||
|
||||
mod ipc;
|
||||
mod sandbox;
|
||||
mod view;
|
||||
|
||||
use ipc::IpcBridge;
|
||||
use nuncio_core::EventBus;
|
||||
use view::GuiViewState;
|
||||
|
||||
fn main() {
|
||||
let bus = EventBus::new();
|
||||
let state = IpcBridge::get_app_state(&bus);
|
||||
let view_state = GuiViewState::default();
|
||||
|
||||
println!(
|
||||
"Nuncio GUI Desktop Shell Initialized: status={:?}, unread={}",
|
||||
state.status, state.unread_count
|
||||
"Nuncio GUI Desktop Shell Initialized: status={:?}, unread={}, active_folder={}",
|
||||
state.status, state.unread_count, view_state.active_folder_id
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//! React/Vite Webview component layout model and state bindings.
|
||||
|
||||
use nuncio_core::model::{Email, Folder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Frontend split-view layout state container.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct GuiViewState {
|
||||
/// Available folders list.
|
||||
pub folders: Vec<Folder>,
|
||||
/// Active selected folder ID.
|
||||
pub active_folder_id: String,
|
||||
/// Loaded email message list.
|
||||
pub messages: Vec<Email>,
|
||||
/// Currently selected email ID for reading preview.
|
||||
pub selected_message_id: Option<String>,
|
||||
/// Dark mode UI theme preference flag.
|
||||
pub dark_mode: bool,
|
||||
}
|
||||
|
||||
impl GuiViewState {
|
||||
/// Create a new default GUI view state.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
folders: vec![
|
||||
Folder {
|
||||
id: "inbox".to_string(),
|
||||
name: "Inbox".to_string(),
|
||||
total_messages: 5,
|
||||
unread_messages: 2,
|
||||
},
|
||||
Folder {
|
||||
id: "sent".to_string(),
|
||||
name: "Sent".to_string(),
|
||||
total_messages: 3,
|
||||
unread_messages: 0,
|
||||
},
|
||||
],
|
||||
active_folder_id: "inbox".to_string(),
|
||||
messages: Vec::new(),
|
||||
selected_message_id: None,
|
||||
dark_mode: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Select active folder.
|
||||
pub fn select_folder(&mut self, folder_id: &str) {
|
||||
self.active_folder_id = folder_id.to_string();
|
||||
self.selected_message_id = None;
|
||||
}
|
||||
|
||||
/// Select active message preview.
|
||||
pub fn select_message(&mut self, message_id: &str) {
|
||||
self.selected_message_id = Some(message_id.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GuiViewState {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn gui_view_state_navigation() {
|
||||
let mut state = GuiViewState::default();
|
||||
|
||||
assert_eq!(state.active_folder_id, "inbox");
|
||||
assert!(state.dark_mode);
|
||||
|
||||
state.select_folder("sent");
|
||||
assert_eq!(state.active_folder_id, "sent");
|
||||
assert!(state.selected_message_id.is_none());
|
||||
|
||||
state.select_message("msg-101");
|
||||
assert_eq!(state.selected_message_id, Some("msg-101".to_string()));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user