1use std::fmt::Debug;
2
3use tokio::sync::mpsc;
4use wiki_api::{
5 languages::Language,
6 page::{LanguageLink, Link, Page},
7 search::{Search, SearchResult},
8 Endpoint,
9};
10
11use crate::components::page::Renderer;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum Action {
15 Quit,
16 Resume,
17 Suspend,
18 RenderTick,
19 Resize(u16, u16),
20
21 ToggleShowLogger,
23 ShowPageLanguageSelection,
24 ShowHelp,
25
26 PopupMessage(String, String),
28 PopupError(String),
30 PopupDialog(String, String, Box<ActionPacket>),
32 PopPopup,
33
34 SwitchContextSearch,
35 SwitchContextPage,
36 SwitchPreviousContext,
37
38 ScrollUp(u16),
40 ScrollDown(u16),
41
42 ScrollToTop,
43 ScrollToBottom,
44
45 ScrollHalfUp,
46 ScrollHalfDown,
47
48 UnselectScroll,
49
50 EnterInsert,
52 EnterNormal,
53 EnterProcessing,
54
55 EnterSearchBar,
57 ClearSearchBar,
58 SubmitSearchBar,
59 ExitSearchBar,
60
61 LoadSearchResult(SearchResult),
63 LoadLink(Link),
64 LoadLangaugeLink(LanguageLink),
65 TryLoadPage(String, Language, Endpoint),
67
68 Search(SearchAction),
69 Page(PageAction),
70 PageViewer(PageViewerAction),
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub enum SearchAction {
75 StartSearch(String),
76 FinshSearch(Search),
77 ContinueSearch,
78 ClearSearchResults,
79 OpenSearchResult,
80 ChangeMode(crate::components::search::Mode),
81 ChangeLanguage(Language),
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub enum PageAction {
86 SwitchRenderer(Renderer),
87 ToggleContents,
88
89 SelectFirstLink,
90 SelectLastLink,
91
92 SelectTopLink,
93 SelectBottomLink,
94
95 SelectPrevLink,
96 SelectNextLink,
97
98 GoToHeader(String),
99}
100
101#[derive(Debug, Clone, PartialEq, Eq)]
102pub enum PageViewerAction {
103 DisplayPage(Page),
104 PopPage,
105 ExitLoading,
106 SaveCache,
107}
108
109pub enum ActionResult {
110 Ignored,
111 Consumed(ActionPacket),
112}
113
114impl ActionResult {
115 pub fn consumed() -> Self {
116 Self::Consumed(ActionPacket::default())
117 }
118
119 pub fn is_consumed(&self) -> bool {
120 matches!(self, ActionResult::Consumed { .. })
121 }
122}
123
124impl From<Action> for ActionResult {
125 fn from(value: Action) -> Self {
126 ActionResult::Consumed(ActionPacket::single(value))
127 }
128}
129
130impl From<ActionPacket> for ActionResult {
131 fn from(value: ActionPacket) -> Self {
132 ActionResult::Consumed(value)
133 }
134}
135
136#[derive(Default, Clone, PartialEq, Eq)]
137pub struct ActionPacket {
138 actions: Vec<Action>,
139}
140
141impl ActionPacket {
142 pub fn single(action: Action) -> Self {
143 Self {
144 actions: vec![action],
145 }
146 }
147
148 pub fn action(mut self, action: Action) -> Self {
149 self.actions.push(action);
150 self
151 }
152
153 pub fn add_action(&mut self, action: Action) {
154 self.actions.push(action);
155 }
156
157 pub fn send(self, action_tx: &mpsc::UnboundedSender<Action>) {
158 for action in self.actions {
159 action_tx.send(action).unwrap();
160 }
161 }
162}
163
164impl From<Action> for ActionPacket {
165 fn from(value: Action) -> Self {
166 ActionPacket::single(value)
167 }
168}
169
170impl Debug for ActionPacket {
171 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172 if self.actions.len() == 1 {
173 return write!(f, "{:?}", self.actions.first().unwrap());
174 } else if self.actions.is_empty() {
175 return write!(f, "Nothing");
176 }
177
178 f.debug_list().entries(self.actions.iter()).finish()
179 }
180}