[Archive] enhance lazyload archive
This commit is contained in:
parent
c38f041a5a
commit
888155fbc7
|
@ -98,9 +98,6 @@ class Client {
|
|||
/// A list of all rooms the user is participating or invited.
|
||||
RoomList roomList;
|
||||
|
||||
/// A list of all rooms the user is not participating anymore.
|
||||
RoomList archive;
|
||||
|
||||
/// Key/Value store of account data.
|
||||
Map<String, AccountData> accountData = {};
|
||||
|
||||
|
@ -262,27 +259,33 @@ class Client {
|
|||
|
||||
/// Creates a new [RoomList] object.
|
||||
RoomList getRoomList(
|
||||
{bool onlyLeft = false,
|
||||
onRoomListUpdateCallback onUpdate,
|
||||
{onRoomListUpdateCallback onUpdate,
|
||||
onRoomListInsertCallback onInsert,
|
||||
onRoomListRemoveCallback onRemove}) {
|
||||
List<Room> rooms = onlyLeft ? archive.rooms : roomList.rooms;
|
||||
List<Room> rooms = roomList.rooms;
|
||||
return RoomList(
|
||||
client: this,
|
||||
onlyLeft: onlyLeft,
|
||||
onlyLeft: false,
|
||||
onUpdate: onUpdate,
|
||||
onInsert: onInsert,
|
||||
onRemove: onRemove,
|
||||
rooms: rooms);
|
||||
}
|
||||
|
||||
/// Searches in the roomList and in the archive for a room with the given [id].
|
||||
Room getRoomById(String id) {
|
||||
Room room = roomList.getRoomById(id);
|
||||
if (room == null) room = archive.getRoomById(id);
|
||||
return room;
|
||||
Future<RoomList> get archive async {
|
||||
RoomList archiveList = RoomList(client: this, rooms: [], onlyLeft: true);
|
||||
String syncFilters =
|
||||
'{"room":{"include_leave":true,"timeline":{"limit":1}}}';
|
||||
String action = "/client/r0/sync?filter=$syncFilters&timeout=0";
|
||||
final syncResp =
|
||||
await connection.jsonRequest(type: HTTPType.GET, action: action);
|
||||
if (!(syncResp is ErrorResponse)) await connection.handleSync(syncResp);
|
||||
return archiveList;
|
||||
}
|
||||
|
||||
/// Searches in the roomList and in the archive for a room with the given [id].
|
||||
Room getRoomById(String id) => roomList.getRoomById(id);
|
||||
|
||||
Future<dynamic> joinRoomById(String id) async {
|
||||
return await connection.jsonRequest(
|
||||
type: HTTPType.POST, action: "/client/r0/join/$id");
|
||||
|
|
|
@ -49,9 +49,6 @@ class Connection {
|
|||
|
||||
static String syncFilters = '{"room":{"state":{"lazy_load_members":true}}}';
|
||||
|
||||
static String firstSyncFilters =
|
||||
'{"room":{"include_leave":true,"state":{"lazy_load_members":true}}}';
|
||||
|
||||
/// Handles the connection to the Matrix Homeserver. You can change this to a
|
||||
/// MockClient for testing.
|
||||
http.Client httpClient = http.Client();
|
||||
|
@ -145,11 +142,9 @@ class Connection {
|
|||
client.prevBatch = newPrevBatch;
|
||||
|
||||
List<Room> rooms = [];
|
||||
List<Room> archivedRooms = [];
|
||||
if (client.store != null) {
|
||||
client.store.storeClient();
|
||||
rooms = await client.store.getRoomList(onlyLeft: false);
|
||||
archivedRooms = await client.store.getRoomList(onlyLeft: true);
|
||||
client.accountData = await client.store.getAccountData();
|
||||
client.presences = await client.store.getPresences();
|
||||
}
|
||||
|
@ -162,14 +157,6 @@ class Connection {
|
|||
onRemove: null,
|
||||
rooms: rooms);
|
||||
|
||||
client.archive = RoomList(
|
||||
client: client,
|
||||
onlyLeft: true,
|
||||
onUpdate: null,
|
||||
onInsert: null,
|
||||
onRemove: null,
|
||||
rooms: archivedRooms);
|
||||
|
||||
_userEventSub ??= onUserEvent.stream.listen(client.handleUserUpdate);
|
||||
|
||||
onLoginStateChanged.add(LoginState.logged);
|
||||
|
@ -309,10 +296,9 @@ class Connection {
|
|||
Future<void> _sync() async {
|
||||
if (client.isLogged() == false) return;
|
||||
|
||||
String action = "/client/r0/sync?filter=$firstSyncFilters";
|
||||
String action = "/client/r0/sync?filter=$syncFilters";
|
||||
|
||||
if (client.prevBatch != null) {
|
||||
action = "/client/r0/sync?filter=$syncFilters";
|
||||
action += "&timeout=30000";
|
||||
action += "&since=${client.prevBatch}";
|
||||
}
|
||||
|
@ -327,12 +313,12 @@ class Connection {
|
|||
try {
|
||||
if (client.store != null)
|
||||
await client.store.transaction(() {
|
||||
_handleSync(syncResp);
|
||||
handleSync(syncResp);
|
||||
client.store.storePrevBatch(syncResp);
|
||||
return;
|
||||
});
|
||||
else
|
||||
await _handleSync(syncResp);
|
||||
await handleSync(syncResp);
|
||||
if (client.prevBatch == null) client.connection.onFirstSync.add(true);
|
||||
client.prevBatch = syncResp["next_batch"];
|
||||
} catch (e) {
|
||||
|
@ -344,7 +330,7 @@ class Connection {
|
|||
if (hash == _syncRequest.hashCode) _sync();
|
||||
}
|
||||
|
||||
void _handleSync(dynamic sync) {
|
||||
void handleSync(dynamic sync) {
|
||||
if (sync["rooms"] is Map<String, dynamic>) {
|
||||
if (sync["rooms"]["join"] is Map<String, dynamic>)
|
||||
_handleRooms(sync["rooms"]["join"], Membership.join);
|
||||
|
|
|
@ -203,11 +203,25 @@ class Room {
|
|||
!canonicalAlias.isEmpty &&
|
||||
canonicalAlias.length > 3)
|
||||
return canonicalAlias.substring(1, canonicalAlias.length).split(":")[0];
|
||||
if (mHeroes != null && mHeroes.length > 0 && mHeroes.any((h) => h.isNotEmpty)) {
|
||||
List<String> heroes = [];
|
||||
if (mHeroes != null &&
|
||||
mHeroes.length > 0 &&
|
||||
mHeroes.any((h) => h.isNotEmpty)) {
|
||||
heroes = mHeroes;
|
||||
} else {
|
||||
if (states["m.room.member"] is Map<String, dynamic>) {
|
||||
for (var entry in states["m.room.member"].entries) {
|
||||
RoomState state = entry.value;
|
||||
if (state.type == EventTypes.RoomMember &&
|
||||
state.stateKey != client?.userID) heroes.add(state.stateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (heroes.length > 0) {
|
||||
String displayname = "";
|
||||
for (int i = 0; i < mHeroes.length; i++) {
|
||||
if (mHeroes[i].isEmpty) continue;
|
||||
displayname += User(mHeroes[i]).calcDisplayname() + ", ";
|
||||
for (int i = 0; i < heroes.length; i++) {
|
||||
if (heroes[i].isEmpty) continue;
|
||||
displayname += User(heroes[i]).calcDisplayname() + ", ";
|
||||
}
|
||||
return displayname.substring(0, displayname.length - 2);
|
||||
}
|
||||
|
@ -679,7 +693,6 @@ class Room {
|
|||
List<User> getParticipants() {
|
||||
List<User> userList = [];
|
||||
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);
|
||||
|
|
|
@ -27,6 +27,7 @@ import 'package:famedlysdk/src/AccountData.dart';
|
|||
import 'package:famedlysdk/src/Client.dart';
|
||||
import 'package:famedlysdk/src/Connection.dart';
|
||||
import 'package:famedlysdk/src/Presence.dart';
|
||||
import 'package:famedlysdk/src/RoomList.dart';
|
||||
import 'package:famedlysdk/src/User.dart';
|
||||
import 'package:famedlysdk/src/requests/SetPushersRequest.dart';
|
||||
import 'package:famedlysdk/src/responses/ErrorResponse.dart';
|
||||
|
@ -207,7 +208,7 @@ void main() {
|
|||
|
||||
List<RoomUpdate> roomUpdateList = await roomUpdateListFuture;
|
||||
|
||||
expect(roomUpdateList.length, 3);
|
||||
expect(roomUpdateList.length, 2);
|
||||
|
||||
expect(roomUpdateList[0].id == "!726s6s6q:example.com", true);
|
||||
expect(roomUpdateList[0].membership == Membership.join, true);
|
||||
|
@ -222,13 +223,6 @@ void main() {
|
|||
expect(roomUpdateList[1].limitedTimeline == false, true);
|
||||
expect(roomUpdateList[1].notification_count == 0, true);
|
||||
expect(roomUpdateList[1].highlight_count == 0, true);
|
||||
|
||||
expect(roomUpdateList[2].id == "!5345234234:example.com", true);
|
||||
expect(roomUpdateList[2].membership == Membership.leave, true);
|
||||
expect(roomUpdateList[2].prev_batch == "", true);
|
||||
expect(roomUpdateList[2].limitedTimeline == false, true);
|
||||
expect(roomUpdateList[2].notification_count == 0, true);
|
||||
expect(roomUpdateList[2].highlight_count == 0, true);
|
||||
});
|
||||
|
||||
test('Event Update Test', () async {
|
||||
|
@ -364,6 +358,15 @@ void main() {
|
|||
expect(resp["room_id"], roomID);
|
||||
});
|
||||
|
||||
test('get archive', () async {
|
||||
RoomList archive = await matrix.archive;
|
||||
|
||||
await new Future.delayed(new Duration(milliseconds: 50));
|
||||
expect(archive.rooms.length, 1);
|
||||
expect(archive.rooms[0].id, "!5345234234:example.com");
|
||||
expect(archive.rooms[0].membership, Membership.leave);
|
||||
});
|
||||
|
||||
test('Logout when token is unknown', () async {
|
||||
Future<LoginState> loginStateFuture =
|
||||
matrix.connection.onLoginStateChanged.stream.first;
|
||||
|
|
|
@ -62,6 +62,176 @@ class FakeMatrixApi extends MockClient {
|
|||
return Response(json.encode(res), 100);
|
||||
});
|
||||
|
||||
static Map<String, dynamic> syncResponse = {
|
||||
"next_batch": Random().nextDouble().toString(),
|
||||
"presence": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.presence",
|
||||
"content": {"presence": "online"}
|
||||
}
|
||||
]
|
||||
},
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"type": "org.example.custom.config",
|
||||
"content": {"custom_config_key": "custom_config_value"}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"@bob:example.com": [
|
||||
"!726s6s6q:example.com",
|
||||
"!hgfedcba:example.com"
|
||||
]
|
||||
},
|
||||
"type": "m.direct"
|
||||
},
|
||||
]
|
||||
},
|
||||
"to_device": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.new_device",
|
||||
"content": {
|
||||
"device_id": "XYZABCDE",
|
||||
"rooms": ["!726s6s6q:example.com"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"rooms": {
|
||||
"join": {
|
||||
"!726s6s6q:example.com": {
|
||||
"unread_notifications": {
|
||||
"highlight_count": 2,
|
||||
"notification_count": 2,
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@alice:example.com",
|
||||
"content": {"membership": "join"},
|
||||
"origin_server_ts": 1417731086795,
|
||||
"event_id": "66697273743031:example.com"
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.canonical_alias",
|
||||
"content": {
|
||||
"alias": "#famedlyContactDiscovery:fakeServer.notExisting"
|
||||
},
|
||||
"state_key": "",
|
||||
"origin_server_ts": 1417731086796,
|
||||
"event_id": "66697273743032:example.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@bob:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@bob:example.com",
|
||||
"content": {"membership": "join"},
|
||||
"prev_content": {"membership": "invite"},
|
||||
"origin_server_ts": 1417731086795,
|
||||
"event_id": "7365636s6r6432:example.com"
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.message",
|
||||
"txn_id": "1234",
|
||||
"content": {"body": "I am a fish", "msgtype": "m.text"},
|
||||
"origin_server_ts": 1417731086797,
|
||||
"event_id": "74686972643033:example.com"
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.typing",
|
||||
"content": {
|
||||
"user_ids": ["@alice:example.com"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"7365636s6r6432:example.com": {
|
||||
"m.read": {
|
||||
"@alice:example.com": {"ts": 1436451550453}
|
||||
}
|
||||
}
|
||||
},
|
||||
"room_id": "!726s6s6q:example.com",
|
||||
"type": "m.receipt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.tag",
|
||||
"content": {
|
||||
"tags": {
|
||||
"work": {"order": 1}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "org.example.custom.room.config",
|
||||
"content": {"custom_config_key": "custom_config_value"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
"!696r7674:example.com": {
|
||||
"invite_state": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.name",
|
||||
"state_key": "",
|
||||
"content": {"name": "My Room Name"}
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@bob:example.com",
|
||||
"content": {"membership": "invite"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static Map<String, dynamic> archiveSyncResponse = {
|
||||
"next_batch": Random().nextDouble().toString(),
|
||||
"presence": {"events": []},
|
||||
"account_data": {"events": []},
|
||||
"to_device": {"events": []},
|
||||
"rooms": {
|
||||
"join": {},
|
||||
"invite": {},
|
||||
"leave": {
|
||||
"!5345234234:example.com": {
|
||||
"timeline": {"events": []}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static final Map<String, Map<String, dynamic>> api = {
|
||||
"GET": {
|
||||
"/client/r0/rooms/!localpart:server.abc/state/m.room.member/@getme:example.com":
|
||||
|
@ -339,171 +509,10 @@ class FakeMatrixApi extends MockClient {
|
|||
]
|
||||
}
|
||||
},
|
||||
"/client/r0/sync?filter=%7B%22room%22:%7B%22include_leave%22:true,%22state%22:%7B%22lazy_load_members%22:true%7D%7D%7D":
|
||||
(var req) => {
|
||||
"next_batch": Random().nextDouble().toString(),
|
||||
"presence": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.presence",
|
||||
"content": {"presence": "online"}
|
||||
}
|
||||
]
|
||||
},
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"type": "org.example.custom.config",
|
||||
"content": {"custom_config_key": "custom_config_value"}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"@bob:example.com": [
|
||||
"!726s6s6q:example.com",
|
||||
"!hgfedcba:example.com"
|
||||
]
|
||||
},
|
||||
"type": "m.direct"
|
||||
},
|
||||
]
|
||||
},
|
||||
"to_device": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.new_device",
|
||||
"content": {
|
||||
"device_id": "XYZABCDE",
|
||||
"rooms": ["!726s6s6q:example.com"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"rooms": {
|
||||
"join": {
|
||||
"!726s6s6q:example.com": {
|
||||
"unread_notifications": {
|
||||
"highlight_count": 2,
|
||||
"notification_count": 2,
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@alice:example.com",
|
||||
"content": {"membership": "join"},
|
||||
"origin_server_ts": 1417731086795,
|
||||
"event_id": "66697273743031:example.com"
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.canonical_alias",
|
||||
"content": {
|
||||
"alias":
|
||||
"#famedlyContactDiscovery:fakeServer.notExisting"
|
||||
},
|
||||
"state_key": "",
|
||||
"origin_server_ts": 1417731086796,
|
||||
"event_id": "66697273743032:example.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@bob:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@bob:example.com",
|
||||
"content": {"membership": "join"},
|
||||
"prev_content": {"membership": "invite"},
|
||||
"origin_server_ts": 1417731086795,
|
||||
"event_id": "7365636s6r6432:example.com"
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.message",
|
||||
"txn_id": "1234",
|
||||
"content": {
|
||||
"body": "I am a fish",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"origin_server_ts": 1417731086797,
|
||||
"event_id": "74686972643033:example.com"
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.typing",
|
||||
"content": {
|
||||
"user_ids": ["@alice:example.com"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"7365636s6r6432:example.com": {
|
||||
"m.read": {
|
||||
"@alice:example.com": {"ts": 1436451550453}
|
||||
}
|
||||
}
|
||||
},
|
||||
"room_id": "!726s6s6q:example.com",
|
||||
"type": "m.receipt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.tag",
|
||||
"content": {
|
||||
"tags": {
|
||||
"work": {"order": 1}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "org.example.custom.room.config",
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
"!696r7674:example.com": {
|
||||
"invite_state": {
|
||||
"events": [
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.name",
|
||||
"state_key": "",
|
||||
"content": {"name": "My Room Name"}
|
||||
},
|
||||
{
|
||||
"sender": "@alice:example.com",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@bob:example.com",
|
||||
"content": {"membership": "invite"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"leave": {
|
||||
"!5345234234:example.com": {
|
||||
"timeline": {"events": []}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"/client/r0/sync?filter=%7B%22room%22:%7B%22include_leave%22:true,%22timeline%22:%7B%22limit%22:1%7D%7D%7D&timeout=0":
|
||||
(var req) => archiveSyncResponse,
|
||||
"/client/r0/sync?filter=%7B%22room%22:%7B%22state%22:%7B%22lazy_load_members%22:true%7D%7D%7D":
|
||||
(var req) => syncResponse,
|
||||
},
|
||||
"POST": {
|
||||
"/client/r0/login": (var req) => {
|
||||
|
|
Loading…
Reference in a new issue