@@ -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
@@ -150,10 +151,7 @@ pub async fn remove_snippet(
150151) -> Result < ( ) , Error > {
151152 match get_snippet_lazy ( & ctx, & id) . await {
152153 Some ( snippet) => {
153- rm_snippet ( & ctx, & snippet) . await ;
154- let title = & "Snippet successfully removed" ;
155- let content = & & format ! ( "Removed snippet '{}: {}'" , snippet. id, snippet. title) ;
156- respond_ok ( & ctx, title, content) . await ;
154+ remove_snippet_confirm ( & ctx, & snippet) . await ?;
157155 }
158156 None => {
159157 let title = & "Failed to remove snippet" ;
@@ -213,10 +211,8 @@ pub async fn export_snippet(
213211) -> Result < ( ) , Error > {
214212 match get_snippet_lazy ( & ctx, & id) . await {
215213 Some ( snippet) => {
216- let attachment = CreateAttachment :: bytes (
217- format ! ( "{}" , & snippet. content. replace( '\n' , r"\n" ) ) ,
218- "snippet.txt" ,
219- ) ;
214+ let attachment =
215+ CreateAttachment :: bytes ( snippet. content . replace ( '\n' , r"\n" ) , "snippet.txt" ) ;
220216 let message = poise:: CreateReply :: default ( )
221217 . attachment ( attachment)
222218 . embed ( snippet. embed ( ) ) ;
@@ -280,3 +276,83 @@ async fn rm_snippet(ctx: &Context<'_>, snippet: &Snippet) {
280276 rwlock_guard. snippets . remove ( index) ;
281277 rwlock_guard. write ( ) ;
282278}
279+
280+ async fn remove_snippet_confirm ( ctx : & Context < ' _ > , snippet : & Snippet ) -> Result < ( ) , Error > {
281+ let snippet_embed = snippet. embed ( ) ;
282+
283+ let ctx_id = ctx. id ( ) ;
284+ let delete_id = format ! ( "{}cancel" , ctx_id) ;
285+ let cancel_id = format ! ( "{}delete" , ctx_id) ;
286+
287+ let components = serenity:: CreateActionRow :: Buttons ( vec ! [
288+ serenity:: CreateButton :: new( & cancel_id) . label( "Cancel" ) ,
289+ serenity:: CreateButton :: new( & delete_id)
290+ . label( "Delete" )
291+ . style( serenity:: ButtonStyle :: Danger ) ,
292+ ] ) ;
293+
294+ let builder: poise:: CreateReply = poise:: CreateReply :: default ( )
295+ . content ( format ! ( "Are you sure you want to delete snippet `{}`?" , snippet. id) )
296+ . ephemeral ( true )
297+ . embed ( snippet_embed)
298+ . components ( vec ! [ components] ) ;
299+
300+ ctx. send ( builder) . await ?;
301+
302+ while let Some ( press) = serenity:: ComponentInteractionCollector :: new ( ctx)
303+ . filter ( move |press| press. data . custom_id . starts_with ( & ctx_id. to_string ( ) ) )
304+ . timeout ( std:: time:: Duration :: from_secs ( 60 ) )
305+ . await
306+ {
307+ if press. data . custom_id == delete_id {
308+ handle_delete ( ctx, snippet, press) . await ?;
309+ } else if press. data . custom_id == cancel_id {
310+ handle_cancel ( ctx, press) . await ?;
311+ }
312+ }
313+
314+ Ok ( ( ) )
315+ }
316+
317+ async fn handle_delete (
318+ ctx : & Context < ' _ > ,
319+ snippet : & Snippet ,
320+ interaction : serenity:: ComponentInteraction ,
321+ ) -> Result < ( ) , Error > {
322+
323+ rm_snippet ( ctx, snippet) . await ;
324+ interaction
325+ . create_response (
326+ ctx,
327+ CreateInteractionResponse :: UpdateMessage (
328+ CreateInteractionResponseMessage :: new ( ) . content ( "Deleted!" )
329+ . embeds ( vec ! [ ] )
330+ . components ( vec ! [ ] ) ,
331+ ) ,
332+ )
333+ . await ?;
334+
335+ let title = format ! ( "{} removed a snippet" , ctx. author( ) . tag( ) ) ;
336+ let content = & & format ! ( "Removed snippet `{}`" , snippet. format_output( ) ) ;
337+ respond_ok ( ctx, & title, content) . await ;
338+
339+ Ok ( ( ) )
340+ }
341+
342+ async fn handle_cancel (
343+ ctx : & Context < ' _ > ,
344+ interaction : serenity:: ComponentInteraction ,
345+ ) -> Result < ( ) , Error > {
346+ interaction
347+ . create_response (
348+ ctx,
349+ CreateInteractionResponse :: UpdateMessage (
350+ CreateInteractionResponseMessage :: new ( )
351+ . content ( "Aborted." )
352+ . embeds ( vec ! [ ] )
353+ . components ( vec ! [ ] ) ,
354+ ) ,
355+ )
356+ . await ?;
357+ Ok ( ( ) )
358+ }
0 commit comments