1use crate::i18n::{MessageKey, tr};
5use crate::state::{AppState, Message, ViewId};
6use crate::views;
7use iced::Element;
8use lucide_icons::Icon as LucideIcon;
9use snora::{AppLayout, Icon, LayoutDirection, SideBar, SideBarItem, render, widget::app_side_bar};
10
11
12#[derive(Default)]
14pub struct OrbokApp {
15 pub state: AppState,
16}
17
18impl OrbokApp {
19 pub fn with_state(state: AppState) -> Self {
20 Self { state }
21 }
22
23 pub fn update(&mut self, message: Message) {
26 self.state.update(&message);
27 }
28
29 pub fn view(&self) -> Element<'_, Message> {
32 let locale = self.state.locale;
33 let icon_for = |view: ViewId| -> Icon {
34 match view {
35 ViewId::Search => Icon::Lucide(LucideIcon::Search),
36 ViewId::Sources => Icon::Lucide(LucideIcon::FolderOpen),
37 ViewId::Indexing => Icon::Lucide(LucideIcon::ListOrdered),
38 ViewId::Storage => Icon::Lucide(LucideIcon::Database),
39 ViewId::Models => Icon::Lucide(LucideIcon::Cpu),
40 ViewId::Settings => Icon::Lucide(LucideIcon::Settings),
41 }
42 };
43 let tooltip_for = |view: ViewId| -> &'static str {
44 match view {
45 ViewId::Search => tr(locale, MessageKey::NavSearch),
46 ViewId::Sources => tr(locale, MessageKey::NavSources),
47 ViewId::Indexing => tr(locale, MessageKey::NavIndexing),
48 ViewId::Storage => tr(locale, MessageKey::NavStorage),
49 ViewId::Models => tr(locale, MessageKey::NavModels),
50 ViewId::Settings => tr(locale, MessageKey::NavSettings),
51 }
52 };
53 let items = ViewId::ALL
54 .iter()
55 .map(|view| SideBarItem {
56 view_id: *view,
57 icon: icon_for(*view),
58 tooltip: tooltip_for(*view).into(),
59 on_press: Message::Switch(*view),
60 })
61 .collect();
62 let side_bar = app_side_bar(
63 SideBar {
64 items,
65 active: self.state.active_view,
66 },
67 LayoutDirection::Ltr,
68 );
69
70 if self.state.wizard.is_some() {
72 return views::wizard_view(&self.state);
73 }
74
75 let body = match self.state.active_view {
76 ViewId::Search => views::search_view(&self.state),
77 ViewId::Sources => views::sources_view(&self.state),
78 ViewId::Indexing => views::indexing_view(&self.state),
79 ViewId::Storage => views::storage_view(&self.state),
80 ViewId::Models => views::models_view(&self.state),
81 ViewId::Settings => views::settings_view(&self.state),
82 };
83
84 render(AppLayout::new(body).side_bar(side_bar))
85 }
86
87 pub fn title(&self) -> String {
89 tr(self.state.locale, MessageKey::AppTitle).to_string()
90 }
91}