feat: browse the highlighted transfer's user with b
In the Downloads / Uploads pane, b now opens the share of whoever owns the selected download or upload, the way it already browses the owner of a highlighted result. With no row selected it still prompts.
This commit is contained in:
@@ -206,6 +206,21 @@ impl MainTui {
|
||||
self.state.results_selected_indices.clear();
|
||||
}
|
||||
|
||||
/// The user behind the highlighted transfer, download or upload.
|
||||
pub(super) fn selected_transfer_user(&self) -> Option<String> {
|
||||
match selected_transfer(
|
||||
self.state.downloads_table_state.selected(),
|
||||
&self.state.downloads,
|
||||
&self.state.uploads,
|
||||
) {
|
||||
Some(InfoSubject::Download(entry)) => {
|
||||
Some(entry.download.username.clone())
|
||||
}
|
||||
Some(InfoSubject::Upload(upload)) => Some(upload.username.clone()),
|
||||
Some(InfoSubject::Result(_)) | None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn cancel_selected_transfer(&self) {
|
||||
let selected = selected_transfer(
|
||||
self.state.downloads_table_state.selected(),
|
||||
|
||||
@@ -151,6 +151,10 @@ impl MainTui {
|
||||
&& let Some(owner) = self.highlighted_result_owner()
|
||||
{
|
||||
self.start_browse(owner);
|
||||
} else if self.state.focused_pane == FocusedPane::Downloads
|
||||
&& let Some(user) = self.selected_transfer_user()
|
||||
{
|
||||
self.start_browse(user);
|
||||
} else {
|
||||
self.state.command_bar_active = true;
|
||||
self.state.command_bar_mode = CommandBarMode::Browse;
|
||||
|
||||
@@ -310,6 +310,20 @@ mod tests {
|
||||
at_status(username, filename, soulseek_rs::DownloadStatus::Completed)
|
||||
}
|
||||
|
||||
fn uploading(
|
||||
username: &str,
|
||||
filename: &str,
|
||||
) -> soulseek_rs::types::UploadInfo {
|
||||
soulseek_rs::types::UploadInfo {
|
||||
username: username.to_string(),
|
||||
filename: filename.to_string(),
|
||||
size: 10,
|
||||
bytes_sent: 1,
|
||||
speed_bytes_per_sec: 1.0,
|
||||
status: soulseek_rs::types::UploadStatus::InProgress,
|
||||
}
|
||||
}
|
||||
|
||||
fn at_status(
|
||||
username: &str,
|
||||
filename: &str,
|
||||
@@ -654,14 +668,7 @@ mod tests {
|
||||
download: queued("bob", "song.mp3"),
|
||||
receiver: None,
|
||||
});
|
||||
tui.state.uploads.push(soulseek_rs::types::UploadInfo {
|
||||
username: "alice".to_string(),
|
||||
filename: "served.mp3".to_string(),
|
||||
size: 10,
|
||||
bytes_sent: 1,
|
||||
speed_bytes_per_sec: 1.0,
|
||||
status: soulseek_rs::types::UploadStatus::InProgress,
|
||||
});
|
||||
tui.state.uploads.push(uploading("alice", "served.mp3"));
|
||||
tui.state.downloads_table_state.select(Some(1));
|
||||
tui.state.focused_pane = FocusedPane::Downloads;
|
||||
|
||||
@@ -677,6 +684,45 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn b_browses_the_user_of_the_highlighted_download() {
|
||||
let mut tui = with_session(TalkativeSession::default());
|
||||
tui.state.downloads.push(crate::models::DownloadEntry {
|
||||
download: queued("bob", "song.mp3"),
|
||||
receiver: None,
|
||||
});
|
||||
tui.state.downloads_table_state.select(Some(0));
|
||||
tui.state.focused_pane = FocusedPane::Downloads;
|
||||
|
||||
tui.handle_key_event(key('b'));
|
||||
|
||||
assert!(tui.state.show_browse, "the browse popup opens");
|
||||
assert_eq!(
|
||||
tui.state.browse.active_tab().map(|b| b.username.as_str()),
|
||||
Some("bob"),
|
||||
"the download's user is the one browsed"
|
||||
);
|
||||
assert!(
|
||||
!tui.state.command_bar_active,
|
||||
"b on a transfer goes straight to the user, not the prompt"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn b_on_an_upload_row_browses_that_user() {
|
||||
let mut tui = with_session(TalkativeSession::default());
|
||||
tui.state.uploads.push(uploading("alice", "served.mp3"));
|
||||
tui.state.downloads_table_state.select(Some(0));
|
||||
tui.state.focused_pane = FocusedPane::Downloads;
|
||||
|
||||
tui.handle_key_event(key('b'));
|
||||
|
||||
assert_eq!(
|
||||
tui.state.browse.active_tab().map(|b| b.username.as_str()),
|
||||
Some("alice")
|
||||
);
|
||||
}
|
||||
|
||||
fn with_session(session: TalkativeSession) -> MainTui {
|
||||
attach(Arc::new(session))
|
||||
}
|
||||
@@ -1591,9 +1637,11 @@ mod tests {
|
||||
let screen = screen_sized(&mut tui, 80, 24);
|
||||
assert!(screen.contains("Tab / Shift-Tab"), "{screen}");
|
||||
|
||||
// A wide window shows both columns at once, nothing to scroll.
|
||||
// A wide window shows both columns at once, nothing to scroll. It
|
||||
// has to be tall enough to hold the taller column outright; in a
|
||||
// shorter one End follows the tail and the headings scroll off.
|
||||
press(&mut tui, KeyCode::End);
|
||||
let screen = screen_of(&mut tui);
|
||||
let screen = screen_sized(&mut tui, 160, 44);
|
||||
let panes = row_with(&screen, "Panes");
|
||||
assert!(panes.contains("Searches"), "two columns: {panes}");
|
||||
assert!(screen.contains("Tab / Shift-Tab"), "{screen}");
|
||||
|
||||
@@ -89,6 +89,7 @@ const HELP_RIGHT: &[(&str, &[(&str, &str)])] = &[
|
||||
("r", "retry a failed one"),
|
||||
("d", "delete a queued or finished one"),
|
||||
("c", "clear every finished one"),
|
||||
("b", "browse that user"),
|
||||
],
|
||||
),
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user