diff --git a/src/signals/messages.nim b/src/signals/messages.nim index c410842a38..c8a0d8fcc5 100644 --- a/src/signals/messages.nim +++ b/src/signals/messages.nim @@ -33,6 +33,20 @@ proc toChatMember*(jsonMember: JsonNode): ChatMember = userName: generateAlias(pubkey) ) +proc toChatMembershipEvent*(jsonMembership: JsonNode): ChatMembershipEvent = + result = ChatMembershipEvent( + chatId: jsonMembership["chatId"].getStr, + clockValue: jsonMembership["clockValue"].getBiggestInt, + fromKey: jsonMembership["from"].getStr, + rawPayload: jsonMembership["rawPayload"].getStr, + signature: jsonMembership["signature"].getStr, + eventType: jsonMembership["type"].getInt, + members: @[] + ) + if jsonMembership{"members"} != nil: + for member in jsonMembership["members"]: + result.members.add(member.getStr) + const channelColors* = ["#fa6565", "#7cda00", "#887af9", "#51d0f0", "#FE8F59", "#d37ef4"] @@ -82,6 +96,11 @@ proc toChat*(jsonChat: JsonNode): Chat = for jsonMember in jsonChat["members"]: result.members.add(jsonMember.toChatMember) + if jsonChat["membershipUpdateEvents"].kind != JNull: + result.membershipUpdateEvents = @[] + for jsonMember in jsonChat["membershipUpdateEvents"]: + result.membershipUpdateEvents.add(jsonMember.toChatMembershipEvent) + proc toMessage*(jsonMsg: JsonNode): Message = result = Message( alias: jsonMsg{"alias"}.getStr, diff --git a/src/status/chat.nim b/src/status/chat.nim index 18452381e5..d878ceb649 100644 --- a/src/status/chat.nim +++ b/src/status/chat.nim @@ -104,10 +104,26 @@ proc init*(self: ChatModel) = warn "No topics found for chats. Cannot load past messages" else: self.events.emit("mailserverTopics", TopicArgs(topics: topics)); + +proc processChatUpdate(self: ChatModel,response: JsonNode): (seq[Chat], seq[Message]) = + var chats: seq[Chat] = @[] + var messages: seq[Message] = @[] + if response["result"]{"chats"} != nil: + for jsonMsg in response["result"]["messages"]: + messages.add(jsonMsg.toMessage) + if response["result"]{"chats"} != nil: + for jsonChat in response["result"]["chats"]: + let chat = jsonChat.toChat + self.channels[chat.id] = chat + chats.add(chat) + result = (chats, messages) + proc leave*(self: ChatModel, chatId: string) = if self.channels[chatId].chatType == ChatType.PrivateGroupChat: - discard status_chat.leaveGroupChat(chatId) + let leaveGroupResponse = status_chat.leaveGroupChat(chatId) + var (chats, messages) = self.processChatUpdate(parseJson(leaveGroupResponse)) + self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages, chats: chats)) # We still want to be able to receive messages unless we block the 1:1 sender if self.filters.hasKey(chatId) and self.channels[chatId].chatType == ChatType.Public: @@ -137,7 +153,7 @@ proc formatChatUpdate(response: JsonNode): (seq[Chat], seq[Message]) = proc sendMessage*(self: ChatModel, chatId: string, msg: string): string = var sentMessage = status_chat.sendChatMessage(chatId, msg) - var (chats, messages) = formatChatUpdate(parseJson(sentMessage)) + var (chats, messages) = self.processChatUpdate(parseJson(sentMessage)) self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages, chats: chats)) sentMessage @@ -159,7 +175,7 @@ proc markAllChannelMessagesRead*(self: ChatModel, chatId: string): JsonNode = proc confirmJoiningGroup*(self: ChatModel, chatId: string) = var response = parseJson(status_chat.confirmJoiningGroup(chatId)) - var (chats, messages) = formatChatUpdate(response) + var (chats, messages) = self.processChatUpdate(response) self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages, chats: chats)) proc blockContact*(self: ChatModel, id: string): string = diff --git a/src/status/chat/chat.nim b/src/status/chat/chat.nim index f326706940..6d63b2e9fe 100644 --- a/src/status/chat/chat.nim +++ b/src/status/chat/chat.nim @@ -1,5 +1,7 @@ import message import strformat +import json +import sequtils type ChatType* {.pure.}= enum Unknown = 0, @@ -16,6 +18,39 @@ type ChatMember* = object identicon*: string userName*: string +proc toJsonNode*(self: ChatMember): JsonNode = + result = %* { + "id": self.id, + "admin": self.admin, + "joined": self.joined + } + +proc toJsonNode*(self: seq[ChatMember]): seq[JsonNode] = + result = map(self, proc(x: ChatMember): JsonNode = x.toJsonNode) + +type ChatMembershipEvent* = object + chatId*: string + clockValue*: int64 + fromKey*: string + members*: seq[string] + rawPayload*: string + signature*: string + eventType*: int + +proc toJsonNode*(self: ChatMembershipEvent): JsonNode = + result = %* { + "chatId": self.chatId, + "clockValue": self.clockValue, + "from": self.fromKey, + "members": self.members, + "rawPayload": self.rawPayload, + "signature": self.signature, + "type": self.eventType + } + +proc toJsonNode*(self: seq[ChatMembershipEvent]): seq[JsonNode] = + result = map(self, proc(x: ChatMembershipEvent): JsonNode = x.toJsonNode) + type Chat* = ref object id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat name*: string @@ -29,11 +64,27 @@ type Chat* = ref object unviewedMessagesCount*: int lastMessage*: Message members*: seq[ChatMember] - # membershipUpdateEvents # ? + membershipUpdateEvents*: seq[ChatMembershipEvent] proc `$`*(self: Chat): string = result = fmt"Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType})" +proc toJsonNode*(self: Chat): JsonNode = + result = %* { + "active": self.isActive, + "chatType": self.chatType.int, + "color": self.color, + "deletedAtClockValue": self.deletedAtClockValue, + "id": self.id, + "lastClockValue": self.lastClockValue, + "lastMessage": nil, + "members": self.members.toJsonNode, + "membershipUpdateEvents": self.membershipUpdateEvents.toJsonNode, + "name": self.name, + "timestamp": self.timestamp, + "unviewedMessagesCount": self.unviewedMessagesCount + } + proc findIndexById*(self: seq[Chat], id: string): int = result = -1 var idx = -1 diff --git a/src/status/libstatus/chat.nim b/src/status/libstatus/chat.nim index 63e6943ed1..b97ce1027e 100644 --- a/src/status/libstatus/chat.nim +++ b/src/status/libstatus/chat.nim @@ -43,19 +43,8 @@ proc saveChat*(chatId: string, oneToOne: bool = false, active: bool = true, colo ]) proc deactivateChat*(chat: Chat) = - discard callPrivateRPC("saveChat".prefix, %* [ - { - "lastClockValue": 0, # TODO: - "color": chat.color, - "name": chat.name, #TODO: 0x04acde for 1:1? - "lastMessage": nil, # TODO: - "active": false, - "id": chat.id, - "unviewedMessagesCount": 0, #TODO: - "chatType": chat.chatType.int, - "timestamp": 0 # TODO: - } - ]) + chat.isActive = false + discard callPrivateRPC("saveChat".prefix, %* [chat.toJsonNode]) proc loadChats*(): seq[Chat] = result = @[]