fix: Only `scrollToMessage` when it's available in the database (#11784)
* rename `fetchMessageByMessageId` to `getMessageByMessageId` * move reply clicking logic to `StatusMessageReply` * make message found animation faster * `asyncGetMessageById`
This commit is contained in:
parent
9d78e23b68
commit
34dba08b7a
|
@ -202,9 +202,8 @@ proc belongsToCommunity*(self: Controller): bool =
|
|||
proc unpinMessage*(self: Controller, messageId: string) =
|
||||
self.messageService.pinUnpinMessage(self.chatId, messageId, false)
|
||||
|
||||
proc getMessageById*(self: Controller, messageId: string):
|
||||
tuple[message: MessageDto, error: string] =
|
||||
return self.messageService.fetchMessageByMessageId(self.chatId, messageId)
|
||||
proc getMessageById*(self: Controller, messageId: string): GetMessageResult =
|
||||
return self.messageService.getMessageByMessageId(messageId)
|
||||
|
||||
proc isUsersListAvailable*(self: Controller): bool =
|
||||
return self.isUsersListAvailable
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import chronicles
|
||||
import chronicles, uuids
|
||||
import io_interface
|
||||
import json
|
||||
|
||||
|
@ -226,6 +226,10 @@ proc init*(self: Controller) =
|
|||
return
|
||||
self.delegate.onFirstUnseenMessageLoaded(args.messageId)
|
||||
|
||||
self.events.on(SIGNAL_GET_MESSAGE_FINISHED) do(e: Args):
|
||||
let args = GetMessageResult(e)
|
||||
self.delegate.onGetMessageById(args.requestId, args.messageId, args.message, args.error)
|
||||
|
||||
proc getMySectionId*(self: Controller): string =
|
||||
return self.sectionId
|
||||
|
||||
|
@ -320,3 +324,6 @@ proc leaveChat*(self: Controller) =
|
|||
|
||||
proc resendChatMessage*(self: Controller, messageId: string): string =
|
||||
return self.messageService.resendChatMessage(messageId)
|
||||
|
||||
proc asyncGetMessageById*(self: Controller, messageId: string): UUID =
|
||||
return self.messageService.asyncGetMessageById(messageId)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml
|
||||
import NimQml, uuids
|
||||
|
||||
import ../../../../../../app_service/service/message/dto/[message, reaction, pinned_message]
|
||||
import ../../../../../../app_service/service/community/dto/community
|
||||
|
@ -179,3 +179,6 @@ method isFirstUnseenMessageInitialized*(self: AccessInterface): bool {.base.} =
|
|||
|
||||
method reevaluateViewLoadingState*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onGetMessageById*(self: AccessInterface, requestId: UUID, messageId: string, message: MessageDto, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, chronicles, sequtils
|
||||
import NimQml, chronicles, sequtils, uuids
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view, controller
|
||||
|
@ -41,6 +41,7 @@ type
|
|||
moduleLoaded: bool
|
||||
initialMessagesLoaded: bool
|
||||
firstUnseenMessageState: FirstUnseenMessageState
|
||||
getMessageRequestId: UUID
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
|
||||
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
|
||||
|
@ -661,13 +662,25 @@ proc switchToMessage*(self: Module, messageId: string) =
|
|||
self.controller.setSearchedMessageId(messageId)
|
||||
|
||||
method scrollToMessage*(self: Module, messageId: string) =
|
||||
if(messageId == ""):
|
||||
if messageId == "":
|
||||
return
|
||||
|
||||
if(self.view.getMessageSearchOngoing()):
|
||||
if self.view.getMessageSearchOngoing():
|
||||
return
|
||||
|
||||
self.getMessageRequestId = self.controller.asyncGetMessageById(messageId)
|
||||
self.view.setMessageSearchOngoing(true)
|
||||
|
||||
method onGetMessageById*(self: Module, requestId: UUID, messageId: string, message: MessageDto, errorMessage: string) =
|
||||
|
||||
if self.getMessageRequestId != requestId:
|
||||
return
|
||||
|
||||
if errorMessage != "":
|
||||
error "attempted to scroll to a not fetched message", errorMessage, messageId, chatId = self.controller.getMyChatId()
|
||||
self.view.setMessageSearchOngoing(false)
|
||||
return
|
||||
|
||||
self.controller.setSearchedMessageId(messageId)
|
||||
self.checkIfMessageLoadedAndScrollToItIfItIs()
|
||||
self.reevaluateViewLoadingState()
|
||||
|
|
|
@ -248,8 +248,10 @@ method onUnpinMessage*(self: Module, messageId: string) =
|
|||
|
||||
method onPinMessage*(self: Module, messageId: string, actionInitiatedBy: string) =
|
||||
var item: pinned_msg_item.Item
|
||||
let (message, err) = self.controller.getMessageById(messageId)
|
||||
if(err.len > 0 or not self.buildPinnedMessageItem(message, actionInitiatedBy, item)):
|
||||
let response = self.controller.getMessageById(messageId)
|
||||
if response.error.len > 0:
|
||||
return
|
||||
if not self.buildPinnedMessageItem(response.message, actionInitiatedBy, item):
|
||||
return
|
||||
|
||||
self.view.pinnedModel().insertItemBasedOnClock(item)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import std/uri
|
||||
import std/uri, uuids
|
||||
include ../../common/json_utils
|
||||
include ../../../app/core/tasks/common
|
||||
|
||||
|
@ -312,3 +312,35 @@ const asyncUnfurlUrlsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
|||
"requestedUrls": %*arg.urls
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
|
||||
#################################################
|
||||
# Async get message by id
|
||||
#################################################
|
||||
|
||||
type
|
||||
AsyncGetMessageByMessageIdTaskArg = ref object of QObjectTaskArg
|
||||
requestId*: string
|
||||
messageId*: string
|
||||
|
||||
const asyncGetMessageByMessageIdTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetMessageByMessageIdTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_go.getMessageByMessageId(arg.messageId)
|
||||
let output = %*{
|
||||
"error": (if response.error != nil: response.error.message else: ""),
|
||||
"message": response.result,
|
||||
"requestId": arg.requestId,
|
||||
"messageId": arg.messageId,
|
||||
}
|
||||
arg.finish(output)
|
||||
except Exception as e:
|
||||
error "asyncGetMessageByMessageIdTask failed", message = e.msg
|
||||
let output = %*{
|
||||
"error": e.msg,
|
||||
"message": "",
|
||||
"requestId": arg.requestId,
|
||||
"messageId": arg.messageId,
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, tables, json, re, sequtils, strformat, strutils, chronicles, times, oids
|
||||
import NimQml, tables, json, re, sequtils, strformat, strutils, chronicles, times, oids, uuids
|
||||
|
||||
import ../../../app/core/tasks/[qt, threadpool]
|
||||
import ../../../app/core/signals/types
|
||||
|
@ -60,6 +60,7 @@ const SIGNAL_ENVELOPE_EXPIRED* = "envelopeExpired"
|
|||
const SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED* = "messageLinkPreviewDataLoaded"
|
||||
const SIGNAL_RELOAD_MESSAGES* = "reloadMessages"
|
||||
const SIGNAL_URLS_UNFURLED* = "urlsUnfurled"
|
||||
const SIGNAL_GET_MESSAGE_FINISHED* = "getMessageFinished"
|
||||
|
||||
include async_tasks
|
||||
|
||||
|
@ -133,6 +134,12 @@ type
|
|||
chatId*: string
|
||||
messageId*: string
|
||||
|
||||
GetMessageResult* = ref object of Args
|
||||
requestId*: UUID
|
||||
messageId*: string
|
||||
message*: MessageDto
|
||||
error*: string
|
||||
|
||||
QtObject:
|
||||
type Service* = ref object of QObject
|
||||
events: EventEmitter
|
||||
|
@ -563,19 +570,54 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error: ", procName="pinUnpinMessage", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc fetchMessageByMessageId*(self: Service, chatId: string, messageId: string):
|
||||
tuple[message: MessageDto, error: string] =
|
||||
proc getMessageByMessageId*(self: Service, messageId: string): GetMessageResult =
|
||||
try:
|
||||
let msgResponse = status_go.fetchMessageByMessageId(messageId)
|
||||
if(msgResponse.error.isNil):
|
||||
let msgResponse = status_go.getMessageByMessageId(messageId)
|
||||
if msgResponse.error.isNil:
|
||||
result.message = msgResponse.result.toMessageDto()
|
||||
|
||||
if(result.message.id.len == 0):
|
||||
if result.message.id.len == 0:
|
||||
result.error = "message with id: " & messageId & " doesn't exist"
|
||||
return
|
||||
except Exception as e:
|
||||
result.error = e.msg
|
||||
error "error: ", procName="fetchMessageByMessageId", errName = e.name, errDesription = e.msg
|
||||
error "error: ", procName="getMessageByMessageId", errName = e.name, errDesription = e.msg
|
||||
|
||||
proc onAsyncGetMessageById*(self: Service, response: string) {.slot.} =
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
if responseObj.kind != JObject:
|
||||
raise newException(RpcException, "getMessageById response is not an json object")
|
||||
|
||||
var signalData = GetMessageResult(
|
||||
requestId: parseUUID(responseObj["requestId"].getStr),
|
||||
messageId: responseObj["messageId"].getStr,
|
||||
error: responseObj["error"].getStr,
|
||||
)
|
||||
|
||||
if signalData.error == "":
|
||||
signalData.message = responseObj["message"].toMessageDto()
|
||||
|
||||
if signalData.message.id.len == 0:
|
||||
signalData.error = "message doesn't exist"
|
||||
|
||||
self.events.emit(SIGNAL_GET_MESSAGE_FINISHED, signalData)
|
||||
|
||||
except Exception as e:
|
||||
error "response processing failed", procName="asyncGetMessageByMessageId", errName = e.name, errDesription = e.msg
|
||||
self.events.emit(SIGNAL_GET_MESSAGE_FINISHED, GetMessageResult( error: e.msg ))
|
||||
|
||||
proc asyncGetMessageById*(self: Service, messageId: string): UUID =
|
||||
let requestId = genUUID()
|
||||
let arg = AsyncGetMessageByMessageIdTaskArg(
|
||||
tptr: cast[ByteAddress](asyncGetMessageByMessageIdTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncGetMessageById",
|
||||
requestId: $requestId,
|
||||
messageId: messageId,
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
return requestId
|
||||
|
||||
proc finishAsyncSearchMessagesWithError*(self: Service, chatId, errorMessage: string) =
|
||||
error "error: ", procName="onAsyncSearchMessages", errDescription = errorMessage
|
||||
|
|
|
@ -32,7 +32,7 @@ proc pinUnpinMessage*(chatId: string, messageId: string, pin: bool): RpcResponse
|
|||
}]
|
||||
result = callPrivateRPC("sendPinMessage".prefix, payload)
|
||||
|
||||
proc fetchMessageByMessageId*(messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
proc getMessageByMessageId*(messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [messageId]
|
||||
result = callPrivateRPC("messageByMessageID".prefix, payload)
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ Control {
|
|||
signal activeChanged(string messageId, bool active)
|
||||
|
||||
function startMessageFoundAnimation() {
|
||||
messageFoundAnimation.start();
|
||||
messageFoundAnimation.restart();
|
||||
}
|
||||
|
||||
onMessageAttachmentsChanged: {
|
||||
|
@ -133,14 +133,11 @@ Control {
|
|||
SequentialAnimation {
|
||||
id: messageFoundAnimation
|
||||
|
||||
PauseAnimation {
|
||||
duration: 600
|
||||
}
|
||||
NumberAnimation {
|
||||
target: highlightRect
|
||||
property: "opacity"
|
||||
to: 1.0
|
||||
duration: 1500
|
||||
duration: 250
|
||||
}
|
||||
PauseAnimation {
|
||||
duration: 1000
|
||||
|
|
|
@ -12,6 +12,7 @@ QtObject {
|
|||
property string messageText: ""
|
||||
property string messageContent: ""
|
||||
property string messageOriginInfo: ""
|
||||
property bool messageDeleted: false
|
||||
property var album: []
|
||||
property int albumCount: 0
|
||||
}
|
||||
|
|
|
@ -174,8 +174,9 @@ Item {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: !root.replyDetails.messageDeleted && root.replyDetails.sender.id
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
root.messageClicked(mouse)
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ MembersSelectorBase {
|
|||
if (root.model.count === 0 && !hasPendingContactRequest) {
|
||||
// List is empty and not a contact yet. Open the contact request popup
|
||||
|
||||
// If `displayName` is not undefiend and not empty,
|
||||
// If `displayName` is not undefined and not empty,
|
||||
// then we open the popup with given `contactData`, which probably came from URL.
|
||||
if (contactData.displayName) {
|
||||
// Open contact request if we have data from url
|
||||
|
|
|
@ -576,7 +576,6 @@ Loader {
|
|||
}
|
||||
|
||||
onReplyMessageClicked: {
|
||||
if (!root.quotedMessageDeleted && root.quotedMessageFrom)
|
||||
root.messageStore.messageModule.jumpToMessage(root.responseToMessageWithId)
|
||||
}
|
||||
|
||||
|
@ -679,14 +678,13 @@ Loader {
|
|||
}
|
||||
|
||||
messageText: {
|
||||
if (root.quotedMessageDeleted) {
|
||||
if (messageDeleted)
|
||||
return qsTr("Message deleted")
|
||||
}
|
||||
if (!root.quotedMessageText && !root.quotedMessageFrom) {
|
||||
if (!root.quotedMessageText && !root.quotedMessageFrom)
|
||||
return qsTr("Unknown message. Try fetching more messages")
|
||||
}
|
||||
return root.quotedMessageText
|
||||
}
|
||||
messageDeleted: root.quotedMessageDeleted
|
||||
contentType: d.convertContentType(root.quotedMessageContentType)
|
||||
amISender: root.quotedMessageFrom === userProfile.pubKey
|
||||
sender.id: root.quotedMessageFrom
|
||||
|
|
Loading…
Reference in New Issue