Skip to content

Commit 4b06939

Browse files
Merge pull request #28 from jamesbt365/interaction-qol
Better interaction handling
2 parents 13a5ef7 + a4d4687 commit 4b06939

7 files changed

Lines changed: 137 additions & 166 deletions

File tree

268075-nixpkgs.patch

Lines changed: 0 additions & 131 deletions
This file was deleted.

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,7 @@
1111

1212
importPkgs = pkgs: import pkgs { inherit system; };
1313

14-
patchedPkgs = (importPkgs nixpkgs).applyPatches {
15-
name = "nixpkgs-patched";
16-
src = nixpkgs;
17-
patches = [ ./268075-nixpkgs.patch ];
18-
};
19-
20-
pkgs = importPkgs patchedPkgs;
14+
pkgs = importPkgs nixpkgs;
2115

2216
in rec {
2317

src/commands/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ pub(crate) const ERROR_COLOUR: Colour = Colour(0xe74c3c);
88
use crate::{Context, Error};
99

1010
use poise::serenity_prelude::{
11-
self as serenity, Colour, ComponentInteractionCollector, CreateActionRow, CreateButton,
12-
CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseMessage,
11+
self as serenity, Colour, ComponentInteraction, ComponentInteractionCollector, CreateActionRow,
12+
CreateButton, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse,
13+
CreateInteractionResponseMessage,
1314
};
1415
use poise::CreateReply;
1516

@@ -49,6 +50,20 @@ pub async fn respond_err(ctx: &Context<'_>, title: &str, content: &str) {
4950
respond_embed(ctx, embed, false).await;
5051
}
5152

53+
pub async fn interaction_err(ctx: &serenity::Context, press: &ComponentInteraction, content: &str) {
54+
let builder = CreateInteractionResponse::Message(
55+
CreateInteractionResponseMessage::new()
56+
.embed(
57+
CreateEmbed::new()
58+
.title("Unable to execute interaction")
59+
.description(content)
60+
.colour(ERROR_COLOUR),
61+
)
62+
.ephemeral(true),
63+
);
64+
let _ = press.create_response(ctx, builder).await;
65+
}
66+
5267
pub async fn paginate_lists<U, E>(
5368
ctx: poise::Context<'_, U, E>,
5469
pages: &[Vec<(String, String, bool)>],

src/commands/snippets.rs

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use crate::{
44
Context, Error,
55
};
66
use ::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

912
async 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+
}

src/commands/utils.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@ async fn autocomplete_key<'a>(
1919
.unwrap()
2020
.issue_prefixes
2121
.iter()
22-
.take(25)
2322
.map(|s| s.0.clone())
2423
.collect()
2524
};
2625

2726
futures::stream::iter(snippet_list)
28-
.filter(move |name| futures::future::ready(name.starts_with(partial)))
29-
.map(|name| name.to_string())
27+
.filter(move |name| futures::future::ready(name.contains(partial)))
3028
}
3129

3230
/// Create an embed in the current channel.

0 commit comments

Comments
 (0)