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