Skip to content

Commit 330d2d3

Browse files
committed
feat(paginator): add player paged view with server interaction
1 parent d01d41a commit 330d2d3

1 file changed

Lines changed: 137 additions & 6 deletions

File tree

src/discord/actions/paginator.rs

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ use std::net::Ipv4Addr;
22
use std::str::FromStr;
33
use std::time::Duration;
44
use chrono::Utc;
5-
use serenity::all::{ButtonStyle, ComponentInteractionCollector, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseMessage, EditAttachments, EditInteractionResponse, EditMessage, Message};
6-
use crate::database::{ServerHistory, ServerInfo};
5+
use serenity::all::{ButtonStyle, ComponentInteractionCollector, CreateActionRow, CreateButton, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseMessage, EditAttachments, EditInteractionResponse, EditMessage, Message, UserId};
6+
use crate::database::{PlayerHistory, ServerHistory, ServerInfo};
7+
use crate::database::server::get_server_by_id;
78
use crate::discord::actions::server::{build_manage_server_action_row, build_server_embed, convert_img_for_discord, view_mods, view_players, view_plugins, view_sample};
8-
use crate::discord::{create_error_embed, create_loading_embed, Context, Error};
9+
use crate::discord::{actions, create_base_embed, create_error_embed, create_loading_embed, Context, Error};
910
use crate::minecraft::{join, ping, query};
1011

1112
fn create_action_row(page: usize, total: usize, disabled: bool) -> Vec<CreateActionRow> {
@@ -31,7 +32,7 @@ fn create_action_row(page: usize, total: usize, disabled: bool) -> Vec<CreateAct
3132

3233
pub async fn base_paginator(
3334
ctx: serenity::all::Context,
34-
author_id: serenity::all::UserId,
35+
author_id: UserId,
3536
mut message: Message,
3637
pages: Vec<CreateEmbed>,
3738
) -> Result<(), Error> {
@@ -99,6 +100,136 @@ pub async fn base_paginator(
99100
Ok(())
100101
}
101102

103+
pub async fn player_paged_view(
104+
ctx: Context<'_>,
105+
author_id: UserId,
106+
mut message: Message,
107+
player_history: Vec<PlayerHistory>,
108+
) -> Result<(), Error> {
109+
let total_pages = player_history.len();
110+
if total_pages == 0 { return Ok(()); }
111+
112+
let embeds: Vec<CreateEmbed> = player_history.iter().map(|history| {
113+
create_base_embed(None)
114+
.title(format!("History Entry: {}", history.username))
115+
.field("Server ID", format!("`{}`", history.server_id), true)
116+
.field("Seen at", format!("<t:{}:F>", history.seen), true)
117+
.thumbnail(format!("https://mc-heads.net/avatar/{}", history.uuid))
118+
}).collect();
119+
120+
let make_components = |disabled: bool, current: usize, total: usize| {
121+
let mut rows = vec![
122+
CreateActionRow::Buttons(vec![
123+
CreateButton::new("view_server")
124+
.label("View Server")
125+
.emoji('⏺')
126+
.style(ButtonStyle::Primary)
127+
.disabled(disabled)
128+
])
129+
];
130+
rows.extend(create_action_row(current, total, disabled));
131+
rows
132+
};
133+
134+
let mut current_page = 0;
135+
136+
let get_page_embed = |idx: usize, base_embeds: &[CreateEmbed]| {
137+
base_embeds[idx].clone().footer(CreateEmbedFooter::new(format!(
138+
"ServerRawler {} • Page {}/{}",
139+
crate::get_version_raw(),
140+
idx + 1,
141+
total_pages
142+
)))
143+
};
144+
145+
loop {
146+
let current_embed = get_page_embed(current_page, &embeds);
147+
148+
message.edit(&ctx.http(), EditMessage::default()
149+
.embed(current_embed)
150+
.components(make_components(false, current_page, total_pages))
151+
).await?;
152+
153+
let interaction = ComponentInteractionCollector::new(ctx)
154+
.author_id(author_id)
155+
.message_id(message.id)
156+
.timeout(Duration::from_secs(35))
157+
.await;
158+
159+
let mci = match interaction {
160+
Some(i) => i,
161+
None => break,
162+
};
163+
164+
match mci.data.custom_id.as_str() {
165+
"first" => current_page = 0,
166+
"prev" => if current_page > 0 { current_page -= 1 },
167+
"next" => if current_page < total_pages - 1 { current_page += 1 },
168+
"last" => current_page = total_pages - 1,
169+
"view_server" => {
170+
let start_time = Utc::now();
171+
let server_id = player_history[current_page].server_id;
172+
173+
mci.create_response(&ctx.http(), CreateInteractionResponse::UpdateMessage(
174+
CreateInteractionResponseMessage::new().embed(create_loading_embed("fetching server from database"))
175+
)).await?;
176+
177+
178+
match get_server_by_id(server_id).await {
179+
Ok(Some((info, history))) => {
180+
actions::server::create_one_server_action(
181+
start_time,
182+
ctx,
183+
&mut message,
184+
info,
185+
history
186+
).await?;
187+
},
188+
Ok(None) => {
189+
message.edit(&ctx.http(), EditMessage::default()
190+
.embed(create_error_embed("Server not found in database.", None))
191+
.components(vec![CreateActionRow::Buttons(vec![
192+
CreateButton::new("back_to_history").label("Back").style(ButtonStyle::Danger)
193+
])])
194+
).await?;
195+
196+
tokio::time::sleep(Duration::from_secs(3)).await;
197+
continue;
198+
},
199+
Err(e) => {
200+
message.edit(&ctx.http(), EditMessage::default()
201+
.embed(create_error_embed("Database error", None))
202+
).await?;
203+
204+
tokio::time::sleep(Duration::from_secs(3)).await;
205+
continue;
206+
}
207+
}
208+
}
209+
_ => continue,
210+
}
211+
212+
mci.create_response(
213+
&ctx.http(),
214+
CreateInteractionResponse::UpdateMessage(
215+
CreateInteractionResponseMessage::new()
216+
.embed(get_page_embed(current_page, &embeds))
217+
.components(make_components(false, current_page, total_pages))
218+
)
219+
).await?;
220+
}
221+
222+
let final_embed = get_page_embed(current_page, &embeds);
223+
let _ = message.edit(
224+
&ctx.http(),
225+
EditMessage::default()
226+
.embed(final_embed)
227+
.components(make_components(true, current_page, total_pages))
228+
).await;
229+
230+
Ok(())
231+
}
232+
102233
pub async fn create_paged_server_view(
103234
ctx: Context<'_>,
104235
mut message: Message,
@@ -307,11 +438,11 @@ pub async fn create_paged_server_view(
307438
let mut components = build_manage_server_action_row(true, history);
308439
components.extend(create_action_row(current_page, total_pages, true));
309440

310-
message.edit(
441+
let _ = message.edit(
311442
ctx, EditMessage::default()
312443
.embed(current_embed.clone())
313444
.components(components)
314-
).await?;
445+
).await;
315446

316447
Ok(())
317448
}

0 commit comments

Comments
 (0)