fix: queuing downloads

This commit is contained in:
Michel de Graaf
2025-11-19 08:27:50 +01:00
parent b7a5037edb
commit bb86e50b4f
3 changed files with 25 additions and 21 deletions
+4 -2
View File
@@ -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<Receiver<(Download, Receiver<DownloadStatus>)>>,
pub downloads_sender_channel:
Option<Sender<(Download, Receiver<DownloadStatus>)>>,
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,
+17 -12
View File
@@ -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
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));
}
}
+2 -5
View File
@@ -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();