Skip to content

Commit 31162ce

Browse files
committed
feat(tui): refine home search activity and settings
1 parent 288a144 commit 31162ce

6 files changed

Lines changed: 474 additions & 91 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ and date are assigned.
2626
- Default-on mouse controls with panel-bounded drag selection, visible
2727
selection feedback, automatic clipboard copy, border removal, and wrapped
2828
URL cleanup.
29+
- Syntax-like Activity highlighting for timestamps, event types, tool output
30+
streams, successful operations, and failures.
2931

3032
### Changed
3133

@@ -60,6 +62,16 @@ and date are assigned.
6062
replace saved/install queue summaries with the current running-app count.
6163
- Distinguish HOME panel focus from retained selection: only the focused panel
6264
shows the selection arrow, with no reversed white row background.
65+
- Show active HOME installs in bold yellow and prioritize `INSTALLING` over a
66+
stale or pre-existing `INSTALLED` marker.
67+
- Let keyboard navigation move upward from Quick Access into Search and tailor
68+
HOME key hints to the currently focused view or app list.
69+
- Search across all HOME applications regardless of the previous view, clear
70+
view selection while typing, and move into results with Down or Right.
71+
- Replace the unused visible mux preference with persistent mouse controls and
72+
show purpose, scope, limits, and controls for each selected setting.
73+
- Keep install timeouts as an internal safety mechanism with per-app overrides
74+
instead of exposing the fallback duration as a routine user preference.
6375
- Spell out horizontal panel switching and vertical row movement in HOME
6476
keyboard hints instead of using the ambiguous generic `arrows` label.
6577
- Prevent drag selection from combining aligned borders of adjacent panels

