Add notification customization (#893)
* Add custom notification formatting * Added `notification_format` to README * cleaned up code formatting * Fix typo Co-authored-by: Henrik Friedrichsen <henrik@affekt.org>
This commit is contained in:
@@ -50,6 +50,21 @@ impl TrackFormat {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||
pub struct NotificationFormat {
|
||||
pub title: Option<String>,
|
||||
pub body: Option<String>,
|
||||
}
|
||||
|
||||
impl NotificationFormat {
|
||||
pub fn default() -> Self {
|
||||
NotificationFormat {
|
||||
title: Some(String::from("%title")),
|
||||
body: Some(String::from("%artists")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
|
||||
pub struct ConfigValues {
|
||||
pub command_key: Option<char>,
|
||||
@@ -73,6 +88,7 @@ pub struct ConfigValues {
|
||||
pub cover_max_scale: Option<f32>,
|
||||
pub playback_state: Option<PlaybackState>,
|
||||
pub track_format: Option<TrackFormat>,
|
||||
pub notification_format: Option<NotificationFormat>,
|
||||
pub statusbar_format: Option<String>,
|
||||
pub library_tabs: Option<Vec<LibraryTab>>,
|
||||
pub hide_display_names: Option<bool>,
|
||||
|
||||
@@ -175,10 +175,14 @@ async fn main() -> Result<(), String> {
|
||||
println!("Connecting to Spotify..");
|
||||
let spotify = spotify::Spotify::new(event_manager.clone(), credentials, cfg.clone());
|
||||
|
||||
let queue = Arc::new(queue::Queue::new(spotify.clone(), cfg.clone()));
|
||||
|
||||
let library = Arc::new(Library::new(&event_manager, spotify.clone(), cfg.clone()));
|
||||
|
||||
let queue = Arc::new(queue::Queue::new(
|
||||
spotify.clone(),
|
||||
cfg.clone(),
|
||||
library.clone(),
|
||||
));
|
||||
|
||||
#[cfg(feature = "mpris")]
|
||||
let mpris_manager = Arc::new(mpris::MprisManager::new(
|
||||
event_manager.clone(),
|
||||
|
||||
33
src/queue.rs
33
src/queue.rs
@@ -10,10 +10,11 @@ use notify_rust::{Hint, Notification, Urgency};
|
||||
use rand::prelude::*;
|
||||
use strum_macros::Display;
|
||||
|
||||
use crate::config::PlaybackState;
|
||||
use crate::config::{Config, NotificationFormat, PlaybackState};
|
||||
use crate::library::Library;
|
||||
use crate::model::playable::Playable;
|
||||
use crate::spotify::PlayerEvent;
|
||||
use crate::spotify::Spotify;
|
||||
use crate::{config::Config, spotify::PlayerEvent};
|
||||
|
||||
#[derive(Display, Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
||||
pub enum RepeatSetting {
|
||||
@@ -38,10 +39,11 @@ pub struct Queue {
|
||||
cfg: Arc<Config>,
|
||||
#[cfg(feature = "notify")]
|
||||
notification_id: Arc<AtomicU32>,
|
||||
library: Arc<Library>,
|
||||
}
|
||||
|
||||
impl Queue {
|
||||
pub fn new(spotify: Spotify, cfg: Arc<Config>) -> Queue {
|
||||
pub fn new(spotify: Spotify, cfg: Arc<Config>, library: Arc<Library>) -> Queue {
|
||||
let queue_state = cfg.state().queuestate.clone();
|
||||
let playback_state = cfg.state().playback_state.clone();
|
||||
let queue = Queue {
|
||||
@@ -52,6 +54,7 @@ impl Queue {
|
||||
cfg,
|
||||
#[cfg(feature = "notify")]
|
||||
notification_id: Arc::new(AtomicU32::new(0)),
|
||||
library,
|
||||
};
|
||||
|
||||
if let Some(playable) = queue.get_current() {
|
||||
@@ -285,13 +288,27 @@ impl Queue {
|
||||
if self.cfg.values().notify.unwrap_or(false) {
|
||||
let notification_id = self.notification_id.clone();
|
||||
std::thread::spawn({
|
||||
let track_name = track.to_string();
|
||||
// use same parser as track_format, Playable::format
|
||||
let format = self
|
||||
.cfg
|
||||
.values()
|
||||
.notification_format
|
||||
.clone()
|
||||
.unwrap_or_default();
|
||||
let default_title = NotificationFormat::default().title.unwrap();
|
||||
let title = format.title.unwrap_or_else(|| default_title.clone());
|
||||
|
||||
let default_body = NotificationFormat::default().body.unwrap();
|
||||
let body = format.body.unwrap_or_else(|| default_body.clone());
|
||||
|
||||
let summary_txt = Playable::format(track, &title, self.library.clone());
|
||||
let body_txt = Playable::format(track, &body, self.library.clone());
|
||||
let cover_url = if cfg!(feature = "cover") {
|
||||
track.cover_url()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
move || send_notification(&track_name, cover_url, notification_id)
|
||||
move || send_notification(&summary_txt, &body_txt, cover_url, notification_id)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -432,7 +449,8 @@ impl Queue {
|
||||
|
||||
#[cfg(feature = "notify")]
|
||||
pub fn send_notification(
|
||||
track_name: &str,
|
||||
summary_txt: &str,
|
||||
body_txt: &str,
|
||||
cover_url: Option<String>,
|
||||
notification_id: Arc<AtomicU32>,
|
||||
) {
|
||||
@@ -441,7 +459,8 @@ pub fn send_notification(
|
||||
let mut n = Notification::new();
|
||||
n.appname("ncspot")
|
||||
.id(current_notification_id)
|
||||
.summary(track_name);
|
||||
.summary(summary_txt)
|
||||
.body(body_txt);
|
||||
|
||||
// album cover image
|
||||
if let Some(u) = cover_url {
|
||||
|
||||
Reference in New Issue
Block a user