prehnite/app/window/main_window/
mod.rs1mod book_opener;
2mod menubar;
3pub mod page;
4
5use crate::app::window::main_window::book_opener::book_opener_handler;
6use crate::app::window::main_window::menubar::{menubar, menubar_handler, MenuBarMessage};
7use crate::app::window::main_window::page::item_list::{ItemListActions, ItemListMessage};
8use crate::app::window::main_window::page::{MainWindowPage, MainWindowPageId};
9use crate::app::window::{Window, WindowMessage};
10use iced::futures::FutureExt;
11use iced::{window, Element, Task};
12use prehnite_core::db::{open_book_or_alert, DBType};
13use prehnite_core::i18n::i18n_w;
14use prehnite_core::settings::registry::SettingRegistry;
15use prehnite_core::settings::GlobalSettingKey;
16use prehnite_core::util::file_dialog::FileOpe;
17use tracing::error;
18
19impl Into<FileOpe> for BookOpenerMessage {
20 fn into(self) -> FileOpe {
21 match self {
22 BookOpenerMessage::New => FileOpe::New,
23 _ => FileOpe::Open,
24 }
25 }
26}
27
28#[derive(Clone, Debug)]
29pub enum BookOpenerMessage {
30 Open,
31 New,
32 Opened,
33 NotOpened,
34}
35
36#[derive(Clone, Debug)]
37pub enum MainWindowMessage {
38 BookOpener(BookOpenerMessage),
39 ChangePage(MainWindowPageId),
40 ItemList(ItemListMessage),
41 MenuBar(MenuBarMessage),
42 BookOpened,
43 OpenVersionInfoWindow,
44 OpenSettingWindow,
45 OpenLicenseInfoWindow,
46 OpenBackgroundInfoEditorWindow,
47 OpenBibliographyEditorWindow,
48 OpenEditorWindow(i64),
49 OpenNewItemPromptWindow
50}
51
52impl From<MainWindowMessage> for WindowMessage {
53 fn from(value: MainWindowMessage) -> Self {
54 Self::MainWindowMessage(value)
55 }
56}
57
58#[derive(Debug)]
59pub struct MainWindow {
60 page: MainWindowPage,
61 is_book_opened: bool,
62 window_id: Option<window::Id>,
63}
64
65impl MainWindow {
66 #[tracing::instrument]
67 async fn open_last_opened_book() -> MainWindowMessage {
68 let last_opened = SettingRegistry::get(&GlobalSettingKey::LastOpened.into());
69 fn return_err() -> MainWindowMessage {
70 MainWindowMessage::ChangePage(MainWindowPageId::BookNotOpened)
71 }
72 match last_opened
73 .and_then(|v| v.to_opt_string())
74 .and_then(|v| v.parse().ok())
75 {
76 None => return_err(),
77 Some(v) => {
78 if open_book_or_alert(v).await {
79 MainWindowMessage::BookOpened
80 } else {
81 return_err()
82 }
83 }
84 }
85 }
86
87 fn update_impl(&mut self, message: MainWindowMessage) -> Task<MainWindowMessage> {
88 match message {
89 MainWindowMessage::BookOpener(msg) => return book_opener_handler(self, msg),
90 MainWindowMessage::ItemList(msg) => {
91 if let MainWindowPage::ItemList(page) = &mut self.page {
92 return match page.update(msg) {
93 ItemListActions::Run(v) => v.map(MainWindowMessage::ItemList),
94 };
95 }
96 error!("invalid message received.");
97 }
98 MainWindowMessage::ChangePage(page) => {
99 self.page = page.clone().into();
100 match page {
101 MainWindowPageId::ItemList => {
102 return Task::done(MainWindowMessage::ItemList(ItemListMessage::LoadItems));
103 }
104 _ => {}
105 }
106 }
107 MainWindowMessage::MenuBar(v) => return menubar_handler(self, v),
108 MainWindowMessage::BookOpened => {
109 self.is_book_opened = true;
110 return Task::future(async {
111 SettingRegistry::load(DBType::PrehniteBook).await;
112 MainWindowMessage::ChangePage(MainWindowPageId::ItemList)
113 });
114 }
115 MainWindowMessage::OpenVersionInfoWindow => { }
116 MainWindowMessage::OpenSettingWindow => { }
117 MainWindowMessage::OpenLicenseInfoWindow => { }
118 MainWindowMessage::OpenBackgroundInfoEditorWindow => { }
119 MainWindowMessage::OpenBibliographyEditorWindow => { }
120 MainWindowMessage::OpenEditorWindow(_) => { }
121 MainWindowMessage::OpenNewItemPromptWindow => {}
122 }
123 Task::none()
124 }
125
126 fn view_impl(&self) -> Element<'_, MainWindowMessage> {
127 Element::from(iced::widget::column![
128 menubar(self.is_book_opened).map(MainWindowMessage::MenuBar),
129 match &self.page {
130 MainWindowPage::NowLoading => i18n_w("now-loading").into(),
131 MainWindowPage::ItemList(v) => v.view().map(MainWindowMessage::ItemList),
132 }
133 ])
134 }
135}
136
137impl Window for MainWindow {
138 fn new() -> Self {
139 Self {
140 page: Default::default(),
141 is_book_opened: false,
142 window_id: None,
143 }
144 }
145
146 fn init_task() -> Task<WindowMessage> {
147 if SettingRegistry::get(&GlobalSettingKey::AutoOpenLastOpened.into())
148 .and_then(|v| v.get())
149 .unwrap_or(true)
150 {
151 Task::future(Self::open_last_opened_book().map(WindowMessage::MainWindowMessage))
152 } else {
153 Task::done(MainWindowMessage::ChangePage(MainWindowPageId::BookNotOpened).into())
154 }
155 }
156
157 #[tracing::instrument]
158 fn update(&mut self, message: WindowMessage) -> Task<WindowMessage> {
159 if let WindowMessage::MainWindowMessage(message) = message {
160 self.update_impl(message)
161 .map(WindowMessage::MainWindowMessage)
162 } else {
163 error!("Invalid message received.");
164 Task::none()
165 }
166 }
167
168 fn view(&'_ self) -> Element<'_, WindowMessage> {
169 self.view_impl().map(WindowMessage::MainWindowMessage)
170 }
171
172 fn title(&'_ self) -> String {
173 "Prehnite".into()
174 }
175
176 fn set_window_id(&mut self, window_id: window::Id) {
177 self.window_id = Some(window_id);
178 }
179}