Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Todos #498

Merged
merged 43 commits into from
Jun 23, 2023
Merged

Todos #498

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1ac1230
Add missing fields in GuildBuilder
abitofevrything Jun 18, 2023
1e5bed3
Make repliedUser nullable in allowed_mentions
abitofevrything Jun 18, 2023
b6a9ad6
Add missing activities field to PresenceBuilder
abitofevrything Jun 18, 2023
e62ccfa
Add initial presence for gateway
abitofevrything Jun 18, 2023
1e4924b
Handle adding an already existing member to a guild
abitofevrything Jun 18, 2023
8fe9c2a
TThrow an exception when a role is not found
abitofevrything Jun 18, 2023
8b02b65
Remove TODOs that won't be addressed
abitofevrything Jun 18, 2023
e0648ce
Fix guild tests
abitofevrything Jun 18, 2023
971a275
Complete thread member parsing test
abitofevrything Jun 18, 2023
b929b67
Merge branch 'rewrite' of github.com:nyxx-discord/nyxx into todos
abitofevrything Jun 20, 2023
2868aa4
Don't use package imports
abitofevrything Jun 20, 2023
e75730b
Move integrations to their own manager
abitofevrything Jun 20, 2023
e8914ce
Fix issues found by tests
abitofevrything Jun 20, 2023
a38eacf
Merge branch 'rewrite' of github.com:nyxx-discord/nyxx into todos
abitofevrything Jun 20, 2023
33d2a42
Add cache identifier to audit log manager
abitofevrything Jun 20, 2023
312f7c2
Add missing application role connection fieldsd & endpoints
abitofevrything Jun 20, 2023
97ec839
Add globalName to users
abitofevrything Jun 20, 2023
969d923
Add missing user endpoints
abitofevrything Jun 20, 2023
3afc19c
Add warning when force killing shard
abitofevrything Jun 20, 2023
bbfc619
Add warning when shard encounters error
abitofevrything Jun 20, 2023
930b2f2
Add exception when fetching an audit log entry that does not exist
abitofevrything Jun 20, 2023
82c42eb
Make HttpResponseError implement NyxxException
abitofevrything Jun 20, 2023
a795a25
Remove completed TODO in Invite
abitofevrything Jun 20, 2023
cb6527e
Add missing application field to Message
abitofevrything Jun 20, 2023
5a7e102
Merge branch 'rewrite' of github.com:nyxx-discord/nyxx into todos
abitofevrything Jun 20, 2023
5fd29d9
Add missing fields to guild create event
abitofevrything Jun 20, 2023
f2c7a7c
Add emoji to onboarding prompt
abitofevrything Jun 20, 2023
c883ce9
Add cache for VoiceStates
abitofevrything Jun 20, 2023
d006303
Add emojis to GuildPreview
abitofevrything Jun 20, 2023
5199d68
Finish InviteCreateEvent
abitofevrything Jun 20, 2023
c5528db
Add presences to GuildMembersChunkEvent
abitofevrything Jun 20, 2023
397d76e
Add emojis field to GuildEmojisUpdateEvent
abitofevrything Jun 20, 2023
957618f
Parse webhooks as such in message author fields
abitofevrything Jun 20, 2023
9ba4e9c
Fix typo
abitofevrything Jun 20, 2023
b38ff46
Implement the fetch guild vanity url endpoint
abitofevrything Jun 20, 2023
a908967
Change InviteCreateEvent to use InviteWithMetadata
abitofevrything Jun 20, 2023
c6776ae
Add missing channel invite endpoints
abitofevrything Jun 20, 2023
dd20ecf
Remove ban cache
abitofevrything Jun 20, 2023
deecb99
Add back protection against running out of session starts
abitofevrything Jun 20, 2023
eef3cfc
Only ignore exceptions after client is connected
abitofevrything Jun 20, 2023
62b5803
Remove TODOs
abitofevrything Jun 21, 2023
9f718b4
Add emoji field to activities
abitofevrything Jun 21, 2023
c2a3072
Address review comments
abitofevrything Jun 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions lib/nyxx.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
export 'src/api_options.dart' show ApiOptions, RestApiOptions, GatewayApiOptions, GatewayCompression, GatewayPayloadFormat;
export 'src/client.dart' show Nyxx, NyxxRest, NyxxGateway;
export 'src/client_options.dart' show ClientOptions, RestClientOptions, GatewayClientOptions;
export 'src/errors.dart' show NyxxException, InvalidEventException;
export 'src/errors.dart'
show
NyxxException,
InvalidEventException,
MemberAlreadyExistsException,
ShardDisconnectedError,
RoleNotFoundException,
AuditLogEntryNotFoundException,
OutOfRemainingSessionsError;

