feat: Trigger an event when the roster changes

This commit is contained in:
PapaTutuWawa 2023-01-07 18:32:15 +01:00
parent 2581bbe203
commit e12f4688d3
3 changed files with 45 additions and 6 deletions

View File

@ -61,6 +61,21 @@ class RosterPushEvent extends XmppEvent {
final String? ver; final String? ver;
} }
/// Triggered when the roster has been modified
class RosterUpdatedEvent extends XmppEvent {
RosterUpdatedEvent(this.removed, this.modified, this.added);
/// A list of bare JIDs that are removed from the roster
final List<String> removed;
/// A list of XmppRosterItems that are modified. Can be correlated with one's cache
/// using the jid attribute.
final List<XmppRosterItem> modified;
/// A list of XmppRosterItems that are added to the roster.
final List<XmppRosterItem> added;
}
/// Triggered when a message is received /// Triggered when a message is received
class MessageEvent extends XmppEvent { class MessageEvent extends XmppEvent {
MessageEvent({ MessageEvent({

View File

@ -61,7 +61,9 @@ class RosterFeatureNegotiator extends XmppFeatureNegotiatorBase {
/// This manager requires a RosterFeatureNegotiator to be registered. /// This manager requires a RosterFeatureNegotiator to be registered.
class RosterManager extends XmppManagerBase { class RosterManager extends XmppManagerBase {
RosterManager(this._stateManager) : super(); RosterManager(this._stateManager) : super() {
_stateManager.register(getAttributes().sendEvent);
}
final BaseRosterStateManager _stateManager; final BaseRosterStateManager _stateManager;
@override @override

View File

@ -28,6 +28,9 @@ abstract class BaseRosterStateManager {
/// A critical section locking both _currentRoster and _currentVersion. /// A critical section locking both _currentRoster and _currentVersion.
final Lock _lock = Lock(); final Lock _lock = Lock();
/// A function to send an XmppEvent to moxxmpp's main event bus
late void Function(XmppEvent) _sendEvent;
/// Overrideable function /// Overrideable function
/// Loads the old cached version of the roster and optionally that roster version /// Loads the old cached version of the roster and optionally that roster version
/// from persistent storage into a RosterCacheLoadResult object. /// from persistent storage into a RosterCacheLoadResult object.
@ -49,6 +52,12 @@ abstract class BaseRosterStateManager {
/// roster push or roster fetch request. /// roster push or roster fetch request.
Future<void> commitRoster(String? version, List<String> removed, List<XmppRosterItem> modified, List<XmppRosterItem> added); Future<void> commitRoster(String? version, List<String> removed, List<XmppRosterItem> modified, List<XmppRosterItem> added);
/// Internal function. Registers functions from the RosterManger against this
/// instance.
void register(void Function(XmppEvent) sendEvent) {
_sendEvent = sendEvent;
}
/// Load and cache or return the cached roster version. /// Load and cache or return the cached roster version.
Future<String?> getRosterVersion() async { Future<String?> getRosterVersion() async {
return _lock.synchronized(() async { return _lock.synchronized(() async {
@ -58,6 +67,20 @@ abstract class BaseRosterStateManager {
}); });
} }
/// A wrapper around _commitRoster that also sends an event to moxxmpp's event
/// bus.
Future<void> _commitRoster(String? version, List<String> removed, List<XmppRosterItem> modified, List<XmppRosterItem> added) async {
_sendEvent(
RosterUpdatedEvent(
removed,
modified,
added,
),
);
await commitRoster(version, removed, modified, added);
}
/// Loads the cached roster data into memory, if that has not already happened. /// Loads the cached roster data into memory, if that has not already happened.
/// NOTE: Must be called from within the _lock critical section. /// NOTE: Must be called from within the _lock critical section.
Future<void> _loadRosterCache() async { Future<void> _loadRosterCache() async {
@ -111,21 +134,21 @@ abstract class BaseRosterStateManager {
final result = _handleRosterItem(event.item); final result = _handleRosterItem(event.item);
if (result.removed != null) { if (result.removed != null) {
return commitRoster( return _commitRoster(
_currentVersion, _currentVersion,
[result.removed!], [result.removed!],
[], [],
[], [],
); );
} else if (result.modified != null) { } else if (result.modified != null) {
return commitRoster( return _commitRoster(
_currentVersion, _currentVersion,
[], [],
[result.modified!], [result.modified!],
[], [],
); );
} else if (result.added != null) { } else if (result.added != null) {
return commitRoster( return _commitRoster(
_currentVersion, _currentVersion,
[], [],
[], [],
@ -153,7 +176,7 @@ abstract class BaseRosterStateManager {
if (result.added != null) added.add(result.added!); if (result.added != null) added.add(result.added!);
} }
await commitRoster( await _commitRoster(
_currentVersion, _currentVersion,
removed, removed,
modified, modified,
@ -187,5 +210,4 @@ class TestingRosterStateManager extends BaseRosterStateManager {
@override @override
Future<void> commitRoster(String? version, List<String> removed, List<XmppRosterItem> modified, List<XmppRosterItem> added) async {} Future<void> commitRoster(String? version, List<String> removed, List<XmppRosterItem> modified, List<XmppRosterItem> added) async {}
} }