Skip to main content

max / makenotwork

5.3 KB · 131 lines History Blame Raw
1 //! keys-screen key-input handler (split out of tui/input.rs).
2
3 use super::{
4 App, AppEvent, ConfirmAction, DataPayload, KeyCode, KeyEvent, MnwApiClient, Screen,
5 load_item_detail, load_license_keys, mpsc,
6 };
7
8 pub(crate) async fn handle_keys_input(
9 key: KeyEvent,
10 app: &mut App,
11 screen: &mut Screen,
12 api: &MnwApiClient,
13 tx: &mpsc::Sender<AppEvent>,
14 ) {
15 // Cancel pending confirmation on any key other than the confirmation key
16 if app.confirm_action.is_some() && !matches!(key.code, KeyCode::Char('x' | 'X')) {
17 app.confirm_action = None;
18 app.keys_status = None;
19 }
20
21 match key.code {
22 KeyCode::Char('j') | KeyCode::Down => app.move_down(screen),
23 KeyCode::Char('k') | KeyCode::Up => app.move_up(screen),
24 KeyCode::Esc => {
25 if let Screen::Keys(pidx, item_id) = &*screen {
26 let pidx = *pidx;
27 let iid = item_id.clone();
28 *screen = Screen::Item(pidx, iid.clone());
29 app.license_keys.clear();
30 app.keys_status = None;
31 app.selected_index = 0;
32 app.loading = true;
33
34 let api = api.clone();
35 let user_id = app.user.user_id.clone();
36 let tx = tx.clone();
37 tokio::spawn(async move {
38 load_item_detail(&api, &user_id, &iid, &tx).await;
39 });
40 }
41 }
42 KeyCode::Char('g' | 'G') => {
43 if let Screen::Keys(_, item_id) = &*screen {
44 let item_id = item_id.clone();
45 let api = api.clone();
46 let user_id = app.user.user_id.clone();
47 let tx = tx.clone();
48 app.keys_status = Some("Generating...".to_string());
49 let iid = item_id.clone();
50 tokio::spawn(async move {
51 match api.generate_license_key(&user_id, &item_id).await {
52 Ok(key) => {
53 let _ = tx
54 .send(AppEvent::DataLoaded(DataPayload::GenericSuccess {
55 message: format!("Generated: {}", key.key_code),
56 }))
57 .await;
58 load_license_keys(&api, &user_id, &iid, &tx).await;
59 }
60 Err(e) => {
61 let _ = tx
62 .send(AppEvent::DataLoaded(DataPayload::GenericError {
63 error: e.to_string(),
64 }))
65 .await;
66 }
67 }
68 });
69 }
70 }
71 KeyCode::Char('x' | 'X') if !app.license_keys.is_empty() => {
72 let idx = app.selected_index;
73 if matches!(app.confirm_action, Some(ConfirmAction::RevokeLicenseKey { key_idx }) if key_idx == idx)
74 {
75 // Confirmed — execute revoke
76 app.confirm_action = None;
77 let key_id = app.license_keys[idx].id.clone();
78 let key_code = app.license_keys[idx].key_code.clone();
79 let user_id = app.user.user_id.clone();
80 tracing::info!(
81 user_id = %user_id,
82 key_id = %key_id,
83 key_code = %key_code,
84 "revoke license key confirmed"
85 );
86 if let Screen::Keys(_, item_id) = &*screen {
87 let item_id = item_id.clone();
88 let api = api.clone();
89 let user_id = app.user.user_id.clone();
90 let tx = tx.clone();
91 app.keys_status = Some("Revoking...".to_string());
92 tokio::spawn(async move {
93 match api.revoke_license_key(&user_id, &key_id).await {
94 Ok(()) => {
95 load_license_keys(&api, &user_id, &item_id, &tx).await;
96 }
97 Err(e) => {
98 let _ = tx
99 .send(AppEvent::DataLoaded(DataPayload::GenericError {
100 error: e.to_string(),
101 }))
102 .await;
103 }
104 }
105 });
106 }
107 } else {
108 // First press — ask for confirmation
109 app.confirm_action = Some(ConfirmAction::RevokeLicenseKey { key_idx: idx });
110 app.keys_status = Some(format!(
111 "Revoke '{}'? Press x again to confirm",
112 app.license_keys[idx].key_code
113 ));
114 }
115 }
116 KeyCode::Char('r' | 'R') => {
117 if let Screen::Keys(_, item_id) = &*screen {
118 app.loading = true;
119 let item_id = item_id.clone();
120 let api = api.clone();
121 let user_id = app.user.user_id.clone();
122 let tx = tx.clone();
123 tokio::spawn(async move {
124 load_license_keys(&api, &user_id, &item_id, &tx).await;
125 });
126 }
127 }
128 _ => {}
129 }
130 }
131