fix: prevent forever chat loading animation (#13929)
* prevent animation if loading not started * prevent scrolling to verification/contact request messages * fix ac click behaviour * remove CURSOR_VALUE_IGNORE. cleanup logs
This commit is contained in:
parent
666ba77051
commit
a6f5f0bc94
|
@ -265,9 +265,9 @@ proc getOneToOneChatNameAndImage*(self: Controller):
|
|||
proc belongsToCommunity*(self: Controller): bool =
|
||||
return self.belongsToCommunity
|
||||
|
||||
proc loadMoreMessages*(self: Controller) =
|
||||
proc loadMoreMessages*(self: Controller): bool =
|
||||
let limit = self.loadingMessagesPerPageFactor * MESSAGES_PER_PAGE
|
||||
self.messageService.asyncLoadMoreMessagesForChat(self.chatId, limit)
|
||||
return self.messageService.asyncLoadMoreMessagesForChat(self.chatId, limit)
|
||||
|
||||
proc addReaction*(self: Controller, messageId: string, emojiId: int) =
|
||||
self.messageService.addReaction(self.chatId, messageId, emojiId)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, chronicles, sequtils, uuids, sets, times, tables, system
|
||||
import NimQml, chronicles, sequtils, uuids, sets, times, tables, system, sugar
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view, controller
|
||||
|
@ -354,19 +354,27 @@ proc createChatIdentifierItem(self: Module): Item =
|
|||
bridgeMessage = BridgeMessage(),
|
||||
)
|
||||
|
||||
proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module) =
|
||||
proc checkIfMessageLoadedAndScroll(self: Module) =
|
||||
let searchedMessageId = self.controller.getSearchedMessageId()
|
||||
if(searchedMessageId.len > 0):
|
||||
let index = self.view.model().findIndexForMessageId(searchedMessageId)
|
||||
if(index != -1):
|
||||
self.controller.clearSearchedMessageId()
|
||||
self.controller.resetLoadingMessagesPerPageFactor()
|
||||
self.view.emitScrollToMessageSignal(index)
|
||||
self.view.setMessageSearchOngoing(false)
|
||||
self.reevaluateViewLoadingState()
|
||||
else:
|
||||
self.controller.increaseLoadingMessagesPerPageFactor()
|
||||
self.loadMoreMessages()
|
||||
|
||||
if searchedMessageId.len == 0:
|
||||
return
|
||||
|
||||
let index = self.view.model().findIndexForMessageId(searchedMessageId)
|
||||
if index == -1:
|
||||
self.controller.increaseLoadingMessagesPerPageFactor()
|
||||
if self.controller.loadMoreMessages():
|
||||
warn "failed to start loading more messages"
|
||||
return
|
||||
# If failed to `loadMoreMessages`, then the most recent message is already loaded.
|
||||
# Then message is not found.
|
||||
|
||||
self.controller.clearSearchedMessageId()
|
||||
self.controller.resetLoadingMessagesPerPageFactor()
|
||||
if index != -1:
|
||||
self.view.emitScrollToMessageSignal(index)
|
||||
self.view.setMessageSearchOngoing(false)
|
||||
self.reevaluateViewLoadingState()
|
||||
|
||||
proc currentUserWalletContainsAddress(self: Module, address: string): bool =
|
||||
if (address.len == 0):
|
||||
|
@ -378,13 +386,14 @@ proc currentUserWalletContainsAddress(self: Module, address: string): bool =
|
|||
return false
|
||||
|
||||
method reevaluateViewLoadingState*(self: Module) =
|
||||
self.view.setLoading(not self.initialMessagesLoaded or
|
||||
not self.firstUnseenMessageState.initialized or
|
||||
self.firstUnseenMessageState.fetching or
|
||||
self.view.getMessageSearchOngoing())
|
||||
let loading = not self.initialMessagesLoaded or
|
||||
not self.firstUnseenMessageState.initialized or
|
||||
self.firstUnseenMessageState.fetching or
|
||||
self.view.getMessageSearchOngoing()
|
||||
self.view.setLoading(loading)
|
||||
|
||||
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto]) =
|
||||
if(messages.len > 0):
|
||||
if messages.len > 0:
|
||||
var viewItems = self.createMessageItemsFromMessageDtos(messages, reactions)
|
||||
|
||||
if self.controller.getChatDetails().hasMoreMessagesToRequest():
|
||||
|
@ -397,7 +406,7 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
|||
self.view.model().resetNewMessagesMarker()
|
||||
|
||||
# check if this loading was caused by the click on a messages from the app search result
|
||||
self.checkIfMessageLoadedAndScrollToItIfItIs()
|
||||
self.checkIfMessageLoadedAndScroll()
|
||||
|
||||
self.initialMessagesLoaded = true
|
||||
self.reevaluateViewLoadingState()
|
||||
|
@ -433,7 +442,7 @@ method onMessageDelivered*(self: Module, messageId: string) =
|
|||
self.view.model().itemDelivered(messageId)
|
||||
|
||||
method loadMoreMessages*(self: Module) =
|
||||
self.controller.loadMoreMessages()
|
||||
discard self.controller.loadMoreMessages()
|
||||
|
||||
method toggleReaction*(self: Module, messageId: string, emojiId: int) =
|
||||
var emojiIdAsEnum: EmojiId
|
||||
|
@ -627,7 +636,7 @@ method updateChatFetchMoreMessages*(self: Module) =
|
|||
|
||||
proc switchToMessage*(self: Module, messageId: string) =
|
||||
let index = self.view.model().findIndexForMessageId(messageId)
|
||||
if(index != -1):
|
||||
if index != -1:
|
||||
self.controller.clearSearchedMessageId()
|
||||
self.view.emitSwitchToMessageSignal(index)
|
||||
else:
|
||||
|
@ -641,10 +650,10 @@ method scrollToMessage*(self: Module, messageId: string) =
|
|||
return
|
||||
|
||||
self.getMessageRequestId = self.controller.asyncGetMessageById(messageId)
|
||||
self.controller.setSearchedMessageId(messageId)
|
||||
self.view.setMessageSearchOngoing(true)
|
||||
|
||||
method onGetMessageById*(self: Module, requestId: UUID, messageId: string, message: MessageDto, errorMessage: string) =
|
||||
|
||||
if self.getMessageRequestId != requestId:
|
||||
return
|
||||
|
||||
|
@ -653,8 +662,13 @@ method onGetMessageById*(self: Module, requestId: UUID, messageId: string, messa
|
|||
self.view.setMessageSearchOngoing(false)
|
||||
return
|
||||
|
||||
self.controller.setSearchedMessageId(messageId)
|
||||
self.checkIfMessageLoadedAndScrollToItIfItIs()
|
||||
if message.contentType == ContentType.ContactIdentityVerification or
|
||||
message.contentType == ContentType.ContactRequest:
|
||||
warn "attempted to scroll to a non-displayed message", messageId, contentType = $message.contentType
|
||||
self.view.setMessageSearchOngoing(false)
|
||||
return
|
||||
|
||||
self.checkIfMessageLoadedAndScroll()
|
||||
self.reevaluateViewLoadingState()
|
||||
|
||||
method requestMoreMessages*(self: Module) =
|
||||
|
|
|
@ -33,22 +33,19 @@ const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
|
|||
}
|
||||
|
||||
# handle messages
|
||||
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||
var messagesArr: JsonNode
|
||||
var messagesCursor: JsonNode
|
||||
let msgsResponse = status_go.fetchMessages(arg.chatId, arg.msgCursor, arg.limit)
|
||||
discard msgsResponse.result.getProp("cursor", messagesCursor)
|
||||
discard msgsResponse.result.getProp("messages", messagesArr)
|
||||
responseJson["messages"] = messagesArr
|
||||
responseJson["messagesCursor"] = messagesCursor
|
||||
var messagesArr: JsonNode
|
||||
var messagesCursor: JsonNode
|
||||
let msgsResponse = status_go.fetchMessages(arg.chatId, arg.msgCursor, arg.limit)
|
||||
discard msgsResponse.result.getProp("cursor", messagesCursor)
|
||||
discard msgsResponse.result.getProp("messages", messagesArr)
|
||||
responseJson["messages"] = messagesArr
|
||||
responseJson["messagesCursor"] = messagesCursor
|
||||
|
||||
# handle reactions
|
||||
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||
# messages and reactions are using the same cursor
|
||||
var reactionsArr: JsonNode
|
||||
let rResponse = status_go.fetchReactions(arg.chatId, arg.msgCursor, arg.limit)
|
||||
reactionsArr = rResponse.result
|
||||
responseJson["reactions"] = reactionsArr
|
||||
var reactionsArr: JsonNode
|
||||
let rResponse = status_go.fetchReactions(arg.chatId, arg.msgCursor, arg.limit)
|
||||
reactionsArr = rResponse.result
|
||||
responseJson["reactions"] = reactionsArr
|
||||
|
||||
arg.finish(responseJson)
|
||||
|
||||
|
@ -61,15 +58,14 @@ const asyncFetchPinnedChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe
|
|||
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
|
||||
# handle pinned messages
|
||||
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)
|
||||
|
||||
|
@ -341,4 +337,4 @@ const asyncMarkMessageAsUnreadTask: Task = proc(argEncoded: string) {.gcsafe, ni
|
|||
error "asyncMarkMessageAsUnreadTask failed", message = e.msg
|
||||
responseJson["error"] = %e.msg
|
||||
|
||||
arg.finish(responseJson)
|
||||
arg.finish(responseJson)
|
||||
|
|
|
@ -28,6 +28,12 @@ proc setPending*(self: MessageCursor) =
|
|||
proc isFetchable*(self: MessageCursor): bool =
|
||||
return not (self.pending or self.mostRecent)
|
||||
|
||||
proc isPending*(self: MessageCursor): bool =
|
||||
return self.pending
|
||||
|
||||
proc isMostRecent*(self: MessageCursor): bool =
|
||||
return self.mostRecent
|
||||
|
||||
proc isEmpty*(self: MessageCursor): bool =
|
||||
return self.value == ""
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ logScope:
|
|||
let NEW_LINE = re"\n|\r" #must be defined as let, not const
|
||||
const MESSAGES_PER_PAGE* = 20
|
||||
const MESSAGES_PER_PAGE_MAX* = 40
|
||||
const CURSOR_VALUE_IGNORE = "ignore"
|
||||
const WEEK_AS_MILLISECONDS = initDuration(seconds = 60*60*24*7).inMilliSeconds
|
||||
|
||||
# Signals which may be emitted by this service:
|
||||
|
@ -213,19 +212,21 @@ QtObject:
|
|||
|
||||
return self.pinnedMsgCursor[chatId]
|
||||
|
||||
proc asyncLoadMoreMessagesForChat*(self: Service, chatId: string, limit = MESSAGES_PER_PAGE) =
|
||||
proc asyncLoadMoreMessagesForChat*(self: Service, chatId: string, limit = MESSAGES_PER_PAGE): bool =
|
||||
if (chatId.len == 0):
|
||||
error "empty chat id", procName="asyncLoadMoreMessagesForChat"
|
||||
return
|
||||
return false
|
||||
|
||||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||
let msgCursorValue = if (msgCursor.isFetchable()): msgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||
|
||||
if(msgCursorValue == CURSOR_VALUE_IGNORE):
|
||||
return
|
||||
if msgCursor.isPending():
|
||||
return true
|
||||
|
||||
if(msgCursorValue != CURSOR_VALUE_IGNORE):
|
||||
msgCursor.setPending()
|
||||
if msgCursor.isMostRecent():
|
||||
return false
|
||||
|
||||
let msgCursorValue = msgCursor.getValue()
|
||||
msgCursor.setPending()
|
||||
|
||||
let arg = AsyncFetchChatMessagesTaskArg(
|
||||
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
|
||||
|
@ -237,6 +238,7 @@ QtObject:
|
|||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
return true
|
||||
|
||||
proc asyncLoadPinnedMessagesForChat*(self: Service, chatId: string) =
|
||||
if (chatId.len == 0):
|
||||
|
@ -244,11 +246,10 @@ QtObject:
|
|||
return
|
||||
|
||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||
let pinnedMsgCursorValue = if (pinnedMsgCursor.isFetchable()): pinnedMsgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||
|
||||
if(pinnedMsgCursorValue == CURSOR_VALUE_IGNORE):
|
||||
if not pinnedMsgCursor.isFetchable():
|
||||
return
|
||||
|
||||
let pinnedMsgCursorValue = pinnedMsgCursor.getValue()
|
||||
pinnedMsgCursor.setPending()
|
||||
|
||||
let arg = AsyncFetchChatMessagesTaskArg(
|
||||
|
@ -263,7 +264,7 @@ QtObject:
|
|||
self.threadpool.start(arg)
|
||||
|
||||
proc asyncLoadInitialMessagesForChat*(self: Service, chatId: string) =
|
||||
if(self.isChatCursorInitialized(chatId)):
|
||||
if self.isChatCursorInitialized(chatId):
|
||||
let data = MessagesLoadedArgs(chatId: chatId,
|
||||
messages: @[],
|
||||
reactions: @[])
|
||||
|
@ -271,7 +272,7 @@ QtObject:
|
|||
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
||||
return
|
||||
|
||||
self.asyncLoadMoreMessagesForChat(chatId)
|
||||
discard self.asyncLoadMoreMessagesForChat(chatId)
|
||||
|
||||
proc handleMessagesUpdate(self: Service, chats: var seq[ChatDto], messages: var seq[MessageDto]) =
|
||||
# We included `chats` in this condition cause that's the form how `status-go` sends updates.
|
||||
|
@ -445,7 +446,7 @@ QtObject:
|
|||
self.events.on(SignalType.DiscordChannelImportFinished.event) do(e: Args):
|
||||
var receivedData = DiscordChannelImportFinishedSignal(e)
|
||||
self.resetMessageCursor(receivedData.channelId)
|
||||
self.asyncLoadMoreMessagesForChat(receivedData.channelId)
|
||||
discard self.asyncLoadMoreMessagesForChat(receivedData.channelId)
|
||||
|
||||
self.events.on(SIGNAL_CHAT_LEFT) do(e: Args):
|
||||
var chatArg = ChatArgs(e)
|
||||
|
|
|
@ -66,6 +66,10 @@ ActivityNotificationMessage {
|
|||
}
|
||||
}
|
||||
|
||||
onMessageClicked: {
|
||||
root.openProfilePopup()
|
||||
}
|
||||
|
||||
Component {
|
||||
id: reviewContactRequestPopupComponent
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@ ActivityNotificationMessage {
|
|||
|
||||
ctaComponent: isOutgoingMessage ? outgoingContactVerificationCta : incomingContactVerificationCta
|
||||
|
||||
onMessageClicked: {
|
||||
root.openProfilePopup()
|
||||
}
|
||||
|
||||
Component {
|
||||
id: outgoingContactVerificationCta
|
||||
|
||||
|
|
|
@ -84,8 +84,7 @@ ActivityNotificationBase {
|
|||
hoverEnabled: root.messageBadgeComponent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.activityCenterStore.switchTo(notification)
|
||||
root.closeActivityCenter()
|
||||
root.messageClicked()
|
||||
}
|
||||
|
||||
SimplifiedMessageView {
|
||||
|
|
|
@ -125,13 +125,26 @@ StatusMenu {
|
|||
}
|
||||
}
|
||||
|
||||
StatusAction {
|
||||
objectName: "chatFetchMessagesMenuItem"
|
||||
text: qsTr("Fetch messages")
|
||||
icon.name: "download"
|
||||
|
||||
StatusMenu {
|
||||
title: qsTr("Debug actions")
|
||||
enabled: root.showDebugOptions
|
||||
onTriggered: {
|
||||
root.requestMoreMessages(root.chatId)
|
||||
|
||||
StatusAction {
|
||||
text: root.isCommunityChat ? qsTr("Copy channel ID") : qsTr("Copy chat ID")
|
||||
icon.name: "copy"
|
||||
onTriggered: {
|
||||
Utils.copyToClipboard(root.chatId)
|
||||
}
|
||||
}
|
||||
|
||||
StatusAction {
|
||||
objectName: "chatFetchMessagesMenuItem"
|
||||
text: qsTr("Fetch messages")
|
||||
icon.name: "download"
|
||||
onTriggered: {
|
||||
root.requestMoreMessages(root.chatId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue