Skip to main content

gitwig/tabs/
remotes.rs

1use crate::app::{App, Mode};
2use crate::keybindings::Action;
3use crossterm::event::KeyEvent;
4
5pub struct RemotesTab;
6
7impl RemotesTab {
8    pub fn handle_event(app: &mut App, key: KeyEvent) -> bool {
9        if app.is_bound(Action::RemotesAdd, key) {
10            app.start_remote_add();
11            return true;
12        }
13        if app.is_bound(Action::RemotesDelete, key) {
14            app.request_remote_delete();
15            return true;
16        }
17        if app.is_bound(Action::RemotesFetch, key) {
18            // Open picker if >1 remote, else fetch directly
19            let remote_action =
20                if let Some(crate::repo::ItemDetail::Repo { info, .. }) = &app.current_detail {
21                    if info.remotes.len() > 1 {
22                        Some(None)
23                    } else {
24                        info.remotes.first().map(|r| Some(r.name.clone()))
25                    }
26                } else {
27                    None
28                };
29            match remote_action {
30                Some(Some(name)) => app.fetch_remote(&name),
31                Some(None) => {
32                    app.remote_picker_action = Some(crate::app::RemotePickerAction::FetchRemote);
33                    app.remote_picker_selection = app.branch_list.remote_selection;
34                    app.mode = Mode::RemotePicker;
35                }
36                None => {}
37            }
38            return true;
39        }
40
41        if app.is_bound(Action::DetailMoveUp, key) {
42            app.remote_up();
43            return true;
44        }
45        if app.is_bound(Action::DetailMoveDown, key) {
46            app.remote_down();
47            return true;
48        }
49        if app.is_bound(Action::DetailPageUp, key) {
50            app.remote_page_up(app.config.page_size);
51            return true;
52        }
53        if app.is_bound(Action::DetailPageDown, key) {
54            app.remote_page_down(app.config.page_size);
55            return true;
56        }
57        if app.is_bound(Action::DetailHome, key) {
58            app.remote_to_top();
59            return true;
60        }
61        if app.is_bound(Action::DetailEnd, key) {
62            app.remote_to_bottom();
63            return true;
64        }
65
66        false
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
74
75    #[test]
76    fn test_remotes_tab_events() {
77        let config = crate::config::Config::default();
78        let mut app = crate::app::App::new(config, std::path::PathBuf::from("test.toml"));
79
80        let key_event = |code: KeyCode| KeyEvent::new(code, KeyModifiers::empty());
81
82        // Test navigation boundaries
83        RemotesTab::handle_event(&mut app, key_event(KeyCode::Up));
84        RemotesTab::handle_event(&mut app, key_event(KeyCode::Down));
85        RemotesTab::handle_event(&mut app, key_event(KeyCode::PageUp));
86        RemotesTab::handle_event(&mut app, key_event(KeyCode::PageDown));
87        RemotesTab::handle_event(&mut app, key_event(KeyCode::Home));
88        RemotesTab::handle_event(&mut app, key_event(KeyCode::End));
89    }
90}