feat(tui): dismiss a finished download with d
A completed row used to ignore d: only a queued transfer could be pulled out of the list, so a finished one sat there until the next restart. d now goes through one handler that drops a finished row whatever the session thinks of it — a completed transfer can live only in this window, restored from an earlier run, where there is nothing to forget. The finished-status test was spelled out twice in clear_finished_downloads and had to agree by hand; both callers now share is_finished().
This commit is contained in:
@@ -265,7 +265,8 @@ pub fn launch_main_tui(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::daemon::proto::ChatMessageDto;
|
||||
use crate::models::{MessageDirection, SearchStatus};
|
||||
use crate::models::{FocusedPane, MessageDirection, SearchStatus};
|
||||
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
|
||||
/// A stand-in for a daemon: it already holds a conversation, a transfer
|
||||
/// queue, and a search cache, none of which this window created.
|
||||
@@ -291,6 +292,21 @@ mod tests {
|
||||
}
|
||||
|
||||
fn queued(username: &str, filename: &str) -> soulseek_rs::types::Download {
|
||||
at_status(username, filename, soulseek_rs::DownloadStatus::Queued)
|
||||
}
|
||||
|
||||
fn completed(
|
||||
username: &str,
|
||||
filename: &str,
|
||||
) -> soulseek_rs::types::Download {
|
||||
at_status(username, filename, soulseek_rs::DownloadStatus::Completed)
|
||||
}
|
||||
|
||||
fn at_status(
|
||||
username: &str,
|
||||
filename: &str,
|
||||
status: soulseek_rs::DownloadStatus,
|
||||
) -> soulseek_rs::types::Download {
|
||||
let (sender, _) = std::sync::mpsc::channel();
|
||||
soulseek_rs::types::Download {
|
||||
username: username.to_string(),
|
||||
@@ -298,13 +314,17 @@ mod tests {
|
||||
token: 1,
|
||||
size: 4096,
|
||||
download_directory: "/tmp".to_string(),
|
||||
status: soulseek_rs::DownloadStatus::Queued,
|
||||
status,
|
||||
sender,
|
||||
queue_position: None,
|
||||
metadata: soulseek_rs::types::DownloadMetadata::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn key(ch: char) -> KeyEvent {
|
||||
KeyEvent::new(KeyCode::Char(ch), KeyModifiers::NONE)
|
||||
}
|
||||
|
||||
impl SessionApi for TalkativeSession {
|
||||
fn message_history(&self) -> Vec<ChatMessageDto> {
|
||||
self.history.clone()
|
||||
@@ -619,6 +639,43 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn d_clears_a_finished_row_but_not_a_running_one() {
|
||||
// Finished transfers are what a list fills up with after a restart, so
|
||||
// `d` has to be able to dismiss one — restored or not. A running
|
||||
// transfer is not ours to discard, and stays put.
|
||||
let mut tui = with_session(TalkativeSession::default());
|
||||
tui.state.downloads.push(crate::models::DownloadEntry {
|
||||
download: completed("bob", "done.mp3"),
|
||||
receiver: None,
|
||||
});
|
||||
tui.state.downloads_table_state.select(Some(0));
|
||||
tui.state.focused_pane = FocusedPane::Downloads;
|
||||
|
||||
tui.handle_key_event(key('d'));
|
||||
|
||||
assert!(tui.state.downloads.is_empty(), "the row goes too");
|
||||
assert_eq!(tui.state.downloads_table_state.selected(), None);
|
||||
|
||||
tui.state.downloads.push(crate::models::DownloadEntry {
|
||||
download: at_status(
|
||||
"bob",
|
||||
"still.mp3",
|
||||
soulseek_rs::DownloadStatus::InProgress {
|
||||
bytes_downloaded: 1,
|
||||
total_bytes: 2,
|
||||
speed_bytes_per_sec: 1.0,
|
||||
},
|
||||
),
|
||||
receiver: None,
|
||||
});
|
||||
tui.state.downloads_table_state.select(Some(0));
|
||||
|
||||
tui.handle_key_event(key('d'));
|
||||
|
||||
assert_eq!(tui.state.downloads.len(), 1, "it is not disposable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_window_shows_searches_run_in_another() {
|
||||
let mut tui =
|
||||
|
||||
Reference in New Issue
Block a user