Browse Source

Better titles and bugfixes for mpd

We handle the case where no song is playing (reached end of the
playlist), as well as handle songs without actual tags.
Thomas Dy 7 years ago
parent
commit
66f08fdecd
2 changed files with 31 additions and 22 deletions
  1. 1 1
      src/widgets/mod.rs
  2. 30 21
      src/widgets/music.rs

+ 1 - 1
src/widgets/mod.rs

@@ -17,7 +17,7 @@ pub enum Message {
     Quit,
     MousePress(u16),
     BspwmEvent(String),
-    MpdEvent(mpd::status::State, String, String),
+    MpdEvent(mpd::status::State, Option<mpd::song::Song>),
     XcbEvent(xcb::GenericEvent)
 }
 

+ 30 - 21
src/widgets/music.rs

@@ -1,7 +1,9 @@
 use mpd;
+use mpd::song::Song;
 use mpd::status::State;
 use mpd::idle;
 use mpd::idle::Idle;
+use std::path::Path;
 use std::thread;
 use ui::draw_context::DrawContext;
 use widgets::{Message, MessageSender, Widget};
@@ -13,8 +15,7 @@ pub struct Music {
     context: DrawContext,
     tx: MessageSender,
     state: State,
-    artist: String,
-    title: String,
+    song: Option<Song>,
     last_pos: u16
 }
 
@@ -23,8 +24,7 @@ pub fn mpd(tx: MessageSender, context: DrawContext) -> Music {
         context: context,
         tx: tx,
         state: State::Stop,
-        artist: "".to_string(),
-        title: "".to_string(),
+        song: None,
         last_pos: 0
     }
 }
@@ -38,6 +38,21 @@ impl Music {
         }
     }
 
+    fn get_text(&self) -> String {
+        match self.song {
+            Some(ref song) => match (&song.title, &song.tags.get("Artist")) {
+                (&Some(ref title), &Some(ref artist)) => format!("{} - {}", title, artist),
+                (&Some(ref title), &None) => title.to_string(),
+                _ => {
+                    let path = Path::new(&song.file);
+                    let path = path.file_name().and_then(|s| s.to_str());
+                    path.unwrap_or("Unknown").to_string()
+                }
+            },
+            None => "mpd".to_string()
+        }
+    }
+
     fn redraw(&mut self) {
         let x = self.last_pos;
         self.context.set_bg_color(0x0, 0x0, 0x0, 0xFFFF);
@@ -62,13 +77,7 @@ impl Widget for Music {
         self.context.draw_bg(x, icon_width + MARGIN * 2);
         self.context.draw_text(self.icon(), x + MARGIN);
 
-
-        let text = if self.state == State::Stop {
-            "Stopped".to_string()
-        }
-        else {
-            format!("{} - {}", self.artist, self.title)
-        };
+        let text = self.get_text();
         let text_width = WIDTH - MARGIN * 4 - icon_width;
         self.context.set_bg_color(0x0, 0x0, 0x0, 0xFFFF);
         self.context.draw_bg(x + icon_width + MARGIN * 3, text_width);
@@ -81,10 +90,9 @@ impl Widget for Music {
 
     fn handle_event(&mut self, event: &Message) -> bool {
         match event {
-            &Message::MpdEvent(ref state, ref artist, ref title) => {
+            &Message::MpdEvent(ref state, ref song) => {
                 self.state = state.clone();
-                self.artist = artist.clone();
-                self.title = title.clone();
+                self.song = song.clone();
                 self.redraw();
             },
             &Message::MousePress(_x) => {
@@ -99,13 +107,14 @@ impl Widget for Music {
 fn monitor_thread(tx: MessageSender) {
     let mut conn = mpd::client::Client::connect("127.0.0.1:6600").unwrap();
     loop {
-        let unknown = "Unknown".to_string();
-        let state = conn.status().unwrap().state;
-        let song = conn.currentsong().unwrap().unwrap();
-        let artist = song.tags.get("Artist").unwrap_or(&unknown);
-        let title = song.title.as_ref().unwrap_or(&unknown);
-
-        tx.send(Message::MpdEvent(state, artist.clone(), title.clone())).expect("Failed to send mpd event");
+        match (conn.status(), conn.currentsong()) {
+            (Ok(status), Ok(song)) => {
+                let state = status.state;
+                let event = Message::MpdEvent(state, song);
+                tx.send(event).expect("Failed to send mpd event");
+            },
+            _ => {}
+        }
         conn.wait(&[idle::Subsystem::Player]).ok();
     }
 }