Now altering messages where possible

This commit is contained in:
StNicolay 2023-07-29 10:19:22 +03:00
parent 426a4736ce
commit 5c14a77f29
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
13 changed files with 122 additions and 68 deletions

8
Cargo.lock generated
View File

@ -2118,18 +2118,18 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.176" version = "1.0.177"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc" checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.176" version = "1.0.177"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f" checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -8,22 +8,23 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
name: String, name: String,
login: String, login: String,
password: String, password: String,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
dialogue.exit().await?; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let account = spawn_blocking(move || { let account = spawn_blocking(move || {
account::ActiveModel::from_unencrypted(user_id, name, &login, &password, &master_pass) account::ActiveModel::from_unencrypted(user_id, name, &login, &password, &master_pass)
}) })
.await??; .await??;
account.insert(&db).await?; account.insert(&db).await?;
bot.send_message(msg.chat.id, "Success")
.reply_markup(deletion_markup()) ids.alter_message(&bot, "Success", deletion_markup(), None)
.await?; .await?;
Ok(()) Ok(())
} }

View File

@ -7,18 +7,23 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
name: String, name: String,
_: String, _: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await;
dialogue.exit().await?; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
Account::delete_by_id((user_id, name)).exec(&db).await?; Account::delete_by_id((user_id, name)).exec(&db).await?;
bot.send_message(msg.chat.id, "The account is successfully deleted")
.reply_markup(deletion_markup()) ids.alter_message(
.await?; &bot,
"The account is successfully deleted",
deletion_markup(),
None,
)
.await?;
Ok(()) Ok(())
} }

View File

@ -10,10 +10,9 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
_: String, _: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await;
dialogue.exit().await?; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let txn = db.begin().await?; let txn = db.begin().await?;
@ -32,8 +31,7 @@ async fn get_master_pass(
"Something went wrong. Try again later" "Something went wrong. Try again later"
} }
}; };
bot.send_message(msg.chat.id, text) ids.alter_message(&bot, text, deletion_markup(), None)
.reply_markup(deletion_markup())
.await?; .await?;
Ok(()) Ok(())
} }

View File

@ -26,6 +26,8 @@ async fn get_master_pass(
ids: MessageIds, ids: MessageIds,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
dialogue.exit().await?;
ids.delete(&bot).await; ids.delete(&bot).await;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let mut accounts = Vec::new(); let mut accounts = Vec::new();
@ -51,7 +53,6 @@ async fn get_master_pass(
bot.send_document(msg.chat.id, file) bot.send_document(msg.chat.id, file)
.reply_markup(deletion_markup()) .reply_markup(deletion_markup())
.await?; .await?;
dialogue.exit().await?;
Ok(()) Ok(())
} }

View File

@ -8,14 +8,14 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
name: String, name: String,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await;
dialogue.exit().await?; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let account = match Account::get(user_id, &name, &db).await? { let account = match Account::get(user_id, &name, &db).await? {
Some(account) => account, Some(account) => account,
None => { None => {
@ -25,11 +25,11 @@ async fn get_master_pass(
return Ok(()); return Ok(());
} }
}; };
let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??; let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??;
let message = format!("Name:\n`{name}`\nLogin:\n`{login}`\nPassword:\n`{password}`"); let text = format!("Name:\n`{name}`\nLogin:\n`{login}`\nPassword:\n`{password}`");
bot.send_message(msg.chat.id, message)
.reply_markup(deletion_markup()) ids.alter_message(&bot, text, deletion_markup(), ParseMode::MarkdownV2)
.parse_mode(ParseMode::MarkdownV2)
.await?; .await?;
Ok(()) Ok(())
} }

View File

@ -31,11 +31,12 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
user: User, user: User,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let mut failed = Vec::new(); let mut failed = Vec::new();
@ -50,7 +51,7 @@ async fn get_master_pass(
.await; .await;
} }
let message = if failed.is_empty() { let text = if failed.is_empty() {
"Success".to_owned() "Success".to_owned()
} else { } else {
format!( format!(
@ -58,10 +59,8 @@ async fn get_master_pass(
failed.into_iter().format("\n") failed.into_iter().format("\n")
) )
}; };
bot.send_message(msg.chat.id, message) ids.alter_message(&bot, text, deletion_markup(), None)
.reply_markup(deletion_markup())
.await?; .await?;
dialogue.exit().await?;
Ok(()) Ok(())
} }

View File

