[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.
|
/// A list of all rooms the user is participating or invited.
|
||||||
RoomList roomList;
|
RoomList roomList;
|
||||||
|
|
||||||
/// A list of all rooms the user is not participating anymore.
|
|
||||||
RoomList archive;
|
|
||||||
|
|
||||||
/// Key/Value store of account data.
|
/// Key/Value store of account data.
|
||||||
Map<String, AccountData> accountData = {};
|
Map<String, AccountData> accountData = {};
|
||||||
|
|
||||||
|
@ -262,27 +259,33 @@ class Client {
|
||||||
|
|
||||||
/// Creates a new [RoomList] object.
|
/// Creates a new [RoomList] object.
|
||||||
RoomList getRoomList(
|
RoomList getRoomList(
|
||||||
{bool onlyLeft = false,
|
{onRoomListUpdateCallback onUpdate,
|
||||||
onRoomListUpdateCallback onUpdate,
|
|
||||||
onRoomListInsertCallback onInsert,
|
onRoomListInsertCallback onInsert,
|
||||||
onRoomListRemoveCallback onRemove}) {
|
onRoomListRemoveCallback onRemove}) {
|
||||||
List<Room> rooms = onlyLeft ? archive.rooms : roomList.rooms;
|
List<Room> rooms = roomList.rooms;
|
||||||
return RoomList(
|
return RoomList(
|
||||||
client: this,
|
client: this,
|
||||||
onlyLeft: onlyLeft,
|
onlyLeft: false,
|
||||||
onUpdate: onUpdate,
|
onUpdate: onUpdate,
|
||||||
onInsert: onInsert,
|
onInsert: onInsert,
|
||||||
onRemove: onRemove,
|
onRemove: onRemove,
|
||||||
rooms: rooms);
|
rooms: rooms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Searches in the roomList and in the archive for a room with the given [id].
|
Future<RoomList> get archive async {
|
||||||
Room getRoomById(String id) {
|
RoomList archiveList = RoomList(client: this, rooms: [], onlyLeft: true);
|
||||||
Room room = roomList.getRoomById(id);
|
String syncFilters =
|
||||||
if (room == null) room = archive.getRoomById(id);
|
'{"room":{"include_leave":true,"timeline":{"limit":1}}}';
|
||||||
return room;
|
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 {
|
Future<dynamic> joinRoomById(String id) async {
|
||||||
return await connection.jsonRequest(
|
return await connection.jsonRequest(
|
||||||
type: HTTPType.POST, action: "/client/r0/join/$id");
|
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 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
|
/// Handles the connection to the Matrix Homeserver. You can change this to a
|
||||||
/// MockClient for testing.
|
/// MockClient for testing.
|
||||||
http.Client httpClient = http.Client();
|
http.Client httpClient = http.Client();
|
||||||
|
@ -145,11 +142,9 @@ class Connection {
|
||||||
client.prevBatch = newPrevBatch;
|
client.prevBatch = newPrevBatch;
|
||||||
|
|
||||||
List<Room> rooms = [];
|
List<Room> rooms = [];
|
||||||
List<Room> archivedRooms = [];
|
|
||||||
if (client.store != null) {
|
if (client.store != null) {
|
||||||
client.store.storeClient();
|
client.store.storeClient();
|
||||||
rooms = await client.store.getRoomList(onlyLeft: false);
|
rooms = await client.store.getRoomList(onlyLeft: false);
|
||||||
archivedRooms = await client.store.getRoomList(onlyLeft: true);
|
|
||||||
client.accountData = await client.store.getAccountData();
|
client.accountData = await client.store.getAccountData();
|
||||||
client.presences = await client.store.getPresences();
|
client.presences = await client.store.getPresences();
|
||||||
}
|
}
|
||||||
|
@ -162,14 +157,6 @@ class Connection {
|
||||||
onRemove: null,
|
onRemove: null,
|
||||||
rooms: rooms);
|
rooms: rooms);
|
||||||
|
|
||||||
client.archive = RoomList(
|
|
||||||
client: client,
|
|
||||||
onlyLeft: true,
|
|
||||||
onUpdate: null,
|
|
||||||
onInsert: null,
|
|
||||||
onRemove: null,
|
|
||||||
rooms: archivedRooms);
|
|
||||||
|
|
||||||
_userEventSub ??= onUserEvent.stream.listen(client.handleUserUpdate);
|
_userEventSub ??= onUserEvent.stream.listen(client.handleUserUpdate);
|
||||||
|
|
||||||
onLoginStateChanged.add(LoginState.logged);
|
onLoginStateChanged.add(LoginState.logged);
|
||||||
|
@ -309,10 +296,9 @@ class Connection {
|
||||||
Future<void> _sync() async {
|
Future<void> _sync() async {
|
||||||
if (client.isLogged() == false) return;
|
if (client.isLogged() == false) return;
|
||||||
|
|
||||||
String action = "/client/r0/sync?filter=$firstSyncFilters";
|
String action = "/client/r0/sync?filter=$syncFilters";
|
||||||
|
|
||||||
if (client.prevBatch != null) {
|
if (client.prevBatch != null) {
|
||||||
action = "/client/r0/sync?filter=$syncFilters";
|
|
||||||
action += "&timeout=30000";
|
action += "&timeout=30000";
|
||||||
action += "&since=${client.prevBatch}";
|
action += "&since=${client.prevBatch}";
|
||||||
}
|
}
|
||||||
|
@ -327,12 +313,12 @@ class Connection {
|
||||||
try {
|
try {
|
||||||
if (client.store != null)
|
if (client.store != null)
|
||||||
await client.store.transaction(() {
|
await client.store.transaction(() {
|
||||||
_handleSync(syncResp);
|
handleSync(syncResp);
|
||||||
client.store.storePrevBatch(syncResp);
|
client.store.storePrevBatch(syncResp);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
else
|
else
|
||||||
await _handleSync(syncResp);
|
await handleSync(syncResp);
|
||||||
if (client.prevBatch == null) client.connection.onFirstSync.add(true);
|
if (client.prevBatch == null) client.connection.onFirstSync.add(true);
|
||||||
client.prevBatch = syncResp["next_batch"];
|
client.prevBatch = syncResp["next_batch"];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -344,7 +330,7 @@ class Connection {
|
||||||
if (hash == _syncRequest.hashCode) _sync();
|
if (hash == _syncRequest.hashCode) _sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleSync(dynamic sync) {
|
void handleSync(dynamic sync) {
|
||||||
if (sync["rooms"] is Map<String, dynamic>) {
|
if (sync["rooms"] is Map<String, dynamic>) {
|
||||||
if (sync["rooms"]["join"] is Map<String, dynamic>)
|
if (sync["rooms"]["join"] is Map<String, dynamic>)
|
||||||
_handleRooms(sync["rooms"]["join"], Membership.join);
|
_handleRooms(sync["rooms"]["join"], Membership.join);
|
||||||
|
|
|
@ -203,11 +203,25 @@ class Room {
|
||||||
!canonicalAlias.isEmpty &&
|
!canonicalAlias.isEmpty &&
|
||||||
canonicalAlias.length > 3)
|
canonicalAlias.length > 3)
|
||||||
return canonicalAlias.substring(1, canonicalAlias.length).split(":")[0];
|
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 = "";
|
String displayname = "";
|
||||||
for (int i = 0; i < mHeroes.length; i++) {
|
for (int i = 0; i < heroes.length; i++) {
|
||||||
if (mHeroes[i].isEmpty) continue;
|
if (heroes[i].isEmpty) continue;
|
||||||
displayname += User(mHeroes[i]).calcDisplayname() + ", ";
|
displayname += User(heroes[i]).calcDisplayname() + ", ";
|
||||||
}
|
}
|
||||||
return displayname.substring(0, displayname.length - 2);
|
return displayname.substring(0, displayname.length - 2);
|
||||||
}
|
}
|
||||||
|
@ -679,7 +693,6 @@ class Room {
|
||||||
List<User> getParticipants() {
|
List<User> getParticipants() {
|
||||||
List<User> userList = [];
|
List<User> userList = [];
|
||||||
if (states["m.room.member"] is Map<String, dynamic>) {
|
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) {
|
for (var entry in states["m.room.member"].entries) {
|
||||||
RoomState state = entry.value;
|
RoomState state = entry.value;
|
||||||
if (state.type == EventTypes.RoomMember) userList.add(state.asUser);
|
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/Client.dart';
|
||||||
import 'package:famedlysdk/src/Connection.dart';
|
import 'package:famedlysdk/src/Connection.dart';
|
||||||
import 'package:famedlysdk/src/Presence.dart';
|
import 'package:famedlysdk/src/Presence.dart';
|
||||||
|
import 'package:famedlysdk/src/RoomList.dart';
|
||||||
import 'package:famedlysdk/src/User.dart';
|
import 'package:famedlysdk/src/User.dart';
|
||||||
import 'package:famedlysdk/src/requests/SetPushersRequest.dart';
|
import 'package:famedlysdk/src/requests/SetPushersRequest.dart';
|
||||||
import 'package:famedlysdk/src/responses/ErrorResponse.dart';
|
import 'package:famedlysdk/src/responses/ErrorResponse.dart';
|
||||||
|
@ -207,7 +208,7 @@ void main() {
|
||||||
|
|
||||||
List<RoomUpdate> roomUpdateList = await roomUpdateListFuture;
|
List<RoomUpdate> roomUpdateList = await roomUpdateListFuture;
|
||||||
|
|
||||||
expect(roomUpdateList.length, 3);
|
expect(roomUpdateList.length, 2);
|
||||||
|
|
||||||
expect(roomUpdateList[0].id == "!726s6s6q:example.com", true);
|
expect(roomUpdateList[0].id == "!726s6s6q:example.com", true);
|
||||||
expect(roomUpdateList[0].membership == Membership.join, true);
|
expect(roomUpdateList[0].membership == Membership.join, true);
|
||||||
|
@ -222,13 +223,6 @@ void main() {
|
||||||
expect(roomUpdateList[1].limitedTimeline == false, true);
|
expect(roomUpdateList[1].limitedTimeline == false, true);
|
||||||
expect(roomUpdateList[1].notification_count == 0, true);
|
expect(roomUpdateList[1].notification_count == 0, true);
|
||||||
expect(roomUpdateList[1].highlight_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 {
|
test('Event Update Test', () async {
|
||||||
|
@ -364,6 +358,15 @@ void main() {
|
||||||
expect(resp["room_id"], roomID);
|
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 {
|
test('Logout when token is unknown', () async {
|
||||||
Future<LoginState> loginStateFuture =
|
Future<LoginState> loginStateFuture =
|
||||||
matrix.connection.onLoginStateChanged.stream.first;
|
matrix.connection.onLoginStateChanged.stream.first;
|
||||||
|
|
|
@ -62,6 +62,176 @@ class FakeMatrixApi extends MockClient {
|
||||||
return Response(json.encode(res), 100);
|
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 = {
|
static final Map<String, Map<String, dynamic>> api = {
|
||||||
"GET": {
|
"GET": {
|
||||||
"/client/r0/rooms/!localpart:server.abc/state/m.room.member/@getme:example.com":
|
"/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":
|
"/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) => {
|
(var req) => archiveSyncResponse,
|
||||||
"next_batch": Random().nextDouble().toString(),
|
"/client/r0/sync?filter=%7B%22room%22:%7B%22state%22:%7B%22lazy_load_members%22:true%7D%7D%7D":
|
||||||
"presence": {
|
(var req) => syncResponse,
|
||||||
"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": []}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"POST": {
|
"POST": {
|
||||||
"/client/r0/login": (var req) => {
|
"/client/r0/login": (var req) => {
|
||||||
|
|
Loading…
Reference in a new issue