@@ -4,7 +4,10 @@ use crate::{
44 Context , Error ,
55} ;
66use :: serenity:: futures:: { Stream , StreamExt } ;
7- use poise:: serenity_prelude:: { futures, CreateAttachment , CreateEmbed } ;
7+ use poise:: serenity_prelude:: {
8+ self as serenity, futures, CreateAttachment , CreateEmbed , CreateInteractionResponse ,
9+ CreateInteractionResponseMessage ,
10+ } ;
811
912async fn autocomplete_snippet < ' a > (
1013 ctx : Context < ' a > ,
@@ -17,14 +20,12 @@ async fn autocomplete_snippet<'a>(
1720 . unwrap ( )
1821 . snippets
1922 . iter ( )
20- . take ( 25 )
2123 . map ( |s| format ! ( "{}: {}" , s. id, s. title) )
2224 . collect ( )
2325 } ;
2426
2527 futures:: stream:: iter ( snippet_list)
26- . filter ( move |name| futures:: future:: ready ( name. starts_with ( partial) ) )
27- . map ( |name| name. to_string ( ) )
28+ . filter ( move |name| futures:: future:: ready ( name. contains ( partial) ) )
2829}
2930
3031/// Show a snippet
@@ -152,10 +153,7 @@ pub async fn remove_snippet(
152153) -> Result < ( ) , Error > {
153154 match get_snippet_lazy ( & ctx, & id) . await {
154155 Some ( snippet) => {
155- rm_snippet ( & ctx, & snippet) . await ;
156- let title = & "Snippet successfully removed" ;
157- let content = & & format ! ( "Removed snippet '{}: {}'" , snippet. id, snippet. title) ;
158- respond_ok ( & ctx, title, content) . await ;
156+ remove_snippet_confirm ( & ctx, & snippet) . await ?;
159157 }
160158 None => {
161159 let title = & "Failed to remove snippet" ;
@@ -215,10 +213,8 @@ pub async fn export_snippet(
215213) -> Result < ( ) , Error > {
216214 match get_snippet_lazy ( & ctx, & id) . await {
217215 Some ( snippet) => {
218- let attachment = CreateAttachment :: bytes (
219- format ! ( "{}" , & snippet. content. replace( '\n' , r"\n" ) ) ,
220- "snippet.txt" ,
221- ) ;
216+ let attachment =
217+ CreateAttachment :: bytes ( snippet. content . replace ( '\n' , r"\n" ) , "snippet.txt" ) ;
222218 let message = poise:: CreateReply :: default ( )
223219 . attachment ( attachment)
224220 . embed ( snippet. embed ( ) ) ;
@@ -282,3 +278,83 @@ async fn rm_snippet(ctx: &Context<'_>, snippet: &Snippet) {
282278 rwlock_guard. snippets . remove ( index) ;
283279 rwlock_guard. write ( ) ;
284280}
281+
282+ async fn remove_snippet_confirm ( ctx : & Context < ' _ > , snippet : & Snippet ) -> Result < ( ) , Error > {
283+ let snippet_embed = snippet. embed ( ) ;
284+
285+ let ctx_id = ctx. id ( ) ;
286+ let delete_id = format ! ( "{}cancel" , ctx_id) ;
287+ let cancel_id = format ! ( "{}delete" , ctx_id) ;
288+
289+ let components = serenity:: CreateActionRow :: Buttons ( vec ! [
290+ serenity:: CreateButton :: new( & cancel_id) . label( "Cancel" ) ,
291+ serenity:: CreateButton :: new( & delete_id)
292+ . label( "Delete" )
293+ . style( serenity:: ButtonStyle :: Danger ) ,
294+ ] ) ;
295+
296+ let builder: poise:: CreateReply = poise:: CreateReply :: default ( )
297+ . content ( format ! ( "Are you sure you want to delete snippet `{}`?" , snippet. id) )
298+ . ephemeral ( true )
299+ . embed ( snippet_embed)
300+ . components ( vec ! [ components] ) ;
301+
302+ ctx. send ( builder) . await ?;
303+
304+ while let Some ( press) = serenity:: ComponentInteractionCollector :: new ( ctx)
305+ . filter ( move |press| press. data . custom_id . starts_with ( & ctx_id. to_string ( ) ) )
306+ . timeout ( std:: time:: Duration :: from_secs ( 60 ) )
307+ . await
308+ {
309+ if press. data . custom_id == delete_id {
310+ handle_delete ( ctx, snippet, press) . await ?;
311+ } else if press. data . custom_id == cancel_id {
312+ handle_cancel ( ctx, press) . await ?;
313+ }
314+ }
315+
316+ Ok ( ( ) )
317+ }
318+
319+ async fn handle_delete (
320+ ctx : & Context < ' _ > ,
321+ snippet : & Snippet ,
322+ interaction : serenity:: ComponentInteraction ,
323+ ) -> Result < ( ) , Error > {
324+
325+ rm_snippet ( ctx, snippet) . await ;
326+ interaction
327+ . create_response (
328+ ctx,
329+ CreateInteractionResponse :: UpdateMessage (
330+ CreateInteractionResponseMessage :: new ( ) . content ( "Deleted!" )
331+ . embeds ( vec ! [ ] )
332+ . components ( vec ! [ ] ) ,
333+ ) ,
334+ )
335+ . await ?;
336+
337+ let title = format ! ( "{} removed a snippet" , ctx. author( ) . tag( ) ) ;
338+ let content = & & format ! ( "Removed snippet `{}`" , snippet. format_output( ) ) ;
339+ respond_ok ( ctx, & title, content) . await ;
340+
341+ Ok ( ( ) )
342+ }
343+
344+ async fn handle_cancel (
345+ ctx : & Context < ' _ > ,
346+ interaction : serenity:: ComponentInteraction ,
347+ ) -> Result < ( ) , Error > {
348+ interaction
349+ . create_response (
350+ ctx,
351+ CreateInteractionResponse :: UpdateMessage (
352+ CreateInteractionResponseMessage :: new ( )
353+ . content ( "Aborted." )
354+ . embeds ( vec ! [ ] )
355+ . components ( vec ! [ ] ) ,
356+ ) ,
357+ )
358+ . await ?;
359+ Ok ( ( ) )
360+ }
0 commit comments