From e64ea06275d1328d28cc49ff5e07cc06dbfcb766 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 10:06:31 +0200 Subject: [PATCH 01/15] feat: Implement mineral uptime --- lib/src/api/client/mineral_client.dart | 5 ++++- lib/src/internal/services/environment.dart | 1 + lib/src/internal/websockets/packets/ready.dart | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/src/api/client/mineral_client.dart b/lib/src/api/client/mineral_client.dart index 9b9335c6..f5f4d72e 100644 --- a/lib/src/api/client/mineral_client.dart +++ b/lib/src/api/client/mineral_client.dart @@ -77,6 +77,7 @@ class MineralClient { String _sessionId; Application _application; List _intents; + late DateTime uptime; MineralClient( this._user, @@ -96,9 +97,11 @@ class MineralClient { Application get application => _application; List get intents => _intents; + /// ### Returns the time the [MineralClient] is online + Duration getUptimeDuration () => DateTime.now().difference(uptime); + /// ### Defines the presence that this should adopt /// - /// /// Example : /// ```dart /// client.setPresence( diff --git a/lib/src/internal/services/environment.dart b/lib/src/internal/services/environment.dart index 39adab93..dc57be78 100644 --- a/lib/src/internal/services/environment.dart +++ b/lib/src/internal/services/environment.dart @@ -26,6 +26,7 @@ class Environment { } return this; + } String? get (String key) { diff --git a/lib/src/internal/websockets/packets/ready.dart b/lib/src/internal/websockets/packets/ready.dart index d5db1dd0..91a9ce25 100644 --- a/lib/src/internal/websockets/packets/ready.dart +++ b/lib/src/internal/websockets/packets/ready.dart @@ -17,8 +17,10 @@ class Ready implements WebsocketPacket { CommandManager commandManager = ioc.singleton(ioc.services.command); ShardManager shardManager = ioc.singleton(ioc.services.shards); - if(ioc.singleton(ioc.services.client) == null) { + if (ioc.singleton(ioc.services.client) == null) { MineralClient client = MineralClient.from(payload: websocketResponse.payload); + client.uptime = DateTime.now(); + ioc.bind(namespace: ioc.services.client, service: client); await client.registerGlobalCommands(commands: commandManager.getGlobals()); @@ -34,7 +36,10 @@ class Ready implements WebsocketPacket { ); } - final Shard shard = websocketResponse.payload['shard'] != null ? shardManager.shards[websocketResponse.payload['shard'][0]]! : shardManager.shards[0]!; + final Shard shard = websocketResponse.payload['shard'] != null + ? shardManager.shards[websocketResponse.payload['shard'][0]]! + : shardManager.shards[0]!; + shard.sessionId = websocketResponse.payload['session_id']; shard.initialize(); From 4ec1897ea8ad36a2d4a2495b5a9a52f07b79d1fd Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:11:42 +0200 Subject: [PATCH 02/15] feat: Implement MessageEmbed factory --- lib/api.dart | 1 + lib/src/api/emoji.dart | 2 +- lib/src/api/guilds/guild.dart | 17 +++-- lib/src/api/guilds/guild_member_reaction.dart | 1 - lib/src/api/guilds/guild_preview.dart | 75 +++++++++++++++++++ lib/src/api/messages/message_embed.dart | 31 ++++++++ lib/src/api/sticker.dart | 6 +- lib/src/api/user.dart | 4 +- .../websockets/packets/guild_create.dart | 6 ++ 9 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 lib/src/api/guilds/guild_preview.dart diff --git a/lib/api.dart b/lib/api.dart index 1d71cab9..bf7754ef 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -13,6 +13,7 @@ export 'src/api/managers/member_role_manager.dart' show MemberRoleManager; export 'src/api/managers/voice_manager.dart' show VoiceManager; export 'src/api/guilds/guild.dart' show Guild; +export 'src/api/guilds/guild_preview.dart' show GuildPreview; export 'src/api/moderation_rule.dart' show ModerationEventType, ModerationTriggerType, ModerationPresetType, ModerationActionType, ModerationTriggerMetadata, ModerationActionMetadata, ModerationAction, ModerationRule; export 'src/api/guilds/guild_scheduled_event.dart' show ScheduledEventStatus, ScheduledEventEntityType, GuildScheduledEvent, ScheduledEventUser; diff --git a/lib/src/api/emoji.dart b/lib/src/api/emoji.dart index eed62b0b..a8544743 100644 --- a/lib/src/api/emoji.dart +++ b/lib/src/api/emoji.dart @@ -111,7 +111,7 @@ class Emoji extends PartialEmoji { @override String toString () => isAnimated ? '' - : '<$label:$id>'; + : '<:$label:$id>'; factory Emoji.from({ required MemberManager memberManager, required EmojiManager emojiManager, required dynamic payload }) { return Emoji( diff --git a/lib/src/api/guilds/guild.dart b/lib/src/api/guilds/guild.dart index f490cfb1..03b89591 100644 --- a/lib/src/api/guilds/guild.dart +++ b/lib/src/api/guilds/guild.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:http/http.dart'; import 'package:mineral/api.dart'; import 'package:mineral/console.dart'; @@ -13,7 +15,6 @@ import 'package:mineral/src/api/managers/moderation_rule_manager.dart'; import 'package:mineral/src/api/managers/sticker_manager.dart'; import 'package:mineral/src/api/managers/webhook_manager.dart'; import 'package:mineral/src/api/managers/guild_scheduled_event_manager.dart'; -import 'package:mineral/src/api/sticker.dart'; import 'package:mineral/src/api/welcome_screen.dart'; import 'package:collection/collection.dart'; @@ -544,6 +545,16 @@ class Guild { } } + Future preview () async { + Http http = ioc.singleton(ioc.services.http); + Response response = await http.get(url: '/guilds/$id/preview'); + + return GuildPreview.from( + guild: this, + payload: jsonDecode(response.body) + ); + } + factory Guild.from({ required EmojiManager emojiManager, required MemberManager memberManager, @@ -555,10 +566,6 @@ class Guild { required dynamic payload }) { StickerManager stickerManager = StickerManager(); - for (dynamic element in payload['stickers']) { - Sticker sticker = Sticker.from(element); - stickerManager.cache.putIfAbsent(sticker.id, () => sticker); - } List features = []; for (String element in payload['features']) { diff --git a/lib/src/api/guilds/guild_member_reaction.dart b/lib/src/api/guilds/guild_member_reaction.dart index 2b7afc1e..578f3cac 100644 --- a/lib/src/api/guilds/guild_member_reaction.dart +++ b/lib/src/api/guilds/guild_member_reaction.dart @@ -20,7 +20,6 @@ class GuildMemberReaction { ? '${_partialEmoji.label}:${_partialEmoji.id}' : _partialEmoji.label; - print('/channels/${_message.channel.id}/messages/${_message.id}/reactions/$_emoji/${user.id}'); Response response = await http.destroy(url: '/channels/${_message.channel.id}/messages/${_message.id}/reactions/$_emoji/${user.id}'); if (response.statusCode == 200) { _manager.reactions.remove(_emoji); diff --git a/lib/src/api/guilds/guild_preview.dart b/lib/src/api/guilds/guild_preview.dart new file mode 100644 index 00000000..eea2bc7a --- /dev/null +++ b/lib/src/api/guilds/guild_preview.dart @@ -0,0 +1,75 @@ +import 'package:mineral/api.dart'; +import 'package:mineral/core.dart'; +import 'package:mineral/src/api/sticker.dart'; + +class GuildPreview { + final Snowflake _id; + final String _label; + final String? _description; + final String? _icon; + final String? _splash; + final String? _discoverySplash; + final Map _emojis; + final Map _stickers; + final List _features; + final int _approximateMemberCount; + final int _approximatePresenceCount; + + GuildPreview( + this._id, + this._label, + this._description, + this._icon, + this._splash, + this._discoverySplash, + this._emojis, + this._stickers, + this._features, + this._approximateMemberCount, + this._approximatePresenceCount, + ); + + Snowflake get id => _id; + String get label => _label; + String? get description => _description; + String? get icon => '${Constants.cdnUrl}/icons/$id/$_icon.png'; + String? get splash => '${Constants.cdnUrl}/splashes/$id/$_splash.png'; + String? get discoverySplash => '${Constants.cdnUrl}/discovery-splashes/$id/$_discoverySplash.png'; + Map get emojis => _emojis; + Map get stickers => _stickers; + List get features => _features; + int get approximateMemberCount => _approximateMemberCount; + int get approximatePresenceCount => _approximatePresenceCount; + + factory GuildPreview.from({ required Guild guild, required dynamic payload }) { + final Map emojis = {}; + for (final payload in payload['emojis']) { + emojis.putIfAbsent(payload['id'], () => guild.emojis.cache.getOrFail(payload['id'])); + } + + final Map stickers = {}; + for (final payload in payload['stickers']) { + stickers.putIfAbsent(payload['id'], () => guild.stickers.cache.getOrFail(payload['id'])); + } + + final List features = []; + for (final payload in payload['features']) { + final feature = GuildFeature.values.firstWhere((feature) => feature.value == payload); + features.add(feature); + } + + return GuildPreview( + payload['id'], + payload['name'], + payload['description'], + payload['icon'], + payload['splash'], + payload['discovery_splash'], + emojis, + stickers, + features, + payload['approximate_member_count'], + payload['approximate_presence_count'] + ); + } +} diff --git a/lib/src/api/messages/message_embed.dart b/lib/src/api/messages/message_embed.dart index bc80608b..6d1b3a57 100644 --- a/lib/src/api/messages/message_embed.dart +++ b/lib/src/api/messages/message_embed.dart @@ -1,4 +1,5 @@ import 'package:mineral/api.dart'; +import 'package:mineral/core.dart'; class Footer { String text; @@ -229,6 +230,8 @@ class MessageEmbed { /// .addField(name: 'My field', value: 'My custom value'); /// ``` MessageEmbed addField ({ required String name, required String value, bool? inline }) { + fields ??= []; + fields?.add(Field(name: name, value: value, inline: inline)); return this; } @@ -254,4 +257,32 @@ class MessageEmbed { 'author': author?.toJson(), }; } + + factory MessageEmbed.fromGuildPreview(GuildPreview preview) { + MineralClient client = ioc.singleton(ioc.services.client); + + final MessageEmbed embed = MessageEmbed( + title: preview.label, + description: preview.description, + thumbnail: preview.icon != null ? Thumbnail(url: preview.icon!) : null, + image: preview.discoverySplash != null ? Image(url: preview.discoverySplash!) : null, + color: Color.invisible, + timestamp: DateTime.now(), + author: Author(name: client.user.username, iconUrl: client.user.getDisplayAvatarUrl()) + ); + + embed.addField(name: 'Identifier', value: preview.id); + embed.addField(name: 'Features', value: preview.features.map((feature) => '• $feature').join('\n'), inline: true); + + if (preview.stickers.isNotEmpty) { + embed.addField(name: 'Emojis', value: preview.emojis.values.map((emoji) => emoji).join(' '), inline: true); + } + + embed.addField(name: '\u200B', value: '\u200B'); + embed.addField(name: 'Online members', value: '${preview.approximatePresenceCount} members', inline: true); + embed.addField(name: 'Members', value: '${preview.approximateMemberCount} members', inline: true); + embed.addField(name: '\u200B', value: '\u200B', inline: true); + + return embed; + } } diff --git a/lib/src/api/sticker.dart b/lib/src/api/sticker.dart index 1695ecf5..3aab4b58 100644 --- a/lib/src/api/sticker.dart +++ b/lib/src/api/sticker.dart @@ -30,7 +30,7 @@ enum FormatType { class Sticker { Snowflake _id; - Snowflake _packId; + Snowflake? _packId; String _name; String? _description; String _tags; @@ -53,7 +53,7 @@ class Sticker { ); Snowflake get id => _id; - Snowflake get packId => _packId; + Snowflake? get packId => _packId; String get name => _name; String? get description => _description; String get tags => _tags; @@ -110,7 +110,7 @@ class Sticker { payload['description'], payload['tags'], StickerType.values.firstWhere((element) => element.value == payload['type']), - payload['format_type'], + FormatType.values.firstWhere((format) => format.value == payload['format_type']), payload['sortValue'] ); diff --git a/lib/src/api/user.dart b/lib/src/api/user.dart index 88c478ed..5b1817b0 100644 --- a/lib/src/api/user.dart +++ b/lib/src/api/user.dart @@ -70,7 +70,9 @@ class User { /// ### Returns the absolute url to the user's avatar String getDisplayAvatarUrl () { - return '${Constants.cdnUrl}/avatars/$id/$avatar'; + return avatar != null + ? '${Constants.cdnUrl}/avatars/$id/$avatar' + : '${Constants.cdnUrl}/embed/avatars/${int.parse(discriminator) % 5 }.png'; } @override diff --git a/lib/src/internal/websockets/packets/guild_create.dart b/lib/src/internal/websockets/packets/guild_create.dart index 8b80f333..30be78b3 100644 --- a/lib/src/internal/websockets/packets/guild_create.dart +++ b/lib/src/internal/websockets/packets/guild_create.dart @@ -11,6 +11,7 @@ import 'package:mineral/src/api/managers/guild_scheduled_event_manager.dart'; import 'package:mineral/src/api/managers/member_manager.dart'; import 'package:mineral/src/api/managers/moderation_rule_manager.dart'; import 'package:mineral/src/api/managers/webhook_manager.dart'; +import 'package:mineral/src/api/sticker.dart'; import 'package:mineral/src/internal/managers/command_manager.dart'; import 'package:mineral/src/internal/managers/context_menu_manager.dart'; import 'package:mineral/src/internal/managers/event_manager.dart'; @@ -84,6 +85,11 @@ class GuildCreate implements WebsocketPacket { client.guilds.cache.putIfAbsent(guild.id, () => guild); + for (dynamic element in websocketResponse.payload['stickers']) { + Sticker sticker = Sticker.from(element); + guild.stickers.cache.putIfAbsent(sticker.id, () => sticker); + } + for (dynamic member in websocketResponse.payload['members']) { User user = User.from(member['user']); GuildMember guildMember = GuildMember.from( From 7fa51f791927773bb495caf891f1c70e80cf694a Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:15:26 +0200 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20MessageEmbed=20=E2=86=92=20Em?= =?UTF-8?q?bedBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 2 +- lib/src/api/channels/text_based_channel.dart | 2 +- lib/src/api/interactions/interaction.dart | 4 +- lib/src/api/messages/dm_message.dart | 4 +- ...{message_embed.dart => embed_builder.dart} | 52 +++++++++---------- lib/src/api/messages/message.dart | 6 +-- lib/src/api/messages/partial_message.dart | 2 +- lib/src/api/user.dart | 2 +- lib/src/api/webhook.dart | 4 +- .../internal/extensions/mineral_client.dart | 4 +- 10 files changed, 41 insertions(+), 41 deletions(-) rename lib/src/api/messages/{message_embed.dart => embed_builder.dart} (84%) diff --git a/lib/api.dart b/lib/api.dart index bf7754ef..b3fed333 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -29,7 +29,7 @@ export 'src/api/channels/news_channel.dart' show NewsChannel; export 'src/api/channels/permission_overwrite.dart' show PermissionOverwrite, PermissionOverwriteType; export 'src/api/messages/message.dart' show Message; -export 'src/api/messages/message_embed.dart' show MessageEmbed, Footer, Image, Thumbnail, Author, Field; +export 'src/api/messages/embed_builder.dart' show EmbedBuilder, Footer, Image, Thumbnail, Author, Field; export 'src/api/color.dart' show Color; export 'src/api/emoji.dart' show EmojiBuilder, Emoji; diff --git a/lib/src/api/channels/text_based_channel.dart b/lib/src/api/channels/text_based_channel.dart index ca182ce8..db894129 100644 --- a/lib/src/api/channels/text_based_channel.dart +++ b/lib/src/api/channels/text_based_channel.dart @@ -45,7 +45,7 @@ class TextBasedChannel extends Channel { MessageManager get messages => _messages; ThreadManager get threads => _threads; - Future send ({ String? content, List? embeds, List? components, bool? tts }) async { + Future send ({ String? content, List? embeds, List? components, bool? tts }) async { MineralClient client = ioc.singleton(ioc.services.client); Response response = await client.sendMessage(this, diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 2c2c5a1f..794c37fa 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -41,12 +41,12 @@ class Interaction { /// ```dart /// await interaction.reply(content: 'Hello ${interaction.user.username}'); /// ``` - Future reply ({ String? content, List? embeds, List? components, bool? tts, bool? private }) async { + Future reply ({ String? content, List? embeds, List? components, bool? tts, bool? private }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; if (embeds != null) { - for (MessageEmbed element in embeds) { + for (EmbedBuilder element in embeds) { embedList.add(element.toJson()); } } diff --git a/lib/src/api/messages/dm_message.dart b/lib/src/api/messages/dm_message.dart index 9fc9ed5d..8b4ed2d5 100644 --- a/lib/src/api/messages/dm_message.dart +++ b/lib/src/api/messages/dm_message.dart @@ -33,7 +33,7 @@ class DmMessage extends PartialMessage { MineralClient client = ioc.singleton(ioc.services.client); User? user = client.users.cache.get(payload['author']['id']); - List embeds = []; + List embeds = []; for (dynamic element in payload['embeds']) { List fields = []; if (element['fields'] != null) { @@ -43,7 +43,7 @@ class DmMessage extends PartialMessage { } } - MessageEmbed embed = MessageEmbed( + EmbedBuilder embed = EmbedBuilder( title: element['title'], description: element['description'], url: element['url'], diff --git a/lib/src/api/messages/message_embed.dart b/lib/src/api/messages/embed_builder.dart similarity index 84% rename from lib/src/api/messages/message_embed.dart rename to lib/src/api/messages/embed_builder.dart index 6d1b3a57..c6033cc2 100644 --- a/lib/src/api/messages/message_embed.dart +++ b/lib/src/api/messages/embed_builder.dart @@ -77,7 +77,7 @@ class Field { }; } -class MessageEmbed { +class EmbedBuilder { String? title; String? description; String? url; @@ -89,7 +89,7 @@ class MessageEmbed { List? fields; Color? color; - MessageEmbed({ + EmbedBuilder({ this.title, this.description, this.url, @@ -106,10 +106,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setTitle('My title'); /// ``` - MessageEmbed setTitle (String value) { + EmbedBuilder setTitle (String value) { title = value; return this; } @@ -118,10 +118,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setDescription('My description'); /// ``` - MessageEmbed setDescription (String value) { + EmbedBuilder setDescription (String value) { description = value; return this; } @@ -130,10 +130,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setFooter(text: 'My title'); /// ``` - MessageEmbed setFooter ({ required String text, String? iconUrl, String? proxyIconUrl }) { + EmbedBuilder setFooter ({ required String text, String? iconUrl, String? proxyIconUrl }) { footer = Footer(text: text, iconUrl: iconUrl, proxyIconUrl: proxyIconUrl); return this; } @@ -142,10 +142,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setImage(url: 'https://..../images/my_picture.png'); /// ``` - MessageEmbed setImage ({ required String url, String? proxyUrl, int? width, int? height }) { + EmbedBuilder setImage ({ required String url, String? proxyUrl, int? width, int? height }) { image = Image(url: url, proxyUrl: proxyUrl, width: width, height: height); return this; } @@ -154,10 +154,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setThumbnail(url: 'https://..../images/my_picture.png'); /// ``` - MessageEmbed setThumbnail ({ required String url, String? proxyUrl, int? width, int? height }) { + EmbedBuilder setThumbnail ({ required String url, String? proxyUrl, int? width, int? height }) { thumbnail = Thumbnail(url: url, proxyUrl: proxyUrl, width: width, height: height); return this; } @@ -166,10 +166,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setAuthor(name: 'John Doe'); /// ``` - MessageEmbed setAuthor ({ required String name, String? url, String? iconUrl, String? proxyIconUrl }) { + EmbedBuilder setAuthor ({ required String name, String? url, String? iconUrl, String? proxyIconUrl }) { author = Author(name: name, url: url, iconUrl: iconUrl, proxyIconUrl: proxyIconUrl); return this; } @@ -178,17 +178,17 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setColor(Color.cyan_600); /// ``` /// Or with your custom color /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setColor(Color('#FFFFFF')); /// ``` - MessageEmbed setColor (Color color) { + EmbedBuilder setColor (Color color) { this.color = color; return this; } @@ -197,15 +197,15 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setTimestamp(); /// ``` /// You can define an older or future timestamp /// DateTime date = DateTime.now().add(DateTime(days: 5)); - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setTimestamp(dateTime: date); /// ``` - MessageEmbed setTimestamp ({ DateTime? dateTime }) { + EmbedBuilder setTimestamp ({ DateTime? dateTime }) { timestamp = dateTime ?? DateTime.now(); return this; } @@ -214,10 +214,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .setUrl('https://.....com'); /// ``` - MessageEmbed setUrl (String url) { + EmbedBuilder setUrl (String url) { this.url = url; return this; } @@ -226,10 +226,10 @@ class MessageEmbed { /// /// Example : /// ```dart - /// final embed = MessageEmbed() + /// final embed = EmbedBuilder() /// .addField(name: 'My field', value: 'My custom value'); /// ``` - MessageEmbed addField ({ required String name, required String value, bool? inline }) { + EmbedBuilder addField ({ required String name, required String value, bool? inline }) { fields ??= []; fields?.add(Field(name: name, value: value, inline: inline)); @@ -258,10 +258,10 @@ class MessageEmbed { }; } - factory MessageEmbed.fromGuildPreview(GuildPreview preview) { + factory EmbedBuilder.fromGuildPreview(GuildPreview preview) { MineralClient client = ioc.singleton(ioc.services.client); - final MessageEmbed embed = MessageEmbed( + final EmbedBuilder embed = EmbedBuilder( title: preview.label, description: preview.description, thumbnail: preview.icon != null ? Thumbnail(url: preview.icon!) : null, diff --git a/lib/src/api/messages/message.dart b/lib/src/api/messages/message.dart index d5b1be60..be8e7a14 100644 --- a/lib/src/api/messages/message.dart +++ b/lib/src/api/messages/message.dart @@ -32,7 +32,7 @@ class Message extends PartialMessage { GuildMember? get author => _author; - Future edit ({ String? content, List? embeds, List? components, bool? tts }) async { + Future edit ({ String? content, List? embeds, List? components, bool? tts }) async { Http http = ioc.singleton(ioc.services.http); Response response = await http.patch( @@ -87,7 +87,7 @@ class Message extends PartialMessage { factory Message.from({ required TextBasedChannel channel, required dynamic payload }) { GuildMember? guildMember = channel.guild?.members.cache.get(payload['author']['id']); - List embeds = []; + List embeds = []; for (dynamic element in payload['embeds']) { List fields = []; @@ -98,7 +98,7 @@ class Message extends PartialMessage { } } - MessageEmbed embed = MessageEmbed( + EmbedBuilder embed = EmbedBuilder( title: element['title'], description: element['description'], url: element['url'], diff --git a/lib/src/api/messages/partial_message.dart b/lib/src/api/messages/partial_message.dart index 26d772c7..7f99e3b8 100644 --- a/lib/src/api/messages/partial_message.dart +++ b/lib/src/api/messages/partial_message.dart @@ -9,7 +9,7 @@ class PartialMessage { final Snowflake _id; String content; final bool _tts; - List embeds; + List embeds; final bool _allowMentions; final PartialMessage? _reference; List components; diff --git a/lib/src/api/user.dart b/lib/src/api/user.dart index 5b1817b0..5376ba2b 100644 --- a/lib/src/api/user.dart +++ b/lib/src/api/user.dart @@ -36,7 +36,7 @@ class User { /// GuildMember? member = guild.members.cache.get('240561194958716924'); /// await member.user.send(content: 'Hello World !'); /// ``` - Future send ({ String? content, List? embeds, List? components, bool? tts }) async { + Future send ({ String? content, List? embeds, List? components, bool? tts }) async { MineralClient client = ioc.singleton(ioc.services.client); Http http = ioc.singleton(ioc.services.http); diff --git a/lib/src/api/webhook.dart b/lib/src/api/webhook.dart index ea0af2b6..b4279549 100644 --- a/lib/src/api/webhook.dart +++ b/lib/src/api/webhook.dart @@ -102,12 +102,12 @@ class Webhook { /// ```dart /// await webhook.execute(content: 'Hello World !'); /// ``` - Future execute ({ String? content, String? username, String? avatarUrl, bool? tts, List? embeds, List? components, bool? suppressEmbed }) async { + Future execute ({ String? content, String? username, String? avatarUrl, bool? tts, List? embeds, List? components, bool? suppressEmbed }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; if (embeds != null) { - for (MessageEmbed element in embeds) { + for (EmbedBuilder element in embeds) { embedList.add(element.toJson()); } } diff --git a/lib/src/internal/extensions/mineral_client.dart b/lib/src/internal/extensions/mineral_client.dart index 71fc2a4f..8d141d77 100644 --- a/lib/src/internal/extensions/mineral_client.dart +++ b/lib/src/internal/extensions/mineral_client.dart @@ -3,12 +3,12 @@ import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; extension MineralClientExtension on MineralClient { - Future sendMessage (dynamic channel, { String? content, List? embeds, List? components, bool? tts }) async { + Future sendMessage (dynamic channel, { String? content, List? embeds, List? components, bool? tts }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; if (embeds != null) { - for (MessageEmbed element in embeds) { + for (EmbedBuilder element in embeds) { embedList.add(element.toJson()); } } From d64eaaa53194e1ba3fa5608e92d0c9c60552cfe6 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:17:27 +0200 Subject: [PATCH 04/15] =?UTF-8?q?refactor:=20Modal=20=E2=86=92=20ModalBuil?= =?UTF-8?q?der?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 2 +- .../components/{modal.dart => modal_builder.dart} | 12 ++++++------ lib/src/api/interactions/interaction.dart | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) rename lib/src/api/components/{modal.dart => modal_builder.dart} (71%) diff --git a/lib/api.dart b/lib/api.dart index b3fed333..01fe4e3d 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -37,7 +37,7 @@ export 'src/api/role.dart' show Role; export 'src/api/components/row.dart' show Row; export 'src/api/components/select_menu.dart' show SelectMenu, SelectMenuOption, EmojiOption; -export 'src/api/components/modal.dart' show Modal; +export 'src/api/components/modal_builder.dart' show ModalBuilder; export 'src/api/components/text_input.dart' show TextInputStyle; export 'src/api/components/button.dart' show Button, ButtonStyle; export 'src/api/components/link.dart' show Link; diff --git a/lib/src/api/components/modal.dart b/lib/src/api/components/modal_builder.dart similarity index 71% rename from lib/src/api/components/modal.dart rename to lib/src/api/components/modal_builder.dart index 909f61da..9b897415 100644 --- a/lib/src/api/components/modal.dart +++ b/lib/src/api/components/modal_builder.dart @@ -3,22 +3,22 @@ import 'package:mineral/src/api/components/text_input.dart'; import '../../../api.dart'; -class Modal extends Component { +class ModalBuilder extends Component { String label; String customId; List components = []; - Modal({ required this.customId, required this.label }) : super(type: ComponentType.selectMenu); + ModalBuilder({ required this.customId, required this.label }) : super(type: ComponentType.selectMenu); /// ### Created a input text field /// /// Example : /// ```dart - /// final Modal modal = Modal(customId: 'my_modal', label: 'My modal') + /// final ModalBuilder modal = ModalBuilder(customId: 'my_modal', label: 'My modal') /// .addInput(customId: 'my_text', label: 'Premier texte'); /// ``` - Modal addInput ({ required String customId, required String label, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { + ModalBuilder addInput ({ required String customId, required String label, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { _addInput(customId: customId, label: label, style: TextInputStyle.short, required: required, minLength: minLength, maxLength: maxLength, placeholder: placeholder, value: value); return this; } @@ -27,10 +27,10 @@ class Modal extends Component { /// /// Example : /// ```dart - /// final Modal modal = Modal(customId: 'my_modal', label: 'My modal') + /// final ModalBuilder modal = ModalBuilder(customId: 'my_modal', label: 'My modal') /// .addParagraph(customId: 'my_paragraph', label: 'Second texte'); /// ``` - Modal addParagraph ({ required String customId, required String label, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { + ModalBuilder addParagraph ({ required String customId, required String label, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { _addInput(customId: customId, label: label, style: TextInputStyle.paragraph, required: required, minLength: minLength, maxLength: maxLength, placeholder: placeholder, value: value); return this; } diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 794c37fa..3d53f850 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -80,7 +80,7 @@ class Interaction { /// /// await interaction.modal(modal); /// ``` - Future modal (Modal modal) async { + Future modal (ModalBuilder modal) async { Http http = ioc.singleton(ioc.services.http); await http.post(url: "/interactions/$id/$token/callback", payload: { From be36a8ef7f57d9440ef94da30bd9d9fdf564210c Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:20:31 +0200 Subject: [PATCH 05/15] =?UTF-8?q?refactor:=20SelectMenu=20=E2=86=92=20Sele?= =?UTF-8?q?ctMenuBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 2 +- .../components/{select_menu.dart => select_menu_builder.dart} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename lib/src/api/components/{select_menu.dart => select_menu_builder.dart} (83%) diff --git a/lib/api.dart b/lib/api.dart index 01fe4e3d..b8b8c8e0 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -36,7 +36,7 @@ export 'src/api/emoji.dart' show EmojiBuilder, Emoji; export 'src/api/role.dart' show Role; export 'src/api/components/row.dart' show Row; -export 'src/api/components/select_menu.dart' show SelectMenu, SelectMenuOption, EmojiOption; +export 'src/api/components/select_menu_builder.dart' show SelectMenuBuilder, SelectMenuOption, EmojiOption; export 'src/api/components/modal_builder.dart' show ModalBuilder; export 'src/api/components/text_input.dart' show TextInputStyle; export 'src/api/components/button.dart' show Button, ButtonStyle; diff --git a/lib/src/api/components/select_menu.dart b/lib/src/api/components/select_menu_builder.dart similarity index 83% rename from lib/src/api/components/select_menu.dart rename to lib/src/api/components/select_menu_builder.dart index 1f0bd62c..e661a56a 100644 --- a/lib/src/api/components/select_menu.dart +++ b/lib/src/api/components/select_menu_builder.dart @@ -1,7 +1,7 @@ import 'package:mineral/api.dart'; import 'package:mineral/src/api/components/component.dart'; -class SelectMenu extends Component { +class SelectMenuBuilder extends Component { String customId; List options = []; String? placeholder; @@ -9,7 +9,7 @@ class SelectMenu extends Component { int? maxValues = 25; bool? disabled = false; - SelectMenu({ required this.customId, required this.options, this.placeholder, this.minValues, this.maxValues, this.disabled }) : super (type: ComponentType.selectMenu); + SelectMenuBuilder({ required this.customId, required this.options, this.placeholder, this.minValues, this.maxValues, this.disabled }) : super (type: ComponentType.selectMenu); @override Object toJson () { From 26bc722a19de7ab94ce9f15c382f77d3559cf811 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:22:02 +0200 Subject: [PATCH 06/15] =?UTF-8?q?refactor:=20Button=20=E2=86=92=20ButtonBu?= =?UTF-8?q?ilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 4 ++-- .../api/components/{button.dart => button_builder.dart} | 8 ++++---- lib/src/api/components/{link.dart => link_builder.dart} | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) rename lib/src/api/components/{button.dart => button_builder.dart} (73%) rename lib/src/api/components/{link.dart => link_builder.dart} (60%) diff --git a/lib/api.dart b/lib/api.dart index b8b8c8e0..905e5bb2 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -39,8 +39,8 @@ export 'src/api/components/row.dart' show Row; export 'src/api/components/select_menu_builder.dart' show SelectMenuBuilder, SelectMenuOption, EmojiOption; export 'src/api/components/modal_builder.dart' show ModalBuilder; export 'src/api/components/text_input.dart' show TextInputStyle; -export 'src/api/components/button.dart' show Button, ButtonStyle; -export 'src/api/components/link.dart' show Link; +export 'src/api/components/button_builder.dart' show ButtonBuilder, ButtonStyle; +export 'src/api/components/link_builder.dart' show Link; export 'src/api/interactions/command_interaction.dart' show CommandInteraction; export 'src/api/interactions/button_interaction.dart' show ButtonInteraction; diff --git a/lib/src/api/components/button.dart b/lib/src/api/components/button_builder.dart similarity index 73% rename from lib/src/api/components/button.dart rename to lib/src/api/components/button_builder.dart index 81778f3b..8abfd6c8 100644 --- a/lib/src/api/components/button.dart +++ b/lib/src/api/components/button_builder.dart @@ -15,14 +15,14 @@ enum ButtonStyle { String toString () => value.toString(); } -class Button extends Component { +class ButtonBuilder extends Component { String customId; String label; ButtonStyle style; EmojiBuilder? emoji; bool disabled; - Button({ required this.customId, required this.label, required this.style, this.emoji, this.disabled = false }) : super(type: ComponentType.button); + ButtonBuilder({ required this.customId, required this.label, required this.style, this.emoji, this.disabled = false }) : super(type: ComponentType.button); @override dynamic toJson () { @@ -36,8 +36,8 @@ class Button extends Component { }; } - factory Button.from({ required dynamic payload }) { - return Button( + factory ButtonBuilder.from({ required dynamic payload }) { + return ButtonBuilder( customId: payload['custom_id'], label: payload['label'], style: ButtonStyle.values.firstWhere((element) => element.value == payload['style']) diff --git a/lib/src/api/components/link.dart b/lib/src/api/components/link_builder.dart similarity index 60% rename from lib/src/api/components/link.dart rename to lib/src/api/components/link_builder.dart index f1fa0fb3..bd9f1d68 100644 --- a/lib/src/api/components/link.dart +++ b/lib/src/api/components/link_builder.dart @@ -1,11 +1,11 @@ import 'package:mineral/src/api/components/component.dart'; -class Link extends Component { +class LinkBuilder extends Component { String label; String url; int style = 5; - Link({ required this.label, required this.url }) : super(type: ComponentType.button); + LinkBuilder({ required this.label, required this.url }) : super(type: ComponentType.button); @override dynamic toJson () { @@ -17,8 +17,8 @@ class Link extends Component { }; } - factory Link.from({ required dynamic payload }) { - return Link( + factory LinkBuilder.from({ required dynamic payload }) { + return LinkBuilder( url: payload['url'], label: payload['label'], ); From 834569d46463aaf11e35f6d791eb69db55882c2c Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:23:47 +0200 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20Row=20=E2=86=92=20RowBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 4 ++-- lib/src/api/channels/text_based_channel.dart | 2 +- lib/src/api/components/modal_builder.dart | 4 ++-- lib/src/api/components/{row.dart => row_builder.dart} | 8 ++++---- lib/src/api/interactions/interaction.dart | 4 ++-- lib/src/api/messages/message.dart | 2 +- lib/src/api/user.dart | 2 +- lib/src/api/webhook.dart | 4 ++-- lib/src/internal/extensions/mineral_client.dart | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) rename lib/src/api/components/{row.dart => row_builder.dart} (58%) diff --git a/lib/api.dart b/lib/api.dart index 905e5bb2..c9484cfb 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -35,12 +35,12 @@ export 'src/api/color.dart' show Color; export 'src/api/emoji.dart' show EmojiBuilder, Emoji; export 'src/api/role.dart' show Role; -export 'src/api/components/row.dart' show Row; +export 'src/api/components/row_builder.dart' show RowBuilder; export 'src/api/components/select_menu_builder.dart' show SelectMenuBuilder, SelectMenuOption, EmojiOption; export 'src/api/components/modal_builder.dart' show ModalBuilder; export 'src/api/components/text_input.dart' show TextInputStyle; export 'src/api/components/button_builder.dart' show ButtonBuilder, ButtonStyle; -export 'src/api/components/link_builder.dart' show Link; +export 'src/api/components/link_builder.dart' show LinkBuilder; export 'src/api/interactions/command_interaction.dart' show CommandInteraction; export 'src/api/interactions/button_interaction.dart' show ButtonInteraction; diff --git a/lib/src/api/channels/text_based_channel.dart b/lib/src/api/channels/text_based_channel.dart index db894129..f4bc5034 100644 --- a/lib/src/api/channels/text_based_channel.dart +++ b/lib/src/api/channels/text_based_channel.dart @@ -45,7 +45,7 @@ class TextBasedChannel extends Channel { MessageManager get messages => _messages; ThreadManager get threads => _threads; - Future send ({ String? content, List? embeds, List? components, bool? tts }) async { + Future send ({ String? content, List? embeds, List? components, bool? tts }) async { MineralClient client = ioc.singleton(ioc.services.client); Response response = await client.sendMessage(this, diff --git a/lib/src/api/components/modal_builder.dart b/lib/src/api/components/modal_builder.dart index 9b897415..bc3a1767 100644 --- a/lib/src/api/components/modal_builder.dart +++ b/lib/src/api/components/modal_builder.dart @@ -7,7 +7,7 @@ class ModalBuilder extends Component { String label; String customId; - List components = []; + List components = []; ModalBuilder({ required this.customId, required this.label }) : super(type: ComponentType.selectMenu); @@ -47,7 +47,7 @@ class ModalBuilder extends Component { value: value, ); - components.add(Row(components: [input])); + components.add(RowBuilder(components: [input])); } @override diff --git a/lib/src/api/components/row.dart b/lib/src/api/components/row_builder.dart similarity index 58% rename from lib/src/api/components/row.dart rename to lib/src/api/components/row_builder.dart index 9b2a5545..0b710e73 100644 --- a/lib/src/api/components/row.dart +++ b/lib/src/api/components/row_builder.dart @@ -1,9 +1,9 @@ import 'package:mineral/src/api/components/component.dart'; -class Row extends Component { +class RowBuilder extends Component { List? components = []; - Row({ this.components }) : super(type: ComponentType.actionRow); + RowBuilder({ this.components }) : super(type: ComponentType.actionRow); @override Object toJson () { @@ -13,7 +13,7 @@ class Row extends Component { }; } - factory Row.from({ required dynamic payload }) { - return Row(); + factory RowBuilder.from({ required dynamic payload }) { + return RowBuilder(); } } diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 3d53f850..28f08dd1 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -41,7 +41,7 @@ class Interaction { /// ```dart /// await interaction.reply(content: 'Hello ${interaction.user.username}'); /// ``` - Future reply ({ String? content, List? embeds, List? components, bool? tts, bool? private }) async { + Future reply ({ String? content, List? embeds, List? components, bool? tts, bool? private }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; @@ -53,7 +53,7 @@ class Interaction { List componentList = []; if (components != null) { - for (Row element in components) { + for (RowBuilder element in components) { componentList.add(element.toJson()); } } diff --git a/lib/src/api/messages/message.dart b/lib/src/api/messages/message.dart index be8e7a14..11d53559 100644 --- a/lib/src/api/messages/message.dart +++ b/lib/src/api/messages/message.dart @@ -32,7 +32,7 @@ class Message extends PartialMessage { GuildMember? get author => _author; - Future edit ({ String? content, List? embeds, List? components, bool? tts }) async { + Future edit ({ String? content, List? embeds, List? components, bool? tts }) async { Http http = ioc.singleton(ioc.services.http); Response response = await http.patch( diff --git a/lib/src/api/user.dart b/lib/src/api/user.dart index 5376ba2b..6e678045 100644 --- a/lib/src/api/user.dart +++ b/lib/src/api/user.dart @@ -36,7 +36,7 @@ class User { /// GuildMember? member = guild.members.cache.get('240561194958716924'); /// await member.user.send(content: 'Hello World !'); /// ``` - Future send ({ String? content, List? embeds, List? components, bool? tts }) async { + Future send ({ String? content, List? embeds, List? components, bool? tts }) async { MineralClient client = ioc.singleton(ioc.services.client); Http http = ioc.singleton(ioc.services.http); diff --git a/lib/src/api/webhook.dart b/lib/src/api/webhook.dart index b4279549..3a19daf2 100644 --- a/lib/src/api/webhook.dart +++ b/lib/src/api/webhook.dart @@ -102,7 +102,7 @@ class Webhook { /// ```dart /// await webhook.execute(content: 'Hello World !'); /// ``` - Future execute ({ String? content, String? username, String? avatarUrl, bool? tts, List? embeds, List? components, bool? suppressEmbed }) async { + Future execute ({ String? content, String? username, String? avatarUrl, bool? tts, List? embeds, List? components, bool? suppressEmbed }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; @@ -114,7 +114,7 @@ class Webhook { List componentList = []; if (components != null) { - for (Row element in components) { + for (RowBuilder element in components) { componentList.add(element.toJson()); } } diff --git a/lib/src/internal/extensions/mineral_client.dart b/lib/src/internal/extensions/mineral_client.dart index 8d141d77..d5f859d8 100644 --- a/lib/src/internal/extensions/mineral_client.dart +++ b/lib/src/internal/extensions/mineral_client.dart @@ -3,7 +3,7 @@ import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; extension MineralClientExtension on MineralClient { - Future sendMessage (dynamic channel, { String? content, List? embeds, List? components, bool? tts }) async { + Future sendMessage (dynamic channel, { String? content, List? embeds, List? components, bool? tts }) async { Http http = ioc.singleton(ioc.services.http); List embedList = []; @@ -15,7 +15,7 @@ extension MineralClientExtension on MineralClient { List componentList = []; if (components != null) { - for (Row element in components) { + for (RowBuilder element in components) { componentList.add(element.toJson()); } } From 4d5c703494e2e3e4e6374d3cb3411186ea1d9681 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:29:27 +0200 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20TextInput=20=E2=86=92=20TextI?= =?UTF-8?q?nputBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api.dart | 2 +- lib/src/api/components/modal_builder.dart | 16 +++++++++------- .../{text_input.dart => text_input_builder.dart} | 10 +++++----- 3 files changed, 15 insertions(+), 13 deletions(-) rename lib/src/api/components/{text_input.dart => text_input_builder.dart} (87%) diff --git a/lib/api.dart b/lib/api.dart index c9484cfb..81e60109 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -38,7 +38,7 @@ export 'src/api/role.dart' show Role; export 'src/api/components/row_builder.dart' show RowBuilder; export 'src/api/components/select_menu_builder.dart' show SelectMenuBuilder, SelectMenuOption, EmojiOption; export 'src/api/components/modal_builder.dart' show ModalBuilder; -export 'src/api/components/text_input.dart' show TextInputStyle; +export 'src/api/components/text_input_builder.dart' show TextInputBuilder, TextInputStyle; export 'src/api/components/button_builder.dart' show ButtonBuilder, ButtonStyle; export 'src/api/components/link_builder.dart' show LinkBuilder; diff --git a/lib/src/api/components/modal_builder.dart b/lib/src/api/components/modal_builder.dart index bc3a1767..a3ea2170 100644 --- a/lib/src/api/components/modal_builder.dart +++ b/lib/src/api/components/modal_builder.dart @@ -1,5 +1,5 @@ import 'package:mineral/src/api/components/component.dart'; -import 'package:mineral/src/api/components/text_input.dart'; +import 'package:mineral/src/api/components/text_input_builder.dart'; import '../../../api.dart'; @@ -7,9 +7,9 @@ class ModalBuilder extends Component { String label; String customId; - List components = []; + List? components = []; - ModalBuilder({ required this.customId, required this.label }) : super(type: ComponentType.selectMenu); + ModalBuilder({ required this.customId, required this.label, this.components }) : super(type: ComponentType.selectMenu); /// ### Created a input text field /// @@ -19,7 +19,7 @@ class ModalBuilder extends Component { /// .addInput(customId: 'my_text', label: 'Premier texte'); /// ``` ModalBuilder addInput ({ required String customId, required String label, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { - _addInput(customId: customId, label: label, style: TextInputStyle.short, required: required, minLength: minLength, maxLength: maxLength, placeholder: placeholder, value: value); + _addInput(customId: customId, label: label, style: TextInputStyle.input, required: required, minLength: minLength, maxLength: maxLength, placeholder: placeholder, value: value); return this; } @@ -36,7 +36,9 @@ class ModalBuilder extends Component { } void _addInput ({ required String customId, required String label, required TextInputStyle style, bool? required, int? minLength, int? maxLength, String? placeholder, String? value }) { - TextInput input = TextInput( + components ??= []; + + final TextInputBuilder input = TextInputBuilder( customId: customId, label: label, style: style, @@ -47,7 +49,7 @@ class ModalBuilder extends Component { value: value, ); - components.add(RowBuilder(components: [input])); + components?.add(RowBuilder(components: [input])); } @override @@ -55,7 +57,7 @@ class ModalBuilder extends Component { return { 'title': label, 'custom_id': customId, - 'components': components.map((component) => component.toJson()).toList() + 'components': components?.map((component) => component.toJson()).toList() }; } } diff --git a/lib/src/api/components/text_input.dart b/lib/src/api/components/text_input_builder.dart similarity index 87% rename from lib/src/api/components/text_input.dart rename to lib/src/api/components/text_input_builder.dart index e05c40bc..6c854845 100644 --- a/lib/src/api/components/text_input.dart +++ b/lib/src/api/components/text_input_builder.dart @@ -1,7 +1,7 @@ import 'package:mineral/src/api/components/component.dart'; enum TextInputStyle { - short(1), + input(1), paragraph(2); final int value; @@ -11,23 +11,23 @@ enum TextInputStyle { String toString () => value.toString(); } -class TextInput extends Component { +class TextInputBuilder extends Component { String customId; String label; TextInputStyle style; int? minLength; int? maxLength; - bool required; + bool required = false; String? placeholder; String? value; - TextInput({ + TextInputBuilder({ required this.customId, required this.label, required this.style, this.minLength, this.maxLength, - required this.required, + this.required = false, this.placeholder, this.value, }) : super(type: ComponentType.textInput); From 6f52d6aac68a432aef51458397e76eb899d1b922 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 12:36:05 +0200 Subject: [PATCH 09/15] refactor: Improve RowBuilder DX --- lib/src/api/components/row_builder.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/src/api/components/row_builder.dart b/lib/src/api/components/row_builder.dart index 0b710e73..0f183349 100644 --- a/lib/src/api/components/row_builder.dart +++ b/lib/src/api/components/row_builder.dart @@ -1,3 +1,4 @@ +import 'package:mineral/api.dart'; import 'package:mineral/src/api/components/component.dart'; class RowBuilder extends Component { @@ -13,7 +14,11 @@ class RowBuilder extends Component { }; } - factory RowBuilder.from({ required dynamic payload }) { - return RowBuilder(); + factory RowBuilder.fromComponents(List components) { + return RowBuilder(components: components); + } + + factory RowBuilder.fromTextInput(TextInputBuilder input) { + return RowBuilder(components: [input]); } } From bc62b912868f1c858c6d77979c84b1e3dd68f871 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 13:24:27 +0200 Subject: [PATCH 10/15] feat: Change emogi builder, bind parameter and improve missing method error message --- .../api/components/select_menu_builder.dart | 6 ++++-- lib/src/api/interactions/interaction.dart | 14 ++++++++++++- .../exceptions/missing_method_exception.dart | 20 +++++++++++++++++++ lib/src/internal/entities/command.dart | 3 ++- .../internal/managers/command_manager.dart | 9 +++++---- .../packets/interaction_create.dart | 14 +++++++++++-- 6 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 lib/src/exceptions/missing_method_exception.dart diff --git a/lib/src/api/components/select_menu_builder.dart b/lib/src/api/components/select_menu_builder.dart index e661a56a..5e194bdd 100644 --- a/lib/src/api/components/select_menu_builder.dart +++ b/lib/src/api/components/select_menu_builder.dart @@ -11,6 +11,8 @@ class SelectMenuBuilder extends Component { SelectMenuBuilder({ required this.customId, required this.options, this.placeholder, this.minValues, this.maxValues, this.disabled }) : super (type: ComponentType.selectMenu); + RowBuilder toRow () => RowBuilder.fromComponents([this]); + @override Object toJson () { return { @@ -43,7 +45,7 @@ class SelectMenuOption { String label; String description; T value; - EmojiOption? emoji; + EmojiBuilder? emoji; SelectMenuOption({ required this.label, required this.description, required this.value, this.emoji }); @@ -52,7 +54,7 @@ class SelectMenuOption { 'label': label, 'description': description, 'value': value, - 'emoji': emoji?.toJson(), + 'emoji': emoji?.emoji.toJson(), }; } } diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 28f08dd1..f3f84003 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -1,5 +1,8 @@ import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; +import 'package:http/http.dart'; + +import 'dart:convert'; enum InteractionCallbackType { pong(1), @@ -57,8 +60,15 @@ class Interaction { componentList.add(element.toJson()); } } + print(jsonEncode({ + 'tts': tts ?? false, + 'content': content, + 'embeds': embeds != null ? embedList : [], + 'components': components != null ? componentList : [], + 'flags': private != null && private == true ? 1 << 6 : null, + })); - await http.post(url: "/interactions/$id/$token/callback", payload: { + Response r = await http.post(url: "/interactions/$id/$token/callback", payload: { 'type': InteractionCallbackType.channelMessageWithSource.value, 'data': { 'tts': tts ?? false, @@ -68,6 +78,8 @@ class Interaction { 'flags': private != null && private == true ? 1 << 6 : null, } }); + + print(r.body); } /// ### Responds to this by an [Modal] diff --git a/lib/src/exceptions/missing_method_exception.dart b/lib/src/exceptions/missing_method_exception.dart new file mode 100644 index 00000000..1abd6a41 --- /dev/null +++ b/lib/src/exceptions/missing_method_exception.dart @@ -0,0 +1,20 @@ +import 'package:mineral/console.dart'; +import 'package:mineral/core.dart'; +import 'package:mineral/src/internal/managers/reporter_manager.dart'; + +class MissingMethodException implements Exception { + String prefix = 'Missing method'; + String cause; + + MissingMethodException({ required this.cause }); + + @override + String toString () { + ReporterManager? reporter = ioc.singleton(ioc.services.reporter); + if (reporter != null) { + reporter.write('[ $prefix ] $cause'); + } + + return Console.getErrorMessage(prefix: prefix, message: cause); + } +} diff --git a/lib/src/internal/entities/command.dart b/lib/src/internal/entities/command.dart index 9f0e0e4d..489df60d 100644 --- a/lib/src/internal/entities/command.dart +++ b/lib/src/internal/entities/command.dart @@ -32,8 +32,9 @@ class Subcommand { final String description; final int type = 1; final String? group; + final String? bind; - const Subcommand ({ required this.name, required this.description, this.group }); + const Subcommand ({ required this.name, required this.description, this.group, this.bind }); } diff --git a/lib/src/internal/managers/command_manager.dart b/lib/src/internal/managers/command_manager.dart index 2d11c58f..3f1befad 100644 --- a/lib/src/internal/managers/command_manager.dart +++ b/lib/src/internal/managers/command_manager.dart @@ -12,6 +12,7 @@ class CommandManager { Map getHandlers () => _handlers; dynamic getHandler (String handler) => _handlers[handler]; + dynamic get handlers => _handlers; CommandManager add (MineralCommand mineralCommand) { SlashCommand command = SlashCommand(name: '', description: '', scope: '', everyone: true, dmChannel: false, options: []); @@ -62,7 +63,7 @@ class CommandManager { if (reflectee is CommandGroup) { SlashCommand group = SlashCommand(name: '', description: '', scope: '', everyone: true, dmChannel: false, options: []) ..type = 2 - ..name = reflectee.name.toLowerCase() + ..name = reflectee.name.snakeCase ..description = reflectee.description; command.groups.add(group); @@ -106,23 +107,23 @@ class CommandManager { if (reflectee is Subcommand) { String? groupName = reflectee.group; + String? bind = reflectee.bind; if (groupName != null) { SlashCommand group = command.groups.firstWhere((group) => group.name == groupName); group.subcommands.add(subcommand); _handlers.putIfAbsent("${command.name}.${group.name}.${subcommand.name}", () => { - 'symbol': Symbol(subcommand.name), + 'symbol': Symbol(bind ?? subcommand.name), 'commandClass': classCommand, }); } else { command.subcommands.add(subcommand); _handlers.putIfAbsent("${command.name}.${subcommand.name}", () => { - 'symbol': Symbol(subcommand.name), + 'symbol': Symbol(bind ?? subcommand.name), 'commandClass': classCommand, }); } - } if (reflectee is Option) { diff --git a/lib/src/internal/websockets/packets/interaction_create.dart b/lib/src/internal/websockets/packets/interaction_create.dart index 9b7d5d28..f902f702 100644 --- a/lib/src/internal/websockets/packets/interaction_create.dart +++ b/lib/src/internal/websockets/packets/interaction_create.dart @@ -5,6 +5,7 @@ import 'package:http/http.dart'; import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; import 'package:mineral/src/api/components/component.dart'; +import 'package:mineral/src/exceptions/missing_method_exception.dart'; import 'package:mineral/src/internal/managers/command_manager.dart'; import 'package:mineral/src/internal/managers/context_menu_manager.dart'; import 'package:mineral/src/internal/managers/event_manager.dart'; @@ -68,6 +69,7 @@ class InteractionCreate implements WebsocketPacket { walk (List objects) { for (dynamic object in objects) { if (object['type'] == 1 || object['type'] == 2) { + print(object); identifier += ".${object['name']}"; if (object['options'] != null) { walk(object['options']); @@ -82,8 +84,16 @@ class InteractionCreate implements WebsocketPacket { walk(payload['data']['options']); } - dynamic handle = manager.getHandler(identifier); - reflect(handle['commandClass']).invoke(handle['symbol'], [commandInteraction]); + final handle = manager.getHandler(identifier); + + try { + reflect(handle['commandClass']).invoke(handle['symbol'], [commandInteraction]); + } catch (err) { + final String command = identifier.split('.').first; + final String method = identifier.split('.').last; + + throw MissingMethodException(cause: 'The "$method" method does not exist on the "$command" command, please associate a valid method to your command or use the bind parameter of your subcommand'); + } } _executeContextMenuInteraction (Guild guild, GuildMember member, dynamic payload) async { From 203ea33cfb1e3e8f051353b0c2733e382ad4d9b1 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 13:25:39 +0200 Subject: [PATCH 11/15] refactor: Remove prints --- lib/src/api/interactions/interaction.dart | 14 +------------- .../websockets/packets/interaction_create.dart | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index f3f84003..28f08dd1 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -1,8 +1,5 @@ import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; -import 'package:http/http.dart'; - -import 'dart:convert'; enum InteractionCallbackType { pong(1), @@ -60,15 +57,8 @@ class Interaction { componentList.add(element.toJson()); } } - print(jsonEncode({ - 'tts': tts ?? false, - 'content': content, - 'embeds': embeds != null ? embedList : [], - 'components': components != null ? componentList : [], - 'flags': private != null && private == true ? 1 << 6 : null, - })); - Response r = await http.post(url: "/interactions/$id/$token/callback", payload: { + await http.post(url: "/interactions/$id/$token/callback", payload: { 'type': InteractionCallbackType.channelMessageWithSource.value, 'data': { 'tts': tts ?? false, @@ -78,8 +68,6 @@ class Interaction { 'flags': private != null && private == true ? 1 << 6 : null, } }); - - print(r.body); } /// ### Responds to this by an [Modal] diff --git a/lib/src/internal/websockets/packets/interaction_create.dart b/lib/src/internal/websockets/packets/interaction_create.dart index f902f702..e31a9686 100644 --- a/lib/src/internal/websockets/packets/interaction_create.dart +++ b/lib/src/internal/websockets/packets/interaction_create.dart @@ -69,7 +69,6 @@ class InteractionCreate implements WebsocketPacket { walk (List objects) { for (dynamic object in objects) { if (object['type'] == 1 || object['type'] == 2) { - print(object); identifier += ".${object['name']}"; if (object['options'] != null) { walk(object['options']); From 455f371484bd768aff4a0106aeb5d4264bbe8044 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 13:42:09 +0200 Subject: [PATCH 12/15] feat: Improve Buttons DX and change label required --- lib/src/api/components/button_builder.dart | 4 ++-- lib/src/api/interactions/interaction.dart | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/src/api/components/button_builder.dart b/lib/src/api/components/button_builder.dart index 8abfd6c8..379a62b2 100644 --- a/lib/src/api/components/button_builder.dart +++ b/lib/src/api/components/button_builder.dart @@ -17,12 +17,12 @@ enum ButtonStyle { class ButtonBuilder extends Component { String customId; - String label; + String? label; ButtonStyle style; EmojiBuilder? emoji; bool disabled; - ButtonBuilder({ required this.customId, required this.label, required this.style, this.emoji, this.disabled = false }) : super(type: ComponentType.button); + ButtonBuilder({ required this.customId, this.label, required this.style, this.emoji, this.disabled = false }) : super(type: ComponentType.button); @override dynamic toJson () { diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 28f08dd1..80dab07b 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; @@ -58,7 +60,15 @@ class Interaction { } } - await http.post(url: "/interactions/$id/$token/callback", payload: { +print(jsonEncode({ + 'tts': tts ?? false, + 'content': content, + 'embeds': embeds != null ? embedList : [], + 'components': components != null ? componentList : [], + 'flags': private != null && private == true ? 1 << 6 : null, +})); + + final r = await http.post(url: "/interactions/$id/$token/callback", payload: { 'type': InteractionCallbackType.channelMessageWithSource.value, 'data': { 'tts': tts ?? false, @@ -68,6 +78,8 @@ class Interaction { 'flags': private != null && private == true ? 1 << 6 : null, } }); + + print(r.body); } /// ### Responds to this by an [Modal] From f41ac5a4b2d4c2d3ecffb802a42f17b0aaa46131 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 13:46:16 +0200 Subject: [PATCH 13/15] refactor: Remove prints --- lib/src/api/interactions/interaction.dart | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/src/api/interactions/interaction.dart b/lib/src/api/interactions/interaction.dart index 80dab07b..28f08dd1 100644 --- a/lib/src/api/interactions/interaction.dart +++ b/lib/src/api/interactions/interaction.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:mineral/api.dart'; import 'package:mineral/core.dart'; @@ -60,15 +58,7 @@ class Interaction { } } -print(jsonEncode({ - 'tts': tts ?? false, - 'content': content, - 'embeds': embeds != null ? embedList : [], - 'components': components != null ? componentList : [], - 'flags': private != null && private == true ? 1 << 6 : null, -})); - - final r = await http.post(url: "/interactions/$id/$token/callback", payload: { + await http.post(url: "/interactions/$id/$token/callback", payload: { 'type': InteractionCallbackType.channelMessageWithSource.value, 'data': { 'tts': tts ?? false, @@ -78,8 +68,6 @@ print(jsonEncode({ 'flags': private != null && private == true ? 1 << 6 : null, } }); - - print(r.body); } /// ### Responds to this by an [Modal] From a1770aa0dd3652f39e7be9dfa32465b70adbd55e Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 14:07:31 +0200 Subject: [PATCH 14/15] refactor: Change to factory --- lib/src/api/components/modal_builder.dart | 3 +-- lib/src/api/components/row_builder.dart | 14 +++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/src/api/components/modal_builder.dart b/lib/src/api/components/modal_builder.dart index a3ea2170..6b98cb18 100644 --- a/lib/src/api/components/modal_builder.dart +++ b/lib/src/api/components/modal_builder.dart @@ -1,5 +1,4 @@ import 'package:mineral/src/api/components/component.dart'; -import 'package:mineral/src/api/components/text_input_builder.dart'; import '../../../api.dart'; @@ -49,7 +48,7 @@ class ModalBuilder extends Component { value: value, ); - components?.add(RowBuilder(components: [input])); + components?.add(RowBuilder.fromComponents([input])); } @override diff --git a/lib/src/api/components/row_builder.dart b/lib/src/api/components/row_builder.dart index 0f183349..8f304448 100644 --- a/lib/src/api/components/row_builder.dart +++ b/lib/src/api/components/row_builder.dart @@ -2,23 +2,27 @@ import 'package:mineral/api.dart'; import 'package:mineral/src/api/components/component.dart'; class RowBuilder extends Component { - List? components = []; + List components = []; - RowBuilder({ this.components }) : super(type: ComponentType.actionRow); + RowBuilder() : super(type: ComponentType.actionRow); @override Object toJson () { return { 'type': type.value, - 'components': components?.map((Component component) => component.toJson()).toList() + 'components': components.map((Component component) => component.toJson()).toList() }; } factory RowBuilder.fromComponents(List components) { - return RowBuilder(components: components); + return RowBuilder.fromComponents(components); + } + + factory RowBuilder.fromComponent(Component component) { + return RowBuilder.fromComponents([component]); } factory RowBuilder.fromTextInput(TextInputBuilder input) { - return RowBuilder(components: [input]); + return RowBuilder.fromComponents([input]); } } From 3e36138bfdeec0f54f2385ed41b459794978d217 Mon Sep 17 00:00:00 2001 From: Freeze455 Date: Mon, 22 Aug 2022 14:36:23 +0200 Subject: [PATCH 15/15] refactor: Move get() to get dart method --- lib/src/api/client/mineral_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/api/client/mineral_client.dart b/lib/src/api/client/mineral_client.dart index f5f4d72e..d457479d 100644 --- a/lib/src/api/client/mineral_client.dart +++ b/lib/src/api/client/mineral_client.dart @@ -98,7 +98,7 @@ class MineralClient { List get intents => _intents; /// ### Returns the time the [MineralClient] is online - Duration getUptimeDuration () => DateTime.now().difference(uptime); + Duration get uptimeDuration => DateTime.now().difference(uptime); /// ### Defines the presence that this should adopt ///