par_term/
remote_shell_install_ui.rs1const INSTALL_URL: &str = "https://paulrobello.github.io/par-term/install-shell-integration.sh";
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum RemoteShellInstallAction {
13 Install,
15 Cancel,
17 None,
19}
20
21pub struct RemoteShellInstallUI {
23 visible: bool,
25}
26
27impl Default for RemoteShellInstallUI {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl RemoteShellInstallUI {
34 pub fn new() -> Self {
36 Self { visible: false }
37 }
38
39 pub fn is_visible(&self) -> bool {
41 self.visible
42 }
43
44 pub fn show_dialog(&mut self) {
46 self.visible = true;
47 }
48
49 fn hide(&mut self) {
51 self.visible = false;
52 }
53
54 pub fn install_command() -> String {
56 format!("curl -sSL {} | sh", INSTALL_URL)
57 }
58
59 pub fn show(&mut self, ctx: &egui::Context) -> RemoteShellInstallAction {
61 if !self.visible {
62 return RemoteShellInstallAction::None;
63 }
64
65 let mut action = RemoteShellInstallAction::None;
66 let command = Self::install_command();
67
68 egui::Window::new("Install Shell Integration on Remote Host")
69 .collapsible(false)
70 .resizable(false)
71 .order(egui::Order::Foreground)
72 .anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
73 .show(ctx, |ui| {
74 ui.vertical_centered(|ui| {
75 ui.add_space(10.0);
76
77 ui.label(
78 egui::RichText::new("Send Install Command to Terminal")
79 .size(16.0)
80 .strong(),
81 );
82 ui.add_space(8.0);
83
84 ui.label("This will send the following command to the active terminal:");
85 ui.add_space(8.0);
86
87 egui::Frame::new()
89 .fill(egui::Color32::from_rgba_unmultiplied(40, 40, 40, 220))
90 .inner_margin(egui::Margin::symmetric(12, 8))
91 .corner_radius(4.0)
92 .show(ui, |ui| {
93 ui.label(
94 egui::RichText::new(&command)
95 .color(egui::Color32::LIGHT_GREEN)
96 .monospace()
97 .size(13.0),
98 );
99 });
100
101 ui.add_space(10.0);
102
103 ui.label(
105 egui::RichText::new(
106 "Only use this when SSH'd into a remote host that needs shell integration.",
107 )
108 .color(egui::Color32::YELLOW)
109 .size(12.0),
110 );
111
112 ui.add_space(15.0);
113
114 ui.horizontal(|ui| {
116 let install_button = egui::Button::new(
117 egui::RichText::new("Install").color(egui::Color32::WHITE),
118 )
119 .fill(egui::Color32::from_rgb(50, 120, 50));
120
121 if ui.add(install_button).clicked() {
122 action = RemoteShellInstallAction::Install;
123 }
124
125 ui.add_space(10.0);
126
127 if ui.button("Cancel").clicked() {
128 action = RemoteShellInstallAction::Cancel;
129 }
130 });
131 ui.add_space(10.0);
132 });
133 });
134
135 if ctx.input(|i| i.key_pressed(egui::Key::Escape)) {
137 action = RemoteShellInstallAction::Cancel;
138 }
139
140 if !matches!(action, RemoteShellInstallAction::None) {
142 self.hide();
143 }
144
145 action
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_install_command_format() {
155 let cmd = RemoteShellInstallUI::install_command();
156 assert!(cmd.starts_with("curl"));
157 assert!(cmd.contains("paulrobello.github.io/par-term"));
158 assert!(cmd.contains("install-shell-integration.sh"));
159 assert!(cmd.ends_with("| sh"));
160 }
161
162 #[test]
163 fn test_dialog_initial_state() {
164 let ui = RemoteShellInstallUI::new();
165 assert!(!ui.is_visible());
166 }
167
168 #[test]
169 fn test_dialog_show_hide() {
170 let mut ui = RemoteShellInstallUI::new();
171 assert!(!ui.is_visible());
172
173 ui.show_dialog();
174 assert!(ui.is_visible());
175
176 ui.hide();
177 assert!(!ui.is_visible());
178 }
179
180 #[test]
181 fn test_default_impl() {
182 let ui = RemoteShellInstallUI::default();
183 assert!(!ui.is_visible());
184 }
185}