handleDiff method

Future<void> handleDiff(
  1. dynamic diff
)

Implementation

Future<void> handleDiff(RoomMessageDiff diff) async {
  List<PostProcessItem> postProcessing = [];
  switch (diff.action()) {
    case 'Append':
      final values = diff.values();
      if (values == null) {
        _log.severe('On append action, values should be available');
        return;
      }
      List<RoomMessage> messages = 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
      final value = diff.value();
      if (value == null) {
        _log.severe('On set action, value should be available');
        return;
      }
      final index = diff.index();
      if (index == null) {
        _log.severe('On set action, index should be available');
        return;
      }
      final message = parseMessage(value);
      replaceMessageAt(index, message);
      postProcessing.add(PostProcessItem(value, message));
      break;
    case 'Insert':
      final value = diff.value();
      if (value == null) {
        _log.severe('On insert action, value should be available');
        return;
      }
      final index = diff.index();
      if (index == null) {
        _log.severe('On insert action, index should be available');
        return;
      }
      final message = parseMessage(value);
      insertMessage(index, message);
      postProcessing.add(PostProcessItem(value, message));
      break;
    case 'Remove':
      final index = diff.index();
      if (index == null) {
        _log.severe('On remove action, index should be available');
        return;
      }
      removeMessage(index);
      break;
    case 'PushBack':
      final value = diff.value();
      if (value == null) {
        _log.severe('On push back action, value should be available');
        return;
      }
      final message = parseMessage(value);
      final newList = messagesCopy();
      newList.add(message);
      setMessages(newList);
      postProcessing.add(PostProcessItem(value, message));
      break;
    case 'PushFront':
      final value = diff.value();
      if (value == null) {
        _log.severe('On push front action, value should be available');
        return;
      }
      final message = parseMessage(value);
      insertMessage(0, message);
      postProcessing.add(PostProcessItem(value, 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':
      final values = diff.values();
      if (values == null) {
        _log.severe('On reset action, values should be available');
        return;
      }
      List<types.Message> newList = [];
      for (final m in values.toList()) {
        final message = parseMessage(m);
        newList.add(message);
        postProcessing.add(PostProcessItem(m, message));
      }
      if (newList.isNotEmpty) {
        setMessages(newList);
      }
      break;
    case 'Truncate':
      final index = diff.index();
      if (index == null) {
        _log.severe('On truncate action, index should be available');
        return;
      }
      final newList = messagesCopy();
      setMessages(newList.take(index).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();
      final remoteId = message.remoteId;
      if (eventItem != null && remoteId != null) {
        await fetchMediaBinary(eventItem.msgType(), remoteId, message.id);
      }
    }
  }
}