export 'src/builders/builder.dart' show Builder, CreateBuilder, UpdateBuilder;
export 'src/builders/image.dart' show ImageBuilder;
Expand Down Expand Up @@ -42,8 +50,10 @@ export 'src/builders/guild/auto_moderation.dart' show AutoModerationRuleBuilder,
export 'src/builders/role.dart' show RoleBuilder, RoleUpdateBuilder;
export 'src/builders/voice.dart' show CurrentUserVoiceStateUpdateBuilder, VoiceStateUpdateBuilder, GatewayVoiceStateBuilder;
export 'src/builders/presence.dart' show PresenceBuilder, CurrentUserStatus;
export 'src/builders/application_role_connection.dart' show ApplicationRoleConnectionUpdateBuilder;
export 'src/builders/emoji/emoji.dart' show EmojiBuilder, EmojiUpdateBuilder;
export 'src/builders/emoji/reaction.dart' show ReactionBuilder;
export 'src/builders/invite.dart' show InviteBuilder;

export 'src/cache/cache.dart' show Cache, CacheConfig;

Expand All @@ -66,6 +76,7 @@ export 'src/http/managers/role_manager.dart' show RoleManager;
export 'src/http/managers/gateway_manager.dart' show GatewayManager;
export 'src/http/managers/scheduled_event_manager.dart' show ScheduledEventManager;
export 'src/http/managers/auto_moderation_manager.dart' show AutoModerationManager;
export 'src/http/managers/integration_manager.dart' show IntegrationManager;
export 'src/http/managers/emoji_manager.dart' show EmojiManager;
export 'src/http/managers/audit_log_manager.dart' show AuditLogManager;

Expand Down Expand Up @@ -113,8 +124,8 @@ export 'src/models/message/reaction.dart' show Reaction;
export 'src/models/message/reference.dart' show MessageReference;
export 'src/models/message/role_subscription_data.dart' show RoleSubscriptionData;
export 'src/models/invite/invite.dart' show Invite, TargetType;
export 'src/models/invite/invite_metadata.dart' show InviteMetadata;
export 'src/models/webhook.dart' show PartialWebhook, Webhook, WebhookType;
export 'src/models/invite/invite_metadata.dart' show InviteWithMetadata;
export 'src/models/webhook.dart' show PartialWebhook, Webhook, WebhookType, WebhookAuthor;
export 'src/models/guild/ban.dart' show Ban;
export 'src/models/guild/guild_preview.dart' show GuildPreview;
export 'src/models/guild/guild_widget.dart' show GuildWidget, WidgetSettings, WidgetImageStyle;
Expand All @@ -130,7 +141,7 @@ export 'src/models/guild/guild.dart'
NsfwLevel,
PremiumTier,
VerificationLevel;
export 'src/models/guild/integration.dart' show Integration, IntegrationAccount, IntegrationApplication, IntegrationExpireBehavior;
export 'src/models/guild/integration.dart' show PartialIntegration, Integration, IntegrationAccount, IntegrationApplication, IntegrationExpireBehavior;
export 'src/models/guild/member.dart' show Member, MemberFlags, PartialMember;
export 'src/models/guild/onboarding.dart' show Onboarding, OnboardingPrompt, OnboardingPromptOption, OnboardingPromptType;
export 'src/models/guild/welcome_screen.dart' show WelcomeScreen, WelcomeScreenChannel;
Expand Down
5 changes: 5 additions & 0 deletions lib/src/api_options.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:nyxx/src/builders/presence.dart';
import 'package:nyxx/src/intents.dart';
import 'package:nyxx/src/utils/flags.dart';

Expand Down Expand Up @@ -79,6 +80,9 @@ class GatewayApiOptions extends RestApiOptions {
/// The threshold after which guilds are considered large in the Gateway.
final int? largeThreshold;

/// The presence the client will set after first connecting to the Gateway.
final PresenceBuilder? initialPresence;

/// The query parameters to append to the Gateway connection URL.
Map<String, String> get gatewayConnectionOptions => {
'v': apiVersion.toString(),
Expand All @@ -96,6 +100,7 @@ class GatewayApiOptions extends RestApiOptions {
this.shards,
this.totalShards,
this.largeThreshold,
this.initialPresence,
});
}

