Iimprove the articet
This commit is contained in:
parent
b8af73ee0f
commit
9a5a93450a
6 changed files with 109 additions and 45 deletions
|
@ -77,10 +77,12 @@ fn main() {
|
|||
// Update the previous response.
|
||||
previous_response = response;
|
||||
|
||||
match notifications_handler.show_notification(events, &previous_response) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
if !events.is_empty() {
|
||||
match notifications_handler.show_notification(events, &previous_response) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::cmus::player_settings::{AAAMode, Shuffle};
|
||||
use crate::cmus::player_settings::{AAAMode, PlayerSettings, Shuffle};
|
||||
use crate::cmus::{Track, TrackStatus};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CmusEvent {
|
||||
StatusChanged(Track),
|
||||
TrackChanged(Track),
|
||||
VolumeChanged { left: u8, right: u8 },
|
||||
PositionChanged(u32),
|
||||
ShuffleChanged(Shuffle),
|
||||
RepeatChanged(bool),
|
||||
AAAMode(AAAMode),
|
||||
StatusChanged(Track, PlayerSettings),
|
||||
TrackChanged(Track, PlayerSettings),
|
||||
VolumeChanged(Track, PlayerSettings),
|
||||
PositionChanged(Track, PlayerSettings),
|
||||
ShuffleChanged(Track, PlayerSettings),
|
||||
RepeatChanged(Track, PlayerSettings),
|
||||
AAAMode(Track, PlayerSettings),
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ use std::str::FromStr;
|
|||
use thiserror::Error;
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
pub struct TrackMetadata {
|
||||
tags: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
pub enum TrackStatus {
|
||||
Playing,
|
||||
Paused,
|
||||
|
@ -25,7 +25,7 @@ pub enum TrackStatus {
|
|||
Stopped,
|
||||
}
|
||||
|
||||
#[derive(Debug, TypedBuilder, PartialEq, Default)]
|
||||
#[derive(Debug, TypedBuilder, PartialEq, Default, Clone)]
|
||||
pub struct Track {
|
||||
pub status: TrackStatus,
|
||||
pub path: String,
|
||||
|
|
|
@ -4,7 +4,7 @@ use log::{debug, info};
|
|||
use std::num::ParseIntError;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct PlayerSettings {
|
||||
pub repeat: bool,
|
||||
pub repeat_current: bool,
|
||||
|
@ -13,7 +13,7 @@ pub struct PlayerSettings {
|
|||
pub volume: Volume,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
pub enum Shuffle {
|
||||
#[default]
|
||||
Off,
|
||||
|
@ -21,13 +21,13 @@ pub enum Shuffle {
|
|||
Albums,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
pub struct Volume {
|
||||
pub left: u8,
|
||||
pub right: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[derive(Debug, PartialEq, Default, Clone)]
|
||||
pub enum AAAMode {
|
||||
#[default]
|
||||
All,
|
||||
|
|
|
@ -51,7 +51,7 @@ impl CmusQueryResponse {
|
|||
if self.track_row.is_empty() || self.player_settings_row.is_empty() {
|
||||
#[cfg(feature = "debug")]
|
||||
info!("Cmus response is empty, returning empty events");
|
||||
return Err(CmusError::NoEvents)
|
||||
return Ok(Vec::new())
|
||||
}
|
||||
|
||||
let mut events = Vec::new();
|
||||
|
@ -59,6 +59,8 @@ impl CmusQueryResponse {
|
|||
let track = self.track()?;
|
||||
let other_track = other.track()?;
|
||||
|
||||
let other_player_settings = other.player_settings()?;
|
||||
|
||||
if track != other_track {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Track changed: {:?} -> {:?}", other_track, track);
|
||||
|
@ -66,7 +68,10 @@ impl CmusQueryResponse {
|
|||
if track.path != other_track.path {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Track changed: {:?} -> {:?}", other_track, track);
|
||||
events.push(CmusEvent::TrackChanged(other_track));
|
||||
events.push(CmusEvent::TrackChanged(
|
||||
other_track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
// We don't need to check for other changes, since the track changed.
|
||||
return Ok(events);
|
||||
} else if track.status != other_track.status {
|
||||
|
@ -75,19 +80,24 @@ impl CmusQueryResponse {
|
|||
"Status changed: {:?} -> {:?}",
|
||||
other_track.status, track.status
|
||||
);
|
||||
events.push(CmusEvent::StatusChanged(track));
|
||||
events.push(CmusEvent::StatusChanged(
|
||||
track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
} else if track.position != other_track.position {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!(
|
||||
"Position changed: {:?} -> {:?}",
|
||||
other_track.position, track.position
|
||||
);
|
||||
events.push(CmusEvent::PositionChanged(other_track.position));
|
||||
events.push(CmusEvent::PositionChanged(
|
||||
track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let player_settings = self.player_settings()?;
|
||||
let other_player_settings = other.player_settings()?;
|
||||
|
||||
if player_settings != other_player_settings {
|
||||
#[cfg(feature = "debug")]
|
||||
|
@ -103,7 +113,10 @@ impl CmusQueryResponse {
|
|||
other_player_settings.shuffle, player_settings.shuffle
|
||||
);
|
||||
|
||||
events.push(CmusEvent::ShuffleChanged(player_settings.shuffle));
|
||||
events.push(CmusEvent::ShuffleChanged(
|
||||
other_track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if player_settings.repeat != other_player_settings.repeat {
|
||||
|
@ -113,7 +126,10 @@ impl CmusQueryResponse {
|
|||
other_player_settings.repeat, player_settings.repeat
|
||||
);
|
||||
|
||||
events.push(CmusEvent::RepeatChanged(player_settings.repeat));
|
||||
events.push(CmusEvent::RepeatChanged(
|
||||
other_track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if player_settings.aaa_mode != other_player_settings.aaa_mode {
|
||||
|
@ -123,7 +139,10 @@ impl CmusQueryResponse {
|
|||
other_player_settings.aaa_mode, player_settings.aaa_mode
|
||||
);
|
||||
|
||||
events.push(CmusEvent::AAAMode(player_settings.aaa_mode));
|
||||
events.push(CmusEvent::AAAMode(
|
||||
other_track.clone(),
|
||||
other_player_settings.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
if player_settings.volume != other_player_settings.volume {
|
||||
|
@ -133,10 +152,7 @@ impl CmusQueryResponse {
|
|||
other_player_settings.volume, player_settings.volume
|
||||
);
|
||||
|
||||
events.push(CmusEvent::VolumeChanged {
|
||||
left: player_settings.volume.left,
|
||||
right: player_settings.volume.right,
|
||||
});
|
||||
events.push(CmusEvent::VolumeChanged(other_track, other_player_settings));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::cmus::events::CmusEvent;
|
||||
use crate::cmus::player_settings::PlayerSettings;
|
||||
use crate::cmus::query::CmusQueryResponse;
|
||||
use crate::cmus::{Track, TrackStatus};
|
||||
use crate::settings::Settings;
|
||||
|
@ -7,6 +8,12 @@ use crate::{process_template_placeholders, track_cover, TrackCover};
|
|||
use log::{debug, info};
|
||||
use notify_rust::Notification;
|
||||
|
||||
enum Action {
|
||||
Show,
|
||||
Update,
|
||||
None,
|
||||
}
|
||||
|
||||
pub struct NotificationsHandler {
|
||||
cover_set: bool,
|
||||
notification: Notification,
|
||||
|
@ -33,26 +40,29 @@ impl NotificationsHandler {
|
|||
//FIXME: Should check if the user has enabled the cover feature or use a static cover.
|
||||
self.update_cover(&events[0], response);
|
||||
|
||||
let mut action = Action::None;
|
||||
|
||||
for event in events {
|
||||
#[cfg(feature = "debug")]
|
||||
info!("event: {:?}", event);
|
||||
|
||||
match event {
|
||||
CmusEvent::StatusChanged(track) => {
|
||||
CmusEvent::StatusChanged(track, player_settings) => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Status changed: {:?}", track.status);
|
||||
self.build_status_notification(track);
|
||||
self.notification.show()?;
|
||||
action = self.build_status_notification(track, player_settings);
|
||||
}
|
||||
CmusEvent::TrackChanged(track) => {
|
||||
CmusEvent::TrackChanged(track, player_settings) => {
|
||||
#[cfg(feature = "debug")]
|
||||
debug!("Track changed: {:?}", track);
|
||||
self.build_track_notification(track)?
|
||||
action = self.build_track_notification(track, player_settings);
|
||||
}
|
||||
CmusEvent::VolumeChanged(track, player_settings)
|
||||
if self.settings.show_player_notifications =>
|
||||
{
|
||||
action = self.build_volume_notification(track, player_settings);
|
||||
}
|
||||
/*
|
||||
CmusEvent::VolumeChanged { left, right } if settings.show_player_notifications => {
|
||||
build_volume_notification(left, right, settings, notification)?
|
||||
}
|
||||
CmusEvent::PositionChanged(position) => todo!(),
|
||||
CmusEvent::ShuffleChanged(shuffle) if settings.show_player_notifications => {
|
||||
build_shuffle_notification(shuffle, settings, notification)?
|
||||
|
@ -66,12 +76,26 @@ impl NotificationsHandler {
|
|||
*/
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match action {
|
||||
Action::Show => {
|
||||
let _ = self.notification.show()?;
|
||||
}
|
||||
Action::None => {}
|
||||
_ => todo!(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn build_status_notification(&mut self, track: Track) {
|
||||
fn build_status_notification(
|
||||
&mut self,
|
||||
track: Track,
|
||||
player_settings: PlayerSettings,
|
||||
) -> Action {
|
||||
// Set the summary and body of the notification.
|
||||
self.notification
|
||||
.summary(
|
||||
|
@ -83,25 +107,47 @@ impl NotificationsHandler {
|
|||
.as_str(),
|
||||
)
|
||||
.timeout(self.settings.status_notification_timeout as i32 * 1000);
|
||||
Action::Show
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn build_track_notification(&mut self, track: Track) -> Result<(), notify_rust::error::Error> {
|
||||
fn build_track_notification(
|
||||
&mut self,
|
||||
track: Track,
|
||||
player_settings: PlayerSettings,
|
||||
) -> Action {
|
||||
// Set the summary and body of the notification.
|
||||
self.notification
|
||||
.summary(process_template_placeholders(&self.settings.summary, &track).as_str())
|
||||
.body(process_template_placeholders(&self.settings.body, &track).as_str());
|
||||
|
||||
let n = self.notification.show()?;
|
||||
Action::Show
|
||||
}
|
||||
|
||||
Ok(())
|
||||
#[inline(always)]
|
||||
fn build_volume_notification(
|
||||
&mut self,
|
||||
track: Track,
|
||||
player_settings: PlayerSettings,
|
||||
) -> Action {
|
||||
self.notification
|
||||
.summary(
|
||||
process_template_placeholders(&self.settings.volume_notification_summary, &track)
|
||||
.as_str(),
|
||||
)
|
||||
.body(
|
||||
process_template_placeholders(&self.settings.volume_notification_body, &track)
|
||||
.as_str(),
|
||||
);
|
||||
|
||||
Action::Show
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn update_cover(&mut self, first_event: &CmusEvent, response: &CmusQueryResponse) {
|
||||
// If the track is changed, we need to update the cover.
|
||||
match first_event {
|
||||
CmusEvent::TrackChanged(track) => {
|
||||
CmusEvent::TrackChanged(track, _) => {
|
||||
self.set_cover(track);
|
||||
}
|
||||
_ => {
|
||||
|
@ -133,7 +179,7 @@ impl NotificationsHandler {
|
|||
self.settings.force_use_external_cover,
|
||||
self.settings.no_use_external_cover,
|
||||
)
|
||||
.set_notification_image(&mut self.notification);
|
||||
.set_notification_image(&mut self.notification);
|
||||
// Flip the change flag
|
||||
self.cover_set = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue