Files
pawctioneer-bot/src/commands/start.rs
Dylan Knutson 5d7a5b26c1 feat: enhance UX with listing type selection and main menu improvements
- Add listing type selection to new listing wizard
  - Create SelectingListingType state for choosing between 4 listing types
  - Add ListingTypeKeyboardButtons with clear descriptions
  - Support BasicAuction, MultiSlotAuction, FixedPriceListing, BlindAuction
  - Update handlers to start with type selection before title input

- Improve main menu navigation
  - Add main menu with action buttons for /start command
  - Create MainMenuButtons with New Listing, My Listings, My Bids, Settings, Help
  - Add back button to My Listings screen for better navigation
  - Implement proper dialogue state management between screens

- Refactor callback handling for type safety
  - Convert string literal matching to enum-based callback handling
  - Use try_from() pattern for all keyboard button callbacks
  - Ensure compile-time safety and exhaustive matching
  - Apply pattern to listing type, slots, duration, and start time callbacks

- Eliminate code duplication
  - Extract reusable main menu functions (enter_main_menu, get_main_menu_message)
  - Centralize main menu logic and message content
  - Update all main menu transitions to use shared functions

- Technical improvements
  - Add proper error handling for invalid callback data
  - Maintain backward compatibility with existing flows
  - Follow established patterns for keyboard button definitions
  - Ensure all changes compile without errors
2025-08-30 05:45:49 +00:00

141 lines
4.2 KiB
Rust

use log::info;
use teloxide::{
types::{CallbackQuery, Message},
utils::command::BotCommands,
Bot,
};
use sqlx::SqlitePool;
use crate::{
commands::{my_listings::show_listings_for_user, new_listing::enter_handle_new_listing},
keyboard_buttons,
message_utils::{extract_callback_data, send_message, MessageTarget},
Command, DialogueRootState, HandlerResult, RootDialogue,
};
keyboard_buttons! {
pub enum MainMenuButtons {
[
NewListing("🛍️ New Listing", "menu_new_listing"),
],
[
MyListings("📋 My Listings", "menu_my_listings"),
MyBids("💰 My Bids", "menu_my_bids"),
],
[
Settings("⚙️ Settings", "menu_settings"),
Help("❓ Help", "menu_help"),
]
}
}
/// Get the main menu welcome message
pub fn get_main_menu_message() -> &'static str {
"🎯 <b>Welcome to Pawctioneer Bot!</b> 🎯\n\n\
This bot helps you participate in various types of auctions:\n\
• Standard auctions with anti-sniping protection\n\
• Multi-slot auctions (multiple winners)\n\
• Fixed price sales\n\
• Blind auctions\n\n\
Choose an option below to get started! 🚀"
}
pub async fn handle_start(bot: Bot, dialogue: RootDialogue, msg: Message) -> HandlerResult {
enter_main_menu(bot, dialogue, msg.chat).await?;
Ok(())
}
/// Show the main menu with buttons
pub async fn enter_main_menu(
bot: Bot,
dialogue: RootDialogue,
target: impl Into<MessageTarget>,
) -> HandlerResult {
dialogue.update(DialogueRootState::MainMenu).await?;
send_message(
&bot,
target,
get_main_menu_message(),
Some(MainMenuButtons::to_keyboard()),
)
.await?;
Ok(())
}
pub async fn handle_main_menu_callback(
db_pool: SqlitePool,
bot: Bot,
dialogue: RootDialogue,
callback_query: CallbackQuery,
) -> HandlerResult {
let (data, from, message_id) = extract_callback_data(&bot, callback_query).await?;
let target = MessageTarget::from((from.clone(), message_id));
info!(
"User {} selected main menu option: {}",
from.username.as_deref().unwrap_or("unknown"),
data
);
let button = MainMenuButtons::try_from(data.as_str())?;
match button {
MainMenuButtons::NewListing => {
enter_handle_new_listing(db_pool, bot, dialogue, from.clone(), target).await?;
}
MainMenuButtons::MyListings => {
// Call show_listings_for_user directly
show_listings_for_user(db_pool, dialogue, bot, from.id, target).await?;
}
MainMenuButtons::MyBids => {
send_message(
&bot,
target,
"💰 <b>My Bids (Coming Soon)</b>\n\n\
Here you'll be able to view:\n\
• Your active bids\n\
• Bid history\n\
• Won/lost auctions\n\
• Outbid notifications\n\n\
Feature in development! 🛠️",
Some(MainMenuButtons::to_keyboard()),
)
.await?;
}
MainMenuButtons::Settings => {
send_message(
&bot,
target,
"⚙️ <b>Settings (Coming Soon)</b>\n\n\
Here you'll be able to configure:\n\
• Notification preferences\n\
• Language settings\n\
• Default bid increments\n\
• Outbid alerts\n\n\
Feature in development! 🛠️",
Some(MainMenuButtons::to_keyboard()),
)
.await?;
}
MainMenuButtons::Help => {
let help_message = format!(
"📋 <b>Available Commands:</b>\n\n{}\n\n\
📧 <b>Support:</b> Contact @admin for help\n\
🔗 <b>More info:</b> Use individual commands to get started!",
Command::descriptions()
);
send_message(
&bot,
target,
help_message,
Some(MainMenuButtons::to_keyboard()),
)
.await?;
}
}
Ok(())
}