update method

Future<void> update(
  1. ReceiptEventContent content,
  2. Room room
)

Implementation

Future<void> update(
  ReceiptEventContent content,
  Room room,
) async {
  final List<LatestReceiptStateForTimeline> updatedTimelines = [];
  final ownUserid = room.client.userID!;

  content.receipts.forEach((eventId, receiptsByType) {
    receiptsByType.forEach((receiptType, receiptsByUser) {
      receiptsByUser.forEach((user, receipt) {
        LatestReceiptStateForTimeline? timeline;
        final threadId = receipt.threadId;
        if (threadId == 'main') {
          timeline = (mainThread ??= LatestReceiptStateForTimeline.empty());
        } else if (threadId != null) {
          timeline =
              (byThread[threadId] ??= LatestReceiptStateForTimeline.empty());
        } else {
          timeline = global;
        }

        final receiptData =
            LatestReceiptStateData(eventId, receipt.originServerTs);
        if (user == ownUserid) {
          if (receiptType == ReceiptType.mReadPrivate) {
            timeline.ownPrivate = receiptData;
          } else if (receiptType == ReceiptType.mRead) {
            timeline.ownPublic = receiptData;
          }
          updatedTimelines.add(timeline);
        } else {
          timeline.otherUsers[user] = receiptData;
        }
      });
    });
  });

  // set the latest receipt to the one furthest down in the timeline, or if we don't know that, the newest ts.
  if (updatedTimelines.isEmpty) return;

  final eventOrder = await room.client.database?.getEventIdList(room) ?? [];

  for (final timeline in updatedTimelines) {
    if (timeline.ownPrivate?.eventId == timeline.ownPublic?.eventId) {
      if (timeline.ownPrivate != null) {
        timeline.latestOwnReceipt = timeline.ownPrivate;
      }
      continue;
    }

    final public = timeline.ownPublic;
    final private = timeline.ownPrivate;

    if (private == null) {
      timeline.latestOwnReceipt = public;
    } else if (public == null) {
      timeline.latestOwnReceipt = private;
    } else {
      final privatePos = eventOrder.indexOf(private.eventId);
      final publicPos = eventOrder.indexOf(public.eventId);

      if (publicPos < 0 ||
          privatePos <= publicPos ||
          (privatePos < 0 && private.ts > public.ts)) {
        timeline.latestOwnReceipt = private;
      } else {
        timeline.latestOwnReceipt = public;
      }
    }
  }
}