todo pager and selector
This commit is contained in:
@ -6,7 +6,10 @@ use serenity::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
component_models::pager::TodoPager,
|
||||
component_models::{
|
||||
pager::{Pager, TodoPager},
|
||||
ComponentDataModel, TodoSelector,
|
||||
},
|
||||
consts::{EMBED_DESCRIPTION_MAX_LENGTH, SELECT_MAX_ENTRIES, THEME_COLOR},
|
||||
framework::{CommandInvoke, CommandOptions, CreateGenericResponse},
|
||||
SQLPool,
|
||||
@ -67,8 +70,6 @@ async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
_ => (Some(invoke.author_id().0), None, None),
|
||||
};
|
||||
|
||||
println!("{:?}", keys);
|
||||
|
||||
match args.get("task") {
|
||||
Some(task) => {
|
||||
let task = task.to_string();
|
||||
@ -91,7 +92,7 @@ async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
None => {
|
||||
let values = sqlx::query!(
|
||||
// fucking braindead mysql use <=> instead of = for null comparison
|
||||
"SELECT value FROM todos WHERE user_id <=> ? AND channel_id <=> ? AND guild_id <=> ?",
|
||||
"SELECT id, value FROM todos WHERE user_id <=> ? AND channel_id <=> ? AND guild_id <=> ?",
|
||||
keys.0,
|
||||
keys.1,
|
||||
keys.2,
|
||||
@ -100,8 +101,8 @@ async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
.await
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|row| row.value.clone())
|
||||
.collect::<Vec<String>>();
|
||||
.map(|row| (row.id as usize, row.value.clone()))
|
||||
.collect::<Vec<(usize, String)>>();
|
||||
|
||||
let resp = show_todo_page(&values, 0, keys.0, keys.1, keys.2);
|
||||
|
||||
@ -119,11 +120,11 @@ async fn todo(ctx: &Context, invoke: CommandInvoke, args: CommandOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max_todo_page(todo_values: &[String]) -> usize {
|
||||
pub fn max_todo_page(todo_values: &[(usize, String)]) -> usize {
|
||||
let mut rows = 0;
|
||||
let mut char_count = 0;
|
||||
|
||||
todo_values.iter().enumerate().map(|(c, v)| format!("{}: {}", c, v)).fold(
|
||||
todo_values.iter().enumerate().map(|(c, (_, v))| format!("{}: {}", c, v)).fold(
|
||||
1,
|
||||
|mut pages, text| {
|
||||
rows += 1;
|
||||
@ -141,13 +142,13 @@ pub fn max_todo_page(todo_values: &[String]) -> usize {
|
||||
}
|
||||
|
||||
pub fn show_todo_page(
|
||||
todo_values: &[String],
|
||||
todo_values: &[(usize, String)],
|
||||
page: usize,
|
||||
user_id: Option<u64>,
|
||||
channel_id: Option<u64>,
|
||||
guild_id: Option<u64>,
|
||||
) -> CreateInteractionResponse {
|
||||
// let pager = TodoPager::new(page, user_id, channel_id, guild_id);
|
||||
let pager = TodoPager::new(page, user_id, channel_id, guild_id);
|
||||
|
||||
let pages = max_todo_page(todo_values);
|
||||
let mut page = page;
|
||||
@ -163,11 +164,11 @@ pub fn show_todo_page(
|
||||
|
||||
let mut skipped_pages = 0;
|
||||
|
||||
let display_vec: Vec<String> = todo_values
|
||||
let (todo_ids, display_vec): (Vec<usize>, Vec<String>) = todo_values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(c, v)| format!("`{}`: {}", c + 1, v))
|
||||
.skip_while(|p| {
|
||||
.map(|(c, (i, v))| (i, format!("`{}`: {}", c + 1, v)))
|
||||
.skip_while(|(_, p)| {
|
||||
first_num += 1;
|
||||
skipped_rows += 1;
|
||||
skipped_char_count += p.len();
|
||||
@ -182,13 +183,13 @@ pub fn show_todo_page(
|
||||
|
||||
skipped_pages < page
|
||||
})
|
||||
.take_while(|p| {
|
||||
.take_while(|(_, p)| {
|
||||
rows += 1;
|
||||
char_count += p.len();
|
||||
|
||||
char_count < EMBED_DESCRIPTION_MAX_LENGTH && rows <= SELECT_MAX_ENTRIES
|
||||
})
|
||||
.collect();
|
||||
.unzip();
|
||||
|
||||
let display = display_vec.join("\n");
|
||||
|
||||
@ -200,6 +201,9 @@ pub fn show_todo_page(
|
||||
"Server"
|
||||
};
|
||||
|
||||
let todo_selector =
|
||||
ComponentDataModel::TodoSelector(TodoSelector { page, user_id, channel_id, guild_id });
|
||||
|
||||
let mut embed = CreateEmbed::default();
|
||||
embed
|
||||
.title(format!("{} Todo List", title))
|
||||
@ -208,7 +212,27 @@ pub fn show_todo_page(
|
||||
.color(*THEME_COLOR);
|
||||
|
||||
let mut response = CreateInteractionResponse::default();
|
||||
response.interaction_response_data(|d| d.embeds(vec![embed]));
|
||||
response.interaction_response_data(|d| {
|
||||
d.embeds(vec![embed]).components(|comp| {
|
||||
pager.create_button_row(pages, comp);
|
||||
|
||||
comp.create_action_row(|row| {
|
||||
row.create_select_menu(|menu| {
|
||||
menu.custom_id(todo_selector.to_custom_id()).options(|opt| {
|
||||
for (count, (id, disp)) in todo_ids.iter().zip(&display_vec).enumerate() {
|
||||
opt.create_option(|o| {
|
||||
o.label(format!("Mark {} complete", count + first_num))
|
||||
.value(id)
|
||||
.description(disp.split_once(" ").unwrap_or(("", "")).1)
|
||||
});
|
||||
}
|
||||
|
||||
opt
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
response
|
||||
}
|
||||
|
Reference in New Issue
Block a user