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