@ -7,10 +7,9 @@ async fn get_master_pass(
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
ids.delete(&bot).await;
dialogue.exit().await?; dialogue.exit().await?;
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
@ -18,8 +17,7 @@ async fn get_master_pass(
spawn_blocking(move || master_pass::ActiveModel::from_unencrypted(user_id, &master_pass)) spawn_blocking(move || master_pass::ActiveModel::from_unencrypted(user_id, &master_pass))
.await?; .await?;
model.insert(&db).await?; model.insert(&db).await?;
bot.send_message(msg.chat.id, "Success") ids.alter_message(&bot, "Success", deletion_markup(), None)
.reply_markup(deletion_markup())
.await?; .await?;
Ok(()) Ok(())
} }
@ -44,7 +42,7 @@ pub async fn set_master_pass(
change_state!( change_state!(
dialogue, dialogue,
previous, &previous,
(), (),
State::GetNewMasterPass, State::GetNewMasterPass,
get_master_pass get_master_pass

View File

@ -4,7 +4,7 @@ macro_rules! change_state {
$dialogue $dialogue
.update($next_state(Handler::new( .update($next_state(Handler::new(
move |bot, msg, db, dialogue, ids, param| Box::pin($next_func(bot, msg, db, dialogue, ids, $($param,)* param)), move |bot, msg, db, dialogue, ids, param| Box::pin($next_func(bot, msg, db, dialogue, ids, $($param,)* param)),
&$previous, $previous,
))) )))
.await?; .await?;
Ok(()) Ok(())
@ -22,7 +22,7 @@ macro_rules! first_handler {
) -> $crate::Result<()> { ) -> $crate::Result<()> {
let previous = bot.send_message(msg.chat.id, $message).await?; let previous = bot.send_message(msg.chat.id, $message).await?;
$crate::change_state!(dialogue, previous, (), $next_state, $next_func) $crate::change_state!(dialogue, &previous, (), $next_state, $next_func)
} }
}; };
} }
@ -37,14 +37,12 @@ macro_rules! handler {
msg: Message, msg: Message,
_: DatabaseConnection, _: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
ids: MessageIds, mut ids: MessageIds,
$($param: $type),* $($param: $type),*
) -> $crate::Result<()> { ) -> $crate::Result<()> {
ids.delete(&bot).await; ids.alter_message(&bot, $message, None, None).await?;
let previous = bot.send_message(msg.chat.id, $message).await?; $crate::change_state!(dialogue, ids, ($($param),*), $next_state, $next_func)
$crate::change_state!(dialogue, previous, ($($param),*), $next_state, $next_func)
} }
}; };
} }
@ -72,7 +70,7 @@ macro_rules! ask_name_handler {
.reply_markup(markup) .reply_markup(markup)
.await?; .await?;
$crate::change_state!(dialogue, previous, (), State::GetExistingName, $next_func) $crate::change_state!(dialogue, &previous, (), State::GetExistingName, $next_func)
} }
}; };
} }

View File

@ -28,23 +28,28 @@ where
let text = match msg.text() { let text = match msg.text() {
Some(text) => text.trim(), Some(text) => text.trim(),
None => { None => {
let msg = bot.send_message(msg.chat.id, no_text_message).await?; handler
handler.previous = MessageIds::from(&msg); .previous
.alter_message(&bot, no_text_message, None, None)
.await?;
return Ok(()); return Ok(());
} }
}; };
if text == "/cancel" { if text == "/cancel" {
dialogue.exit().await?; dialogue.exit().await?;
bot.send_message(msg.chat.id, "Successfully cancelled") handler
.reply_markup(deletion_markup()) .previous
.alter_message(&bot, "Successfully cancelled", deletion_markup(), None)
.await?; .await?;
return Ok(()); return Ok(());
} }
if let Some(text) = check(&msg, &db, text).await? { if let Some(text) = check(&msg, &db, text).await? {
let failure_message = bot.send_message(msg.chat.id, text).await?; handler
handler.previous = MessageIds::from(&failure_message); .previous
.alter_message(&bot, text, None, None)
.await?;
return Ok(()); return Ok(());
} }

View File

@ -33,8 +33,9 @@ pub async fn get_existing_name(
if text == "/cancel" { if text == "/cancel" {
dialogue.exit().await?; dialogue.exit().await?;
bot.send_message(msg.chat.id, "Successfully cancelled") handler
.reply_markup(deletion_markup()) .previous
.alter_message(&bot, "Successfully cancelled", deletion_markup(), None)
.await?; .await?;
return Ok(()); return Ok(());
} }
@ -48,12 +49,10 @@ pub async fn get_existing_name(
return Ok(()); return Ok(());
} }
let previous = handler.previous;
let func = handler.func.take().unwrap(); let func = handler.func.take().unwrap();
drop(handler);
let text = text.to_owned(); let text = text.to_owned();
if let Err(err) = func(bot, msg, db, dialogue.clone(), previous, text).await { if let Err(err) = func(bot, msg, db, dialogue.clone(), handler.previous, text).await {
let _ = dialogue.exit().await; let _ = dialogue.exit().await;
return Err(err); return Err(err);
} }

