look command pager
This commit is contained in:
@ -1,13 +1,28 @@
|
||||
use std::io::Cursor;
|
||||
|
||||
use chrono_tz::Tz;
|
||||
use rmp_serde::Serializer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serenity::model::{
|
||||
id::{ChannelId, RoleId},
|
||||
interactions::message_component::MessageComponentInteraction,
|
||||
use serenity::{
|
||||
builder::CreateEmbed,
|
||||
client::Context,
|
||||
model::{
|
||||
channel::Channel,
|
||||
id::{ChannelId, RoleId},
|
||||
interactions::{
|
||||
message_component::{ButtonStyle, MessageComponentInteraction},
|
||||
InteractionResponseType,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::models::reminder::look_flags::LookFlags;
|
||||
use crate::{
|
||||
consts::{EMBED_DESCRIPTION_MAX_LENGTH, THEME_COLOR},
|
||||
models::{
|
||||
reminder::{look_flags::LookFlags, Reminder},
|
||||
user_data::UserData,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
@ -29,23 +44,160 @@ impl ComponentDataModel {
|
||||
rmp_serde::from_read(cur).unwrap()
|
||||
}
|
||||
|
||||
pub async fn act(&self, component: MessageComponentInteraction) {
|
||||
pub async fn act(&self, ctx: &Context, component: MessageComponentInteraction) {
|
||||
match self {
|
||||
ComponentDataModel::Restrict(restrict) => {
|
||||
println!("{:?}", component.data.values);
|
||||
}
|
||||
ComponentDataModel::LookPager(pager) => {}
|
||||
ComponentDataModel::LookPager(pager) => {
|
||||
let flags = pager.flags;
|
||||
|
||||
let channel_opt = component.channel_id.to_channel_cached(&ctx);
|
||||
|
||||
let channel_id = if let Some(Channel::Guild(channel)) = channel_opt {
|
||||
if Some(channel.guild_id) == component.guild_id {
|
||||
flags.channel_id.unwrap_or(component.channel_id)
|
||||
} else {
|
||||
component.channel_id
|
||||
}
|
||||
} else {
|
||||
component.channel_id
|
||||
};
|
||||
|
||||
let reminders = Reminder::from_channel(ctx, channel_id, &flags).await;
|
||||
|
||||
let pages = reminders
|
||||
.iter()
|
||||
.map(|reminder| reminder.display(&flags, &pager.timezone))
|
||||
.fold(0, |t, r| t + r.len())
|
||||
.div_ceil(EMBED_DESCRIPTION_MAX_LENGTH) as u16;
|
||||
|
||||
let channel_name =
|
||||
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
|
||||
Some(channel.name)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let next_page = match pager.action {
|
||||
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 skip_char_count = 0;
|
||||
|
||||
let display = reminders
|
||||
.iter()
|
||||
.map(|reminder| reminder.display(&flags, &pager.timezone))
|
||||
.skip_while(|p| {
|
||||
skip_char_count += p.len();
|
||||
|
||||
skip_char_count < EMBED_DESCRIPTION_MAX_LENGTH * next_page as usize
|
||||
})
|
||||
.take_while(|p| {
|
||||
char_count += p.len();
|
||||
|
||||
char_count < EMBED_DESCRIPTION_MAX_LENGTH
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.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();
|
||||
embed
|
||||
.title(format!(
|
||||
"Reminders{}",
|
||||
channel_name.map_or(String::new(), |n| format!(" on #{}", n))
|
||||
))
|
||||
.description(display)
|
||||
.footer(|f| f.text(format!("Page {} of {}", next_page + 1, pages)))
|
||||
.color(*THEME_COLOR);
|
||||
|
||||
let _ =
|
||||
component
|
||||
.create_interaction_response(&ctx, |r| {
|
||||
r.kind(InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|response| {
|
||||
response.embeds(vec![embed]).components(|comp| {
|
||||
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 == pages)
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.label("⏭️")
|
||||
.style(ButtonStyle::Primary)
|
||||
.custom_id(page_last.to_custom_id())
|
||||
.disabled(next_page + 1 == pages)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Restrict {
|
||||
pub role_id: RoleId,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum PageAction {
|
||||
First = 0,
|
||||
Previous = 1,
|
||||
Next = 2,
|
||||
Last = 3,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LookPager {
|
||||
pub flags: LookFlags,
|
||||
pub page_request: u16,
|
||||
pub page: u16,
|
||||
pub action: PageAction,
|
||||
pub timezone: Tz,
|
||||
}
|
||||
|
Reference in New Issue
Block a user