perf(ChatLoadingTime): Separate get chat messages and get pinned messages in different tasks
This commit is contained in:
parent
d5e5ba2796
commit
d1ffa2e3b3
|
@ -58,8 +58,8 @@ proc delete*(self: Controller) =
|
||||||
self.events.disconnect()
|
self.events.disconnect()
|
||||||
|
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller) =
|
||||||
self.events.on(SIGNAL_MESSAGES_LOADED) do(e:Args):
|
self.events.on(SIGNAL_PINNED_MESSAGES_LOADED) do(e:Args):
|
||||||
let args = MessagesLoadedArgs(e)
|
let args = PinnedMessagesLoadedArgs(e)
|
||||||
if(self.chatId != args.chatId or args.pinnedMessages.len == 0):
|
if(self.chatId != args.chatId or args.pinnedMessages.len == 0):
|
||||||
return
|
return
|
||||||
self.delegate.newPinnedMessagesLoaded(args.pinnedMessages)
|
self.delegate.newPinnedMessagesLoaded(args.pinnedMessages)
|
||||||
|
|
|
@ -58,7 +58,13 @@ proc init*(self: Controller) =
|
||||||
let args = MessagesLoadedArgs(e)
|
let args = MessagesLoadedArgs(e)
|
||||||
if(self.chatId != args.chatId):
|
if(self.chatId != args.chatId):
|
||||||
return
|
return
|
||||||
self.delegate.newMessagesLoaded(args.messages, args.reactions, args.pinnedMessages)
|
self.delegate.newMessagesLoaded(args.messages, args.reactions)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_PINNED_MESSAGES_LOADED) do(e:Args):
|
||||||
|
let args = PinnedMessagesLoadedArgs(e)
|
||||||
|
if(self.chatId != args.chatId):
|
||||||
|
return
|
||||||
|
self.delegate.newPinnedMessagesLoaded(args.pinnedMessages)
|
||||||
|
|
||||||
self.events.on(SIGNAL_NEW_MESSAGE_RECEIVED) do(e: Args):
|
self.events.on(SIGNAL_NEW_MESSAGE_RECEIVED) do(e: Args):
|
||||||
var args = MessagesArgs(e)
|
var args = MessagesArgs(e)
|
||||||
|
|
|
@ -25,8 +25,10 @@ method updateChatIdentifier*(self: AccessInterface) {.base.} =
|
||||||
method updateChatFetchMoreMessages*(self: AccessInterface) {.base.} =
|
method updateChatFetchMoreMessages*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto]) {.base.} =
|
||||||
pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method newPinnedMessagesLoaded*(self: AccessInterface, pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onReactionAdded*(self: AccessInterface, messageId: string, emojiId: int, reactionId: string) {.base.} =
|
method onReactionAdded*(self: AccessInterface, messageId: string, emojiId: int, reactionId: string) {.base.} =
|
||||||
|
|
|
@ -221,8 +221,7 @@ method reevaluateViewLoadingState*(self: Module) =
|
||||||
not self.firstUnseenMessageState.initialized or
|
not self.firstUnseenMessageState.initialized or
|
||||||
self.firstUnseenMessageState.fetching)
|
self.firstUnseenMessageState.fetching)
|
||||||
|
|
||||||
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto]) =
|
||||||
pinnedMessages: seq[PinnedMessageDto]) =
|
|
||||||
var viewItems: seq[Item]
|
var viewItems: seq[Item]
|
||||||
|
|
||||||
if(messages.len > 0):
|
if(messages.len > 0):
|
||||||
|
@ -327,11 +326,6 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
||||||
else:
|
else:
|
||||||
error "wrong emoji id found when loading messages", methodName="newMessagesLoaded"
|
error "wrong emoji id found when loading messages", methodName="newMessagesLoaded"
|
||||||
|
|
||||||
for p in pinnedMessages:
|
|
||||||
if(p.message.id == message.id):
|
|
||||||
item.pinned = true
|
|
||||||
item.pinnedBy = p.pinnedBy
|
|
||||||
|
|
||||||
if message.editedAt != 0:
|
if message.editedAt != 0:
|
||||||
item.isEdited = true
|
item.isEdited = true
|
||||||
|
|
||||||
|
@ -357,6 +351,10 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
||||||
self.initialMessagesLoaded = true
|
self.initialMessagesLoaded = true
|
||||||
self.reevaluateViewLoadingState()
|
self.reevaluateViewLoadingState()
|
||||||
|
|
||||||
|
method newPinnedMessagesLoaded*(self: Module, pinnedMessages: seq[PinnedMessageDto]) =
|
||||||
|
for p in pinnedMessages:
|
||||||
|
self.onPinMessage(p.message.id, p.pinnedBy)
|
||||||
|
|
||||||
method messagesAdded*(self: Module, messages: seq[MessageDto]) =
|
method messagesAdded*(self: Module, messages: seq[MessageDto]) =
|
||||||
var items: seq[Item]
|
var items: seq[Item]
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ type
|
||||||
AsyncFetchChatMessagesTaskArg = ref object of QObjectTaskArg
|
AsyncFetchChatMessagesTaskArg = ref object of QObjectTaskArg
|
||||||
chatId: string
|
chatId: string
|
||||||
msgCursor: string
|
msgCursor: string
|
||||||
pinnedMsgCursor: string
|
|
||||||
limit: int
|
limit: int
|
||||||
|
|
||||||
const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
@ -32,16 +31,6 @@ const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
|
||||||
responseJson["messages"] = messagesArr
|
responseJson["messages"] = messagesArr
|
||||||
responseJson["messagesCursor"] = messagesCursor
|
responseJson["messagesCursor"] = messagesCursor
|
||||||
|
|
||||||
# handle pinned messages
|
|
||||||
if(arg.pinnedMsgCursor != CURSOR_VALUE_IGNORE):
|
|
||||||
var pinnedMsgArr: JsonNode
|
|
||||||
var pinnedMsgCursor: JsonNode
|
|
||||||
let pinnedMsgsResponse = status_go.fetchPinnedMessages(arg.chatId, arg.pinnedMsgCursor, arg.limit)
|
|
||||||
discard pinnedMsgsResponse.result.getProp("cursor", pinnedMsgCursor)
|
|
||||||
discard pinnedMsgsResponse.result.getProp("pinnedMessages", pinnedMsgArr)
|
|
||||||
responseJson["pinnedMessages"] = pinnedMsgArr
|
|
||||||
responseJson["pinnedMessagesCursor"] = pinnedMsgCursor
|
|
||||||
|
|
||||||
# handle reactions
|
# handle reactions
|
||||||
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||||
# messages and reactions are using the same cursor
|
# messages and reactions are using the same cursor
|
||||||
|
@ -52,6 +41,28 @@ const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
|
||||||
|
|
||||||
arg.finish(responseJson)
|
arg.finish(responseJson)
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
# Async load pinned messages
|
||||||
|
#################################################
|
||||||
|
const asyncFetchPinnedChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncFetchChatMessagesTaskArg](argEncoded)
|
||||||
|
|
||||||
|
var responseJson = %*{
|
||||||
|
"chatId": arg.chatId
|
||||||
|
}
|
||||||
|
#handle pinned messages
|
||||||
|
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||||
|
var pinnedMsgArr: JsonNode
|
||||||
|
var msgCursor: JsonNode
|
||||||
|
let pinnedMsgsResponse = status_go.fetchPinnedMessages(arg.chatId, arg.msgCursor, arg.limit)
|
||||||
|
discard pinnedMsgsResponse.result.getProp("cursor", msgCursor)
|
||||||
|
discard pinnedMsgsResponse.result.getProp("pinnedMessages", pinnedMsgArr)
|
||||||
|
responseJson["pinnedMessages"] = pinnedMsgArr
|
||||||
|
responseJson["pinnedMessagesCursor"] = msgCursor
|
||||||
|
|
||||||
|
arg.finish(responseJson)
|
||||||
|
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
# Async search messages
|
# Async search messages
|
||||||
#################################################
|
#################################################
|
||||||
|
|
|
@ -40,6 +40,7 @@ const WEEK_AS_MILLISECONDS = initDuration(seconds = 60*60*24*7).inMilliSeconds
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_MESSAGES_LOADED* = "messagesLoaded"
|
const SIGNAL_MESSAGES_LOADED* = "messagesLoaded"
|
||||||
|
const SIGNAL_PINNED_MESSAGES_LOADED* = "pinnedMessagesLoaded"
|
||||||
const SIGNAL_FIRST_UNSEEN_MESSAGE_LOADED* = "firstUnseenMessageLoaded"
|
const SIGNAL_FIRST_UNSEEN_MESSAGE_LOADED* = "firstUnseenMessageLoaded"
|
||||||
const SIGNAL_NEW_MESSAGE_RECEIVED* = "newMessageReceived"
|
const SIGNAL_NEW_MESSAGE_RECEIVED* = "newMessageReceived"
|
||||||
const SIGNAL_MESSAGE_PINNED* = "messagePinned"
|
const SIGNAL_MESSAGE_PINNED* = "messagePinned"
|
||||||
|
@ -72,9 +73,12 @@ type
|
||||||
MessagesLoadedArgs* = ref object of Args
|
MessagesLoadedArgs* = ref object of Args
|
||||||
chatId*: string
|
chatId*: string
|
||||||
messages*: seq[MessageDto]
|
messages*: seq[MessageDto]
|
||||||
pinnedMessages*: seq[PinnedMessageDto]
|
|
||||||
reactions*: seq[ReactionDto]
|
reactions*: seq[ReactionDto]
|
||||||
|
|
||||||
|
PinnedMessagesLoadedArgs* = ref object of Args
|
||||||
|
chatId*: string
|
||||||
|
pinnedMessages*: seq[PinnedMessageDto]
|
||||||
|
|
||||||
MessagePinUnpinArgs* = ref object of Args
|
MessagePinUnpinArgs* = ref object of Args
|
||||||
chatId*: string
|
chatId*: string
|
||||||
messageId*: string
|
messageId*: string
|
||||||
|
@ -188,16 +192,11 @@ QtObject:
|
||||||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||||
let msgCursorValue = if (msgCursor.isFetchable()): msgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
let msgCursorValue = if (msgCursor.isFetchable()): msgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||||
|
|
||||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
if(msgCursorValue == CURSOR_VALUE_IGNORE):
|
||||||
let pinnedMsgCursorValue = if (pinnedMsgCursor.isFetchable()): pinnedMsgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
|
||||||
|
|
||||||
if(msgCursorValue == CURSOR_VALUE_IGNORE and pinnedMsgCursorValue == CURSOR_VALUE_IGNORE):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if(msgCursorValue != CURSOR_VALUE_IGNORE):
|
if(msgCursorValue != CURSOR_VALUE_IGNORE):
|
||||||
msgCursor.setPending()
|
msgCursor.setPending()
|
||||||
if (pinnedMsgCursorValue != CURSOR_VALUE_IGNORE):
|
|
||||||
pinnedMsgCursor.setPending()
|
|
||||||
|
|
||||||
let arg = AsyncFetchChatMessagesTaskArg(
|
let arg = AsyncFetchChatMessagesTaskArg(
|
||||||
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
|
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
|
||||||
|
@ -205,17 +204,39 @@ QtObject:
|
||||||
slot: "onAsyncLoadMoreMessagesForChat",
|
slot: "onAsyncLoadMoreMessagesForChat",
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
msgCursor: msgCursorValue,
|
msgCursor: msgCursorValue,
|
||||||
pinnedMsgCursor: pinnedMsgCursorValue,
|
|
||||||
limit: if(limit <= MESSAGES_PER_PAGE_MAX): limit else: MESSAGES_PER_PAGE_MAX
|
limit: if(limit <= MESSAGES_PER_PAGE_MAX): limit else: MESSAGES_PER_PAGE_MAX
|
||||||
)
|
)
|
||||||
|
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc asyncLoadPinnedMessagesForChat*(self: Service, chatId: string) =
|
||||||
|
if (chatId.len == 0):
|
||||||
|
error "empty chat id", procName="asyncLoadPinnedMessagesForChat"
|
||||||
|
return
|
||||||
|
|
||||||
|
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||||
|
let pinnedMsgCursorValue = if (pinnedMsgCursor.isFetchable()): pinnedMsgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||||
|
|
||||||
|
if(pinnedMsgCursorValue == CURSOR_VALUE_IGNORE):
|
||||||
|
return
|
||||||
|
|
||||||
|
pinnedMsgCursor.setPending()
|
||||||
|
|
||||||
|
let arg = AsyncFetchChatMessagesTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncFetchPinnedChatMessagesTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onAsyncLoadPinnedMessagesForChat",
|
||||||
|
chatId: chatId,
|
||||||
|
msgCursor: pinnedMsgCursorValue,
|
||||||
|
limit: MESSAGES_PER_PAGE_MAX
|
||||||
|
)
|
||||||
|
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
proc asyncLoadInitialMessagesForChat*(self: Service, chatId: string) =
|
proc asyncLoadInitialMessagesForChat*(self: Service, chatId: string) =
|
||||||
if(self.isChatCursorInitialized(chatId)):
|
if(self.isChatCursorInitialized(chatId)):
|
||||||
let data = MessagesLoadedArgs(chatId: chatId,
|
let data = MessagesLoadedArgs(chatId: chatId,
|
||||||
messages: @[],
|
messages: @[],
|
||||||
pinnedMessages: @[],
|
|
||||||
reactions: @[])
|
reactions: @[])
|
||||||
|
|
||||||
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
||||||
|
@ -389,30 +410,17 @@ QtObject:
|
||||||
weiStr.trimZeros()
|
weiStr.trimZeros()
|
||||||
return (tokenStr, weiStr)
|
return (tokenStr, weiStr)
|
||||||
|
|
||||||
proc onAsyncLoadMoreMessagesForChat*(self: Service, response: string) {.slot.} =
|
proc onAsyncLoadPinnedMessagesForChat*(self: Service, response: string) {.slot.} =
|
||||||
let responseObj = response.parseJson
|
let responseObj = response.parseJson
|
||||||
if (responseObj.kind != JObject):
|
if (responseObj.kind != JObject):
|
||||||
info "load more messages response is not a json object"
|
info "load pinned messages response is not a json object"
|
||||||
# notify view, this is important
|
self.events.emit(SIGNAL_PINNED_MESSAGES_LOADED, PinnedMessagesLoadedArgs())
|
||||||
self.events.emit(SIGNAL_MESSAGES_LOADED, MessagesLoadedArgs())
|
|
||||||
return
|
return
|
||||||
|
|
||||||
var chatId: string
|
var chatId: string
|
||||||
discard responseObj.getProp("chatId", chatId)
|
discard responseObj.getProp("chatId", chatId)
|
||||||
|
|
||||||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
|
||||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||||
|
|
||||||
# handling messages
|
|
||||||
var msgCursorValue: string
|
|
||||||
if(responseObj.getProp("messagesCursor", msgCursorValue)):
|
|
||||||
msgCursor.setValue(msgCursorValue)
|
|
||||||
|
|
||||||
var messagesArr: JsonNode
|
|
||||||
var messages: seq[MessageDto]
|
|
||||||
if(responseObj.getProp("messages", messagesArr)):
|
|
||||||
messages = map(messagesArr.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())
|
|
||||||
|
|
||||||
# handling pinned messages
|
# handling pinned messages
|
||||||
var pinnedMsgCursorValue: string
|
var pinnedMsgCursorValue: string
|
||||||
if(responseObj.getProp("pinnedMessagesCursor", pinnedMsgCursorValue)):
|
if(responseObj.getProp("pinnedMessagesCursor", pinnedMsgCursorValue)):
|
||||||
|
@ -426,6 +434,38 @@ QtObject:
|
||||||
# set initial number of pinned messages
|
# set initial number of pinned messages
|
||||||
self.numOfPinnedMessagesPerChat[chatId] = pinnedMessages.len
|
self.numOfPinnedMessagesPerChat[chatId] = pinnedMessages.len
|
||||||
|
|
||||||
|
let data = PinnedMessagesLoadedArgs(chatId: chatId,
|
||||||
|
pinnedMessages: pinnedMessages)
|
||||||
|
|
||||||
|
self.events.emit(SIGNAL_PINNED_MESSAGES_LOADED, data)
|
||||||
|
|
||||||
|
proc onAsyncLoadMoreMessagesForChat*(self: Service, response: string) {.slot.} =
|
||||||
|
let responseObj = response.parseJson
|
||||||
|
if (responseObj.kind != JObject):
|
||||||
|
info "load more messages response is not a json object"
|
||||||
|
# notify view, this is important
|
||||||
|
self.events.emit(SIGNAL_MESSAGES_LOADED, MessagesLoadedArgs())
|
||||||
|
return
|
||||||
|
|
||||||
|
var chatId: string
|
||||||
|
discard responseObj.getProp("chatId", chatId)
|
||||||
|
|
||||||
|
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||||
|
if(msgCursor.getValue() == ""):
|
||||||
|
# this is the first time we load messages for this chat
|
||||||
|
# we need to load pinned messages as well
|
||||||
|
self.asyncLoadPinnedMessagesForChat(chatId)
|
||||||
|
|
||||||
|
# handling messages
|
||||||
|
var msgCursorValue: string
|
||||||
|
if(responseObj.getProp("messagesCursor", msgCursorValue)):
|
||||||
|
msgCursor.setValue(msgCursorValue)
|
||||||
|
|
||||||
|
var messagesArr: JsonNode
|
||||||
|
var messages: seq[MessageDto]
|
||||||
|
if(responseObj.getProp("messages", messagesArr)):
|
||||||
|
messages = map(messagesArr.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())
|
||||||
|
|
||||||
# handling reactions
|
# handling reactions
|
||||||
var reactionsArr: JsonNode
|
var reactionsArr: JsonNode
|
||||||
var reactions: seq[ReactionDto]
|
var reactions: seq[ReactionDto]
|
||||||
|
@ -434,7 +474,6 @@ QtObject:
|
||||||
|
|
||||||
let data = MessagesLoadedArgs(chatId: chatId,
|
let data = MessagesLoadedArgs(chatId: chatId,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
pinnedMessages: pinnedMessages,
|
|
||||||
reactions: reactions)
|
reactions: reactions)
|
||||||
|
|
||||||
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
||||||
|
|
Loading…
Reference in New Issue