fix: Timeline view crash with SIGSEGV when loaded

Fixes: #2618.

The main culprit was that `self.pinnedMessagesList` did not contain the `self.activeChannel.id` because it was correctly upserted in `upsertChannel`.

To fix this, when calling `upsertChannel`, `self.pinnedMessagesList` was checked if it contained an entry for the upserted channel first before adding it to the list.

Nil checks were added to parsing the messages RPC response in case specific fields were not returned in the response.

In addition, a copy/paste error was fixed in `asyncMessageLoadTask`.
This commit is contained in:
Eric Mastro 2021-06-01 17:28:20 +10:00 committed by Iuri Matias
parent aa57de15a9
commit 815abdc226
1 changed files with 21 additions and 12 deletions

View File

@ -68,7 +68,7 @@ const asyncMessageLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.}
var pinnedMessages: JsonNode var pinnedMessages: JsonNode
var pinnedMessagesCallSuccess: bool var pinnedMessagesCallSuccess: bool
let pinnedMessagesCallResult = rpcPinnedChatMessages(arg.chatId, newJString(""), 20, pinnedMessagesCallSuccess) let pinnedMessagesCallResult = rpcPinnedChatMessages(arg.chatId, newJString(""), 20, pinnedMessagesCallSuccess)
if(reactionsCallSuccess): if(pinnedMessagesCallSuccess):
pinnedMessages = pinnedMessagesCallResult.parseJson()["result"] pinnedMessages = pinnedMessagesCallResult.parseJson()["result"]
let responseJson = %*{ let responseJson = %*{
@ -445,9 +445,10 @@ QtObject:
if not self.messageList.hasKey(channel): if not self.messageList.hasKey(channel):
self.beginInsertRows(newQModelIndex(), self.messageList.len, self.messageList.len) self.beginInsertRows(newQModelIndex(), self.messageList.len, self.messageList.len)
self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile) self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile)
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false)
self.channelOpenTime[channel] = now().toTime.toUnix * 1000 self.channelOpenTime[channel] = now().toTime.toUnix * 1000
self.endInsertRows(); self.endInsertRows();
if not self.pinnedMessagesList.hasKey(channel):
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false)
proc messagePushed*(self: ChatsView, messageIndex: int) {.signal.} proc messagePushed*(self: ChatsView, messageIndex: int) {.signal.}
proc newMessagePushed*(self: ChatsView) {.signal.} proc newMessagePushed*(self: ChatsView) {.signal.}
@ -624,19 +625,27 @@ QtObject:
self.asyncMessageLoad("asyncMessageLoaded", chatId) self.asyncMessageLoad("asyncMessageLoaded", chatId)
proc asyncMessageLoaded*(self: ChatsView, rpcResponse: string) {.slot.} = proc asyncMessageLoaded*(self: ChatsView, rpcResponse: string) {.slot.} =
let rpcResponseObj = rpcResponse.parseJson let
rpcResponseObj = rpcResponse.parseJson
chatId = rpcResponseObj{"chatId"}.getStr
if(rpcResponseObj["messages"].kind != JNull): if chatId == "": # .getStr() returns "" when field is not found
let chatMessages = parseChatMessagesResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["messages"]) return
self.status.chat.chatMessages(rpcResponseObj["chatId"].getStr, true, chatMessages[0], chatMessages[1])
if(rpcResponseObj["reactions"].kind != JNull): let messages = rpcResponseObj{"messages"}
let reactions = parseReactionsResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["reactions"]) if(messages != nil and messages.kind != JNull):
self.status.chat.chatReactions(rpcResponseObj["chatId"].getStr, true, reactions[0], reactions[1]) let chatMessages = parseChatMessagesResponse(chatId, messages)
self.status.chat.chatMessages(chatId, true, chatMessages[0], chatMessages[1])
if(rpcResponseObj["pinnedMessages"].kind != JNull): let rxns = rpcResponseObj{"reactions"}
let pinnedMessages = parseChatMessagesResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["pinnedMessages"], true) if(rxns != nil and rxns.kind != JNull):
self.status.chat.pinnedMessagesByChatID(rpcResponseObj["chatId"].getStr, pinnedMessages[0], pinnedMessages[1]) let reactions = parseReactionsResponse(chatId, rxns)
self.status.chat.chatReactions(chatId, true, reactions[0], reactions[1])
let pinnedMsgs = rpcResponseObj{"pinnedMessages"}
if(pinnedMsgs != nil and pinnedMsgs.kind != JNull):
let pinnedMessages = parseChatMessagesResponse(chatId, pinnedMsgs, true)
self.status.chat.pinnedMessagesByChatID(chatId, pinnedMessages[0], pinnedMessages[1])
proc hideLoadingIndicator*(self: ChatsView) {.slot.} = proc hideLoadingIndicator*(self: ChatsView) {.slot.} =
self.loadingMessages = false self.loadingMessages = false