RealtimePresence constructor

RealtimePresence(
  1. RealtimeChannel channel, [
  2. PresenceOpts? opts
])

Initializes the Presence

channel - The RealtimeChannel

opts - The options, for example PresenceOpts(events: PresenceEvents(state: 'state', diff: 'diff'))

Implementation

RealtimePresence(this.channel, [PresenceOpts? opts]) {
  final events = opts?.events ??
      PresenceEvents(state: 'presence_state', diff: 'presence_diff');

  channel.onEvents(events.state, ChannelFilter(), (newState, [_]) {
    final onJoin = caller['onJoin'];
    final onLeave = caller['onLeave'];
    final onSync = caller['onSync'];

    joinRef = channel.joinRef;

    state = RealtimePresence.syncState(
      state,
      newState,
      onJoin,
      onLeave,
    );

    for (final diff in pendingDiffs) {
      state = RealtimePresence.syncDiff(
        state,
        diff,
        onJoin,
        onLeave,
      );
    }

    pendingDiffs = [];

    onSync();
  });

  channel.onEvents(events.diff, ChannelFilter(), (diff, [_]) {
    final onJoin = caller['onJoin'];
    final onLeave = caller['onLeave'];
    final onSync = caller['onSync'];

    if (inPendingSyncState()) {
      pendingDiffs.add(diff);
    } else {
      state = RealtimePresence.syncDiff(
        state,
        diff,
        onJoin,
        onLeave,
      );

      onSync();
    }
  });

  onJoin((key, currentPresences, newPresences) {
    channel.trigger(
      'presence',
      {
        'event': 'join',
        'key': key,
        'currentPresences': currentPresences,
        'newPresences': newPresences,
      },
    );
  });

  onLeave((key, currentPresences, leftPresences) {
    channel.trigger(
      'presence',
      {
        'event': 'leave',
        'key': key,
        'currentPresences': currentPresences,
        'leftPresences': leftPresences,
      },
    );
  });

  onSync(() => channel.trigger('presence', {'event': 'sync'}));
}