feat(tui): folder jumps, open-all and a path filter in the browse popup

A browsed share only moved a row at a time, so a folder of a few
hundred files stood between the user and the next folder. J and K now
jump between folder rows, H and L close or open every folder, and /
filters the whole tree by path the way the results and the room list
filter: type to narrow, Enter keeps it, Esc clears it, then hides. A
folder under a filter shows the paths that match and d downloads just
those. The keys popup gains a browse section and the bar lists them.
This commit is contained in:
Michel de Graaf
2026-09-08 11:24:41 +02:00
parent 0931bb01b4
commit b8da8668b4
7 changed files with 430 additions and 65 deletions
+36 -11
View File
@@ -98,6 +98,18 @@ const HELP_RIGHT: &[(&str, &[(&str, &str)])] = &[
("Tab / Shift-Tab", "next room, chat or user"),
],
),
(
"Browse popup",
&[
("← → / h l", "close / open a folder, or step out / in"),
("J K", "next / previous folder"),
("H L", "close / open every folder"),
("/", "filter by path, Enter keeps it, Esc clears"),
("Enter", "open a folder, or download a file"),
("d", "download a file, or a folder's files"),
("r", "ask again after a timeout"),
],
),
];
impl MainTui {
@@ -551,17 +563,30 @@ impl MainTui {
} else if self.state.show_rooms {
self.rooms_shortcuts()
} else if self.state.show_browse {
vec![
("↑↓", "move"),
("PgUp/PgDn", "page"),
("→←", "expand/collapse"),
("Enter", "open/download"),
("d", "download folder"),
("Tab", "switch user"),
("r", "retry"),
("w", "close tab"),
("Esc", "hide"),
]
if self.state.browse.active_tab().is_some_and(|b| b.filtering) {
// Typing goes to the filter, so no letter keys are on offer.
vec![
("Type", "filter"),
("↑/↓", "navigate"),
("PgUp/PgDn", "page"),
("Enter", "keep filter"),
("Esc", "clear filter"),
]
} else {
vec![
("↑↓", "move"),
("J/K", "next/prev folder"),
("→←", "expand/collapse"),
("H/L", "collapse/expand all"),
("/", "filter"),
("Enter", "open/download"),
("d", "download folder"),
("Tab", "switch user"),
("r", "retry"),
("w", "close tab"),
("Esc", "hide"),
]
}
} else if self.state.command_bar_active {
match self.state.command_bar_mode {
CommandBarMode::Search => vec![