Just create the notifications handler

This commit is contained in:
Anas Elgarhy 2023-02-20 05:34:03 +02:00
parent 6270ea9717
commit 19ef64f8ed
No known key found for this signature in database
GPG key ID: 0501802A1D496528
2 changed files with 128 additions and 125 deletions

View file

@ -50,7 +50,10 @@ fn main() {
#[cfg(feature = "debug")]
info!("Query command built: {:?}", query_command);
let mut notification = notify_rust::Notification::new();
let interval = settings.interval;
let link = settings.link;
let mut notifications_handler = notification::NotificationsHandler::new(settings);
// Initialize the buffer to store the response from cmus, to compare it with the next one.
let mut previous_response = CmusQueryResponse::default();
@ -58,11 +61,11 @@ fn main() {
loop {
// Get the response from cmus.
let Ok(response) = cmus::ping_cmus(&mut query_command) else {
if settings.link {
if link {
std::process::exit(0)
} else {
// If the track info is the same as the previous one, just sleep for a while and try again.
sleep!(settings.interval);
sleep!(interval);
continue;
}
};
@ -74,8 +77,7 @@ fn main() {
// Update the previous response.
previous_response = response;
match notification::show_notification(events, &settings, &mut notification, &previous_response) {
match notifications_handler.show_notification(events, &previous_response) {
Ok(_) => {}
Err(e) => {
eprintln!("Error: {}", e);
@ -83,6 +85,6 @@ fn main() {
}
}
}
sleep!(settings.interval);
sleep!(interval);
}
}

View file

@ -7,133 +7,134 @@ use log::{debug, info};
use notify_rust::Notification;
use crate::cmus::query::CmusQueryResponse;
#[inline(always)]
pub fn show_notification(
events: Vec<CmusEvent>,
settings: &Settings,
notification: &mut Notification,
response: &CmusQueryResponse,
) -> Result<(), notify_rust::error::Error> {
if events.is_empty() {
#[cfg(feature = "debug")]
info!("no events to process");
return Ok(()); // No events to process.
pub struct NotificationsHandler {
cover_set: bool,
notification: Notification,
handlers: Vec<notify_rust::NotificationHandle>,
settings: Settings,
}
impl NotificationsHandler {
pub fn new(settings: Settings) -> Self {
Self {
cover_set: false,
notification: Notification::new(),
handlers: Vec::new(),
settings,
}
}
//FIXME: Should check if the user has enabled the cover feature or use a static cover.
update_cover(&events[0], response, settings, notification);
pub fn show_notification(
&mut self,
events: Vec<CmusEvent>,
response: &CmusQueryResponse,
) -> Result<(), notify_rust::error::Error> {
if events.is_empty() {
#[cfg(feature = "debug")]
info!("no events to process");
return Ok(()); // No events to process.
}
for event in events {
#[cfg(feature = "debug")]
info!("event: {:?}", event);
//FIXME: Should check if the user has enabled the cover feature or use a static cover.
self.update_cover(&events[0], response);
match event {
CmusEvent::StatusChanged(track) => {
#[cfg(feature = "debug")]
debug!("Status changed: {:?}", track.status);
build_status_notification(track, settings, notification);
notification.show()?;
for event in events {
#[cfg(feature = "debug")]
info!("event: {:?}", event);
match event {
CmusEvent::StatusChanged(track) => {
#[cfg(feature = "debug")]
debug!("Status changed: {:?}", track.status);
self.build_status_notification(track);
self.notification.show()?;
}
CmusEvent::TrackChanged(track) => {
#[cfg(feature = "debug")]
debug!("Track changed: {:?}", track);
self.build_track_notification(track)?
}
/*
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)?
}
CmusEvent::RepeatChanged(repeat) if settings.show_player_notifications => {
build_repeat_notification(repeat, settings, notification)?
}
CmusEvent::AAAMode(aaa_mode) if settings.show_player_notifications => {
build_aaa_mode_notification(aaa_mode, settings, notification)?
}
*/
_ => {}
}
}
Ok(())
}
#[inline(always)]
fn build_status_notification(&mut self, track: Track) {
// Set the summary and body of the notification.
self.notification
.summary(
process_template_placeholders(&self.settings.status_notification_summary, &track).as_str(),
)
.body(process_template_placeholders(&self.settings.status_notification_body, &track).as_str())
.timeout(self.settings.status_notification_timeout as i32 * 1000);
}
#[inline(always)]
fn build_track_notification(&mut self, track: Track) -> Result<(), notify_rust::error::Error> {
// 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()?;
Ok(())
}
#[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) => {
#[cfg(feature = "debug")]
debug!("Track changed: {:?}", track);
build_track_notification(track, settings, notification)?
self.set_cover(track);
}
/*
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)?
}
CmusEvent::RepeatChanged(repeat) if settings.show_player_notifications => {
build_repeat_notification(repeat, settings, notification)?
}
CmusEvent::AAAMode(aaa_mode) if settings.show_player_notifications => {
build_aaa_mode_notification(aaa_mode, settings, notification)?
}
*/
_ => {}
}
}
Ok(())
}
#[inline(always)]
fn build_status_notification(
track: Track,
settings: &Settings,
notification: &mut Notification,
) {
// Set the summary and body of the notification.
notification
.summary(
process_template_placeholders(&settings.status_notification_summary, &track).as_str(),
)
.body(process_template_placeholders(&settings.status_notification_body, &track).as_str())
.timeout(settings.status_notification_timeout as i32 * 1000);
}
#[inline(always)]
fn build_track_notification(
track: Track,
settings: &Settings,
notification: &mut Notification,
) -> Result<(), notify_rust::error::Error> {
// Set the summary and body of the notification.
notification
.summary(process_template_placeholders(&settings.summary, &track).as_str())
.body(process_template_placeholders(&settings.body, &track).as_str());
let n = notification.show()?;
Ok(())
}
macro_rules! setup_notification {
($notification: expr, $settings: expr) => {
$notification
.appname("cmus-notify")
.timeout($settings.timeout as i32 * 1000)
.hint(notify_rust::Hint::Category("music".to_string()))
.hint(notify_rust::Hint::DesktopEntry("cmus-notify.desktop".to_string()))
.hint(notify_rust::Hint::Resident(true));
};
}
#[inline(always)]
fn update_cover(first_event: &CmusEvent, response: &CmusQueryResponse, settings: &Settings, notification: &mut Notification) {
let mut cover = TrackCover::None;
// If the track is changed, we need to update the cover.
match first_event {
CmusEvent::TrackChanged(track) => {
cover = track_cover(
&track.path,
settings.depth,
settings.force_use_external_cover,
settings.no_use_external_cover,
);
}
_ => {
if cover == TrackCover::None {
// If the cover is not found, we need to update it.
if let Ok(track) = &response.track() {
cover = track_cover(
&track.path,
settings.depth,
settings.force_use_external_cover,
settings.no_use_external_cover,
);
_ => {
if !self.cover_set {
// If the cover is not found, we need to update it.
if let Ok(track) = response.track() {
self.set_cover(&track);
}
}
}
}
};
// Set the notification cover.
if cover != TrackCover::None {
*notification = Notification::new();
// Reset the notification.
setup_notification!(&mut *notification, &settings);
cover.set_notification_image(&mut *notification);
};
}
fn set_cover(&mut self, track: &Track) {
// Reset the notification
self.notification = Notification::new();
self.notification.appname("cmus-notify")
.timeout(self.settings.timeout as i32 * 1000)
.hint(notify_rust::Hint::Category("music".to_string()))
.hint(notify_rust::Hint::DesktopEntry("cmus.desktop".to_string()))
.hint(notify_rust::Hint::Resident(true));
// Get the track cover and set it to notification
track_cover(
&track.path,
self.settings.depth,
self.settings.force_use_external_cover,
self.settings.no_use_external_cover,
).set_notification_image(&mut self.notification);
// Flip the change flag
self.cover_set = true;
}
}