mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2026-03-03 15:10:53 +01:00
Add per-user default search setting
This commit is contained in:
@@ -3,12 +3,14 @@ pub mod commands;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use smartstring::alias::String as SmartString;
|
||||
|
||||
use crate::bots::{
|
||||
approved_bot::{
|
||||
services::user_settings::{
|
||||
create_or_update_user_settings, get_langs, get_user_or_default_lang_codes, Lang,
|
||||
create_or_update_user_settings, get_langs, get_user_or_default_lang_codes,
|
||||
get_user_settings, DefaultSearchType, Lang,
|
||||
},
|
||||
tools::filter_callback_query,
|
||||
},
|
||||
@@ -23,18 +25,28 @@ use teloxide::{
|
||||
|
||||
use self::{callback_data::SettingsCallbackData, commands::SettingsCommand};
|
||||
|
||||
async fn settings_handler(message: Message, bot: CacheMe<Throttle<Bot>>) -> BotHandlerInternal {
|
||||
let keyboard = InlineKeyboardMarkup {
|
||||
inline_keyboard: vec![vec![InlineKeyboardButton {
|
||||
text: "Языки".to_string(),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::Settings.to_string(),
|
||||
),
|
||||
}]],
|
||||
};
|
||||
fn get_main_settings_keyboard() -> InlineKeyboardMarkup {
|
||||
InlineKeyboardMarkup {
|
||||
inline_keyboard: vec![
|
||||
vec![InlineKeyboardButton {
|
||||
text: "Языки".to_string(),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::Settings.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: "Поиск по умолчанию".to_string(),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearchMenu.to_string(),
|
||||
),
|
||||
}],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
async fn settings_handler(message: Message, bot: CacheMe<Throttle<Bot>>) -> BotHandlerInternal {
|
||||
bot.send_message(message.chat.id, "Настройки")
|
||||
.reply_markup(keyboard)
|
||||
.reply_markup(get_main_settings_keyboard())
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
@@ -71,6 +83,65 @@ fn get_lang_keyboard(
|
||||
}
|
||||
}
|
||||
|
||||
fn get_default_search_keyboard(current: Option<DefaultSearchType>) -> InlineKeyboardMarkup {
|
||||
let check = |v: DefaultSearchType| if current == Some(v) { " ✓" } else { "" };
|
||||
InlineKeyboardMarkup {
|
||||
inline_keyboard: vec![
|
||||
vec![InlineKeyboardButton {
|
||||
text: format!("Книга{}", check(DefaultSearchType::Book)),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearch {
|
||||
value: "book".into(),
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: format!("Автор{}", check(DefaultSearchType::Author)),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearch {
|
||||
value: "author".into(),
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: format!("Серия{}", check(DefaultSearchType::Series)),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearch {
|
||||
value: "series".into(),
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: format!("Переводчик{}", check(DefaultSearchType::Translator)),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearch {
|
||||
value: "translator".into(),
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: format!("Не выбрано{}", if current.is_none() { " ✓" } else { "" }),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearch {
|
||||
value: "none".into(),
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
}],
|
||||
vec![InlineKeyboardButton {
|
||||
text: "← Назад".to_string(),
|
||||
kind: teloxide::types::InlineKeyboardButtonKind::CallbackData(
|
||||
SettingsCallbackData::DefaultSearchBack.to_string(),
|
||||
),
|
||||
}],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
async fn settings_callback_handler(
|
||||
cq: CallbackQuery,
|
||||
bot: CacheMe<Throttle<Bot>>,
|
||||
@@ -89,6 +160,72 @@ async fn settings_callback_handler(
|
||||
|
||||
let user = cq.from;
|
||||
|
||||
match &callback_data {
|
||||
SettingsCallbackData::DefaultSearchMenu => {
|
||||
let current = get_user_settings(user.id).await.ok().flatten();
|
||||
let current_default = current.as_ref().and_then(|s| s.default_search);
|
||||
let keyboard = get_default_search_keyboard(current_default);
|
||||
bot.edit_message_text(message.chat().id, message.id(), "Поиск по умолчанию")
|
||||
.reply_markup(keyboard)
|
||||
.send()
|
||||
.await?;
|
||||
bot.answer_callback_query(cq.id).send().await?;
|
||||
return Ok(());
|
||||
}
|
||||
SettingsCallbackData::DefaultSearchBack => {
|
||||
bot.edit_message_text(message.chat().id, message.id(), "Настройки")
|
||||
.reply_markup(get_main_settings_keyboard())
|
||||
.send()
|
||||
.await?;
|
||||
bot.answer_callback_query(cq.id).send().await?;
|
||||
return Ok(());
|
||||
}
|
||||
SettingsCallbackData::DefaultSearch { value } => {
|
||||
let current = get_user_settings(user.id).await.ok().flatten();
|
||||
let allowed_langs: SmallVec<[SmartString; 3]> = match current {
|
||||
Some(s) => s.allowed_langs.into_iter().map(|l| l.code).collect(),
|
||||
None => get_user_or_default_lang_codes(user.id).await,
|
||||
};
|
||||
let default_search = if value.as_str() == "none" {
|
||||
None
|
||||
} else if let Some(t) = DefaultSearchType::from_api_str(value.as_str()) {
|
||||
Some(t)
|
||||
} else {
|
||||
bot.answer_callback_query(cq.id).send().await?;
|
||||
return Ok(());
|
||||
};
|
||||
if create_or_update_user_settings(
|
||||
user.id,
|
||||
&user.last_name.unwrap_or("".to_string()),
|
||||
&user.first_name,
|
||||
user.username.as_deref().unwrap_or(""),
|
||||
&me.username.clone().unwrap(),
|
||||
allowed_langs,
|
||||
default_search,
|
||||
)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
bot.answer_callback_query(cq.id)
|
||||
.text("Ошибка! Попробуйте заново(")
|
||||
.show_alert(true)
|
||||
.send()
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
bot.edit_message_text(message.chat().id, message.id(), "Настройки")
|
||||
.reply_markup(get_main_settings_keyboard())
|
||||
.send()
|
||||
.await?;
|
||||
bot.answer_callback_query(cq.id)
|
||||
.text("Готово")
|
||||
.send()
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let allowed_langs = get_user_or_default_lang_codes(user.id).await;
|
||||
|
||||
let mut allowed_langs_set: HashSet<SmartString> = HashSet::new();
|
||||
@@ -104,6 +241,7 @@ async fn settings_callback_handler(
|
||||
SettingsCallbackData::Off { code } => {
|
||||
allowed_langs_set.remove(&code);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
if allowed_langs_set.is_empty() {
|
||||
@@ -116,6 +254,9 @@ async fn settings_callback_handler(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let current_settings = get_user_settings(user.id).await.ok().flatten();
|
||||
let default_search = current_settings.as_ref().and_then(|s| s.default_search);
|
||||
|
||||
if let Err(err) = create_or_update_user_settings(
|
||||
user.id,
|
||||
&user.last_name.unwrap_or("".to_string()),
|
||||
@@ -123,6 +264,7 @@ async fn settings_callback_handler(
|
||||
&user.username.unwrap_or("".to_string()),
|
||||
&me.username.clone().unwrap(),
|
||||
allowed_langs_set.clone().into_iter().collect(),
|
||||
default_search,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user