Skip to content

Commit

Permalink
Merge pull request #94 from mineral-dart/feat-implement-user-status
Browse files Browse the repository at this point in the history
feat: Implement user presences
  • Loading branch information
LeadcodeDev authored Mar 26, 2023
2 parents 00f2cf6 + a20af67 commit 3573d64
Show file tree
Hide file tree
Showing 19 changed files with 314 additions and 22 deletions.
1 change: 1 addition & 0 deletions lib/core/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,6 @@ export '../src/api/users/user_decoration.dart' show UserDecoration;
export '../src/api/users/user_flags/user_flag_contract.dart' show UserFlagContract;
export '../src/api/client/client_scope.dart' show ClientScope;
export '../src/api/client/client_permission.dart' show ClientPermission;
export '../src/api/guilds/activities/activity_type.dart' show ActivityType;

typedef Snowflake = String;
4 changes: 3 additions & 1 deletion lib/core/builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ export '../src/api/builders/menus/mentionable_select_menu_builder.dart' show Men
export '../src/api/builders/modal/text_builder.dart' show TextBuilder;
export '../src/api/builders/modal/paragraph_builder.dart' show ParagraphBuilder;

export '../src/api/builders/attachment_builder.dart' show AttachmentBuilder;
export '../src/api/builders/attachment_builder.dart' show AttachmentBuilder;
export '../src/api/builders/markdown/markdown.dart' show Md;
export '../src/api/builders/markdown/timestamp_style.dart' show TimestampStyle;
21 changes: 21 additions & 0 deletions lib/src/api/builders/markdown/markdown.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:mineral/core/builders.dart';

class Md {
Md._();

static String bold (dynamic value) => '**$value**';

static String underline (dynamic value) => '__${value}__';

static String strikethrough (dynamic value) => '~~$value~~';

static String code (String value) => '```$value```';

static String italic (String value) => '*$value*';

static String spoil (dynamic value) => '||$value||';

static String timestamp (DateTime value, { TimestampStyle? style }) => style != null
? '<t:${(value.millisecondsSinceEpoch / 1000).round()}:${style.value}>'
: '<t:${(value.millisecondsSinceEpoch / 1000).round()}>';
}
12 changes: 12 additions & 0 deletions lib/src/api/builders/markdown/timestamp_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
enum TimestampStyle {
shortTime('t'),
longTime('T'),
shortDate('d'),
longDate('D'),
shortDateTime('f*'),
longDateTime('F'),
relativeTime('R');

final String value;
const TimestampStyle(this.value);
}
8 changes: 2 additions & 6 deletions lib/src/api/emoji.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:mineral_ioc/ioc.dart';

