feat: add download info pane to TUI

Splits the downloads area 60/40 with a new info pane that adapts to the
selected download's status: header (filename, user, size, status, save
path, bitrate, length) plus queued-specific fields (queue position, peer
slots, peer upload speed) or live progress/speed/ETA when transferring.

Plumbs queue position via a new ClientOperation::PlaceInQueueUpdate so
PlaceInQueueResponse messages from peers reach DownloadStore, and threads
search-time metadata (bitrate, length, peer slots/speed) onto Download
through a new download_with_metadata entry point.
This commit is contained in:
michel
2026-04-26 17:19:26 +02:00
parent fa962a0dea
commit 574833bf61
12 changed files with 454 additions and 29 deletions
+2 -14
View File
@@ -1,4 +1,3 @@
use std::env;
use std::fs;
use std::io::{self, Read, Write};
use std::net::TcpStream;
@@ -12,6 +11,7 @@ use crate::client::ClientContext;
use crate::message::server::MessageFactory;
use crate::trace;
use crate::types::{Download, DownloadStatus};
use crate::utils::path::expand_tilde;
const START_DOWNLOAD: [u8; 8] =
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
@@ -72,18 +72,6 @@ impl From<io::Error> for DownloadError {
struct FileManager;
impl FileManager {
fn expand_path(path: &str) -> PathBuf {
if let Some(stripped) = path.strip_prefix('~') {
if let Ok(home) = env::var("HOME") {
PathBuf::from(home).join(stripped.trim_start_matches('/'))
} else {
PathBuf::from(path)
}
} else {
PathBuf::from(path)
}
}
fn extract_filename_from_path(full_path: &str) -> &str {
full_path
.split(['/', '\\'])
@@ -414,7 +402,7 @@ impl DownloadPeer {
download: &Download,
) -> Result<String, DownloadError> {
let download_directory = &download.download_directory;
let mut expanded_path = FileManager::expand_path(download_directory);
let mut expanded_path = expand_tilde(download_directory);
if !expanded_path.is_dir() {
expanded_path = expanded_path