Skip to content

Commit

Permalink
Add a plugin for detecting when the client joins or leaves a guild (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
abitofevrything authored Feb 21, 2024
1 parent 658d623 commit b5d37b4
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/nyxx_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ library nyxx_extensions;
export 'src/utils/emoji.dart';
export 'src/utils/endpoint_paginator.dart' hide streamPaginatedEndpoint;
export 'src/utils/formatters.dart';
export 'src/utils/guild_joins.dart';
export 'src/utils/pagination.dart';
export 'src/utils/permissions.dart';
export 'src/utils/sanitizer.dart';
Expand Down
72 changes: 72 additions & 0 deletions lib/src/utils/guild_joins.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import 'dart:async';

import 'package:nyxx/nyxx.dart';

/// A global instance of the [GuildJoins] plugin.
final guildJoins = GuildJoins();

/// Provides a way to know when the client joins or leaves a [Guild].
///
/// [NyxxGateway.onGuildCreate] and [NyxxGateway.onGuildDelete] can be
/// misleading, as although they do emit an event when the client is added to
/// or removed from a [Guild], they can also emit events in a variety of other
/// scenarios:
/// - When guilds become available or unavailable due to outages
/// - As part of session initialisation, to populate the cache with information
/// about the guild contained in the [ReadyEvent].
///
/// This plugin exposes two streams. [onGuildJoin] and [onGuildLeave], that
/// emit the same type of events as [NyxxGateway.onGuildCreate] and
/// [NyxxGateway.onGuildDelete], but only when the event is triggered by the
/// client joining or leaving a guild.
class GuildJoins extends NyxxPlugin<NyxxGateway> {
final StreamController<UnavailableGuildCreateEvent> _onGuildJoinController = StreamController.broadcast();
final StreamController<GuildDeleteEvent> _onGuildLeaveController = StreamController.broadcast();

/// A stream of [UnavailableGuildCreateEvent] triggered by the client being
/// added to a [Guild].
///
/// As with [NyxxGateway.onGuildCreate], this stream normally emits
/// [GuildCreateEvent]s, other than in the event of an outage.
Stream<UnavailableGuildCreateEvent> get onGuildJoin => _onGuildJoinController.stream;

/// A stream of [GuildDeleteEvent]s triggered by the client being removed
/// from a [Guild].
Stream<GuildDeleteEvent> get onGuildLeave => _onGuildLeaveController.stream;

@override
NyxxPluginState<NyxxGateway, GuildJoins> createState() => _GuildJoinsState(this);
}

class _GuildJoinsState extends NyxxPluginState<NyxxGateway, GuildJoins> {
final Set<Snowflake> _currentGuildIds = {};

_GuildJoinsState(super.plugin);

@override
void afterConnect(NyxxGateway client) {
super.afterConnect(client);

client.onReady.listen(
(event) => _currentGuildIds.addAll(event.guilds.map((guild) => guild.id)),
);

client.onGuildCreate.listen((event) {
if (_currentGuildIds.contains(event.guild.id)) {
return;
}

_currentGuildIds.add(event.guild.id);
plugin._onGuildJoinController.add(event);
});

client.onGuildDelete.listen((event) {
if (event.isUnavailable) {
return;
}

_currentGuildIds.remove(event.guild.id);
plugin._onGuildLeaveController.add(event);
});
}
}

0 comments on commit b5d37b4

Please sign in to comment.