Show notifications on song download
This commit is contained in:
parent
a5090e7251
commit
b97e6b56f4
|
@ -1,5 +1,6 @@
|
||||||
use std::{collections::HashMap, str::FromStr, sync::{Arc, Mutex, MutexGuard}, time::Duration};
|
use std::{collections::HashMap, str::FromStr, sync::{mpsc::{self, Receiver, Sender}, Arc, Mutex, MutexGuard}, time::Duration};
|
||||||
use downloader::song::SongStatus;
|
use downloader::song::SongStatus;
|
||||||
|
use log::warn;
|
||||||
use xmpd_manifest::song::Song;
|
use xmpd_manifest::song::Song;
|
||||||
|
|
||||||
pub mod downloader;
|
pub mod downloader;
|
||||||
|
@ -25,6 +26,11 @@ pub enum DlStatus {
|
||||||
Error(String),
|
Error(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Message {
|
||||||
|
DownloadDone(uuid::Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
impl Cache {
|
impl Cache {
|
||||||
pub fn get() -> crate::Result<MutexGuard<'static, Self>> {
|
pub fn get() -> crate::Result<MutexGuard<'static, Self>> {
|
||||||
match CACHE.lock() {
|
match CACHE.lock() {
|
||||||
|
@ -33,8 +39,10 @@ impl Cache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self) -> Result<()> {
|
pub fn init(&mut self) -> Result<Receiver<Message>> {
|
||||||
start_cache_mv_thread();
|
let (internal_tx, cache_rx) = mpsc::channel::<Message>();
|
||||||
|
// let (internal_rx, cache_tx) = mpsc::channel::<Message>();
|
||||||
|
start_cache_mv_thread(internal_tx);
|
||||||
self.cache_dir = xmpd_cliargs::CLIARGS.cache_path();
|
self.cache_dir = xmpd_cliargs::CLIARGS.cache_path();
|
||||||
|
|
||||||
{ // Get cached songs
|
{ // Get cached songs
|
||||||
|
@ -62,7 +70,7 @@ impl Cache {
|
||||||
}
|
}
|
||||||
{ // Get Cached meta
|
{ // Get Cached meta
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(cache_rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn download_to_cache(&mut self, sid: uuid::Uuid, song: Song) {
|
pub fn download_to_cache(&mut self, sid: uuid::Uuid, song: Song) {
|
||||||
|
@ -77,12 +85,13 @@ impl Cache {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cached_song_status(&mut self, sid: &uuid::Uuid) -> Option<DlStatus> {
|
pub fn get_cached_song_status(&mut self, sid: &uuid::Uuid) -> Option<DlStatus> {
|
||||||
Some(self.song_cache.get(sid)?.clone())
|
let original = self.song_cache.get(sid)?.clone();
|
||||||
|
Some(original)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_cache_mv_thread() {
|
fn start_cache_mv_thread(tx: Sender<Message>) {
|
||||||
std::thread::spawn(|| {
|
std::thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
{
|
{
|
||||||
std::thread::sleep(Duration::from_millis(500));
|
std::thread::sleep(Duration::from_millis(500));
|
||||||
|
@ -98,6 +107,7 @@ fn start_cache_mv_thread() {
|
||||||
let song_p = song_p.with_extension(&song_format);
|
let song_p = song_p.with_extension(&song_format);
|
||||||
log::debug!("Found done: {:?}: {}", song_p, song_p.exists());
|
log::debug!("Found done: {:?}: {}", song_p, song_p.exists());
|
||||||
if song_p.exists() {
|
if song_p.exists() {
|
||||||
|
let _ = tx.send(Message::DownloadDone(sid.clone()));
|
||||||
cache.song_cache.insert(sid.clone(), DlStatus::Done(song_p));
|
cache.song_cache.insert(sid.clone(), DlStatus::Done(song_p));
|
||||||
done_jobs.push(sid.clone());
|
done_jobs.push(sid.clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,13 @@ fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) {
|
||||||
.fit_to_exact_size(Vec2::new(16.0, 16.0))
|
.fit_to_exact_size(Vec2::new(16.0, 16.0))
|
||||||
);
|
);
|
||||||
if img.clicked() {
|
if img.clicked() {
|
||||||
handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone())
|
handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone());
|
||||||
|
let mut toast = handle_error_ui!(crate::components::toast::Toast::get());
|
||||||
|
toast.show_toast(
|
||||||
|
"Downloading Song",
|
||||||
|
&format!("Started downloading {} by {}", song.name(), song.author()),
|
||||||
|
super::toast::ToastType::Info
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use xmpd_manifest::store::BaseStore;
|
use xmpd_manifest::store::BaseStore;
|
||||||
|
|
||||||
use crate::components::{left_nav::LeftNav, CompGetter, CompUi};
|
use crate::components::{left_nav::LeftNav, toast::ToastType, CompGetter, CompUi};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SearchType {
|
pub enum SearchType {
|
||||||
|
@ -53,6 +53,12 @@ impl CompUi for SongListNav {
|
||||||
handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone())
|
handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut toast = handle_error_ui!(crate::components::toast::Toast::get());
|
||||||
|
toast.show_toast(
|
||||||
|
"Downloading Songs",
|
||||||
|
&format!("Started downloading {} songs", songs.len()),
|
||||||
|
ToastType::Info
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -100,7 +100,9 @@ impl CompUi for Toast {
|
||||||
|
|
||||||
|
|
||||||
impl Toast {
|
impl Toast {
|
||||||
pub fn show_toast(&mut self, title: &str, description: &str, toast_type: ToastType) {
|
pub fn show_toast<S>(&mut self, title: S, description: S, toast_type: ToastType)
|
||||||
|
where S: ToString
|
||||||
|
{
|
||||||
self.queue.push_front((title.to_string(), description.to_string(), toast_type, SystemTime::now()));
|
self.queue.push_front((title.to_string(), description.to_string(), toast_type, SystemTime::now()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,13 @@ const W_NAME: &str = "xmpd v2.0.0a";
|
||||||
type Result<T> = anyhow::Result<T>;
|
type Result<T> = anyhow::Result<T>;
|
||||||
|
|
||||||
pub fn start() -> Result<()> {
|
pub fn start() -> Result<()> {
|
||||||
xmpd_cache::Cache::get()?.init()?;
|
let cache_rx = xmpd_cache::Cache::get()?.init()?;
|
||||||
let options = eframe::NativeOptions::default();
|
let options = eframe::NativeOptions::default();
|
||||||
let mut state = GuiState::new()?;
|
let mut state = GuiState::new()?;
|
||||||
let res = eframe::run_simple_native(W_NAME, options, move |ctx, _frame| {
|
let res = eframe::run_simple_native(W_NAME, options, move |ctx, _frame| {
|
||||||
egui_extras::install_image_loaders(ctx);
|
egui_extras::install_image_loaders(ctx);
|
||||||
state.windows.clone().draw_all(ctx, &mut state);
|
state.windows.clone().draw_all(ctx, &mut state);
|
||||||
handle_error_ui!(main_window::draw(ctx, &mut state));
|
handle_error_ui!(main_window::draw(ctx, &mut state, &cache_rx));
|
||||||
ctx.request_repaint_after(Duration::from_millis(500));
|
ctx.request_repaint_after(Duration::from_millis(500));
|
||||||
});
|
});
|
||||||
if let Err(e) = res { // dumb err value by eframe
|
if let Err(e) = res { // dumb err value by eframe
|
||||||
|
@ -31,6 +31,8 @@ pub fn start() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct GuiState {
|
pub struct GuiState {
|
||||||
pub manifest: Manifest<JsonStore>,
|
pub manifest: Manifest<JsonStore>,
|
||||||
pub windows: windows::Windows,
|
pub windows: windows::Windows,
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
|
||||||
|
use xmpd_cache::Message;
|
||||||
|
use xmpd_manifest::store::BaseStore;
|
||||||
use xmpd_settings::theme::Theme;
|
use xmpd_settings::theme::Theme;
|
||||||
|
|
||||||
use crate::{components::{self, song_list, CompUi}, GuiState};
|
use crate::{components::{self, song_list, toast::ToastType, CompGetter, CompUi}, GuiState};
|
||||||
|
|
||||||
pub fn draw(ctx: &egui::Context, state: &mut GuiState) -> crate::Result<()> {
|
pub fn draw(ctx: &egui::Context, state: &mut GuiState, cache_rx: &Receiver<Message>) -> crate::Result<()> {
|
||||||
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
||||||
egui::TopBottomPanel::new(egui::panel::TopBottomSide::Top, "top_nav")
|
egui::TopBottomPanel::new(egui::panel::TopBottomSide::Top, "top_nav")
|
||||||
.frame(get_themed_frame(&theme))
|
.frame(get_themed_frame(&theme))
|
||||||
|
@ -53,6 +57,21 @@ pub fn draw(ctx: &egui::Context, state: &mut GuiState) -> crate::Result<()> {
|
||||||
handle_error_ui!(crate::components::player::Player::draw(ui, state));
|
handle_error_ui!(crate::components::player::Player::draw(ui, state));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if let Ok(msg) = cache_rx.try_recv() {
|
||||||
|
match msg {
|
||||||
|
Message::DownloadDone(sid) => {
|
||||||
|
if let Some(song) = state.manifest.store().get_song(&sid) {
|
||||||
|
let mut toast = crate::components::toast::Toast::get()?;
|
||||||
|
toast.show_toast(
|
||||||
|
"Done downloading",
|
||||||
|
&format!("Downloaded {} by {}", song.name(), song.author()),
|
||||||
|
ToastType::Info
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user