feature(@desktop/chat): support jumping to search result message that is not currently loaded in memory
Crash adding public chat which is caused by changes applied to this feature is fixed. Fixes: #3005
This commit is contained in:
parent
5d8b02e057
commit
83d6817f70
|
@ -13,6 +13,7 @@ proc handleChatEvents(self: ChatController) =
|
|||
self.status.events.on("messagesLoaded") do(e:Args):
|
||||
let evArgs = MsgsLoadedArgs(e)
|
||||
self.view.onMessagesLoaded(evArgs.messages)
|
||||
self.view.onMessagesLoaded(msgArgs.chatId, msgArgs.messages)
|
||||
for statusUpdate in evArgs.statusUpdates:
|
||||
self.view.communities.updateMemberVisibility(statusUpdate)
|
||||
|
||||
|
|
|
@ -438,8 +438,8 @@ QtObject:
|
|||
let task = RequestMessagesTaskArg( `method`: "requestMoreMessages", chatId: self.channelView.activeChannel.id)
|
||||
mailserverWorker.start(task)
|
||||
|
||||
proc onMessagesLoaded*(self: ChatsView, messages: var seq[Message]) =
|
||||
self.messageView.onMessagesLoaded(messages)
|
||||
proc onMessagesLoaded*(self: ChatsView, chatId: string, messages: var seq[Message]) =
|
||||
self.messageView.onMessagesLoaded(chatId, messages)
|
||||
|
||||
proc onSearchMessagesLoaded*(self: ChatsView, messages: seq[Message]) =
|
||||
self.messageView.onSearchMessagesLoaded(messages)
|
||||
|
|
|
@ -57,6 +57,8 @@ QtObject:
|
|||
messageReactions*: Table[string, string]
|
||||
timedoutMessages: HashSet[string]
|
||||
userList: UserListView
|
||||
loadingHistoryMessages: bool
|
||||
initialMessagesLoaded: bool
|
||||
|
||||
proc delete*(self: ChatMessageList) =
|
||||
self.messages = @[]
|
||||
|
@ -81,6 +83,8 @@ QtObject:
|
|||
proc setup*(self: ChatMessageList, chatId: string, status: Status, addFakeMessages: bool) =
|
||||
self.messages = @[]
|
||||
self.id = chatId
|
||||
self.loadingHistoryMessages = false
|
||||
self.initialMessagesLoaded = false
|
||||
|
||||
if addFakeMessages:
|
||||
self.addFakeMessages()
|
||||
|
@ -97,6 +101,41 @@ QtObject:
|
|||
new(result, delete)
|
||||
result.setup(chatId, status, addFakeMessages)
|
||||
|
||||
#################################################
|
||||
# Properties
|
||||
#################################################
|
||||
proc loadingHistoryMessagesChanged*(self: ChatMessageList) {.signal.}
|
||||
|
||||
proc setLoadingHistoryMessages*(self: ChatMessageList, value: bool) =
|
||||
if (value == self.loadingHistoryMessages):
|
||||
return
|
||||
|
||||
self.loadingHistoryMessages = value
|
||||
self.loadingHistoryMessagesChanged()
|
||||
|
||||
proc getLoadingHistoryMessages*(self: ChatMessageList): QVariant {.slot.} =
|
||||
return newQVariant(self.loadingHistoryMessages)
|
||||
|
||||
QtProperty[QVariant] loadingHistoryMessages:
|
||||
read = getLoadingHistoryMessages
|
||||
notify = loadingHistoryMessagesChanged
|
||||
|
||||
proc initialMessagesLoadedChanged*(self: ChatMessageList) {.signal.}
|
||||
|
||||
proc setInitialMessagesLoaded*(self: ChatMessageList, value: bool) =
|
||||
if (value == self.initialMessagesLoaded):
|
||||
return
|
||||
|
||||
self.initialMessagesLoaded = value
|
||||
self.initialMessagesLoadedChanged()
|
||||
|
||||
proc getInitialMessagesLoaded*(self: ChatMessageList): QVariant {.slot.} =
|
||||
return newQVariant(self.initialMessagesLoaded)
|
||||
|
||||
QtProperty[QVariant] initialMessagesLoaded:
|
||||
read = getInitialMessagesLoaded
|
||||
notify = initialMessagesLoadedChanged
|
||||
|
||||
proc countChanged*(self: ChatMessageList) {.signal.}
|
||||
|
||||
proc count*(self: ChatMessageList): int {.slot.} =
|
||||
|
|
|
@ -18,6 +18,7 @@ logScope:
|
|||
type
|
||||
ChatViewRoles {.pure.} = enum
|
||||
MessageList = UserRole + 1
|
||||
ChatId
|
||||
|
||||
QtObject:
|
||||
type MessageView* = ref object of QAbstractListModel
|
||||
|
@ -33,7 +34,6 @@ QtObject:
|
|||
unreadDirectMessagesAndMentionsCount: int
|
||||
channelOpenTime*: Table[string, int64]
|
||||
searchedMessageId: string
|
||||
loadingHistoryMessages: bool
|
||||
|
||||
proc setup(self: MessageView) = self.QAbstractListModel.setup
|
||||
proc delete*(self: MessageView) =
|
||||
|
@ -59,32 +59,14 @@ QtObject:
|
|||
result.unreadMessageCnt = 0
|
||||
result.searchResultMessageModel = newMessageListProxyModel(status)
|
||||
result.unreadDirectMessagesAndMentionsCount = 0
|
||||
result.loadingHistoryMessages = false
|
||||
result.setup
|
||||
|
||||
#################################################
|
||||
# Forward declaration section
|
||||
#################################################
|
||||
proc checkIfSearchedMessageIsLoaded(self: MessageView)
|
||||
|
||||
#################################################
|
||||
# Properties
|
||||
#################################################
|
||||
proc loadingHistoryMessagesChanged*(self: MessageView) {.signal.}
|
||||
|
||||
proc setLoadingHistoryMessages*(self: MessageView, value: bool) =
|
||||
if (value == self.loadingHistoryMessages):
|
||||
return
|
||||
|
||||
self.loadingHistoryMessages = value
|
||||
self.loadingHistoryMessagesChanged()
|
||||
|
||||
proc getLoadingHistoryMessages*(self: MessageView): QVariant {.slot.} =
|
||||
return newQVariant(self.loadingHistoryMessages)
|
||||
|
||||
QtProperty[QVariant] loadingHistoryMessages:
|
||||
read = getLoadingHistoryMessages
|
||||
notify = loadingHistoryMessagesChanged
|
||||
proc checkIfSearchedMessageIsLoaded(self: MessageView, chatId: string)
|
||||
proc setLoadingHistoryMessages*(self: MessageView, chatId: string, value: bool)
|
||||
proc setInitialMessagesLoaded*(self: MessageView, chatId: string, value: bool)
|
||||
|
||||
proc replaceMentionsWithPubKeys(self: MessageView, mentions: seq[string], contacts: seq[Profile], message: string, predicate: proc (contact: Profile): string): string =
|
||||
var updatedMessage = message
|
||||
|
@ -286,18 +268,17 @@ QtObject:
|
|||
|
||||
proc messagesLoaded*(self: MessageView) {.signal.}
|
||||
|
||||
proc loadMoreMessages*(self: MessageView) {.slot.} =
|
||||
let channelId = self.channelView.activeChannel.id
|
||||
|
||||
self.setLoadingHistoryMessages(true)
|
||||
proc loadMoreMessages*(self: MessageView, channelId: string) {.slot.} =
|
||||
self.setLoadingHistoryMessages(channelId, true)
|
||||
self.status.chat.loadMoreMessagesForChannel(channelId)
|
||||
|
||||
proc onMessagesLoaded*(self: MessageView, messages: var seq[Message]) =
|
||||
proc onMessagesLoaded*(self: MessageView, chatId: string, messages: var seq[Message]) =
|
||||
self.pushMessages(messages)
|
||||
self.messagesLoaded();
|
||||
self.setLoadingHistoryMessages(false)
|
||||
self.messagesLoaded()
|
||||
|
||||
self.checkIfSearchedMessageIsLoaded()
|
||||
self.setInitialMessagesLoaded(chatId, true)
|
||||
self.setLoadingHistoryMessages(chatId, false)
|
||||
self.checkIfSearchedMessageIsLoaded(chatId)
|
||||
|
||||
proc loadingMessagesChanged*(self: MessageView, value: bool) {.signal.}
|
||||
|
||||
|
@ -432,10 +413,15 @@ QtObject:
|
|||
return
|
||||
if index.row < 0 or index.row >= self.messageList.len:
|
||||
return
|
||||
return newQVariant(toSeq(self.messageList.values)[index.row])
|
||||
|
||||
let chatViewRole = role.ChatViewRoles
|
||||
case chatViewRole:
|
||||
of ChatViewRoles.ChatId: result = newQVariant(toSeq(self.messageList.keys)[index.row])
|
||||
of ChatViewRoles.MessageList: result = newQVariant(toSeq(self.messageList.values)[index.row])
|
||||
|
||||
method roleNames(self: MessageView): Table[int, string] =
|
||||
{
|
||||
ChatViewRoles.ChatId.int:"chatId",
|
||||
ChatViewRoles.MessageList.int:"messages"
|
||||
}.toTable
|
||||
|
||||
|
@ -472,13 +458,15 @@ QtObject:
|
|||
|
||||
return message.id != ""
|
||||
|
||||
proc loadMessagesTillMessageWithIdIsLoaded*(self: MessageView, messageId: string) {.slot.} =
|
||||
proc loadMessagesUntillMessageWithIdIsLoaded*(self: MessageView, messageId: string) {.slot.} =
|
||||
self.searchedMessageId = messageId
|
||||
self.loadMoreMessages()
|
||||
let chatId = self.channelView.activeChannel.id
|
||||
|
||||
self.loadMoreMessages(chatId)
|
||||
|
||||
proc searchedMessageLoaded*(self: MessageView, messageId: string) {.signal.}
|
||||
|
||||
proc checkIfSearchedMessageIsLoaded(self: MessageView) =
|
||||
proc checkIfSearchedMessageIsLoaded(self: MessageView, chatId: string) =
|
||||
if (self.searchedMessageId.len == 0):
|
||||
return
|
||||
|
||||
|
@ -486,4 +474,13 @@ QtObject:
|
|||
self.searchedMessageLoaded(self.searchedMessageId)
|
||||
self.searchedMessageId = ""
|
||||
else:
|
||||
self.loadMoreMessages()
|
||||
self.loadMoreMessages(chatId)
|
||||
|
||||
proc setLoadingHistoryMessages*(self: MessageView, chatId: string, value: bool) =
|
||||
if self.messageList.hasKey(chatId):
|
||||
self.messageList[chatId].setLoadingHistoryMessages(value)
|
||||
|
||||
proc setInitialMessagesLoaded*(self: MessageView, chatId: string, value: bool) =
|
||||
if self.messageList.hasKey(chatId):
|
||||
self.messageList[chatId].setInitialMessagesLoaded(value)
|
||||
|
|
@ -46,6 +46,7 @@ type
|
|||
active*: bool
|
||||
|
||||
MsgsLoadedArgs* = ref object of Args
|
||||
chatId*: string
|
||||
messages*: seq[Message]
|
||||
statusUpdates*: seq[StatusUpdate]
|
||||
|
||||
|
@ -76,10 +77,10 @@ QtObject:
|
|||
mailserverReady*: bool
|
||||
contacts*: Table[string, Profile]
|
||||
channels*: Table[string, Chat]
|
||||
msgCursor*: Table[string, string]
|
||||
pinnedMsgCursor*: Table[string, string]
|
||||
msgCursor: Table[string, string]
|
||||
pinnedMsgCursor: Table[string, string]
|
||||
activityCenterCursor*: string
|
||||
emojiCursor*: Table[string, string]
|
||||
emojiCursor: Table[string, string]
|
||||
lastMessageTimestamps*: Table[string, int64]
|
||||
|
||||
proc setup(self: ChatModel) =
|
||||
|
@ -665,13 +666,22 @@ QtObject:
|
|||
for jsonMsg in messagesArray:
|
||||
messages.add(jsonMsg.toMessage())
|
||||
|
||||
self.events.emit("searchMessagesLoaded", MsgsLoadedArgs(messages: messages))
|
||||
self.events.emit("searchMessagesLoaded", MsgsLoadedArgs(chatId: chatId, messages: messages))
|
||||
|
||||
proc loadMoreMessagesForChannel*(self: ChatModel, channelId: string) =
|
||||
if (channelId.len == 0):
|
||||
info "empty channel id set for fetching more messages"
|
||||
return
|
||||
|
||||
if(not self.msgCursor.hasKey(channelId)):
|
||||
self.msgCursor[channelId] = ""
|
||||
|
||||
if(not self.emojiCursor.hasKey(channelId)):
|
||||
self.emojiCursor[channelId] = ""
|
||||
|
||||
if(not self.pinnedMsgCursor.hasKey(channelId)):
|
||||
self.pinnedMsgCursor[channelId] = ""
|
||||
|
||||
let arg = AsyncFetchChatMessagesTaskArg(
|
||||
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
|
@ -690,19 +700,13 @@ QtObject:
|
|||
info "empty channel id set for loading initial messages"
|
||||
return
|
||||
|
||||
if(not self.msgCursor.hasKey(channelId)):
|
||||
self.msgCursor[channelId] = ""
|
||||
else:
|
||||
if(self.msgCursor.hasKey(channelId)):
|
||||
return
|
||||
|
||||
if(not self.emojiCursor.hasKey(channelId)):
|
||||
self.emojiCursor[channelId] = ""
|
||||
else:
|
||||
if(self.emojiCursor.hasKey(channelId)):
|
||||
return
|
||||
|
||||
if(not self.pinnedMsgCursor.hasKey(channelId)):
|
||||
self.pinnedMsgCursor[channelId] = ""
|
||||
else:
|
||||
if(self.pinnedMsgCursor.hasKey(channelId)):
|
||||
return
|
||||
|
||||
self.loadMoreMessagesForChannel(channelId)
|
||||
|
@ -771,6 +775,6 @@ QtObject:
|
|||
pinnedMessages.add(msg)
|
||||
|
||||
# notify view
|
||||
self.events.emit("messagesLoaded", MsgsLoadedArgs(messages: messages))
|
||||
self.events.emit("messagesLoaded", MsgsLoadedArgs(chatId: chatId, messages: messages))
|
||||
self.events.emit("reactionsLoaded", ReactionsLoadedArgs(reactions: reactions))
|
||||
self.events.emit("pinnedMessagesLoaded", MsgsLoadedArgs(messages: pinnedMessages))
|
||||
self.events.emit("pinnedMessagesLoaded", MsgsLoadedArgs(chatId: chatId, messages: pinnedMessages))
|
|
@ -308,7 +308,7 @@ Item {
|
|||
active: stackLayoutChatMessages.currentIndex === index
|
||||
sourceComponent: ChatMessages {
|
||||
id: chatMessages
|
||||
messageList: model.messages
|
||||
messageList: messages
|
||||
messageContextMenuInst: MessageContextMenu {
|
||||
reactionModel: EmojiReactions { }
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ Item {
|
|||
property alias scrollToMessage: chatLogView.scrollToMessage
|
||||
|
||||
property var messageContextMenuInst
|
||||
property var messageList: MessagesData {}
|
||||
property real scrollY: chatLogView.visibleArea.yPosition * chatLogView.contentHeight
|
||||
property int newMessages: 0
|
||||
property int countOnStartUp: 0
|
||||
|
@ -223,10 +222,10 @@ Item {
|
|||
}
|
||||
|
||||
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
||||
if(chatsModel.messageView.loadingHistoryMessages)
|
||||
if(!messages.initialMessagesLoaded || messages.loadingHistoryMessages)
|
||||
return
|
||||
|
||||
chatsModel.messageView.loadMoreMessages();
|
||||
chatsModel.messageView.loadMoreMessages(chatId);
|
||||
});
|
||||
|
||||
onContentYChanged: {
|
||||
|
@ -263,7 +262,7 @@ Item {
|
|||
function(left, right) { return left.clock > right.clock }
|
||||
]
|
||||
|
||||
model: messageList
|
||||
model: messages
|
||||
|
||||
delegate: Message {
|
||||
id: msgDelegate
|
||||
|
|
|
@ -215,7 +215,7 @@ Popup {
|
|||
if(chatsModel.messageView.isMessageDisplayed(model.messageId))
|
||||
positionAtMessage(model.messageId)
|
||||
else
|
||||
chatsModel.messageView.loadMessagesTillMessageWithIdIsLoaded(model.messageId)
|
||||
chatsModel.messageView.loadMessagesUntillMessageWithIdIsLoaded(model.messageId)
|
||||
}
|
||||
|
||||
prevMessageIndex: -1
|
||||
|
|
|
@ -4,7 +4,6 @@ import "../../../../shared"
|
|||
|
||||
Rectangle {
|
||||
property string channel: "status"
|
||||
property var onJoin: function() {}
|
||||
|
||||
border.width: 1
|
||||
radius: 8
|
||||
|
@ -30,7 +29,6 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
onClicked: {
|
||||
chatsModel.channelView.joinPublicChat(channel);
|
||||
onJoin()
|
||||
}
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue