Skip to main content

purple_ssh/app/
pickers.rs

1//! Overlay picker lifecycle. Implements `impl App` continuation with
2//! open/close domain actions for every `.open`-flag-based picker overlay
3//! (password, key, proxyjump, vault_role, region). Screen-based pickers
4//! (TagPicker, ThemePicker, SnippetPicker, etc.) live in `selection.rs`.
5
6use ratatui::widgets::ListState;
7
8use crate::app::App;
9
10impl App {
11    /// Close the password picker overlay.
12    pub fn close_password_picker(&mut self) {
13        log::debug!("[purple] close_password_picker");
14        self.ui.password_picker.open = false;
15    }
16
17    /// Close the key picker overlay.
18    pub fn close_key_picker(&mut self) {
19        log::debug!("[purple] close_key_picker");
20        self.ui.key_picker.open = false;
21    }
22
23    /// Close the ProxyJump picker overlay.
24    pub fn close_proxyjump_picker(&mut self) {
25        log::debug!("[purple] close_proxyjump_picker");
26        self.ui.proxyjump_picker.open = false;
27    }
28
29    /// Close the Vault SSH role picker overlay.
30    pub fn close_vault_role_picker(&mut self) {
31        log::debug!("[purple] close_vault_role_picker");
32        self.ui.vault_role_picker.open = false;
33    }
34
35    /// Close the provider region picker overlay.
36    pub fn close_region_picker(&mut self) {
37        log::debug!("[purple] close_region_picker");
38        self.ui.region_picker.open = false;
39    }
40
41    /// Open the password picker overlay focused on the first source.
42    pub fn open_password_picker(&mut self) {
43        log::debug!("[purple] open_password_picker");
44        self.ui.password_picker.open = true;
45        self.ui.password_picker.list = ListState::default();
46        self.ui.password_picker.list.select(Some(0));
47    }
48
49    /// Open the key picker overlay. Rescans `~/.ssh` first so the list
50    /// reflects keys added since the form was opened, then selects the
51    /// first key when at least one was discovered.
52    pub fn open_key_picker(&mut self) {
53        log::debug!("[purple] open_key_picker");
54        self.scan_keys();
55        self.ui.key_picker.open = true;
56        self.ui.key_picker.list = ListState::default();
57        if !self.keys.list.is_empty() {
58            self.ui.key_picker.list.select(Some(0));
59        }
60    }
61
62    /// Open the ProxyJump picker overlay. The opening cursor lands on the
63    /// first host row rather than the first list entry, so separator/header
64    /// rows above the host list do not steal initial focus.
65    pub fn open_proxyjump_picker(&mut self) {
66        log::debug!("[purple] open_proxyjump_picker");
67        self.ui.proxyjump_picker.open = true;
68        self.ui.proxyjump_picker.list = ListState::default();
69        if let Some(idx) = self.proxyjump_first_host_index() {
70            self.ui.proxyjump_picker.list.select(Some(idx));
71        }
72    }
73
74    /// Open the Vault SSH role picker. The caller is responsible for
75    /// guarding against an empty candidate list; this method assumes at
76    /// least one role and selects the first.
77    pub fn open_vault_role_picker(&mut self) {
78        log::debug!("[purple] open_vault_role_picker");
79        self.ui.vault_role_picker.open = true;
80        self.ui.vault_role_picker.list = ListState::default();
81        self.ui.vault_role_picker.list.select(Some(0));
82    }
83
84    /// Open the provider region picker overlay with the cursor on the
85    /// first row. Region picker uses a `cursor: usize` rather than a
86    /// ratatui `ListState` because its rows are a synthetic flat array.
87    pub fn open_region_picker(&mut self) {
88        log::debug!("[purple] open_region_picker");
89        self.ui.region_picker.open = true;
90        self.ui.region_picker.cursor = 0;
91    }
92}