diff --git a/src/callbacks/get_menu.rs b/src/callbacks/get_menu.rs new file mode 100644 index 0000000..32cbb94 --- /dev/null +++ b/src/callbacks/get_menu.rs @@ -0,0 +1,28 @@ +use crate::prelude::*; +use tokio::task::spawn_blocking; + +pub async fn get_menu( + bot: Throttle, + q: CallbackQuery, + db: DatabaseConnection, +) -> crate::Result<()> { + let user_id = q.from.id.0; + let msg = q.message.as_ref().unwrap(); + + let names: Vec = Account::get_names(user_id, &db) + .await? + .try_collect() + .await?; + + if names.is_empty() { + bot.edit_message_text(msg.chat.id, msg.id, "You don't have any accounts") + .reply_markup(deletion_markup()) + .await?; + } + + let markup = spawn_blocking(|| menu_markup(names)).await?; + bot.edit_message_text(msg.chat.id, msg.id, "Choose your account") + .reply_markup(markup) + .await?; + Ok(()) +} diff --git a/src/callbacks/mod.rs b/src/callbacks/mod.rs index 935acb4..0b694e7 100644 --- a/src/callbacks/mod.rs +++ b/src/callbacks/mod.rs @@ -1,8 +1,10 @@ //! This module consists of endpoints to handle callbacks mod delete_message; +mod get_menu; pub use delete_message::delete_message; +pub use get_menu::get_menu; use crate::errors::InvalidCommand; use base64::{engine::general_purpose::STANDARD_NO_PAD as B64_ENGINE, Engine as _}; @@ -23,7 +25,6 @@ pub enum CallbackCommand { DeleteMessage, Get(NameHash), GetMenu, - GetAccounts, Decrypt(NameHash), Hide(NameHash), Alter(NameHash, AlterableField), @@ -47,7 +48,6 @@ impl FromStr for CallbackCommand { match s { "delete_message" => return Ok(DeleteMessage), "get_menu" => return Ok(GetMenu), - "get_accounts" => return Ok(GetAccounts), _ => (), }; diff --git a/src/commands/menu.rs b/src/commands/menu.rs new file mode 100644 index 0000000..9d44f32 --- /dev/null +++ b/src/commands/menu.rs @@ -0,0 +1,23 @@ +use crate::prelude::*; +use tokio::task::spawn_blocking; + +pub async fn menu(bot: Throttle, msg: Message, db: DatabaseConnection) -> crate::Result<()> { + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + + let names: Vec = Account::get_names(user_id, &db) + .await? + .try_collect() + .await?; + + if names.is_empty() { + bot.send_message(msg.chat.id, "You don't have any accounts") + .reply_markup(deletion_markup()) + .await?; + } + + let markup = spawn_blocking(|| menu_markup(names)).await?; + bot.send_message(msg.chat.id, "Choose your account") + .reply_markup(markup) + .await?; + Ok(()) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 6abbbc2..4769947 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -10,6 +10,7 @@ mod get_account; mod get_accounts; mod help; mod import; +mod menu; mod set_master_pass; mod start; @@ -23,6 +24,7 @@ pub use get_account::get_account; pub use get_accounts::get_accounts; pub use help::help; pub use import::import; +pub use menu::menu; pub use set_master_pass::set_master_pass; pub use start::start; @@ -56,6 +58,8 @@ pub enum Command { Import, #[command(description = "generates 10 secure passwords")] GenPassword, + #[command(description = "gives you a menu to manage your accounts")] + Menu, #[command(description = "cancels the current action")] Cancel, } diff --git a/src/main.rs b/src/main.rs index fb3b1c9..35ebe69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,7 @@ fn get_dispatcher( .branch(case![Command::Cancel].endpoint(commands::cancel)) // This branch filters out the users that don't have a master password set .branch(master_password_check::get_handler()) + .branch(case![Command::Menu].endpoint(commands::menu)) .branch(case![Command::AddAccount].endpoint(commands::add_account)) .branch(case![Command::GetAccount].endpoint(commands::get_account)) .branch(case![Command::GetAccounts].endpoint(commands::get_accounts)) @@ -61,6 +62,7 @@ fn get_dispatcher( let callback_handler = Update::filter_callback_query() .filter_map(CallbackCommand::from_query) + .branch(case![CallbackCommand::GetMenu].endpoint(callbacks::get_menu)) .branch(case![CallbackCommand::DeleteMessage].endpoint(callbacks::delete_message)); let handler = dptree::entry() diff --git a/src/markups.rs b/src/markups.rs index 048e60c..e5183dc 100644 --- a/src/markups.rs +++ b/src/markups.rs @@ -24,6 +24,22 @@ pub async fn account_markup( Ok(markup) } +#[inline] +pub fn menu_markup(names: impl IntoIterator) -> InlineKeyboardMarkup { + let names = names + .into_iter() + .map(|name| { + let hash = ::digest(name.as_bytes()); + let mut data = "get ".to_owned(); + data.reserve(43); + B64_ENGINE.encode_string(hash, &mut data); + InlineKeyboardButton::callback(name, data) + }) + .chunks(3); + + InlineKeyboardMarkup::new(&names) +} + /// Creates a markup with a "Delete message" button. /// This markup should be added for all messages that won't be deleted afterwards #[inline]