Skip to content

Commit

Permalink
Merge pull request #25 from mineral-dart/develop
Browse files Browse the repository at this point in the history
feat: Implement GuildMemberRoles
  • Loading branch information
LeadcodeDev authored Jul 5, 2022
2 parents 0da3c6c + 95126d7 commit fa43b6e
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 37 deletions.
1 change: 1 addition & 0 deletions lib/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export 'src/api/user.dart' show User;
export 'src/api/status.dart' show Status, StatusType;
export 'src/api/activity.dart' show Activity;
export 'src/api/guilds/guild_member.dart' show GuildMember;
export 'src/api/guilds/member_role_manager.dart' show MemberRoleManager;
export 'src/api/voice.dart' show Voice;

export 'src/api/guilds/guild.dart' show Guild;
Expand Down
21 changes: 6 additions & 15 deletions lib/src/api/emoji.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/managers/emoji_manager.dart';
import 'package:mineral/src/api/managers/member_manager.dart';
import 'package:mineral/src/api/managers/role_manager.dart';

/// Represents an [Emoji] on [Guild] context.
/// {@category Api}
class Emoji {
Snowflake id;
String label;
List<Role> roles;
//List<Role> roles;
GuildMember? creator;
bool requireColons;
bool managed;
Expand All @@ -21,7 +20,7 @@ class Emoji {
Emoji({
required this.id,
required this.label,
required this.roles,
//required this.roles,
required this.creator,
required this.requireColons,
required this.managed,
Expand Down Expand Up @@ -55,7 +54,7 @@ class Emoji {
/// await emoji.setRoles([role.id]);
/// }
/// ```
Future<void> setRoles (List<Snowflake> roles) async {
/*Future<void> setRoles (List<Snowflake> roles) async {
Http http = ioc.singleton(ioc.services.http);
Response response = await http.patch(url: "/guilds/${manager.guildId}/emojis/$id", payload: { 'roles': roles });
Expand All @@ -70,7 +69,7 @@ class Emoji {
this.roles = _roles;
}
}
}*/

/// Removes the current this from the [EmojiManager]'s cache
/// ```dart
Expand Down Expand Up @@ -105,19 +104,11 @@ class Emoji {
? '<a:$label:$id>'
: '<$label:$id>';

factory Emoji.from({ required MemberManager memberManager, required RoleManager roleManager, required EmojiManager emojiManager, required dynamic payload }) {
List<Role> roles = [];
for (dynamic id in payload['roles']) {
Role? role = roleManager.cache.get(id);
if (role != null) {
roles.add(role);
}
}

factory Emoji.from({ required MemberManager memberManager, required EmojiManager emojiManager, required dynamic payload }) {
return Emoji(
id: payload['id'],
label: payload['name'],
roles: roles,
//roles: roles,
creator: payload['user'] != null ? memberManager.cache.get(payload['user']['id']) : null,
requireColons: payload['require_colons'] ?? false,
managed: payload['managed'] ?? false,
Expand Down
6 changes: 3 additions & 3 deletions lib/src/api/guilds/guild.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import 'package:mineral/console.dart';
import 'package:mineral/core.dart';
import 'package:mineral/exception.dart';
import 'package:mineral/helper.dart';
import 'package:mineral/src/api/guilds/guild_role_manager.dart';
import 'package:mineral/src/api/managers/channel_manager.dart';
import 'package:mineral/src/api/managers/emoji_manager.dart';
import 'package:mineral/src/api/managers/guild_webhook_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/role_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';
Expand Down Expand Up @@ -45,7 +45,7 @@ class Guild {
VerificationLevel verificationLevel;
int defaultMessageNotifications;
int explicitContentFilter;
RoleManager roles;
GuildRoleManager roles;
List<GuildFeature> features;
int mfaLevel;
Snowflake? applicationId;
Expand Down Expand Up @@ -347,7 +347,7 @@ class Guild {
factory Guild.from({
required EmojiManager emojiManager,
required MemberManager memberManager,
required RoleManager roleManager,
required GuildRoleManager roleManager,
required ChannelManager channelManager,
required ModerationRuleManager moderationRuleManager,
required WebhookManager webhookManager,
Expand Down
12 changes: 6 additions & 6 deletions lib/src/api/guilds/guild_member.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:http/http.dart';
import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/managers/role_manager.dart';
import 'package:mineral/src/api/guilds/guild_role_manager.dart';

class GuildMember {
User user;
Expand All @@ -12,7 +12,7 @@ class GuildMember {
String? permissions;
bool isPending;
DateTime? timeoutDuration;
RoleManager roles;
MemberRoleManager roles;
Voice voice;
late Guild guild;

Expand Down Expand Up @@ -97,12 +97,12 @@ class GuildMember {
..roles = roles;
}

factory GuildMember.from({ required user, required RoleManager roles, dynamic member, required Snowflake guildId }) {
RoleManager roleManager = RoleManager(guildId: guildId);
factory GuildMember.from({ required user, required GuildRoleManager roles, dynamic member, required Snowflake guildId }) {
MemberRoleManager memberRoleManager = MemberRoleManager(manager: roles, memberId: user.id);
for (var element in (member['roles'] as List<dynamic>)) {
Role? role = roles.cache.get(element);
if (role != null) {
roleManager.cache.putIfAbsent(role.id, () => role);
memberRoleManager.cache.putIfAbsent(role.id, () => role);
}
}

Expand All @@ -115,7 +115,7 @@ class GuildMember {
permissions: member['permissions'],
isPending: member['pending'] == true,
timeoutDuration: member['communication_disabled_until'] != null ? DateTime.parse(member['communication_disabled_until']) : null,
roles: roleManager,
roles: memberRoleManager,
voice: Voice.from(payload: member),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import 'package:mineral/exception.dart';
import 'package:mineral/helper.dart';
import 'package:mineral/src/api/managers/cache_manager.dart';

class RoleManager implements CacheManager<Role> {
class GuildRoleManager implements CacheManager<Role> {
@override
Map<Snowflake, Role> cache = {};

Snowflake guildId;
late Guild guild;

RoleManager({ required this.guildId });
GuildRoleManager({ required this.guildId });

@override
Future<Map<Snowflake, Role>> sync () async {
Expand Down
127 changes: 127 additions & 0 deletions lib/src/api/guilds/member_role_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import 'dart:convert';

import 'package:http/http.dart';
import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/guilds/guild_role_manager.dart';
import 'package:mineral/src/api/managers/cache_manager.dart';
import 'package:mineral/src/exceptions/not_exist.dart';

class MemberRoleManager implements CacheManager<Role> {
@override
Map<Snowflake, Role> cache = {};

GuildRoleManager manager;
Snowflake memberId;
//late Guild guild;

MemberRoleManager({ required this.manager, required this.memberId });

/// Add a [Role] to the [GuildMember]
/// ```dart
/// final Role? role = guild.roles.cache.get('446556480850755604');
/// final GuildMember? member = guild.members.cache.get('240561194958716924');
/// if (member != null && role != null) {
/// await member.roles.add(role.id)
/// }
/// ```
///
/// You can pass a reason for the audit logs.
/// ```dart
/// await member.roles.add('446556480850755604', reason: 'I love this user');
/// ```
Future<void> add (Snowflake id, {String? reason}) async {
Http http = ioc.singleton(ioc.services.http);
Role? role = manager.cache.get(id);

if(role == null) {
throw NotExist(prefix: 'role not exist', cause: 'You can\'t add a role that don\'t exist!');
}

Map<String, String> headers = {};
if(reason != null) {
headers.putIfAbsent('X-Audit-Log-Reason', () => reason);
}

Response response = await http.put(
url: '/guilds/{guild.id}/members/$memberId/roles/$id',
payload: {},
headers: headers
);

if(response.statusCode == 204) {
cache.putIfAbsent(id, () => role);
}
}

/// Remove a [Role] from the [GuildMember]
/// ```dart
/// final Role? role = guild.roles.cache.get('446556480850755604');
/// final GuildMember? member = guild.members.cache.get('240561194958716924');
/// if (member != null && role != null) {
/// await member.roles.remove(role.id)
/// }
/// ```
///
/// You can pass a reason for the audit logs.
/// ```dart
/// await member.roles.remove('446556480850755604', reason: 'Hello, World!');
/// ```
Future<void> remove (Snowflake id, {String? reason}) async {
Http http = ioc.singleton(ioc.services.http);

Map<String, String> headers = {};
if(reason != null) {
headers.putIfAbsent('X-Audit-Log-Reason', () => reason);
}

Response response = await http.destroy(
url: '/guilds/{guild.id}/members/$memberId/roles/$id',
headers: headers
);

if(response.statusCode == 204) {
cache.remove(id);
}
}

/// Toggle a [Role] from the [GuildMember]. If the user has the role, this method will remove the role, else this method will add the role.
/// ```dart
/// final Role? role = guild.roles.cache.get('446556480850755604');
/// final GuildMember? member = guild.members.cache.get('240561194958716924');
/// if (member != null && role != null) {
/// await member.roles.toggle(role.id)
/// }
/// ```
///
/// You can pass a reason for the audit logs.
/// ```dart
/// await member.roles.toggle('446556480850755604', reason: 'Hello, World!');
/// ```
Future<void> toggle (Snowflake id, {String? reason}) async {
return cache.containsKey(id)
? remove(id, reason: reason)
: add(id, reason: reason);
}

@override
Future<Map<Snowflake, Role>> sync () async {
Http http = ioc.singleton(ioc.services.http);

Response response = await http.get(url: "/guilds/${manager.guildId}/members/$memberId");
if(response.statusCode == 200) {
cache.clear();
dynamic payload = jsonDecode(response.body)['roles'];

for(dynamic element in payload) {
final Role? role = manager.cache.get(element);
if(role != null) {
cache.putIfAbsent(role.id, () => role);
}
}
}

return cache;
}

}
4 changes: 2 additions & 2 deletions lib/src/api/managers/emoji_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class EmojiManager implements CacheManager<Emoji> {
for(dynamic element in payload) {
Emoji emoji = Emoji.from(
memberManager: guild!.members,
roleManager: guild!.roles,
//roleManager: guild!.roles,
emojiManager: this,
payload: element
);
Expand All @@ -53,7 +53,7 @@ class EmojiManager implements CacheManager<Emoji> {

Emoji emoji = Emoji.from(
memberManager: guild!.members,
roleManager: guild!.roles,
//roleManager: guild!.roles,
emojiManager: this,
payload: jsonDecode(response.body),
);
Expand Down
8 changes: 4 additions & 4 deletions lib/src/api/role.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/exception.dart';
import 'package:mineral/helper.dart';
import 'package:mineral/src/api/managers/role_manager.dart';
import 'package:mineral/src/api/guilds/guild_role_manager.dart';

class Tag {
Snowflake? botId;
Expand Down Expand Up @@ -33,7 +33,7 @@ class Role {
bool managed;
bool mentionable;
Tag? tags;
RoleManager manager;
GuildRoleManager manager;

Role({
required this.id,
Expand Down Expand Up @@ -224,7 +224,7 @@ class Role {
}
}

/// Removes the current this from the [RoleManager]'s cache
/// Removes the current this from the [MemberRoleManager]'s cache
/// ```dart
/// final Role? role = guild.roles.cache.get('240561194958716924');
/// if (role != null) {
Expand Down Expand Up @@ -261,7 +261,7 @@ class Role {
@override
String toString () => '<@&$id>';

factory Role.from({ required RoleManager roleManager, dynamic payload }) {
factory Role.from({ required GuildRoleManager roleManager, dynamic payload }) {
return Role(
id: payload['id'],
label: payload['name'],
Expand Down
5 changes: 2 additions & 3 deletions lib/src/internal/websockets/packets/guild_create.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import 'package:http/http.dart';
import 'package:mineral/api.dart';
import 'package:mineral/core.dart';
import 'package:mineral/src/api/channels/channel.dart';
import 'package:mineral/src/api/guilds/guild_role_manager.dart';
import 'package:mineral/src/api/guilds/guild_scheduled_event.dart';
import 'package:mineral/src/api/managers/channel_manager.dart';
import 'package:mineral/src/api/managers/emoji_manager.dart';
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/role_manager.dart';
import 'package:mineral/src/api/managers/webhook_manager.dart';
import 'package:mineral/src/internal/entities/command_manager.dart';
import 'package:mineral/src/internal/entities/event_manager.dart';
Expand All @@ -27,7 +27,7 @@ class GuildCreate implements WebsocketPacket {
CommandManager commandManager = ioc.singleton(ioc.services.command);
MineralClient client = ioc.singleton(ioc.services.client);

RoleManager roleManager = RoleManager(guildId: websocketResponse.payload['id']);
GuildRoleManager roleManager = GuildRoleManager(guildId: websocketResponse.payload['id']);
for (dynamic item in websocketResponse.payload['roles']) {
Role role = Role.from(roleManager: roleManager, payload: item);
roleManager.cache.putIfAbsent(role.id, () => role);
Expand Down Expand Up @@ -63,7 +63,6 @@ class GuildCreate implements WebsocketPacket {
for(dynamic payload in websocketResponse.payload['emojis']) {
Emoji emoji = Emoji.from(
memberManager: memberManager,
roleManager: roleManager,
emojiManager: emojiManager,
payload: payload
);
Expand Down
Loading

0 comments on commit fa43b6e

Please sign in to comment.