Merge branch 'room-fix-states-with-statekeys' into 'master'
[Room] fix states with statekeys See merge request famedly/famedlysdk!118
This commit is contained in:
commit
a408764c86
|
@ -32,6 +32,7 @@ export 'package:famedlysdk/src/sync/UserUpdate.dart';
|
||||||
export 'package:famedlysdk/src/utils/ChatTime.dart';
|
export 'package:famedlysdk/src/utils/ChatTime.dart';
|
||||||
export 'package:famedlysdk/src/utils/MatrixFile.dart';
|
export 'package:famedlysdk/src/utils/MatrixFile.dart';
|
||||||
export 'package:famedlysdk/src/utils/MxContent.dart';
|
export 'package:famedlysdk/src/utils/MxContent.dart';
|
||||||
|
export 'package:famedlysdk/src/utils/StatesMap.dart';
|
||||||
export 'package:famedlysdk/src/AccountData.dart';
|
export 'package:famedlysdk/src/AccountData.dart';
|
||||||
export 'package:famedlysdk/src/Client.dart';
|
export 'package:famedlysdk/src/Client.dart';
|
||||||
export 'package:famedlysdk/src/Connection.dart';
|
export 'package:famedlysdk/src/Connection.dart';
|
||||||
|
|
|
@ -37,6 +37,7 @@ import 'package:mime_type/mime_type.dart';
|
||||||
import './User.dart';
|
import './User.dart';
|
||||||
import 'Connection.dart';
|
import 'Connection.dart';
|
||||||
import 'Timeline.dart';
|
import 'Timeline.dart';
|
||||||
|
import 'utils/StatesMap.dart';
|
||||||
|
|
||||||
typedef onRoomUpdate = void Function();
|
typedef onRoomUpdate = void Function();
|
||||||
|
|
||||||
|
@ -67,8 +68,7 @@ class Room {
|
||||||
/// The number of users with membership of invite.
|
/// The number of users with membership of invite.
|
||||||
int mInvitedMemberCount;
|
int mInvitedMemberCount;
|
||||||
|
|
||||||
/// Key-Value store for room states.
|
StatesMap states = StatesMap();
|
||||||
Map<String, RoomState> states = {};
|
|
||||||
|
|
||||||
/// Key-Value store for ephemerals.
|
/// Key-Value store for ephemerals.
|
||||||
Map<String, RoomAccountData> ephemerals = {};
|
Map<String, RoomAccountData> ephemerals = {};
|
||||||
|
@ -155,18 +155,16 @@ class Room {
|
||||||
|
|
||||||
Event get lastEvent {
|
Event get lastEvent {
|
||||||
ChatTime lastTime = ChatTime(0);
|
ChatTime lastTime = ChatTime(0);
|
||||||
Event lastEvent = null;
|
Event lastEvent = states["m.room.message"]?.timelineEvent;
|
||||||
for (final entry in states.entries) {
|
if (lastEvent == null)
|
||||||
final RoomState state = entry.value;
|
states.forEach((final String key, final entry) {
|
||||||
if ((state.time != null && state.time > lastTime) ||
|
if (!entry.containsKey("")) return;
|
||||||
state.typeKey == "m.room.message") {
|
final RoomState state = entry[""];
|
||||||
|
if (state.time != null && state.time > lastTime) {
|
||||||
lastTime = state.time;
|
lastTime = state.time;
|
||||||
lastEvent = state.timelineEvent;
|
lastEvent = state.timelineEvent;
|
||||||
if (state.typeKey == "m.room.message") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
return lastEvent;
|
return lastEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +192,6 @@ class Room {
|
||||||
this.mHeroes = const [],
|
this.mHeroes = const [],
|
||||||
this.mInvitedMemberCount = 0,
|
this.mInvitedMemberCount = 0,
|
||||||
this.mJoinedMemberCount = 0,
|
this.mJoinedMemberCount = 0,
|
||||||
this.states = const {},
|
|
||||||
this.roomAccountData = const {},
|
this.roomAccountData = const {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -624,7 +621,6 @@ class Room {
|
||||||
mJoinedMemberCount: row["joined_member_count"],
|
mJoinedMemberCount: row["joined_member_count"],
|
||||||
mHeroes: row["heroes"]?.split(",") ?? [],
|
mHeroes: row["heroes"]?.split(",") ?? [],
|
||||||
client: matrix,
|
client: matrix,
|
||||||
states: {},
|
|
||||||
roomAccountData: {},
|
roomAccountData: {},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -635,7 +631,8 @@ class Room {
|
||||||
RoomState newState = RoomState.fromJson(rawStates[i], newRoom);
|
RoomState newState = RoomState.fromJson(rawStates[i], newRoom);
|
||||||
newStates[newState.key] = newState;
|
newStates[newState.key] = newState;
|
||||||
}
|
}
|
||||||
newRoom.states = newStates;
|
for (var entry in newStates.entries)
|
||||||
|
newRoom.states[entry.key] = entry.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, RoomAccountData> newRoomAccountData = {};
|
Map<String, RoomAccountData> newRoomAccountData = {};
|
||||||
|
@ -682,9 +679,13 @@ class Room {
|
||||||
/// case.
|
/// case.
|
||||||
List<User> getParticipants() {
|
List<User> getParticipants() {
|
||||||
List<User> userList = [];
|
List<User> userList = [];
|
||||||
for (var entry in states.entries)
|
if (states["m.room.member"] is Map<String, dynamic>) {
|
||||||
if (entry.value.type == EventTypes.RoomMember)
|
print('Check members: ${states["m.room.member"].length}');
|
||||||
userList.add(entry.value.asUser);
|
for (var entry in states["m.room.member"].entries) {
|
||||||
|
RoomState state = entry.value;
|
||||||
|
if (state.type == EventTypes.RoomMember) userList.add(state.asUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
return userList;
|
return userList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,6 @@ class RoomList {
|
||||||
mHeroes: chatUpdate.summary?.mHeroes,
|
mHeroes: chatUpdate.summary?.mHeroes,
|
||||||
mJoinedMemberCount: chatUpdate.summary?.mJoinedMemberCount,
|
mJoinedMemberCount: chatUpdate.summary?.mJoinedMemberCount,
|
||||||
mInvitedMemberCount: chatUpdate.summary?.mInvitedMemberCount,
|
mInvitedMemberCount: chatUpdate.summary?.mInvitedMemberCount,
|
||||||
states: {},
|
|
||||||
roomAccountData: {},
|
roomAccountData: {},
|
||||||
client: client,
|
client: client,
|
||||||
);
|
);
|
||||||
|
|
36
lib/src/utils/StatesMap.dart
Normal file
36
lib/src/utils/StatesMap.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
|
||||||
|
/// Matrix room states are addressed by a tuple of the [type] and an
|
||||||
|
/// optional [stateKey].
|
||||||
|
class StatesMap {
|
||||||
|
Map<String, Map<String, RoomState>> states = {};
|
||||||
|
|
||||||
|
/// Returns either the [RoomState] or a map of state_keys to [RoomState] objects.
|
||||||
|
/// If you just enter a MatrixID, it will try to return the corresponding m.room.member event.
|
||||||
|
dynamic operator [](String key) {
|
||||||
|
if (key.startsWith("@") && key.contains(":")) {
|
||||||
|
if (!states.containsKey("m.room.member")) states["m.room.member"] = {};
|
||||||
|
return states["m.room.member"][key];
|
||||||
|
}
|
||||||
|
if (!states.containsKey(key)) states[key] = {};
|
||||||
|
if (states[key][""] is RoomState)
|
||||||
|
return states[key][""];
|
||||||
|
else if (states[key].length == 0)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return states[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator []=(String key, RoomState val) {
|
||||||
|
if (key.startsWith("@") && key.contains(":")) {
|
||||||
|
if (!states.containsKey("m.room.member")) states["m.room.member"] = {};
|
||||||
|
states["m.room.member"][key] = val;
|
||||||
|
}
|
||||||
|
if (!states.containsKey(key)) states[key] = {};
|
||||||
|
states[key][val.stateKey ?? ""] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsKey(String key) => states.containsKey(key);
|
||||||
|
|
||||||
|
void forEach(f) => states.forEach(f);
|
||||||
|
}
|
74
test/StatesMap_test.dart
Normal file
74
test/StatesMap_test.dart
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Zender & Kurtz GbR.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Christian Pauly <krille@famedly.com>
|
||||||
|
* Marcel Radzio <mtrnord@famedly.com>
|
||||||
|
*
|
||||||
|
* This file is part of famedlysdk.
|
||||||
|
*
|
||||||
|
* famedlysdk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* famedlysdk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:famedlysdk/src/utils/StatesMap.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/// All Tests related to the ChatTime
|
||||||
|
group("StateKeys", () {
|
||||||
|
test("Operator overload", () async {
|
||||||
|
StatesMap states = StatesMap();
|
||||||
|
states["m.room.name"] = RoomState(
|
||||||
|
eventId: "1",
|
||||||
|
content: {"name": "test"},
|
||||||
|
typeKey: "m.room.name",
|
||||||
|
stateKey: "",
|
||||||
|
roomId: "!test:test.test",
|
||||||
|
senderId: "@alice:test.test");
|
||||||
|
|
||||||
|
states["@alice:test.test"] = RoomState(
|
||||||
|
eventId: "2",
|
||||||
|
content: {"membership": "join"},
|
||||||
|
typeKey: "m.room.name",
|
||||||
|
stateKey: "@alice:test.test",
|
||||||
|
roomId: "!test:test.test",
|
||||||
|
senderId: "@alice:test.test");
|
||||||
|
|
||||||
|
states["m.room.member"]["@bob:test.test"] = RoomState(
|
||||||
|
eventId: "3",
|
||||||
|
content: {"membership": "join"},
|
||||||
|
typeKey: "m.room.name",
|
||||||
|
stateKey: "@bob:test.test",
|
||||||
|
roomId: "!test:test.test",
|
||||||
|
senderId: "@bob:test.test");
|
||||||
|
|
||||||
|
states["com.test.custom"] = RoomState(
|
||||||
|
eventId: "4",
|
||||||
|
content: {"custom": "stuff"},
|
||||||
|
typeKey: "com.test.custom",
|
||||||
|
stateKey: "customStateKey",
|
||||||
|
roomId: "!test:test.test",
|
||||||
|
senderId: "@bob:test.test");
|
||||||
|
|
||||||
|
expect(states["m.room.name"].eventId, "1");
|
||||||
|
expect(states["@alice:test.test"].eventId, "2");
|
||||||
|
expect(states["m.room.member"]["@alice:test.test"].eventId, "2");
|
||||||
|
expect(states["@bob:test.test"].eventId, "3");
|
||||||
|
expect(states["m.room.member"]["@bob:test.test"].eventId, "3");
|
||||||
|
expect(states["m.room.member"].length, 2);
|
||||||
|
expect(states["com.test.custom"]["customStateKey"].eventId, "4");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -43,11 +43,7 @@ void main() {
|
||||||
client.homeserver = "https://fakeServer.notExisting";
|
client.homeserver = "https://fakeServer.notExisting";
|
||||||
|
|
||||||
Room room = Room(
|
Room room = Room(
|
||||||
id: roomID,
|
id: roomID, client: client, prev_batch: "1234", roomAccountData: {});
|
||||||
client: client,
|
|
||||||
prev_batch: "1234",
|
|
||||||
states: {},
|
|
||||||
roomAccountData: {});
|
|
||||||
Timeline timeline = Timeline(
|
Timeline timeline = Timeline(
|
||||||
room: room,
|
room: room,
|
||||||
events: [],
|
events: [],
|
||||||
|
|
Loading…
Reference in a new issue