feat: load messages on scroll to top, and fix last message scrolling
This commit is contained in:
parent
b5b02cfd57
commit
f3ff229bf8
|
@ -1,6 +1,7 @@
|
|||
import NimQml
|
||||
import Tables
|
||||
import json
|
||||
import chronicles
|
||||
|
||||
import ../../signals/types
|
||||
import ../../status/chat
|
||||
|
@ -10,6 +11,9 @@ import views/channels_list
|
|||
import views/message_list
|
||||
import views/chat_item
|
||||
|
||||
logScope:
|
||||
topics = "chats-view"
|
||||
|
||||
QtObject:
|
||||
type
|
||||
ChatsView* = ref object of QAbstractListModel
|
||||
|
@ -78,14 +82,18 @@ QtObject:
|
|||
if not self.messageList.hasKey(channel):
|
||||
self.messageList[channel] = newChatMessageList(channel)
|
||||
|
||||
proc messagePushed*(self: ChatsView) {.signal.}
|
||||
|
||||
proc pushMessage*(self:ChatsView, message: ChatMessage) =
|
||||
self.upsertChannel(message.chatId)
|
||||
self.messageList[message.chatId].add(message)
|
||||
self.messagePushed()
|
||||
|
||||
proc pushMessages*(self:ChatsView, messages: seq[Message]) =
|
||||
for msg in messages:
|
||||
self.upsertChannel(msg.chatId)
|
||||
self.messageList[msg.chatId].add(msg.toChatMessage())
|
||||
self.messagePushed()
|
||||
|
||||
proc getMessageList(self: ChatsView): QVariant {.slot.} =
|
||||
self.upsertChannel(self.activeChannel.id)
|
||||
|
@ -97,6 +105,7 @@ QtObject:
|
|||
|
||||
proc pushChatItem*(self: ChatsView, chatItem: ChatItem) =
|
||||
discard self.chats.addChatItemToList(chatItem)
|
||||
self.messagePushed()
|
||||
|
||||
proc sendMessage*(self: ChatsView, message: string) {.slot.} =
|
||||
discard self.status.chat.sendMessage(self.activeChannel.id, message)
|
||||
|
@ -104,6 +113,13 @@ QtObject:
|
|||
proc joinChat*(self: ChatsView, channel: string, chatTypeInt: int): int {.slot.} =
|
||||
self.status.chat.join(channel, ChatType(chatTypeInt))
|
||||
|
||||
proc messagesLoaded*(self: ChatsView) {.signal.}
|
||||
|
||||
proc loadMoreMessages*(self: ChatsView) {.slot.} =
|
||||
trace "Loading more messages", chaId = self.activeChannel.id
|
||||
self.status.chat.chatMessages(self.activeChannel.id, false)
|
||||
self.messagesLoaded();
|
||||
|
||||
proc leaveActiveChat*(self: ChatsView) {.slot.} =
|
||||
self.status.chat.leave(self.activeChannel.id)
|
||||
|
||||
|
|
|
@ -33,12 +33,14 @@ type
|
|||
events*: EventEmitter
|
||||
channels*: HashSet[string]
|
||||
filters*: Table[string, string]
|
||||
msgCursor*: Table[string, string]
|
||||
|
||||
proc newChatModel*(events: EventEmitter): ChatModel =
|
||||
result = ChatModel()
|
||||
result.events = events
|
||||
result.channels = initHashSet[string]()
|
||||
result.filters = initTable[string, string]()
|
||||
result.msgCursor = initTable[string, string]()
|
||||
|
||||
proc delete*(self: ChatModel) =
|
||||
discard
|
||||
|
@ -117,9 +119,17 @@ proc sendMessage*(self: ChatModel, chatId: string, msg: string): string =
|
|||
self.events.emit("messageSent", MsgArgs(message: msg, chatId: chatId, payload: parsedMessage))
|
||||
sentMessage
|
||||
|
||||
proc chatMessages*(self: ChatModel, chatId: string) =
|
||||
let msgs = status_chat.chatMessages(chatId)
|
||||
self.events.emit("messagesLoaded", MsgsLoadedArgs(messages: msgs))
|
||||
proc chatMessages*(self: ChatModel, chatId: string, initialLoad:bool = true) =
|
||||
if not self.msgCursor.hasKey(chatId):
|
||||
self.msgCursor[chatId] = "";
|
||||
|
||||
# Messages were already loaded, since cursor will
|
||||
# be nil/empty if there are no more messages
|
||||
if(not initialLoad and self.msgCursor[chatId] == ""): return
|
||||
|
||||
let messageTuple = status_chat.chatMessages(chatId, self.msgCursor[chatId])
|
||||
self.msgCursor[chatId] = messageTuple[0];
|
||||
self.events.emit("messagesLoaded", MsgsLoadedArgs(messages: messageTuple[1]))
|
||||
|
||||
proc markAllChannelMessagesRead*(self: ChatModel, chatId: string): JsonNode =
|
||||
var response = status_chat.markAllRead(chatId)
|
||||
|
|
|
@ -71,12 +71,22 @@ proc loadChats*(): seq[Chat] =
|
|||
if chat.active and chat.chatType != ChatType.Unknown:
|
||||
result.add(jsonChat.toChat)
|
||||
|
||||
proc chatMessages*(chatId: string): seq[Message] =
|
||||
result = @[]
|
||||
let rpcResult = parseJson(callPrivateRPC("chatMessages".prefix, %* [chatId, nil, 1000]))["result"]
|
||||
proc chatMessages*(chatId: string, cursor: string = ""): (string, seq[Message]) =
|
||||
var messages: seq[Message] = @[]
|
||||
var cursorVal: JsonNode
|
||||
|
||||
if cursor == "":
|
||||
cursorVal = newJNull()
|
||||
else:
|
||||
cursorVal = newJString(cursor)
|
||||
|
||||
let rpcResult = parseJson(callPrivateRPC("chatMessages".prefix, %* [chatId, cursorVal, 20]))["result"]
|
||||
|
||||
if rpcResult["messages"].kind != JNull:
|
||||
for jsonMsg in rpcResult["messages"]:
|
||||
result.add(jsonMsg.toMessage)
|
||||
messages.add(jsonMsg.toMessage)
|
||||
|
||||
return (rpcResult{"cursor"}.getStr, messages)
|
||||
|
||||
# TODO this probably belongs in another file
|
||||
proc generateSymKeyFromPassword*(): string =
|
||||
|
|
|
@ -13,6 +13,7 @@ ScrollView {
|
|||
id: scrollView
|
||||
|
||||
property var messageList: MessagesData {}
|
||||
property bool loadingMessages: false
|
||||
|
||||
contentItem: chatLogView
|
||||
anchors.fill: parent
|
||||
|
@ -28,14 +29,36 @@ ScrollView {
|
|||
id: chatLogView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
onCountChanged: {
|
||||
if (!this.atYEnd) {
|
||||
|
||||
Connections {
|
||||
target: chatsModel
|
||||
onMessagesLoaded: {
|
||||
loadingMessages = false;
|
||||
}
|
||||
|
||||
onActiveChannelChanged: {
|
||||
Qt.callLater( chatLogView.positionViewAtEnd )
|
||||
}
|
||||
|
||||
onMessagePushed: {
|
||||
if (!chatLogView.atYEnd) {
|
||||
// User has scrolled up, we don't want to scroll back
|
||||
return
|
||||
}
|
||||
|
||||
if(chatLogView.atYEnd)
|
||||
Qt.callLater( chatLogView.positionViewAtEnd )
|
||||
}
|
||||
}
|
||||
|
||||
onContentYChanged: {
|
||||
if(atYBeginning && !loadingMessages){
|
||||
loadingMessages = true;
|
||||
chatsModel.loadMoreMessages();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
model: messageListDelegate
|
||||
section.property: "fromAuthor"
|
||||
section.criteria: ViewSection.FullString
|
||||
|
|
Loading…
Reference in New Issue