mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Optimize user langs
This commit is contained in:
@@ -3,6 +3,7 @@ pub mod services;
|
|||||||
mod tools;
|
mod tools;
|
||||||
|
|
||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}};
|
use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}};
|
||||||
|
|
||||||
use crate::{bots::approved_bot::services::user_settings::create_or_update_user_settings, bots_manager::AppState};
|
use crate::{bots::approved_bot::services::user_settings::create_or_update_user_settings, bots_manager::AppState};
|
||||||
@@ -23,7 +24,7 @@ async fn _update_activity(
|
|||||||
me: teloxide::types::Me,
|
me: teloxide::types::Me,
|
||||||
user: teloxide::types::User,
|
user: teloxide::types::User,
|
||||||
activity_cache: Cache<UserId, ()>,
|
activity_cache: Cache<UserId, ()>,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
if activity_cache.contains_key(&user.id) {
|
if activity_cache.contains_key(&user.id) {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Throttle, CacheMe}};
|
use teloxide::{dispatching::UpdateFilterExt, dptree, prelude::*, adaptors::{Throttle, CacheMe}};
|
||||||
|
|
||||||
use crate::{bots::approved_bot::{
|
use crate::{bots::approved_bot::{
|
||||||
@@ -118,8 +119,8 @@ async fn send_book_handler<T, P, Fut>(
|
|||||||
message: Message,
|
message: Message,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
command: BookCommand,
|
command: BookCommand,
|
||||||
books_getter: fn(id: u32, page: u32, allowed_langs: Vec<String>) -> Fut,
|
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
@@ -190,8 +191,8 @@ async fn send_pagination_book_handler<T, P, Fut>(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: BookCallbackData,
|
callback_data: BookCallbackData,
|
||||||
books_getter: fn(id: u32, page: u32, allowed_langs: Vec<String>) -> Fut,
|
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> crate::bots::BotHandlerInternal
|
) -> crate::bots::BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ async fn download_archive(
|
|||||||
object_id: id,
|
object_id: id,
|
||||||
object_type: task_type,
|
object_type: task_type,
|
||||||
file_format: file_type,
|
file_format: file_type,
|
||||||
allowed_langs
|
allowed_langs: allowed_langs.into_vec(),
|
||||||
}).await;
|
}).await;
|
||||||
|
|
||||||
let mut task = match task {
|
let mut task = match task {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use strum_macros::{Display, EnumIter};
|
use strum_macros::{Display, EnumIter};
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@@ -168,8 +169,8 @@ where
|
|||||||
async fn get_random_item_handler<T, Fut>(
|
async fn get_random_item_handler<T, Fut>(
|
||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
item_getter: fn(allowed_langs: Vec<String>) -> Fut,
|
item_getter: fn(allowed_langs: SmallVec<[String; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> BotHandlerInternal
|
) -> BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format,
|
T: Format,
|
||||||
@@ -293,7 +294,7 @@ async fn get_random_book_by_genre(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
genre_id: u32,
|
genre_id: u32,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await;
|
let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@@ -111,8 +112,8 @@ async fn generic_search_pagination_handler<T, P, Fut>(
|
|||||||
cq: CallbackQuery,
|
cq: CallbackQuery,
|
||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
search_data: SearchCallbackData,
|
search_data: SearchCallbackData,
|
||||||
items_getter: fn(query: String, page: u32, allowed_langs: Vec<String>) -> Fut,
|
items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> BotHandlerInternal
|
) -> BotHandlerInternal
|
||||||
where
|
where
|
||||||
T: Format + Clone + Debug,
|
T: Format + Clone + Debug,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use crate::{bots::{
|
|||||||
|
|
||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use teloxide::{
|
use teloxide::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
types::{InlineKeyboardButton, InlineKeyboardMarkup, Me},
|
types::{InlineKeyboardButton, InlineKeyboardMarkup, Me},
|
||||||
@@ -119,7 +120,7 @@ async fn settings_callback_handler(
|
|||||||
bot: CacheMe<Throttle<Bot>>,
|
bot: CacheMe<Throttle<Bot>>,
|
||||||
callback_data: SettingsCallbackData,
|
callback_data: SettingsCallbackData,
|
||||||
me: Me,
|
me: Me,
|
||||||
user_langs_cache: Cache<UserId, Vec<String>>,
|
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
) -> BotHandlerInternal {
|
) -> BotHandlerInternal {
|
||||||
let message = match cq.message {
|
let message = match cq.message {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ pub mod formaters;
|
|||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
|
||||||
use self::types::Empty;
|
use self::types::Empty;
|
||||||
|
|
||||||
fn get_allowed_langs_params(allowed_langs: Vec<String>) -> Vec<(&'static str, String)> {
|
fn get_allowed_langs_params(allowed_langs: SmallVec<[String; 3]>) -> Vec<(&'static str, String)> {
|
||||||
allowed_langs
|
allowed_langs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|lang| ("allowed_langs", lang))
|
.map(|lang| ("allowed_langs", lang))
|
||||||
@@ -45,7 +46,7 @@ pub async fn get_book(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_random_book_by_genre(
|
pub async fn get_random_book_by_genre(
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
genre: Option<u32>,
|
genre: Option<u32>,
|
||||||
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs);
|
let mut params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs);
|
||||||
@@ -58,13 +59,13 @@ pub async fn get_random_book_by_genre(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_random_book(
|
pub async fn get_random_book(
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
get_random_book_by_genre(allowed_langs, None).await
|
get_random_book_by_genre(allowed_langs, None).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_random_author(
|
pub async fn get_random_author(
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Author, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Author, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs);
|
let params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ pub async fn get_random_author(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_random_sequence(
|
pub async fn get_random_sequence(
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Sequence, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Sequence, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = get_allowed_langs_params(allowed_langs);
|
let params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ const PAGE_SIZE: &str = "5";
|
|||||||
pub async fn search_book(
|
pub async fn search_book(
|
||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ pub async fn search_book(
|
|||||||
pub async fn search_author(
|
pub async fn search_author(
|
||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::Author, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Author, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ pub async fn search_author(
|
|||||||
pub async fn search_sequence(
|
pub async fn search_sequence(
|
||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::Sequence, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Sequence, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ pub async fn search_sequence(
|
|||||||
pub async fn search_translator(
|
pub async fn search_translator(
|
||||||
query: String,
|
query: String,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::Translator, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::Translator, Empty>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -164,7 +165,7 @@ pub async fn get_author_annotation(
|
|||||||
pub async fn get_author_books(
|
pub async fn get_author_books(
|
||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::AuthorBook, types::BookAuthor>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::AuthorBook, types::BookAuthor>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -177,7 +178,7 @@ pub async fn get_author_books(
|
|||||||
pub async fn get_translator_books(
|
pub async fn get_translator_books(
|
||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::TranslatorBook, types::BookTranslator>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::TranslatorBook, types::BookTranslator>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ pub async fn get_translator_books(
|
|||||||
pub async fn get_sequence_books(
|
pub async fn get_sequence_books(
|
||||||
id: u32,
|
id: u32,
|
||||||
page: u32,
|
page: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<types::Page<types::SequenceBook, types::Sequence>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<types::Page<types::SequenceBook, types::Sequence>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut params = get_allowed_langs_params(allowed_langs);
|
let mut params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -218,7 +219,7 @@ pub async fn get_uploaded_books(
|
|||||||
|
|
||||||
pub async fn get_author_books_available_types(
|
pub async fn get_author_books_available_types(
|
||||||
id: u32,
|
id: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = get_allowed_langs_params(allowed_langs);
|
let params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -227,7 +228,7 @@ pub async fn get_author_books_available_types(
|
|||||||
|
|
||||||
pub async fn get_translator_books_available_types(
|
pub async fn get_translator_books_available_types(
|
||||||
id: u32,
|
id: u32,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = get_allowed_langs_params(allowed_langs);
|
let params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
@@ -236,7 +237,7 @@ pub async fn get_translator_books_available_types(
|
|||||||
|
|
||||||
pub async fn get_sequence_books_available_types(
|
pub async fn get_sequence_books_available_types(
|
||||||
id: u32,
|
id: u32,
|
||||||
allowed_langs: Vec<String>
|
allowed_langs: SmallVec<[String; 3]>
|
||||||
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let params = get_allowed_langs_params(allowed_langs);
|
let params = get_allowed_langs_params(allowed_langs);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use moka::future::Cache;
|
use moka::future::Cache;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use smallvec::{SmallVec, smallvec};
|
||||||
use teloxide::{types::{UserId, ChatId}};
|
use teloxide::{types::{UserId, ChatId}};
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
@@ -41,17 +42,17 @@ pub async fn get_user_settings(
|
|||||||
|
|
||||||
pub async fn get_user_or_default_lang_codes(
|
pub async fn get_user_or_default_lang_codes(
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
cache: Cache<UserId, Vec<String>>
|
cache: Cache<UserId, SmallVec<[String; 3]>>
|
||||||
) -> Vec<String> {
|
) -> SmallVec<[String; 3]> {
|
||||||
if let Some(cached_langs) = cache.get(&user_id) {
|
if let Some(cached_langs) = cache.get(&user_id) {
|
||||||
return cached_langs;
|
return cached_langs;
|
||||||
}
|
}
|
||||||
|
|
||||||
let default_lang_codes = vec![String::from("ru"), String::from("be"), String::from("uk")];
|
let default_lang_codes = smallvec![String::from("ru"), String::from("be"), String::from("uk")];
|
||||||
|
|
||||||
match get_user_settings(user_id).await {
|
match get_user_settings(user_id).await {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
let langs: Vec<String> = v.allowed_langs.into_iter().map(|lang| lang.code).collect();
|
let langs: SmallVec<[String; 3]> = v.allowed_langs.into_iter().map(|lang| lang.code).collect();
|
||||||
cache.insert(user_id, langs.clone()).await;
|
cache.insert(user_id, langs.clone()).await;
|
||||||
langs
|
langs
|
||||||
},
|
},
|
||||||
@@ -65,8 +66,8 @@ pub async fn create_or_update_user_settings(
|
|||||||
first_name: String,
|
first_name: String,
|
||||||
username: String,
|
username: String,
|
||||||
source: String,
|
source: String,
|
||||||
allowed_langs: Vec<String>,
|
allowed_langs: SmallVec<[String; 3]>,
|
||||||
cache: Cache<UserId, Vec<String>>
|
cache: Cache<UserId, SmallVec<[String; 3]>>
|
||||||
) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
cache.invalidate(&user_id).await;
|
cache.invalidate(&user_id).await;
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ pub async fn create_or_update_user_settings(
|
|||||||
"first_name": first_name,
|
"first_name": first_name,
|
||||||
"username": username,
|
"username": username,
|
||||||
"source": source,
|
"source": source,
|
||||||
"allowed_langs": allowed_langs
|
"allowed_langs": allowed_langs.into_vec()
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = reqwest::Client::new()
|
let response = reqwest::Client::new()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use teloxide::adaptors::throttle::Limits;
|
use teloxide::adaptors::throttle::Limits;
|
||||||
use teloxide::types::BotCommand;
|
use teloxide::types::BotCommand;
|
||||||
use tokio::time::{sleep, Duration};
|
use tokio::time::{sleep, Duration};
|
||||||
@@ -25,7 +26,7 @@ use crate::config;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub user_activity_cache: Cache<UserId, ()>,
|
pub user_activity_cache: Cache<UserId, ()>,
|
||||||
pub user_langs_cache: Cache<UserId, Vec<String>>,
|
pub user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>,
|
||||||
pub chat_donation_notifications_cache: Cache<ChatId, ()>,
|
pub chat_donation_notifications_cache: Cache<ChatId, ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user