Merge pull request #1726 from famedly/nico/fix-state-handling-after-invite
fix state handling after invite
This commit is contained in:
commit
2f95e41ee9
|
|
@ -1071,19 +1071,19 @@ class Client extends MatrixApi {
|
|||
[]));
|
||||
|
||||
archivedRoom.prev_batch = update.timeline?.prevBatch;
|
||||
update.state?.forEach((event) {
|
||||
archivedRoom.setState(Event.fromMatrixEvent(
|
||||
event,
|
||||
archivedRoom,
|
||||
));
|
||||
});
|
||||
|
||||
update.timeline?.events?.forEach((event) {
|
||||
archivedRoom.setState(Event.fromMatrixEvent(
|
||||
event,
|
||||
archivedRoom,
|
||||
));
|
||||
});
|
||||
final stateEvents = roomUpdate.state;
|
||||
if (stateEvents != null) {
|
||||
await _handleRoomEvents(archivedRoom, stateEvents, EventUpdateType.state,
|
||||
store: false);
|
||||
}
|
||||
|
||||
final timelineEvents = roomUpdate.timeline?.events;
|
||||
if (timelineEvents != null) {
|
||||
await _handleRoomEvents(archivedRoom, timelineEvents.reversed.toList(),
|
||||
EventUpdateType.timeline,
|
||||
store: false);
|
||||
}
|
||||
|
||||
for (var i = 0; i < timeline.events.length; i++) {
|
||||
// Try to decrypt encrypted events but don't update the database.
|
||||
|
|
@ -2463,6 +2463,10 @@ class Client extends MatrixApi {
|
|||
final importantOrRoomLoaded =
|
||||
eventUpdate.type == EventUpdateType.inviteState ||
|
||||
!room.partial ||
|
||||
// make sure we do overwrite events we have already loaded.
|
||||
room.states[stateEvent.type]
|
||||
?.containsKey(stateEvent.stateKey ?? '') ==
|
||||
true ||
|
||||
importantStateEvents.contains(stateEvent.type);
|
||||
if ((noMessageOrNoEdit || editingLastEvent || consecutiveEdit) &&
|
||||
importantOrRoomLoaded) {
|
||||
|
|
|
|||
|
|
@ -210,10 +210,8 @@ class Event extends MatrixEvent {
|
|||
type: jsonPayload['type'],
|
||||
eventId: jsonPayload['event_id'] ?? '',
|
||||
senderId: jsonPayload['sender'],
|
||||
originServerTs: jsonPayload['origin_server_ts'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(
|
||||
jsonPayload['origin_server_ts'])
|
||||
: DateTime.now(),
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(
|
||||
jsonPayload['origin_server_ts'] ?? 0),
|
||||
unsigned: unsigned,
|
||||
room: room,
|
||||
originalSource: originalSource.isEmpty
|
||||
|
|
|
|||
|
|
@ -196,15 +196,6 @@ class Room {
|
|||
return;
|
||||
}
|
||||
|
||||
// Do not set old events as state events
|
||||
final prevEvent = getState(state.type, stateKey);
|
||||
if (prevEvent != null &&
|
||||
prevEvent.eventId != state.eventId &&
|
||||
prevEvent.originServerTs.millisecondsSinceEpoch >
|
||||
state.originServerTs.millisecondsSinceEpoch) {
|
||||
return;
|
||||
}
|
||||
|
||||
(states[state.type] ??= {})[stateKey] = state;
|
||||
|
||||
client.onRoomState.add(state);
|
||||
|
|
@ -1574,8 +1565,6 @@ class Room {
|
|||
return <User>[];
|
||||
}
|
||||
|
||||
bool _requestedParticipants = false;
|
||||
|
||||
/// Request the full list of participants from the server. The local list
|
||||
/// from the store is not complete if the client uses lazy loading.
|
||||
/// List `membershipFilter` defines with what membership do you want the
|
||||
|
|
@ -1591,17 +1580,20 @@ class Room {
|
|||
],
|
||||
bool suppressWarning = false,
|
||||
bool cache = true]) async {
|
||||
if (!participantListComplete && partial) {
|
||||
if (!participantListComplete || partial) {
|
||||
// we aren't fully loaded, maybe the users are in the database
|
||||
// We always need to check the database in the partial case, since state
|
||||
// events won't get written to memory in this case and someone new could
|
||||
// have joined, while someone else left, which might lead to the same
|
||||
// count in the completeness check.
|
||||
final users = await client.database?.getUsers(this) ?? [];
|
||||
for (final user in users) {
|
||||
setState(user);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not request users from the server if we have already done it
|
||||
// in this session or have a complete list locally.
|
||||
if (_requestedParticipants || participantListComplete) {
|
||||
// Do not request users from the server if we have already have a complete list locally.
|
||||
if (participantListComplete) {
|
||||
return getParticipants(membershipFilter);
|
||||
}
|
||||
|
||||
|
|
@ -1626,7 +1618,6 @@ class Room {
|
|||
}
|
||||
}
|
||||
|
||||
_requestedParticipants = cache;
|
||||
users.removeWhere((u) => !membershipFilter.contains(u.membership));
|
||||
return users;
|
||||
}
|
||||
|
|
@ -1634,10 +1625,14 @@ class Room {
|
|||
/// Checks if the local participant list of joined and invited users is complete.
|
||||
bool get participantListComplete {
|
||||
final knownParticipants = getParticipants();
|
||||
knownParticipants.removeWhere(
|
||||
(u) => ![Membership.join, Membership.invite].contains(u.membership));
|
||||
return knownParticipants.length ==
|
||||
(summary.mJoinedMemberCount ?? 0) + (summary.mInvitedMemberCount ?? 0);
|
||||
final joinedCount =
|
||||
knownParticipants.where((u) => u.membership == Membership.join).length;
|
||||
final invitedCount = knownParticipants
|
||||
.where((u) => u.membership == Membership.invite)
|
||||
.length;
|
||||
|
||||
return (summary.mJoinedMemberCount ?? 0) == joinedCount &&
|
||||
(summary.mInvitedMemberCount ?? 0) == invitedCount;
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -70,6 +70,7 @@ void main() {
|
|||
),
|
||||
},
|
||||
);
|
||||
|
||||
room.setState(Event(
|
||||
room: room,
|
||||
eventId: '143273582443PhrSn:example.org',
|
||||
|
|
@ -80,6 +81,46 @@ void main() {
|
|||
content: {'join_rule': 'public'},
|
||||
stateKey: '',
|
||||
));
|
||||
room.setState(Event(
|
||||
room: room,
|
||||
eventId: '143273582443PhrSnY:example.org',
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||
senderId: matrix.userID!,
|
||||
type: 'm.room.member',
|
||||
unsigned: {'age': 1234},
|
||||
content: {'membership': 'join', 'displayname': 'YOU'},
|
||||
stateKey: matrix.userID!,
|
||||
));
|
||||
room.setState(Event(
|
||||
room: room,
|
||||
eventId: '143273582443PhrSnA:example.org',
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||
senderId: '@alice:matrix.org',
|
||||
type: 'm.room.member',
|
||||
unsigned: {'age': 1234},
|
||||
content: {'membership': 'join', 'displayname': 'Alice Margatroid'},
|
||||
stateKey: '@alice:matrix.org',
|
||||
));
|
||||
room.setState(Event(
|
||||
room: room,
|
||||
eventId: '143273582443PhrSnB:example.org',
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||
senderId: '@bob:example.com',
|
||||
type: 'm.room.member',
|
||||
unsigned: {'age': 1234},
|
||||
content: {'membership': 'invite', 'displayname': 'Bob'},
|
||||
stateKey: '@bob:example.com',
|
||||
));
|
||||
room.setState(Event(
|
||||
room: room,
|
||||
eventId: '143273582443PhrSnC:example.org',
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||
senderId: '@charley:example.org',
|
||||
type: 'm.room.member',
|
||||
unsigned: {'age': 1234},
|
||||
content: {'membership': 'invite', 'displayname': 'Charley'},
|
||||
stateKey: '@charley:example.org',
|
||||
));
|
||||
|
||||
final heroUsers = await room.loadHeroUsers();
|
||||
expect(heroUsers.length, 3);
|
||||
|
|
@ -89,9 +130,10 @@ void main() {
|
|||
expect(room.notificationCount, notificationCount);
|
||||
expect(room.highlightCount, highlightCount);
|
||||
expect(room.summary.mJoinedMemberCount, notificationCount);
|
||||
expect(room.summary.mInvitedMemberCount, notificationCount);
|
||||
expect(room.summary.mInvitedMemberCount, 2);
|
||||
expect(room.summary.mHeroes, heroes);
|
||||
expect(room.getLocalizedDisplayname(), 'Group with Alice, Bob, Charley');
|
||||
expect(room.getLocalizedDisplayname(),
|
||||
'Group with Alice Margatroid, Bob, Charley');
|
||||
expect(
|
||||
room.getState('m.room.join_rules')?.content['join_rule'], 'public');
|
||||
expect(room.roomAccountData['com.test.foo']?.content['foo'], 'bar');
|
||||
|
|
@ -434,12 +476,12 @@ void main() {
|
|||
|
||||
test('requestParticipants', () async {
|
||||
final participants = await room.requestParticipants();
|
||||
expect(participants.length, 1);
|
||||
final user = participants[0];
|
||||
expect(user.id, '@alice:example.org');
|
||||
expect(participants.length, 4);
|
||||
final user = participants.singleWhere((u) => u.id == '@alice:matrix.org');
|
||||
expect(user.id, '@alice:matrix.org');
|
||||
expect(user.displayName, 'Alice Margatroid');
|
||||
expect(user.membership, Membership.join);
|
||||
expect(user.avatarUrl.toString(), 'mxc://example.org/SEsfnsuifSDFSSEF');
|
||||
//expect(user.avatarUrl.toString(), 'mxc://example.org/SEsfnsuifSDFSSEF');
|
||||
expect(user.room.id, '!localpart:server.abc');
|
||||
});
|
||||
|
||||
|
|
@ -1405,10 +1447,13 @@ void main() {
|
|||
|
||||
test('getMention', () async {
|
||||
expect(room.getMention('@invalid'), null);
|
||||
expect(room.getMention('@[Alice Margatroid]'), '@alice:example.org');
|
||||
expect(room.getMention('@[Alice Margatroid]#1754'), '@alice:example.org');
|
||||
expect(room.getMention('@[Alice Margatroid]'), '@alice:matrix.org');
|
||||
expect(room.getMention('@[Alice Margatroid]#1667'), '@alice:matrix.org');
|
||||
});
|
||||
test('inviteLink', () async {
|
||||
// ensure we don't rerequest members
|
||||
room.summary.mJoinedMemberCount = 4;
|
||||
|
||||
var matrixToLink = await room.matrixToInviteLink();
|
||||
expect(matrixToLink.toString(),
|
||||
'https://matrix.to/#/%23testalias%3Aexample.com');
|
||||
|
|
@ -1424,7 +1469,7 @@ void main() {
|
|||
);
|
||||
matrixToLink = await room.matrixToInviteLink();
|
||||
expect(matrixToLink.toString(),
|
||||
'https://matrix.to/#/!localpart%3Aserver.abc?via=example.org&via=example.com&via=test.abc');
|
||||
'https://matrix.to/#/!localpart%3Aserver.abc?via=example.com&via=test.abc&via=example.org');
|
||||
});
|
||||
|
||||
test('callMemberStateIsExpired', () {
|
||||
|
|
|
|||
Loading…
Reference in New Issue