1use crate::i18n::Locale;
9use orbok_models::SearchCapability;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum ViewId {
14 Search,
15 Sources,
16 Indexing,
17 Storage,
18 Models,
19 Settings,
20}
21
22impl ViewId {
23 pub const ALL: &'static [ViewId] = &[
26 ViewId::Search,
27 ViewId::Sources,
28 ViewId::Indexing,
29 ViewId::Storage,
30 ViewId::Models,
31 ViewId::Settings,
32 ];
33}
34
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
37pub struct IndexHealth {
38 pub indexed: u64,
39 pub stale: u64,
40 pub failed: u64,
41 pub queued: u64,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct SourceCard {
48 pub display_name: String,
49 pub display_path: String,
50 pub indexed: u64,
51 pub stale: u64,
52 pub failed: u64,
53 pub active: bool,
54}
55
56#[derive(Debug, Clone)]
58pub struct AppState {
59 pub active_view: ViewId,
60 pub locale: Locale,
61 pub query: String,
62 pub last_query: Option<String>,
63 pub health: IndexHealth,
64 pub sources: Vec<SourceCard>,
65 pub capability: SearchCapability,
66 pub storage_total_bytes: u64,
68}
69
70impl Default for AppState {
71 fn default() -> Self {
72 Self {
73 active_view: ViewId::Search,
74 locale: Locale::default(),
75 query: String::new(),
76 last_query: None,
77 health: IndexHealth::default(),
78 sources: Vec::new(),
79 capability: SearchCapability::KeywordOnly,
80 storage_total_bytes: 0,
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
89pub enum Message {
90 Switch(ViewId),
91 QueryChanged(String),
92 SubmitSearch,
93 SetLocale(Locale),
94}
95
96impl AppState {
97 pub fn update(&mut self, message: &Message) {
101 match message {
102 Message::Switch(view) => self.active_view = *view,
103 Message::QueryChanged(query) => self.query = query.clone(),
104 Message::SubmitSearch => {
105 let trimmed = self.query.trim();
106 if !trimmed.is_empty() {
107 self.last_query = Some(trimmed.to_string());
108 }
109 }
110 Message::SetLocale(locale) => self.locale = *locale,
111 }
112 }
113}