View File

@ -147,8 +147,9 @@ pub async fn get_user(
if let Some("/cancel") = msg.text().map(str::trim) { if let Some("/cancel") = msg.text().map(str::trim) {
dialogue.exit().await?; dialogue.exit().await?;
bot.send_message(msg.chat.id, "Successfully cancelled") handler
.reply_markup(deletion_markup()) .previous
.alter_message(&bot, "Successfully cancelled", deletion_markup(), None)
.await?; .await?;
return Ok(()); return Ok(());
} }
@ -156,8 +157,10 @@ pub async fn get_user(
let file = match validate_document(msg.document()) { let file = match validate_document(msg.document()) {
Ok(document) => &document.file, Ok(document) => &document.file,
Err(text) => { Err(text) => {
let msg = bot.send_message(msg.chat.id, text).await?; handler
handler.previous = MessageIds::from(&msg); .previous
.alter_message(&bot, text, None, None)
.await?;
return Ok(()); return Ok(());
} }
}; };
@ -175,15 +178,17 @@ pub async fn get_user(
let user = match spawn_blocking(move || user_from_vec(data, existing_names)).await? { let user = match spawn_blocking(move || user_from_vec(data, existing_names)).await? {
Ok(Ok(user)) => user, Ok(Ok(user)) => user,
Ok(Err(error_text)) => { Ok(Err(error_text)) => {
let msg = bot.send_message(msg.chat.id, error_text).await?; handler
handler.previous = MessageIds::from(&msg); .previous
.alter_message(&bot, error_text, None, None)
.await?;
return Ok(()); return Ok(());
} }
Err(_) => { Err(_) => {
let msg = bot handler
.send_message(msg.chat.id, "Error parsing the json file. Try again") .previous
.alter_message(&bot, "Error parsing the json file. Try again", None, None)
.await?; .await?;
handler.previous = MessageIds::from(&msg);
return Ok(()); return Ok(());
} }
}; };

View File

@ -1,17 +1,62 @@
use crate::prelude::*; use crate::prelude::*;
use futures::future::BoxFuture; use futures::future::BoxFuture;
use std::sync::Arc; use std::{mem, sync::Arc};
use teloxide::types::{InlineKeyboardMarkup, MessageId}; use teloxide::{
use tokio::sync::Mutex; requests::HasPayload,
types::{InlineKeyboardMarkup, MessageId, ParseMode},
RequestError,
};
use tokio::{join, sync::Mutex};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct MessageIds(pub ChatId, pub MessageId); pub struct MessageIds(pub ChatId, pub MessageId);
impl MessageIds { impl MessageIds {
#[inline] #[inline]
pub async fn delete(&self, bot: &Throttle<Bot>) { pub async fn delete(self, bot: &Throttle<Bot>) {
let _ = bot.delete_message(self.0, self.1).await; let _ = bot.delete_message(self.0, self.1).await;
} }
/// Tries to alter the message or sends a new one
///
/// # Returns
///
/// Returns true if the message was edited successfully. Returns false otherwise
#[inline]
pub async fn alter_message(
&mut self,
bot: &Throttle<Bot>,
text: impl Into<String>,
markup: impl Into<Option<InlineKeyboardMarkup>>,
parse_mode: impl Into<Option<ParseMode>> + Copy,
) -> crate::Result<()> {
let mut edit = bot.edit_message_text(self.0, self.1, text);
edit.parse_mode = parse_mode.into();
let mut markup = markup.into();
if let Some(markup) = markup {
edit = edit.reply_markup(markup)
}
match edit.send_ref().await {
Ok(msg) => return Ok(()),
Err(RequestError::Api(_)) => (),
Err(err) => return Err(err.into()),
};
let text = mem::take(&mut edit.text);
markup = mem::take(&mut edit.reply_markup);
let mut send = bot.send_message(self.0, text);
send.payload_mut().parse_mode = parse_mode.into();
if let Some(markup) = markup {
send = send.reply_markup(markup);
}
let msg = join!(self.delete(bot), send.send()).1?;
*self = Self::from(&msg);
Ok(())
}
} }
impl From<&Message> for MessageIds { impl From<&Message> for MessageIds {