fix: two medium bugs from the final adversarial review

- Retry was broken for the common case: retry_selected_download removed
  the failed download only from the UI list, not the client's
  DownloadStore. Since Client::download re-derives the same md5 token
  from the unchanged filename, retrying a still-Failed download left a
  duplicate-token entry; the token-migration path then deleted both,
  misrouting completion so the retried file downloaded to disk but the
  UI showed 'Queued' forever. Add Client::remove_download /
  DownloadStore::remove_by_file (status-agnostic) and clear the stale
  entry before re-issuing. Regression-tested.

- Chat-room member selection could point out of range: RoomEvent::UserLeft
  shrank the active room's member list without clamping user_selected, so
  the highlight silently shifted to the wrong user (or vanished, making
  'b'/'m' no-ops, and blanking the member pane). Clamp user_selected after
  every applied room event. Regression-tested.
This commit is contained in:
michel
2026-07-20 07:26:03 +02:00
parent 2d5fc26db7
commit 6821fd1907
4 changed files with 113 additions and 1 deletions
+5 -1
View File
@@ -1324,9 +1324,13 @@ impl MainTui {
let client = self.client.clone();
let sender = self.state.downloads_sender_channel.clone().unwrap();
// Drop the old failed entry; the retry pushes a fresh one.
// Drop the old failed entry from both the UI list and the client's
// download store; otherwise the stale entry (same md5-derived token and
// filename) shadows the retry and its completion is misrouted, leaving
// the retried download stuck showing "Queued".
self.state.downloads.remove(index);
self.select_download_after_removal(index);
let _ = self.client.remove_download(&username, &filename);
thread::spawn(move || {
match client.download(filename.clone(), username, size, directory) {