handleDiff method
Future<void>
handleDiff( - 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);
}
}
}
}