diff --git a/lib/src/Room.dart b/lib/src/Room.dart index c037999..1b1630e 100644 --- a/lib/src/Room.dart +++ b/lib/src/Room.dart @@ -98,6 +98,9 @@ class Room { } return displayname.substring(0, displayname.length - 2); } + if (membership == Membership.invite && states.containsKey(client.userID)) { + return states[client.userID].sender.calcDisplayname(); + } return "Empty chat"; } @@ -112,6 +115,9 @@ class Room { return MxContent(states["m.room.avatar"].content["url"]); if (mHeroes != null && mHeroes.length == 1 && states[mHeroes[0]] != null) return states[mHeroes[0]].asUser.avatarUrl; + if (membership == Membership.invite && states.containsKey(client.userID)) { + return states[client.userID].sender.avatarUrl; + } return MxContent(""); } @@ -378,8 +384,24 @@ class Room { return null; } - /// Call the Matrix API to leave this room. + /// Call the Matrix API to join this room if the user is not already a member. + /// If this room is intended to be a direct chat, the direct chat flag will + /// automatically be set. + Future join() async { + dynamic res = await client.connection.jsonRequest( + type: HTTPType.POST, action: "/client/r0/rooms/${id}/join"); + if (res is ErrorResponse) client.connection.onError.add(res); + if (states.containsKey(client.userID) && + states[client.userID].content["is_direct"] is bool && + states[client.userID].content["is_direct"]) + addToDirectChat(states[client.userID].sender.id); + return res; + } + + /// Call the Matrix API to leave this room. If this room is set as a direct + /// chat, this will be removed too. Future leave() async { + if (directChatMatrixID != "") await removeFromDirectChat(); dynamic res = await client.connection.jsonRequest( type: HTTPType.POST, action: "/client/r0/rooms/${id}/leave"); if (res is ErrorResponse) client.connection.onError.add(res); @@ -542,6 +564,22 @@ class Room { return resp; } + /// Sets this room as a direct chat for this user. + Future removeFromDirectChat() async { + Map directChats = client.directChats; + if (directChats.containsKey(directChatMatrixID) && + directChats[directChatMatrixID].contains(id)) + directChats[directChatMatrixID].remove(id); + else + return null; // Nothing to do here + + final resp = await client.connection.jsonRequest( + type: HTTPType.PUT, + action: "/client/r0/user/${client.userID}/account_data/m.direct", + data: directChats); + return resp; + } + /// Sends *m.fully_read* and *m.read* for the given event ID. Future sendReadReceipt(String eventID) async { final dynamic resp = client.connection.jsonRequest( diff --git a/lib/src/RoomList.dart b/lib/src/RoomList.dart index 19be2fe..e31031a 100644 --- a/lib/src/RoomList.dart +++ b/lib/src/RoomList.dart @@ -124,9 +124,11 @@ class RoomList { // Update notification, highlight count and/or additional informations else if (found && chatUpdate.membership != Membership.leave && - (rooms[j].notificationCount != chatUpdate.notification_count || + (rooms[j].membership != chatUpdate.membership || + rooms[j].notificationCount != chatUpdate.notification_count || rooms[j].highlightCount != chatUpdate.highlight_count || chatUpdate.summary != null)) { + rooms[j].membership = chatUpdate.membership; rooms[j].notificationCount = chatUpdate.notification_count; rooms[j].highlightCount = chatUpdate.highlight_count; if (chatUpdate.prev_batch != null) @@ -145,7 +147,9 @@ class RoomList { } void _handleEventUpdate(EventUpdate eventUpdate) { - if (eventUpdate.type != "timeline" && eventUpdate.type != "state") return; + if (eventUpdate.type != "timeline" && + eventUpdate.type != "state" && + eventUpdate.type != "invite_state") return; // Search the room in the rooms num j = 0; for (j = 0; j < rooms.length; j++) {