Added Handler struct to hold the boxed next step handler and the previous message to be able to delete the previous message to allways delete it
This commit is contained in:
parent
c264623510
commit
ab6e4d9233
@ -11,8 +11,5 @@ pub async fn run(bot: Throttle<Bot>, q: CallbackQuery) -> crate::Result<()> {
|
||||
}
|
||||
|
||||
pub fn filter(q: CallbackQuery) -> bool {
|
||||
match q.data.as_deref() {
|
||||
Some("delete_message") => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(q.data.as_deref(), Some("delete_message"))
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
entity::{account, prelude::Account},
|
||||
entity::prelude::Account,
|
||||
errors::NoUserInfo,
|
||||
handlers::{markups::deletion_markup, utils::package_handler, MainDialogue, State},
|
||||
models::DecryptedAccount,
|
||||
};
|
||||
use sea_orm::prelude::*;
|
||||
use teloxide::{adaptors::Throttle, prelude::*};
|
||||
@ -12,19 +13,12 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
login: String,
|
||||
password: String,
|
||||
account: DecryptedAccount,
|
||||
master_pass: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
dialogue.exit().await?;
|
||||
let account = spawn_blocking(move || {
|
||||
account::ActiveModel::from_unencrypted(user_id, name, &login, &password, &master_pass)
|
||||
})
|
||||
.await??;
|
||||
let account = spawn_blocking(move || account.into_account(user_id, &master_pass)).await??;
|
||||
account.insert(&db).await?;
|
||||
bot.send_message(msg.chat.id, "Success")
|
||||
.reply_markup(deletion_markup())
|
||||
@ -37,30 +31,24 @@ async fn get_password(
|
||||
msg: Message,
|
||||
_: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
login: String,
|
||||
password: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let previous = bot
|
||||
.send_message(msg.chat.id, "Send master password")
|
||||
.await?;
|
||||
let account = DecryptedAccount {
|
||||
name,
|
||||
login,
|
||||
password,
|
||||
};
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, master_pass| {
|
||||
get_master_pass(
|
||||
bot,
|
||||
msg,
|
||||
db,
|
||||
dialogue,
|
||||
previous,
|
||||
name,
|
||||
login,
|
||||
password,
|
||||
master_pass,
|
||||
)
|
||||
get_master_pass(bot, msg, db, dialogue, account, master_pass)
|
||||
},
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -71,17 +59,16 @@ async fn get_login(
|
||||
msg: Message,
|
||||
_: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
login: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let previous = bot.send_message(msg.chat.id, "Send password").await?;
|
||||
dialogue
|
||||
.update(State::GetPassword(package_handler(
|
||||
move |bot, msg, db, dialogue, password| {
|
||||
get_password(bot, msg, db, dialogue, previous, name, login, password)
|
||||
get_password(bot, msg, db, dialogue, name, login, password)
|
||||
},
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -92,10 +79,8 @@ async fn get_account_name(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
if Account::exists(user_id, &name, &db).await? {
|
||||
bot.send_message(msg.chat.id, "Account alreay exists")
|
||||
@ -106,9 +91,8 @@ async fn get_account_name(
|
||||
let previous = bot.send_message(msg.chat.id, "Send login").await?;
|
||||
dialogue
|
||||
.update(State::GetLogin(package_handler(
|
||||
move |bot, msg, db, dialogue, login| {
|
||||
get_login(bot, msg, db, dialogue, previous, name, login)
|
||||
},
|
||||
move |bot, msg, db, dialogue, login| get_login(bot, msg, db, dialogue, name, login),
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -122,9 +106,8 @@ pub async fn add_account(
|
||||
let previous = bot.send_message(msg.chat.id, "Send account name").await?;
|
||||
dialogue
|
||||
.update(State::GetAccountName(package_handler(
|
||||
move |bot, msg, db, dialogue, name| {
|
||||
get_account_name(bot, msg, db, dialogue, previous, name)
|
||||
},
|
||||
get_account_name,
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -15,10 +15,8 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
dialogue.exit().await?;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
Account::delete_by_id((user_id, name)).exec(&db).await?;
|
||||
@ -33,10 +31,8 @@ async fn get_account_name(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
if !Account::exists(user_id, &name, &db).await? {
|
||||
bot.send_message(msg.chat.id, "Account doesn't exists")
|
||||
@ -49,9 +45,8 @@ async fn get_account_name(
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, _| {
|
||||
get_master_pass(bot, msg, db, dialogue, previous, name)
|
||||
},
|
||||
move |bot, msg, db, dialogue, _| get_master_pass(bot, msg, db, dialogue, name),
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -71,9 +66,8 @@ pub async fn delete(
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetAccountName(package_handler(
|
||||
move |bot, msg, db, dialogue, name| {
|
||||
get_account_name(bot, msg, db, dialogue, previous, name)
|
||||
},
|
||||
get_account_name,
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -11,9 +11,8 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
_master_pass: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
dialogue.exit().await?;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
Account::delete_many()
|
||||
@ -40,7 +39,8 @@ pub async fn delete_all(
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, _| get_master_pass(bot, msg, db, dialogue, previous),
|
||||
get_master_pass,
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -16,10 +16,8 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
master_pass: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let master_pass: Arc<str> = master_pass.into();
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
let accounts = Arc::new(Mutex::new(Vec::new()));
|
||||
@ -59,8 +57,9 @@ pub async fn export(bot: Throttle<Bot>, msg: Message, dialogue: MainDialogue) ->
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, master_pass| {
|
||||
get_master_pass(bot, msg, db, dialogue, previous, master_pass)
|
||||
get_master_pass(bot, msg, db, dialogue, master_pass)
|
||||
},
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -16,11 +16,9 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
master_pass: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
dialogue.exit().await?;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
let account = match Account::get(user_id, &name, &db).await? {
|
||||
@ -46,10 +44,8 @@ async fn get_account_name(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
name: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
if !Account::exists(user_id, &name, &db).await? {
|
||||
bot.send_message(msg.chat.id, "Account doesn't exists")
|
||||
@ -63,8 +59,9 @@ async fn get_account_name(
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, master_pass| {
|
||||
get_master_pass(bot, msg, db, dialogue, previous, name, master_pass)
|
||||
get_master_pass(bot, msg, db, dialogue, name, master_pass)
|
||||
},
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -84,9 +81,8 @@ pub async fn get_account(
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetAccountName(package_handler(
|
||||
move |bot, msg, db, dialogue, name| {
|
||||
get_account_name(bot, msg, db, dialogue, previous, name)
|
||||
},
|
||||
get_account_name,
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -17,10 +17,8 @@ async fn get_master_pass(
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
master_pass: String,
|
||||
previous: Message,
|
||||
accounts: Vec<DecryptedAccount>,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
let master_pass: Arc<str> = master_pass.into();
|
||||
let failed = Arc::new(Mutex::new(Vec::new()));
|
||||
@ -66,9 +64,8 @@ async fn get_document(
|
||||
msg: Message,
|
||||
_: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
(): (),
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
let document = match msg.document() {
|
||||
Some(doc) => doc,
|
||||
None => {
|
||||
@ -113,8 +110,9 @@ async fn get_document(
|
||||
dialogue
|
||||
.update(State::GetMasterPass(package_handler(
|
||||
move |bot, msg, db, dialogue, master_pass| {
|
||||
get_master_pass(bot, msg, db, dialogue, master_pass, previous, accounts)
|
||||
get_master_pass(bot, msg, db, dialogue, master_pass, accounts)
|
||||
},
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
@ -128,9 +126,7 @@ pub async fn import(bot: Throttle<Bot>, msg: Message, dialogue: MainDialogue) ->
|
||||
)
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetDocument(package_handler(
|
||||
move |bot, msg, db, dialogue, ()| get_document(bot, msg, db, dialogue, previous),
|
||||
)))
|
||||
.update(State::GetDocument(package_handler(get_document, previous)))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -12,10 +12,8 @@ async fn get_master_pass(
|
||||
msg: Message,
|
||||
db: DatabaseConnection,
|
||||
dialogue: MainDialogue,
|
||||
previous: Message,
|
||||
master_password: String,
|
||||
) -> crate::Result<()> {
|
||||
let _ = bot.delete_message(previous.chat.id, previous.id).await;
|
||||
dialogue.exit().await?;
|
||||
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
|
||||
let model = task::spawn_blocking(move || {
|
||||
@ -47,9 +45,8 @@ pub async fn set_master_pass(
|
||||
.await?;
|
||||
dialogue
|
||||
.update(State::GetPassword(package_handler(
|
||||
move |bot, msg, db, dialogue, master_pass| {
|
||||
get_master_pass(bot, msg, db, dialogue, previous, master_pass)
|
||||
},
|
||||
get_master_pass,
|
||||
previous,
|
||||
)))
|
||||
.await?;
|
||||
Ok(())
|
||||
|
@ -10,7 +10,7 @@ pub async fn account_markup(
|
||||
) -> crate::Result<KeyboardMarkup> {
|
||||
let account_names: Vec<Vec<KeyboardButton>> = Account::get_names(user_id, db, true)
|
||||
.await?
|
||||
.map_ok(|account| KeyboardButton::new(account))
|
||||
.map_ok(KeyboardButton::new)
|
||||
.try_chunks(3)
|
||||
.try_collect()
|
||||
.await?;
|
||||
|
@ -16,23 +16,25 @@ use teloxide::{
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
type MainDialogue = Dialogue<State, InMemStorage<State>>;
|
||||
type PackagedHandler<T> = Arc<
|
||||
Mutex<
|
||||
Option<
|
||||
Box<
|
||||
dyn FnOnce(
|
||||
Throttle<Bot>,
|
||||
Message,
|
||||
DatabaseConnection,
|
||||
MainDialogue,
|
||||
T,
|
||||
) -> crate::PinnedFuture<'static, crate::Result<()>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>,
|
||||
>,
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub struct Handler<T> {
|
||||
pub handler: Box<
|
||||
dyn FnOnce(
|
||||
Throttle<Bot>,
|
||||
Message,
|
||||
DatabaseConnection,
|
||||
MainDialogue,
|
||||
T,
|
||||
) -> crate::PinnedFuture<'static, crate::Result<()>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub previous: Option<Message>,
|
||||
}
|
||||
|
||||
type PackagedHandler<T> = Arc<Mutex<Option<Handler<T>>>>;
|
||||
|
||||
#[derive(BotCommands, Clone, Copy)]
|
||||
#[command(rename_rule = "snake_case")]
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{errors::HandlerUsed, handlers::markups::deletion_markup, PinnedFuture};
|
||||
use crate::{
|
||||
errors::HandlerUsed,
|
||||
handlers::{markups::deletion_markup, utils::delete_optional},
|
||||
PinnedFuture,
|
||||
};
|
||||
use sea_orm::prelude::*;
|
||||
use teloxide::{adaptors::Throttle, prelude::*};
|
||||
|
||||
@ -19,13 +23,17 @@ where
|
||||
&'a str,
|
||||
) -> PinnedFuture<'a, crate::Result<bool>>,
|
||||
{
|
||||
let handler = next.lock().await.take();
|
||||
if text == "/cancel" {
|
||||
dialogue.exit().await?;
|
||||
let previous = handler.and_then(|handler| handler.previous);
|
||||
delete_optional(&bot, &previous).await;
|
||||
bot.send_message(msg.chat.id, "Successfully cancelled")
|
||||
.reply_markup(deletion_markup())
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
let handler = handler.ok_or(HandlerUsed)?;
|
||||
delete_optional(&bot, &handler.previous).await;
|
||||
match check(&bot, &msg, &db, &text).await {
|
||||
Ok(true) => (),
|
||||
Ok(false) => {
|
||||
@ -37,5 +45,5 @@ where
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
next.lock().await.take().ok_or(HandlerUsed)?(bot, msg, db, dialogue, text).await
|
||||
(handler.handler)(bot, msg, db, dialogue, text).await
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
errors::HandlerUsed,
|
||||
handlers::{MainDialogue, PackagedHandler},
|
||||
handlers::{utils::delete_optional, MainDialogue, PackagedHandler},
|
||||
};
|
||||
use sea_orm::prelude::*;
|
||||
use teloxide::{adaptors::Throttle, prelude::*};
|
||||
@ -12,5 +12,7 @@ pub async fn get_document(
|
||||
dialogue: MainDialogue,
|
||||
next: PackagedHandler<()>,
|
||||
) -> crate::Result<()> {
|
||||
next.lock().await.take().ok_or(HandlerUsed)?(bot, msg, db, dialogue, ()).await
|
||||
let handler = next.lock().await.take().ok_or(HandlerUsed)?;
|
||||
delete_optional(&bot, &handler.previous).await;
|
||||
(handler.handler)(bot, msg, db, dialogue, ()).await
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ pub async fn check_master_pass<'a>(
|
||||
.await?;
|
||||
Ok(false)
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
use super::{MainDialogue, PackagedHandler};
|
||||
use super::{Handler, MainDialogue, PackagedHandler};
|
||||
use sea_orm::DatabaseConnection;
|
||||
use std::{future::Future, sync::Arc};
|
||||
use teloxide::{adaptors::Throttle, prelude::*};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
#[inline]
|
||||
pub fn package_handler<H, F, T>(f: H) -> PackagedHandler<T>
|
||||
pub fn package_handler<H, F, T>(f: H, previous: impl Into<Option<Message>>) -> PackagedHandler<T>
|
||||
where
|
||||
H: FnOnce(Throttle<Bot>, Message, DatabaseConnection, MainDialogue, T) -> F
|
||||
+ Send
|
||||
@ -13,11 +13,21 @@ where
|
||||
+ 'static,
|
||||
F: Future<Output = crate::Result<()>> + Send + 'static,
|
||||
{
|
||||
Arc::new(Mutex::new(Some(Box::new(
|
||||
move |bot, msg, db, dialogue, val| Box::pin(f(bot, msg, db, dialogue, val)),
|
||||
))))
|
||||
Arc::new(Mutex::new(Some(Handler {
|
||||
handler: Box::new(move |bot, msg, db, dialogue, val| {
|
||||
Box::pin(f(bot, msg, db, dialogue, val))
|
||||
}),
|
||||
previous: previous.into(),
|
||||
})))
|
||||
}
|
||||
|
||||
pub async fn delete_message(bot: Throttle<Bot>, msg: Message) {
|
||||
let _ = bot.delete_message(msg.chat.id, msg.id).await;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn delete_optional(bot: &Throttle<Bot>, msg: &Option<Message>) {
|
||||
if let Some(msg) = msg {
|
||||
let _ = bot.delete_message(msg.chat.id, msg.id).await;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user