feat: DeviceListModifiedEvent now contains a delta

This commit is contained in:
PapaTutuWawa 2023-06-16 20:13:30 +02:00
parent 0b2d6f0a97
commit e6c792a8ac
4 changed files with 85 additions and 11 deletions

View File

@ -59,3 +59,27 @@ OmemoPublicKey? decodeKeyIfNotNull(
int getTimestamp() { int getTimestamp() {
return DateTime.now().millisecondsSinceEpoch; return DateTime.now().millisecondsSinceEpoch;
} }
/// Describes the differences between two lists in terms of its items.
class ListDiff<T> {
ListDiff(this.added, this.removed);
/// The items that were added.
final List<T> added;
/// The items that were removed.
final List<T> removed;
}
extension BeforeAfterListDiff<T> on List<T> {
/// Compute the set-based changes between this list and [newList].
ListDiff<T> diff(List<T> newList) {
final oldSet = Set<T>.from(this);
final newSet = Set<T>.from(newList);
return ListDiff(
newSet.difference(oldSet).toList(),
oldSet.difference(newSet).toList(),
);
}
}

View File

@ -39,13 +39,16 @@ class RatchetRemovedEvent extends OmemoEvent {
/// Triggered when the device map has been modified /// Triggered when the device map has been modified
class DeviceListModifiedEvent extends OmemoEvent { class DeviceListModifiedEvent extends OmemoEvent {
DeviceListModifiedEvent(this.jid, this.devices); DeviceListModifiedEvent(this.jid, this.added, this.removed);
/// The JID of the user. /// The JID of the user.
final String jid; final String jid;
/// The list of devices for [jid]. /// The list of added devices for [jid].
final List<int> devices; final List<int> added;
/// The list of removed devices for [jid].
final List<int> removed;
} }
/// Triggered by the OmemoSessionManager when our own device bundle was modified /// Triggered by the OmemoSessionManager when our own device bundle was modified

View File

@ -154,7 +154,7 @@ class OmemoManager {
_deviceListRequested[jid] = true; _deviceListRequested[jid] = true;
_eventStreamController.add( _eventStreamController.add(
DeviceListModifiedEvent(jid, newDeviceList), DeviceListModifiedEvent(jid, newDeviceList, []),
); );
} }
} }
@ -709,9 +709,10 @@ class OmemoManager {
} }
// Clear the device list // Clear the device list
_eventStreamController
.add(DeviceListModifiedEvent(jid, [], _deviceList[jid]!));
_deviceList.remove(jid); _deviceList.remove(jid);
_deviceListRequested.remove(jid); _deviceListRequested.remove(jid);
_eventStreamController.add(DeviceListModifiedEvent(jid, []));
}, },
); );
} }
@ -719,13 +720,26 @@ class OmemoManager {
/// To be called when a update to the device list of [jid] is returned. /// To be called when a update to the device list of [jid] is returned.
/// [devices] is the list of device identifiers contained in the update. /// [devices] is the list of device identifiers contained in the update.
Future<void> onDeviceListUpdate(String jid, List<int> devices) async { Future<void> onDeviceListUpdate(String jid, List<int> devices) async {
// Update our state await _ratchetQueue.synchronized(
_deviceList[jid] = devices; [jid],
_deviceListRequested[jid] = true; () async {
// Compute the delta
ListDiff<int> delta;
if (_deviceList.containsKey(jid)) {
delta = _deviceList[jid]!.diff(devices);
} else {
delta = ListDiff(devices, []);
}
// Commit the device list // Update our state
_eventStreamController.add( _deviceList[jid] = devices;
DeviceListModifiedEvent(jid, devices), _deviceListRequested[jid] = true;
// Commit the device list
_eventStreamController.add(
DeviceListModifiedEvent(jid, delta.added, delta.removed),
);
},
); );
} }

33
test/helpers_test.dart Normal file
View File

@ -0,0 +1,33 @@
import 'package:omemo_dart/src/helpers.dart';
import 'package:omemo_dart/src/omemo/queue.dart';
import 'package:test/test.dart';
void main() {
group('List diff', () {
test('Empty list to full list', () {
final result = <int>[].diff([1, 2, 3, 4]);
expect(result.removed, isEmpty);
expect(
result.added.containsAll([1, 2, 3, 4]),
isTrue,
);
expect(result.added.length, 4);
});
test('Full list to empty list', () {
final result = [1, 2, 3, 4].diff([]);
expect(result.added, isEmpty);
expect(
result.removed.containsAll([1, 2, 3, 4]),
isTrue,
);
expect(result.removed.length, 4);
});
test('Full list to full list', () {
final result = [1, 2, 3, 4].diff([1, 2, 4, 5]);
expect(result.added, [5]);
expect(result.removed, [3]);
});
});
}