fix: workaround for a bug where playing players are somtimes incorrectly reported as paused

This commit is contained in:
Djairo Hougee 2024-04-22 17:18:48 +02:00
parent c074b4279e
commit d34e842f3e
2 changed files with 136 additions and 97 deletions

View File

@ -29,15 +29,20 @@ fn value_to_string(v: &MetadataValue, sep: char) -> String {
MetadataValue::F64(v) => v.to_string(),
MetadataValue::Bool(v) => v.to_string(),
MetadataValue::Array(v) => {
let mut out = v.iter().map( |val| {
let mut out = v
.iter()
.map(|val| {
let mut str = value_to_string(val, sep);
str.push(sep);
str
}).collect::<String>();
})
.collect::<String>();
out.pop();
out
},
MetadataValue::Map(_v) => panic!("unimplemented! TBH i have no clue when a metadataValue would even return this?"),
}
MetadataValue::Map(_v) => {
panic!("unimplemented! TBH i have no clue when a metadataValue would even return this?")
}
MetadataValue::Unsupported => panic!("Unsupported Metadata type detected!"),
}
}
@ -57,19 +62,23 @@ fn rating_to_string(r: Option<&MetadataValue>, str: &Vec<String>) -> Option<Stri
Some(rating) => {
if let Some(f) = rating.as_f64() {
let mut i = (f * 10_f64).round() as i64;
if i > 10 {i = 10}
if i < 0 {i = 0}
if i > 10 {
i = 10
}
if i < 0 {
i = 0
}
Some(str[i as usize].to_owned()) //TODO: still inefficient. would be better to note the idx and load it in print_text
} else {
debug!("failed to convert MetadataValue to f64!");
None
}
},
}
None => {
trace!("no userRating MetadataValue found!");
None
},
}
}
}
@ -94,11 +103,32 @@ pub fn update_message(cfg: &Config, data: &mut Data, ratings: &Vec<String>) {
}
} else {
match meta.get(&key) {
Some(value) => data.field_text.insert(key.to_owned(), value_to_string(value, cfg.array_separator)),
None => data.field_text.insert(key.to_owned(), format!("No {}", key.trim_start_matches("xesam:"))),
Some(value) => {
trace!(
"update_messages: field {} has value {}",
key,
value_to_string(value, cfg.array_separator)
);
data.field_text
.insert(key.to_owned(), value_to_string(value, cfg.array_separator))
}
None => {
trace!("update_messages: field {} has no value!", key);
data.field_text.insert(
key.to_owned(),
format!("No {}", key.trim_start_matches("xesam:")),
)
}
};
}
}
} else {
debug!(
"update_messages: Player {} has no metadata!",
player.unique_name()
);
}
} else {
debug!("update_messages: No player found!");
}
}

View File

@ -2,10 +2,9 @@
//! 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 ('>').
@ -37,21 +36,31 @@ pub fn update_players(pf: &PlayerFinder, cfg: &Config, data: &mut Data) {
let players = pf.find_all().unwrap_or(Vec::new());
if players.is_empty() {
data.current_player = None;
debug!("update_players: no players found!")
} else {
let mut active: BTreeMap<u8, Player> = BTreeMap::new();
let mut trees = vec![BTreeMap::new(), BTreeMap::new(), BTreeMap::new()];
for player in players {
if let Ok(mpris::PlaybackStatus::Playing) = player.get_playback_status() {
if let Ok(status) = player.get_playback_status() {
let idx = cfg.find_player_priorities_idx(player.identity());
active.insert(idx, player);
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.
if let Some((_, player)) = active.pop_first() {
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!");
}
}
}
}