From 5225d75315fa30e6826cb0400b154c59c0f7238f Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Mon, 27 Mar 2023 10:56:13 +0200 Subject: [PATCH 1/7] Remove deprecated analyzer rule --- analysis_options.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index d6cb7dc..a9f0d67 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -9,5 +9,4 @@ analyzer: exclude: [build/**, "*.g.dart"] language: strict-raw-types: true - strong-mode: - implicit-casts: false + strict-casts: false From 176fe07d585e4ed364d9287b6ad2dd570d4cb8c4 Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Mon, 27 Mar 2023 11:12:52 +0200 Subject: [PATCH 2/7] Use named parameters in GuildCheck connstructor --- lib/src/checks/guild.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/checks/guild.dart b/lib/src/checks/guild.dart index 6a482ff..0727d38 100644 --- a/lib/src/checks/guild.dart +++ b/lib/src/checks/guild.dart @@ -29,7 +29,7 @@ class GuildCheck extends Check { /// You might also be interested in: /// - [GuildCheck.id], for creating this same check without an instance of [IGuild]; /// - [GuildCheck.any], for checking if the context originated in any of a set of guilds. - GuildCheck(IGuild guild, [String? name]) : this.id(guild.id, name: name); + GuildCheck(IGuild guild, {String? name}) : this.id(guild.id, name: name); /// Create a [GuildCheck] that succeeds if the ID of the guild the context originated in is [id]. GuildCheck.id(Snowflake id, {String? name}) From 61c59fafefaa377ff1cb7cb14fb7722e3c1e881a Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Mon, 27 Mar 2023 11:33:34 +0200 Subject: [PATCH 3/7] Release 5.0.0 --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25b23db..680234d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ +## 5.0.0 +__Breaking changes__ +- Removed all deprecated APIs. +- APIs which used to take `Type` objects now take `RuntimeType`s for the relevant type. +- APIs which used to take the `customId` of a component now take a `ComponentId`. +- Context types have been reorganized. See the docs for `IContextData`, `ICommandContext` and `IInteractiveContext` for more. +- Converter & check APIs now take `IContextData` objects instead of `IContext` objects. +- Checks now use named parameters instead of positional ones in their constructors. +- `IInteractiveContext.respond` (formerly `IContext.respond`) now takes a `ResponseLevel` object instead of `private` and `hidden`. +- The `interactions` field on `CommandsPlugin` is now nullable to avoid a `late` modifier. Use `IContextData.interactions` instead for a non nullable field. + +__New features__ +- Contexts are now managed by a `ContextManager` which allows users to create their own contexts. +- Added support for modal helpers. See `IInteractionInteractiveContext.getModal` for more. +- Added new errors: `ConverterFailedException`, `InteractionTimeoutException`, `UncaughtCommandsException` and `UnhandledInteractionException`. +- Events & listeners are now handled by an `EventManager` and `ComponentId`s. +- Prefix callbacks can now be asynchronous and return any `Pattern`. +- Added `autoAcknowledgeDuration` for more control over auto-acknowledge. +- Added parsing utilities on `AutocompleteContext` for parsing arguments. +- Contexts in a command are now chained, so interaction expiry and inconsistent formatting of responses to commands are no longer an issue. See `IInteractiveContext.delegate` for more. +- Added many helpers for handling message components: + - `awaitButtonPress`, `awaitSelection` and `awaitMultiSelection` for using fully custom components with nyxx_commands; + - `getButtonPress`, `getButtonSelection` and `getConfirmation` for handling buttons; + - `getSelection` and `getMultiSelection` for handling multiselect menus. +- Added `SimpleConverter` to simplify creating custom converters. +- The prefix callback can now be set to null to disable message commands. This will change the default command type to `slashOnly` unless `CommandsOptions.inferDefaultCommandType` is set to `false`. +- Added `skipPattern` to `StringView`, similar to `skipString`. + +__Bug fixes__ +- Fixed a bug that prevented `part` files from being compiled. +- Fixed a bug that prevented enum parameters from being compiled. +- Fixed nested command `fullName`s not being correct. + +__Miscellaneous__ +- Optimized the compilation script to generate less code and use a more reliable subtype checking method. +- Instructions for compilation can now be found at the package README. +- Bump `nyxx` to 5.0.0 and `nyxx_interactions` to 4.6.0. + ## 5.0.0-dev.3 __Bug fixes__ - Fixed a bug which caused `IInteractiveContext.respond` to error after auto-acknowledge. diff --git a/pubspec.yaml b/pubspec.yaml index b216d32..a0f15a0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: nyxx_commands -version: 5.0.0-dev.3 +version: 5.0.0 description: A framework for easily creating slash commands and text commands for Discord using the nyxx library. homepage: https://github.com/nyxx-discord/nyxx_commands/blob/main/README.md From a5faea5f56a0f9cf1c9dd1ef04351ff32c0d5d7f Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Mon, 3 Apr 2023 08:58:41 +0200 Subject: [PATCH 4/7] Fix component timeout being negative, value lookups using unparsed components and display selected options in disabled multiselect builder --- lib/src/context/component_context.dart | 10 +++++++ lib/src/util/mixins.dart | 37 +++++++++++++++++++++++--- lib/src/util/util.dart | 2 +- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/lib/src/context/component_context.dart b/lib/src/context/component_context.dart index f6b5190..c93202e 100644 --- a/lib/src/context/component_context.dart +++ b/lib/src/context/component_context.dart @@ -1,3 +1,4 @@ +import 'package:nyxx_commands/src/util/util.dart'; import 'package:nyxx_interactions/nyxx_interactions.dart'; import '../util/mixins.dart'; @@ -16,6 +17,9 @@ abstract class IComponentContextData implements IInteractionContextData { /// The ID of the component that was interacted with. String get componentId; + + /// If [componentId] is a valid [ComponentId], this is the parsed version of that. + ComponentId? get parsedComponentId; } /// A context in which a component was interacted with. @@ -43,6 +47,9 @@ class ButtonComponentContext extends ContextBase @override String get componentId => interaction.customId; + @override + ComponentId? get parsedComponentId => ComponentId.parse(componentId); + /// Create a new [ButtonComponentContext]. ButtonComponentContext({ required super.user, @@ -78,6 +85,9 @@ class MultiselectComponentContext extends ContextBase /// Will be a [List] if multiple items were selected. final T selected; + @override + ComponentId? get parsedComponentId => ComponentId.parse(componentId); + /// Create a new [MultiselectComponentContext]. MultiselectComponentContext({ required super.user, diff --git a/lib/src/util/mixins.dart b/lib/src/util/mixins.dart index ee1b9a3..1256d81 100644 --- a/lib/src/util/mixins.dart +++ b/lib/src/util/mixins.dart @@ -360,7 +360,7 @@ mixin InteractiveMixin implements IInteractiveContext, IContextData { context._parent = this; _delegate = context; - return idToValue[context.componentId]!; + return idToValue[context.parsedComponentId]!; } on TimeoutException catch (e, s) { throw InteractionTimeoutException( 'Timed out waiting for button selection', @@ -516,10 +516,26 @@ mixin InteractiveMixin implements IInteractiveContext, IContextData { context._parent = this; _delegate = context; - return idToValue[context.selected.single]!; + final result = idToValue[context.selected.single] as T; + + final matchingOptionIndex = menu.options.indexWhere( + (option) => option.value == context!.selected.single, + ); + + if (matchingOptionIndex >= 0) { + final builder = await toMultiSelect(result); + + menu.options[matchingOptionIndex] = MultiselectOptionBuilder( + builder.label, + builder.value, + true, + ); + } + + return result; } on TimeoutException catch (e, s) { throw InteractionTimeoutException( - 'TImed out waiting for selection', + 'Timed out waiting for selection', _nearestCommandContext, )..stackTrace = s; } finally { @@ -578,7 +594,8 @@ mixin InteractiveMixin implements IInteractiveContext, IContextData { allowedUser: authorOnly ? user.id : null, ); - MultiselectBuilder menu = MultiselectBuilder(menuId.toString(), options); + MultiselectBuilder menu = MultiselectBuilder(menuId.toString(), options) + ..maxValues = choices.length; ComponentRowBuilder row = ComponentRowBuilder()..addComponent(menu); (builder as ComponentMessageBuilder).addComponentRow(row); @@ -592,6 +609,18 @@ mixin InteractiveMixin implements IInteractiveContext, IContextData { context._parent = this; _delegate = context; + for (final value in context.selected) { + final matchingOptionIndex = menu.options.indexWhere((option) => option.value == value); + + if (matchingOptionIndex >= 0) { + menu.options[matchingOptionIndex] = MultiselectOptionBuilder( + menu.options[matchingOptionIndex].label, + value, + true, + ); + } + } + return context.selected.map((id) => idToValue[id]!).toList(); } on TimeoutException catch (e, s) { throw InteractionTimeoutException( diff --git a/lib/src/util/util.dart b/lib/src/util/util.dart index 024d7fe..8728872 100644 --- a/lib/src/util/util.dart +++ b/lib/src/util/util.dart @@ -391,7 +391,7 @@ class ComponentId { final Snowflake? allowedUser; /// The time remaining until the handler for this [ComponentId] expires, if [expiresAt] was set. - Duration? get expiresIn => expiresAt != null ? DateTime.now().difference(expiresAt!) : null; + Duration? get expiresIn => expiresAt?.difference(DateTime.now()); /// The status of this [ComponentId]. /// From 79007beaad5b0b6d1e0c787f1682e483dc2e0695 Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Mon, 3 Apr 2023 09:02:42 +0200 Subject: [PATCH 5/7] Release 5.0.1 --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 680234d..83c08e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 5.0.1 +__Bug fixes__ +- Fix component timeouts triggering instantly +- Fix component wrappers causing null assertions to trigger + ## 5.0.0 __Breaking changes__ - Removed all deprecated APIs. diff --git a/pubspec.yaml b/pubspec.yaml index a0f15a0..9f9dbbc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: nyxx_commands -version: 5.0.0 +version: 5.0.1 description: A framework for easily creating slash commands and text commands for Discord using the nyxx library. homepage: https://github.com/nyxx-discord/nyxx_commands/blob/main/README.md From 7a7faeb71ba16310c0f8ef18d820d177b49b27f4 Mon Sep 17 00:00:00 2001 From: Abitofevrything Date: Sun, 9 Apr 2023 20:13:17 +0200 Subject: [PATCH 6/7] Don't throw if plugin is disposed partway through command execution. --- lib/src/commands.dart | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/src/commands.dart b/lib/src/commands.dart index c906757..00b037c 100644 --- a/lib/src/commands.dart +++ b/lib/src/commands.dart @@ -220,8 +220,19 @@ class CommandsPlugin extends BasePlugin implements ICommandGroup>[]; + @override Future onBotStop(INyxx nyxx, Logger logger) async { + await Future.wait(_subscriptionsToCancel.map((subscription) => subscription.cancel())); + await _onPostCallController.close(); await _onPreCallController.close(); await _onCommandErrorController.close(); @@ -241,7 +252,13 @@ class CommandsPlugin extends BasePlugin implements ICommandGroup Function(T) _handleErrorsFrom(Future Function(T) fn) { @@ -527,8 +544,8 @@ class CommandsPlugin extends BasePlugin implements ICommandGroup Date: Sun, 9 Apr 2023 20:14:24 +0200 Subject: [PATCH 7/7] Release 5.0.2 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c08e3..aa9835f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.2 +__Bug fixes__ +- Fix disposing the plugin partway through command execution causing errors + ## 5.0.1 __Bug fixes__ - Fix component timeouts triggering instantly diff --git a/pubspec.yaml b/pubspec.yaml index 9f9dbbc..74f2be1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: nyxx_commands -version: 5.0.1 +version: 5.0.2 description: A framework for easily creating slash commands and text commands for Discord using the nyxx library. homepage: https://github.com/nyxx-discord/nyxx_commands/blob/main/README.md