class PartialEmoji {
final Snowflake _id;
String _label;
final String _label;
final bool _animated;

PartialEmoji(this._id, this._label, this._animated);
Expand Down Expand Up @@ -59,14 +59,10 @@ class Emoji extends PartialEmoji {
/// }
/// ```
Future<void> setLabel (String label, { String? reason }) async {
Response response = await ioc.use<DiscordApiHttpService>().patch(url: "/guilds/${manager.guild.id}/emojis/$id")
await ioc.use<DiscordApiHttpService>().patch(url: "/guilds/${manager.guild.id}/emojis/$id")
.payload({ 'name': label })
.auditLog(reason)
.build();

if (response.statusCode == 200) {
_label = label;
}
}

Future<void> setAllowedRoles (List<Snowflake> roles, { String? reason }) async {
Expand Down
11 changes: 11 additions & 0 deletions lib/src/api/guilds/activities/activity_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
enum ActivityType {
game(0),
streaming(1),
listening(2),
watching(3),
custom(4),
competing(5);

final int value;
const ActivityType(this.value);
}
15 changes: 15 additions & 0 deletions lib/src/api/guilds/activities/assets_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:mineral/core/api.dart';

class AssetsActivity {
final ImageFormater? _smallImage;
final String? _smallText;
final ImageFormater? _largeImage;
final String? _largeText;

AssetsActivity(this._smallImage, this._smallText, this._largeImage, this._largeText);

ImageFormater? get smallImage => _smallImage;
String? get smallText => _smallText;
ImageFormater? get largeImage => _largeImage;
String? get largeText => _largeText;
}
42 changes: 42 additions & 0 deletions lib/src/api/guilds/activities/custom_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:mineral/core/api.dart';
import 'package:mineral/src/api/emoji.dart';
import 'package:mineral/src/api/guilds/activities/guild_member_activity.dart';
import 'package:mineral/src/api/guilds/activities/secret_activity.dart';

class CustomActivity extends GuildMemberActivity {
final String _id;
final String? _state;
final PartialEmoji? _emoji;
final String _createdAt;
final SecretActivity _secrets;

CustomActivity(
String name,
this._id,
this._state,
this._emoji,
this._createdAt,
this._secrets,
): super(ActivityType.custom, name);

String get id => _id;
String? get state => _state;
PartialEmoji? get emoji => _emoji;
String get createdAt => _createdAt;
SecretActivity get secrets => _secrets;

factory CustomActivity.from(Snowflake guildId, dynamic payload) => CustomActivity(
payload['name'],
payload['id'],
payload['state'],
payload['emoji'] != null
? PartialEmoji(payload['emoji']['id'], payload['emoji']['name'], payload['emoji']['animated'])
: null,
payload['created_at'],
SecretActivity(
payload['secrets']?['join'],
payload['secrets']?['spectate'],
payload['secrets']?['match'],
)
);
}
75 changes: 75 additions & 0 deletions lib/src/api/guilds/activities/game_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'package:mineral/core/api.dart';
import 'package:mineral/src/api/guilds/activities/assets_activity.dart';
import 'package:mineral/src/api/guilds/activities/guild_member_activity.dart';
import 'package:mineral/src/api/guilds/activities/secret_activity.dart';

class GameActivity extends GuildMemberActivity {
final String _id;
final String? _state;
final int? _startingAt;
final int? _endAt;
final int _createdAt;
final String? _details;
final String? _applicationId;
final AssetsActivity _assets;
final SecretActivity _secrets;

GameActivity(
String name,
this._id,
this._state,
this._startingAt,
this._endAt,
this._createdAt,
this._details,
this._applicationId,
this._assets,
this._secrets,
): super(ActivityType.game, name);

String get id => _id;

String? get state => _state;

int? get startingAt => _startingAt;

DateTime? get endAt => _endAt != null
? DateTime.fromMicrosecondsSinceEpoch(_endAt!)
: null;

DateTime get createdAt => DateTime.fromMicrosecondsSinceEpoch(_createdAt);

String? get details => _details;

String? get applicationId => _applicationId;

AssetsActivity get assets => _assets;

SecretActivity get secrets => _secrets;

factory GameActivity.from(Snowflake guildId, dynamic payload) => GameActivity(
payload['name'],
payload['id'],
payload['state'],
payload['timestamps']?['start'],
payload['timestamps']?['end'],
payload['created_at'],
payload['details'],
payload['application_id'],
AssetsActivity(
payload['assets']?['small_image'] != null
? ImageFormater(payload['assets']['large_image'], 'app-assets/${payload['application_id']}')
: null,
payload['assets']?['small_text'],
payload['assets']?['large_image'] != null
? ImageFormater(payload['assets']['large_image'], 'app-assets/${payload['application_id']}')
: null,
payload['assets']?['large_text'],
),
SecretActivity(
payload['secrets']?['join'],
payload['secrets']?['spectate'],
payload['secrets']?['match'],
)
);
}
11 changes: 11 additions & 0 deletions lib/src/api/guilds/activities/guild_member_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:mineral/core/api.dart';

class GuildMemberActivity {
final ActivityType _type;
final String _name;

GuildMemberActivity(this._type, this._name);

ActivityType get type => _type;
String get name => _name;
}
11 changes: 11 additions & 0 deletions lib/src/api/guilds/activities/secret_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class SecretActivity {
final String? _join;
final String? _spectate;
final String? _match;

SecretActivity(this._join, this._spectate, this._match);

String? get join => _join;
String? get spectate => _spectate;
String? get match => _match;
}
26 changes: 26 additions & 0 deletions lib/src/api/guilds/activities/streaming_activity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:mineral/core/api.dart';
import 'package:mineral/src/api/guilds/activities/guild_member_activity.dart';

class StreamingActivity extends GuildMemberActivity {
final String _state;
final String? _details;
final String _url;

StreamingActivity(
String name,
this._state,
this._details,
this._url,
): super(ActivityType.streaming, name);

String get state => _state;
String? get details => _details;
String get url => _url;

factory StreamingActivity.from(Snowflake guildId, dynamic payload) => StreamingActivity(
payload['name'],
payload['state'],
payload['details'],
payload['url'],
);
}
11 changes: 11 additions & 0 deletions lib/src/api/guilds/client_status_bucket.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ClientStatusBucket {
final String? _desktop;
final String? _web;
final String? _mobile;

ClientStatusBucket(this._desktop, this._web, this._mobile);

String? get desktop => _desktop;
String? get web => _web;
String? get mobile => _mobile;
}
8 changes: 6 additions & 2 deletions lib/src/api/guilds/guild_member.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:http/http.dart';
import 'package:mineral/core.dart';
import 'package:mineral/core/api.dart';
import 'package:mineral/framework.dart';
import 'package:mineral/src/api/guilds/guild_member_presence.dart';
import 'package:mineral/src/api/managers/guild_role_manager.dart';
import 'package:mineral_ioc/ioc.dart';

Expand All @@ -17,6 +18,7 @@ class GuildMember {
MemberRoleManager _roles;
VoiceManager voice;
Guild _guild;
GuildMemberPresence? presence;

GuildMember(
this._user,
Expand All @@ -30,6 +32,7 @@ class GuildMember {
this._roles,
this.voice,
this._guild,
this.presence,
);

Snowflake get id => _user.id;
Expand Down Expand Up @@ -157,7 +160,7 @@ class GuildMember {
@override
String toString () => '<@${_nickname != null ? '!' : ''}${user.id}>';

GuildMember clone () => GuildMember(user, nickname, avatar, joinedAt, premiumSince, permissions, pending, timeoutDuration, roles, voice, guild);
GuildMember clone () => GuildMember(user, nickname, avatar, joinedAt, premiumSince, permissions, pending, timeoutDuration, roles, voice, guild, presence);

factory GuildMember.from({ required user, required GuildRoleManager roles, required Guild guild, dynamic member, required VoiceManager voice }) {
MemberRoleManager memberRoleManager = MemberRoleManager(manager: roles, memberId: user.id);
Expand All @@ -179,7 +182,8 @@ class GuildMember {
member['communication_disabled_until'] != null ? DateTime.parse(member['communication_disabled_until']) : null,
memberRoleManager,
voice,
guild
guild,
null,
);
}
}
20 changes: 20 additions & 0 deletions lib/src/api/guilds/guild_member_presence.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:mineral/core/api.dart';
import 'package:mineral/src/api/guilds/activities/guild_member_activity.dart';
import 'package:mineral/src/api/guilds/client_status_bucket.dart';

class GuildMemberPresence {
final Snowflake _guildId;
final String _status;
final String? _premiumSince;
final ClientStatusBucket _clientStatus;
final List<GuildMemberActivity> _activities;

GuildMemberPresence(this._guildId, this._status, this._premiumSince, this._clientStatus, this._activities);

StatusType get status => StatusType.values.firstWhere((element) => element.value == _status);
DateTime? get premiumSince => _premiumSince != null
? DateTime.parse(_premiumSince!)
: null;
ClientStatusBucket get clientStatus => _clientStatus;
List<GuildMemberActivity> get activities => _activities;
}
7 changes: 2 additions & 5 deletions lib/src/api/status.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ enum StatusType {
doNotDisturb('dnd'),
offline('offline');

final String _value;
const StatusType(this._value);

@override
String toString () => _value;
final String value;
const StatusType(this.value);
}

class Status {
Expand Down
1 change: 0 additions & 1 deletion lib/src/api/users/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class User {
UserDecoration _decoration;
String _lang;
PremiumType premiumType;
// late Status status;

User(
this._id,
Expand Down
4 changes: 1 addition & 3 deletions lib/src/internal/websockets/packets/guild_remove_packet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ class GuildRemovePacket with Container implements WebsocketPacket {
EventService eventService = container.use<EventService>();
MineralClient client = container.use<MineralClient>();

dynamic payload = websocketResponse.payload;

Guild? guild = client.guilds.cache.getOrFail(payload['guild_id']);
Guild guild = client.guilds.cache.getOrFail(websocketResponse.payload['id']);

eventService.controller.add(GuildDeleteEvent(guild));
client.guilds.cache.remove(guild.id);
Expand Down
Loading

0 comments on commit 3573d64

Please sign in to comment.