diff --git a/soulseek-rs/src/models/app_state.rs b/soulseek-rs/src/models/app_state.rs index 1c4dc40..ca0c880 100644 --- a/soulseek-rs/src/models/app_state.rs +++ b/soulseek-rs/src/models/app_state.rs @@ -2,14 +2,13 @@ use crate::models::FileDisplayData; use ratatui::{layout::Rect, widgets::TableState}; use soulseek_rs::{types::Download, DownloadStatus}; use std::sync::atomic::AtomicBool; -use std::sync::{mpsc::Receiver, Arc}; +use std::sync::{mpsc::Receiver, mpsc::Sender, Arc}; use std::time::Instant; #[derive(Debug, Clone, PartialEq)] pub enum SearchStatus { Active, Completed, - Failed(String), } pub struct SearchEntry { @@ -53,6 +52,8 @@ pub struct AppState { pub downloads_table_state: TableState, pub downloads_receiver_channel: Option)>>, + pub downloads_sender_channel: + Option)>>, pub active_downloads_count: usize, // UI State @@ -94,6 +95,7 @@ impl AppState { downloads: Vec::new(), downloads_table_state, downloads_receiver_channel: None, + downloads_sender_channel: None, active_downloads_count: 0, focused_pane: FocusedPane::Searches, diff --git a/soulseek-rs/src/ui/main_tui.rs b/soulseek-rs/src/ui/main_tui.rs index 47598ff..58393a6 100644 --- a/soulseek-rs/src/ui/main_tui.rs +++ b/soulseek-rs/src/ui/main_tui.rs @@ -1,6 +1,6 @@ use crate::models::{ - AppState, DownloadEntry, FileDisplayData, FocusedPane, - SearchEntry, SearchStatus, + AppState, DownloadEntry, FileDisplayData, FocusedPane, SearchEntry, + SearchStatus, }; use crate::ui::panes::{ render_downloads_pane, render_results_pane, render_searches_pane, @@ -711,11 +711,6 @@ impl MainTui { let selected_search_index = self.state.selected_search_index; for (idx, search) in self.state.searches.iter_mut().enumerate() { - // Only skip failed searches; allow Active and Completed to update - if matches!(search.status, SearchStatus::Failed(_)) { - continue; - } - // Poll for new results let search_query = search.query.clone(); let search_results = self.client.get_search_results(&search_query); @@ -748,7 +743,9 @@ impl MainTui { } // Mark as completed after timeout (but continue updating) - if search.status == SearchStatus::Active && search.start_time.elapsed() > timeout { + if search.status == SearchStatus::Active + && search.start_time.elapsed() > timeout + { search.status = SearchStatus::Completed; } } @@ -769,13 +766,15 @@ impl MainTui { return; } - // Create channel for async download initialization - let (sender, receiver) = mpsc::channel(); - self.state.downloads_receiver_channel = Some(receiver); + if self.state.downloads_receiver_channel.is_none() { + let (sender, receiver) = mpsc::channel(); + self.state.downloads_receiver_channel = Some(receiver); + self.state.downloads_sender_channel = Some(sender); + } - // Start downloads in background let client = self.client.clone(); let download_dir = self.download_dir.clone(); + let sender = self.state.downloads_sender_channel.clone().unwrap(); thread::spawn(move || { for (filename, username, size) in selected_files.into_iter() { @@ -786,8 +785,14 @@ impl MainTui { download_dir.clone(), ) { Ok(rx) => { - // Get the download from client - if let Some(download) = client.get_all_downloads().iter().find(|d| d.filename == filename && d.username == username).cloned() { + if let Some(download) = client + .get_all_downloads() + .iter() + .find(|d| { + d.filename == filename && d.username == username + }) + .cloned() + { let _ = sender.send((download, rx)); } } diff --git a/soulseek-rs/src/ui/panes/searches_pane.rs b/soulseek-rs/src/ui/panes/searches_pane.rs index 431a4c4..aa45997 100644 --- a/soulseek-rs/src/ui/panes/searches_pane.rs +++ b/soulseek-rs/src/ui/panes/searches_pane.rs @@ -1,7 +1,7 @@ use crate::models::{SearchEntry, SearchStatus}; use crate::ui::{ - border_style, border_type, error_style, header_style, highlight_style, - success_style, warning_style, HIGHLIGHT_SYMBOL, + border_style, border_type, header_style, highlight_style, success_style, + warning_style, HIGHLIGHT_SYMBOL, }; use ratatui::{ layout::Rect, @@ -33,9 +33,6 @@ pub fn render_searches_pane( SearchStatus::Completed => { Cell::from("Done").style(success_style()) } - SearchStatus::Failed(msg) => { - Cell::from(format!("Failed: {}", msg)).style(error_style()) - } }; let results_count = search.results.len();