Skip to content

Commit 1dea45f

Browse files
committed
Implement new Invite event and new fields in User object.
discord/discord-api-docs#1309 [ci skip]
1 parent 3eda48c commit 1dea45f

File tree

10 files changed

+256
-10
lines changed

10 files changed

+256
-10
lines changed

nyxx/lib/nyxx.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ part 'src/events/HttpEvents.dart';
5353
part 'src/events/ChannelEvents.dart';
5454
part 'src/events/GuildEvents.dart';
5555

56+
part 'src/events/InviteEvents.dart';
57+
5658
// BUILDERS
5759

5860
part 'src/builders/Builder.dart';
@@ -116,6 +118,8 @@ part 'src/objects/user/Member.dart';
116118
part 'src/objects/guild/Status.dart';
117119
part 'src/objects/guild/Role.dart';
118120
part 'src/objects/user/User.dart';
121+
part 'src/objects/user/UserFlags.dart';
122+
part 'src/objects/user/NitroType.dart';
119123
part 'src/objects/guild/Ban.dart';
120124
part 'src/objects/guild/GuildEnums.dart';
121125

nyxx/lib/src/Nyxx.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,15 @@ class Nyxx implements Disposable {
175175
/// Emitted when bot is mentioned
176176
late Stream<MessageReceivedEvent> onSelfMention;
177177

178+
/// Emitted when invite is created
179+
late Stream<InviteCreatedEvent> onInviteCreated;
180+
181+
/// Emitted when invite is deleted
182+
late Stream<InviteDeletedEvent> onInviteDeleted;
183+
184+
/// Emitted when a bot removes all instances of a given emoji from the reactions of a message
185+
late Stream<MessageReactionRemoveEmojiEvent> onMessageReactionRemoveEmoji;
186+
178187
/// Logger instance
179188
Logger _logger = Logger("Client");
180189

@@ -262,9 +271,12 @@ class Nyxx implements Disposable {
262271
/// var user = client.getClient(Snowflake("302359032612651009"));
263272
/// ``
264273
Future<User?> getUser(Snowflake id) async {
265-
if (this.users.hasKey(id)) return this.users[id];
274+
//if (this.users.hasKey(id)) return this.users[id];
266275

267276
var r = await this._http.send("GET", "/users/${id.toString()}");
277+
278+
print(r.body);
279+
268280
return User._new(r.body as Map<String, dynamic>, this);
269281
}
270282

nyxx/lib/src/Shard.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,21 @@ class Shard implements Disposable {
377377
.add(UserUpdateEvent._new(msg, _ws._client));
378378
break;
379379

380+
case 'INVITE_CREATE':
381+
_ws._client._events.onInviteCreated
382+
.add(InviteCreatedEvent._new(msg, _ws._client));
383+
break;
384+
385+
case 'INVITE_DELETE':
386+
_ws._client._events.onInviteDelete
387+
.add(InviteDeletedEvent._new(msg, _ws._client));
388+
break;
389+
390+
case 'MESSAGE_REACTION_REMOVE_EMOJI':
391+
_ws._client._events.onMessageReactionRemoveEmoji
392+
.add(MessageReactionRemoveEmojiEvent._new(msg, _ws._client));
393+
break;
394+
380395
default:
381396
print("UNKNOWN OPCODE: ${jsonEncode(msg)}");
382397
}

nyxx/lib/src/events/InviteEvents.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
part of nyxx;
2+
3+
/// Emitted when invite is creating
4+
class InviteCreatedEvent {
5+
late final Invite invite;
6+
7+
InviteCreatedEvent._new(Map<String, dynamic> json, Nyxx client) {
8+
this.invite = Invite._new(json['d'] as Map<String, dynamic>, client);
9+
}
10+
}
11+
12+
/// Emitted when invite is deleted
13+
class InviteDeletedEvent {
14+
Channel? channel;
15+
Guild? guild;
16+
17+
late final String code;
18+
19+
InviteDeletedEvent._new(Map<String, dynamic> json, Nyxx client) {
20+
this.code = json['d']['code'] as String;
21+
this.channel = client.channels[Snowflake(json['d']['channel_id'])];
22+
23+
if(json['d']['guild_id'] != null) {
24+
this.guild = client.guilds[Snowflake(json['d']['guild_id'])];
25+
}
26+
}
27+
}

nyxx/lib/src/events/MessageEvents.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,33 @@ class MessageReactionsRemovedEvent extends MessageEvent {
130130
}
131131
}
132132

133+
class MessageReactionRemoveEmojiEvent extends MessageEvent {
134+
/// Channel where reactions are removed
135+
late final MessageChannel? channel;
136+
137+
@override
138+
139+
/// Message on which messages are removed
140+
late final Message? message;
141+
142+
/// Guild where event occurs
143+
late final Guild? guild;
144+
145+
/// The emoji that was removed
146+
late final Emoji? emoji;
147+
148+
MessageReactionRemoveEmojiEvent._new(Map<String, dynamic> json, Nyxx client) {
149+
this.channel = client.channels[Snowflake(json['d']['channel_id'])] as MessageChannel?;
150+
this.message = channel?.messages[Snowflake(json['d']['message_id'])];
151+
152+
if(json['d']['guild_id'] != null) {
153+
this.guild = client.guilds[Snowflake(json['d']['guild_id'])];
154+
155+
this.emoji = this.guild?.emojis[Snowflake(json['d']['emoji']['id'])];
156+
}
157+
}
158+
}
159+
133160
/// Emitted when multiple messages are deleted at once.
134161
class MessageDeleteBulkEvent {
135162
/// List of deleted messages

nyxx/lib/src/internal/_EventController.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ class _EventController implements Disposable {
117117
/// Emitted on any message related event
118118
late final StreamController<MessageEvent> onMessage;
119119

120+
/// Emitted when invite is creating
121+
late final StreamController<InviteCreatedEvent> onInviteCreated;
122+
123+
/// Emitted when invite is deleted
124+
late final StreamController<InviteDeletedEvent> onInviteDelete;
125+
126+
/// Emitted when a bot removes all instances of a given emoji from the reactions of a message
127+
late final StreamController<MessageReactionRemoveEmojiEvent> onMessageReactionRemoveEmoji;
128+
120129
/// Makes a new `EventController`.
121130
_EventController(Nyxx _client) {
122131
this.onRaw = StreamController.broadcast();
@@ -229,6 +238,15 @@ class _EventController implements Disposable {
229238

230239
this.onMessage = StreamController.broadcast();
231240
_client.onMessage = this.onMessage.stream;
241+
242+
this.onInviteCreated = StreamController.broadcast();
243+
_client.onInviteCreated = this.onInviteCreated.stream;
244+
245+
this.onInviteDelete = StreamController.broadcast();
246+
_client.onInviteDeleted = this.onInviteDelete.stream;
247+
248+
this.onMessageReactionRemoveEmoji = StreamController.broadcast();
249+
_client.onMessageReactionRemoveEmoji = this.onMessageReactionRemoveEmoji.stream;
232250
}
233251

234252
@override
@@ -271,6 +289,10 @@ class _EventController implements Disposable {
271289
this.onMessageReactionsRemoved.close();
272290
this.onVoiceStateUpdate.close();
273291
this.onVoiceServerUpdate.close();
292+
this.onMessageReactionRemoveEmoji.close();
293+
294+
this.onInviteCreated.close();
295+
this.onInviteDelete.close();
274296

275297
this.onUserUpdate.close();
276298
}

nyxx/lib/src/objects/Invite.dart

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
part of nyxx;
22

33
/// Represents invite to guild.
4-
class Invite {
4+
class Invite {
55
/// The invite's code.
66
late final String code;
77

88
/// A mini guild object for the invite's guild.
99
late final Guild? guild;
1010

1111
/// A mini channel object for the invite's channel.
12-
late final GuildChannel channel;
12+
late final Channel? channel;
1313

1414
/// Returns url invite
1515
String get url => "https://discord.gg/$code";
1616

1717
/// Date when invite was created
1818
late final DateTime createdAt;
1919

20-
/// True if invite is temporary
20+
/// Whether this invite only grants temporary membership
2121
late final bool temporary;
2222

2323
/// Number of uses of this invite
@@ -29,22 +29,64 @@ class Invite {
2929
/// User who created this invite
3030
late final User? inviter;
3131

32+
/// The target user for this invite
33+
late final User? targetUser;
34+
35+
/// Duration (in seconds) after which the invite expires
36+
late final int maxAge;
37+
38+
/// Date when invite will expire
39+
DateTime get expiryDate {
40+
return this.createdAt.add(Duration(seconds: maxAge));
41+
}
42+
43+
/// True if Invite is valid and can be used
44+
bool get isValid {
45+
var ageValidity = true;
46+
var expiryValidity = true;
47+
48+
if(this.maxUses > 0) {
49+
ageValidity = this.uses <= this.maxUses;
50+
}
51+
52+
if(this.maxAge > 0) {
53+
expiryValidity = expiryDate.isAfter(DateTime.now());
54+
}
55+
56+
return ageValidity && expiryValidity;
57+
}
58+
3259
/// Reference to bot instance
3360
Nyxx client;
3461

3562
Invite._new(Map<String, dynamic> raw, this.client) {
3663
this.code = raw['code'] as String;
37-
this.guild = client.guilds[Snowflake(raw['guild']['id'] as String)];
3864

39-
this.channel = client.channels[Snowflake(raw['channel']['id'] as String)]
40-
as GuildChannel;
65+
if(raw['guild'] != null) {
66+
this.guild = client.guilds[Snowflake(raw['guild']['id'])];
67+
}
68+
69+
if(raw['channel'] != null) {
70+
this.channel = client.channels[Snowflake(raw['channel']['id'])];
71+
}
72+
73+
if(raw['channel_id'] != null) {
74+
this.channel = client.channels[Snowflake(raw['channel_id'])];
75+
}
4176

4277
this.createdAt = DateTime.parse(raw['created_at'] as String);
4378
this.temporary = raw['temporary'] as bool;
4479
this.uses = raw['uses'] as int;
4580
this.maxUses = raw['max_uses'] as int;
81+
this.maxAge = raw['max_age'] as int;
82+
83+
if(raw['inviter'] != null) {
84+
this.inviter = client.users[Snowflake(raw['inviter']['id'])];
85+
}
4686

47-
this.inviter = client.users[Snowflake(raw['inviter']['id'] as String)];
87+
if(raw['target_user'] != null) {
88+
this.targetUser = client.users[Snowflake(raw['target_user']['id'])];
89+
}
4890
}
4991

5092
/// Deletes this Invite.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
part of nyxx;
2+
3+
///Premium types denote the level of premium a user has.
4+
class NitroType {
5+
static const NitroType none = const NitroType._create(0);
6+
static const NitroType classic = const NitroType._create(1);
7+
static const NitroType nitro = const NitroType._create(2);
8+
9+
final int _value;
10+
11+
const NitroType._create(int? value) : _value = value ?? 0;
12+
NitroType.from(int? value) : _value = value ?? 0;
13+
14+
@override
15+
String toString() => _value.toString();
16+
17+
@override
18+
int get hashCode => _value.hashCode;
19+
20+
@override
21+
bool operator ==(other) {
22+
if (other is NitroType || other is int)
23+
return other == _value;
24+
25+
return false;
26+
}
27+
}

nyxx/lib/src/objects/user/User.dart

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class User extends SnowflakeEntity with ISend, Mentionable, IMessageAuthor {
1515
/// The user's avatar hash.
1616
late final String? avatar;
1717

18-
1918
/// The string to mention the user.
2019
@override
2120
String get mention => "<@!${this.id}>";
@@ -24,22 +23,41 @@ class User extends SnowflakeEntity with ISend, Mentionable, IMessageAuthor {
2423
@override
2524
String get tag => "${this.username}#${this.discriminator}";
2625

27-
/// Whether or not the user is a bot.
26+
/// Whether the user belongs to an OAuth2 application
2827
@override
2928
late final bool bot;
3029

30+
/// Whether the user is an Official Discord System user (part of the urgent message system)
31+
late final bool system;
32+
3133
/// The member's status. `offline`, `online`, `idle`, or `dnd`.
3234
ClientStatus? status;
3335

3436
/// The member's presence.
3537
Presence? presence;
3638

39+
/// Additional flags associated with user account. Describes if user has certain
40+
/// features like joined into one of houses or is discord employee.
41+
UserFlags? userFlags;
42+
43+
/// Premium types denote the level of premium a user has.
44+
NitroType? nitroType;
45+
3746
User._new(Map<String, dynamic> raw, this.client)
3847
: super(Snowflake(raw['id'] as String)) {
3948
this.username = raw['username'] as String;
4049
this.discriminator = raw['discriminator'] as String;
4150
this.avatar = raw['avatar'] as String?;
4251
this.bot = raw['bot'] as bool? ?? false;
52+
this.system = raw['system'] as bool? ?? false;
53+
54+
if(raw['public_flags'] != null) {
55+
this.userFlags = UserFlags._new(raw['public_flags'] as int);
56+
}
57+
58+
if(raw['premium_type'] != null) {
59+
this.nitroType = NitroType.from(raw['premium_type'] as int);
60+
}
4361
}
4462

4563
/// The user's avatar, represented as URL.

0 commit comments

Comments
 (0)