From 898767875a3d4748695f85a1681a3e789da3e3d7 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Wed, 7 Aug 2019 12:06:28 +0200 Subject: [PATCH] [SDK] Fix bugs --- lib/src/AccountData.dart | 9 +++++++++ lib/src/Client.dart | 36 +++++++++++++++++++++++++++++++++++- lib/src/Connection.dart | 32 ++++++++++++++++++++------------ lib/src/Presence.dart | 11 +++++++++++ lib/src/Room.dart | 3 +-- lib/src/RoomList.dart | 7 +++++++ lib/src/Store.dart | 22 ++++++++++++++++++++++ lib/src/User.dart | 2 +- 8 files changed, 106 insertions(+), 16 deletions(-) diff --git a/lib/src/AccountData.dart b/lib/src/AccountData.dart index 0eb1393..ccb9059 100644 --- a/lib/src/AccountData.dart +++ b/lib/src/AccountData.dart @@ -21,6 +21,8 @@ * along with famedlysdk. If not, see . */ +import 'package:famedlysdk/src/RawEvent.dart'; + class AccountData { /// The json payload of the content. The content highly depends on the type. final Map content; @@ -29,4 +31,11 @@ class AccountData { final String typeKey; AccountData({this.content, this.typeKey}); + + /// Get a State event from a table row or from the event stream. + factory AccountData.fromJson(Map jsonPayload) { + final Map content = + RawEvent.getMapFromPayload(jsonPayload['content']); + return AccountData(content: content, typeKey: jsonPayload['type']); + } } diff --git a/lib/src/Client.dart b/lib/src/Client.dart index 263b207..6de66c2 100644 --- a/lib/src/Client.dart +++ b/lib/src/Client.dart @@ -24,6 +24,10 @@ import 'dart:async'; import 'dart:core'; +import 'package:famedlysdk/src/AccountData.dart'; +import 'package:famedlysdk/src/Presence.dart'; +import 'package:famedlysdk/src/sync/UserUpdate.dart'; + import 'Connection.dart'; import 'Room.dart'; import 'RoomList.dart'; @@ -86,8 +90,38 @@ class Client { /// Returns the current login state. bool isLogged() => accessToken != null; + /// A list of all rooms the user is participating or invited. RoomList roomList; + /// Key/Value store of account data. + Map accountData = {}; + + /// Presences of users by a given matrix ID + Map presences = {}; + + void handleUserUpdate(UserUpdate userUpdate) { + if (userUpdate.type == "account_data") { + AccountData newAccountData = AccountData.fromJson(userUpdate.content); + accountData[newAccountData.typeKey] = newAccountData; + } + if (userUpdate.type == "presence") { + Presence newPresence = Presence.fromJson(userUpdate.content); + presences[newPresence.typeKey] = newPresence; + } + } + + Map> get directChats => + accountData["m.direct"] != null ? accountData["m.direct"].content : {}; + + /// Returns the (first) room ID from the store which is a private chat with the user [userId]. + /// Returns null if there is none. + String getDirectChatFromUserId(String userId) => + accountData["m.direct"] != null && + accountData["m.direct"].content[userId] is List && + accountData["m.direct"].content[userId].length > 0 + ? accountData["m.direct"].content[userId][0] + : null; + /// Checks the supported versions of the Matrix protocol and the supported /// login types. Returns false if the server is not compatible with the /// client. Automatically sets [matrixVersions] and [lazyLoadMembers]. @@ -227,7 +261,7 @@ class Client { /// defined by the autojoin room feature in Synapse. Future> loadFamedlyContacts() async { List contacts = []; - Room contactDiscoveryRoom = await store + Room contactDiscoveryRoom = roomList .getRoomByAlias("#famedlyContactDiscovery:${userID.split(":")[1]}"); if (contactDiscoveryRoom != null) contacts = await contactDiscoveryRoom.requestParticipants(); diff --git a/lib/src/Connection.dart b/lib/src/Connection.dart index 4d86f2a..ab312a9 100644 --- a/lib/src/Connection.dart +++ b/lib/src/Connection.dart @@ -149,25 +149,33 @@ class Connection { client.lazyLoadMembers = newLazyLoadMembers; client.prevBatch = newPrevBatch; - client.store?.storeClient(); + if (client.store != null) { + client.store.storeClient(); - List rooms = await client.store - ?.getRoomList(onlyLeft: false, onlyGroups: false, onlyDirect: false); - client.roomList = RoomList( - client: client, - onlyLeft: false, - onlyDirect: false, - onlyGroups: false, - onUpdate: null, - onInsert: null, - onRemove: null, - rooms: rooms); + List rooms = await client.store + .getRoomList(onlyLeft: false, onlyGroups: false, onlyDirect: false); + client.roomList = RoomList( + client: client, + onlyLeft: false, + onlyDirect: false, + onlyGroups: false, + onUpdate: null, + onInsert: null, + onRemove: null, + rooms: rooms); + client.accountData = await client.store.getAccountData(); + client.presences = await client.store.getPresences(); + } + + _userEventSub ??= onUserEvent.stream.listen(client.handleUserUpdate); onLoginStateChanged.add(LoginState.logged); _sync(); } + StreamSubscription _userEventSub; + /// Resets all settings and stops the synchronisation. void clear() { client.store?.clear(); diff --git a/lib/src/Presence.dart b/lib/src/Presence.dart index 291cd04..2014519 100644 --- a/lib/src/Presence.dart +++ b/lib/src/Presence.dart @@ -22,6 +22,7 @@ */ import 'package:famedlysdk/src/AccountData.dart'; +import 'package:famedlysdk/src/RawEvent.dart'; class Presence extends AccountData { /// The user who has sent this event if it is not a global account data event. @@ -29,4 +30,14 @@ class Presence extends AccountData { Presence({this.sender, Map content, String typeKey}) : super(content: content, typeKey: typeKey); + + /// Get a State event from a table row or from the event stream. + factory Presence.fromJson(Map jsonPayload) { + final Map content = + RawEvent.getMapFromPayload(jsonPayload['content']); + return Presence( + content: content, + typeKey: jsonPayload['type'], + sender: jsonPayload['sender']); + } } diff --git a/lib/src/Room.dart b/lib/src/Room.dart index b83682e..04fa9c5 100644 --- a/lib/src/Room.dart +++ b/lib/src/Room.dart @@ -363,8 +363,7 @@ class Room { /// Sets this room as a direct chat for this user. Future addToDirectChat(String userID) async { - Map> directChats = - await client.store.getAccountDataDirectChats(); + Map> directChats = client.directChats; if (directChats.containsKey(userID)) if (!directChats[userID].contains(id)) directChats[userID].add(id); else diff --git a/lib/src/RoomList.dart b/lib/src/RoomList.dart index 44ede0f..1a160b5 100644 --- a/lib/src/RoomList.dart +++ b/lib/src/RoomList.dart @@ -73,6 +73,13 @@ class RoomList { roomSub ??= client.connection.onRoomUpdate.stream.listen(_handleRoomUpdate); } + Room getRoomByAlias(String alias) { + for (int i = 0; i < rooms.length; i++) { + if (rooms[i].canonicalAlias == alias) return rooms[i]; + } + return null; + } + void _handleRoomUpdate(RoomUpdate chatUpdate) { // Update the chat list item. // Search the room in the rooms diff --git a/lib/src/Store.dart b/lib/src/Store.dart index 1b77729..5a2bb9b 100644 --- a/lib/src/Store.dart +++ b/lib/src/Store.dart @@ -25,6 +25,8 @@ import 'dart:async'; import 'dart:convert'; import 'dart:core'; +import 'package:famedlysdk/src/AccountData.dart'; +import 'package:famedlysdk/src/Presence.dart'; import 'package:famedlysdk/src/State.dart'; import 'package:path/path.dart' as p; import 'package:sqflite/sqflite.dart'; @@ -398,6 +400,26 @@ class Store { return Event.fromJson(res[0], room); } + Future> getAccountData() async { + Map newAccountData = {}; + List> rawAccountData = + await db.rawQuery("SELECT * FROM AccountData"); + for (int i = 0; i < rawAccountData.length; i++) + newAccountData[rawAccountData[i]["type"]] = + AccountData.fromJson(rawAccountData[i]); + return newAccountData; + } + + Future> getPresences() async { + Map newPresences = {}; + List> rawPresences = + await db.rawQuery("SELECT * FROM Presences"); + for (int i = 0; i < rawPresences.length; i++) + newPresences[rawPresences[i]["type"]] = + Presence.fromJson(rawPresences[i]); + return newPresences; + } + Future forgetNotification(String roomID) async { await db .rawDelete("DELETE FROM NotificationsCache WHERE chat_id=?", [roomID]); diff --git a/lib/src/User.dart b/lib/src/User.dart index 6152341..7a10ab0 100644 --- a/lib/src/User.dart +++ b/lib/src/User.dart @@ -89,7 +89,7 @@ class User extends State { /// Returns null on error. Future startDirectChat() async { // Try to find an existing direct chat - String roomID = await room.client?.rooms.getDirectChatRoomID(id); + String roomID = await room.client?.getDirectChatFromUserId(id); if (roomID != null) return roomID; // Start a new direct chat