Skip to content

Commit

Permalink
Merge pull request #362 from nyxx-discord/next
Browse files Browse the repository at this point in the history
Release 4.0.0
  • Loading branch information
l7ssha authored Jul 29, 2022
2 parents 5e1c53f + 903d114 commit 509a8db
Show file tree
Hide file tree
Showing 59 changed files with 2,100 additions and 603 deletions.
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
## 4.0.0
___29.07.2022__

- breaking: Fix typo in `IHttpResponseSucess`
- breaking: Remove `threeDayThreadArchive` and `sevenDayThreadArchive` guild features
- breaking: Remove all deprecated members
- bug: Fix ratelimiting
- breaking: All calls to the API are now made via `IHttpRoute`s instead of `String`s.
- Construct routes by creating an `IHttpRoute()` and `add`ing `HttpRoutePart`s or by calling the helper methods on the route.
- feature: Move to Gateway & API v10
- Added the Message Content privileged intent
- feature: Add guild Audit Log options
- feature: Implement forum channels
- feature: Implement guild Welcome Screen & Channel
- feature: Add missing Audit log types
- feature: Implement guild Banners
- feature: Implement partial presences
- feature: Add missing guild properties
- feature: Add missing reaction endpoints
- feature: Handle websocket disconnections
- feature: Implement clean client shutdown
- feature: Add `limitLength` to `MessageBuilder`
- feature: Add paginated bans
- feature: Remove dollar prefix for identify payload (#361)
- bug: Fix mention string, and use a better approach to retrieve everyone role (#360)
- bug: Fix incorrect guild URLs
- bug: Fix incorrect file encoding
- bug: Fix member editing
- bug: Fix serialization issues
- bug: Fix uninitialized fields

## 4.0.0-dev.2
__12.06.2022__

- feature: Add missing emoji endpoints (#346)
- feature: Add `threadName` on `IWebhook#execute()` (#348)
- feature: Implement graceful shutdown (#347)
- feature: Implement forum channels (#332)
- feature: Implement Dynamic Bucket Rate Limits (#316)
- feature: Implement paginated bans (#326)
- feature: Implement missing guild properties
- bug: Fixed disconnecting user from voice
- bug: failed to edit guild members (#328)
- bug: Invalid serialization of query params (#352)
- bug: Fix some serialization bugs (#351)

## 4.0.0-dev.1
__09.05.2022__

- feature: Handle no internet on websocket (#321)
- bug: Remove Error form IHttpResponseError (#324)
- Fixup field names on IHttpResponseError
- Fixup IHttpResponseSuccess name
- feature: Move to API v10 (#325)

## 4.0.0-dev.0
__31.03.2022__

- feature: Fix target id property and add guild audit logs options (#307)

## 3.4.2
__22.04.2022__

Expand Down
13 changes: 11 additions & 2 deletions lib/nyxx.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ export "src/core/application/oauth2_application.dart" show IOAuth2Application;
export 'src/core/audit_logs/audit_log.dart' show IAuditLog;
export 'src/core/audit_logs/audit_log_change.dart' show ChangeKeyType, IAuditLogChange;
export 'src/core/audit_logs/audit_log_entry.dart' show IAuditLogEntry, AuditLogEntryType;
export 'src/core/audit_logs/audit_log_options.dart' show IAuditLogOptions;
export 'src/core/channel/cacheable_text_channel.dart' show ICacheableTextChannel;
export 'src/core/channel/channel.dart' show IChannel, ChannelType;
export 'src/core/channel/dm_channel.dart' show IDMChannel;
export 'src/core/channel/text_channel.dart' show ITextChannel;
export 'src/core/channel/guild/forum/forum_channel.dart' show IForumChannel;
export 'src/core/channel/guild/forum/forum_tag.dart' show IForumTag;
export 'src/core/channel/thread_channel.dart' show IThreadMember, IThreadChannel;
export 'src/core/channel/thread_preview_channel.dart' show IThreadPreviewChannel;
export 'src/core/channel/guild/activity_types.dart' show VoiceActivityType;
Expand All @@ -46,6 +49,8 @@ export 'src/core/guild/premium_tier.dart' show PremiumTier;
export 'src/core/guild/role.dart' show IRole, IRoleTags;
export 'src/core/guild/status.dart' show IClientStatus, UserStatus;
export 'src/core/guild/webhook.dart' show IWebhook, WebhookType;
export 'src/core/guild/guild_welcome_screen.dart' show IGuildWelcomeScreen, IGuildWelcomeChannel;
export 'src/core/guild/system_channel_flags.dart' show SystemChannelFlags;
export 'src/core/message/attachment.dart' show IAttachment;
export 'src/core/message/emoji.dart' show IEmoji;
export 'src/core/message/guild_emoji.dart' show IBaseGuildEmoji, IGuildEmoji, IGuildEmojiPartial, IResolvableGuildEmojiPartial;
Expand Down Expand Up @@ -77,7 +82,7 @@ export 'src/core/permissions/permissions_constants.dart' show PermissionsConstan
export 'src/core/user/member.dart' show IMember;
export 'src/core/user/nitro_type.dart' show NitroType;
export 'src/core/user/presence.dart'
show IActivity, IActivityEmoji, IActivityFlags, IActivityParty, IActivityTimestamps, IGameAssets, IGameSecrets, ActivityType;
show IActivity, IActivityEmoji, IActivityFlags, IActivityParty, IActivityTimestamps, IGameAssets, IGameSecrets, ActivityType, IPartialPresence;
export 'src/core/user/user.dart' show IUser;
export 'src/core/user/user_flags.dart' show IUserFlags;
export 'src/core/voice/voice_region.dart' show IVoiceRegion;
Expand Down Expand Up @@ -137,7 +142,10 @@ export 'src/internal/exceptions/invalid_shard_exception.dart' show InvalidShardE
export 'src/internal/exceptions/invalid_snowflake_exception.dart' show InvalidSnowflakeException;
export 'src/internal/exceptions/missing_token_error.dart' show MissingTokenError;
export 'src/internal/exceptions/unrecoverable_nyxx_error.dart' show UnrecoverableNyxxError;
export 'src/internal/http/http_response.dart' show IHttpResponse, IHttpResponseError, IHttpResponseSucess;
export 'src/internal/http/http_route_param.dart' show HttpRouteParam;
export 'src/internal/http/http_route_part.dart' show HttpRoutePart;
export 'src/internal/http/http_route.dart' show IHttpRoute;
export 'src/internal/http/http_response.dart' show IHttpResponse, IHttpResponseError, IHttpResponseSuccess;
export 'src/internal/interfaces/convertable.dart' show Convertable;
export 'src/internal/interfaces/disposable.dart' show Disposable;
export 'src/internal/interfaces/message_author.dart' show IMessageAuthor;
Expand All @@ -164,6 +172,7 @@ export 'src/utils/builders/reply_builder.dart' show ReplyBuilder;
export 'src/utils/builders/sticker_builder.dart' show StickerBuilder;
export 'src/utils/builders/thread_builder.dart' show ThreadArchiveTime, ThreadBuilder;
export 'src/utils/builders/guild_event_builder.dart' show GuildEventBuilder;
export 'src/utils/builders/forum_thread_builder.dart' show ForumThreadBuilder;
export 'src/utils/extensions.dart' show IntExtensions, SnowflakeEntityListExtensions, StringExtensions;
export 'src/utils/permissions.dart' show PermissionsUtils;
export 'src/utils/utils.dart' show ListSafeFirstWhere;
Expand Down
7 changes: 6 additions & 1 deletion lib/src/client_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ class GatewayIntents {
/// Includes events: `TYPING_START`
static const int directMessageTyping = 1 << 14;

/// Includes public content of messages in guilds (content, embeds, attachments, components)
/// If your bot is mentioned it will always receive full message
/// If you are not opted in for message content intent you will receive empty fields
static const int messageContent = 1 << 15;

/// Includes events: `GUILD_SCHEDULED_EVENT_CREATE`, `GUILD_SCHEDULED_EVENT_DELETE`, `GUILD_SCHEDULED_EVENT_UPDATE`, `GUILD_SCHEDULED_EVENT_USER_ADD`, `GUILD_SCHEDULED_EVENT_USER_REMOVE`
static const int guildScheduledEvents = 1 << 16;

Expand All @@ -153,7 +158,7 @@ class GatewayIntents {
guildScheduledEvents;

/// All privileged intents
static const int allPrivileged = guildMembers | guildPresences;
static const int allPrivileged = guildMembers | guildPresences | messageContent;

/// All intents
static const int all = allUnprivileged | allPrivileged;
Expand Down
1 change: 0 additions & 1 deletion lib/src/core/application/app_team_user.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:nyxx/nyxx.dart';
import 'package:nyxx/src/core/snowflake.dart';
import 'package:nyxx/src/core/snowflake_entity.dart';
import 'package:nyxx/src/typedefs.dart';
Expand Down
28 changes: 24 additions & 4 deletions lib/src/core/audit_logs/audit_log_entry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:nyxx/src/core/user/user.dart';
import 'package:nyxx/src/internal/cache/cacheable.dart';
import 'package:nyxx/src/typedefs.dart';
import 'package:nyxx/src/utils/enum.dart';
import 'package:nyxx/src/core/audit_logs/audit_log_options.dart';

abstract class IAuditLogEntry implements SnowflakeEntity {
/// Id of the affected entity (webhook, user, role, etc.)
Expand All @@ -21,7 +22,7 @@ abstract class IAuditLogEntry implements SnowflakeEntity {
AuditLogEntryType get type;

/// Additional info for certain action types
String? get options;
IAuditLogOptions? get options;

/// The reason for the change
String? get reason;
Expand Down Expand Up @@ -49,15 +50,15 @@ class AuditLogEntry extends SnowflakeEntity implements IAuditLogEntry {

/// Additional info for certain action types
@override
late final String? options;
late final IAuditLogOptions? options;

/// The reason for the change
@override
late final String? reason;

/// Creates an instance of [AuditLogEntry]
AuditLogEntry(RawApiMap raw, INyxx client) : super(Snowflake(raw["id"] as String)) {
targetId = raw["targetId"] as String;
targetId = raw["target_id"] as String;

changes = [
if (raw["changes"] != null)
Expand All @@ -67,7 +68,11 @@ class AuditLogEntry extends SnowflakeEntity implements IAuditLogEntry {
user = UserCacheable(client, Snowflake(raw["user_id"]));
type = AuditLogEntryType._create(raw["action_type"] as int);

options = raw["options"] as String?;
if (raw["options"] != null) {
options = AuditLogOptions(raw["options"] as RawApiMap);
} else {
options = null;
}

reason = raw["reason"] as String?;
}
Expand All @@ -87,6 +92,9 @@ class AuditLogEntryType extends IEnum<int> {
static const AuditLogEntryType memberBanRemove = AuditLogEntryType._create(23);
static const AuditLogEntryType memberUpdate = AuditLogEntryType._create(24);
static const AuditLogEntryType memberRoleUpdate = AuditLogEntryType._create(25);
static const AuditLogEntryType memberMove = AuditLogEntryType._create(26);
static const AuditLogEntryType memberDisconnect = AuditLogEntryType._create(27);
static const AuditLogEntryType botAdd = AuditLogEntryType._create(28);
static const AuditLogEntryType roleCreate = AuditLogEntryType._create(30);
static const AuditLogEntryType roleUpdate = AuditLogEntryType._create(31);
static const AuditLogEntryType roleDelete = AuditLogEntryType._create(32);
Expand All @@ -106,6 +114,18 @@ class AuditLogEntryType extends IEnum<int> {
static const AuditLogEntryType integrationCreate = AuditLogEntryType._create(80);
static const AuditLogEntryType integrationUpdate = AuditLogEntryType._create(81);
static const AuditLogEntryType integrationDelete = AuditLogEntryType._create(82);
static const AuditLogEntryType stageInstanceCreate = AuditLogEntryType._create(83);
static const AuditLogEntryType stageInstanceUpdate = AuditLogEntryType._create(84);
static const AuditLogEntryType stageInstanceDelete = AuditLogEntryType._create(85);
static const AuditLogEntryType stickerCreate = AuditLogEntryType._create(90);
static const AuditLogEntryType stickerUpdate = AuditLogEntryType._create(91);
static const AuditLogEntryType stickerDelete = AuditLogEntryType._create(92);
static const AuditLogEntryType guildScheduledEventCreate = AuditLogEntryType._create(100);
static const AuditLogEntryType guildScheduledEventUpdate = AuditLogEntryType._create(101);
static const AuditLogEntryType guildScheduledEventDelete = AuditLogEntryType._create(102);
static const AuditLogEntryType threadCreate = AuditLogEntryType._create(110);
static const AuditLogEntryType threadUpdate = AuditLogEntryType._create(111);
static const AuditLogEntryType threadDelete = AuditLogEntryType._create(112);

const AuditLogEntryType._create(int value) : super(value);

Expand Down
90 changes: 90 additions & 0 deletions lib/src/core/audit_logs/audit_log_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import 'package:nyxx/nyxx.dart';

/// Additionnal info for certain action types
///
/// [Look here for more](https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events)
abstract class IAuditLogOptions {
/// The channel in which the entites were targeted.
Snowflake? get channelId;

/// The number of entities targeted.
int? get count;

/// The number of days after which inactive users will be kicked.
Duration? get deleteMemberDuration;

/// Id of the overwritten entity.
Snowflake? get id;

/// The number of the members removed by the prune.
int? get pruneCount;

/// The id of the message that was targeted.
Snowflake? get messageId;

/// The name of the role that was targeted. (Not present if [overwrittenType] is `member`).
String? get roleName;

/// Type of overwritten entity.
/// One of:
/// - `role`
/// - `member`
String? get overwrittenType;
}

class AuditLogOptions implements IAuditLogOptions {
/// The channel in which the entites were targeted.
@override
late final Snowflake? channelId;

/// The number of entities targeted.
@override
late final int? count;

/// The number of days after which inactive users will be kicked.
@override
late final Duration? deleteMemberDuration;

/// Id of the overwritten entity.
@override
late final Snowflake? id;

/// The number of the members removed by the prune.
@override
late final int? pruneCount;

/// The id of the message that was targeted.
@override
late final Snowflake? messageId;

/// The name of the role that was targeted. (Not present if [overwrittenType] is `member`).
@override
late final String? roleName;

/// Type of overwritten entity.
/// One of:
/// - `role`
/// - `member`
@override
late final String? overwrittenType;

AuditLogOptions(RawApiMap raw) {
channelId = (raw['channel_id'] as String?)?.toSnowflake();
count = raw['count'] != null ? int.parse(raw['count'] as String) : null;
deleteMemberDuration = (raw['delete_member_days'] as String?) != null ? Duration(days: int.parse(raw['delete_member_days'] as String)) : null;
id = (raw['id'] as String?)?.toSnowflake();
pruneCount = (raw['members_removed'] as String?) != null ? int.parse(raw['members_removed'] as String) : null;
messageId = (raw['message_id'] as String?)?.toSnowflake();
roleName = raw['role_name'] as String?;
switch (raw['type']) {
case '0':
overwrittenType = 'role';
break;
case '1':
overwrittenType = 'member';
break;
default:
overwrittenType = null;
}
}
}
5 changes: 5 additions & 0 deletions lib/src/core/channel/channel.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:nyxx/src/core/channel/guild/forum/forum_channel.dart';
import 'package:nyxx/src/nyxx.dart';
import 'package:nyxx/src/core/snowflake.dart';
import 'package:nyxx/src/core/snowflake_entity.dart';
Expand Down Expand Up @@ -63,6 +64,8 @@ abstract class Channel extends SnowflakeEntity implements IChannel {
return ThreadChannel(client, raw);
case 13:
return StageVoiceGuildChannel(client, raw, guildId);
case 15:
return ForumChannel(client, raw, guildId);
default:
return _InternalChannel._new(client, raw, guildId);
}
Expand Down Expand Up @@ -100,6 +103,8 @@ class ChannelType extends IEnum<int> {
/// Channel in a Student Hub containing the listed servers
static const ChannelType guildDirectory = ChannelType._create(14);

static const ChannelType forumChannel = ChannelType._create(15);

/// Type of channel is unknown
static const ChannelType unknown = ChannelType._create(1337);

Expand Down
60 changes: 60 additions & 0 deletions lib/src/core/channel/guild/forum/forum_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:nyxx/src/core/channel/guild/forum/forum_tag.dart';
import 'package:nyxx/src/core/channel/guild/guild_channel.dart';
import 'package:nyxx/src/core/channel/thread_channel.dart';
import 'package:nyxx/src/core/channel/thread_preview_channel.dart';
import 'package:nyxx/src/core/snowflake.dart';
import 'package:nyxx/src/internal/interfaces/mentionable.dart';
import 'package:nyxx/src/internal/response_wrapper/thread_list_result_wrapper.dart';
import 'package:nyxx/src/nyxx.dart';
import 'package:nyxx/src/typedefs.dart';
import 'package:nyxx/src/utils/builders/forum_thread_builder.dart';

abstract class IForumChannel implements IGuildChannel, Mentionable {
/// Tags available to assign to forum posts
List<IForumTag> get availableTags;

/// Creates a thread in a channel, that only retrieves a [ThreadPreviewChannel]
Future<IThreadChannel> createThread(ForumThreadBuilder builder);

/// Fetches joined private and archived thread channels
Future<IThreadListResultWrapper> fetchJoinedPrivateArchivedThreads({DateTime? before, int? limit});

/// Fetches private, archived thread channels
Future<IThreadListResultWrapper> fetchPrivateArchivedThreads({DateTime? before, int? limit});

/// Fetches public, archives thread channels
Future<IThreadListResultWrapper> fetchPublicArchivedThreads({DateTime? before, int? limit});
}

class ForumChannel extends GuildChannel implements IForumChannel {
@override
late final List<IForumTag> availableTags;

/// Creates an instance of [TextGuildChannel]
ForumChannel(INyxx client, RawApiMap raw, [Snowflake? guildId]) : super(client, raw, guildId) {
availableTags = (raw['available_tags'] as List<dynamic>).cast<RawApiMap>().map((e) => ForumTag(e)).toList();
}

/// The channel's mention string.
@override
String get mention => "<#$id>";

/// Creates a thread in a channel, that only retrieves a [ThreadPreviewChannel]
@override
Future<IThreadChannel> createThread(ForumThreadBuilder builder) => client.httpEndpoints.startForumThread(id, builder);

/// Fetches joined private and archived thread channels
@override
Future<IThreadListResultWrapper> fetchJoinedPrivateArchivedThreads({DateTime? before, int? limit}) =>
client.httpEndpoints.fetchJoinedPrivateArchivedThreads(id, before: before, limit: limit);

/// Fetches private, archived thread channels
@override
Future<IThreadListResultWrapper> fetchPrivateArchivedThreads({DateTime? before, int? limit}) =>
client.httpEndpoints.fetchPrivateArchivedThreads(id, before: before, limit: limit);

/// Fetches public, archives thread channels
@override
Future<IThreadListResultWrapper> fetchPublicArchivedThreads({DateTime? before, int? limit}) =>
client.httpEndpoints.fetchPublicArchivedThreads(id, before: before, limit: limit);
}
Loading

0 comments on commit 509a8db

Please sign in to comment.