feat: settings popup and uploads in the transfers pane

Press 'o' for a settings popup: edit the download folder, add/remove
share paths (applied live via a rescan and persisted to config.toml),
and force a re-index with 'r' for files changed on disk. The state
machine is unit-tested; feedback shows the shared file/folder counts.

The downloads pane is now Downloads/Uploads: uploads being served are
listed after downloads with an up-arrow marker, live progress, and
status; 'x' cancels an in-progress upload. Client::shared_counts exposes
the index size for the status line.
This commit is contained in:
michel
2026-07-20 20:56:39 +02:00
parent 4936d4dd2a
commit 724796c1eb
10 changed files with 533 additions and 19 deletions
+18 -12
View File
@@ -29,6 +29,11 @@ impl MainTui {
return self.handle_rooms_input(key);
}
// Settings popup takes over navigation while open.
if self.state.settings.is_some() {
return self.handle_settings_input(key);
}
// Filter mode in Results pane
if self.state.results_is_filtering
&& self.state.focused_pane == FocusedPane::Results
@@ -81,6 +86,10 @@ impl MainTui {
self.start_rooms();
return;
}
KeyCode::Char('o') => {
self.open_settings();
return;
}
KeyCode::Char('b') => {
// From a highlighted search result, browse its owner directly;
// otherwise prompt for a username.
@@ -361,27 +370,24 @@ impl MainTui {
}
fn handle_downloads_input(&mut self, key: KeyEvent) {
// The pane lists downloads first, then uploads; navigation spans both.
let rows = self.state.downloads.len() + self.state.uploads.len();
match key.code {
KeyCode::Up | KeyCode::Char('k')
if !self.state.downloads.is_empty() =>
{
KeyCode::Up | KeyCode::Char('k') if rows > 0 => {
let current =
self.state.downloads_table_state.selected().unwrap_or(0);
let new = if current == 0 {
self.state.downloads.len() - 1
} else {
current - 1
};
let new = if current == 0 { rows - 1 } else { current - 1 };
self.state.downloads_table_state.select(Some(new));
}
KeyCode::Down | KeyCode::Char('j')
if !self.state.downloads.is_empty() =>
{
KeyCode::Down | KeyCode::Char('j') if rows > 0 => {
let current =
self.state.downloads_table_state.selected().unwrap_or(0);
let new = (current + 1) % self.state.downloads.len();
let new = (current + 1) % rows;
self.state.downloads_table_state.select(Some(new));
}
KeyCode::Char('x') => {
self.cancel_selected_upload();
}
KeyCode::Char('p') => {
self.toggle_selected_download_pause();
}