From 81d7fa59971e2d8c5b8e1676b7af0206b627b366 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Sat, 8 May 2021 22:36:52 +0100 Subject: [PATCH 1/3] Updated dependencies --- .../Discord.Addons.Interactive.csproj | 4 ++-- SampleApp/SampleApp.csproj | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj index ce5f9bc..8a136a2 100644 --- a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj +++ b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj @@ -18,8 +18,8 @@ - - + + \ No newline at end of file diff --git a/SampleApp/SampleApp.csproj b/SampleApp/SampleApp.csproj index 50052b9..d3de106 100644 --- a/SampleApp/SampleApp.csproj +++ b/SampleApp/SampleApp.csproj @@ -6,9 +6,9 @@ - - - + + + From 113fa3509eecb1987a1ce883446ba009bf0a30d3 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Wed, 5 Jan 2022 19:37:38 +0000 Subject: [PATCH 2/3] Updated to latest, cleaned up some code formatting. --- .gitignore | 3 +- .../Criteria/Criteria.cs | 2 +- .../Discord.Addons.Interactive.csproj | 4 +- ...cord.Addons.Interactive.csproj.DotSettings | 5 ++ Discord.Addons.Interactive/InteractiveBase.cs | 12 +++-- .../InteractiveService.cs | 48 +++++++++++-------- .../EnsureReactionFromSourceUserCriterion.cs | 6 +-- SampleApp/SampleApp.csproj | 14 ++++-- 8 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 Discord.Addons.Interactive/Discord.Addons.Interactive.csproj.DotSettings diff --git a/.gitignore b/.gitignore index 3c4efe2..e5d4b2a 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,5 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc +/SampleApp/*.ignore diff --git a/Discord.Addons.Interactive/Criteria/Criteria.cs b/Discord.Addons.Interactive/Criteria/Criteria.cs index f3ffbe3..156ca50 100644 --- a/Discord.Addons.Interactive/Criteria/Criteria.cs +++ b/Discord.Addons.Interactive/Criteria/Criteria.cs @@ -6,7 +6,7 @@ namespace Discord.Addons.Interactive { public class Criteria : ICriterion { - private List> _critiera = new List>(); + private readonly List> _critiera = new List>(); public Criteria AddCriterion(ICriterion criterion) { diff --git a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj index 8a136a2..fdc84b8 100644 --- a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj +++ b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj @@ -18,8 +18,8 @@ - - + + \ No newline at end of file diff --git a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj.DotSettings b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj.DotSettings new file mode 100644 index 0000000..0f273b0 --- /dev/null +++ b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj.DotSettings @@ -0,0 +1,5 @@ + + True + True + True + True \ No newline at end of file diff --git a/Discord.Addons.Interactive/InteractiveBase.cs b/Discord.Addons.Interactive/InteractiveBase.cs index 89e5369..3dc7f8f 100644 --- a/Discord.Addons.Interactive/InteractiveBase.cs +++ b/Discord.Addons.Interactive/InteractiveBase.cs @@ -7,18 +7,20 @@ namespace Discord.Addons.Interactive { - public abstract class InteractiveBase : InteractiveBase + public abstract class InteractiveBase + : InteractiveBase { } - public abstract class InteractiveBase : ModuleBase + public abstract class InteractiveBase + : ModuleBase where T : SocketCommandContext { public InteractiveService Interactive { get; set; } - public Task NextMessageAsync(ICriterion criterion, TimeSpan? timeout = null, CancellationToken token = default(CancellationToken)) + public Task NextMessageAsync(ICriterion criterion, TimeSpan? timeout = null, CancellationToken token = default) => Interactive.NextMessageAsync(Context, criterion, timeout, token); - public Task NextMessageAsync(bool fromSourceUser = true, bool inSourceChannel = true, TimeSpan? timeout = null, CancellationToken token = default(CancellationToken)) + public Task NextMessageAsync(bool fromSourceUser = true, bool inSourceChannel = true, TimeSpan? timeout = null, CancellationToken token = default) => Interactive.NextMessageAsync(Context, fromSourceUser, inSourceChannel, timeout, token); public Task ReplyAndDeleteAsync(string content, bool isTTS = false, Embed embed = null, TimeSpan? timeout = null, RequestOptions options = null) @@ -32,6 +34,7 @@ public Task PagedReplyAsync(IEnumerable pages, bool fromSo }; return PagedReplyAsync(pager, fromSourceUser); } + public Task PagedReplyAsync(PaginatedMessage pager, bool fromSourceUser = true) { var criterion = new Criteria(); @@ -39,6 +42,7 @@ public Task PagedReplyAsync(PaginatedMessage pager, bool fromSourc criterion.AddCriterion(new EnsureReactionFromSourceUserCriterion()); return PagedReplyAsync(pager, criterion); } + public Task PagedReplyAsync(PaginatedMessage pager, ICriterion criterion) => Interactive.SendPaginatedMessageAsync(Context, pager, criterion); diff --git a/Discord.Addons.Interactive/InteractiveService.cs b/Discord.Addons.Interactive/InteractiveService.cs index 6a9e421..5499a4a 100644 --- a/Discord.Addons.Interactive/InteractiveService.cs +++ b/Discord.Addons.Interactive/InteractiveService.cs @@ -7,19 +7,24 @@ namespace Discord.Addons.Interactive { - public class InteractiveService : IDisposable + public class InteractiveService + : IDisposable { public BaseSocketClient Discord { get; } - private Dictionary _callbacks; - private TimeSpan _defaultTimeout; + private readonly Dictionary _callbacks; + private readonly TimeSpan _defaultTimeout; // helpers to allow DI containers to resolve without a custom factory public InteractiveService(DiscordSocketClient discord, InteractiveServiceConfig config = null) - : this((BaseSocketClient)discord, config) {} - + : this((BaseSocketClient)discord, config) + { + } + public InteractiveService(DiscordShardedClient discord, InteractiveServiceConfig config = null) - : this((BaseSocketClient)discord, config) {} + : this((BaseSocketClient)discord, config) + { + } public InteractiveService(BaseSocketClient discord, InteractiveServiceConfig config = null) { @@ -32,24 +37,27 @@ public InteractiveService(BaseSocketClient discord, InteractiveServiceConfig con _callbacks = new Dictionary(); } - public Task NextMessageAsync(SocketCommandContext context, + public Task NextMessageAsync( + SocketCommandContext context, bool fromSourceUser = true, bool inSourceChannel = true, TimeSpan? timeout = null, - CancellationToken token = default(CancellationToken)) + CancellationToken token = default) { var criterion = new Criteria(); if (fromSourceUser) criterion.AddCriterion(new EnsureSourceUserCriterion()); if (inSourceChannel) criterion.AddCriterion(new EnsureSourceChannelCriterion()); + return NextMessageAsync(context, criterion, timeout, token); } - public async Task NextMessageAsync(SocketCommandContext context, + public async Task NextMessageAsync( + SocketCommandContext context, ICriterion criterion, TimeSpan? timeout = null, - CancellationToken token = default(CancellationToken)) + CancellationToken token = default) { timeout = timeout ?? _defaultTimeout; @@ -103,17 +111,17 @@ public async Task SendPaginatedMessageAsync(SocketCommandContext c return callback.Message; } - public void AddReactionCallback(IMessage message, IReactionCallback callback) - => _callbacks[message.Id] = callback; - public void RemoveReactionCallback(IMessage message) - => RemoveReactionCallback(message.Id); - public void RemoveReactionCallback(ulong id) - => _callbacks.Remove(id); - public void ClearReactionCallbacks() - => _callbacks.Clear(); + public void AddReactionCallback(IMessage message, IReactionCallback callback) => _callbacks[message.Id] = callback; + + public void RemoveReactionCallback(IMessage message) => RemoveReactionCallback(message.Id); + + public void RemoveReactionCallback(ulong id) => _callbacks.Remove(id); + + public void ClearReactionCallbacks() => _callbacks.Clear(); - private async Task HandleReactionAsync(Cacheable message, - ISocketMessageChannel channel, + private async Task HandleReactionAsync( + Cacheable message, + Cacheable cacheable, SocketReaction reaction) { if (reaction.UserId == Discord.CurrentUser.Id) return; diff --git a/Discord.Addons.Interactive/Paginator/EnsureReactionFromSourceUserCriterion.cs b/Discord.Addons.Interactive/Paginator/EnsureReactionFromSourceUserCriterion.cs index 9444d5e..af5fe14 100644 --- a/Discord.Addons.Interactive/Paginator/EnsureReactionFromSourceUserCriterion.cs +++ b/Discord.Addons.Interactive/Paginator/EnsureReactionFromSourceUserCriterion.cs @@ -4,12 +4,12 @@ namespace Discord.Addons.Interactive { - internal class EnsureReactionFromSourceUserCriterion : ICriterion + internal class EnsureReactionFromSourceUserCriterion + : ICriterion { public Task JudgeAsync(SocketCommandContext sourceContext, SocketReaction parameter) { - bool ok = parameter.UserId == sourceContext.User.Id; - return Task.FromResult(ok); + return Task.FromResult(parameter.UserId == sourceContext.User.Id); } } } diff --git a/SampleApp/SampleApp.csproj b/SampleApp/SampleApp.csproj index d3de106..25a000e 100644 --- a/SampleApp/SampleApp.csproj +++ b/SampleApp/SampleApp.csproj @@ -2,17 +2,23 @@ Exe - netcoreapp3.1 + net6.0 - - - + + + + + + PreserveNewest + + + \ No newline at end of file From 2631f2c5dbf9a5734b696bcc98ad0cc1cda1f81d Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Thu, 12 Mar 2026 00:07:50 +0000 Subject: [PATCH 3/3] Minor code cleanup --- .../Criteria/EmptyCriterion.cs | 6 +----- .../Criteria/EnsureFromChannelCriterion.cs | 7 +++++-- .../Criteria/EnsureFromUserCriterion.cs | 2 +- Discord.Addons.Interactive/Criteria/ICriterion.cs | 6 +----- .../Discord.Addons.Interactive.csproj | 10 ++++------ Discord.Addons.Interactive/InteractiveService.cs | 10 +++++++--- .../Paginator/EnsureIsIntegerCriterion.cs | 2 +- .../Paginator/PaginatedMessageCallback.cs | 15 +++++++-------- 8 files changed, 27 insertions(+), 31 deletions(-) diff --git a/Discord.Addons.Interactive/Criteria/EmptyCriterion.cs b/Discord.Addons.Interactive/Criteria/EmptyCriterion.cs index ed8cdfe..d13f9ce 100644 --- a/Discord.Addons.Interactive/Criteria/EmptyCriterion.cs +++ b/Discord.Addons.Interactive/Criteria/EmptyCriterion.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Discord.Commands; -using Discord.WebSocket; namespace Discord.Addons.Interactive { diff --git a/Discord.Addons.Interactive/Criteria/EnsureFromChannelCriterion.cs b/Discord.Addons.Interactive/Criteria/EnsureFromChannelCriterion.cs index 32d6941..dd20296 100644 --- a/Discord.Addons.Interactive/Criteria/EnsureFromChannelCriterion.cs +++ b/Discord.Addons.Interactive/Criteria/EnsureFromChannelCriterion.cs @@ -1,9 +1,12 @@ using System.Threading.Tasks; using Discord.Commands; +using JetBrains.Annotations; namespace Discord.Addons.Interactive { - public class EnsureFromChannelCriterion : ICriterion + [UsedImplicitly] + public class EnsureFromChannelCriterion + : ICriterion { private readonly ulong _channelId; @@ -12,7 +15,7 @@ public EnsureFromChannelCriterion(IMessageChannel channel) public Task JudgeAsync(SocketCommandContext sourceContext, IMessage parameter) { - bool ok = _channelId == parameter.Channel.Id; + var ok = _channelId == parameter.Channel.Id; return Task.FromResult(ok); } } diff --git a/Discord.Addons.Interactive/Criteria/EnsureFromUserCriterion.cs b/Discord.Addons.Interactive/Criteria/EnsureFromUserCriterion.cs index e2ecd38..54bb552 100644 --- a/Discord.Addons.Interactive/Criteria/EnsureFromUserCriterion.cs +++ b/Discord.Addons.Interactive/Criteria/EnsureFromUserCriterion.cs @@ -17,7 +17,7 @@ public EnsureFromUserCriterion(ulong id) public Task JudgeAsync(SocketCommandContext sourceContext, IMessage parameter) { - bool ok = _id == parameter.Author.Id; + var ok = _id == parameter.Author.Id; return Task.FromResult(ok); } } diff --git a/Discord.Addons.Interactive/Criteria/ICriterion.cs b/Discord.Addons.Interactive/Criteria/ICriterion.cs index 4927faf..27423a3 100644 --- a/Discord.Addons.Interactive/Criteria/ICriterion.cs +++ b/Discord.Addons.Interactive/Criteria/ICriterion.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Discord.WebSocket; -using System.Threading.Tasks; +using System.Threading.Tasks; using Discord.Commands; namespace Discord.Addons.Interactive diff --git a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj index fdc84b8..d93aa7f 100644 --- a/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj +++ b/Discord.Addons.Interactive/Discord.Addons.Interactive.csproj @@ -11,15 +11,13 @@ git://github.com/foxbot/Discord.Addons.Interactive https://github.com/foxbot/Discord.Addons.Interactive/raw/master/marketing/PackageLogo.png - $(Version) - 0.0.0-dev - - netstandard2.0 + net10.0 - - + + + \ No newline at end of file diff --git a/Discord.Addons.Interactive/InteractiveService.cs b/Discord.Addons.Interactive/InteractiveService.cs index 5499a4a..272de0d 100644 --- a/Discord.Addons.Interactive/InteractiveService.cs +++ b/Discord.Addons.Interactive/InteractiveService.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Discord.Commands; using Discord.WebSocket; +using JetBrains.Annotations; namespace Discord.Addons.Interactive { @@ -53,6 +54,7 @@ public Task NextMessageAsync( return NextMessageAsync(context, criterion, timeout, token); } + [ItemCanBeNull] public async Task NextMessageAsync( SocketCommandContext context, ICriterion criterion, @@ -77,15 +79,14 @@ async Task Handler(SocketMessage message) var trigger = eventTrigger.Task; var cancel = cancelTrigger.Task; - var delay = Task.Delay(timeout.Value); + var delay = Task.Delay(timeout.Value, token); var task = await Task.WhenAny(trigger, delay, cancel).ConfigureAwait(false); context.Client.MessageReceived -= Handler; if (task == trigger) return await trigger.ConfigureAwait(false); - else - return null; + return null; } public async Task ReplyAndDeleteAsync(SocketCommandContext context, @@ -137,6 +138,9 @@ private async Task HandleReactionAsync( RemoveReactionCallback(message.Id); }); break; + + case RunMode.Sync: + case RunMode.Default: default: if (await callback.HandleCallbackAsync(reaction).ConfigureAwait(false)) RemoveReactionCallback(message.Id); diff --git a/Discord.Addons.Interactive/Paginator/EnsureIsIntegerCriterion.cs b/Discord.Addons.Interactive/Paginator/EnsureIsIntegerCriterion.cs index ce62cb8..e596f83 100644 --- a/Discord.Addons.Interactive/Paginator/EnsureIsIntegerCriterion.cs +++ b/Discord.Addons.Interactive/Paginator/EnsureIsIntegerCriterion.cs @@ -8,7 +8,7 @@ internal class EnsureIsIntegerCriterion : ICriterion { public Task JudgeAsync(SocketCommandContext sourceContext, SocketMessage parameter) { - bool ok = int.TryParse(parameter.Content, out _); + var ok = int.TryParse(parameter.Content, out _); return Task.FromResult(ok); } } diff --git a/Discord.Addons.Interactive/Paginator/PaginatedMessageCallback.cs b/Discord.Addons.Interactive/Paginator/PaginatedMessageCallback.cs index e5e93d8..475d6da 100644 --- a/Discord.Addons.Interactive/Paginator/PaginatedMessageCallback.cs +++ b/Discord.Addons.Interactive/Paginator/PaginatedMessageCallback.cs @@ -14,10 +14,10 @@ public class PaginatedMessageCallback : IReactionCallback public IUserMessage Message { get; private set; } public RunMode RunMode => RunMode.Sync; - public ICriterion Criterion => _criterion; + public ICriterion Criterion { get; } + public TimeSpan? Timeout => options.Timeout; - private readonly ICriterion _criterion; private readonly PaginatedMessage _pager; private PaginatedAppearanceOptions options => _pager.Options; @@ -32,7 +32,7 @@ public PaginatedMessageCallback(InteractiveService interactive, { Interactive = interactive; Context = sourceContext; - _criterion = criterion ?? new EmptyCriterion(); + Criterion = criterion ?? new EmptyCriterion(); _pager = pager; pages = _pager.Pages.Count(); if (_pager.Pages is IEnumerable) @@ -53,9 +53,8 @@ public async Task DisplayAsync() await message.AddReactionAsync(options.Next); await message.AddReactionAsync(options.Last); - var manageMessages = (Context.Channel is IGuildChannel guildChannel) - ? (Context.User as IGuildUser).GetPermissions(guildChannel).ManageMessages - : false; + var manageMessages = Context.Channel is IGuildChannel guildChannel + && ((IGuildUser)Context.User).GetPermissions(guildChannel).ManageMessages; if (options.JumpDisplayOptions == JumpDisplayOptions.Always || (options.JumpDisplayOptions == JumpDisplayOptions.WithManageMessages && manageMessages)) @@ -67,12 +66,12 @@ public async Task DisplayAsync() await message.AddReactionAsync(options.Info); }); // TODO: (Next major version) timeouts need to be handled at the service-level! - if (Timeout.HasValue && Timeout.Value != null) + if (Timeout.HasValue) { _ = Task.Delay(Timeout.Value).ContinueWith(_ => { Interactive.RemoveReactionCallback(message); - _ = Message.DeleteAsync(); + Message.DeleteAsync(); }); } }