refactor: Replace all logic regarding sortOrder
The current implementation of sortOrder can be made way more easier now by just keeping the sortOrder of the list and the timelineFragments in the hiveStore. This needed a huge change but mostly removes a lot of code which can be done way more easy now. This also needed some rewriting of the setState logic and changes to the prevEvent calculation. This solution should also be more stable. More information: https://www.reddit.com/r/fluffychat/comments/pfnlhq/the_sort_order_of_matrix_timelines/
This commit is contained in:
parent
803c7598c6
commit
9c1f79359e
|
|
@ -273,7 +273,6 @@ class Encryption {
|
|||
stateKey: event.stateKey,
|
||||
prevContent: event.prevContent,
|
||||
status: event.status,
|
||||
sortOrder: event.sortOrder,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +306,6 @@ class Encryption {
|
|||
content: event.toJson(),
|
||||
roomID: event.roomId,
|
||||
type: updateType,
|
||||
sortOrder: event.sortOrder,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -678,7 +678,6 @@ class Client extends MatrixApi {
|
|||
leftRoom.setState(Event.fromMatrixEvent(
|
||||
event,
|
||||
leftRoom,
|
||||
sortOrder: event.originServerTs.millisecondsSinceEpoch.toDouble(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -687,7 +686,6 @@ class Client extends MatrixApi {
|
|||
leftRoom.setState(Event.fromMatrixEvent(
|
||||
event,
|
||||
leftRoom,
|
||||
sortOrder: event.originServerTs.millisecondsSinceEpoch.toDouble(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1264,14 +1262,8 @@ class Client extends MatrixApi {
|
|||
await database.storeRoomUpdate(this.id, update, getRoomById(id));
|
||||
}
|
||||
_updateRoomsByRoomUpdate(update);
|
||||
final roomObj = getRoomById(id);
|
||||
if (update.limitedTimeline && roomObj != null) {
|
||||
roomObj.resetSortOrder();
|
||||
}
|
||||
onRoomUpdate.add(update);
|
||||
|
||||
var handledEvents = false;
|
||||
|
||||
/// Handle now all room events and save them in the database
|
||||
if (room is JoinedRoomUpdate) {
|
||||
if (room.state?.isNotEmpty ?? false) {
|
||||
|
|
@ -1279,7 +1271,6 @@ class Client extends MatrixApi {
|
|||
await _handleRoomEvents(id,
|
||||
room.state.map((i) => i.toJson()).toList(), EventUpdateType.state,
|
||||
sortAtTheEnd: sortAtTheEnd);
|
||||
handledEvents = true;
|
||||
}
|
||||
if (room.timeline?.events?.isNotEmpty ?? false) {
|
||||
await _handleRoomEvents(
|
||||
|
|
@ -1287,7 +1278,6 @@ class Client extends MatrixApi {
|
|||
room.timeline.events.map((i) => i.toJson()).toList(),
|
||||
sortAtTheEnd ? EventUpdateType.history : EventUpdateType.timeline,
|
||||
sortAtTheEnd: sortAtTheEnd);
|
||||
handledEvents = true;
|
||||
}
|
||||
if (room.ephemeral?.isNotEmpty ?? false) {
|
||||
// TODO: This method seems to be comperatively slow for some updates
|
||||
|
|
@ -1308,7 +1298,6 @@ class Client extends MatrixApi {
|
|||
room.timeline.events.map((i) => i.toJson()).toList(),
|
||||
EventUpdateType.timeline,
|
||||
sortAtTheEnd: sortAtTheEnd);
|
||||
handledEvents = true;
|
||||
}
|
||||
if (room.accountData?.isNotEmpty ?? false) {
|
||||
await _handleRoomEvents(
|
||||
|
|
@ -1321,7 +1310,6 @@ class Client extends MatrixApi {
|
|||
id,
|
||||
room.state.map((i) => i.toJson()).toList(),
|
||||
EventUpdateType.state);
|
||||
handledEvents = true;
|
||||
}
|
||||
}
|
||||
if (room is InvitedRoomUpdate &&
|
||||
|
|
@ -1331,9 +1319,6 @@ class Client extends MatrixApi {
|
|||
room.inviteState.map((i) => i.toJson()).toList(),
|
||||
EventUpdateType.inviteState);
|
||||
}
|
||||
if (handledEvents && database != null && roomObj != null) {
|
||||
await roomObj.updateSortOrder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1404,16 +1389,10 @@ class Client extends MatrixApi {
|
|||
return;
|
||||
}
|
||||
|
||||
// ephemeral events aren't persisted and don't need a sort order - they are
|
||||
// expected to be processed as soon as they come in
|
||||
final sortOrder = type != EventUpdateType.ephemeral
|
||||
? (sortAtTheEnd ? room.oldSortOrder : room.newSortOrder)
|
||||
: 0.0;
|
||||
var update = EventUpdate(
|
||||
roomID: roomID,
|
||||
type: type,
|
||||
content: event,
|
||||
sortOrder: sortOrder,
|
||||
);
|
||||
if (event['type'] == EventTypes.Encrypted && encryptionEnabled) {
|
||||
update = await update.decrypt(room);
|
||||
|
|
@ -1441,17 +1420,13 @@ class Client extends MatrixApi {
|
|||
|
||||
if (prevBatch != null && type == EventUpdateType.timeline) {
|
||||
if (rawUnencryptedEvent['type'] == EventTypes.CallInvite) {
|
||||
onCallInvite
|
||||
.add(Event.fromJson(rawUnencryptedEvent, room, sortOrder));
|
||||
onCallInvite.add(Event.fromJson(rawUnencryptedEvent, room));
|
||||
} else if (rawUnencryptedEvent['type'] == EventTypes.CallHangup) {
|
||||
onCallHangup
|
||||
.add(Event.fromJson(rawUnencryptedEvent, room, sortOrder));
|
||||
onCallHangup.add(Event.fromJson(rawUnencryptedEvent, room));
|
||||
} else if (rawUnencryptedEvent['type'] == EventTypes.CallAnswer) {
|
||||
onCallAnswer
|
||||
.add(Event.fromJson(rawUnencryptedEvent, room, sortOrder));
|
||||
onCallAnswer.add(Event.fromJson(rawUnencryptedEvent, room));
|
||||
} else if (rawUnencryptedEvent['type'] == EventTypes.CallCandidates) {
|
||||
onCallCandidates
|
||||
.add(Event.fromJson(rawUnencryptedEvent, room, sortOrder));
|
||||
onCallCandidates.add(Event.fromJson(rawUnencryptedEvent, room));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1524,18 +1499,7 @@ class Client extends MatrixApi {
|
|||
case EventUpdateType.timeline:
|
||||
case EventUpdateType.state:
|
||||
case EventUpdateType.inviteState:
|
||||
final stateEvent =
|
||||
Event.fromJson(eventUpdate.content, room, eventUpdate.sortOrder);
|
||||
final prevState = room.getState(stateEvent.type, stateEvent.stateKey);
|
||||
if (eventUpdate.type == EventUpdateType.timeline &&
|
||||
prevState != null &&
|
||||
prevState.sortOrder > stateEvent.sortOrder) {
|
||||
Logs().w('''
|
||||
A new ${eventUpdate.type} event of the type ${stateEvent.type} has arrived with a previews
|
||||
sort order ${stateEvent.sortOrder} than the current ${stateEvent.type} event with a
|
||||
sort order of ${prevState.sortOrder}. This should never happen...''');
|
||||
return;
|
||||
}
|
||||
final stateEvent = Event.fromJson(eventUpdate.content, room);
|
||||
if (stateEvent.type == EventTypes.Redaction) {
|
||||
final String redacts = eventUpdate.content['redacts'];
|
||||
room.states.forEach(
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import 'package:hive/hive.dart';
|
|||
///
|
||||
/// This database does not support file caching!
|
||||
class FamedlySdkHiveDatabase extends DatabaseApi {
|
||||
static const int version = 3;
|
||||
static const int version = 4;
|
||||
final String name;
|
||||
late Box _clientBox;
|
||||
late Box _accountDataBox;
|
||||
|
|
@ -310,9 +310,13 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
|
||||
@override
|
||||
Future<List<Event>> getEventList(int clientId, Room room) async {
|
||||
final List eventIds =
|
||||
final List timelineEventIds =
|
||||
(await _timelineFragmentsBox.get(MultiKey(room.id, '').toString()) ??
|
||||
[]);
|
||||
final List sendingEventIds = (await _timelineFragmentsBox
|
||||
.get(MultiKey(room.id, 'SENDING').toString()) ??
|
||||
[]);
|
||||
final eventIds = sendingEventIds + timelineEventIds;
|
||||
final events = await Future.wait(eventIds
|
||||
.map(
|
||||
(eventId) async => Event.fromJson(
|
||||
|
|
@ -323,7 +327,6 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
),
|
||||
)
|
||||
.toList());
|
||||
events.sort((a, b) => b.sortOrder.compareTo(a.sortOrder));
|
||||
return events;
|
||||
}
|
||||
|
||||
|
|
@ -812,7 +815,6 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
eventUpdate.content['unsigned'] ??= <String, dynamic>{};
|
||||
eventUpdate.content['unsigned'][messageSendingStatusKey] =
|
||||
eventUpdate.content['status'] = status;
|
||||
eventUpdate.content['unsigned'][sortOrderKey] = eventUpdate.sortOrder;
|
||||
|
||||
// In case this event has sent from this account we have a transaction ID
|
||||
final transactionId = eventUpdate.content
|
||||
|
|
@ -823,13 +825,28 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
eventUpdate.content);
|
||||
|
||||
// Update timeline fragments
|
||||
final key = MultiKey(eventUpdate.roomID, '').toString();
|
||||
final key =
|
||||
MultiKey(eventUpdate.roomID, status == 2 ? '' : 'SENDING').toString();
|
||||
final List eventIds = (await _timelineFragmentsBox.get(key) ?? []);
|
||||
if (!eventIds.any((id) => id == eventId)) {
|
||||
eventIds.add(eventId);
|
||||
if (!eventIds.contains(eventId)) {
|
||||
if (eventUpdate.type == EventUpdateType.history) {
|
||||
eventIds.add(eventId);
|
||||
} else {
|
||||
eventIds.insert(0, eventId);
|
||||
}
|
||||
await _timelineFragmentsBox.put(key, eventIds);
|
||||
}
|
||||
|
||||
// If event comes from server timeline, remove sending events with this ID
|
||||
if (status == 2) {
|
||||
final key = MultiKey(eventUpdate.roomID, 'SENDING').toString();
|
||||
final List eventIds = (await _timelineFragmentsBox.get(key) ?? []);
|
||||
final i = eventIds.indexWhere((id) => id == eventId);
|
||||
if (i != -1) {
|
||||
await _timelineFragmentsBox.put(key, eventIds..removeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Is there a transaction id? Then delete the event with this id.
|
||||
if (status != -1 && status != 0 && transactionId != null) {
|
||||
await removeEvent(clientId, transactionId, eventUpdate.roomID);
|
||||
|
|
@ -979,10 +996,6 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
prev_batch: roomUpdate.prev_batch ?? currentRoom.prev_batch,
|
||||
summary: RoomSummary.fromJson(currentRoom.summary.toJson()
|
||||
..addAll(roomUpdate.summary?.toJson() ?? {})),
|
||||
newestSortOrder:
|
||||
roomUpdate.limitedTimeline ? 0.0 : currentRoom.newSortOrder,
|
||||
oldestSortOrder:
|
||||
roomUpdate.limitedTimeline ? 0.0 : currentRoom.oldSortOrder,
|
||||
).toJson());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,21 +79,19 @@ class Event extends MatrixEvent {
|
|||
|
||||
User get stateKeyUser => room.getUserByMXIDSync(stateKey);
|
||||
|
||||
double sortOrder;
|
||||
|
||||
Event(
|
||||
{this.status = defaultStatus,
|
||||
Map<String, dynamic> content,
|
||||
String type,
|
||||
String eventId,
|
||||
String roomId,
|
||||
String senderId,
|
||||
DateTime originServerTs,
|
||||
Map<String, dynamic> unsigned,
|
||||
Map<String, dynamic> prevContent,
|
||||
String stateKey,
|
||||
this.room,
|
||||
this.sortOrder = 0.0}) {
|
||||
Event({
|
||||
this.status = defaultStatus,
|
||||
Map<String, dynamic> content,
|
||||
String type,
|
||||
String eventId,
|
||||
String roomId,
|
||||
String senderId,
|
||||
DateTime originServerTs,
|
||||
Map<String, dynamic> unsigned,
|
||||
Map<String, dynamic> prevContent,
|
||||
String stateKey,
|
||||
this.room,
|
||||
}) {
|
||||
this.content = content;
|
||||
this.type = type;
|
||||
this.eventId = eventId;
|
||||
|
|
@ -156,7 +154,6 @@ class Event extends MatrixEvent {
|
|||
factory Event.fromMatrixEvent(
|
||||
MatrixEvent matrixEvent,
|
||||
Room room, {
|
||||
double sortOrder,
|
||||
int status,
|
||||
}) =>
|
||||
Event(
|
||||
|
|
@ -171,12 +168,13 @@ class Event extends MatrixEvent {
|
|||
prevContent: matrixEvent.prevContent,
|
||||
stateKey: matrixEvent.stateKey,
|
||||
room: room,
|
||||
sortOrder: sortOrder,
|
||||
);
|
||||
|
||||
/// Get a State event from a table row or from the event stream.
|
||||
factory Event.fromJson(Map<String, dynamic> jsonPayload, Room room,
|
||||
[double sortOrder]) {
|
||||
factory Event.fromJson(
|
||||
Map<String, dynamic> jsonPayload,
|
||||
Room room,
|
||||
) {
|
||||
final content = Event.getMapFromPayload(jsonPayload['content']);
|
||||
final unsigned = Event.getMapFromPayload(jsonPayload['unsigned']);
|
||||
final prevContent = Event.getMapFromPayload(jsonPayload['prev_content']);
|
||||
|
|
@ -196,7 +194,6 @@ class Event extends MatrixEvent {
|
|||
: DateTime.now(),
|
||||
unsigned: unsigned,
|
||||
room: room,
|
||||
sortOrder: sortOrder ?? unsigned.tryGet<num>(sortOrderKey) ?? 0.0,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -311,14 +308,14 @@ class Event extends MatrixEvent {
|
|||
await room.client.database?.removeEvent(room.client.id, eventId, room.id);
|
||||
|
||||
room.client.onEvent.add(EventUpdate(
|
||||
roomID: room.id,
|
||||
type: EventUpdateType.timeline,
|
||||
content: {
|
||||
'event_id': eventId,
|
||||
'status': -2,
|
||||
'content': {'body': 'Removed...'}
|
||||
},
|
||||
sortOrder: sortOrder));
|
||||
roomID: room.id,
|
||||
type: EventUpdateType.timeline,
|
||||
content: {
|
||||
'event_id': eventId,
|
||||
'status': -2,
|
||||
'content': {'body': 'Removed...'}
|
||||
},
|
||||
));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -702,7 +699,11 @@ class Event extends MatrixEvent {
|
|||
// we need to check again if it isn't empty, as we potentially removed all
|
||||
// aggregated edits
|
||||
if (allEditEvents.isNotEmpty) {
|
||||
allEditEvents.sort((a, b) => a.sortOrder - b.sortOrder > 0 ? 1 : -1);
|
||||
allEditEvents.sort((a, b) => a.originServerTs.millisecondsSinceEpoch -
|
||||
b.originServerTs.millisecondsSinceEpoch >
|
||||
0
|
||||
? 1
|
||||
: -1);
|
||||
final rawEvent = allEditEvents.last.toJson();
|
||||
// update the content of the new event to render
|
||||
if (rawEvent['content']['m.new_content'] is Map) {
|
||||
|
|
|
|||
|
|
@ -96,9 +96,6 @@ class Room {
|
|||
/// Key-Value store for private account data only visible for this user.
|
||||
Map<String, BasicRoomEvent> roomAccountData = {};
|
||||
|
||||
double _newestSortOrder;
|
||||
double _oldestSortOrder;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'membership': membership.toString().split('.').last,
|
||||
|
|
@ -126,29 +123,6 @@ class Room {
|
|||
oldestSortOrder: json['oldest_sort_order'].toDouble(),
|
||||
);
|
||||
|
||||
double get newSortOrder {
|
||||
var now = DateTime.now().millisecondsSinceEpoch.toDouble();
|
||||
if (_newestSortOrder >= now) {
|
||||
now = _newestSortOrder + 1;
|
||||
}
|
||||
_newestSortOrder = now;
|
||||
return _newestSortOrder;
|
||||
}
|
||||
|
||||
double get oldSortOrder {
|
||||
_oldestSortOrder--;
|
||||
return _oldestSortOrder;
|
||||
}
|
||||
|
||||
void resetSortOrder() {
|
||||
_oldestSortOrder = _newestSortOrder = 0.0;
|
||||
}
|
||||
|
||||
Future<void> updateSortOrder() async {
|
||||
await client.database?.updateRoomSortOrder(
|
||||
_oldestSortOrder, _newestSortOrder, client.id, id);
|
||||
}
|
||||
|
||||
/// Flag if the room is partial, meaning not all state events have been loaded yet
|
||||
bool partial = true;
|
||||
|
||||
|
|
@ -185,20 +159,33 @@ class Room {
|
|||
Logs().e('[LibOlm] Could not decrypt room state', e, s);
|
||||
}
|
||||
}
|
||||
if (!(state.stateKey is String) &&
|
||||
![EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
|
||||
.contains(state.type) ||
|
||||
(state.type == EventTypes.Message &&
|
||||
state.messageType.startsWith('m.room.verification.'))) {
|
||||
|
||||
// We ignore room verification events for lastEvents
|
||||
if (state.type == EventTypes.Message &&
|
||||
state.messageType.startsWith('m.room.verification.')) {
|
||||
return;
|
||||
}
|
||||
final oldStateEvent = getState(state.type, state.stateKey ?? '');
|
||||
if (oldStateEvent != null && oldStateEvent.sortOrder >= state.sortOrder) {
|
||||
|
||||
final isMessageEvent = [
|
||||
EventTypes.Message,
|
||||
EventTypes.Sticker,
|
||||
EventTypes.Encrypted,
|
||||
].contains(state.type);
|
||||
|
||||
// We ignore events relating to events older than the current-latest here so
|
||||
// i.e. newly sent edits for older events don't show up in room preview
|
||||
if (isMessageEvent &&
|
||||
state.relationshipEventId != null &&
|
||||
state.relationshipEventId != lastEvent?.eventId) {
|
||||
return;
|
||||
}
|
||||
if (!states.containsKey(state.type)) {
|
||||
states[state.type] = {};
|
||||
|
||||
// Ignore other non-state events
|
||||
if (!isMessageEvent && state.stateKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
states[state.type] ??= {};
|
||||
states[state.type][state.stateKey ?? ''] = state;
|
||||
}
|
||||
|
||||
|
|
@ -340,13 +327,16 @@ class Room {
|
|||
var lastEvent = lastEvents.isEmpty
|
||||
? null
|
||||
: lastEvents.reduce((a, b) {
|
||||
if (a.sortOrder == b.sortOrder) {
|
||||
if (a.originServerTs == b.originServerTs) {
|
||||
// if two events have the same sort order we want to give encrypted events a lower priority
|
||||
// This is so that if the same event exists in the state both encrypted *and* unencrypted,
|
||||
// the unencrypted one is picked
|
||||
return a.type == EventTypes.Encrypted ? b : a;
|
||||
}
|
||||
return a.sortOrder > b.sortOrder ? a : b;
|
||||
return a.originServerTs.millisecondsSinceEpoch >
|
||||
b.originServerTs.millisecondsSinceEpoch
|
||||
? a
|
||||
: b;
|
||||
});
|
||||
if (lastEvent == null) {
|
||||
states.forEach((final String key, final entry) {
|
||||
|
|
@ -385,9 +375,7 @@ class Room {
|
|||
double newestSortOrder = 0.0,
|
||||
double oldestSortOrder = 0.0,
|
||||
RoomSummary summary,
|
||||
}) : _newestSortOrder = newestSortOrder,
|
||||
_oldestSortOrder = oldestSortOrder,
|
||||
notificationCount = notificationCount ?? 0,
|
||||
}) : notificationCount = notificationCount ?? 0,
|
||||
highlightCount = highlightCount ?? 0,
|
||||
roomAccountData = roomAccountData ?? <String, BasicRoomEvent>{},
|
||||
summary = summary ??
|
||||
|
|
@ -987,7 +975,6 @@ class Room {
|
|||
await client.database.transaction(() async {
|
||||
await client.database.setRoomPrevBatch(resp.end, client.id, id);
|
||||
await loadFn();
|
||||
await updateSortOrder();
|
||||
});
|
||||
} else {
|
||||
await loadFn();
|
||||
|
|
@ -1268,10 +1255,10 @@ class Room {
|
|||
await client.database.storeEventUpdate(
|
||||
client.id,
|
||||
EventUpdate(
|
||||
content: content,
|
||||
roomID: id,
|
||||
type: EventUpdateType.state,
|
||||
sortOrder: 0.0),
|
||||
content: content,
|
||||
roomID: id,
|
||||
type: EventUpdateType.state,
|
||||
),
|
||||
);
|
||||
});
|
||||
onUpdate.add(id);
|
||||
|
|
|
|||
|
|
@ -95,10 +95,9 @@ class Timeline {
|
|||
_collectHistoryUpdates = false;
|
||||
for (final update in _historyUpdates) {
|
||||
_handleEventUpdate(await update.decrypt(room, store: true),
|
||||
sortAndUpdate: false);
|
||||
update: false);
|
||||
}
|
||||
_historyUpdates.clear();
|
||||
_sort();
|
||||
if (onUpdate != null) onUpdate();
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +121,6 @@ class Timeline {
|
|||
for (final e in events) {
|
||||
addAggregatedEvent(e);
|
||||
}
|
||||
_sort();
|
||||
}
|
||||
|
||||
/// Don't forget to call this before you dismiss this object!
|
||||
|
|
@ -245,8 +243,7 @@ class Timeline {
|
|||
}
|
||||
}
|
||||
|
||||
void _handleEventUpdate(EventUpdate eventUpdate,
|
||||
{bool sortAndUpdate = true}) {
|
||||
void _handleEventUpdate(EventUpdate eventUpdate, {bool update = true}) {
|
||||
try {
|
||||
if (eventUpdate.roomID != room.id) return;
|
||||
|
||||
|
|
@ -270,8 +267,10 @@ class Timeline {
|
|||
final eventId = _findEvent(event_id: eventUpdate.content['redacts']);
|
||||
if (eventId < events.length) {
|
||||
removeAggregatedEvent(events[eventId]);
|
||||
events[eventId].setRedactionEvent(
|
||||
Event.fromJson(eventUpdate.content, room, eventUpdate.sortOrder));
|
||||
events[eventId].setRedactionEvent(Event.fromJson(
|
||||
eventUpdate.content,
|
||||
room,
|
||||
));
|
||||
}
|
||||
} else if (status == -2) {
|
||||
final i = _findEvent(event_id: eventUpdate.content['event_id']);
|
||||
|
|
@ -290,53 +289,49 @@ class Timeline {
|
|||
// if the old status is larger than the new one, we also want to preserve the old status
|
||||
final oldStatus = events[i].status;
|
||||
events[i] = Event.fromJson(
|
||||
eventUpdate.content,
|
||||
room,
|
||||
eventUpdate.type == EventUpdateType.history
|
||||
? events[i].sortOrder
|
||||
: eventUpdate.sortOrder);
|
||||
eventUpdate.content,
|
||||
room,
|
||||
);
|
||||
// do we preserve the status? we should allow 0 -> -1 updates and status increases
|
||||
if (status < oldStatus && !(status == -1 && oldStatus == 0)) {
|
||||
events[i].status = oldStatus;
|
||||
}
|
||||
addAggregatedEvent(events[i]);
|
||||
} else {
|
||||
final newEvent =
|
||||
Event.fromJson(eventUpdate.content, room, eventUpdate.sortOrder);
|
||||
final newEvent = Event.fromJson(
|
||||
eventUpdate.content,
|
||||
room,
|
||||
);
|
||||
|
||||
if (eventUpdate.type == EventUpdateType.history &&
|
||||
events.indexWhere(
|
||||
(e) => e.eventId == eventUpdate.content['event_id']) !=
|
||||
-1) return;
|
||||
|
||||
events.insert(0, newEvent);
|
||||
if (eventUpdate.type == EventUpdateType.history) {
|
||||
events.add(newEvent);
|
||||
} else if (status == -1) {
|
||||
events.insert(events.firstIndexWhereNotError, newEvent);
|
||||
} else {
|
||||
events.insert(events.firstIndexWhereNotError, newEvent);
|
||||
}
|
||||
addAggregatedEvent(newEvent);
|
||||
if (onInsert != null) onInsert(0);
|
||||
}
|
||||
}
|
||||
if (sortAndUpdate) {
|
||||
_sort();
|
||||
if (update) {
|
||||
if (onUpdate != null) onUpdate();
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logs().w('Handle event update failed', e, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _sortLock = false;
|
||||
|
||||
void _sort() {
|
||||
if (_sortLock || events.length < 2) return;
|
||||
_sortLock = true;
|
||||
events?.sort((a, b) {
|
||||
if (b.status == -1 && a.status != -1) {
|
||||
return 1;
|
||||
}
|
||||
if (a.status == -1 && b.status != -1) {
|
||||
return -1;
|
||||
}
|
||||
return b.sortOrder - a.sortOrder > 0 ? 1 : -1;
|
||||
});
|
||||
_sortLock = false;
|
||||
extension on List<Event> {
|
||||
int get firstIndexWhereNotError {
|
||||
if (isEmpty) return 0;
|
||||
final index = indexWhere((e) => e.status != -1);
|
||||
if (index == -1) return length;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,14 +42,10 @@ class EventUpdate {
|
|||
// The json payload of the content of this event.
|
||||
final Map<String, dynamic> content;
|
||||
|
||||
// the order where to stort this event
|
||||
final double sortOrder;
|
||||
|
||||
EventUpdate({
|
||||
required this.roomID,
|
||||
required this.type,
|
||||
required this.content,
|
||||
required this.sortOrder,
|
||||
});
|
||||
|
||||
Future<EventUpdate> decrypt(Room room, {bool store = false}) async {
|
||||
|
|
@ -59,13 +55,12 @@ class EventUpdate {
|
|||
}
|
||||
try {
|
||||
final decrpytedEvent = await room.client.encryption.decryptRoomEvent(
|
||||
room.id, Event.fromJson(content, room, sortOrder),
|
||||
room.id, Event.fromJson(content, room),
|
||||
store: store, updateType: type);
|
||||
return EventUpdate(
|
||||
roomID: roomID,
|
||||
type: type,
|
||||
content: decrpytedEvent.toJson(),
|
||||
sortOrder: sortOrder,
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().e('[LibOlm] Could not decrypt megolm event', e, s);
|
||||
|
|
|
|||
|
|
@ -192,7 +192,6 @@ void testDatabase(Future<DatabaseApi> futureDatabase, int clientId) {
|
|||
EventUpdate(
|
||||
roomID: '!testroom:example.com',
|
||||
type: EventUpdateType.timeline,
|
||||
sortOrder: DateTime.now().millisecondsSinceEpoch.toDouble(),
|
||||
content: {
|
||||
'type': EventTypes.Message,
|
||||
'content': {
|
||||
|
|
|
|||
|
|
@ -359,7 +359,6 @@ void main() {
|
|||
'session_id': sessionId,
|
||||
},
|
||||
stateKey: '',
|
||||
sortOrder: 42.0,
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.type, 'm.room.encrypted');
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ EventUpdate getLastSentEvent(KeyVerification req) {
|
|||
},
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: req.room.id,
|
||||
sortOrder: DateTime.now().millisecondsSinceEpoch.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -462,7 +461,6 @@ void main() {
|
|||
},
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: req2.room.id,
|
||||
sortOrder: DateTime.now().millisecondsSinceEpoch.toDouble(),
|
||||
));
|
||||
expect(req2.state, KeyVerificationState.error);
|
||||
|
||||
|
|
|
|||
|
|
@ -1045,7 +1045,6 @@ void main() {
|
|||
'event_id': '\$source',
|
||||
'sender': '@alice:example.org',
|
||||
}, null);
|
||||
event.sortOrder = 0;
|
||||
final edit1 = Event.fromJson({
|
||||
'type': EventTypes.Message,
|
||||
'content': {
|
||||
|
|
@ -1063,7 +1062,6 @@ void main() {
|
|||
'event_id': '\$edit1',
|
||||
'sender': '@alice:example.org',
|
||||
}, null);
|
||||
edit1.sortOrder = 1;
|
||||
final edit2 = Event.fromJson({
|
||||
'type': EventTypes.Message,
|
||||
'content': {
|
||||
|
|
@ -1081,7 +1079,6 @@ void main() {
|
|||
'event_id': '\$edit2',
|
||||
'sender': '@alice:example.org',
|
||||
}, null);
|
||||
edit2.sortOrder = 2;
|
||||
final edit3 = Event.fromJson({
|
||||
'type': EventTypes.Message,
|
||||
'content': {
|
||||
|
|
@ -1099,7 +1096,6 @@ void main() {
|
|||
'event_id': '\$edit3',
|
||||
'sender': '@bob:example.org',
|
||||
}, null);
|
||||
edit3.sortOrder = 3;
|
||||
final room = Room(client: client);
|
||||
// no edits
|
||||
var displayEvent =
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ void main() {
|
|||
Client client;
|
||||
Room room;
|
||||
Room room2;
|
||||
var sortOrder = 0.0;
|
||||
|
||||
test('setupClient', () async {
|
||||
client = await getClient();
|
||||
|
|
@ -70,7 +69,6 @@ void main() {
|
|||
},
|
||||
room: room,
|
||||
stateKey: '',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
final packs = room.getImagePacks();
|
||||
expect(packs.length, 1);
|
||||
|
|
@ -97,7 +95,6 @@ void main() {
|
|||
},
|
||||
room: room,
|
||||
stateKey: '',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
packsFlat = room.getImagePacksFlat(ImagePackUsage.emoticon);
|
||||
expect(packsFlat, {
|
||||
|
|
@ -120,7 +117,6 @@ void main() {
|
|||
},
|
||||
room: room,
|
||||
stateKey: '',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
packsFlat = room.getImagePacksFlat(ImagePackUsage.emoticon);
|
||||
expect(packsFlat, {
|
||||
|
|
@ -141,7 +137,6 @@ void main() {
|
|||
},
|
||||
room: room,
|
||||
stateKey: 'fox',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
packsFlat = room.getImagePacksFlat(ImagePackUsage.emoticon);
|
||||
expect(packsFlat, {
|
||||
|
|
@ -182,7 +177,6 @@ void main() {
|
|||
},
|
||||
room: room2,
|
||||
stateKey: '',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
client.accountData['im.ponies.emote_rooms'] = BasicEvent.fromJson({
|
||||
'type': 'im.ponies.emote_rooms',
|
||||
|
|
@ -213,7 +207,6 @@ void main() {
|
|||
},
|
||||
room: room2,
|
||||
stateKey: 'fox',
|
||||
sortOrder: sortOrder++,
|
||||
));
|
||||
client.accountData['im.ponies.emote_rooms'] = BasicEvent.fromJson({
|
||||
'type': 'im.ponies.emote_rooms',
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ void main() {
|
|||
'event_id': '\$event-1',
|
||||
'sender': '@blah:blubb',
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
var event = await database.getEventById(clientId, '\$event-1', room);
|
||||
|
|
@ -71,7 +70,6 @@ void main() {
|
|||
'sender': '@blah:blubb',
|
||||
'status': 0,
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, 'transaction-1', room);
|
||||
|
|
@ -90,7 +88,6 @@ void main() {
|
|||
},
|
||||
'status': 1,
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, 'transaction-1', room);
|
||||
|
|
@ -109,7 +106,6 @@ void main() {
|
|||
'sender': '@blah:blubb',
|
||||
'status': 0,
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, '\$event-3', room);
|
||||
|
|
@ -128,7 +124,6 @@ void main() {
|
|||
'transaction_id': 'transaction-2',
|
||||
},
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, '\$event-3', room);
|
||||
|
|
@ -149,7 +144,6 @@ void main() {
|
|||
'sender': '@blah:blubb',
|
||||
'status': 2,
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, '\$event-4', room);
|
||||
|
|
@ -168,7 +162,6 @@ void main() {
|
|||
'transaction_id': 'transaction-3',
|
||||
},
|
||||
},
|
||||
sortOrder: 0.0,
|
||||
);
|
||||
await database.storeEventUpdate(clientId, update);
|
||||
event = await database.getEventById(clientId, '\$event-4', room);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ void main() {
|
|||
room: room,
|
||||
eventId: '143273582443PhrSn:example.org',
|
||||
roomId: id,
|
||||
sortOrder: 0.0,
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||
senderId: '@example:example.org',
|
||||
type: 'm.room.join_rules',
|
||||
|
|
@ -167,15 +166,15 @@ void main() {
|
|||
expect(room.pinnedEventIds.first, '1234');
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.message',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '12345',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'abc'},
|
||||
stateKey: '',
|
||||
sortOrder: 0),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.message',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '12345',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'abc'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.eventId, '12345');
|
||||
expect(room.lastEvent.body, 'abc');
|
||||
|
|
@ -185,28 +184,28 @@ void main() {
|
|||
test('lastEvent is set properly', () {
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '1',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'cd'},
|
||||
stateKey: '',
|
||||
sortOrder: 1),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '1',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'cd'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.body, 'cd');
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '2',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'cdc'},
|
||||
stateKey: '',
|
||||
sortOrder: 2),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '2',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'cdc'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.body, 'cdc');
|
||||
room.setState(
|
||||
|
|
@ -229,53 +228,53 @@ void main() {
|
|||
expect(room.lastEvent.body, 'cdc'); // because we edited the "cd" message
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '4',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': 'edited cdc',
|
||||
'm.new_content': {'msgtype': 'm.text', 'body': 'edited cdc'},
|
||||
'm.relates_to': {'rel_type': 'm.replace', 'event_id': '2'},
|
||||
},
|
||||
stateKey: '',
|
||||
sortOrder: 4),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '4',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': 'edited cdc',
|
||||
'm.new_content': {'msgtype': 'm.text', 'body': 'edited cdc'},
|
||||
'm.relates_to': {'rel_type': 'm.replace', 'event_id': '2'},
|
||||
},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.body, 'edited cdc');
|
||||
});
|
||||
test('lastEvent when reply parent edited', () async {
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '5',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'A'},
|
||||
stateKey: '',
|
||||
sortOrder: 5),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '5',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {'msgtype': 'm.text', 'body': 'A'},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.body, 'A');
|
||||
|
||||
room.setState(
|
||||
Event(
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '6',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': 'B',
|
||||
'm.relates_to': {'rel_type': 'm.in_reply_to', 'event_id': '5'}
|
||||
},
|
||||
stateKey: '',
|
||||
sortOrder: 6),
|
||||
senderId: '@test:example.com',
|
||||
type: 'm.room.encrypted',
|
||||
roomId: room.id,
|
||||
room: room,
|
||||
eventId: '6',
|
||||
originServerTs: DateTime.now(),
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': 'B',
|
||||
'm.relates_to': {'rel_type': 'm.in_reply_to', 'event_id': '5'}
|
||||
},
|
||||
stateKey: '',
|
||||
),
|
||||
);
|
||||
expect(room.lastEvent.body, 'B');
|
||||
room.setState(
|
||||
|
|
@ -398,7 +397,6 @@ void main() {
|
|||
'users_default': 0
|
||||
},
|
||||
stateKey: '',
|
||||
sortOrder: 1,
|
||||
),
|
||||
);
|
||||
expect(room.ownPowerLevel, 0);
|
||||
|
|
@ -756,16 +754,19 @@ void main() {
|
|||
test('joinRules', () async {
|
||||
expect(room.canChangeJoinRules, false);
|
||||
expect(room.joinRules, JoinRules.public);
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'join_rule': 'invite'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.join_rules',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'join_rule': 'invite'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.join_rules',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.joinRules, JoinRules.invite);
|
||||
await room.setJoinRules(JoinRules.invite);
|
||||
});
|
||||
|
|
@ -773,16 +774,19 @@ void main() {
|
|||
test('guestAccess', () async {
|
||||
expect(room.canChangeGuestAccess, false);
|
||||
expect(room.guestAccess, GuestAccess.forbidden);
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'guest_access': 'can_join'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.guest_access',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'guest_access': 'can_join'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.guest_access',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.guestAccess, GuestAccess.canJoin);
|
||||
await room.setGuestAccess(GuestAccess.canJoin);
|
||||
});
|
||||
|
|
@ -790,145 +794,175 @@ void main() {
|
|||
test('historyVisibility', () async {
|
||||
expect(room.canChangeHistoryVisibility, false);
|
||||
expect(room.historyVisibility, null);
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.history_visibility',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.room.history_visibility',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.historyVisibility, HistoryVisibility.shared);
|
||||
await room.setHistoryVisibility(HistoryVisibility.joined);
|
||||
});
|
||||
|
||||
test('setState', () async {
|
||||
// not set non-state-events
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.custom',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.custom',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.getState('m.custom') != null, false);
|
||||
|
||||
// set state events
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.custom',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'state_key': '',
|
||||
'type': 'm.custom',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.getState('m.custom') != null, true);
|
||||
|
||||
// sets messages as state events
|
||||
room.setState(Event.fromJson({
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.room.message',
|
||||
'unsigned': {'age': 1234}
|
||||
}, room, 1432735824653.0));
|
||||
room.setState(Event.fromJson(
|
||||
{
|
||||
'content': {'history_visibility': 'shared'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.room.message',
|
||||
'unsigned': {'age': 1234}
|
||||
},
|
||||
room,
|
||||
));
|
||||
expect(room.getState('m.room.message') != null, true);
|
||||
});
|
||||
|
||||
test('Spaces', () async {
|
||||
expect(room.isSpace, false);
|
||||
room.states['m.room.create'] = {
|
||||
'': Event.fromJson({
|
||||
'content': {'type': 'm.space'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.room.create',
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '',
|
||||
}, room, 1432735824653.0),
|
||||
'': Event.fromJson(
|
||||
{
|
||||
'content': {'type': 'm.space'},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': 'm.room.create',
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '',
|
||||
},
|
||||
room,
|
||||
),
|
||||
};
|
||||
expect(room.isSpace, true);
|
||||
|
||||
expect(room.spaceParents.isEmpty, true);
|
||||
room.states[EventTypes.spaceParent] = {
|
||||
'!1234:example.invalid': Event.fromJson({
|
||||
'content': {
|
||||
'via': ['example.invalid']
|
||||
'!1234:example.invalid': Event.fromJson(
|
||||
{
|
||||
'content': {
|
||||
'via': ['example.invalid']
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceParent,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!1234:example.invalid',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceParent,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!1234:example.invalid',
|
||||
}, room, 1432735824653.0),
|
||||
room,
|
||||
),
|
||||
};
|
||||
expect(room.spaceParents.length, 1);
|
||||
|
||||
expect(room.spaceChildren.isEmpty, true);
|
||||
room.states[EventTypes.spaceChild] = {
|
||||
'!b:example.invalid': Event.fromJson({
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'b',
|
||||
'!b:example.invalid': Event.fromJson(
|
||||
{
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'b',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!b:example.invalid',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!b:example.invalid',
|
||||
}, room, 1432735824653.0),
|
||||
'!c:example.invalid': Event.fromJson({
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'c',
|
||||
room,
|
||||
),
|
||||
'!c:example.invalid': Event.fromJson(
|
||||
{
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'c',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!c:example.invalid',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!c:example.invalid',
|
||||
}, room, 1432735824653.0),
|
||||
'!noorder:example.invalid': Event.fromJson({
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
room,
|
||||
),
|
||||
'!noorder:example.invalid': Event.fromJson(
|
||||
{
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!noorder:example.invalid',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!noorder:example.invalid',
|
||||
}, room, 1432735824653.0),
|
||||
'!a:example.invalid': Event.fromJson({
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'a',
|
||||
room,
|
||||
),
|
||||
'!a:example.invalid': Event.fromJson(
|
||||
{
|
||||
'content': {
|
||||
'via': ['example.invalid'],
|
||||
'order': 'a',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!a:example.invalid',
|
||||
},
|
||||
'event_id': '\$143273582443PhrSn:example.org',
|
||||
'origin_server_ts': 1432735824653,
|
||||
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
|
||||
'sender': '@example:example.org',
|
||||
'type': EventTypes.spaceChild,
|
||||
'unsigned': {'age': 1234},
|
||||
'state_key': '!a:example.invalid',
|
||||
}, room, 1432735824653.0),
|
||||
room,
|
||||
),
|
||||
};
|
||||
expect(room.spaceChildren.length, 4);
|
||||
|
||||
|
|
|
|||
|
|
@ -70,29 +70,29 @@ void main() {
|
|||
checkWellKnown: false);
|
||||
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '2',
|
||||
'origin_server_ts': testTimeStamp - 1000
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '2',
|
||||
'origin_server_ts': testTimeStamp - 1000
|
||||
},
|
||||
));
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '1',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '1',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
));
|
||||
|
||||
expect(timeline.sub != null, true);
|
||||
|
||||
|
|
@ -130,17 +130,17 @@ void main() {
|
|||
expect(timeline.events[0].receipts[0].user.id, '@alice:example.com');
|
||||
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.redaction',
|
||||
'content': {'reason': 'spamming'},
|
||||
'sender': '@alice:example.com',
|
||||
'redacts': '2',
|
||||
'event_id': '3',
|
||||
'origin_server_ts': testTimeStamp + 1000
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.redaction',
|
||||
'content': {'reason': 'spamming'},
|
||||
'sender': '@alice:example.com',
|
||||
'redacts': '2',
|
||||
'event_id': '3',
|
||||
'origin_server_ts': testTimeStamp + 1000
|
||||
},
|
||||
));
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
|
||||
|
|
@ -164,18 +164,18 @@ void main() {
|
|||
expect(timeline.events[0].status, 1);
|
||||
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'test'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': eventId,
|
||||
'unsigned': {'transaction_id': '1234'},
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'test'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': eventId,
|
||||
'unsigned': {'transaction_id': '1234'},
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch
|
||||
},
|
||||
));
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
|
||||
|
|
@ -188,17 +188,17 @@ void main() {
|
|||
|
||||
test('Send message with error', () async {
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'abc',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'abc',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
|
||||
expect(updateCount, 7);
|
||||
|
|
@ -251,18 +251,18 @@ void main() {
|
|||
test('Resend message', () async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'new-test-event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'newresend'},
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'new-test-event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'newresend'},
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, -1);
|
||||
await timeline.events[0].sendAgain();
|
||||
|
|
@ -308,29 +308,29 @@ void main() {
|
|||
test('sort errors on top', () async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'abc',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'abc',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
));
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': 'def',
|
||||
'origin_server_ts': testTimeStamp + 5
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': 'def',
|
||||
'origin_server_ts': testTimeStamp + 5
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, -1);
|
||||
expect(timeline.events[1].status, 2);
|
||||
|
|
@ -339,32 +339,32 @@ void main() {
|
|||
test('sending event to failed update', () async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'will-fail',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'will-fail',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 0);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'will-fail',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'event_id': 'will-fail',
|
||||
'origin_server_ts': testTimeStamp
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, -1);
|
||||
expect(timeline.events.length, 1);
|
||||
|
|
@ -373,49 +373,49 @@ void main() {
|
|||
() async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 0);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 1,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'}
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 1,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'}
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 1);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'}
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'}
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
|
|
@ -424,56 +424,56 @@ void main() {
|
|||
() async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
'unsigned': {
|
||||
messageSendingStatusKey: 0,
|
||||
'transaction_id': 'transaction',
|
||||
},
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
'unsigned': {
|
||||
messageSendingStatusKey: 0,
|
||||
'transaction_id': 'transaction',
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 0);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {
|
||||
'transaction_id': 'transaction',
|
||||
messageSendingStatusKey: 2,
|
||||
},
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {
|
||||
'transaction_id': 'transaction',
|
||||
messageSendingStatusKey: 2,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {
|
||||
'transaction_id': 'transaction',
|
||||
messageSendingStatusKey: 1,
|
||||
},
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {
|
||||
'transaction_id': 'transaction',
|
||||
messageSendingStatusKey: 1,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
|
|
@ -481,48 +481,48 @@ void main() {
|
|||
test('sending an event 0 -> -1 -> 2', () async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 0);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, -1);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
|
|
@ -530,48 +530,48 @@ void main() {
|
|||
test('sending an event 0 -> 2 -> -1', () async {
|
||||
timeline.events.clear();
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 0,
|
||||
'event_id': 'transaction',
|
||||
'origin_server_ts': DateTime.now().millisecondsSinceEpoch,
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 0);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': 2,
|
||||
'event_id': '\$event',
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
client.onEvent.add(EventUpdate(
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
sortOrder: room.newSortOrder));
|
||||
type: EventUpdateType.timeline,
|
||||
roomID: roomID,
|
||||
content: {
|
||||
'type': 'm.room.message',
|
||||
'content': {'msgtype': 'm.text', 'body': 'Testcase'},
|
||||
'sender': '@alice:example.com',
|
||||
'status': -1,
|
||||
'origin_server_ts': testTimeStamp,
|
||||
'unsigned': {'transaction_id': 'transaction'},
|
||||
},
|
||||
));
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(timeline.events[0].status, 2);
|
||||
expect(timeline.events.length, 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue