pager improvements. deleting working

This commit is contained in:
jellywx 2021-09-16 18:30:16 +01:00
parent b2207e308a
commit a9c91bee93
8 changed files with 527 additions and 190 deletions

View File

@ -1,26 +1,16 @@
use std::{collections::HashMap, iter};
use chrono::offset::Utc; use chrono::offset::Utc;
use chrono_tz::{Tz, TZ_VARIANTS}; use chrono_tz::{Tz, TZ_VARIANTS};
use levenshtein::levenshtein; use levenshtein::levenshtein;
use regex::Regex;
use regex_command_attr::command; use regex_command_attr::command;
use serenity::{ use serenity::{client::Context, model::misc::Mentionable};
client::Context,
model::{
channel::Message,
id::{ChannelId, MessageId, RoleId},
misc::Mentionable,
},
};
use crate::{ use crate::{
component_models::{ComponentDataModel, Restrict}, component_models::{ComponentDataModel, Restrict},
consts::{REGEX_ALIAS, REGEX_COMMANDS, THEME_COLOR}, consts::THEME_COLOR,
framework::{ framework::{
CommandInvoke, CommandOptions, CreateGenericResponse, OptionValue, PermissionLevel, CommandInvoke, CommandOptions, CreateGenericResponse, OptionValue, PermissionLevel,
}, },
models::{channel_data::ChannelData, guild_data::GuildData, user_data::UserData, CtxData}, models::{channel_data::ChannelData, CtxData},
PopularTimezones, RegexFramework, SQLPool, PopularTimezones, RegexFramework, SQLPool,
}; };

View File

