Krolyxon
Commit 4993431

rmptuisrcbrowser.rs

126 lines · 3.5 KB · Rust

1use std::ffi::OsStr;
2use std::path::Path;
3
4use mpd::Song;
5
6use crate::{app::AppResult, connection::Connection};
7
8#[derive(Debug)]
9pub struct FileBrowser {
10 pub filetree: Vec<(String, String)>,
11 pub selected: usize,
12 pub prev_selected: usize,
13 pub path: String,
14 pub prev_path: String,
15 pub songs: Vec<Song>,
16}
17
18// https://stackoverflow.com/questions/72392835/check-if-a-file-is-of-a-given-type
19pub trait FileExtension {
20 fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool;
21}
22
23impl<P: AsRef<Path>> FileExtension for P {
24 fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool {
25 if let Some(ref extension) = self.as_ref().extension().and_then(OsStr::to_str) {
26 return extensions
27 .iter()
28 .any(|x| x.as_ref().eq_ignore_ascii_case(extension));
29 }
30
31 false
32 }
33}
34
35impl FileBrowser {
36 pub fn new() -> FileBrowser {
37 FileBrowser {
38 filetree: Vec::new(),
39 selected: 0,
40 prev_selected: 0,
41 path: ".".to_string(),
42 prev_path: ".".to_string(),
43 songs: vec![],
44 }
45 }
46
47 pub fn update_directory(&mut self, conn: &mut Connection) -> AppResult<()> {
48 self.filetree.clear();
49 self.filetree = conn
50 .conn
51 .listfiles(self.path.as_str())?
52 .into_iter()
53 .filter(|(f, l)| {
54 f == "directory"
55 || f == "file" && Path::new(l).has_extension(&["mp3", "ogg", "flac", "m4a", "wav", "aac" ,"opus", "ape", "wma", "mpc", "aiff", "dff", "mp2", "mka"])
56 })
57 .collect::<Vec<(String, String)>>();
58
59 self.songs.clear();
60 for (t, song) in self.filetree.iter() {
61 if t == "file" {
62 let v = conn
63 .conn
64 .lsinfo(Song {
65 file: conn
66 .get_full_path(song)
67 .unwrap_or_else(|| "Not a song".to_string()),
68 ..Default::default()
69 })
70 .unwrap_or_else(|_| {
71 vec![Song {
72 file: "Not a song".to_string(),
73 ..Default::default()
74 }]
75 });
76
77 self.songs.push(v.get(0).unwrap().clone());
78 } else {
79 let v = Song {
80 file: "".to_string(),
81 ..Default::default()
82 };
83
84 self.songs.push(v);
85 }
86 }
87
88 Ok(())
89 }
90
91 // Go to next item in filetree
92 pub fn next(&mut self) {
93 // if self.selected < self.filetree.len() - 1 {
94 // self.selected += 1;
95 // }
96
97 if self.selected == self.filetree.len() - 1 {
98 self.selected = 0;
99 } else {
100 self.selected += 1;
101 }
102 }
103
104 /// Go to previous item in filetree
105 pub fn prev(&mut self) {
106 if self.selected == 0 {
107 self.selected = self.filetree.len() - 1;
108 } else {
109 self.selected -= 1;
110 }
111 }
112
113 pub fn handle_go_back(&mut self, conn: &mut Connection) -> AppResult<()> {
114 if self.prev_path != "." {
115 let r = self.path.rfind("/").unwrap();
116 self.path = self.path.as_str()[..r].to_string();
117 self.update_directory(conn)?;
118 } else {
119 self.path = self.prev_path.clone();
120 self.update_directory(conn)?;
121 }
122
123 self.selected = self.prev_selected;
124 Ok(())
125 }
126}