Krolyxon
Commit 9dceacc

rmptuisrchandler.rs

351 lines · 11.8 KB · Rust

1use std::time::Duration;
2
3use crate::{
4 app::{App, AppResult, SelectedTab},
5 ui::InputMode,
6};
7use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
8use rust_fuzzy_search::{self, fuzzy_search_sorted};
9
10pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
11 if app.inputmode == InputMode::Editing {
12 // Live search update
13 match app.selected_tab {
14 SelectedTab::DirectoryBrowser => {
15 let list: Vec<&str> = app
16 .browser
17 .filetree
18 .iter()
19 .map(|(_, f)| f.as_str())
20 .collect::<Vec<&str>>();
21
22 let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
23 let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
24
25 for (i, (_, item)) in app.browser.filetree.iter().enumerate() {
26 if item.contains(res.get(0).unwrap()) {
27 app.browser.selected = i;
28 }
29 }
30 }
31
32 SelectedTab::Queue => {
33 let list: Vec<&str> = app
34 .queue_list
35 .list
36 .iter()
37 .map(|f| f.as_str())
38 .collect::<Vec<&str>>();
39 let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
40 let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
41
42 for (i, item) in app.queue_list.list.iter().enumerate() {
43 if item.contains(res.get(0).unwrap()) {
44 app.queue_list.index = i;
45 }
46 }
47 }
48
49 SelectedTab::Playlists => {
50 let list: Vec<&str> = app
51 .pl_list
52 .list
53 .iter()
54 .map(|f| f.as_str())
55 .collect::<Vec<&str>>();
56 let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
57 let res = res.iter().map(|(x, _)| *x).collect::<Vec<&str>>();
58
59 for (i, item) in app.pl_list.list.iter().enumerate() {
60 if item.contains(res.get(0).unwrap()) {
61 app.pl_list.index = i;
62 }
63 }
64 }
65 }
66
67 match key_event.code {
68 KeyCode::Esc => {
69 app.inputmode = InputMode::Normal;
70 }
71 KeyCode::Char(to_insert) => {
72 app.enter_char(to_insert);
73 }
74 KeyCode::Enter => {
75 let list: Vec<&str> = app
76 .browser
77 .filetree
78 .iter()
79 .map(|(_, f)| f.as_str())
80 .collect::<Vec<&str>>();
81
82 let res: Vec<(&str, f32)> = fuzzy_search_sorted(&app.search_input, &list);
83 let (res, _) = res.get(0).unwrap();
84
85 for (i, (_, item)) in app.browser.filetree.iter().enumerate() {
86 if item.contains(res) {
87 app.browser.selected = i;
88 }
89 }
90
91 app.search_input.clear();
92 app.inputmode = InputMode::Normal;
93 app.reset_cursor();
94 }
95
96 KeyCode::Backspace => {
97 app.delete_char();
98 }
99
100 KeyCode::Left => {
101 app.move_cursor_left();
102 }
103
104 KeyCode::Right => {
105 app.move_cursor_right();
106 }
107
108 _ => {}
109 }
110 } else if app.playlist_popup {
111 match key_event.code {
112 KeyCode::Char('q') | KeyCode::Esc => {
113 app.playlist_popup = false;
114 }
115
116 KeyCode::Char('j') | KeyCode::Down => app.append_list.next(),
117 KeyCode::Char('k') | KeyCode::Up => app.append_list.prev(),
118
119 KeyCode::Enter => {
120 let pl_index = app.append_list.index;
121 let pl_name = app.append_list.list.get(pl_index).unwrap();
122
123 let s_index: usize;
124 let mut short_path: String = String::new();
125 match app.selected_tab {
126 SelectedTab::Queue => {
127 s_index = app.queue_list.index;
128 short_path = app.queue_list.list.get(s_index).unwrap().to_string();
129 }
130
131 SelectedTab::DirectoryBrowser => {
132 let (t, f) = app.browser.filetree.get(app.browser.selected).unwrap();
133 if t == "file" {
134 short_path = f.to_string();
135 }
136 }
137 _ => {}
138 }
139
140 let full_path = app.conn.get_full_path(&short_path)?;
141 let song = app.conn.get_song_with_only_filename(&full_path);
142
143 if pl_name == "Current Playlist" {
144 app.conn.conn.push(&song)?;
145 app.update_queue();
146 } else {
147 app.conn.add_to_playlist(pl_name, &song)?;
148 }
149
150 // hide the playlist popup
151 app.playlist_popup = false;
152 app.append_list.index = 0;
153 }
154 _ => {}
155 }
156 } else {
157 match key_event.code {
158 // Quit
159 KeyCode::Char('q') | KeyCode::Esc => app.quit(),
160 KeyCode::Char('c') | KeyCode::Char('C') => {
161 if key_event.modifiers == KeyModifiers::CONTROL {
162 app.quit();
163 } else {
164 app.conn.conn.clear()?;
165 app.conn.update_status();
166 app.queue_list.list.clear();
167 app.queue_list.reset_index();
168 }
169 }
170
171 // Go Up
172 KeyCode::Char('j') | KeyCode::Down => match app.selected_tab {
173 SelectedTab::DirectoryBrowser => app.browser.next(),
174 SelectedTab::Queue => app.queue_list.next(),
175 SelectedTab::Playlists => app.pl_list.next(),
176 },
177
178 // Go down
179 KeyCode::Char('k') | KeyCode::Up => match app.selected_tab {
180 SelectedTab::DirectoryBrowser => app.browser.prev(),
181 SelectedTab::Queue => app.queue_list.prev(),
182 SelectedTab::Playlists => app.pl_list.prev(),
183 },
184
185 // Next directory
186 KeyCode::Enter | KeyCode::Char('l') => {
187 // app.update_queue();
188
189 match app.selected_tab {
190 SelectedTab::DirectoryBrowser => {
191 app.handle_enter()?;
192 }
193
194 SelectedTab::Queue => {
195 app.conn.conn.switch(app.queue_list.index as u32)?;
196 }
197
198 SelectedTab::Playlists => {
199 app.conn
200 .load_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?;
201 }
202 }
203 app.conn.update_status();
204 }
205
206 // head back to previous directory
207 KeyCode::Char('h') => match app.selected_tab {
208 SelectedTab::DirectoryBrowser => {
209 app.browser.handle_go_back(&mut app.conn)?;
210 }
211 SelectedTab::Queue => {}
212 SelectedTab::Playlists => {}
213 },
214
215 // Playback controls
216 // Toggle Pause
217 KeyCode::Char('p') => app.conn.toggle_pause(),
218
219 // Pause
220 KeyCode::Char('s') => app.conn.pause(),
221
222 // Toggle rpeat
223 KeyCode::Char('r') => {
224 app.conn.toggle_repeat();
225 app.conn.update_status();
226 }
227
228 // Toggle random
229 KeyCode::Char('z') => {
230 app.conn.toggle_random();
231 app.conn.update_status();
232 }
233
234 // Dmenu prompt
235 KeyCode::Char('D') => app.conn.play_dmenu()?,
236
237 // add to queue
238 KeyCode::Char('a') => app.playlist_popup = true,
239
240 KeyCode::Right => {
241 app.conn
242 .load_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?;
243 }
244
245 // Fast forward
246 KeyCode::Char('f') => {
247 let place = app.conn.conn.status().unwrap().song.unwrap().pos;
248 let (pos, _) = app.conn.conn.status().unwrap().time.unwrap();
249 let pos = Duration::from_secs(pos.as_secs().wrapping_add(2));
250 app.conn.conn.seek(place, pos)?;
251 }
252
253 // backward
254 KeyCode::Char('b') => {
255 let place = app.conn.conn.status().unwrap().song.unwrap().pos;
256 let (pos, _) = app.conn.conn.status().unwrap().time.unwrap();
257 let pos = Duration::from_secs(pos.as_secs().wrapping_add(2));
258 app.conn.conn.seek(place, pos)?;
259 }
260
261 // Cycle through tabs
262 KeyCode::Tab => {
263 app.cycle_tabls();
264 }
265
266 // Directory browser tab
267 KeyCode::Char('1') => {
268 app.selected_tab = SelectedTab::DirectoryBrowser;
269 }
270
271 // Playing queue tab
272 KeyCode::Char('2') => {
273 app.selected_tab = SelectedTab::Queue;
274 }
275
276 // Playlists tab
277 KeyCode::Char('3') => {
278 app.selected_tab = SelectedTab::Playlists;
279 }
280
281 // Play next song
282 KeyCode::Char('>') => {
283 app.conn.conn.next()?;
284 }
285
286 // Play previous song
287 KeyCode::Char('<') => {
288 app.conn.conn.prev()?;
289 }
290
291 // Volume controls
292 KeyCode::Char('=') => {
293 app.conn.inc_volume(2);
294 app.conn.update_status();
295 }
296
297 KeyCode::Char('-') => {
298 app.conn.dec_volume(2);
299 app.conn.update_status();
300 }
301
302 // Delete highlighted song from the queue
303 KeyCode::Char('d') => {
304 if app.queue_list.index >= app.queue_list.list.len() - 1 {
305 if app.queue_list.index != 0 {
306 app.queue_list.index -= 1;
307 }
308 }
309
310 app.conn.conn.delete(app.queue_list.index as u32)?;
311 app.update_queue();
312 }
313
314 // Update MPD database
315 KeyCode::Char('U') => {
316 app.conn.conn.update()?;
317 }
318
319 // Search for songs
320 KeyCode::Char('/') => {
321 app.inputmode = InputMode::toggle_editing_states(&app.inputmode);
322 }
323
324 // Remove from Current Playlsit
325 KeyCode::Char(' ') | KeyCode::Backspace => {
326 app.handle_remove_or_from_current_playlist()?;
327 }
328
329 // Change playlist name
330 KeyCode::Char('e') => if app.selected_tab == SelectedTab::Playlists {},
331
332 // go to top of list
333 KeyCode::Char('g') => match app.selected_tab {
334 SelectedTab::Queue => app.queue_list.index = 0,
335 SelectedTab::DirectoryBrowser => app.browser.selected = 0,
336 SelectedTab::Playlists => app.pl_list.index = 0,
337 },
338
339 // go to bottom of list
340 KeyCode::Char('G') => match app.selected_tab {
341 SelectedTab::Queue => app.queue_list.index = app.queue_list.list.len() - 1,
342 SelectedTab::DirectoryBrowser => {
343 app.browser.selected = app.browser.filetree.len() - 1
344 }
345 SelectedTab::Playlists => app.pl_list.index = app.pl_list.list.len() - 1,
346 },
347 _ => {}
348 }
349 }
350 Ok(())
351}