@ -1,5 +1,4 @@
use std::{ use std::{
collections::HashMap,
default::Default, default::Default,
string::ToString, string::ToString,
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, UNIX_EPOCH},
@ -8,20 +7,14 @@ use std::{
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use num_integer::Integer; use num_integer::Integer;
use regex_command_attr::command; use regex_command_attr::command;
use serenity::{ use serenity::{client::Context, model::channel::Channel};
client::Context,
futures::StreamExt,
model::{
channel::{Channel, Message},
id::ChannelId,
interactions::message_component::ButtonStyle,
misc::Mentionable,
},
};
use crate::{ use crate::{
check_subscription_on_message, check_subscription_on_message,
component_models::{ComponentDataModel, LookPager, PageAction}, component_models::{
pager::{DelPager, LookPager, Pager},
ComponentDataModel, DelSelector,
},
consts::{ consts::{
EMBED_DESCRIPTION_MAX_LENGTH, REGEX_CHANNEL_USER, REGEX_NATURAL_COMMAND_1, EMBED_DESCRIPTION_MAX_LENGTH, REGEX_CHANNEL_USER, REGEX_NATURAL_COMMAND_1,
REGEX_NATURAL_COMMAND_2, REGEX_REMIND_COMMAND, THEME_COLOR, REGEX_NATURAL_COMMAND_2, REGEX_REMIND_COMMAND, THEME_COLOR,
@ -160,7 +153,7 @@ async fn offset(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args:
let channels = guild let channels = guild
.channels .channels
.iter() .iter()
.filter(|(channel_id, channel)| match channel { .filter(|(_, channel)| match channel {
Channel::Guild(guild_channel) => guild_channel.is_text_based(), Channel::Guild(guild_channel) => guild_channel.is_text_based(),
_ => false, _ => false,
}) })
@ -333,30 +326,7 @@ async fn look(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: C
.fold(0, |t, r| t + r.len()) .fold(0, |t, r| t + r.len())
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH); .div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
let page_first = ComponentDataModel::LookPager(LookPager { let pager = LookPager::new(flags, timezone);
flags: flags.clone(),
page: 0,
action: PageAction::First,
timezone,
});
let page_prev = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: 0,
action: PageAction::Previous,
timezone,
});
let page_next = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: 0,
action: PageAction::Next,
timezone,
});
let page_last = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: 0,
action: PageAction::Last,
timezone,
});
invoke invoke
.respond( .respond(
@ -372,32 +342,9 @@ async fn look(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: C
.color(*THEME_COLOR) .color(*THEME_COLOR)
}) })
.components(|comp| { .components(|comp| {
comp.create_action_row(|row| { pager.create_button_row(pages, comp);
row.create_button(|b| {
b.label("⏮️") comp
.style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id())
.disabled(true)
})
.create_button(|b| {
b.label("◀️")
.style(ButtonStyle::Secondary)
.custom_id(page_prev.to_custom_id())
.disabled(true)
})
.create_button(|b| {
b.label("▶️")
.style(ButtonStyle::Secondary)
.custom_id(page_next.to_custom_id())
.disabled(pages == 1)
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(pages == 1)
})
})
}), }),
) )
.await .await
@ -409,19 +356,92 @@ async fn look(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync), args: C
#[description("Delete reminders")] #[description("Delete reminders")]
#[required_permissions(Managed)] #[required_permissions(Managed)]
async fn delete(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync)) { async fn delete(ctx: &Context, invoke: &(dyn CommandInvoke + Send + Sync)) {
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
let timezone = UserData::timezone_of(&invoke.author_id(), &pool).await;
let reminders = Reminder::from_guild(ctx, invoke.guild_id(), invoke.author_id()).await; let reminders = Reminder::from_guild(ctx, invoke.guild_id(), invoke.author_id()).await;
let enumerated_reminders = reminders.iter().enumerate().map(|(count, reminder)| { if reminders.is_empty() {
format!( let _ = invoke
"**{}**: '{}' *<#{}>* at <t:{}>", .respond(
count + 1, ctx.http.clone(),
reminder.display_content(), CreateGenericResponse::new().content("No reminders to delete!"),
reminder.channel,
reminder.utc_time.timestamp()
) )
}); .await;
} else {
let mut char_count = 0;
let _ = invoke.respond(ctx.http.clone(), CreateGenericResponse::new().content("test")).await; let (shown_reminders, display_vec): (Vec<&Reminder>, Vec<String>) = reminders
.iter()
.enumerate()
.map(|(count, reminder)| (reminder, reminder.display_del(count, &timezone)))
.take_while(|(_, p)| {
char_count += p.len();
char_count < EMBED_DESCRIPTION_MAX_LENGTH
})
.unzip();
let display = display_vec.join("\n");
let pages = reminders
.iter()
.enumerate()
.map(|(count, reminder)| reminder.display_del(count, &timezone))
.fold(0, |t, r| t + r.len())
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
let pager = DelPager::new(timezone);
let del_selector = ComponentDataModel::DelSelector(DelSelector { page: 0, timezone });
invoke
.respond(
ctx.http.clone(),
CreateGenericResponse::new()
.embed(|e| {
e.title("Delete Reminders")
.description(display)
.footer(|f| f.text(format!("Page {} of {}", 1, pages)))
.color(*THEME_COLOR)
})
.components(|comp| {
pager.create_button_row(pages, comp);
comp.create_action_row(|row| {
row.create_select_menu(|menu| {
menu.custom_id(del_selector.to_custom_id()).options(|opt| {
for (count, reminder) in shown_reminders.iter().enumerate() {
opt.create_option(|o| {
o.label(count + 1).value(reminder.id).description({
let c = reminder.display_content();
if c.len() > 100 {
format!(
"{}...",
reminder
.display_content()
.chars()
.take(97)
.collect::<String>()
)
} else {
c.to_string()
}
})
});
}
opt
})
})
})
}),
)
.await
.unwrap();
}
} }
#[command("timer")] #[command("timer")]

View File

