Skip to main content

wiki_tui/
action.rs

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    // View Focus
22    ToggleShowLogger,
23    ShowPageLanguageSelection,
24    ShowHelp,
25
26    /// PopupMessage(Title, Content)
27    PopupMessage(String, String),
28    /// PopupError(Error)
29    PopupError(String),
30    /// PopupError(Title, Content, Callback)
31    PopupDialog(String, String, Box<ActionPacket>),
32    PopPopup,
33
34    SwitchContextSearch,
35    SwitchContextPage,
36    SwitchPreviousContext,
37
38    // Scrolling
39    ScrollUp(u16),
40    ScrollDown(u16),
41
42    ScrollToTop,
43    ScrollToBottom,
44
45    ScrollHalfUp,
46    ScrollHalfDown,
47
48    UnselectScroll,
49
50    // Mode
51    EnterInsert,
52    EnterNormal,
53    EnterProcessing,
54
55    // Search Bar
56    EnterSearchBar,
57    ClearSearchBar,
58    SubmitSearchBar,
59    ExitSearchBar,
60
61    // Page loading
62    LoadSearchResult(SearchResult),
63    LoadLink(Link),
64    LoadLangaugeLink(LanguageLink),
65    /// Try to load a page, checking cache first
66    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}