@@ -2,10 +2,11 @@ use std::net::Ipv4Addr;
22use std:: str:: FromStr ;
33use std:: time:: Duration ;
44use 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;
78use 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 } ;
910use crate :: minecraft:: { join, ping, query} ;
1011
1112fn 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
3233pub 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+
102233pub 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