@ -1,29 +1,25 @@
pub(crate) mod pager;
use std::io::Cursor; use std::io::Cursor;
use chrono_tz::Tz; use chrono_tz::Tz;
use rmp_serde::Serializer; use rmp_serde::Serializer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_repr::*;
use serenity::{ use serenity::{
builder::CreateEmbed, builder::CreateEmbed,
client::Context, client::Context,
model::{ model::{
channel::Channel, channel::Channel,
id::{ChannelId, GuildId, RoleId, UserId}, id::{GuildId, RoleId, UserId},
interactions::{ interactions::{message_component::MessageComponentInteraction, InteractionResponseType},
message_component::{ButtonStyle, MessageComponentInteraction},
InteractionResponseType,
},
prelude::InteractionApplicationCommandCallbackDataFlags, prelude::InteractionApplicationCommandCallbackDataFlags,
}, },
}; };
use crate::{ use crate::{
component_models::pager::{DelPager, LookPager, Pager},
consts::{EMBED_DESCRIPTION_MAX_LENGTH, THEME_COLOR}, consts::{EMBED_DESCRIPTION_MAX_LENGTH, THEME_COLOR},
models::{ models::reminder::Reminder,
reminder::{look_flags::LookFlags, Reminder},
user_data::UserData,
},
SQLPool, SQLPool,
}; };
@ -33,6 +29,8 @@ use crate::{
pub enum ComponentDataModel { pub enum ComponentDataModel {
Restrict(Restrict), Restrict(Restrict),
LookPager(LookPager), LookPager(LookPager),
DelPager(DelPager),
DelSelector(DelSelector),
} }
impl ComponentDataModel { impl ComponentDataModel {
@ -109,7 +107,7 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
.iter() .iter()
.map(|reminder| reminder.display(&flags, &pager.timezone)) .map(|reminder| reminder.display(&flags, &pager.timezone))
.fold(0, |t, r| t + r.len()) .fold(0, |t, r| t + r.len())
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH) as u16; .div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
let channel_name = let channel_name =
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) { if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
@ -118,12 +116,7 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
None None
}; };
let next_page = match pager.action { let next_page = pager.next_page(pages);
PageAction::First => 0,
PageAction::Previous => 0.max(pager.page - 1),
PageAction::Next => (pages - 1).min(pager.page + 1),
PageAction::Last => pages - 1,
};
let mut char_count = 0; let mut char_count = 0;
let mut skip_char_count = 0; let mut skip_char_count = 0;
@ -144,31 +137,6 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("\n"); .join("\n");
let page_first = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: next_page,
action: PageAction::First,
timezone: pager.timezone,
});
let page_prev = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: next_page,
action: PageAction::Previous,
timezone: pager.timezone,
});
let page_next = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: next_page,
action: PageAction::Next,
timezone: pager.timezone,
});
let page_last = ComponentDataModel::LookPager(LookPager {
flags: flags.clone(),
page: next_page,
action: PageAction::Last,
timezone: pager.timezone,
});
let mut embed = CreateEmbed::default(); let mut embed = CreateEmbed::default();
embed embed
.title(format!( .title(format!(
@ -179,40 +147,223 @@ INSERT IGNORE INTO roles (role, name, guild_id) VALUES (?, \"Role\", (SELECT id
.footer(|f| f.text(format!("Page {} of {}", next_page + 1, pages))) .footer(|f| f.text(format!("Page {} of {}", next_page + 1, pages)))
.color(*THEME_COLOR); .color(*THEME_COLOR);
let _ = let _ = component
.create_interaction_response(&ctx, |r| {
r.kind(InteractionResponseType::UpdateMessage).interaction_response_data(
|response| {
response.embeds(vec![embed]).components(|comp| {
pager.create_button_row(pages, comp);
comp
})
},
)
})
.await;
}
ComponentDataModel::DelPager(pager) => {
let reminders =
Reminder::from_guild(ctx, component.guild_id, component.user.id).await;
let pages = reminders
.iter()
.enumerate()
.map(|(count, reminder)| reminder.display_del(count, &pager.timezone))
.fold(0, |t, r| t + r.len())
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
let next_page = pager.next_page(pages);
let mut char_count = 0;
let mut skip_char_count = 0;
let mut first_num = 0;
let (shown_reminders, display_vec): (Vec<&Reminder>, Vec<String>) = reminders
.iter()
.enumerate()
.map(|(count, reminder)| {
(reminder, reminder.display_del(count, &pager.timezone))
})
.skip_while(|(_, p)| {
first_num += 1;
skip_char_count += p.len();
skip_char_count < EMBED_DESCRIPTION_MAX_LENGTH * next_page
})
.take_while(|(_, p)| {
char_count += p.len();
char_count < EMBED_DESCRIPTION_MAX_LENGTH
})
.unzip();
let display = display_vec.join("\n");
let del_selector = ComponentDataModel::DelSelector(DelSelector {
page: next_page,
timezone: pager.timezone,
});
let mut embed = CreateEmbed::default();
embed
.title("Delete Reminders")
.description(display)
.footer(|f| f.text(format!("Page {} of {}", next_page + 1, pages)))
.color(*THEME_COLOR);
component component
.create_interaction_response(&ctx, |r| { .create_interaction_response(&ctx, |r| {
r.kind(InteractionResponseType::UpdateMessage) r.kind(InteractionResponseType::UpdateMessage).interaction_response_data(
.interaction_response_data(|response| { |response| {
response.embeds(vec![embed]).components(|comp| { response.embeds(vec![embed]).components(|comp| {
pager.create_button_row(pages, comp);
comp.create_action_row(|row| { comp.create_action_row(|row| {
row.create_button(|b| { row.create_select_menu(|menu| {
b.label("⏮️") menu.custom_id(del_selector.to_custom_id()).options(
.style(ButtonStyle::Primary) |opt| {
.custom_id(page_first.to_custom_id()) for (count, reminder) in
.disabled(next_page == 0) shown_reminders.iter().enumerate()
{
opt.create_option(|o| {
o.label(count + first_num)
.value(reminder.id)
.description({
let c =
reminder.display_content();
if c.len() > 100 {
format!(
"{}...",
reminder
.display_content()
.chars()
.take(97)
.collect::<String>(
)
)
} else {
c.to_string()
}
}) })
.create_button(|b| { });
b.label("◀️") }
.style(ButtonStyle::Secondary)
.custom_id(page_prev.to_custom_id()) opt
.disabled(next_page == 0) },
}) )
.create_button(|b| {
b.label("▶️")
.style(ButtonStyle::Secondary)
.custom_id(page_next.to_custom_id())
.disabled(next_page + 1 == pages)
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == pages)
}) })
}) })
}) })
},
)
}) })
.await;
}
ComponentDataModel::DelSelector(selector) => {
let pool = ctx.data.read().await.get::<SQLPool>().cloned().unwrap();
let selected_id = component.data.values.join(",");
sqlx::query!("DELETE FROM reminders WHERE FIND_IN_SET(id, ?)", selected_id)
.execute(&pool)
.await
.unwrap();
let reminders =
Reminder::from_guild(ctx, component.guild_id, component.user.id).await;
let mut char_count = 0;
let mut skip_char_count = 0;
let mut first_num = 0;
let (shown_reminders, display_vec): (Vec<&Reminder>, Vec<String>) = reminders
.iter()
.enumerate()
.map(|(count, reminder)| {
(reminder, reminder.display_del(count, &selector.timezone))
})
.skip_while(|(_, p)| {
first_num += 1;
skip_char_count += p.len();
skip_char_count < EMBED_DESCRIPTION_MAX_LENGTH * selector.page
})
.take_while(|(_, p)| {
char_count += p.len();
char_count < EMBED_DESCRIPTION_MAX_LENGTH
})
.unzip();
let display = display_vec.join("\n");
let pages = reminders
.iter()
.enumerate()
.map(|(count, reminder)| reminder.display_del(count, &selector.timezone))
.fold(0, |t, r| t + r.len())
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH);
let pager = DelPager::new(selector.timezone);
let del_selector = ComponentDataModel::DelSelector(DelSelector {
page: selector.page,
timezone: selector.timezone,
});
let mut embed = CreateEmbed::default();
embed
.title("Delete Reminders")
.description(display)
.footer(|f| f.text(format!("Page {} of {}", selector.page + 1, pages)))
.color(*THEME_COLOR);
component
.create_interaction_response(&ctx, |r| {
r.kind(InteractionResponseType::UpdateMessage).interaction_response_data(
|response| {
response.embeds(vec![embed]).components(|comp| {
pager.create_button_row(pages, comp);
comp.create_action_row(|row| {
row.create_select_menu(|menu| {
menu.custom_id(del_selector.to_custom_id()).options(
|opt| {
for (count, reminder) in
shown_reminders.iter().enumerate()
{
opt.create_option(|o| {
o.label(count + 1)
.value(reminder.id)
.description({
let c =
reminder.display_content();
if c.len() > 100 {
format!(
"{}...",
reminder
.display_content()
.chars()
.take(97)
.collect::<String>(
)
)
} else {
c.to_string()
}
})
});
}
opt
},
)
})
})
})
},
)
}) })
.await; .await;
} }
@ -227,19 +378,8 @@ pub struct Restrict {
pub guild_id: GuildId, pub guild_id: GuildId,
} }
#[derive(Serialize_repr, Deserialize_repr, Debug)] #[derive(Serialize, Deserialize)]
#[repr(u8)] pub struct DelSelector {
pub enum PageAction { pub page: usize,
First = 0,
Previous = 1,
Next = 2,
Last = 3,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct LookPager {
pub flags: LookFlags,
pub page: u16,
pub action: PageAction,
pub timezone: Tz, pub timezone: Tz,
} }