Expand Down
20 changes: 20 additions & 0 deletions lib/src/builders/application_role_connection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:nyxx/src/builders/builder.dart';
import 'package:nyxx/src/builders/sentinels.dart';
import 'package:nyxx/src/models/user/application_role_connection.dart';

class ApplicationRoleConnectionUpdateBuilder extends UpdateBuilder<ApplicationRoleConnection> {
final String? platformName;

final String? platformUsername;

final Map<String, String>? metadata;

ApplicationRoleConnectionUpdateBuilder({this.platformName = sentinelString, this.platformUsername = sentinelString, this.metadata});

@override
Map<String, Object?> build() => {
if (!identical(platformName, sentinelString)) 'platform_name': platformName,
if (!identical(platformUsername, sentinelString)) 'platform_username': platformUsername,
if (metadata != null) 'metadata': metadata,
};
}
12 changes: 8 additions & 4 deletions lib/src/builders/guild/guild.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:nyxx/src/builders/builder.dart';
import 'package:nyxx/src/builders/channel/guild_channel.dart';
import 'package:nyxx/src/builders/image.dart';
import 'package:nyxx/src/builders/role.dart';
import 'package:nyxx/src/builders/sentinels.dart';
import 'package:nyxx/src/http/managers/guild_manager.dart';
import 'package:nyxx/src/models/guild/guild.dart';
Expand All @@ -18,11 +20,9 @@ class GuildBuilder extends CreateBuilder<Guild> {

final ExplicitContentFilterLevel? explicitContentFilterLevel;

// TODO
//final List<Role> roles;
final List<RoleBuilder>? roles;

// TODO
//final List<GuildChannel> channels;
final List<GuildChannelBuilder>? channels;

final Snowflake? afkChannelId;

Expand All @@ -38,6 +38,8 @@ class GuildBuilder extends CreateBuilder<Guild> {
this.verificationLevel,
this.defaultMessageNotificationLevel,
this.explicitContentFilterLevel,
this.roles,
this.channels,
this.afkChannelId,
this.afkTimeout,
this.systemChannelId,
Expand All @@ -51,6 +53,8 @@ class GuildBuilder extends CreateBuilder<Guild> {
if (verificationLevel != null) 'verification_level': verificationLevel!.value,
if (defaultMessageNotificationLevel != null) 'default_message_notification_level': defaultMessageNotificationLevel!.value,
if (explicitContentFilterLevel != null) 'explicit_content_filter_level': explicitContentFilterLevel!.value,
if (roles != null) 'roles': roles!.map((b) => b.build()).toList(),
if (channels != null) 'channels': channels!.map((b) => b.build()).toList(),
if (afkChannelId != null) 'afk_channel_id': afkChannelId!.toString(),
if (afkTimeout != null) 'afk_timeout': afkTimeout!.inSeconds,
if (systemChannelId != null) 'system_channel_id': systemChannelId!.toString(),
Expand Down
41 changes: 41 additions & 0 deletions lib/src/builders/invite.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:nyxx/src/builders/builder.dart';
import 'package:nyxx/src/builders/sentinels.dart';
import 'package:nyxx/src/models/invite/invite.dart';
import 'package:nyxx/src/models/snowflake.dart';

class InviteBuilder extends CreateBuilder<Invite> {
final Duration? maxAge;

final int? maxUses;

final bool? isTemporary;

final bool? isUnique;

final TargetType? targetType;

final Snowflake? targetUserId;

final Snowflake? targetApplicationId;

InviteBuilder({
this.maxAge = sentinelDuration,
this.maxUses,
this.isTemporary,
this.isUnique,
this.targetType,
this.targetUserId,
this.targetApplicationId,
});

@override
Map<String, Object?> build() => {
if (!identical(maxAge, sentinelDuration)) 'max_age': maxAge == null ? 0 : maxAge?.inSeconds,
if (maxUses != null) 'max_uses': maxUses,
if (isTemporary != null) 'temporary': isTemporary,
if (isUnique != null) 'unique': isUnique,
if (targetType != null) 'target_type': targetType!.value,
if (targetUserId != null) 'target_user_id': targetUserId!.toString(),
if (targetApplicationId != null) 'target_application_id': targetApplicationId!.toString(),
};
}
19 changes: 12 additions & 7 deletions lib/src/builders/message/allowed_mentions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ class AllowedMentions {

final List<Snowflake>? roles;

// TODO: Should this be nullable?
// The docs don't seem to require this to be present so we could make it nullable but it seems easier to have it non-nullable.
final bool repliedUser;
final bool? repliedUser;

AllowedMentions({this.parse, this.users, this.roles, this.repliedUser = false});
AllowedMentions({this.parse, this.users, this.roles, this.repliedUser});

factory AllowedMentions.users([List<Snowflake>? users]) => AllowedMentions(parse: users == null ? ['users'] : null, users: users);

Expand All @@ -30,11 +28,18 @@ class AllowedMentions {
parse.remove('parse');
}

bool? repliedUser = this.repliedUser;
if (repliedUser != null && other.repliedUser != null) {
repliedUser = repliedUser || other.repliedUser!;
} else {
repliedUser ??= other.repliedUser;
}

return AllowedMentions(
parse: parse,
users: users,
roles: roles,
repliedUser: repliedUser || other.repliedUser,
repliedUser: repliedUser,
);
}

Expand Down Expand Up @@ -75,14 +80,14 @@ class AllowedMentions {
parse: parse,
roles: roles,
users: users,
repliedUser: repliedUser && other.repliedUser,
repliedUser: repliedUser == true && other.repliedUser == true,
);
}

Map<String, Object?> build() => {
if (parse != null) 'parse': parse,
if (users != null && users!.isNotEmpty) 'users': users!.map((e) => e.toString()).toList(),
if (roles != null && roles!.isNotEmpty) 'roles': roles!.map((e) => e.toString()).toList(),
'replied_user': repliedUser,
if (repliedUser != null) 'replied_user': repliedUser,
};
}
25 changes: 21 additions & 4 deletions lib/src/builders/presence.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import 'package:nyxx/src/builders/builder.dart';
import 'package:nyxx/src/models/gateway/events/presence.dart';
import 'package:nyxx/src/models/presence.dart';

// TODO: Better generic here?
class PresenceBuilder extends CreateBuilder<PresenceUpdateEvent> {
final DateTime? since;

// TODO
//final List<ActivityBuilder> activities;
final List<ActivityBuilder>? activities;

final CurrentUserStatus status;

final bool isAfk;

PresenceBuilder({this.since, required this.status, required this.isAfk});
PresenceBuilder({this.since, this.activities, required this.status, required this.isAfk});

@override
Map<String, Object?> build() => {
'since': since?.millisecondsSinceEpoch,
if (activities != null) 'activities': activities!.map((e) => e.build()).toList(),
'status': status.value,
'afk': isAfk,
};
Expand All @@ -36,3 +36,20 @@ enum CurrentUserStatus {
@override
String toString() => 'CurrentUserStatus($value)';
}

class ActivityBuilder extends CreateBuilder<Activity> {
final String name;

final ActivityType type;

final Uri? url;

ActivityBuilder({required this.name, required this.type, this.url});

@override
Map<String, Object?> build() => {
'name': name,
'type': type.value,
if (url != null) 'url': url!.toString(),
};
}
9 changes: 9 additions & 0 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:nyxx/src/http/managers/gateway_manager.dart';
import 'package:nyxx/src/intents.dart';
import 'package:nyxx/src/manager_mixin.dart';
import 'package:nyxx/src/api_options.dart';
import 'package:nyxx/src/models/guild/guild.dart';
import 'package:nyxx/src/models/snowflake.dart';
import 'package:nyxx/src/plugin/plugin.dart';
import 'package:nyxx/src/utils/flags.dart';
Expand Down Expand Up @@ -121,6 +122,10 @@ class NyxxRest with ManagerMixin implements Nyxx {
/// * Discord API Reference: https://discord.com/developers/docs/resources/channel#leave-thread
Future<void> leaveThread(Snowflake id) => channels.leaveThread(id);

/// List the guilds the current user is a member of.
Future<List<PartialGuild>> listGuilds({Snowflake? before, Snowflake? after, int? limit}) =>
users.listCurrentUserGuilds(before: before, after: after, limit: limit);

@override
Future<void> close() {
logger.info('Closing client');
Expand Down Expand Up @@ -155,6 +160,10 @@ class NyxxGateway with ManagerMixin, EventMixin implements NyxxRest {
@override
Future<void> leaveThread(Snowflake id) => channels.leaveThread(id);

@override
Future<List<PartialGuild>> listGuilds({Snowflake? before, Snowflake? after, int? limit}) =>
users.listCurrentUserGuilds(before: before, after: after, limit: limit);

/// Update the client's voice state in the guild with the ID [guildId].
void updateVoiceState(Snowflake guildId, GatewayVoiceStateBuilder builder) => gateway.updateVoiceState(guildId, builder);

Expand Down
26 changes: 20 additions & 6 deletions lib/src/client_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import 'package:nyxx/src/models/emoji.dart';
import 'package:nyxx/src/models/channel/stage_instance.dart';
import 'package:nyxx/src/models/guild/audit_log.dart';
import 'package:nyxx/src/models/guild/auto_moderation.dart';
import 'package:nyxx/src/models/guild/ban.dart';
import 'package:nyxx/src/models/guild/guild.dart';
import 'package:nyxx/src/models/guild/integration.dart';
import 'package:nyxx/src/models/guild/member.dart';
import 'package:nyxx/src/models/guild/scheduled_event.dart';
import 'package:nyxx/src/models/message/message.dart';
import 'package:nyxx/src/models/role.dart';
import 'package:nyxx/src/models/user/user.dart';
import 'package:nyxx/src/models/voice/voice_state.dart';
import 'package:nyxx/src/models/webhook.dart';
import 'package:nyxx/src/plugin/plugin.dart';

Expand Down Expand Up @@ -54,9 +55,6 @@ class RestClientOptions extends ClientOptions {
/// The [CacheConfig] to use for the [Guild.roles] manager.
final CacheConfig<Role> roleCacheConfig;

/// The [CacheConfig] to use for [Ban]s in the [NyxxRest.guilds] manager.
final CacheConfig<Ban> banCacheConfig;

/// The [CacheConfig] to use for the [Emoji]s in the [Guild.emojis] manager.
final CacheConfig<Emoji> emojiCacheConfig;

Expand All @@ -69,9 +67,15 @@ class RestClientOptions extends ClientOptions {
/// The [CacheConfig] to use for the [Guild.autoModerationRules] manager.
final CacheConfig<AutoModerationRule> autoModerationRuleConfig;

/// The [CacheConfig] to use for the [Guild.integrations] manager.
final CacheConfig<Integration> integrationConfig;

/// The [CacheConfig] to use for the [Guild.auditLogs] manager.
final CacheConfig<AuditLogEntry> auditLogEntryConfig;

/// The [CacheConfig] to use for the [NyxxRest.voice] manager.
final CacheConfig<VoiceState> voiceStateConfig;

/// Create a new [RestClientOptions].
const RestClientOptions({
super.plugins,
Expand All @@ -83,18 +87,27 @@ class RestClientOptions extends ClientOptions {
this.guildCacheConfig = const CacheConfig(),
this.memberCacheConfig = const CacheConfig(),
this.roleCacheConfig = const CacheConfig(),
this.banCacheConfig = const CacheConfig(),
this.emojiCacheConfig = const CacheConfig(),
this.stageInstanceCacheConfig = const CacheConfig(),
this.scheduledEventCacheConfig = const CacheConfig(),
this.autoModerationRuleConfig = const CacheConfig(),
this.integrationConfig = const CacheConfig(),
this.auditLogEntryConfig = const CacheConfig(),
this.voiceStateConfig = const CacheConfig(),
});
}

/// Options for controlling the behavior of a [NyxxWebsocket] client.
class GatewayClientOptions extends RestClientOptions {
/// The minimum number of session starts this client needs to connect.
///
/// This is a safety feature to avoid API bans due to excessive connection starts.
///
/// If the remaining number of session starts is below this number, an error will be thrown when connecting.
final int minimumSessionStarts;

const GatewayClientOptions({
this.minimumSessionStarts = 10,
super.plugins,
super.loggerName,
super.userCacheConfig,
Expand All @@ -104,10 +117,11 @@ class GatewayClientOptions extends RestClientOptions {
super.guildCacheConfig,
super.memberCacheConfig,
super.roleCacheConfig,
super.banCacheConfig,
super.stageInstanceCacheConfig,
super.scheduledEventCacheConfig,
super.autoModerationRuleConfig,
super.integrationConfig,
super.auditLogEntryConfig,
super.voiceStateConfig,
});
}
Loading
Loading