fix: initial load of messages and reactions done on a separate thread

This commit is contained in:
Richard Ramos 2021-01-19 13:06:06 -04:00 committed by Iuri Matias
parent 6af10ac900
commit 55466416d6
4 changed files with 66 additions and 16 deletions

View File

@ -48,8 +48,7 @@ proc handleChatEvents(self: ChatController) =
# Do not add community chats to the normal chat list
elif channel.chat.chatType != ChatType.Profile and channel.chat.chatType != status_chat.ChatType.CommunityChat:
discard self.view.chats.addChatItemToList(channel.chat)
self.status.chat.chatMessages(channel.chat.id)
self.status.chat.chatReactions(channel.chat.id)
self.view.asyncMessageLoad(channel.chat.id)
self.status.events.on("chatsLoaded") do(e:Args):
self.view.calculateUnreadMessages()

View File

@ -5,6 +5,8 @@ import ../../status/libstatus/chat as libstatus_chat
import ../../status/libstatus/accounts/constants
import ../../status/libstatus/mailservers as status_mailservers
import ../../status/libstatus/types
import ../../status/libstatus/core
import ../../status/libstatus/chat as core_chat
import ../../status/libstatus/utils as status_utils
import ../../status/accounts as status_accounts
import ../../status/chat as status_chat
@ -447,6 +449,21 @@ QtObject:
proc loadingMessagesChanged*(self: ChatsView, value: bool) {.signal.}
proc asyncMessageLoad*(self: ChatsView, chatId: string) {.slot.} =
spawnAndSend(self, "asyncMessageLoaded") do: # Call self.ensResolved(string) when ens is resolved
$(%*{
"chatId": chatId,
"messages": callPrivateRPC("chatMessages".prefix, %* [chatId, "", 20]).parseJson()["result"],
"reactions": callPrivateRPC("emojiReactionsByChatID".prefix, %* [chatId, "", 20]).parseJson()["result"]
})
proc asyncMessageLoaded*(self: ChatsView, rpcResponse: string) {.slot.} =
let rpcResponseObj = rpcResponse.parseJson
let chatMessages = parseChatMessagesResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["messages"])
let reactions = parseReactionsResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["reactions"])
self.status.chat.chatMessages(rpcResponseObj["chatId"].getStr, true, chatMessages[0], chatMessages[1])
self.status.chat.chatReactions(rpcResponseObj["chatId"].getStr, true, reactions[0], reactions[1])
proc hideLoadingIndicator*(self: ChatsView) {.slot.} =
self.loadingMessages = false
self.loadingMessagesChanged(false)

View File

@ -266,6 +266,38 @@ proc chatMessages*(self: ChatModel, chatId: string, initialLoad:bool = true) =
self.events.emit("messagesLoaded", MsgsLoadedArgs(messages: messageTuple[1]))
proc chatMessages*(self: ChatModel, chatId: string, initialLoad:bool = true, cursor: string = "", messages: seq[Message]) =
if not self.msgCursor.hasKey(chatId):
self.msgCursor[chatId] = "";
# Messages were already loaded, since cursor will
# be nil/empty if there are no more messages
if(not initialLoad and self.msgCursor[chatId] == ""): return
self.msgCursor[chatId] = cursor
if messages.len > 0:
let lastMsgIndex = messages.len - 1
let ts = times.convert(Milliseconds, Seconds, messages[lastMsgIndex].whisperTimestamp.parseInt())
self.lastMessageTimestamps[chatId] = ts
self.events.emit("messagesLoaded", MsgsLoadedArgs(messages: messages))
proc chatReactions*(self: ChatModel, chatId: string, initialLoad:bool = true, cursor: string = "", reactions: seq[Reaction]) =
try:
if not self.emojiCursor.hasKey(chatId):
self.emojiCursor[chatId] = "";
# Messages were already loaded, since cursor will
# be nil/empty if there are no more messages
if(not initialLoad and self.emojiCursor[chatId] == ""): return
self.emojiCursor[chatId] = cursor;
self.events.emit("reactionsLoaded", ReactionsLoadedArgs(reactions: reactions))
except Exception as e:
error "Error reactions", msg = e.msg
proc chatReactions*(self: ChatModel, chatId: string, initialLoad:bool = true) =
try:
if not self.emojiCursor.hasKey(chatId):

View File

@ -55,8 +55,14 @@ proc loadChats*(): seq[Chat] =
result.add(chat)
result.sort(sortChats)
proc chatMessages*(chatId: string, cursor: string = ""): (string, seq[Message]) =
proc parseChatMessagesResponse*(chatId: string, rpcResult: JsonNode): (string, seq[Message]) =
var messages: seq[Message] = @[]
if rpcResult["messages"].kind != JNull:
for jsonMsg in rpcResult["messages"]:
messages.add(jsonMsg.toMessage)
return (rpcResult{"cursor"}.getStr, messages)
proc chatMessages*(chatId: string, cursor: string = ""): (string, seq[Message]) =
var cursorVal: JsonNode
if cursor == "":
@ -64,16 +70,17 @@ proc chatMessages*(chatId: string, cursor: string = ""): (string, seq[Message])
else:
cursorVal = newJString(cursor)
let rpcResult = parseJson(callPrivateRPC("chatMessages".prefix, %* [chatId, cursorVal, 20]))["result"]
if rpcResult["messages"].kind != JNull:
for jsonMsg in rpcResult["messages"]:
messages.add(jsonMsg.toMessage)
return (rpcResult{"cursor"}.getStr, messages)
let callRPCResult = parseJson(callPrivateRPC("chatMessages".prefix, %* [chatId, cursorVal, 20]))["result"]
return parseChatMessagesResponse(chatId, callRPCResult)
proc parseReactionsResponse*(chatId: string, rpcResult: JsonNode): (string, seq[Reaction]) =
var reactions: seq[Reaction] = @[]
if rpcResult != nil and rpcResult.kind != JNull and rpcResult.len != 0:
for jsonMsg in rpcResult:
reactions.add(jsonMsg.toReaction)
return (rpcResult{"cursor"}.getStr, reactions)
proc getEmojiReactionsByChatId*(chatId: string, cursor: string = ""): (string, seq[Reaction]) =
var reactions: seq[Reaction] = @[]
var cursorVal: JsonNode
if cursor == "":
@ -82,12 +89,7 @@ proc getEmojiReactionsByChatId*(chatId: string, cursor: string = ""): (string, s
cursorVal = newJString(cursor)
let rpcResult = parseJson(callPrivateRPC("emojiReactionsByChatID".prefix, %* [chatId, cursorVal, 20]))["result"]
if rpcResult != nil and rpcResult.len != 0:
for jsonMsg in rpcResult:
reactions.add(jsonMsg.toReaction)
return (rpcResult{"cursor"}.getStr, reactions)
return parseReactionsResponse(chatId, rpcResult)
proc addEmojiReaction*(chatId: string, messageId: string, emojiId: int): seq[Reaction] =
let rpcResult = parseJson(callPrivateRPC("sendEmojiReaction".prefix, %* [chatId, messageId, emojiId]))["result"]