syncDiff static method

Map<String, List<Presence>> syncDiff(
  1. Map<String, List<Presence>> state,
  2. Map<String, dynamic> diff, [
  3. PresenceOnJoinCallback? onJoin,
  4. PresenceOnLeaveCallback? onLeave,
])

Used to sync a diff of presence join and leave events from the server, as they happen.

Like syncState, syncDiff accepts optional onJoin and onLeave callbacks to react to a user joining or leaving from a device.

Implementation

static Map<String, List<Presence>> syncDiff(
  Map<String, List<Presence>> state,
  Map<String, dynamic> diff, [
  PresenceOnJoinCallback? onJoin,
  PresenceOnLeaveCallback? onLeave,
]) {
  final joins = _transformState(diff['joins']);
  final leaves = _transformState(diff['leaves']);

  onJoin ??= (_, __, ___) => {};

  onLeave ??= (_, __, ___) => {};

  _map(joins, (key, newPresences) {
    final currentPresences = state[key] ?? [];
    state[key] = (newPresences as List).map((presence) {
      return presence.deepClone() as Presence;
    }).toList();

    if (currentPresences.isNotEmpty) {
      final joinedPresenceRefs =
          state[key]!.map((m) => m.presenceRef).toList();
      final curPresences = currentPresences
          .where((m) => !joinedPresenceRefs.contains(m.presenceRef))
          .toList();

      state[key]!.insertAll(0, curPresences);
    }

    onJoin!(key, currentPresences, newPresences);
  });

  _map(leaves, (key, leftPresences) {
    var currentPresences = state[key];

    if (currentPresences == null) return;

    final presenceRefsToRemove = (leftPresences as List)
        .map((leftPresence) => leftPresence.presenceRef as String)
        .toList();

    currentPresences = currentPresences
        .where((presence) =>
            !presenceRefsToRemove.contains(presence.presenceRef))
        .toList();

    state[key] = currentPresences;

    onLeave!(key, currentPresences, leftPresences);

    if (currentPresences.isEmpty) {
      state.remove(key);
    }
  });

  return state;
}