1use crate::i18n::Locale;
9use orbok_models::SearchCapability;
10use orbok_search::SearchMode;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ViewId {
15 Search,
16 Sources,
17 Indexing,
18 Storage,
19 Models,
20 Settings,
21}
22
23impl ViewId {
24 pub const ALL: &'static [ViewId] = &[
25 ViewId::Search,
26 ViewId::Sources,
27 ViewId::Indexing,
28 ViewId::Storage,
29 ViewId::Models,
30 ViewId::Settings,
31 ];
32}
33
34#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
36pub struct IndexHealth {
37 pub indexed: u64,
38 pub stale: u64,
39 pub failed: u64,
40 pub queued: u64,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct SourceCard {
46 pub display_name: String,
47 pub display_path: String,
48 pub indexed: u64,
49 pub stale: u64,
50 pub failed: u64,
51 pub active: bool,
52}
53
54#[derive(Debug, Clone, PartialEq)]
57pub struct SearchResultDisplay {
58 pub display_path: String,
59 pub title: Option<String>,
60 pub heading_path: Option<String>,
61 pub snippet: Option<String>,
62 pub keyword_rank: u32,
63 pub badges: Vec<String>,
64}
65
66#[derive(Debug, Clone)]
68pub struct AppState {
69 pub active_view: ViewId,
70 pub locale: Locale,
71 pub query: String,
72 pub last_query: Option<String>,
73 pub search_mode: SearchMode,
74 pub search_results: Vec<SearchResultDisplay>,
75 pub search_running: bool,
76 pub health: IndexHealth,
77 pub sources: Vec<SourceCard>,
78 pub capability: SearchCapability,
79 pub storage_total_bytes: u64,
80}
81
82impl Default for AppState {
83 fn default() -> Self {
84 Self {
85 active_view: ViewId::Search,
86 locale: Locale::default(),
87 query: String::new(),
88 last_query: None,
89 search_mode: SearchMode::Auto,
90 search_results: Vec::new(),
91 search_running: false,
92 health: IndexHealth::default(),
93 sources: Vec::new(),
94 capability: SearchCapability::KeywordOnly,
95 storage_total_bytes: 0,
96 }
97 }
98}
99
100#[derive(Debug, Clone)]
102pub enum Message {
103 Switch(ViewId),
104 QueryChanged(String),
105 SubmitSearch,
106 SearchResultsReady(Vec<SearchResultDisplay>),
107 SearchError(String),
108 SetSearchMode(SearchMode),
109 SetLocale(Locale),
110}
111
112impl AppState {
113 pub fn update(&mut self, message: &Message) {
114 match message {
115 Message::Switch(view) => self.active_view = *view,
116 Message::QueryChanged(query) => self.query = query.clone(),
117 Message::SubmitSearch => {
118 let trimmed = self.query.trim();
119 if !trimmed.is_empty() {
120 self.last_query = Some(trimmed.to_string());
121 self.search_running = true;
122 self.search_results.clear();
123 }
124 }
125 Message::SearchResultsReady(results) => {
126 self.search_results = results.clone();
127 self.search_running = false;
128 }
129 Message::SearchError(_) => {
130 self.search_running = false;
131 }
132 Message::SetSearchMode(mode) => self.search_mode = *mode,
133 Message::SetLocale(locale) => self.locale = *locale,
134 }
135 }
136}