bhcli

"Strange's fork of n0tr1v's bhcli (onion)"
git clone https://git.dasho.dev/Strange/bhcli.git
Log | Files | Refs | README

commit 90c9fc504346657e67a92046b4e3fa34738681fb
parent a9ea0b6e2c9e6f66ce420b6ebff68bfbe3299e85
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Thu, 30 Mar 2023 23:04:46 -0700

cleanup events

Diffstat:
Msrc/main.rs | 467++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 248 insertions(+), 219 deletions(-)

diff --git a/src/main.rs b/src/main.rs @@ -1319,234 +1319,263 @@ impl LeChatPHPClient { Ok(()) } - fn handle_editing_mode_key_event( - &mut self, - app: &mut App, - key_event: KeyEvent, - users: &Arc<Mutex<Users>>, - ) -> std::result::Result<(), ExitSignal> { - match key_event { - KeyEvent { code: KeyCode::Enter, modifiers: KeyModifiers::NONE, .. } => { - if FIND_RGX.is_match(&app.input) { - return Ok(()); - } + fn handle_editing_mode_key_event_enter(&mut self, app: &mut App) -> std::result::Result<(), ExitSignal> { + if FIND_RGX.is_match(&app.input) { + return Ok(()); + } - let input: String = app.input.drain(..).collect(); - app.input_idx = 0; - if input == "/dl" { - // Delete last message - self.post_msg(PostType::DeleteLast).unwrap(); - } else if let Some(captures) = DLX_RGX.captures(&input) { - // Delete the last X messages - let x: usize = captures.get(1).unwrap().as_str().parse().unwrap(); - for _ in 0..x { - self.post_msg(PostType::DeleteLast).unwrap(); - } - } else if input == "/dall" { - // Delete all messages - self.post_msg(PostType::DeleteAll).unwrap(); - } else if input == "/cycles" { - self.color_tx.send(()).unwrap(); - } else if input == "/cycle1" { - self.start_cycle(true); - } else if input == "/cycle2" { - self.start_cycle(false); - } else if input == "/kall" { - // Kick all guests - let username = "s _".to_owned(); - let msg = "".to_owned(); - self.post_msg(PostType::Kick(msg, username)).unwrap(); - } else if input.starts_with("/m ") { - // Send message to "members" section - let msg = remove_prefix(&input, "/m ").to_owned(); - let to = Some(SEND_TO_MEMBERS.to_owned()); - self.post_msg(PostType::Post(msg, to)).unwrap(); - app.input = "/m ".to_owned(); - app.input_idx = app.input.width() - } else if input.starts_with("/a ") { - // Send message to "admin" section - let msg = remove_prefix(&input, "/a ").to_owned(); - let to = Some(SEND_TO_ADMINS.to_owned()); - self.post_msg(PostType::Post(msg, to)).unwrap(); - app.input = "/a ".to_owned(); - app.input_idx = app.input.width() - } else if input.starts_with("/s ") { - // Send message to "staff" section - let msg = remove_prefix(&input, "/s ").to_owned(); - let to = Some(SEND_TO_STAFFS.to_owned()); - self.post_msg(PostType::Post(msg, to)).unwrap(); - app.input = "/s ".to_owned(); - app.input_idx = app.input.width() - } else if let Some(captures) = PM_RGX.captures(&input) { - // Send PM message - let username = &captures[1]; - let msg = captures[2].to_owned(); - let to = Some(username.to_owned()); - self.post_msg(PostType::Post(msg, to)).unwrap(); - app.input = format!("/pm {} ", username); - app.input_idx = app.input.width() - } else if let Some(captures) = NEW_NICKNAME_RGX.captures(&input) { - // Change nickname - let new_nickname = captures[1].to_owned(); - self.post_msg(PostType::NewNickname(new_nickname)).unwrap(); - } else if let Some(captures) = NEW_COLOR_RGX.captures(&input) { - // Change color - let new_color = captures[1].to_owned(); - self.post_msg(PostType::NewColor(new_color)).unwrap(); - } else if let Some(captures) = KICK_RGX.captures(&input) { - // Kick a user - let username = captures[1].to_owned(); - let msg = captures[2].to_owned(); - self.post_msg(PostType::Kick(msg, username)).unwrap(); - } else if let Some(captures) = IGNORE_RGX.captures(&input) { - // Ignore a user - let username = captures[1].to_owned(); - self.post_msg(PostType::Ignore(username)).unwrap(); - } else if let Some(captures) = UNIGNORE_RGX.captures(&input) { - // Unignore a user - let username = captures[1].to_owned(); - self.post_msg(PostType::Unignore(username)).unwrap(); - } else if let Some(captures) = UPLOAD_RGX.captures(&input) { - // Upload a file - let file_path = captures[1].to_owned(); - let send_to = match captures.get(2) { - Some(to_match) => match to_match.as_str() { - "members" => SEND_TO_MEMBERS, - "staffs" => SEND_TO_STAFFS, - "admins" => SEND_TO_ADMINS, - _ => SEND_TO_ALL, - }, - None => SEND_TO_ALL, - } - .to_owned(); - let msg = match captures.get(3) { - Some(msg_match) => msg_match.as_str().to_owned(), - None => "".to_owned(), - }; - self.post_msg(PostType::Upload(file_path, send_to, msg)) - .unwrap(); - } else { - // Send normal message - self.post_msg(PostType::Post(input, None)).unwrap(); - } + let input: String = app.input.drain(..).collect(); + app.input_idx = 0; + if input == "/dl" { + // Delete last message + self.post_msg(PostType::DeleteLast).unwrap(); + } else if let Some(captures) = DLX_RGX.captures(&input) { + // Delete the last X messages + let x: usize = captures.get(1).unwrap().as_str().parse().unwrap(); + for _ in 0..x { + self.post_msg(PostType::DeleteLast).unwrap(); + } + } else if input == "/dall" { + // Delete all messages + self.post_msg(PostType::DeleteAll).unwrap(); + } else if input == "/cycles" { + self.color_tx.send(()).unwrap(); + } else if input == "/cycle1" { + self.start_cycle(true); + } else if input == "/cycle2" { + self.start_cycle(false); + } else if input == "/kall" { + // Kick all guests + let username = "s _".to_owned(); + let msg = "".to_owned(); + self.post_msg(PostType::Kick(msg, username)).unwrap(); + } else if input.starts_with("/m ") { + // Send message to "members" section + let msg = remove_prefix(&input, "/m ").to_owned(); + let to = Some(SEND_TO_MEMBERS.to_owned()); + self.post_msg(PostType::Post(msg, to)).unwrap(); + app.input = "/m ".to_owned(); + app.input_idx = app.input.width() + } else if input.starts_with("/a ") { + // Send message to "admin" section + let msg = remove_prefix(&input, "/a ").to_owned(); + let to = Some(SEND_TO_ADMINS.to_owned()); + self.post_msg(PostType::Post(msg, to)).unwrap(); + app.input = "/a ".to_owned(); + app.input_idx = app.input.width() + } else if input.starts_with("/s ") { + // Send message to "staff" section + let msg = remove_prefix(&input, "/s ").to_owned(); + let to = Some(SEND_TO_STAFFS.to_owned()); + self.post_msg(PostType::Post(msg, to)).unwrap(); + app.input = "/s ".to_owned(); + app.input_idx = app.input.width() + } else if let Some(captures) = PM_RGX.captures(&input) { + // Send PM message + let username = &captures[1]; + let msg = captures[2].to_owned(); + let to = Some(username.to_owned()); + self.post_msg(PostType::Post(msg, to)).unwrap(); + app.input = format!("/pm {} ", username); + app.input_idx = app.input.width() + } else if let Some(captures) = NEW_NICKNAME_RGX.captures(&input) { + // Change nickname + let new_nickname = captures[1].to_owned(); + self.post_msg(PostType::NewNickname(new_nickname)).unwrap(); + } else if let Some(captures) = NEW_COLOR_RGX.captures(&input) { + // Change color + let new_color = captures[1].to_owned(); + self.post_msg(PostType::NewColor(new_color)).unwrap(); + } else if let Some(captures) = KICK_RGX.captures(&input) { + // Kick a user + let username = captures[1].to_owned(); + let msg = captures[2].to_owned(); + self.post_msg(PostType::Kick(msg, username)).unwrap(); + } else if let Some(captures) = IGNORE_RGX.captures(&input) { + // Ignore a user + let username = captures[1].to_owned(); + self.post_msg(PostType::Ignore(username)).unwrap(); + } else if let Some(captures) = UNIGNORE_RGX.captures(&input) { + // Unignore a user + let username = captures[1].to_owned(); + self.post_msg(PostType::Unignore(username)).unwrap(); + } else if let Some(captures) = UPLOAD_RGX.captures(&input) { + // Upload a file + let file_path = captures[1].to_owned(); + let send_to = match captures.get(2) { + Some(to_match) => match to_match.as_str() { + "members" => SEND_TO_MEMBERS, + "staffs" => SEND_TO_STAFFS, + "admins" => SEND_TO_ADMINS, + _ => SEND_TO_ALL, + }, + None => SEND_TO_ALL, } - KeyEvent { code: KeyCode::Tab, modifiers: KeyModifiers::NONE, .. } => { - let (p1, p2) = app.input.split_at(app.input_idx); - if p2 == "" || p2.chars().nth(0) == Some(' ') { - let mut parts: Vec<&str> = p1.split(" ").collect(); - if let Some(user_prefix) = parts.pop() { - let mut should_autocomplete = false; - let mut prefix = ""; - if parts.len() == 1 - && ((parts[0] == "/kick" || parts[0] == "/k" || parts[0] == "/pm") - || parts[0] == "/ignore" - || parts[0] == "/unignore") - { - should_autocomplete = true; - } else if user_prefix.starts_with("@") { - should_autocomplete = true; - prefix = "@"; - } - if should_autocomplete { - let user_prefix_norm = remove_prefix(user_prefix, prefix); - let user_prefix_norm_len = user_prefix_norm.len(); - if let Some(name) = autocomplete_username(users, user_prefix_norm) { - let complete_name = format!("{}{}", prefix, name); - parts.push(complete_name.as_str()); - let p2 = p2.trim_start(); - if p2 != "" { - parts.push(p2); - } - app.input = parts.join(" "); - app.input_idx += name.len() - user_prefix_norm_len; - } + .to_owned(); + let msg = match captures.get(3) { + Some(msg_match) => msg_match.as_str().to_owned(), + None => "".to_owned(), + }; + self.post_msg(PostType::Upload(file_path, send_to, msg)) + .unwrap(); + } else { + // Send normal message + self.post_msg(PostType::Post(input, None)).unwrap(); + } + Ok(()) + } + + fn handle_editing_mode_key_event_tab(&mut self, app: &mut App, users: &Arc<Mutex<Users>>) { + let (p1, p2) = app.input.split_at(app.input_idx); + if p2 == "" || p2.chars().nth(0) == Some(' ') { + let mut parts: Vec<&str> = p1.split(" ").collect(); + if let Some(user_prefix) = parts.pop() { + let mut should_autocomplete = false; + let mut prefix = ""; + if parts.len() == 1 + && ((parts[0] == "/kick" || parts[0] == "/k" || parts[0] == "/pm") + || parts[0] == "/ignore" + || parts[0] == "/unignore") + { + should_autocomplete = true; + } else if user_prefix.starts_with("@") { + should_autocomplete = true; + prefix = "@"; + } + if should_autocomplete { + let user_prefix_norm = remove_prefix(user_prefix, prefix); + let user_prefix_norm_len = user_prefix_norm.len(); + if let Some(name) = autocomplete_username(users, user_prefix_norm) { + let complete_name = format!("{}{}", prefix, name); + parts.push(complete_name.as_str()); + let p2 = p2.trim_start(); + if p2 != "" { + parts.push(p2); } + app.input = parts.join(" "); + app.input_idx += name.len() - user_prefix_norm_len; } } } - KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, .. } => { - app.clear_filter(); - app.input = "".to_owned(); - app.input_idx = 0; - app.input_mode = InputMode::Normal; - } - KeyEvent { code: KeyCode::Char('a'), modifiers: KeyModifiers::CONTROL, .. } => { + } + } + + fn handle_editing_mode_key_event_ctrl_c(&mut self, app: &mut App) { + app.clear_filter(); + app.input = "".to_owned(); + app.input_idx = 0; + app.input_mode = InputMode::Normal; + } + + fn handle_editing_mode_key_event_ctrl_a(&mut self, app: &mut App) { + app.input_idx = 0; + } + + fn handle_editing_mode_key_event_ctrl_e(&mut self, app: &mut App) { + app.input_idx = app.input.width(); + } + + fn handle_editing_mode_key_event_ctrl_f(&mut self, app: &mut App) { + if let Some(idx) = app.input.chars().skip(app.input_idx).position(|c| c == ' ') { + app.input_idx = std::cmp::min(app.input_idx + idx + 1, app.input.width()); + } else { + app.input_idx = app.input.width(); + } + } + + fn handle_editing_mode_key_event_ctrl_b(&mut self, app: &mut App) { + if let Some(idx) = app.input_idx.checked_sub(2) { + let tmp = app + .input + .chars() + .take(idx) + .collect::<String>() + .chars() + .rev() + .collect::<String>(); + if let Some(idx) = tmp.chars().position(|c| c == ' ') { + app.input_idx = std::cmp::max(tmp.width() - idx, 0); + } else { app.input_idx = 0; } - KeyEvent { code: KeyCode::Char('e'), modifiers: KeyModifiers::CONTROL, .. } => { - app.input_idx = app.input.width(); - } - KeyEvent { code: KeyCode::Char('f'), modifiers: KeyModifiers::CONTROL, .. } => { - if let Some(idx) = app.input.chars().skip(app.input_idx).position(|c| c == ' ') { - app.input_idx = std::cmp::min(app.input_idx + idx + 1, app.input.width()); - } else { - app.input_idx = app.input.width(); - } - } - KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::CONTROL, .. } => { - if let Some(idx) = app.input_idx.checked_sub(2) { - let tmp = app - .input - .chars() - .take(idx) - .collect::<String>() - .chars() - .rev() - .collect::<String>(); - if let Some(idx) = tmp.chars().position(|c| c == ' ') { - app.input_idx = std::cmp::max(tmp.width() - idx, 0); - } else { - app.input_idx = 0; - } - } - } - KeyEvent { code: KeyCode::Char('v'), modifiers: KeyModifiers::CONTROL, .. } => { - let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap(); - if let Ok(clipboard) = ctx.get_contents() { - let byte_position = byte_pos(&app.input, app.input_idx).unwrap(); - app.input.insert_str(byte_position, &clipboard); - app.input_idx += clipboard.width(); - } - } - KeyEvent { code: KeyCode::Left, modifiers: KeyModifiers::NONE, .. } => { - if app.input_idx > 0 { - app.input_idx -= 1; - } - } - KeyEvent { code: KeyCode::Right, modifiers: KeyModifiers::NONE, .. } => { - if app.input_idx < app.input.width() { - app.input_idx += 1; - } - } - KeyEvent { code: KeyCode::Down, modifiers: KeyModifiers::NONE, .. } => { - app.input_mode = InputMode::Normal; - app.items.next(); - } - KeyEvent { code: KeyCode::Char(c), modifiers: KeyModifiers::NONE, .. } - | KeyEvent { code: KeyCode::Char(c), modifiers: KeyModifiers::SHIFT, .. } => { - let byte_position = byte_pos(&app.input, app.input_idx).unwrap(); - app.input.insert(byte_position, c); + } + } - app.input_idx += 1; - app.update_filter(); - } - KeyEvent { code: KeyCode::Backspace, modifiers: KeyModifiers::NONE, .. } => { - if app.input_idx > 0 { - app.input_idx -= 1; - app.input = remove_at(&app.input, app.input_idx); - app.update_filter(); - } - } - KeyEvent { code: KeyCode::Delete, modifiers: KeyModifiers::NONE, .. } => { - if app.input_idx > 0 && app.input_idx == app.input.width() { - app.input_idx -= 1; - } - app.input = remove_at(&app.input, app.input_idx); - app.update_filter(); - } - KeyEvent { code: KeyCode::Esc, modifiers: KeyModifiers::NONE, .. } => { - app.input_mode = InputMode::Normal; - } + fn handle_editing_mode_key_event_ctrl_v(&mut self, app: &mut App) { + let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap(); + if let Ok(clipboard) = ctx.get_contents() { + let byte_position = byte_pos(&app.input, app.input_idx).unwrap(); + app.input.insert_str(byte_position, &clipboard); + app.input_idx += clipboard.width(); + } + } + + fn handle_editing_mode_key_event_left(&mut self, app: &mut App) { + if app.input_idx > 0 { + app.input_idx -= 1; + } + } + + fn handle_editing_mode_key_event_right(&mut self, app: &mut App) { + if app.input_idx < app.input.width() { + app.input_idx += 1; + } + } + + fn handle_editing_mode_key_event_down(&mut self, app: &mut App) { + app.input_mode = InputMode::Normal; + app.items.next(); + } + + fn handle_editing_mode_key_event_shift_c(&mut self, app: &mut App, c: char) { + let byte_position = byte_pos(&app.input, app.input_idx).unwrap(); + app.input.insert(byte_position, c); + + app.input_idx += 1; + app.update_filter(); + } + + fn handle_editing_mode_key_event_backspace(&mut self, app: &mut App) { + if app.input_idx > 0 { + app.input_idx -= 1; + app.input = remove_at(&app.input, app.input_idx); + app.update_filter(); + } + } + + fn handle_editing_mode_key_event_delete(&mut self, app: &mut App) { + if app.input_idx > 0 && app.input_idx == app.input.width() { + app.input_idx -= 1; + } + app.input = remove_at(&app.input, app.input_idx); + app.update_filter(); + } + + fn handle_editing_mode_key_event_esc(&mut self, app: &mut App) { + app.input_mode = InputMode::Normal; + } + + fn handle_editing_mode_key_event(&mut self, app: &mut App, + key_event: KeyEvent, + users: &Arc<Mutex<Users>>, + ) -> std::result::Result<(), ExitSignal> { + match key_event { + KeyEvent { code: KeyCode::Enter, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_enter(app)?, + KeyEvent { code: KeyCode::Tab, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_tab(app, users), + KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_c(app), + KeyEvent { code: KeyCode::Char('a'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_a(app), + KeyEvent { code: KeyCode::Char('e'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_e(app), + KeyEvent { code: KeyCode::Char('f'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_f(app), + KeyEvent { code: KeyCode::Char('b'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_b(app), + KeyEvent { code: KeyCode::Char('v'), modifiers: KeyModifiers::CONTROL, .. } => self.handle_editing_mode_key_event_ctrl_v(app), + KeyEvent { code: KeyCode::Left, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_left(app), + KeyEvent { code: KeyCode::Right, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_right(app), + KeyEvent { code: KeyCode::Down, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_down(app), + KeyEvent { code: KeyCode::Char(c), modifiers: KeyModifiers::NONE, .. } | + KeyEvent { code: KeyCode::Char(c), modifiers: KeyModifiers::SHIFT, .. } => self.handle_editing_mode_key_event_shift_c(app, c), + KeyEvent { code: KeyCode::Backspace, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_backspace(app), + KeyEvent { code: KeyCode::Delete, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_delete(app), + KeyEvent { code: KeyCode::Esc, modifiers: KeyModifiers::NONE, .. } => self.handle_editing_mode_key_event_esc(app), _ => {} } Ok(())