fix: workaround for a bug where playing players are somtimes incorrectly reported as paused
This commit is contained in:
1 parent
c074b4279e
commit
d34e842f3e
2 files changed
+136
-97
No files matched your search
+43
-34
@@ -1,57 +1,66 @@
|
||||
//! This file deals with updating the active player.
|
||||
//! This file deals with updating the active player.
|
||||
//! It also updates the prefix, which kind of breaks seperation of concerns, but this saves me a lot of headache so I'm not changing it.
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use log::trace;
|
||||
use mpris::{PlayerFinder, Player};
|
||||
use crate::structs::{data::Data, config::Config};
|
||||
|
||||
use crate::structs::{config::Config, data::Data};
|
||||
use log::{debug, trace};
|
||||
use mpris::PlayerFinder;
|
||||
|
||||
/// This function updates the current prefix.
|
||||
/// If no entry is found in config containing the active player, a default value is used instead ('>').
|
||||
///
|
||||
///
|
||||
/// Input:
|
||||
/// cfg: Config struct for the program, containing the hashmap of prefixes.
|
||||
/// data: mutable char containing the active prefix.
|
||||
/// name: name of active player, to fetch the appropriate prefix from cfg.
|
||||
fn update_prefix(cfg: &Config, data: &mut char, name: &str) {
|
||||
if let Some(char) = cfg.player_prefixes.get(name) {
|
||||
*data = *char;
|
||||
trace!("updated prefix to {}", data);
|
||||
} else {
|
||||
*data = *cfg.player_prefixes.get("default").unwrap_or(&'>');
|
||||
trace!("set prefix to default ({})", data);
|
||||
}
|
||||
if let Some(char) = cfg.player_prefixes.get(name) {
|
||||
*data = *char;
|
||||
trace!("updated prefix to {}", data);
|
||||
} else {
|
||||
*data = *cfg.player_prefixes.get("default").unwrap_or(&'>');
|
||||
trace!("set prefix to default ({})", data);
|
||||
}
|
||||
}
|
||||
|
||||
/// This function updates which player is selected as 'active'.
|
||||
/// It only considers players present in the config.player_priorities field to be valid candidates, then selects the active one with the highest rating.
|
||||
/// If none of the acceptable players are available, current_player is set to None instead.
|
||||
///
|
||||
///
|
||||
/// Input:
|
||||
/// pf: PlayerFinder instance of the program.
|
||||
/// cfg: Config struct of the program, containing the list of acceptable players.
|
||||
/// data: mutable Data struct of the program, containing a marker for the currently active player.
|
||||
pub fn update_players(pf: &PlayerFinder, cfg: &Config, data: &mut Data) {
|
||||
// get all acceptable players
|
||||
let players = pf.find_all().unwrap_or(Vec::new());
|
||||
if players.is_empty() {
|
||||
data.current_player = None;
|
||||
} else {
|
||||
let mut active: BTreeMap<u8, Player> = BTreeMap::new();
|
||||
for player in players {
|
||||
if let Ok(mpris::PlaybackStatus::Playing) = player.get_playback_status() {
|
||||
let idx = cfg.find_player_priorities_idx(player.identity());
|
||||
active.insert(idx, player);
|
||||
}
|
||||
}
|
||||
|
||||
// select the player with the highest priority.
|
||||
if let Some((_, player)) = active.pop_first() {
|
||||
update_prefix(cfg, &mut data.prefix, player.identity());
|
||||
data.current_player = Some(player);
|
||||
// get all acceptable players
|
||||
let players = pf.find_all().unwrap_or(Vec::new());
|
||||
if players.is_empty() {
|
||||
data.current_player = None;
|
||||
debug!("update_players: no players found!")
|
||||
} else {
|
||||
data.current_player = None;
|
||||
let mut trees = vec![BTreeMap::new(), BTreeMap::new(), BTreeMap::new()];
|
||||
for player in players {
|
||||
if let Ok(status) = player.get_playback_status() {
|
||||
let idx = cfg.find_player_priorities_idx(player.identity());
|
||||
match status {
|
||||
mpris::PlaybackStatus::Playing => trees[0].insert(idx, player),
|
||||
mpris::PlaybackStatus::Paused => trees[1].insert(idx, player),
|
||||
mpris::PlaybackStatus::Stopped => trees[2].insert(idx, player),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// select the player with the highest priority.
|
||||
for mut tree in trees {
|
||||
if let Some((_, player)) = tree.pop_first() {
|
||||
update_prefix(cfg, &mut data.prefix, player.identity());
|
||||
debug!("update_players: updated player to {}!", player.identity());
|
||||
data.current_player = Some(player);
|
||||
break;
|
||||
} else {
|
||||
data.current_player = None;
|
||||
debug!("update_players: No acceptable player found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||