atac 0.11.2

Arguably a Terminal API Client. Feature-full, free, open-source, offline and account-less.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
use crossterm::event;
use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers};
use tui_textarea::CursorMove;
use crate::app::app::{App};
use crate::app::app_states::AppState;
use crate::app::ui::param_tabs::param_tabs::RequestParamsTabs;

impl App<'_> {
    /// Handle events
    pub async fn handle_events(&mut self) {
        // Refreshes the app every tick_rate
        if event::poll(self.tick_rate).unwrap() {
            // Default state
            self.display_full_help = false;
            
            // Block while a key is pressed
            if let Event::Key(key) = event::read().unwrap() {
                let mut miss_input = false;

                let previous_app_state = self.state;
                let control_pressed: bool = key.modifiers == KeyModifiers::CONTROL;
                let shift_pressed: bool = key.modifiers == KeyModifiers::SHIFT;

                // Debug tool
                //println!("{:?} {:?}", key.modifiers, key.code);

                if key.kind == KeyEventKind::Press {
                    match self.state {
                        AppState::Normal => match key.code {
                            KeyCode::Char('c') if control_pressed => self.should_quit = true,
                            KeyCode::Char('q') => self.should_quit = true,

                            KeyCode::Up if control_pressed => self.move_request_up(),
                            KeyCode::Down if control_pressed => self.move_request_down(),

                            KeyCode::Up => self.collections_tree.up(),
                            KeyCode::Down => self.collections_tree.down(),
                            KeyCode::Left => self.unselect_request(),
                            KeyCode::Right => {
                                self.collections_tree.state.toggle_selected();
                            },
                            KeyCode::Enter => self.select_request_or_expand_collection(),

                            KeyCode::Char('e') => self.next_environment(),

                            KeyCode::Char('c') => self.display_cookies_state(),
                            
                            KeyCode::Char('n') => self.create_new_element_state(),
                            KeyCode::Char('d') => self.delete_element(),
                            KeyCode::Char('r') => self.rename_element(),
                            
                            KeyCode::Char('h') => self.display_full_help = true,

                            _ => miss_input = true
                        },
                        
                        /* Cookies */
                        
                        AppState::DisplayingCookies => match key.code {
                            KeyCode::Esc => self.normal_state(),
                            //KeyCode::Enter if !control_pressed && self.cookies_popup.cookies_table.is_selected() => self.edit_cookie_state(),

                            KeyCode::Up => self.cookies_popup.cookies_table.up(),
                            KeyCode::Down => self.cookies_popup.cookies_table.down(),
                            KeyCode::Left => self.cookies_popup.cookies_table.left(),
                            KeyCode::Right => self.cookies_popup.cookies_table.right(),

                            //KeyCode::Char('n') => self.create_new_cookie(),
                            KeyCode::Char('d') => self.delete_cookie(),

                            _ => {}
                        },

                        AppState::EditingCookies => match key.code {
                            KeyCode::Char(char) => self.cookies_popup.cookies_table.selection_text_input.enter_char(char),

                            KeyCode::Esc => self.display_cookies_state(),
                            KeyCode::Enter => self.modify_cookie(),

                            KeyCode::Delete => self.cookies_popup.cookies_table.selection_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.cookies_popup.cookies_table.selection_text_input.delete_char_backward(),
                            KeyCode::Left => self.cookies_popup.cookies_table.selection_text_input.move_cursor_left(),
                            KeyCode::Right => self.cookies_popup.cookies_table.selection_text_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        /* Collections */

                        AppState::ChoosingElementToCreate => match key.code {
                            KeyCode::Esc => self.normal_state(),

                            KeyCode::Enter if !self.creation_popup.state => self.create_new_collection_state(),
                            KeyCode::Enter if self.creation_popup.state => self.create_new_request_state(),

                            KeyCode::Left => self.creation_popup.change_state(),
                            KeyCode::Right => self.creation_popup.change_state(),

                            _ => miss_input = true
                        },

                        AppState::CreatingNewCollection => match key.code {
                            KeyCode::Char(char) => self.new_collection_input.enter_char(char),

                            KeyCode::Esc => self.normal_state(),
                            KeyCode::Enter => self.new_collection(),

                            KeyCode::Delete => self.new_collection_input.delete_char_forward(),
                            KeyCode::Backspace => self.new_collection_input.delete_char_backward(),
                            KeyCode::Left => self.new_collection_input.move_cursor_left(),
                            KeyCode::Right => self.new_collection_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        AppState::CreatingNewRequest => match key.code {
                            KeyCode::Char(char) => self.new_request_popup.text_input.enter_char(char),

                            KeyCode::Esc => self.normal_state(),
                            KeyCode::Enter => self.new_request(),

                            KeyCode::Delete => self.new_request_popup.text_input.delete_char_forward(),
                            KeyCode::Backspace => self.new_request_popup.text_input.delete_char_backward(),
                            KeyCode::Left => self.new_request_popup.text_input.move_cursor_left(),
                            KeyCode::Right => self.new_request_popup.text_input.move_cursor_right(),

                            KeyCode::Up => self.new_request_popup.previous_collection(),
                            KeyCode::Down => self.new_request_popup.next_collection(),

                            _ => miss_input = true
                        },

                        AppState::DeletingCollection => match key.code {
                            KeyCode::Esc => self.normal_state(),

                            KeyCode::Enter if self.delete_collection_popup.state => self.delete_collection(),
                            KeyCode::Enter if !self.delete_collection_popup.state => self.normal_state(),

                            KeyCode::Left => self.delete_collection_popup.change_state(),
                            KeyCode::Right => self.delete_collection_popup.change_state(),

                            _ => miss_input = true
                        },

                        AppState::DeletingRequest => match key.code {
                            KeyCode::Esc => self.normal_state(),

                            KeyCode::Enter if self.delete_request_popup.state => self.delete_request(),
                            KeyCode::Enter if !self.delete_request_popup.state => self.normal_state(),

                            KeyCode::Left => self.delete_request_popup.change_state(),
                            KeyCode::Right => self.delete_request_popup.change_state(),

                            _ => miss_input = true
                        },

                        AppState::RenamingCollection => match key.code {
                            KeyCode::Char(char) => self.rename_collection_input.enter_char(char),

                            KeyCode::Esc => self.normal_state(),
                            KeyCode::Enter => self.rename_collection(),

                            KeyCode::Delete => self.rename_collection_input.delete_char_forward(),
                            KeyCode::Backspace => self.rename_collection_input.delete_char_backward(),
                            KeyCode::Left => self.rename_collection_input.move_cursor_left(),
                            KeyCode::Right => self.rename_collection_input.move_cursor_right(),

                            _ => miss_input = true
                        },
                        
                        AppState::RenamingRequest => match key.code {
                            KeyCode::Char(char) => self.rename_request_input.enter_char(char),

                            KeyCode::Esc => self.normal_state(),
                            KeyCode::Enter => self.rename_request(),

                            KeyCode::Delete => self.rename_request_input.delete_char_forward(),
                            KeyCode::Backspace => self.rename_request_input.delete_char_backward(),
                            KeyCode::Left => self.rename_request_input.move_cursor_left(),
                            KeyCode::Right => self.rename_request_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        /* Request */
                        /* /!\ Below, consider that a request has been selected /!\ */

                        AppState::SelectedRequest => {
                            // Param tabs
                            match self.request_param_tab {
                                RequestParamsTabs::QueryParams => match key.code {
                                    KeyCode::Enter if !control_pressed && self.query_params_table.is_selected() => self.edit_request_param_state(),

                                    KeyCode::Up => self.query_params_table.up(),
                                    KeyCode::Down => self.query_params_table.down(),
                                    KeyCode::Left | KeyCode::Right => self.query_params_table.change_y(),

                                    KeyCode::Char('n') => self.create_new_query_param(),
                                    KeyCode::Char('d') => self.delete_query_param(),
                                    KeyCode::Char('t') => self.toggle_query_param(),

                                    _ => {}
                                },
                                RequestParamsTabs::Auth if self.auth_text_input_selection.usable => match key.code {
                                    KeyCode::Enter if !control_pressed => self.select_request_auth_input_text(),

                                    KeyCode::Up => self.auth_text_input_selection.previous(),
                                    KeyCode::Down => self.auth_text_input_selection.next(),

                                    _ => {}
                                }
                                RequestParamsTabs::Headers => match key.code {
                                    KeyCode::Enter if !control_pressed && self.headers_table.is_selected() => self.edit_request_header_state(),

                                    KeyCode::Up => self.headers_table.up(),
                                    KeyCode::Down => self.headers_table.down(),
                                    KeyCode::Left | KeyCode::Right => self.headers_table.change_y(),

                                    KeyCode::Char('n') => self.create_new_header(),
                                    KeyCode::Char('d') => self.delete_header(),
                                    KeyCode::Char('t') => self.toggle_header(),

                                    _ => {}
                                },
                                RequestParamsTabs::Body => match key.code {
                                    KeyCode::Enter if !control_pressed && self.body_form_table.is_selected() => self.edit_request_body_table_state(),
                                    KeyCode::Enter if !control_pressed => self.edit_request_body_string_state(),

                                    KeyCode::Up => self.body_form_table.up(),
                                    KeyCode::Down => self.body_form_table.down(),
                                    KeyCode::Left | KeyCode::Right => self.body_form_table.change_y(),

                                    KeyCode::Char('n') => self.create_new_form_data(),
                                    KeyCode::Char('d') => self.delete_form_data(),
                                    KeyCode::Char('t') => self.toggle_form_data(),

                                    _ => {}
                                },
                                _ => {}
                            }

                            match key.code {
                                KeyCode::Esc => self.normal_state(),

                                KeyCode::Char('c') => self.display_cookies_state(),
                                KeyCode::Char('e') => self.next_environment(),

                                KeyCode::Char('h') => self.display_full_help = true,

                                //KeyCode::Char('p') => self.load_request_query_params_tab(),

                                KeyCode::Char('a') if control_pressed => self.modify_request_auth(),
                                //KeyCode::Char('a') => self.load_request_auth_param_tab(),

                                //KeyCode::Char('h') => self.load_request_headers_tab(),

                                KeyCode::Char('b') if control_pressed => self.modify_request_content_type(),
                                //KeyCode::Char('b') => self.load_request_body_param_tab(),

                                KeyCode::Char('u') => self.edit_request_url_state(),
                                KeyCode::Char('m') => self.modify_request_method(),

                                KeyCode::Char('s') => self.edit_request_settings_state(),

                                KeyCode::Up if control_pressed => self.result_vertical_scrollbar.page_up(),
                                KeyCode::Down if control_pressed => self.result_vertical_scrollbar.page_down(),
                                KeyCode::Left if control_pressed => self.result_horizontal_scrollbar.page_up(),
                                KeyCode::Right if control_pressed => self.result_horizontal_scrollbar.page_down(),

                                KeyCode::BackTab if shift_pressed => self.next_request_view(),
                                KeyCode::Tab if control_pressed => self.next_request_result_tab(),
                                KeyCode::Tab => self.next_request_param_tab(),

                                KeyCode::Enter if control_pressed => self.send_request().await,

                                _ => miss_input = true
                            }
                        },

                        AppState::EditingRequestUrl => match key.code {
                            KeyCode::Char(char) => self.url_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_url(),

                            KeyCode::Delete => self.url_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.url_text_input.delete_char_backward(),
                            KeyCode::Left => self.url_text_input.move_cursor_left(),
                            KeyCode::Right => self.url_text_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        AppState::EditingRequestParam => match key.code {
                            KeyCode::Char(char) => self.query_params_table.selection_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_query_param(),

                            KeyCode::Delete => self.query_params_table.selection_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.query_params_table.selection_text_input.delete_char_backward(),
                            KeyCode::Left => self.query_params_table.selection_text_input.move_cursor_left(),
                            KeyCode::Right => self.query_params_table.selection_text_input.move_cursor_right(),

                            _ => miss_input = true
                        }

                        AppState::EditingRequestAuthUsername => match key.code {
                            KeyCode::Char(char) => self.auth_basic_username_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_auth_basic_username(),

                            KeyCode::Delete => self.auth_basic_username_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.auth_basic_username_text_input.delete_char_backward(),
                            KeyCode::Left => self.auth_basic_username_text_input.move_cursor_left(),
                            KeyCode::Right => self.auth_basic_username_text_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        AppState::EditingRequestAuthPassword => match key.code {
                            KeyCode::Char(char) => self.auth_basic_password_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_auth_basic_password(),

                            KeyCode::Delete => self.auth_basic_password_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.auth_basic_password_text_input.delete_char_backward(),
                            KeyCode::Left => self.auth_basic_password_text_input.move_cursor_left(),
                            KeyCode::Right => self.auth_basic_password_text_input.move_cursor_right(),

                            _ => miss_input = true
                        },

                        AppState::EditingRequestAuthBearerToken => match key.code {
                            KeyCode::Char(char) => self.auth_bearer_token_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_auth_bearer_token(),

                            KeyCode::Delete => self.auth_bearer_token_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.auth_bearer_token_text_input.delete_char_backward(),
                            KeyCode::Left => self.auth_bearer_token_text_input.move_cursor_left(),
                            KeyCode::Right => self.auth_bearer_token_text_input.move_cursor_right(),

                            _ => miss_input = true
                        }

                        AppState::EditingRequestHeader => match key.code {
                            KeyCode::Char(char) => self.headers_table.selection_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_header(),

                            KeyCode::Delete => self.headers_table.selection_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.headers_table.selection_text_input.delete_char_backward(),
                            KeyCode::Left => self.headers_table.selection_text_input.move_cursor_left(),
                            KeyCode::Right => self.headers_table.selection_text_input.move_cursor_right(),

                            _ => miss_input = true
                        }

                        AppState::EditingRequestBodyTable => match key.code {
                            KeyCode::Char(char) => self.body_form_table.selection_text_input.enter_char(char),

                            KeyCode::Esc => self.select_request_state(),
                            KeyCode::Enter => self.modify_request_form_data(),

                            KeyCode::Delete => self.body_form_table.selection_text_input.delete_char_forward(),
                            KeyCode::Backspace => self.body_form_table.selection_text_input.delete_char_backward(),
                            KeyCode::Left => self.body_form_table.selection_text_input.move_cursor_left(),
                            KeyCode::Right => self.body_form_table.selection_text_input.move_cursor_right(),

                            _ => miss_input = true
                        }

                        AppState::EditingRequestBodyString => match key.code {
                            KeyCode::Char('c') if control_pressed => self.body_text_area.copy(),
                            KeyCode::Char('v') if control_pressed => {
                                self.body_text_area.paste();
                            },
                            KeyCode::Char('z') if control_pressed => {
                                self.body_text_area.undo();
                            },
                            KeyCode::Char('y') if control_pressed => {
                                self.body_text_area.redo();
                            },
                            KeyCode::Char('s') if control_pressed => self.modify_request_body(),

                            KeyCode::Char(char) => self.body_text_area.insert_char(char),

                            KeyCode::Esc => self.quit_request_body(),
                            KeyCode::Enter => self.body_text_area.insert_newline(),

                            KeyCode::Tab => {
                                self.body_text_area.set_hard_tab_indent(true);
                                self.body_text_area.insert_tab();
                            },
                            KeyCode::Backspace => {
                                self.body_text_area.delete_char();
                            },
                            KeyCode::Delete => {
                                self.body_text_area.delete_next_char();
                            },

                            KeyCode::Right if control_pressed => self.body_text_area.move_cursor(CursorMove::WordForward),
                            KeyCode::Left if control_pressed => self.body_text_area.move_cursor(CursorMove::WordBack),

                            KeyCode::Up => self.body_text_area.move_cursor(CursorMove::Up),
                            KeyCode::Down => self.body_text_area.move_cursor(CursorMove::Bottom),
                            KeyCode::Right => self.body_text_area.move_cursor(CursorMove::Forward),
                            KeyCode::Left => self.body_text_area.move_cursor(CursorMove::Back),

                            _ => miss_input = true
                        },

                        AppState::EditingRequestSettings => match key.code {
                            KeyCode::Esc => self.select_request_state(),

                            KeyCode::Enter => self.modify_request_settings(),

                            KeyCode::Up => self.request_settings_popup.previous(),
                            KeyCode::Down => self.request_settings_popup.next(),
                            KeyCode::Left => self.request_settings_popup.toggle_setting(),
                            KeyCode::Right => self.request_settings_popup.toggle_setting(),

                            _ => miss_input = true
                        },
                    };

                    if !miss_input {
                        self.write_to_log_file(format!("{:?}", key.modifiers), format!("{:?}", key.code), previous_app_state.to_string());
                    }
                }
            }
        }
    }
}