fix: Last event calculation
This commit is contained in:
parent
d9c4472cac
commit
b05e4da34f
|
@ -10,4 +10,3 @@ analyzer:
|
||||||
todo: ignore
|
todo: ignore
|
||||||
exclude:
|
exclude:
|
||||||
- example/main.dart
|
- example/main.dart
|
||||||
- lib/src/utils/logs.dart
|
|
|
@ -59,15 +59,16 @@ class Client extends MatrixApi {
|
||||||
|
|
||||||
Set<String> importantStateEvents;
|
Set<String> importantStateEvents;
|
||||||
|
|
||||||
|
Set<String> roomPreviewLastEvents;
|
||||||
|
|
||||||
/// Create a client
|
/// Create a client
|
||||||
/// clientName = unique identifier of this client
|
/// [clientName] = unique identifier of this client
|
||||||
/// debug: Print debug output?
|
/// [database]: The database instance to use
|
||||||
/// database: The database instance to use
|
/// [enableE2eeRecovery]: Enable additional logic to try to recover from bad e2ee sessions
|
||||||
/// enableE2eeRecovery: Enable additional logic to try to recover from bad e2ee sessions
|
/// [verificationMethods]: A set of all the verification methods this client can handle. Includes:
|
||||||
/// verificationMethods: A set of all the verification methods this client can handle. Includes:
|
|
||||||
/// KeyVerificationMethod.numbers: Compare numbers. Most basic, should be supported
|
/// KeyVerificationMethod.numbers: Compare numbers. Most basic, should be supported
|
||||||
/// KeyVerificationMethod.emoji: Compare emojis
|
/// KeyVerificationMethod.emoji: Compare emojis
|
||||||
/// importantStateEvents: A set of all the important state events to load when the client connects.
|
/// [importantStateEvents]: A set of all the important state events to load when the client connects.
|
||||||
/// To speed up performance only a set of state events is loaded on startup, those that are
|
/// To speed up performance only a set of state events is loaded on startup, those that are
|
||||||
/// needed to display a room list. All the remaining state events are automatically post-loaded
|
/// needed to display a room list. All the remaining state events are automatically post-loaded
|
||||||
/// when opening the timeline of a room or manually by calling `room.postLoad()`.
|
/// when opening the timeline of a room or manually by calling `room.postLoad()`.
|
||||||
|
@ -80,6 +81,8 @@ class Client extends MatrixApi {
|
||||||
/// - m.room.canonical_alias
|
/// - m.room.canonical_alias
|
||||||
/// - m.room.tombstone
|
/// - m.room.tombstone
|
||||||
/// - *some* m.room.member events, where needed
|
/// - *some* m.room.member events, where needed
|
||||||
|
/// [roomPreviewLastEvents]: The event types that should be used to calculate the last event
|
||||||
|
/// in a room for the room list.
|
||||||
Client(
|
Client(
|
||||||
this.clientName, {
|
this.clientName, {
|
||||||
this.database,
|
this.database,
|
||||||
|
@ -87,11 +90,12 @@ class Client extends MatrixApi {
|
||||||
this.verificationMethods,
|
this.verificationMethods,
|
||||||
http.Client httpClient,
|
http.Client httpClient,
|
||||||
this.importantStateEvents,
|
this.importantStateEvents,
|
||||||
|
this.roomPreviewLastEvents,
|
||||||
this.pinUnreadRooms = false,
|
this.pinUnreadRooms = false,
|
||||||
@deprecated bool debug,
|
@deprecated bool debug,
|
||||||
}) {
|
}) {
|
||||||
verificationMethods ??= <KeyVerificationMethod>{};
|
verificationMethods ??= <KeyVerificationMethod>{};
|
||||||
importantStateEvents ??= <String>{};
|
importantStateEvents ??= {};
|
||||||
importantStateEvents.addAll([
|
importantStateEvents.addAll([
|
||||||
EventTypes.RoomName,
|
EventTypes.RoomName,
|
||||||
EventTypes.RoomAvatar,
|
EventTypes.RoomAvatar,
|
||||||
|
@ -101,6 +105,12 @@ class Client extends MatrixApi {
|
||||||
EventTypes.RoomCanonicalAlias,
|
EventTypes.RoomCanonicalAlias,
|
||||||
EventTypes.RoomTombstone,
|
EventTypes.RoomTombstone,
|
||||||
]);
|
]);
|
||||||
|
roomPreviewLastEvents ??= {};
|
||||||
|
roomPreviewLastEvents.addAll([
|
||||||
|
EventTypes.Message,
|
||||||
|
EventTypes.Encrypted,
|
||||||
|
EventTypes.Sticker,
|
||||||
|
]);
|
||||||
this.httpClient = httpClient ?? http.Client();
|
this.httpClient = httpClient ?? http.Client();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,44 +1109,49 @@ class Client extends MatrixApi {
|
||||||
|
|
||||||
void _updateRoomsByEventUpdate(EventUpdate eventUpdate) {
|
void _updateRoomsByEventUpdate(EventUpdate eventUpdate) {
|
||||||
if (eventUpdate.type == 'history') return;
|
if (eventUpdate.type == 'history') return;
|
||||||
// Search the room in the rooms
|
|
||||||
num j = 0;
|
final room = getRoomById(eventUpdate.roomID);
|
||||||
for (j = 0; j < rooms.length; j++) {
|
if (room == null) return;
|
||||||
if (rooms[j].id == eventUpdate.roomID) break;
|
|
||||||
}
|
switch (eventUpdate.type) {
|
||||||
final found = (j < rooms.length && rooms[j].id == eventUpdate.roomID);
|
case 'timeline':
|
||||||
if (!found) return;
|
case 'state':
|
||||||
if (eventUpdate.type == 'timeline' ||
|
case 'invite_state':
|
||||||
eventUpdate.type == 'state' ||
|
var stateEvent =
|
||||||
eventUpdate.type == 'invite_state') {
|
Event.fromJson(eventUpdate.content, room, eventUpdate.sortOrder);
|
||||||
var stateEvent =
|
var prevState = room.getState(stateEvent.type, stateEvent.stateKey);
|
||||||
Event.fromJson(eventUpdate.content, rooms[j], eventUpdate.sortOrder);
|
|
||||||
if (stateEvent.type == EventTypes.Redaction) {
|
|
||||||
final String redacts = eventUpdate.content['redacts'];
|
|
||||||
rooms[j].states.states.forEach(
|
|
||||||
(String key, Map<String, Event> states) => states.forEach(
|
|
||||||
(String key, Event state) {
|
|
||||||
if (state.eventId == redacts) {
|
|
||||||
state.setRedactionEvent(stateEvent);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
var prevState = rooms[j].getState(stateEvent.type, stateEvent.stateKey);
|
|
||||||
if (prevState != null && prevState.sortOrder > stateEvent.sortOrder) {
|
if (prevState != null && prevState.sortOrder > stateEvent.sortOrder) {
|
||||||
|
Logs.warning('''
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
rooms[j].setState(stateEvent);
|
if (stateEvent.type == EventTypes.Redaction) {
|
||||||
}
|
final String redacts = eventUpdate.content['redacts'];
|
||||||
} else if (eventUpdate.type == 'account_data') {
|
room.states.states.forEach(
|
||||||
rooms[j].roomAccountData[eventUpdate.eventType] =
|
(String key, Map<String, Event> states) => states.forEach(
|
||||||
BasicRoomEvent.fromJson(eventUpdate.content);
|
(String key, Event state) {
|
||||||
} else if (eventUpdate.type == 'ephemeral') {
|
if (state.eventId == redacts) {
|
||||||
rooms[j].ephemerals[eventUpdate.eventType] =
|
state.setRedactionEvent(stateEvent);
|
||||||
BasicRoomEvent.fromJson(eventUpdate.content);
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
room.setState(stateEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'account_data':
|
||||||
|
room.roomAccountData[eventUpdate.eventType] =
|
||||||
|
BasicRoomEvent.fromJson(eventUpdate.content);
|
||||||
|
break;
|
||||||
|
case 'ephemeral':
|
||||||
|
room.ephemerals[eventUpdate.eventType] =
|
||||||
|
BasicRoomEvent.fromJson(eventUpdate.content);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (rooms[j].onUpdate != null) rooms[j].onUpdate.add(rooms[j].id);
|
room.onUpdate.add(room.id);
|
||||||
if (['timeline', 'account_data'].contains(eventUpdate.type)) _sortRooms();
|
if (['timeline', 'account_data'].contains(eventUpdate.type)) _sortRooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,13 @@ class Room {
|
||||||
// perfect, it is only used for the room preview in the room list and sorting
|
// perfect, it is only used for the room preview in the room list and sorting
|
||||||
// said room list, so it should be good enough.
|
// said room list, so it should be good enough.
|
||||||
var lastTime = DateTime.fromMillisecondsSinceEpoch(0);
|
var lastTime = DateTime.fromMillisecondsSinceEpoch(0);
|
||||||
var lastEvent = getState(EventTypes.Message);
|
final lastEvents = <Event>[
|
||||||
|
for (var type in client.roomPreviewLastEvents) getState(type)
|
||||||
|
]..removeWhere((e) => e == null);
|
||||||
|
|
||||||
|
var lastEvent = lastEvents.isEmpty
|
||||||
|
? null
|
||||||
|
: lastEvents.reduce((a, b) => a.sortOrder > b.sortOrder ? a : b);
|
||||||
if (lastEvent == null) {
|
if (lastEvent == null) {
|
||||||
states.forEach((final String key, final entry) {
|
states.forEach((final String key, final entry) {
|
||||||
if (!entry.containsKey('')) return;
|
if (!entry.containsKey('')) return;
|
||||||
|
|
|
@ -26,20 +26,24 @@ abstract class Logs {
|
||||||
|
|
||||||
static const String _prefixText = '[Famedly Matrix SDK] ';
|
static const String _prefixText = '[Famedly Matrix SDK] ';
|
||||||
|
|
||||||
|
// ignore: avoid_print
|
||||||
static void info(dynamic info) => print(
|
static void info(dynamic info) => print(
|
||||||
_prefixText + _infoPen(info.toString()),
|
_prefixText + _infoPen(info.toString()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ignore: avoid_print
|
||||||
static void success(dynamic obj, [dynamic stackTrace]) => print(
|
static void success(dynamic obj, [dynamic stackTrace]) => print(
|
||||||
_prefixText + _successPen(obj.toString()),
|
_prefixText + _successPen(obj.toString()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ignore: avoid_print
|
||||||
static void warning(dynamic warning, [dynamic stackTrace]) => print(
|
static void warning(dynamic warning, [dynamic stackTrace]) => print(
|
||||||
_prefixText +
|
_prefixText +
|
||||||
_warningPen(warning.toString()) +
|
_warningPen(warning.toString()) +
|
||||||
(stackTrace != null ? '\n${stackTrace.toString()}' : ''),
|
(stackTrace != null ? '\n${stackTrace.toString()}' : ''),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ignore: avoid_print
|
||||||
static void error(dynamic obj, [dynamic stackTrace]) => print(
|
static void error(dynamic obj, [dynamic stackTrace]) => print(
|
||||||
_prefixText +
|
_prefixText +
|
||||||
_errorPen(obj.toString()) +
|
_errorPen(obj.toString()) +
|
||||||
|
|
Loading…
Reference in a new issue