pass_manager/src/markups.rs

101 lines
3.1 KiB
Rust
Raw Normal View History

use crate::prelude::*;
use base64::{engine::general_purpose::STANDARD_NO_PAD as B64_ENGINE, Engine as _};
2023-07-25 14:44:12 +00:00
use itertools::Itertools;
use sha2::{Digest, Sha256};
use teloxide::types::{InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, KeyboardMarkup};
use tokio::task::spawn_blocking;
2023-05-04 18:15:41 +00:00
2023-05-09 17:27:58 +00:00
/// Creates a markup of all user's account names
2023-05-04 18:15:41 +00:00
#[inline]
pub async fn account_list_markup(
2023-05-04 18:15:41 +00:00
user_id: u64,
db: &DatabaseConnection,
) -> crate::Result<KeyboardMarkup> {
let account_names: Vec<Vec<KeyboardButton>> = Account::get_names(user_id, db)
2023-05-04 18:15:41 +00:00
.await?
.map_ok(KeyboardButton::new)
2023-05-04 18:15:41 +00:00
.try_chunks(3)
2023-05-27 18:56:58 +00:00
.map_err(|err| err.1)
2023-05-04 18:15:41 +00:00
.try_collect()
.await?;
let markup = KeyboardMarkup::new(account_names)
.resize_keyboard(true)
.one_time_keyboard(true);
Ok(markup)
}
2023-07-25 16:09:34 +00:00
#[inline]
pub fn menu_markup_sync(names: impl IntoIterator<Item = String>) -> InlineKeyboardMarkup {
2023-07-25 16:09:34 +00:00
let names = names
.into_iter()
.map(|name| {
let hash = <Sha256 as Digest>::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)
}
#[inline]
pub async fn menu_markup(
user_id: u64,
db: &DatabaseConnection,
) -> crate::Result<InlineKeyboardMarkup> {
let names: Vec<String> = Account::get_names(user_id, db).await?.try_collect().await?;
spawn_blocking(|| menu_markup_sync(names))
.await
.map_err(Into::into)
}
#[inline]
fn make_button(text: &str, command: &str, hash: &str) -> InlineKeyboardButton {
let mut data = command.to_owned();
data.reserve(44);
data.push(' ');
data.push_str(hash);
InlineKeyboardButton::callback(text, data)
}
#[inline]
pub fn account_markup(name: &str, is_encrypted: bool) -> InlineKeyboardMarkup {
let mut hash = [0; 43];
B64_ENGINE
.encode_slice(<Sha256 as Digest>::digest(name), &mut hash)
.unwrap();
let hash = std::str::from_utf8(&hash).unwrap();
let alter_buttons = [
("Alter name", "an"),
("Alter login", "al"),
("Alter password", "ap"),
]
.map(|(text, command)| make_button(text, command, hash));
let mut second_raw = Vec::new();
if is_encrypted {
second_raw.push(make_button("Decrypt", "decrypt", hash))
} else {
second_raw.push(make_button("Hide", "hide", hash));
}
second_raw.push(make_button("Delete account", "delete", hash));
let menu_button = InlineKeyboardButton::callback("Back to the menu", "get_menu");
InlineKeyboardMarkup::new([alter_buttons])
.append_row(second_raw)
.append_row([menu_button])
}
2023-05-09 17:27:58 +00:00
/// Creates a markup with a "Delete message" button.
/// This markup should be added for all messages that won't be deleted afterwards
#[inline]
pub fn deletion_markup() -> InlineKeyboardMarkup {
let button = InlineKeyboardButton::callback("Delete message", "delete_message");
InlineKeyboardMarkup::new([[button]])
}