From 0a975a2df620c74ef503a8febb5ea5cc699e1146 Mon Sep 17 00:00:00 2001 From: Sokhibjon Orzikulov Date: Mon, 20 Nov 2023 10:17:33 +0500 Subject: [PATCH] final touches --- .env.example | 5 +- source.json | 4 +- src/functions/mod.rs | 11 +++- src/functions/useful.rs | 124 ++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 2 +- src/utils/resources.rs | 8 ++- 6 files changed, 141 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 178ad4f..67debda 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,2 @@ -TOKEN= -HOST= -MODE= +TELOXIDE_TOKEN= +GITHUB_TOKEN= \ No newline at end of file diff --git a/source.json b/source.json index f084eeb..dcc3577 100644 --- a/source.json +++ b/source.json @@ -12,8 +12,8 @@ }, { "name": "Rust Cookbook", - "desc": "https://rust-lang-nursery.github.io/rust-cookbook/", - "link": "Learn Rust good practices with practical code samples" + "desc": "Learn Rust good practices with practical code samples", + "link": "https://rust-lang-nursery.github.io/rust-cookbook/" }, { "name": "CIS 198", diff --git a/src/functions/mod.rs b/src/functions/mod.rs index 10d85bd..5fbd3b9 100644 --- a/src/functions/mod.rs +++ b/src/functions/mod.rs @@ -32,7 +32,7 @@ pub async fn commands( Command::Help => crate::functions::help::command(&bot, &msg, &cmd).await, Command::Rules => crate::functions::rules::command(&bot, &msg).await, Command::About => crate::functions::about::command(&bot, &msg).await, - Command::Groups => crate::functions::groups::command(&bot, &msg, &groups).await, + Command::Group => crate::functions::groups::command(&bot, &msg, &groups).await, Command::Latest => crate::functions::latest::command(&bot, github, &msg).await, Command::Version => crate::functions::version::command(&bot, github, &msg).await, Command::Off => crate::functions::offtop::command(&bot, &msg, &me).await, @@ -47,6 +47,7 @@ pub async fn callback( q: CallbackQuery, github: GitHub, groups: Groups, + resources: Resources, ) -> Result<(), Box> { let mut args: Vec<&str> = Vec::new(); @@ -64,6 +65,14 @@ pub async fn callback( "changelog" => { crate::functions::version::callback_detail(&bot, &q, &args, github).await } + "useful" => crate::functions::useful::callback_list(&bot, &q, &resources).await, + "category" => { + crate::functions::useful::callback_category_list(&bot, &q, &args, &resources).await + } + "material" => { + crate::functions::useful::callback_material_detail(&bot, &q, &args, &resources) + .await + } _ => Ok(()), }; } diff --git a/src/functions/useful.rs b/src/functions/useful.rs index 4177ae7..04ce2d1 100644 --- a/src/functions/useful.rs +++ b/src/functions/useful.rs @@ -1,4 +1,7 @@ -use crate::utils::{keyboard::Keyboard, resources::Resources}; +use crate::utils::{ + keyboard::Keyboard, + resources::{Resource, Resources}, +}; use teloxide::{ payloads::SendMessageSetters, prelude::*, @@ -15,14 +18,95 @@ pub async fn command(bot: &Bot, msg: &Message, resources: &Resources) -> Respons bot.send_message(msg.chat.id, TEXT) .parse_mode(ParseMode::Html) - .reply_markup(keyboard_list(1, categories)) + .reply_markup(keyboard_list(categories)) .disable_web_page_preview(true) .await?; Ok(()) } -pub fn keyboard_list(page: u32, categories: Vec) -> InlineKeyboardMarkup { +pub async fn callback_list( + bot: &Bot, + q: &CallbackQuery, + resources: &Resources, +) -> ResponseResult<()> { + let categories = resources.get_keys(); + + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, TEXT) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_list(categories)) + .disable_web_page_preview(true) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + + Ok(()) +} + +pub async fn callback_category_list( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + resources: &Resources, +) -> ResponseResult<()> { + let find = resources.get_materials(args.join("_").as_str()).unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_category_list(&args.join(" "))) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_category_list(find, args.join("_"))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub async fn callback_material_detail( + bot: &Bot, + q: &CallbackQuery, + args: &Vec<&str>, + resources: &Resources, +) -> ResponseResult<()> { + let find = resources + .get_material(args[1..].join("_").as_str(), args[0].parse().unwrap()) + .unwrap(); + + if !args.is_empty() { + if let Some(Message { id, chat, .. }) = q.message.clone() { + bot.edit_message_text(chat.id, id, view_material_detail(find)) + .parse_mode(ParseMode::Html) + .reply_markup(keyboard_material_detail(find, args[1..].join("_"))) + .await?; + } else if let Some(id) = q.inline_message_id.clone() { + bot.edit_message_text_inline(id, "Oopsie, something went wrong...") + .await?; + } + } + + Ok(()) +} + +pub fn view_category_list(category: &str) -> String { + format!("Siz hozirda {}{} kategoriyasi ichida turibsiz.\nIltimos, keltirilgan materiallardan birini tanlang...", + &category[0..1].to_uppercase(), &category[1..].replace('_', " ")) +} + +pub fn view_material_detail(material: &Resource) -> String { + format!( + "{}\n\n{}\n\nUshbu pastdagi tugmacha orqali lavha ga o'tib oling:", + material.name, material.desc + ) +} + +pub fn keyboard_list(categories: Vec) -> InlineKeyboardMarkup { let mut keyboard = Keyboard::new(); for category in categories { @@ -30,12 +114,42 @@ pub fn keyboard_list(page: u32, categories: Vec) -> InlineKeyboardMarkup &format!( "{}{}", &category[0..1].to_uppercase(), - &category[1..].replace("_", " ") + &category[1..].replace('_', " ") + ), + &format!("category_{}", category), + ); + keyboard.row(); + } + + keyboard.get() +} + +pub fn keyboard_category_list(material: &[Resource], category: String) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + for (index, value) in material.iter().enumerate() { + keyboard.text( + &format!( + "{}{}", + &value.name[0..1].to_uppercase(), + &value.name[1..].replace('_', " ") ), - &format!("useful_{}_{}", page, category), + &format!("material_{}_{}", index, category), ); keyboard.row(); } + keyboard.text("🔙 Orqaga", "useful"); + + keyboard.get() +} + +pub fn keyboard_material_detail(resource: &Resource, category: String) -> InlineKeyboardMarkup { + let mut keyboard = Keyboard::new(); + + keyboard.url("Web Sahifasi", &resource.link); + keyboard.row(); + keyboard.text("🔙 Orqaga", &format!("category_{}", category)); + keyboard.get() } diff --git a/src/lib.rs b/src/lib.rs index e31baa6..fbc9464 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub enum Command { About, /// Available groups - Groups, + Group, /// Latest version Latest, diff --git a/src/utils/resources.rs b/src/utils/resources.rs index a29d9bf..b240c6a 100644 --- a/src/utils/resources.rs +++ b/src/utils/resources.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; -static RESOURCE: &'static str = include_str!("../../source.json"); +static RESOURCE: &str = include_str!("../../source.json"); #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Resource { @@ -15,6 +15,12 @@ pub struct Resources { materials: HashMap>, } +impl Default for Resources { + fn default() -> Self { + Self::new() + } +} + impl Resources { pub fn new() -> Self { Resources {