🚀 Overhaul to files, made easier to use! Missing documentation for all public APIS.
This commit is contained in:
parent
1d6f937f96
commit
23dfa06ac0
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -32,4 +32,5 @@ pubspec.lock
|
|||
private-*.dart
|
||||
test-*.dart
|
||||
[Rr]pc*
|
||||
**/doc/api/**
|
||||
**/doc/api/**
|
||||
old.*
|
|
@ -1,26 +1,28 @@
|
|||
library nyxx_interactions;
|
||||
|
||||
import 'dart:async';
|
||||
import "dart:async";
|
||||
|
||||
import "package:logging/logging.dart";
|
||||
import "package:nyxx/nyxx.dart";
|
||||
|
||||
// Root
|
||||
part "src/Interactions.dart";
|
||||
// Events
|
||||
part "src/events/InteractionEvent.dart";
|
||||
// Internal
|
||||
part "src/internal/_EventController.dart";
|
||||
|
||||
// Models
|
||||
part "src/models/CommandInteractionData.dart";
|
||||
part "src/models/CommandInteractionOption.dart";
|
||||
part "src/models/Interaction.dart";
|
||||
part "src/models/InteractionResponse/IInteractionResponse.dart";
|
||||
part "src/models/SlashArg.dart";
|
||||
part "src/models/SlashCommand.dart";
|
||||
part "src/models/SlashArgChoice.dart";
|
||||
part 'src/Models/SlashCommand.dart';
|
||||
part "src/Models/Interaction.dart";
|
||||
part "src/Models/InteractionOption.dart";
|
||||
|
||||
// Command Args
|
||||
part 'src/Models/CommandArgs/ArgChoice.dart';
|
||||
part 'src/Models/CommandArgs/CommandArg.dart';
|
||||
|
||||
// Internal
|
||||
part 'src/Internal/_EventController.dart';
|
||||
|
||||
// Events
|
||||
part "src/Events/InteractionEvent.dart";
|
||||
|
||||
// Exceptions
|
||||
part "src/models/exceptions/AlreadyResponded.dart";
|
||||
part "src/models/exceptions/InteractionExpired.dart";
|
||||
part "src/models/exceptions/SlashArgMisconfiguration.dart";
|
||||
part "src/models/exceptions/ArgLength.dart";
|
||||
part "src/Exceptions/InteractionExpired.dart";
|
||||
part "src/Exceptions/AlreadyResponded.dart";
|
|
@ -9,44 +9,44 @@ class InteractionEvent {
|
|||
InteractionEvent._new(Nyxx client, Map<String, dynamic> rawJson) {
|
||||
this._client = client;
|
||||
interaction = Interaction._new(client, rawJson);
|
||||
|
||||
if(interaction.type == 1) {
|
||||
this._pong();
|
||||
}
|
||||
}
|
||||
|
||||
/// Should be sent when you receive a ping from interactions. Used to acknowledge a ping.
|
||||
Future Pong() {
|
||||
Future _pong() {
|
||||
if (DateTime.now()
|
||||
.isBefore(this.recievedAt.add(const Duration(minutes: 15)))) {
|
||||
String url;
|
||||
if (hasResponded) {
|
||||
url =
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}";
|
||||
} else {
|
||||
url =
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
|
||||
}
|
||||
final response = this._client.httpEndpoints.sendRawRequest(
|
||||
url,
|
||||
"POST",
|
||||
body: {
|
||||
"type": 1,
|
||||
"data": null,
|
||||
},
|
||||
);
|
||||
|
||||
if (response is HttpResponseError) {
|
||||
return Future.error(response);
|
||||
}
|
||||
|
||||
if (!hasResponded) {
|
||||
hasResponded = true;
|
||||
final response = this._client.httpEndpoints.sendRawRequest(
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback",
|
||||
"POST",
|
||||
body: {
|
||||
"type": 1,
|
||||
"data": null,
|
||||
},
|
||||
);
|
||||
|
||||
if (response is HttpResponseError) {
|
||||
return Future.error(response);
|
||||
}
|
||||
|
||||
if (!hasResponded) {
|
||||
hasResponded = true;
|
||||
}
|
||||
return Future.value(null);
|
||||
} else {
|
||||
return Future.error(InteractionExpired());
|
||||
}
|
||||
return Future.value(null);
|
||||
} else {
|
||||
return Future.error(InteractionExpired());
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to acknowledge a Interaction but not send any response yet. Once this is sent you can then only send ChannelMessages with or without source.
|
||||
Future Acknowledge({
|
||||
Future acknowledge({
|
||||
bool showSource = false,
|
||||
}) {
|
||||
if (DateTime.now()
|
||||
|
@ -80,32 +80,31 @@ class InteractionEvent {
|
|||
}
|
||||
}
|
||||
|
||||
Future Reply({
|
||||
Future reply({
|
||||
dynamic content,
|
||||
EmbedBuilder? embed,
|
||||
bool? tts,
|
||||
AllowedMentions? allowedMentions,
|
||||
bool showSource = false,
|
||||
}) {
|
||||
}) async {
|
||||
if (DateTime.now()
|
||||
.isBefore(this.recievedAt.add(const Duration(minutes: 15)))) {
|
||||
String url;
|
||||
if (hasResponded) {
|
||||
url =
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}";
|
||||
"/webhooks/${this.interaction.id.toString()}/${this.interaction.token}";
|
||||
} else {
|
||||
url =
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
|
||||
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
|
||||
}
|
||||
final response = this._client.httpEndpoints.sendRawRequest(
|
||||
final response = await this._client.httpEndpoints.sendRawRequest(
|
||||
url,
|
||||
"POST",
|
||||
body: {
|
||||
"type": showSource ? 4 : 3,
|
||||
"data": {
|
||||
"content": content,
|
||||
"embeds":
|
||||
embed != null ? BuilderUtility.buildRawEmbed(embed) : null,
|
||||
"embeds": embed != null ? [ BuilderUtility.buildRawEmbed(embed) ] : null,
|
||||
"allowed_mentions": allowedMentions != null
|
||||
? BuilderUtility.buildRawAllowedMentions(allowedMentions)
|
||||
: null,
|
||||
|
@ -118,6 +117,8 @@ class InteractionEvent {
|
|||
return Future.error(response);
|
||||
}
|
||||
|
||||
print((response as HttpResponseSuccess).body);
|
||||
|
||||
if (!hasResponded) {
|
||||
hasResponded = true;
|
||||
}
|
|
@ -9,4 +9,4 @@ class AlreadyResponded implements Error {
|
|||
|
||||
@override
|
||||
StackTrace? get stackTrace => StackTrace.empty;
|
||||
}
|
||||
}
|
|
@ -9,4 +9,4 @@ class InteractionExpired implements Error {
|
|||
|
||||
@override
|
||||
StackTrace? get stackTrace => StackTrace.empty;
|
||||
}
|
||||
}
|
|
@ -4,19 +4,25 @@ part of nyxx_interactions;
|
|||
class Interactions {
|
||||
late final Nyxx _client;
|
||||
final Logger _logger = Logger("Interactions");
|
||||
final List<SlashCommand> _commands = List.empty(growable: true);
|
||||
late final _EventController _events;
|
||||
|
||||
/// Emitted when a a slash command is sent.
|
||||
late Stream<InteractionEvent> onSlashCommand;
|
||||
|
||||
/// Emitted when a a slash command is sent.
|
||||
late Stream<SlashCommand> onSlashCommandCreated;
|
||||
|
||||
///
|
||||
Interactions(Nyxx client) {
|
||||
client.options.dispatchRawShardEvent = true;
|
||||
this._client = client;
|
||||
_events = _EventController(this);
|
||||
_client.options.dispatchRawShardEvent = true;
|
||||
_logger.info("Interactions ready");
|
||||
|
||||
client.onReady.listen((event) {
|
||||
client.shardManager.rawEvent.listen((event) {
|
||||
print(event);
|
||||
print(event.rawData);
|
||||
if (event.rawData["op"] as int == 0) {
|
||||
if (event.rawData["t"] as String == "INTERACTION_CREATE") {
|
||||
_events.onSlashCommand.add(
|
||||
|
@ -26,42 +32,58 @@ class Interactions {
|
|||
}
|
||||
}
|
||||
});
|
||||
_logger.info("Interactions ready");
|
||||
});
|
||||
}
|
||||
|
||||
Future<SlashCommand> registerSlashGlobal(
|
||||
String name, String description, List<SlashArg> args) async {
|
||||
final command =
|
||||
SlashCommand._new(this._client, name, args, description, null);
|
||||
final response = await this._client.httpEndpoints.sendRawRequest(
|
||||
"/applications/${this._client.app.id.toString()}/commands",
|
||||
"POST",
|
||||
body: command._build(),
|
||||
);
|
||||
SlashCommand createCommand(String name, String description, List<CommandArg> args, {String? guild})
|
||||
=> SlashCommand._new(_client, name, description, args, guild: guild != null ? CacheUtility.createCacheableGuild(_client, Snowflake(guild)) : null);
|
||||
|
||||
if (response is HttpResponseError) {
|
||||
return Future.error(response);
|
||||
}
|
||||
|
||||
return Future.value(command);
|
||||
/// Registers a single command.
|
||||
///
|
||||
/// @param command A [SlashCommand] to register.
|
||||
void registerCommand(SlashCommand command) {
|
||||
_commands.add(command);
|
||||
}
|
||||
|
||||
Future<SlashCommand> registerSlashGuild(String name, String description,
|
||||
Snowflake guildId, List<SlashArg> args) async {
|
||||
final command =
|
||||
SlashCommand._new(this._client, name, args, description, guildId);
|
||||
command._build();
|
||||
final response = await this._client.httpEndpoints.sendRawRequest(
|
||||
"/applications/${this._client.app.id.toString()}/guilds/${guildId.toString()}/commands",
|
||||
"POST",
|
||||
body: command._build(),
|
||||
);
|
||||
|
||||
if (response is HttpResponseError) {
|
||||
return Future.error(response);
|
||||
/// Registers multiple commands at one.
|
||||
///
|
||||
/// This wraps around [Interactions.registerCommand()] running [Interactions.registerCommand] for each command in the list.
|
||||
/// @param commands A list of [SlashCommand]s to register.
|
||||
void registerCommands(List<SlashCommand> commands) {
|
||||
for(var i = 0; i < commands.length; i++) {
|
||||
this.registerCommand(commands[i]);
|
||||
}
|
||||
|
||||
return Future.value(command);
|
||||
}
|
||||
|
||||
List<SlashCommand> getCommands({bool registeredOnly = false}) {
|
||||
if(!registeredOnly) { return _commands; }
|
||||
final registeredCommands = List<SlashCommand>.empty(growable: true);
|
||||
for(var i = 0; i < _commands.length; i++) {
|
||||
final el = _commands[i];
|
||||
if(el.isRegistered) {
|
||||
registeredCommands.add(el);
|
||||
}
|
||||
}
|
||||
return registeredCommands;
|
||||
}
|
||||
|
||||
Future<void> sync() async {
|
||||
var success = 0;
|
||||
var failed = 0;
|
||||
for(var i = 0; i < _commands.length; i++) {
|
||||
final el = _commands[i];
|
||||
if(!el.isRegistered) {
|
||||
final command = await el._register();
|
||||
if(command != null) {
|
||||
_commands[i] = command;
|
||||
this._events.onSlashCommandCreated.add(_commands[i]);
|
||||
success++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
_logger.info("Successfully registered $success ${success > 1 ? "commands" : "command"}. Failed registering $failed ${failed > 1 ? "commands" : "command"}.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,13 +4,20 @@ class _EventController implements Disposable {
|
|||
/// Emitted when a a slash command is sent.
|
||||
late final StreamController<InteractionEvent> onSlashCommand;
|
||||
|
||||
/// Emitted when a a slash command is sent.
|
||||
late final StreamController<SlashCommand> onSlashCommandCreated;
|
||||
|
||||
_EventController(Interactions _client) {
|
||||
this.onSlashCommand = StreamController.broadcast();
|
||||
_client.onSlashCommand = this.onSlashCommand.stream;
|
||||
|
||||
this.onSlashCommandCreated = StreamController.broadcast();
|
||||
_client.onSlashCommandCreated = this.onSlashCommandCreated.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
await this.onSlashCommand.close();
|
||||
await this.onSlashCommandCreated.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +1,31 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
class SlashArgChoice {
|
||||
|
||||
/// This options name.
|
||||
late final String name;
|
||||
|
||||
/// This options int value. If there is an int value there can't be a [SlashArgChoice.stringValue]
|
||||
late final int? intValue;
|
||||
|
||||
/// This options string value. If there is an string value there can't be a [SlashArgChoice.intValue]
|
||||
late final String? stringValue;
|
||||
|
||||
/// A Choice for the user to input in int & string args. You can only have an int or string option.
|
||||
SlashArgChoice(this.name, {this.intValue, this.stringValue}) {
|
||||
if(this.intValue != null && this.stringValue != null) {
|
||||
throw SlashArgMisconfiguration._new("stringValue & intValue");
|
||||
}
|
||||
if(this.intValue == null && this.stringValue == null) {
|
||||
throw "MissingArgError: All SlashArgChoice need an int or string value";
|
||||
}
|
||||
if(this.name.length > 100) {
|
||||
throw ArgLength._new("SlashArgChoice.name", "1", "100");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _build() => {
|
||||
"name": this.name,
|
||||
"value": this.stringValue ?? this.intValue
|
||||
};
|
||||
}
|
||||
part of nyxx_interactions;
|
||||
|
||||
class ArgChoice {
|
||||
|
||||
/// This options name.
|
||||
late final String name;
|
||||
|
||||
/// This options int value. If there is an int value there can't be a [SlashArgChoice.stringValue]
|
||||
late final int? intValue;
|
||||
|
||||
/// This options string value. If there is an string value there can't be a [SlashArgChoice.intValue]
|
||||
late final String? stringValue;
|
||||
|
||||
/// A Choice for the user to input in int & string args. You can only have an int or string option.
|
||||
ArgChoice(this.name, dynamic value) {
|
||||
if(value is String) {
|
||||
this.stringValue = value;
|
||||
}
|
||||
if(value is int) {
|
||||
this.intValue = value;
|
||||
}
|
||||
if(value is! int && value is! String) {
|
||||
throw 'InvalidParamTypeError: Please send a string if its a string arg or an int if its an int arg.';
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _build() => {
|
||||
"name": this.name,
|
||||
"value": this.stringValue ?? this.intValue
|
||||
};
|
||||
}
|
|
@ -1,99 +1,75 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
/// The type that a user should input for a [SlashArg]
|
||||
enum SlashArgType {
|
||||
SUB_COMMAND,
|
||||
SUB_COMMAND_GROUP,
|
||||
STRING,
|
||||
INTEGER,
|
||||
BOOLEAN,
|
||||
USER,
|
||||
CHANNEL,
|
||||
ROLE,
|
||||
}
|
||||
|
||||
/// An argument for a [SlashCommand].
|
||||
class SlashArg {
|
||||
/// The type of arg that will be later changed to an INT value, their values can be seen in the table below:
|
||||
/// | Name | Value |
|
||||
/// |-------------------|-------|
|
||||
/// | SUB_COMMAND | 1 |
|
||||
/// | SUB_COMMAND_GROUP | 2 |
|
||||
/// | STRING | 3 |
|
||||
/// | INTEGER | 4 |
|
||||
/// | BOOLEAN | 5 |
|
||||
/// | USER | 6 |
|
||||
/// | CHANNEL | 7 |
|
||||
/// | ROLE | 8 |
|
||||
late final SlashArgType type;
|
||||
|
||||
/// The name of your argument / sub-group.
|
||||
late final String name;
|
||||
|
||||
/// The description of your argument / sub-group.
|
||||
late final String description;
|
||||
|
||||
/// If this should be the fist required option the user picks
|
||||
late final bool defaultArg;
|
||||
|
||||
/// If this argument is required
|
||||
late final bool required;
|
||||
|
||||
/// Choices for [SlashArgType.STRING] and [SlashArgType.INTEGER] types for the user to pick from
|
||||
late final List<SlashArgChoice>? choices;
|
||||
|
||||
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters
|
||||
late final List<SlashArg>? options;
|
||||
|
||||
/// Used to create an argument for a [SlashCommand]. Thease are used in [Interactions.registerSlashGlobal] and [Interactions.registerSlashGuild]
|
||||
SlashArg(this.type, this.name, this.description,
|
||||
{this.defaultArg = false,
|
||||
this.required = false,
|
||||
this.choices,
|
||||
this.options}) {
|
||||
if (this.options != null &&
|
||||
(this.type != SlashArgType.SUB_COMMAND ||
|
||||
this.type != SlashArgType.SUB_COMMAND_GROUP)) {
|
||||
throw SlashArgMisconfiguration._new("Options & Type");
|
||||
}
|
||||
|
||||
if (this.choices != null &&
|
||||
(this.type != SlashArgType.STRING ||
|
||||
this.type != SlashArgType.INTEGER)) {
|
||||
throw SlashArgMisconfiguration._new("Choices & Type");
|
||||
}
|
||||
|
||||
if (!this.required && this.defaultArg) {
|
||||
throw SlashArgMisconfiguration._new("Required & Default Arg");
|
||||
}
|
||||
|
||||
if (this.name.length > 32) {
|
||||
throw ArgLength._new("SlashArg.name", "1", "32");
|
||||
}
|
||||
|
||||
if (this.description.length > 100) {
|
||||
throw ArgLength._new("SlashArg.description", "1", "100");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _build() {
|
||||
final subOptions = this.options != null
|
||||
? List<Map<String, dynamic>>.generate(
|
||||
this.options!.length, (i) => this.options![i]._build())
|
||||
: null;
|
||||
|
||||
final rawChoices = this.choices != null
|
||||
? List<Map<String, dynamic>>.generate(
|
||||
this.choices!.length, (i) => this.choices![i]._build())
|
||||
: null;
|
||||
return {
|
||||
"type": (this.type.index) + 1,
|
||||
"name": this.name,
|
||||
"description": this.description,
|
||||
"default": this.defaultArg,
|
||||
"required": this.required,
|
||||
"choices": rawChoices,
|
||||
"options": subOptions
|
||||
};
|
||||
}
|
||||
}
|
||||
part of nyxx_interactions;
|
||||
|
||||
/// The type that a user should input for a [SlashArg]
|
||||
enum CommandArgType {
|
||||
SUB_COMMAND,
|
||||
SUB_COMMAND_GROUP,
|
||||
STRING,
|
||||
INTEGER,
|
||||
BOOLEAN,
|
||||
USER,
|
||||
CHANNEL,
|
||||
ROLE,
|
||||
}
|
||||
|
||||
/// An argument for a [SlashCommand].
|
||||
class CommandArg {
|
||||
/// The type of arg that will be later changed to an INT value, their values can be seen in the table below:
|
||||
/// | Name | Value |
|
||||
/// |-------------------|-------|
|
||||
/// | SUB_COMMAND | 1 |
|
||||
/// | SUB_COMMAND_GROUP | 2 |
|
||||
/// | STRING | 3 |
|
||||
/// | INTEGER | 4 |
|
||||
/// | BOOLEAN | 5 |
|
||||
/// | USER | 6 |
|
||||
/// | CHANNEL | 7 |
|
||||
/// | ROLE | 8 |
|
||||
late final CommandArgType type;
|
||||
|
||||
/// The name of your argument / sub-group.
|
||||
late final String name;
|
||||
|
||||
/// The description of your argument / sub-group.
|
||||
late final String description;
|
||||
|
||||
/// If this should be the fist required option the user picks
|
||||
late final bool defaultArg;
|
||||
|
||||
/// If this argument is required
|
||||
late final bool required;
|
||||
|
||||
/// Choices for [SlashArgType.STRING] and [SlashArgType.INTEGER] types for the user to pick from
|
||||
late final List<ArgChoice>? choices;
|
||||
|
||||
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters
|
||||
late final List<CommandArg>? options;
|
||||
|
||||
/// Used to create an argument for a [SlashCommand]. Thease are used in [Interactions.registerSlashGlobal] and [Interactions.registerSlashGuild]
|
||||
CommandArg(this.type, this.name, this.description,
|
||||
{this.defaultArg = false,
|
||||
this.required = false,
|
||||
this.choices,
|
||||
this.options});
|
||||
|
||||
Map<String, dynamic> _build() {
|
||||
final subOptions = this.options != null
|
||||
? List<Map<String, dynamic>>.generate(
|
||||
this.options!.length, (i) => this.options![i]._build())
|
||||
: null;
|
||||
|
||||
final rawChoices = this.choices != null
|
||||
? List<Map<String, dynamic>>.generate(
|
||||
this.choices!.length, (i) => this.choices![i]._build())
|
||||
: null;
|
||||
return {
|
||||
"type": (this.type.index) + 1,
|
||||
"name": this.name,
|
||||
"description": this.description,
|
||||
"default": this.defaultArg,
|
||||
"required": this.required,
|
||||
"choices": rawChoices,
|
||||
"options": subOptions
|
||||
};
|
||||
}
|
||||
}
|
|
@ -6,8 +6,6 @@ class Interaction extends SnowflakeEntity implements Disposable {
|
|||
|
||||
late final int type;
|
||||
|
||||
late final CommandInteractionData? data;
|
||||
|
||||
late final Cacheable<Snowflake, Guild> guild;
|
||||
|
||||
late final Cacheable<Snowflake, TextChannel> channel;
|
||||
|
@ -18,26 +16,16 @@ class Interaction extends SnowflakeEntity implements Disposable {
|
|||
|
||||
late final int version;
|
||||
|
||||
CommandInteractionData? _generateData(Map<String, dynamic> raw) {
|
||||
return raw["data"] != null
|
||||
? CommandInteractionData._new(
|
||||
Snowflake(raw["data"]["id"]),
|
||||
raw["data"]["name"] as String,
|
||||
null, //TODO Add Tree Implimentation to show options
|
||||
)
|
||||
: null;
|
||||
}
|
||||
late final String name; // TODO
|
||||
|
||||
late final Map<String, InteractionOption> args; // TODO
|
||||
|
||||
Interaction._new(
|
||||
this.client,
|
||||
Map<String, dynamic> raw,
|
||||
) : super(Snowflake(raw["id"])) {
|
||||
this.client,
|
||||
Map<String, dynamic> raw,
|
||||
) : super(Snowflake(raw["id"])) {
|
||||
this.type = raw["type"] as int;
|
||||
|
||||
this.data = _generateData(
|
||||
raw,
|
||||
);
|
||||
|
||||
this.guild = CacheUtility.createCacheableGuild(
|
||||
client,
|
||||
Snowflake(
|
||||
|
@ -63,8 +51,29 @@ class Interaction extends SnowflakeEntity implements Disposable {
|
|||
this.token = raw["token"] as String;
|
||||
|
||||
this.version = raw["version"] as int;
|
||||
|
||||
this.name = raw["data"]["name"] as String;
|
||||
|
||||
this.args = _generateArgs(raw["data"] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Map<String, InteractionOption> _generateArgs(Map<String, dynamic> rawData) {
|
||||
final args = <String, InteractionOption>{};
|
||||
|
||||
if(rawData["options"] != null) {
|
||||
final l = rawData["options"] as List;
|
||||
for(var i = 0; i < l.length; i++) {
|
||||
final el = l[i];
|
||||
args[el["name"] as String] = InteractionOption._new(
|
||||
el["value"] as dynamic,
|
||||
(el["options"] ?? List<dynamic>.empty() ) as List,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() => Future.value(null);
|
||||
}
|
||||
}
|
15
nyxx.interactions/lib/src/Models/InteractionOption.dart
Normal file
15
nyxx.interactions/lib/src/Models/InteractionOption.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
class InteractionOption {
|
||||
final dynamic? value;
|
||||
final Map<String, InteractionOption> args = <String, InteractionOption>{};
|
||||
InteractionOption._new(this.value, List rawOptions) {
|
||||
for(var i = 0; i < rawOptions.length; i++) {
|
||||
final el = rawOptions[i];
|
||||
this.args[el["name"] as String] = InteractionOption._new(
|
||||
el["value"] as dynamic,
|
||||
(el["options"] ?? List<dynamic>.empty() ) as List,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
39
nyxx.interactions/lib/src/Models/SlashCommand.dart
Normal file
39
nyxx.interactions/lib/src/Models/SlashCommand.dart
Normal file
|
@ -0,0 +1,39 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
class SlashCommand {
|
||||
|
||||
late final String name;
|
||||
late final String description;
|
||||
late final Cacheable<Snowflake, Guild>? guild;
|
||||
late final List<CommandArg> args;
|
||||
late final bool isGlobal;
|
||||
late bool isRegistered = false;
|
||||
|
||||
late final Nyxx _client;
|
||||
|
||||
SlashCommand._new(this._client, this.name, this.description, this.args, {this.guild}) {
|
||||
this.isGlobal = guild == null;
|
||||
}
|
||||
|
||||
Future<SlashCommand> _register() async {
|
||||
final options = List<Map<String, dynamic>>.generate(
|
||||
this.args.length, (i) => this.args[i]._build());
|
||||
|
||||
final response = await this._client.httpEndpoints.sendRawRequest(
|
||||
"/applications/${this._client.app.id.toString()}/commands",
|
||||
"POST",
|
||||
body: {
|
||||
"name": this.name,
|
||||
"description": this.description,
|
||||
"options": options.isNotEmpty ? options : null
|
||||
},
|
||||
);
|
||||
|
||||
if (response is HttpResponseError) {
|
||||
return Future.error(response);
|
||||
}
|
||||
this.isRegistered = true;
|
||||
return Future.value(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
class CommandInteractionData {
|
||||
final Snowflake id;
|
||||
|
||||
final String name;
|
||||
|
||||
final List<CommandInteractionOption>? options;
|
||||
|
||||
CommandInteractionData._new(this.id, this.name, this.options);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
class CommandInteractionOption {
|
||||
final String name;
|
||||
final int? value;
|
||||
final List<CommandInteractionOption>? options;
|
||||
CommandInteractionOption._new(this.name, this.value, this.options);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
abstract class IInteractionResponse implements Disposable {}
|
|
@ -1,38 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
/// This class contains data about a slash command and is returned after registering one.
|
||||
class SlashCommand {
|
||||
/// The name of your command.
|
||||
late final String name;
|
||||
|
||||
/// The description of your command.
|
||||
late final String description;
|
||||
|
||||
/// The args registered for a command
|
||||
late final List<SlashArg> args;
|
||||
|
||||
/// If you command is registered globally
|
||||
late final bool isGlobal;
|
||||
|
||||
/// When you command is only for one guild the [SlashCommand.guild] will contain a [Cacheable] for
|
||||
late final Cacheable<Snowflake, Guild>? guild;
|
||||
|
||||
SlashCommand._new(
|
||||
Nyxx client, this.name, this.args, this.description, Snowflake? guildId) {
|
||||
this.isGlobal = guildId == null;
|
||||
this.guild = guildId != null
|
||||
? CacheUtility.createCacheableGuild(client, Snowflake(guildId))
|
||||
: null;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _build() {
|
||||
final options = List<Map<String, dynamic>>.generate(
|
||||
this.args.length, (i) => this.args[i]._build());
|
||||
|
||||
return {
|
||||
"name": this.name,
|
||||
"description": this.description,
|
||||
"options": options.isNotEmpty ? options : null
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
/// Thrown when your slash are is configured in a way that is not possible
|
||||
class ArgLength implements Error {
|
||||
/// The max length for the incorrect length variable/param.
|
||||
late final String maxLength;
|
||||
|
||||
/// The min length for the incorrect length variable/param.
|
||||
late final String minLength;
|
||||
|
||||
/// The name of the incorrect length variable/param.
|
||||
late final String name;
|
||||
|
||||
ArgLength._new(this.name, this.minLength, this.maxLength);
|
||||
|
||||
/// Returns a string representation of this object.
|
||||
@override
|
||||
String toString() =>
|
||||
"ArgLengthError: $name isn't the correct length. It must be larger than $minLength and smaller than $maxLength ($minLength-$maxLength)";
|
||||
|
||||
@override
|
||||
StackTrace? get stackTrace => StackTrace.empty;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
part of nyxx_interactions;
|
||||
|
||||
/// Thrown when your slash are is configured in a way that is not possible
|
||||
class SlashArgMisconfiguration implements Error {
|
||||
/// The params that are incorrect.
|
||||
late final String params;
|
||||
|
||||
SlashArgMisconfiguration._new(this.params);
|
||||
|
||||
/// Returns a string representation of this object.
|
||||
@override
|
||||
String toString() =>
|
||||
"SlashArgMisconfigurationError: ${this.params} are mismatched. Please refer to the nyxx.interaction docs and the discord developer docs to make sure that all your slash args arguments are compatible together.";
|
||||
|
||||
@override
|
||||
StackTrace? get stackTrace => StackTrace.empty;
|
||||
}
|
Loading…
Reference in a new issue