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/MatrixFile.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/Client.dart'; | ||||
| export 'package:famedlysdk/src/Connection.dart'; | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ import 'package:mime_type/mime_type.dart'; | |||
| import './User.dart'; | ||||
| import 'Connection.dart'; | ||||
| import 'Timeline.dart'; | ||||
| import 'utils/StatesMap.dart'; | ||||
| 
 | ||||
| typedef onRoomUpdate = void Function(); | ||||
| 
 | ||||
|  | @ -67,8 +68,7 @@ class Room { | |||
|   /// The number of users with membership of invite. | ||||
|   int mInvitedMemberCount; | ||||
| 
 | ||||
|   /// Key-Value store for room states. | ||||
|   Map<String, RoomState> states = {}; | ||||
|   StatesMap states = StatesMap(); | ||||
| 
 | ||||
|   /// Key-Value store for ephemerals. | ||||
|   Map<String, RoomAccountData> ephemerals = {}; | ||||
|  | @ -155,18 +155,16 @@ class Room { | |||
| 
 | ||||
|   Event get lastEvent { | ||||
|     ChatTime lastTime = ChatTime(0); | ||||
|     Event lastEvent = null; | ||||
|     for (final entry in states.entries) { | ||||
|       final RoomState state = entry.value; | ||||
|       if ((state.time != null && state.time > lastTime) || | ||||
|           state.typeKey == "m.room.message") { | ||||
|     Event lastEvent = states["m.room.message"]?.timelineEvent; | ||||
|     if (lastEvent == null) | ||||
|       states.forEach((final String key, final entry) { | ||||
|         if (!entry.containsKey("")) return; | ||||
|         final RoomState state = entry[""]; | ||||
|         if (state.time != null && state.time > lastTime) { | ||||
|           lastTime = state.time; | ||||
|           lastEvent = state.timelineEvent; | ||||
|         if (state.typeKey == "m.room.message") { | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|         } | ||||
|       }); | ||||
|     return lastEvent; | ||||
|   } | ||||
| 
 | ||||
|  | @ -194,7 +192,6 @@ class Room { | |||
|     this.mHeroes = const [], | ||||
|     this.mInvitedMemberCount = 0, | ||||
|     this.mJoinedMemberCount = 0, | ||||
|     this.states = const {}, | ||||
|     this.roomAccountData = const {}, | ||||
|   }); | ||||
| 
 | ||||
|  | @ -624,7 +621,6 @@ class Room { | |||
|       mJoinedMemberCount: row["joined_member_count"], | ||||
|       mHeroes: row["heroes"]?.split(",") ?? [], | ||||
|       client: matrix, | ||||
|       states: {}, | ||||
|       roomAccountData: {}, | ||||
|     ); | ||||
| 
 | ||||
|  | @ -635,7 +631,8 @@ class Room { | |||
|         RoomState newState = RoomState.fromJson(rawStates[i], newRoom); | ||||
|         newStates[newState.key] = newState; | ||||
|       } | ||||
|       newRoom.states = newStates; | ||||
|       for (var entry in newStates.entries) | ||||
|         newRoom.states[entry.key] = entry.value; | ||||
|     } | ||||
| 
 | ||||
|     Map<String, RoomAccountData> newRoomAccountData = {}; | ||||
|  | @ -682,9 +679,13 @@ class Room { | |||
|   /// case. | ||||
|   List<User> getParticipants() { | ||||
|     List<User> userList = []; | ||||
|     for (var entry in states.entries) | ||||
|       if (entry.value.type == EventTypes.RoomMember) | ||||
|         userList.add(entry.value.asUser); | ||||
|     if (states["m.room.member"] is Map<String, dynamic>) { | ||||
|       print('Check members: ${states["m.room.member"].length}'); | ||||
|       for (var entry in states["m.room.member"].entries) { | ||||
|         RoomState state = entry.value; | ||||
|         if (state.type == EventTypes.RoomMember) userList.add(state.asUser); | ||||
|       } | ||||
|     } | ||||
|     return userList; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -130,7 +130,6 @@ class RoomList { | |||
|         mHeroes: chatUpdate.summary?.mHeroes, | ||||
|         mJoinedMemberCount: chatUpdate.summary?.mJoinedMemberCount, | ||||
|         mInvitedMemberCount: chatUpdate.summary?.mInvitedMemberCount, | ||||
|         states: {}, | ||||
|         roomAccountData: {}, | ||||
|         client: client, | ||||
|       ); | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  | @ -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"; | ||||
| 
 | ||||
|     Room room = Room( | ||||
|         id: roomID, | ||||
|         client: client, | ||||
|         prev_batch: "1234", | ||||
|         states: {}, | ||||
|         roomAccountData: {}); | ||||
|         id: roomID, client: client, prev_batch: "1234", roomAccountData: {}); | ||||
|     Timeline timeline = Timeline( | ||||
|         room: room, | ||||
|         events: [], | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue