mod config; use crate::clients::music::{self, MusicClient, PlayerState, PlayerUpdate, Status, Track}; use crate::modules::{Module, ModuleInfo, ModuleUpdateEvent, ModuleWidget, WidgetContext}; use crate::popup::Popup; use crate::{send_async, try_send}; use color_eyre::Result; use glib::Continue; use gtk::gdk_pixbuf::Pixbuf; use gtk::prelude::*; use gtk::{Button, Image, Label, Orientation, Scale}; use regex::Regex; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; use tokio::spawn; use tokio::sync::mpsc::{Receiver, Sender}; use tracing::error; pub use self::config::MusicModule; use self::config::{Icons, PlayerType}; #[derive(Debug)] pub enum PlayerCommand { Previous, Play, Pause, Next, Volume(u8), } /// Formats a duration given in seconds /// in hh:mm format fn format_time(duration: Duration) -> String { let time = duration.as_secs(); let minutes = (time / 60) % 60; let seconds = time % 60; format!("{minutes:0>2}:{seconds:0>2}") } /// Extracts the formatting tokens from a formatting string fn get_tokens(re: &Regex, format_string: &str) -> Vec { re.captures_iter(format_string) .map(|caps| caps[1].to_string()) .collect::>() } #[derive(Clone, Debug)] pub struct SongUpdate { song: Track, status: Status, display_string: String, } async fn get_client( player_type: PlayerType, host: &str, music_dir: PathBuf, ) -> Box> { match player_type { PlayerType::Mpd => music::get_client(music::ClientType::Mpd { host, music_dir }), PlayerType::Mpris => music::get_client(music::ClientType::Mpris {}), } .await } impl Module