Move all commands to their own files
This commit is contained in:
157
src/commands/todo/mod.rs
Normal file
157
src/commands/todo/mod.rs
Normal file
@ -0,0 +1,157 @@
|
||||
use poise::{
|
||||
serenity_prelude::{
|
||||
CreateActionRow, CreateEmbed, CreateEmbedFooter, CreateSelectMenu, CreateSelectMenuKind,
|
||||
CreateSelectMenuOption,
|
||||
},
|
||||
CreateReply,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
component_models::{
|
||||
pager::{Pager, TodoPager},
|
||||
ComponentDataModel, TodoSelector,
|
||||
},
|
||||
consts::{EMBED_DESCRIPTION_MAX_LENGTH, SELECT_MAX_ENTRIES, THEME_COLOR},
|
||||
Context, Error,
|
||||
};
|
||||
|
||||
pub mod channel;
|
||||
pub mod guild;
|
||||
pub mod user;
|
||||
|
||||
/// Manage todo lists
|
||||
#[poise::command(slash_command, default_member_permissions = "MANAGE_GUILD")]
|
||||
pub async fn todo(_ctx: Context<'_>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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(
|
||||
1,
|
||||
|mut pages, text| {
|
||||
rows += 1;
|
||||
char_count += text.len();
|
||||
|
||||
if char_count > EMBED_DESCRIPTION_MAX_LENGTH || rows > SELECT_MAX_ENTRIES {
|
||||
rows = 1;
|
||||
char_count = text.len();
|
||||
pages += 1;
|
||||
}
|
||||
|
||||
pages
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn show_todo_page(
|
||||
todo_values: &[(usize, String)],
|
||||
page: usize,
|
||||
user_id: Option<u64>,
|
||||
channel_id: Option<u64>,
|
||||
guild_id: Option<u64>,
|
||||
) -> CreateReply {
|
||||
let pager = TodoPager::new(page, user_id, channel_id, guild_id);
|
||||
|
||||
let pages = max_todo_page(todo_values);
|
||||
let mut page = page;
|
||||
if page >= pages {
|
||||
page = pages - 1;
|
||||
}
|
||||
|
||||
let mut char_count = 0;
|
||||
let mut rows = 0;
|
||||
let mut skipped_rows = 0;
|
||||
let mut skipped_char_count = 0;
|
||||
let mut first_num = 0;
|
||||
|
||||
let mut skipped_pages = 0;
|
||||
|
||||
let (todo_ids, display_vec): (Vec<usize>, Vec<String>) = todo_values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(c, (i, v))| (i, format!("`{}`: {}", c + 1, v)))
|
||||
.skip_while(|(_, p)| {
|
||||
first_num += 1;
|
||||
skipped_rows += 1;
|
||||
skipped_char_count += p.len();
|
||||
|
||||
if skipped_char_count > EMBED_DESCRIPTION_MAX_LENGTH
|
||||
|| skipped_rows > SELECT_MAX_ENTRIES
|
||||
{
|
||||
skipped_rows = 1;
|
||||
skipped_char_count = p.len();
|
||||
skipped_pages += 1;
|
||||
}
|
||||
|
||||
skipped_pages < page
|
||||
})
|
||||
.take_while(|(_, p)| {
|
||||
rows += 1;
|
||||
char_count += p.len();
|
||||
|
||||
char_count < EMBED_DESCRIPTION_MAX_LENGTH && rows <= SELECT_MAX_ENTRIES
|
||||
})
|
||||
.unzip();
|
||||
|
||||
let display = display_vec.join("\n");
|
||||
|
||||
let title = if user_id.is_some() {
|
||||
"Your"
|
||||
} else if channel_id.is_some() {
|
||||
"Channel"
|
||||
} else {
|
||||
"Server"
|
||||
};
|
||||
|
||||
if todo_ids.is_empty() {
|
||||
CreateReply::default().embed(
|
||||
CreateEmbed::new()
|
||||
.title(format!("{} Todo List", title))
|
||||
.description("Todo List Empty!")
|
||||
.color(*THEME_COLOR)
|
||||
.footer(CreateEmbedFooter::new(format!("Page {} of {}", page + 1, pages))),
|
||||
)
|
||||
} else {
|
||||
let todo_selector =
|
||||
ComponentDataModel::TodoSelector(TodoSelector { page, user_id, channel_id, guild_id });
|
||||
|
||||
CreateReply::default()
|
||||
.embed(
|
||||
CreateEmbed::new()
|
||||
.title(format!("{} Todo List", title))
|
||||
.description(display)
|
||||
.color(*THEME_COLOR)
|
||||
.footer(CreateEmbedFooter::new(format!("Page {} of {}", page + 1, pages))),
|
||||
)
|
||||
.components(vec![
|
||||
pager.create_button_row(pages),
|
||||
CreateActionRow::SelectMenu(CreateSelectMenu::new(
|
||||
todo_selector.to_custom_id(),
|
||||
CreateSelectMenuKind::String {
|
||||
options: todo_ids
|
||||
.iter()
|
||||
.zip(&display_vec)
|
||||
.enumerate()
|
||||
.map(|(count, (id, disp))| {
|
||||
let c = disp.split_once(' ').unwrap_or(("", "")).1;
|
||||
let description = if c.len() > 100 {
|
||||
format!("{}...", c.chars().take(97).collect::<String>())
|
||||
} else {
|
||||
c.to_string()
|
||||
};
|
||||
|
||||
CreateSelectMenuOption::new(
|
||||
format!("Mark {} complete", count + first_num),
|
||||
id.to_string(),
|
||||
)
|
||||
.description(description)
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
)),
|
||||
])
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user