View File

@ -0,0 +1,183 @@
use chrono_tz::Tz;
use serde::{Deserialize, Serialize};
use serde_repr::*;
use serenity::{builder::CreateComponents, model::interactions::message_component::ButtonStyle};
use crate::{component_models::ComponentDataModel, models::reminder::look_flags::LookFlags};
pub trait Pager {
fn next_page(&self, max_pages: usize) -> usize;
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents);
}
#[derive(Serialize_repr, Deserialize_repr)]
#[repr(u8)]
enum PageAction {
First = 0,
Previous = 1,
Next = 2,
Last = 3,
}
#[derive(Serialize, Deserialize)]
pub struct LookPager {
pub flags: LookFlags,
pub page: usize,
action: PageAction,
pub timezone: Tz,
}
impl Pager for LookPager {
fn next_page(&self, max_pages: usize) -> usize {
match self.action {
PageAction::First => 0,
PageAction::Previous => 0.max(self.page - 1),
PageAction::Next => (max_pages - 1).min(self.page + 1),
PageAction::Last => max_pages - 1,
}
}
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) {
let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_next, page_last) =
LookPager::buttons(self.flags, next_page, self.timezone);
comp.create_action_row(|row| {
row.create_button(|b| {
b.label("⏮️")
.style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id())
.disabled(next_page == 0)
})
.create_button(|b| {
b.label("◀️")
.style(ButtonStyle::Secondary)
.custom_id(page_prev.to_custom_id())
.disabled(next_page == 0)
})
.create_button(|b| {
b.label("▶️")
.style(ButtonStyle::Secondary)
.custom_id(page_next.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
}
}
impl LookPager {
pub fn new(flags: LookFlags, timezone: Tz) -> Self {
Self { flags, page: 0, action: PageAction::First, timezone }
}
pub fn buttons(
flags: LookFlags,
page: usize,
timezone: Tz,
) -> (ComponentDataModel, ComponentDataModel, ComponentDataModel, ComponentDataModel) {
(
ComponentDataModel::LookPager(LookPager {
flags,
page,
action: PageAction::First,
timezone,
}),
ComponentDataModel::LookPager(LookPager {
flags,
page,
action: PageAction::Previous,
timezone,
}),
ComponentDataModel::LookPager(LookPager {
flags,
page,
action: PageAction::Next,
timezone,
}),
ComponentDataModel::LookPager(LookPager {
flags,
page,
action: PageAction::Last,
timezone,
}),
)
}
}
#[derive(Serialize, Deserialize)]
pub struct DelPager {
pub page: usize,
action: PageAction,
pub timezone: Tz,
}
impl Pager for DelPager {
fn next_page(&self, max_pages: usize) -> usize {
match self.action {
PageAction::First => 0,
PageAction::Previous => 0.max(self.page - 1),
PageAction::Next => (max_pages - 1).min(self.page + 1),
PageAction::Last => max_pages - 1,
}
}
fn create_button_row(&self, max_pages: usize, comp: &mut CreateComponents) {
let next_page = self.next_page(max_pages);
let (page_first, page_prev, page_next, page_last) =
DelPager::buttons(next_page, self.timezone);
comp.create_action_row(|row| {
row.create_button(|b| {
b.label("⏮️")
.style(ButtonStyle::Primary)
.custom_id(page_first.to_custom_id())
.disabled(next_page == 0)
})
.create_button(|b| {
b.label("◀️")
.style(ButtonStyle::Secondary)
.custom_id(page_prev.to_custom_id())
.disabled(next_page == 0)
})
.create_button(|b| {
b.label("▶️")
.style(ButtonStyle::Secondary)
.custom_id(page_next.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
.create_button(|b| {
b.label("⏭️")
.style(ButtonStyle::Primary)
.custom_id(page_last.to_custom_id())
.disabled(next_page + 1 == max_pages)
})
});
}
}
impl DelPager {
pub fn new(timezone: Tz) -> Self {
Self { page: 0, action: PageAction::First, timezone }
}
pub fn buttons(
page: usize,
timezone: Tz,
) -> (ComponentDataModel, ComponentDataModel, ComponentDataModel, ComponentDataModel) {
(
ComponentDataModel::DelPager(DelPager { page, action: PageAction::First, timezone }),
ComponentDataModel::DelPager(DelPager { page, action: PageAction::Previous, timezone }),
ComponentDataModel::DelPager(DelPager { page, action: PageAction::Next, timezone }),
ComponentDataModel::DelPager(DelPager { page, action: PageAction::Last, timezone }),
)
}
}

View File

@ -16,15 +16,13 @@ use serenity::{
framework::Framework, framework::Framework,
futures::prelude::future::BoxFuture, futures::prelude::future::BoxFuture,
http::Http, http::Http,
json::Value,
model::{ model::{
channel::{Channel, GuildChannel, Message}, channel::{Channel, GuildChannel, Message},
guild::{Guild, Member}, guild::{Guild, Member},
id::{ChannelId, GuildId, MessageId, RoleId, UserId}, id::{ChannelId, GuildId, MessageId, RoleId, UserId},
interactions::{ interactions::{
application_command::{ application_command::{
ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOption, ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType,
ApplicationCommandOptionType,
}, },
InteractionResponseType, InteractionResponseType,
}, },
@ -772,7 +770,8 @@ impl RegexFramework {
ApplicationCommand::set_global_application_commands(&http, |c| { ApplicationCommand::set_global_application_commands(&http, |c| {
self._populate_commands(c) self._populate_commands(c)
}) })
.await; .await
.unwrap();
} }
Some(debug_guild) => { Some(debug_guild) => {
debug_guild debug_guild

View File

@ -304,9 +304,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
.add_command("natural", &reminder_cmds::NATURAL_COMMAND) .add_command("natural", &reminder_cmds::NATURAL_COMMAND)
.add_command("n", &reminder_cmds::NATURAL_COMMAND) .add_command("n", &reminder_cmds::NATURAL_COMMAND)
.add_command("", &reminder_cmds::NATURAL_COMMAND) .add_command("", &reminder_cmds::NATURAL_COMMAND)
// management commands
.add_command("del", &reminder_cmds::DELETE_COMMAND)
*/ */
// management commands
.add_command(&reminder_cmds::DELETE_COMMAND)
.add_command(&reminder_cmds::LOOK_COMMAND) .add_command(&reminder_cmds::LOOK_COMMAND)
.add_command(&reminder_cmds::PAUSE_COMMAND) .add_command(&reminder_cmds::PAUSE_COMMAND)
.add_command(&reminder_cmds::OFFSET_COMMAND) .add_command(&reminder_cmds::OFFSET_COMMAND)

View File

@ -2,8 +2,6 @@ use serde::{Deserialize, Serialize};
use serde_repr::*; use serde_repr::*;
use serenity::model::id::ChannelId; use serenity::model::id::ChannelId;
use crate::consts::REGEX_CHANNEL;
#[derive(Serialize_repr, Deserialize_repr, Copy, Clone, Debug)] #[derive(Serialize_repr, Deserialize_repr, Copy, Clone, Debug)]
#[repr(u8)] #[repr(u8)]
pub enum TimeDisplayType { pub enum TimeDisplayType {

View File

@ -4,11 +4,6 @@ pub mod errors;
mod helper; mod helper;
pub mod look_flags; pub mod look_flags;
use std::{
convert::{TryFrom, TryInto},
env,
};
use chrono::{NaiveDateTime, TimeZone}; use chrono::{NaiveDateTime, TimeZone};
use chrono_tz::Tz; use chrono_tz::Tz;
use serenity::{ use serenity::{
@ -19,14 +14,13 @@ use sqlx::MySqlPool;
use crate::{ use crate::{
models::reminder::{ models::reminder::{
errors::InteractionError,
helper::longhand_displacement, helper::longhand_displacement,
look_flags::{LookFlags, TimeDisplayType}, look_flags::{LookFlags, TimeDisplayType},
}, },
SQLPool, SQLPool,
}; };
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Reminder { pub struct Reminder {
pub id: u32, pub id: u32,
pub uid: String, pub uid: String,
@ -284,6 +278,19 @@ WHERE
} }
} }
pub fn display_del(&self, count: usize, timezone: &Tz) -> String {
format!(
"**{}**: '{}' *<#{}>* at **{}**",
count + 1,
self.display_content(),
self.channel,
timezone
.timestamp(self.utc_time.timestamp(), 0)
.format("%Y-%m-%d %H:%M:%S")
.to_string()
)
}
pub fn display(&self, flags: &LookFlags, timezone: &Tz) -> String { pub fn display(&self, flags: &LookFlags, timezone: &Tz) -> String {
let time_display = match flags.time_display { let time_display = match flags.time_display {
TimeDisplayType::Absolute => timezone TimeDisplayType::Absolute => timezone