move target into state
This commit is contained in:
@@ -12,7 +12,6 @@ use crate::{
|
||||
dptree_utils::MapTwo,
|
||||
handle_error::with_error_handler,
|
||||
handler_utils::find_listing_by_id,
|
||||
message_utils::MessageTarget,
|
||||
start_command_data::StartCommandData,
|
||||
App, BotError, BotHandler, BotResult, DialogueRootState, RootDialogue,
|
||||
};
|
||||
@@ -75,7 +74,6 @@ pub fn bidding_handler() -> BotHandler {
|
||||
async fn handle_place_bid_on_listing(
|
||||
app: App,
|
||||
user_dao: UserDAO,
|
||||
target: MessageTarget,
|
||||
user: PersistedUser,
|
||||
listing: PersistedListing,
|
||||
dialogue: RootDialogue,
|
||||
@@ -116,7 +114,7 @@ async fn handle_place_bid_on_listing(
|
||||
.append_row([InlineKeyboardButton::callback("Bid $1", "cancel")]);
|
||||
|
||||
app.bot
|
||||
.send_html_message(target, response_lines.join("\n"), Some(keyboard))
|
||||
.send_html_message(response_lines.join("\n"), Some(keyboard))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
@@ -125,7 +123,6 @@ async fn handle_place_bid_on_listing(
|
||||
async fn handle_awaiting_bid_amount_input(
|
||||
app: App,
|
||||
listing: PersistedListing,
|
||||
target: MessageTarget,
|
||||
dialogue: RootDialogue,
|
||||
msg: Message,
|
||||
) -> BotResult {
|
||||
@@ -146,7 +143,6 @@ async fn handle_awaiting_bid_amount_input(
|
||||
let bid_amount_str = format!("{}{}", listing.base.currency_type.symbol(), bid_amount);
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
format!("Confirm bid amount: {bid_amount_str} - this cannot be undone!"),
|
||||
Some(InlineKeyboardMarkup::default().append_row([
|
||||
InlineKeyboardButton::callback(
|
||||
@@ -174,7 +170,6 @@ async fn handle_awaiting_confirm_bid_amount_callback(
|
||||
listing: PersistedListing,
|
||||
user: PersistedUser,
|
||||
bid_amount: MoneyAmount,
|
||||
target: MessageTarget,
|
||||
dialogue: RootDialogue,
|
||||
callback_query: CallbackQuery,
|
||||
) -> BotResult {
|
||||
@@ -188,7 +183,7 @@ async fn handle_awaiting_confirm_bid_amount_callback(
|
||||
"cancel_bid" => {
|
||||
dialogue.exit().await.context("failed to exit dialogue")?;
|
||||
app.bot
|
||||
.send_html_message(target, "Bid cancelled".to_string(), None)
|
||||
.send_html_message("Bid cancelled".to_string(), None)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
@@ -206,8 +201,8 @@ async fn handle_awaiting_confirm_bid_amount_callback(
|
||||
|
||||
let bid_amount_str = format!("{}{}", listing.base.currency_type.symbol(), bid_amount);
|
||||
app.bot
|
||||
.with_target(callback_query.from.into())
|
||||
.send_html_message(
|
||||
target.only_chat_id(),
|
||||
format!("Bid placed for {bid_amount_str} on {}", listing.base.title),
|
||||
None,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{message_utils::MessageTarget, App, BotResult, Command};
|
||||
use crate::{App, BotResult, Command};
|
||||
use teloxide::utils::command::BotCommands;
|
||||
|
||||
pub async fn handle_help(app: App, target: MessageTarget) -> BotResult {
|
||||
pub async fn handle_help(app: App) -> BotResult {
|
||||
let help_message = format!(
|
||||
"📋 Available Commands:\n\n{}\n\n\
|
||||
📧 Support: Contact @admin for help\n\
|
||||
@@ -9,8 +9,6 @@ pub async fn handle_help(app: App, target: MessageTarget) -> BotResult {
|
||||
Command::descriptions()
|
||||
);
|
||||
|
||||
app.bot
|
||||
.send_html_message(target, help_message, None)
|
||||
.await?;
|
||||
app.bot.send_html_message(help_message, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{message_utils::MessageTarget, App, BotResult};
|
||||
use crate::{App, BotResult};
|
||||
use log::info;
|
||||
use teloxide::types::Message;
|
||||
|
||||
pub async fn handle_my_bids(app: App, msg: Message, target: MessageTarget) -> BotResult {
|
||||
pub async fn handle_my_bids(app: App, msg: Message) -> BotResult {
|
||||
let response = "🎯 My Bids (Coming Soon)\n\n\
|
||||
Here you'll be able to view:\n\
|
||||
• Your active bids\n\
|
||||
@@ -18,6 +18,6 @@ pub async fn handle_my_bids(app: App, msg: Message, target: MessageTarget) -> Bo
|
||||
msg.chat.id
|
||||
);
|
||||
|
||||
app.bot.send_html_message(target, response, None).await?;
|
||||
app.bot.send_html_message(response, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
},
|
||||
handle_error::with_error_handler,
|
||||
handler_utils::{find_listing_by_id, find_or_create_db_user_from_update},
|
||||
message_utils::{extract_callback_data, pluralize_with_count, MessageTarget},
|
||||
message_utils::{extract_callback_data, pluralize_with_count},
|
||||
start_command_data::StartCommandData,
|
||||
App, BotError, BotResult, Command, DialogueRootState, RootDialogue,
|
||||
};
|
||||
@@ -87,12 +87,8 @@ pub fn my_listings_handler() -> Handler<'static, BotResult, DpHandlerDescription
|
||||
)
|
||||
}
|
||||
|
||||
async fn handle_view_listing_details(
|
||||
app: App,
|
||||
listing: PersistedListing,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
send_listing_details_message(app, target, listing, None).await?;
|
||||
async fn handle_view_listing_details(app: App, listing: PersistedListing) -> BotResult {
|
||||
send_listing_details_message(app, listing, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -230,9 +226,8 @@ async fn handle_my_listings_command_input(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
user: PersistedUser,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
enter_my_listings(app, dialogue, user, target, None).await?;
|
||||
enter_my_listings(app, dialogue, user, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -240,7 +235,6 @@ pub async fn enter_my_listings(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
user: PersistedUser,
|
||||
target: MessageTarget,
|
||||
flash: Option<String>,
|
||||
) -> BotResult {
|
||||
// Transition to ViewingListings state
|
||||
@@ -263,7 +257,6 @@ pub async fn enter_my_listings(
|
||||
if listings.is_empty() {
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
"📋 <b>My Listings</b>\n\n\
|
||||
You don't have any listings yet."
|
||||
.to_string(),
|
||||
@@ -284,9 +277,7 @@ pub async fn enter_my_listings(
|
||||
response = format!("{flash}\n\n{response}");
|
||||
}
|
||||
|
||||
app.bot
|
||||
.send_html_message(target, response, Some(keyboard))
|
||||
.await?;
|
||||
app.bot.send_html_message(response, Some(keyboard)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -295,12 +286,11 @@ async fn handle_viewing_listings_callback(
|
||||
dialogue: RootDialogue,
|
||||
callback_query: CallbackQuery,
|
||||
user: PersistedUser,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(app.bot.deref(), callback_query).await?;
|
||||
|
||||
if let Ok(NavKeyboardButtons::Back) = NavKeyboardButtons::try_from(data.as_str()) {
|
||||
return enter_main_menu(app, dialogue, target).await;
|
||||
return enter_main_menu(app, dialogue).await;
|
||||
}
|
||||
|
||||
// Check if it's the back to menu button
|
||||
@@ -308,10 +298,10 @@ async fn handle_viewing_listings_callback(
|
||||
match button {
|
||||
MyListingsButtons::SelectListing(listing_id) => {
|
||||
let listing = get_listing_for_user(&app.daos, user, listing_id).await?;
|
||||
enter_show_listing_details(app, dialogue, listing, target).await?;
|
||||
enter_show_listing_details(app, dialogue, listing).await?;
|
||||
}
|
||||
MyListingsButtons::NewListing => {
|
||||
enter_select_new_listing_type(app, dialogue, target).await?;
|
||||
enter_select_new_listing_type(app, dialogue).await?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +312,6 @@ async fn enter_show_listing_details(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
listing: PersistedListing,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let listing_id = listing.persisted.id;
|
||||
dialogue
|
||||
@@ -342,13 +331,12 @@ async fn enter_show_listing_details(
|
||||
ManageListingButtons::Delete.to_button(),
|
||||
])
|
||||
.append_row([ManageListingButtons::Back.to_button()]);
|
||||
send_listing_details_message(app, target, listing, Some(keyboard)).await?;
|
||||
send_listing_details_message(app, listing, Some(keyboard)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_listing_details_message(
|
||||
app: App,
|
||||
target: MessageTarget,
|
||||
listing: PersistedListing,
|
||||
keyboard: Option<InlineKeyboardMarkup>,
|
||||
) -> BotResult {
|
||||
@@ -365,7 +353,7 @@ async fn send_listing_details_message(
|
||||
response_lines.push(format!("<b>{}:</b> {}", step.field_name, field_value));
|
||||
}
|
||||
app.bot
|
||||
.send_html_message(target, response_lines.join("\n"), keyboard)
|
||||
.send_html_message(response_lines.join("\n"), keyboard)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -376,7 +364,6 @@ async fn handle_managing_listing_callback(
|
||||
callback_query: CallbackQuery,
|
||||
user: PersistedUser,
|
||||
listing_id: ListingDbId,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let from = callback_query.from.clone();
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
@@ -397,21 +384,14 @@ async fn handle_managing_listing_callback(
|
||||
ManageListingButtons::Edit => {
|
||||
let listing = get_listing_for_user(&app.daos, user, listing_id).await?;
|
||||
let draft = ListingDraft::from_persisted(listing);
|
||||
enter_edit_listing_draft(app, target, draft, dialogue, None).await?;
|
||||
enter_edit_listing_draft(app, draft, dialogue, None).await?;
|
||||
}
|
||||
ManageListingButtons::Delete => {
|
||||
app.daos.listing.delete_listing(listing_id).await?;
|
||||
enter_my_listings(
|
||||
app,
|
||||
dialogue,
|
||||
user,
|
||||
target,
|
||||
Some("Listing deleted.".to_string()),
|
||||
)
|
||||
.await?;
|
||||
enter_my_listings(app, dialogue, user, Some("Listing deleted.".to_string())).await?;
|
||||
}
|
||||
ManageListingButtons::Back => {
|
||||
enter_my_listings(app, dialogue, user, target, None).await?;
|
||||
enter_my_listings(app, dialogue, user, None).await?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,9 +439,10 @@ async fn send_preview_listing_message(
|
||||
if let Some(description) = &listing.base.description {
|
||||
response_lines.push(description.to_owned());
|
||||
}
|
||||
|
||||
app.bot
|
||||
.with_target(from.into())
|
||||
.send_html_message(
|
||||
from.into(),
|
||||
response_lines.join("\n\n"),
|
||||
Some(keyboard_for_listing(&listing)),
|
||||
)
|
||||
|
||||
@@ -28,13 +28,12 @@ pub async fn handle_selecting_listing_type_callback(
|
||||
dialogue: RootDialogue,
|
||||
user: PersistedUser,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
info!("User {target:?} selected listing type: {data:?}");
|
||||
info!("User selected listing type: {data:?}");
|
||||
|
||||
if let Ok(NavKeyboardButtons::Back) = NavKeyboardButtons::try_from(data.as_str()) {
|
||||
return enter_my_listings(app, dialogue, user, target, None).await;
|
||||
return enter_my_listings(app, dialogue, user, None).await;
|
||||
}
|
||||
|
||||
// Parse the listing type from callback data
|
||||
@@ -62,11 +61,7 @@ pub async fn handle_selecting_listing_type_callback(
|
||||
);
|
||||
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
response,
|
||||
get_keyboard_for_field(ListingField::Title),
|
||||
)
|
||||
.send_html_message(response, get_keyboard_for_field(ListingField::Title))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
@@ -79,21 +74,20 @@ pub async fn handle_awaiting_draft_field_callback(
|
||||
field: ListingField,
|
||||
draft: ListingDraft,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
info!("User {target:?} selected callback: {data:?}");
|
||||
info!("User selected callback: {data:?}");
|
||||
|
||||
if let Ok(button) = NavKeyboardButtons::try_from(data.as_str()) {
|
||||
match button {
|
||||
NavKeyboardButtons::Back => {
|
||||
return enter_select_new_listing_type(app, dialogue, target).await;
|
||||
return enter_select_new_listing_type(app, dialogue).await;
|
||||
}
|
||||
NavKeyboardButtons::Skip => {
|
||||
return handle_skip_field(app, dialogue, field, draft, target).await;
|
||||
return handle_skip_field(app, dialogue, field, draft).await;
|
||||
}
|
||||
NavKeyboardButtons::Cancel => {
|
||||
return cancel_wizard(app, dialogue, target).await;
|
||||
return cancel_wizard(app, dialogue).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,23 +96,23 @@ pub async fn handle_awaiting_draft_field_callback(
|
||||
match field {
|
||||
ListingField::Slots => {
|
||||
let button = SlotsKeyboardButtons::try_from(data.as_str())?;
|
||||
handle_slots_callback(app, dialogue, draft, button, target).await
|
||||
handle_slots_callback(app, dialogue, draft, button).await
|
||||
}
|
||||
ListingField::StartTime => {
|
||||
let button = StartTimeKeyboardButtons::try_from(data.as_str())?;
|
||||
handle_start_time_callback(app, dialogue, draft, button, target).await
|
||||
handle_start_time_callback(app, dialogue, draft, button).await
|
||||
}
|
||||
ListingField::EndTime => {
|
||||
let button = DurationKeyboardButtons::try_from(data.as_str())?;
|
||||
handle_duration_callback(app, dialogue, draft, button, target).await
|
||||
handle_duration_callback(app, dialogue, draft, button).await
|
||||
}
|
||||
ListingField::MinBidIncrement => {
|
||||
let button = EditMinimumBidIncrementKeyboardButtons::try_from(data.as_str())?;
|
||||
handle_starting_bid_amount_callback(app, dialogue, draft, button, target).await
|
||||
handle_starting_bid_amount_callback(app, dialogue, draft, button).await
|
||||
}
|
||||
ListingField::CurrencyType => {
|
||||
let button = CurrencyTypeKeyboardButtons::try_from(data.as_str())?;
|
||||
handle_currency_type_callback(app, dialogue, draft, button, target).await
|
||||
handle_currency_type_callback(app, dialogue, draft, button).await
|
||||
}
|
||||
_ => {
|
||||
error!("Unknown callback data for field {field:?}: {data}");
|
||||
@@ -132,7 +126,6 @@ async fn handle_skip_field(
|
||||
dialogue: RootDialogue,
|
||||
current_field: ListingField,
|
||||
draft: ListingDraft,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let field_name = get_field_name(current_field, draft.listing_type());
|
||||
let next_field = get_next_field(current_field, draft.listing_type());
|
||||
@@ -145,10 +138,10 @@ async fn handle_skip_field(
|
||||
);
|
||||
transition_to_field(dialogue, next_field, draft).await?;
|
||||
app.bot
|
||||
.send_html_message(target, response, get_keyboard_for_field(next_field))
|
||||
.send_html_message(response, get_keyboard_for_field(next_field))
|
||||
.await?;
|
||||
} else {
|
||||
enter_confirm_save_listing(app, dialogue, target, draft, Some(flash)).await?;
|
||||
enter_confirm_save_listing(app, dialogue, draft, Some(flash)).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -159,7 +152,6 @@ async fn handle_slots_callback(
|
||||
dialogue: RootDialogue,
|
||||
mut draft: ListingDraft,
|
||||
button: SlotsKeyboardButtons,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let num_slots = match button {
|
||||
SlotsKeyboardButtons::OneSlot => 1,
|
||||
@@ -181,11 +173,7 @@ async fn handle_slots_callback(
|
||||
);
|
||||
transition_to_field(dialogue, ListingField::StartTime, draft).await?;
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
response,
|
||||
get_keyboard_for_field(ListingField::StartTime),
|
||||
)
|
||||
.send_html_message(response, get_keyboard_for_field(ListingField::StartTime))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -196,7 +184,6 @@ async fn handle_start_time_callback(
|
||||
dialogue: RootDialogue,
|
||||
mut draft: ListingDraft,
|
||||
button: StartTimeKeyboardButtons,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let start_time = match button {
|
||||
StartTimeKeyboardButtons::Now => ListingDuration::zero(),
|
||||
@@ -216,11 +203,7 @@ async fn handle_start_time_callback(
|
||||
);
|
||||
transition_to_field(dialogue, ListingField::EndTime, draft).await?;
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
response,
|
||||
get_keyboard_for_field(ListingField::EndTime),
|
||||
)
|
||||
.send_html_message(response, get_keyboard_for_field(ListingField::EndTime))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -231,7 +214,6 @@ async fn handle_duration_callback(
|
||||
dialogue: RootDialogue,
|
||||
mut draft: ListingDraft,
|
||||
button: DurationKeyboardButtons,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let duration = ListingDuration::days(match button {
|
||||
DurationKeyboardButtons::OneDay => 1,
|
||||
@@ -248,7 +230,7 @@ async fn handle_duration_callback(
|
||||
.map_err(|e| anyhow::anyhow!("Error updating duration: {e:?}"))?;
|
||||
|
||||
let flash = get_success_message(ListingField::EndTime, draft.listing_type());
|
||||
enter_confirm_save_listing(app, dialogue, target, draft, Some(flash)).await
|
||||
enter_confirm_save_listing(app, dialogue, draft, Some(flash)).await
|
||||
}
|
||||
|
||||
async fn handle_starting_bid_amount_callback(
|
||||
@@ -256,7 +238,6 @@ async fn handle_starting_bid_amount_callback(
|
||||
dialogue: RootDialogue,
|
||||
mut draft: ListingDraft,
|
||||
button: EditMinimumBidIncrementKeyboardButtons,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let starting_bid_amount = MoneyAmount::from_str(match button {
|
||||
EditMinimumBidIncrementKeyboardButtons::OneDollar => "1.00",
|
||||
@@ -273,7 +254,7 @@ async fn handle_starting_bid_amount_callback(
|
||||
.map_err(|e| anyhow::anyhow!("Error updating starting bid amount: {e:?}"))?;
|
||||
|
||||
let flash = get_success_message(ListingField::StartingBidAmount, draft.listing_type());
|
||||
enter_confirm_save_listing(app, dialogue, target, draft, Some(flash)).await
|
||||
enter_confirm_save_listing(app, dialogue, draft, Some(flash)).await
|
||||
}
|
||||
|
||||
async fn handle_currency_type_callback(
|
||||
@@ -281,7 +262,6 @@ async fn handle_currency_type_callback(
|
||||
dialogue: RootDialogue,
|
||||
mut draft: ListingDraft,
|
||||
button: CurrencyTypeKeyboardButtons,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let currency_type = match button {
|
||||
CurrencyTypeKeyboardButtons::Usd => CurrencyType::Usd,
|
||||
@@ -305,14 +285,14 @@ async fn handle_currency_type_callback(
|
||||
);
|
||||
transition_to_field(dialogue, next_field, draft).await?;
|
||||
app.bot
|
||||
.send_html_message(target, response, get_keyboard_for_field(next_field))
|
||||
.send_html_message(response, get_keyboard_for_field(next_field))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Cancel the wizard and exit
|
||||
pub async fn cancel_wizard(app: App, dialogue: RootDialogue, target: MessageTarget) -> BotResult {
|
||||
info!("{target:?} cancelled new listing wizard");
|
||||
enter_select_new_listing_type(app, dialogue, target).await?;
|
||||
pub async fn cancel_wizard(app: App, dialogue: RootDialogue) -> BotResult {
|
||||
info!("User cancelled new listing wizard");
|
||||
enter_select_new_listing_type(app, dialogue).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -35,20 +35,12 @@ use log::info;
|
||||
use teloxide::{prelude::*, types::*};
|
||||
|
||||
/// Handle the /newlisting command - starts the dialogue
|
||||
pub(super) async fn handle_new_listing_command(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
enter_select_new_listing_type(app, dialogue, target).await?;
|
||||
pub(super) async fn handle_new_listing_command(app: App, dialogue: RootDialogue) -> BotResult {
|
||||
enter_select_new_listing_type(app, dialogue).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn enter_select_new_listing_type(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
pub async fn enter_select_new_listing_type(app: App, dialogue: RootDialogue) -> BotResult {
|
||||
// Initialize the dialogue to listing type selection state
|
||||
dialogue
|
||||
.update(NewListingState::SelectingListingType)
|
||||
@@ -57,7 +49,6 @@ pub async fn enter_select_new_listing_type(
|
||||
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
get_listing_type_selection_message().to_string(),
|
||||
Some(get_listing_type_keyboard()),
|
||||
)
|
||||
@@ -71,10 +62,9 @@ pub async fn handle_awaiting_draft_field_input(
|
||||
dialogue: RootDialogue,
|
||||
field: ListingField,
|
||||
mut draft: ListingDraft,
|
||||
target: MessageTarget,
|
||||
msg: Message,
|
||||
) -> BotResult {
|
||||
info!("User {target:?} entered input step: {field:?}");
|
||||
info!("User entered input step: {field:?}");
|
||||
|
||||
// Process the field update
|
||||
match update_field_on_draft(field, &mut draft, msg.text()) {
|
||||
@@ -99,11 +89,11 @@ pub async fn handle_awaiting_draft_field_input(
|
||||
);
|
||||
transition_to_field(dialogue, next_field, draft).await?;
|
||||
app.bot
|
||||
.send_html_message(target, response, get_keyboard_for_field(next_field))
|
||||
.send_html_message(response, get_keyboard_for_field(next_field))
|
||||
.await?;
|
||||
} else {
|
||||
// Final step - go to confirmation
|
||||
enter_confirm_save_listing(app, dialogue, target, draft, None).await?;
|
||||
enter_confirm_save_listing(app, dialogue, draft, None).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -114,10 +104,9 @@ pub async fn handle_editing_field_input(
|
||||
dialogue: RootDialogue,
|
||||
field: ListingField,
|
||||
mut draft: ListingDraft,
|
||||
target: MessageTarget,
|
||||
msg: Message,
|
||||
) -> BotResult {
|
||||
info!("User {target:?} editing field {field:?}");
|
||||
info!("User editing field {field:?}");
|
||||
|
||||
// Process the field update
|
||||
match update_field_on_draft(field, &mut draft, msg.text()) {
|
||||
@@ -134,7 +123,7 @@ pub async fn handle_editing_field_input(
|
||||
};
|
||||
|
||||
let flash = get_edit_success_message(field, draft.listing_type());
|
||||
enter_edit_listing_draft(app, target, draft, dialogue, Some(flash)).await?;
|
||||
enter_edit_listing_draft(app, draft, dialogue, Some(flash)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -145,37 +134,36 @@ pub async fn handle_viewing_draft_callback(
|
||||
draft: ListingDraft,
|
||||
user: PersistedUser,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
|
||||
match ConfirmationKeyboardButtons::try_from(data.as_str())? {
|
||||
ConfirmationKeyboardButtons::Create | ConfirmationKeyboardButtons::Save => {
|
||||
info!("User {target:?} confirmed listing creation");
|
||||
info!("User confirmed listing creation");
|
||||
let success_message = save_listing(&app.daos.listing, draft).await?;
|
||||
enter_my_listings(app, dialogue, user, target, Some(success_message)).await?;
|
||||
enter_my_listings(app, dialogue, user, Some(success_message)).await?;
|
||||
}
|
||||
ConfirmationKeyboardButtons::Cancel => {
|
||||
info!("User {target:?} cancelled listing update");
|
||||
info!("User cancelled listing update");
|
||||
let response = "🗑️ <b>Changes Discarded</b>\n\n\
|
||||
Your changes have been discarded and not saved."
|
||||
.to_string();
|
||||
app.bot.send_html_message(target, response, None).await?;
|
||||
app.bot.send_html_message(response, None).await?;
|
||||
dialogue.exit().await.context("failed to exit dialogue")?;
|
||||
}
|
||||
ConfirmationKeyboardButtons::Discard => {
|
||||
info!("User {target:?} discarded listing creation");
|
||||
info!("User discarded listing creation");
|
||||
|
||||
let response = "🗑️ <b>Listing Discarded</b>\n\n\
|
||||
Your listing has been discarded and not created.\n\
|
||||
You can start a new listing anytime with /newlisting."
|
||||
.to_string();
|
||||
app.bot.send_html_message(target, response, None).await?;
|
||||
app.bot.send_html_message(response, None).await?;
|
||||
dialogue.exit().await.context("failed to exit dialogue")?;
|
||||
}
|
||||
ConfirmationKeyboardButtons::Edit => {
|
||||
info!("User {target:?} chose to edit listing");
|
||||
enter_edit_listing_draft(app, target, draft, dialogue, None).await?;
|
||||
info!("User chose to edit listing");
|
||||
enter_edit_listing_draft(app, draft, dialogue, None).await?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,14 +176,13 @@ pub async fn handle_editing_draft_callback(
|
||||
draft: ListingDraft,
|
||||
dialogue: RootDialogue,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
info!("User {target:?} in editing screen, showing field selection");
|
||||
info!("User in editing screen, showing field selection");
|
||||
|
||||
let button = FieldSelectionKeyboardButtons::try_from(data.as_str())?;
|
||||
if button == FieldSelectionKeyboardButtons::Done {
|
||||
return enter_confirm_save_listing(app, dialogue, target, draft, None).await;
|
||||
return enter_confirm_save_listing(app, dialogue, draft, None).await;
|
||||
}
|
||||
|
||||
let field = match button {
|
||||
@@ -221,9 +208,7 @@ pub async fn handle_editing_draft_callback(
|
||||
.context("failed to update dialogue")?;
|
||||
|
||||
let response = format!("Editing {field:?}\n\nPrevious value: {value}");
|
||||
app.bot
|
||||
.send_html_message(target, response, Some(keyboard))
|
||||
.await?;
|
||||
app.bot.send_html_message(response, Some(keyboard)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -235,19 +220,18 @@ pub async fn handle_editing_draft_field_callback(
|
||||
field: ListingField,
|
||||
draft: ListingDraft,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
info!("User {target:?} editing field: {field:?} -> {data:?}");
|
||||
info!("User editing field: {field:?} -> {data:?}");
|
||||
|
||||
if data == "edit_back" {
|
||||
enter_edit_listing_draft(app, target, draft, dialogue, None).await?;
|
||||
enter_edit_listing_draft(app, draft, dialogue, None).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// This callback handler typically receives button presses, not text input
|
||||
// For now, just redirect back to edit screen since callback data isn't suitable for validation
|
||||
enter_edit_listing_draft(app, target, draft, dialogue, None).await?;
|
||||
enter_edit_listing_draft(app, draft, dialogue, None).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -255,14 +239,12 @@ pub async fn handle_editing_draft_field_callback(
|
||||
/// Enter the edit listing draft screen
|
||||
pub async fn enter_edit_listing_draft(
|
||||
app: App,
|
||||
target: MessageTarget,
|
||||
draft: ListingDraft,
|
||||
dialogue: RootDialogue,
|
||||
flash_message: Option<String>,
|
||||
) -> BotResult {
|
||||
display_listing_summary(
|
||||
app,
|
||||
target,
|
||||
&draft,
|
||||
Some(FieldSelectionKeyboardButtons::to_keyboard()),
|
||||
flash_message,
|
||||
|
||||
@@ -9,14 +9,13 @@ use crate::commands::new_listing::NewListingState;
|
||||
use crate::db::ListingType;
|
||||
use crate::App;
|
||||
use crate::RootDialogue;
|
||||
use crate::{commands::new_listing::types::ListingDraft, message_utils::*, BotResult};
|
||||
use crate::{commands::new_listing::types::ListingDraft, BotResult};
|
||||
use anyhow::Context;
|
||||
use teloxide::types::InlineKeyboardMarkup;
|
||||
|
||||
/// Display the listing summary with optional flash message and keyboard
|
||||
pub async fn display_listing_summary(
|
||||
app: App,
|
||||
target: MessageTarget,
|
||||
draft: &ListingDraft,
|
||||
keyboard: Option<InlineKeyboardMarkup>,
|
||||
flash_message: Option<String>,
|
||||
@@ -50,7 +49,7 @@ pub async fn display_listing_summary(
|
||||
response_lines.push("Edit your listing:".to_string());
|
||||
|
||||
app.bot
|
||||
.send_html_message(target, response_lines.join("\n"), keyboard)
|
||||
.send_html_message(response_lines.join("\n"), keyboard)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
@@ -60,7 +59,6 @@ pub async fn display_listing_summary(
|
||||
pub async fn enter_confirm_save_listing(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
target: MessageTarget,
|
||||
draft: ListingDraft,
|
||||
flash: Option<String>,
|
||||
) -> BotResult {
|
||||
@@ -78,7 +76,7 @@ pub async fn enter_confirm_save_listing(
|
||||
])
|
||||
};
|
||||
|
||||
display_listing_summary(app, target, &draft, Some(keyboard), flash).await?;
|
||||
display_listing_summary(app, &draft, Some(keyboard), flash).await?;
|
||||
dialogue
|
||||
.update(NewListingState::ViewingDraft(draft))
|
||||
.await
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{message_utils::MessageTarget, App, BotResult};
|
||||
use crate::{App, BotResult};
|
||||
use log::info;
|
||||
use teloxide::types::Message;
|
||||
|
||||
pub async fn handle_settings(app: App, msg: Message, target: MessageTarget) -> BotResult {
|
||||
pub async fn handle_settings(app: App, msg: Message) -> BotResult {
|
||||
let response = "⚙️ Settings (Coming Soon)\n\n\
|
||||
Here you'll be able to configure:\n\
|
||||
• Notification preferences\n\
|
||||
@@ -18,6 +18,6 @@ pub async fn handle_settings(app: App, msg: Message, target: MessageTarget) -> B
|
||||
msg.chat.id
|
||||
);
|
||||
|
||||
app.bot.send_html_message(target, response, None).await?;
|
||||
app.bot.send_html_message(response, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,11 +6,8 @@ use teloxide::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
commands::my_listings::enter_my_listings,
|
||||
db::user::PersistedUser,
|
||||
keyboard_buttons,
|
||||
message_utils::{extract_callback_data, MessageTarget},
|
||||
App, BotResult, Command, DialogueRootState, RootDialogue,
|
||||
commands::my_listings::enter_my_listings, db::user::PersistedUser, keyboard_buttons,
|
||||
message_utils::extract_callback_data, App, BotResult, Command, DialogueRootState, RootDialogue,
|
||||
};
|
||||
|
||||
keyboard_buttons! {
|
||||
@@ -37,19 +34,14 @@ fn get_main_menu_message() -> &'static str {
|
||||
Choose an option below to get started! 🚀"
|
||||
}
|
||||
|
||||
pub async fn handle_start(
|
||||
app: App,
|
||||
dialogue: RootDialogue,
|
||||
target: MessageTarget,
|
||||
update: Update,
|
||||
) -> BotResult {
|
||||
pub async fn handle_start(app: App, dialogue: RootDialogue, update: Update) -> BotResult {
|
||||
info!("got start message: {update:?}");
|
||||
enter_main_menu(app, dialogue, target).await?;
|
||||
enter_main_menu(app, dialogue).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Show the main menu with buttons
|
||||
pub async fn enter_main_menu(app: App, dialogue: RootDialogue, target: MessageTarget) -> BotResult {
|
||||
pub async fn enter_main_menu(app: App, dialogue: RootDialogue) -> BotResult {
|
||||
dialogue
|
||||
.update(DialogueRootState::MainMenu)
|
||||
.await
|
||||
@@ -57,7 +49,6 @@ pub async fn enter_main_menu(app: App, dialogue: RootDialogue, target: MessageTa
|
||||
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
get_main_menu_message().to_string(),
|
||||
Some(MainMenuButtons::to_keyboard()),
|
||||
)
|
||||
@@ -71,21 +62,19 @@ pub async fn handle_main_menu_callback(
|
||||
dialogue: RootDialogue,
|
||||
user: PersistedUser,
|
||||
callback_query: CallbackQuery,
|
||||
target: MessageTarget,
|
||||
) -> BotResult {
|
||||
let data = extract_callback_data(&app.bot, callback_query).await?;
|
||||
info!("User {target:?} selected main menu option: {data:?}");
|
||||
info!("User selected main menu option: {data:?}");
|
||||
|
||||
let button = MainMenuButtons::try_from(data.as_str())?;
|
||||
match button {
|
||||
MainMenuButtons::MyListings => {
|
||||
// Call show_listings_for_user directly
|
||||
enter_my_listings(app, dialogue, user, target, None).await?;
|
||||
enter_my_listings(app, dialogue, user, None).await?;
|
||||
}
|
||||
MainMenuButtons::MyBids => {
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
"💰 <b>My Bids (Coming Soon)</b>\n\n\
|
||||
Here you'll be able to view:\n\
|
||||
• Your active bids\n\
|
||||
@@ -101,7 +90,6 @@ pub async fn handle_main_menu_callback(
|
||||
MainMenuButtons::Settings => {
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
"⚙️ <b>Settings (Coming Soon)</b>\n\n\
|
||||
Here you'll be able to configure:\n\
|
||||
• Notification preferences\n\
|
||||
@@ -122,7 +110,7 @@ pub async fn handle_main_menu_callback(
|
||||
Command::descriptions()
|
||||
);
|
||||
app.bot
|
||||
.send_html_message(target, help_message, Some(MainMenuButtons::to_keyboard()))
|
||||
.send_html_message(help_message, Some(MainMenuButtons::to_keyboard()))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
use crate::{
|
||||
message_utils::MessageTarget, wrap_endpoint, App, BotError, BotResult, WrappedAsyncFn,
|
||||
};
|
||||
use crate::{wrap_endpoint, App, BotError, BotResult, WrappedAsyncFn};
|
||||
use futures::future::BoxFuture;
|
||||
|
||||
pub async fn handle_error(app: App, target: MessageTarget, error: BotError) -> BotResult {
|
||||
pub async fn handle_error(app: App, error: BotError) -> BotResult {
|
||||
log::error!("Error in handler: {error:?}");
|
||||
match error {
|
||||
BotError::UserVisibleError(message) => {
|
||||
app.bot.send_html_message(target, message, None).await?
|
||||
}
|
||||
BotError::UserVisibleError(message) => app.bot.send_html_message(message, None).await?,
|
||||
BotError::InternalError(_) => {
|
||||
app.bot
|
||||
.send_html_message(
|
||||
target,
|
||||
"An internal error occurred. Please try again later.".to_string(),
|
||||
None,
|
||||
)
|
||||
@@ -22,20 +17,16 @@ pub async fn handle_error(app: App, target: MessageTarget, error: BotError) -> B
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn boxed_handle_error(
|
||||
app: App,
|
||||
target: MessageTarget,
|
||||
error: BotError,
|
||||
) -> BoxFuture<'static, BotResult> {
|
||||
Box::pin(handle_error(app, target, error))
|
||||
fn boxed_handle_error(app: App, error: BotError) -> BoxFuture<'static, BotResult> {
|
||||
Box::pin(handle_error(app, error))
|
||||
}
|
||||
|
||||
pub type ErrorHandlerWrapped<FnBase, FnBaseArgs> = WrappedAsyncFn<
|
||||
FnBase,
|
||||
fn(App, MessageTarget, BotError) -> BoxFuture<'static, BotResult>,
|
||||
fn(App, BotError) -> BoxFuture<'static, BotResult>,
|
||||
BotError,
|
||||
FnBaseArgs,
|
||||
(App, MessageTarget),
|
||||
(App,),
|
||||
>;
|
||||
|
||||
pub fn with_error_handler<FnBase, FnBaseArgs>(
|
||||
|
||||
33
src/main.rs
33
src/main.rs
@@ -25,7 +25,7 @@ use crate::commands::{
|
||||
use crate::db::DAOs;
|
||||
use crate::handle_error::with_error_handler;
|
||||
use crate::handler_utils::{find_or_create_db_user_from_update, update_into_message_target};
|
||||
use crate::message_sender::BoxMessageSender;
|
||||
use crate::message_sender::{BotMessageSender, BoxedMessageSender};
|
||||
use crate::sqlite_storage::SqliteStorage;
|
||||
use anyhow::Result;
|
||||
pub use bot_result::*;
|
||||
@@ -39,12 +39,12 @@ pub use wrap_endpoint::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct App {
|
||||
pub bot: Arc<BoxMessageSender>,
|
||||
pub bot: Arc<BoxedMessageSender>,
|
||||
pub daos: DAOs,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(bot: BoxMessageSender, daos: DAOs) -> Self {
|
||||
pub fn new(bot: BoxedMessageSender, daos: DAOs) -> Self {
|
||||
Self {
|
||||
bot: Arc::new(bot),
|
||||
daos,
|
||||
@@ -100,11 +100,9 @@ type RootDialogue = Dialogue<DialogueRootState, SqliteStorage<Json>>;
|
||||
|
||||
pub fn main_handler() -> BotHandler {
|
||||
dptree::entry()
|
||||
.map(|app: App| app.daos.clone())
|
||||
.map(|daos: DAOs| daos.user.clone())
|
||||
.map(|daos: DAOs| daos.listing.clone())
|
||||
.map(|daos: DAOs| daos.bid.clone())
|
||||
.filter_map(update_into_message_target)
|
||||
.filter_map_async(find_or_create_db_user_from_update)
|
||||
.branch(my_listings_inline_handler())
|
||||
.branch(
|
||||
@@ -156,20 +154,21 @@ async fn main() -> Result<()> {
|
||||
// Set up the bot's command menu
|
||||
setup_bot_commands(&bot).await?;
|
||||
|
||||
let handler_with_deps = dptree::entry()
|
||||
.filter_map(|bot: Box<Bot>, update: Update, daos: DAOs| {
|
||||
let target = update_into_message_target(update)?;
|
||||
Some(App::new(
|
||||
Box::new(BotMessageSender::new(*bot, target)),
|
||||
daos.clone(),
|
||||
))
|
||||
})
|
||||
.chain(main_handler());
|
||||
|
||||
let dialog_storage = SqliteStorage::new(db_pool.clone(), Json).await?;
|
||||
let daos = DAOs::new(db_pool.clone());
|
||||
let app = App::new(bot.clone(), daos.clone());
|
||||
|
||||
// Create dispatcher with dialogue system
|
||||
Dispatcher::builder(bot, main_handler())
|
||||
.dependencies(dptree::deps![
|
||||
dialog_storage,
|
||||
daos,
|
||||
app.daos.user.clone(),
|
||||
app.daos.listing.clone(),
|
||||
app.daos.bid.clone(),
|
||||
app
|
||||
])
|
||||
Dispatcher::builder(bot, handler_with_deps)
|
||||
.dependencies(dptree::deps![dialog_storage, daos])
|
||||
.enable_ctrlc_handler()
|
||||
.worker_queue_size(1)
|
||||
.build()
|
||||
@@ -199,7 +198,7 @@ mod tests {
|
||||
let mut bot = MockMessageSender::new();
|
||||
bot.expect_send_html_message()
|
||||
.times(1)
|
||||
.returning(|_, _, _| Ok(()));
|
||||
.returning(|_, _| Ok(()));
|
||||
let deps = create_deps(bot).await;
|
||||
let handler = main_handler();
|
||||
dptree::type_check(handler.sig(), &deps, &[]);
|
||||
|
||||
@@ -14,10 +14,10 @@ use teloxide::{
|
||||
pub trait MessageSender {
|
||||
async fn send_html_message(
|
||||
&self,
|
||||
target: MessageTarget,
|
||||
text: String,
|
||||
keyboard: Option<InlineKeyboardMarkup>,
|
||||
) -> BotResult;
|
||||
fn with_target(&self, target: MessageTarget) -> BoxedMessageSender;
|
||||
async fn answer_inline_query(
|
||||
&self,
|
||||
inline_query_id: InlineQueryId,
|
||||
@@ -27,7 +27,7 @@ pub trait MessageSender {
|
||||
async fn get_me(&self) -> BotResult<Me>;
|
||||
}
|
||||
|
||||
pub type BoxMessageSender = Box<dyn MessageSender + Send + Sync>;
|
||||
pub type BoxedMessageSender = Box<dyn MessageSender + Send + Sync>;
|
||||
|
||||
#[cfg(test)]
|
||||
mockall::mock! {
|
||||
@@ -37,9 +37,9 @@ mockall::mock! {
|
||||
}
|
||||
#[async_trait]
|
||||
impl MessageSender for MessageSender {
|
||||
fn with_target(&self, target: MessageTarget) -> BoxedMessageSender;
|
||||
async fn send_html_message(
|
||||
&self,
|
||||
target: MessageTarget,
|
||||
text: String,
|
||||
keyboard: Option<InlineKeyboardMarkup>,
|
||||
) -> BotResult;
|
||||
@@ -53,17 +53,29 @@ mockall::mock! {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BotMessageSender(Bot, MessageTarget);
|
||||
impl BotMessageSender {
|
||||
pub fn new(bot: Bot, message_target: MessageTarget) -> Self {
|
||||
Self(bot, message_target)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl MessageSender for Bot {
|
||||
impl MessageSender for BotMessageSender {
|
||||
fn with_target(&self, target: MessageTarget) -> BoxedMessageSender {
|
||||
let clone = Self(self.0.clone(), target);
|
||||
Box::new(clone)
|
||||
}
|
||||
async fn send_html_message(
|
||||
&self,
|
||||
target: MessageTarget,
|
||||
text: String,
|
||||
keyboard: Option<InlineKeyboardMarkup>,
|
||||
) -> BotResult {
|
||||
let target = self.1.clone();
|
||||
if let Some(message_id) = target.message_id {
|
||||
log::info!("Editing message in chat: {target:?}");
|
||||
let mut message = self
|
||||
.0
|
||||
.edit_message_text(target.chat_id, message_id, &text)
|
||||
.parse_mode(ParseMode::Html);
|
||||
if let Some(kb) = keyboard {
|
||||
@@ -73,6 +85,7 @@ impl MessageSender for Bot {
|
||||
} else {
|
||||
log::info!("Sending message to chat: {target:?}");
|
||||
let mut message = self
|
||||
.0
|
||||
.send_message(target.chat_id, &text)
|
||||
.parse_mode(ParseMode::Html);
|
||||
if let Some(kb) = keyboard {
|
||||
@@ -88,21 +101,24 @@ impl MessageSender for Bot {
|
||||
inline_query_id: InlineQueryId,
|
||||
results: Vec<InlineQueryResult>,
|
||||
) -> BotResult {
|
||||
teloxide::prelude::Requester::answer_inline_query(self, inline_query_id, results)
|
||||
self.0
|
||||
.answer_inline_query(inline_query_id, results)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.map_err(|err| BotError::InternalError(err.into()))
|
||||
}
|
||||
|
||||
async fn answer_callback_query(&self, query_id: CallbackQueryId) -> BotResult {
|
||||
teloxide::prelude::Requester::answer_callback_query(self, query_id)
|
||||
self.0
|
||||
.answer_callback_query(query_id)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.map_err(|err| BotError::InternalError(err.into()))
|
||||
}
|
||||
|
||||
async fn get_me(&self) -> BotResult<Me> {
|
||||
teloxide::prelude::Requester::get_me(self)
|
||||
self.0
|
||||
.get_me()
|
||||
.await
|
||||
.map_err(|err| BotError::InternalError(err.into()))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{message_sender::BoxMessageSender, BotResult};
|
||||
use crate::{message_sender::BoxedMessageSender, BotResult};
|
||||
use anyhow::anyhow;
|
||||
use chrono::{DateTime, Utc};
|
||||
use num::One;
|
||||
@@ -127,7 +127,7 @@ pub fn create_single_button_keyboard(text: &str, callback_data: &str) -> InlineK
|
||||
|
||||
// Extract callback data and answer callback query
|
||||
pub async fn extract_callback_data(
|
||||
bot: &BoxMessageSender,
|
||||
bot: &BoxedMessageSender,
|
||||
callback_query: CallbackQuery,
|
||||
) -> BotResult<String> {
|
||||
let data = match callback_query.data {
|
||||
|
||||
@@ -178,7 +178,8 @@ pub async fn create_deps(mock_bot: MockMessageSender) -> DependencyMap {
|
||||
let update = create_tele_update();
|
||||
let pool = create_test_pool().await;
|
||||
let dialog_storage = SqliteStorage::new(pool.clone(), Json).await.unwrap();
|
||||
let app = App::new(Box::new(mock_bot), DAOs::new(pool));
|
||||
let daos = DAOs::new(pool);
|
||||
let app = App::new(Box::new(mock_bot), daos.clone());
|
||||
let me_user = create_tele_user("me");
|
||||
let me = Me {
|
||||
user: me_user,
|
||||
@@ -188,7 +189,7 @@ pub async fn create_deps(mock_bot: MockMessageSender) -> DependencyMap {
|
||||
can_connect_to_business: true,
|
||||
has_main_web_app: true,
|
||||
};
|
||||
dptree::deps![update, dialog_storage, app, me]
|
||||
dptree::deps![update, dialog_storage, app, me, daos]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user