fix(tui): make browse retry work and de-jargon the copy

- Retry actually retries: 'r' in the browse popup re-requests a
  timed-out user (previously the 'Press b to retry' hint did nothing —
  b wasn't handled inside the popup). BrowseTabs::retry_active is
  unit-tested.
- Friendlier timeout copy that explains the likely cause: "Couldn't
  reach <user>. They may be offline, or their connection can't be
  reached (both of you may be behind a router/firewall). Press r to try
  again."
- Replace protocol terminology in user-facing labels: 'Peer slots' ->
  'Free slots', 'Peer upload speed' -> 'Upload speed'.
This commit is contained in:
michel
2026-07-19 20:49:32 +02:00
parent 1b62d218dd
commit e59c2bc199
4 changed files with 50 additions and 6 deletions
+28
View File
@@ -371,6 +371,20 @@ impl BrowseTabs {
}
}
/// Retry the active tab if it timed out: reset it to loading and return the
/// username so the caller can re-issue the request. Returns `None` if the
/// active tab isn't in a retryable (timed-out) state.
pub fn retry_active(&mut self) -> Option<String> {
let tab = self.tabs.get_mut(self.active)?;
if tab.status == BrowseStatus::TimedOut {
let username = tab.username.clone();
*tab = BrowseState::loading(username.clone());
Some(username)
} else {
None
}
}
/// Close the active tab, returning `false` when no tabs remain.
pub fn close_active(&mut self) -> bool {
if self.active < self.tabs.len() {
@@ -545,6 +559,20 @@ mod tests {
assert_eq!(tabs.active_tab().unwrap().status, BrowseStatus::Loading);
}
#[test]
fn browse_tabs_retry_active_only_when_timed_out() {
let mut tabs = BrowseTabs::new();
tabs.open("alice");
// Loading tab isn't retryable.
assert_eq!(tabs.retry_active(), None);
tabs.active_tab_mut().unwrap().status = BrowseStatus::TimedOut;
// Timed-out tab retries and resets to loading.
assert_eq!(tabs.retry_active().as_deref(), Some("alice"));
assert_eq!(tabs.active_tab().unwrap().status, BrowseStatus::Loading);
// Now loading again, no further retry.
assert_eq!(tabs.retry_active(), None);
}
#[test]
fn browse_state_load_auto_expands_top_level() {
let mut state = BrowseState::loading("bob".to_string());