handleDiff method

Future<void> handleDiff(
  1. dynamic diff
)

Implementation

Future<void> handleDiff(RoomMessageDiff diff) async {
  List<PostProcessItem> postProcessing = [];
  switch (diff.action()) {
    case 'Append':
      List<RoomMessage> messages = diff.values()!.toList();
      List<types.Message> messagesToAdd = [];
      for (final m in messages) {
        final message = parseMessage(m);
        messagesToAdd.add(message);
        postProcessing.add(PostProcessItem(m, message));
      }
      if (messagesToAdd.isNotEmpty) {
        final newList = messagesCopy();
        newList.addAll(messagesToAdd);
        setMessages(newList);
      }
      break;
    case 'Set': // used to update UnableToDecrypt message
      RoomMessage m = diff.value()!;
      final index = diff.index()!;
      final message = parseMessage(m);
      replaceMessageAt(index, message);
      postProcessing.add(PostProcessItem(m, message));
      break;
    case 'Insert':
      RoomMessage m = diff.value()!;
      final index = diff.index()!;
      final message = parseMessage(m);
      insertMessage(index, message);
      postProcessing.add(PostProcessItem(m, message));
      break;
    case 'Remove':
      int index = diff.index()!;
      removeMessage(index);
      break;
    case 'PushBack':
      RoomMessage m = diff.value()!;
      final message = parseMessage(m);
      final newList = messagesCopy();
      newList.add(message);
      setMessages(newList);
      postProcessing.add(PostProcessItem(m, message));
      break;
    case 'PushFront':
      RoomMessage m = diff.value()!;
      final message = parseMessage(m);
      insertMessage(0, message);
      postProcessing.add(PostProcessItem(m, message));
      break;
    case 'PopBack':
      final newList = messagesCopy();
      newList.removeLast();
      setMessages(newList);
      break;
    case 'PopFront':
      final newList = messagesCopy();
      newList.removeAt(0);
      setMessages(newList);
      break;
    case 'Clear':
      setMessages([]);
      break;
    case 'Reset':
      List<RoomMessage> messages = diff.values()!.toList();
      List<types.Message> newList = [];
      for (final m in messages) {
        final message = parseMessage(m);
        newList.add(message);
        postProcessing.add(PostProcessItem(m, message));
      }
      if (newList.isNotEmpty) {
        setMessages(newList);
      }
      break;
    case 'Truncate':
      final length = diff.index()!;
      final newList = messagesCopy();
      setMessages(newList.take(length).toList());
      break;
    default:
      break;
  }

  // ensure we are done with the state list to avoid
  // races between the async tasks and the diff
  if (postProcessing.isNotEmpty) {
    for (final p in postProcessing) {
      final message = p.message;
      final m = p.event;
      final repliedTo = getRepliedTo(message);
      if (repliedTo != null) {
        await fetchOriginalContent(repliedTo, message.id);
      }
      RoomEventItem? eventItem = m.eventItem();
      if (eventItem != null && message.remoteId != null) {
        await fetchMediaBinary(
          eventItem.msgType(),
          message.remoteId!,
          message.id,
        );
      }
    }
  }
}