src/app/state.rs

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ impl AppState {
314314
}
315315
reconcile_saved_queue(&catalog, &mut saved);
316316
saved.logs.push(timestamp_log("T4E dashboard started"));
317+
let mouse_enabled = saved.settings.mouse_enabled;
317318
Self {
318319
catalog,
319320
workspaces,
@@ -331,7 +332,7 @@ impl AppState {
331332
search_query: String::new(),
332333
search_mode: false,
333334
should_quit: false,
334-
mouse_enabled: true,
335+
mouse_enabled,
335336
mouse_selection: None,
336337
queue: saved.queue,
337338
logs: saved.logs,
@@ -375,6 +376,7 @@ impl AppState {
375376
pub fn handle_key(&mut self, key: KeyEvent) {
376377
if key.modifiers.contains(KeyModifiers::ALT) && key.code == KeyCode::Char('m') {
377378
self.mouse_enabled = !self.mouse_enabled;
379+
self.settings.mouse_enabled = self.mouse_enabled;
378380
self.mouse_selection = None;
379381
self.effects
380382
.push_back(AppEffect::SetMouseCapture(self.mouse_enabled));
@@ -522,9 +524,7 @@ impl AppState {
522524
&& (3..=5).contains(&mouse.row) =>
523525
{
524526
self.mouse_selection = None;
525-
self.home_focus = HomeFocus::AppList;
526-
self.search_mode = true;
527-
self.status = "Search HOME apps".to_string();
527+
self.begin_home_search();
528528
}
529529
MouseEventKind::Down(MouseButton::Left) => {
530530
self.select_list_row(mouse.column, mouse.row)
@@ -615,6 +615,16 @@ impl AppState {
615615
.any(|tag| tag.to_ascii_lowercase().contains(&query))
616616
};
617617

618+
if self.search_mode || !query.is_empty() {
619+
return self
620+
.catalog
621+
.tools
622+
.iter()
623+
.filter(|tool| tool.is_launchable_app())
624+
.filter(matches_query)
625+
.collect();
626+
}
627+
618628
match filter {
619629
HomeFilter::Recent => self
620630
.recents
@@ -1193,6 +1203,12 @@ impl AppState {
11931203

11941204
fn handle_search_key(&mut self, code: KeyCode) {
11951205
match code {
1206+
KeyCode::Down | KeyCode::Right | KeyCode::Enter if self.screen == Screen::Home => {
1207+
self.search_mode = false;
1208+
self.home_focus = HomeFocus::AppList;
1209+
self.home_app_index = 0;
1210+
self.status = format!("Showing search results for {}", self.search_query);
1211+
}
11961212
KeyCode::Esc | KeyCode::Enter => self.search_mode = false,
11971213
KeyCode::Backspace => {
11981214
self.search_query.pop();
@@ -1313,8 +1329,7 @@ impl AppState {
13131329
}
13141330
KeyCode::Enter => self.request_selected_tool_launch(),
13151331
KeyCode::Char('/') => {
1316-
self.home_focus = HomeFocus::AppList;
1317-
self.search_mode = true;
1332+
self.begin_home_search();
13181333
}
13191334
KeyCode::Char('I') => self.queue_selected_tool(),
13201335
KeyCode::Char('U') => self.request_selected_uninstall(),
@@ -1391,7 +1406,7 @@ impl AppState {
13911406
KeyCode::Up | KeyCode::Char('k') => self.move_setting(-1),
13921407
KeyCode::Left | KeyCode::Char('h') => self.adjust_setting(-1),
13931408
KeyCode::Right | KeyCode::Char('l') | KeyCode::Char(' ') => self.adjust_setting(1),
1394-
KeyCode::Enter if self.settings_index == 4 => self.reset_saved_preferences(),
1409+
KeyCode::Enter if self.settings_index == 3 => self.reset_saved_preferences(),
13951410
_ => {}
13961411
},
13971412
Screen::Help => {}
@@ -1621,7 +1636,7 @@ impl AppState {
16211636
self.workspace_index = index;
16221637
}
16231638
Screen::Agents if index < self.agent_tools().len() => self.agent_index = index,
1624-
Screen::Settings if index < 5 => self.settings_index = index,
1639+
Screen::Settings if index < 4 => self.settings_index = index,
16251640
Screen::AppView
16261641
| Screen::Logs
16271642
| Screen::Home
@@ -1669,6 +1684,10 @@ impl AppState {
16691684
fn move_home_selection(&mut self, delta: isize) {
16701685
match self.home_focus {
16711686
HomeFocus::Views => {
1687+
if delta < 0 && self.home_filter_index == 0 {
1688+
self.begin_home_search();
1689+
return;
1690+
}
16721691
self.home_filter_index =
16731692
move_index(self.home_filter_index, HomeFilter::ALL.len(), delta);
16741693
self.home_app_index = 0;
@@ -1680,8 +1699,18 @@ impl AppState {
16801699
}
16811700
}
16821701

1702+
fn begin_home_search(&mut self) {
1703+
self.home_filter_index = HomeFilter::ALL
1704+
.iter()
1705+
.position(|filter| *filter == HomeFilter::AllApps)
1706+
.unwrap_or_default();
1707+
self.home_app_index = 0;
1708+
self.search_mode = true;
1709+
self.status = "Search all HOME apps".to_string();
1710+
}
1711+
16831712
fn move_setting(&mut self, delta: isize) {
1684-
self.settings_index = move_index(self.settings_index, 5, delta);
1713+
self.settings_index = move_index(self.settings_index, 4, delta);
16851714
}
16861715

16871716
fn queue_selected_tool(&mut self) {
@@ -2437,28 +2466,22 @@ impl AppState {
24372466
}
24382467

24392468
fn adjust_setting(&mut self, delta: isize) {
2440-
if self.settings_index == 4 {
2469+
if self.settings_index == 3 {
24412470
return;
24422471
}
24432472
match self.settings_index {
24442473
0 => {
2445-
const OPTIONS: [&str; 3] = ["tmux", "zellij", "none"];
2446-
let current = OPTIONS
2447-
.iter()
2448-
.position(|value| *value == self.settings.default_mux)
2449-
.unwrap_or_default();
2450-
let next = (current as isize + delta).rem_euclid(OPTIONS.len() as isize) as usize;
2451-
self.settings.default_mux = OPTIONS[next].to_string();
2474+
self.mouse_enabled = !self.mouse_enabled;
2475+
self.settings.mouse_enabled = self.mouse_enabled;
2476+
self.mouse_selection = None;
2477+
self.effects
2478+
.push_back(AppEffect::SetMouseCapture(self.mouse_enabled));
24522479
}
24532480
1 => {
2454-
let next = self.settings.install_timeout_sec as i64 + delta as i64 * 60;
2455-
self.settings.install_timeout_sec = next.clamp(60, 3600) as u64;
2456-
}
2457-
2 => {
24582481
let next = self.settings.max_install_attempts as isize + delta;
24592482
self.settings.max_install_attempts = next.clamp(1, 5) as u32;
24602483
}
2461-
3 => {
2484+
2 => {
24622485
self.settings.confirm_all_installs = !self.settings.confirm_all_installs;
24632486
}
24642487
_ => {}
@@ -2468,6 +2491,10 @@ impl AppState {
24682491

24692492
fn reset_saved_preferences(&mut self) {
24702493
self.settings = UserSettings::default();
2494+
self.mouse_enabled = self.settings.mouse_enabled;
2495+
self.mouse_selection = None;
2496+
self.effects
2497+
.push_back(AppEffect::SetMouseCapture(self.mouse_enabled));
24712498
self.launch_preferences.clear();
24722499
self.status = "Runtime settings and saved app options reset".to_string();
24732500
self.logs.push(timestamp_log(

0 commit comments

Comments
 (0)