Add system notifications for track changes
- Add notify-rust dependency for desktop notifications - Create notification.rs commands module with show_track_notification and show_notification - Register notification commands in lib.rs - Wire up notifications in frontend for all playback scenarios: - Search results playback - Album track playback - Playlist track playback - Queue navigation and auto-advance
This commit is contained in:
1 parent
ddbedf6ab0
commit
ef8feebc45
5 files changed
+101
No files matched your search
@@ -52,6 +52,9 @@ symphonia = { version = "0.5", features = ["all"] }
|
||||
# Media controls (MPRIS on Linux)
|
||||
souvlaki = "0.7"
|
||||
|
||||
# Desktop notifications
|
||||
notify-rust = "4"
|
||||
|
||||
# Storage
|
||||
# sled = "0.34"
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
pub mod auth;
|
||||
pub mod favorites;
|
||||
pub mod notification;
|
||||
pub mod playback;
|
||||
pub mod playlist;
|
||||
pub mod queue;
|
||||
@@ -11,6 +12,7 @@ pub mod search;
|
||||
|
||||
pub use auth::*;
|
||||
pub use favorites::*;
|
||||
pub use notification::*;
|
||||
pub use playback::*;
|
||||
pub use playlist::*;
|
||||
pub use queue::*;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//! System notification commands
|
||||
|
||||
use notify_rust::Notification;
|
||||
|
||||
/// Show a track change notification
|
||||
#[tauri::command]
|
||||
pub fn show_track_notification(
|
||||
title: String,
|
||||
artist: String,
|
||||
album: String,
|
||||
_artwork_url: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
log::info!("Command: show_track_notification - {} by {}", title, artist);
|
||||
|
||||
let body = if album.is_empty() {
|
||||
artist.clone()
|
||||
} else {
|
||||
format!("{} • {}", artist, album)
|
||||
};
|
||||
|
||||
Notification::new()
|
||||
.summary(&title)
|
||||
.body(&body)
|
||||
.appname("QBZ")
|
||||
.timeout(3000) // 3 seconds
|
||||
.show()
|
||||
.map_err(|e| format!("Failed to show notification: {}", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Show a generic notification
|
||||
#[tauri::command]
|
||||
pub fn show_notification(
|
||||
title: String,
|
||||
body: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
log::info!("Command: show_notification - {}", title);
|
||||
|
||||
let mut notification = Notification::new();
|
||||
notification.summary(&title).appname("QBZ").timeout(3000);
|
||||
|
||||
if let Some(body_text) = body {
|
||||
notification.body(&body_text);
|
||||
}
|
||||
|
||||
notification
|
||||
.show()
|
||||
.map_err(|e| format!("Failed to show notification: {}", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -124,6 +124,9 @@ pub fn run() {
|
||||
commands::get_favorites,
|
||||
commands::add_favorite,
|
||||
commands::remove_favorite,
|
||||
// Notification commands
|
||||
commands::show_track_notification,
|
||||
commands::show_notification,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -277,6 +277,14 @@
|
||||
durationSecs: track.duration,
|
||||
coverUrl: artwork || null
|
||||
});
|
||||
|
||||
// Show system notification
|
||||
showTrackNotification(
|
||||
track.title,
|
||||
track.performer?.name || 'Unknown Artist',
|
||||
track.album?.title || '',
|
||||
artwork || undefined
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Failed to play track:', err);
|
||||
showToast(`Playback error: ${err}`, 'error');
|
||||
@@ -350,6 +358,14 @@
|
||||
durationSecs: track.durationSeconds,
|
||||
coverUrl: artwork || null
|
||||
});
|
||||
|
||||
// Show system notification
|
||||
showTrackNotification(
|
||||
track.title,
|
||||
track.artist || selectedAlbum?.artist || 'Unknown Artist',
|
||||
selectedAlbum?.title || '',
|
||||
artwork || undefined
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Failed to play track:', err);
|
||||
showToast(`Playback error: ${err}`, 'error');
|
||||
@@ -483,6 +499,9 @@
|
||||
coverUrl: track.artwork_url
|
||||
});
|
||||
|
||||
// Show system notification
|
||||
showTrackNotification(track.title, track.artist, track.album, track.artwork_url || undefined);
|
||||
|
||||
// Refresh queue state
|
||||
await syncQueueState();
|
||||
} catch (err) {
|
||||
@@ -653,6 +672,14 @@
|
||||
coverUrl: track.albumArt
|
||||
});
|
||||
|
||||
// Show system notification
|
||||
showTrackNotification(
|
||||
track.title,
|
||||
track.artist || 'Unknown Artist',
|
||||
track.album || 'Playlist',
|
||||
track.albumArt
|
||||
);
|
||||
|
||||
await syncQueueState();
|
||||
} catch (err) {
|
||||
console.error('Failed to play track:', err);
|
||||
@@ -661,6 +688,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
// System Notification for track changes
|
||||
async function showTrackNotification(title: string, artist: string, album: string, artworkUrl?: string) {
|
||||
try {
|
||||
await invoke('show_track_notification', {
|
||||
title,
|
||||
artist,
|
||||
album,
|
||||
artworkUrl: artworkUrl || null
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to show track notification:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// Toast Functions
|
||||
function showToast(message: string, type: 'success' | 'error' | 'info' = 'info') {
|
||||
toast = { message, type };
|
||||
|
||||
Reference in new issue
Block a user