Use section identifiers as a way to identify if messages have been sent by the current user (no need to modify the model with `repeatMessageInfo`)
This commit is contained in:
parent
4fe6d9b767
commit
9d75f6f552
|
@ -31,15 +31,14 @@ proc delete*(self: ChatController) =
|
|||
proc handleChatEvents(self: ChatController) =
|
||||
# Display already saved messages
|
||||
self.status.events.on("messagesLoaded") do(e:Args):
|
||||
for message in MsgsLoadedArgs(e).messages:
|
||||
self.view.pushMessage(message.chatId, message.toChatMessage())
|
||||
self.view.pushMessages(MsgsLoadedArgs(e).messages)
|
||||
|
||||
self.status.events.on("messageSent") do(e: Args):
|
||||
var sentMessage = MsgArgs(e)
|
||||
var chatMessage = sentMessage.payload.toChatMessage()
|
||||
chatMessage.message = sentMessage.message
|
||||
chatMessage.isCurrentUser = true
|
||||
self.view.pushMessage(sentMessage.chatId, chatMessage)
|
||||
self.view.pushMessage(chatMessage)
|
||||
|
||||
self.status.events.on("channelJoined") do(e: Args):
|
||||
var channelMessage = ChannelArgs(e)
|
||||
|
@ -69,13 +68,10 @@ proc init*(self: ChatController) =
|
|||
self.status.mailservers.init()
|
||||
self.status.chat.init()
|
||||
|
||||
|
||||
proc handleMessage(self: ChatController, data: MessageSignal) =
|
||||
for c in data.chats:
|
||||
self.view.updateChat(c.toChatItem())
|
||||
|
||||
for message in data.messages:
|
||||
self.view.pushMessage(message.localChatId, message.toChatMessage())
|
||||
self.view.pushMessages(data.messages)
|
||||
|
||||
proc handleDiscoverySummary(self: ChatController, data: DiscoverySummarySignal) =
|
||||
## Handle mailserver peers being added and removed
|
||||
|
|
|
@ -50,6 +50,7 @@ QtObject:
|
|||
let selectedChannel = self.chats.getChannel(index)
|
||||
if self.activeChannel.id == selectedChannel.id: return
|
||||
self.activeChannel.setChatItem(selectedChannel)
|
||||
self.status.chat.setActiveChannel(selectedChannel.id)
|
||||
self.activeChannelChanged()
|
||||
|
||||
proc getActiveChannelIdx(self: ChatsView): QVariant {.slot.} =
|
||||
|
@ -77,9 +78,14 @@ QtObject:
|
|||
if not self.messageList.hasKey(channel):
|
||||
self.messageList[channel] = newChatMessageList()
|
||||
|
||||
proc pushMessage*(self:ChatsView, channel: string, message: ChatMessage) =
|
||||
self.upsertChannel(channel)
|
||||
self.messageList[channel].add(message)
|
||||
proc pushMessage*(self:ChatsView, message: ChatMessage) =
|
||||
self.upsertChannel(message.chatId)
|
||||
self.messageList[message.chatId].add(message)
|
||||
|
||||
proc pushMessages*(self:ChatsView, messages: seq[Message]) =
|
||||
for msg in messages:
|
||||
self.upsertChannel(msg.chatId)
|
||||
self.messageList[msg.chatId].add(msg.toChatMessage())
|
||||
|
||||
proc getMessageList(self: ChatsView): QVariant {.slot.} =
|
||||
self.upsertChannel(self.activeChannel.id)
|
||||
|
|
|
@ -8,11 +8,10 @@ type
|
|||
Timestamp = UserRole + 3
|
||||
Identicon = UserRole + 4
|
||||
IsCurrentUser = UserRole + 5
|
||||
RepeatMessageInfo = UserRole + 6
|
||||
ContentType = UserRole + 7
|
||||
Sticker = UserRole + 8
|
||||
FromAuthor = UserRole + 9
|
||||
Clock = UserRole + 10
|
||||
ContentType = UserRole + 6
|
||||
Sticker = UserRole + 7
|
||||
FromAuthor = UserRole + 8
|
||||
Clock = UserRole + 9
|
||||
QtObject:
|
||||
type
|
||||
ChatMessageList* = ref object of QAbstractListModel
|
||||
|
@ -41,7 +40,6 @@ QtObject:
|
|||
if index.row < 0 or index.row >= self.messages.len:
|
||||
return
|
||||
let message = self.messages[index.row]
|
||||
let repeatMessageInfo = (index.row == 0) or message.fromAuthor != self.messages[index.row - 1].fromAuthor
|
||||
let chatMessageRole = role.ChatMessageRoles
|
||||
case chatMessageRole:
|
||||
of ChatMessageRoles.UserName: result = newQVariant(message.userName)
|
||||
|
@ -50,7 +48,6 @@ QtObject:
|
|||
of ChatMessageRoles.Clock: result = newQVariant($message.clock)
|
||||
of ChatMessageRoles.Identicon: result = newQVariant(message.identicon)
|
||||
of ChatMessageRoles.IsCurrentUser: result = newQVariant(message.isCurrentUser)
|
||||
of ChatMessageRoles.RepeatMessageInfo: result = newQVariant(repeatMessageInfo)
|
||||
of ChatMessageRoles.ContentType: result = newQVariant(message.contentType)
|
||||
of ChatMessageRoles.Sticker: result = newQVariant(message.sticker)
|
||||
of ChatMessageRoles.FromAuthor: result = newQVariant(message.fromAuthor)
|
||||
|
@ -63,7 +60,6 @@ QtObject:
|
|||
ChatMessageRoles.Clock.int:"clock",
|
||||
ChatMessageRoles.Identicon.int:"identicon",
|
||||
ChatMessageRoles.IsCurrentUser.int:"isCurrentUser",
|
||||
ChatMessageRoles.RepeatMessageInfo.int:"repeatMessageInfo",
|
||||
ChatMessageRoles.ContentType.int:"contentType",
|
||||
ChatMessageRoles.Sticker.int:"sticker",
|
||||
ChatMessageRoles.FromAuthor.int:"fromAuthor"
|
||||
|
@ -73,3 +69,10 @@ QtObject:
|
|||
self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len)
|
||||
self.messages.add(message)
|
||||
self.endInsertRows()
|
||||
|
||||
proc add*(self: ChatMessageList, messages: seq[ChatMessage]) =
|
||||
self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len)
|
||||
for message in messages:
|
||||
self.messages.add(message)
|
||||
self.endInsertRows()
|
||||
|
||||
|
|
|
@ -108,6 +108,9 @@ proc leave*(self: ChatModel, chatId: string) =
|
|||
self.events.emit("channelLeft", ChannelArgs(channel: chatId))
|
||||
self.events.emit("activeChannelChanged", ChannelArgs(channel: self.getActiveChannel()))
|
||||
|
||||
proc setActiveChannel*(self: ChatModel, chatId: string) =
|
||||
self.events.emit("activeChannelChanged", ChannelArgs(channel: chatId))
|
||||
|
||||
proc sendMessage*(self: ChatModel, chatId: string, msg: string): string =
|
||||
var sentMessage = status_chat.sendChatMessage(chatId, msg)
|
||||
var parsedMessage = parseJson(sentMessage)["result"]["chats"][0]["lastMessage"]
|
||||
|
|
|
@ -12,6 +12,7 @@ type ChatMessage* = ref object
|
|||
isCurrentUser*: bool
|
||||
contentType*: int
|
||||
sticker*: string
|
||||
chatId*: string
|
||||
|
||||
proc delete*(self: ChatMessage) =
|
||||
discard
|
||||
|
@ -27,9 +28,11 @@ proc newChatMessage*(): ChatMessage =
|
|||
result.isCurrentUser = false
|
||||
result.contentType = 1
|
||||
result.sticker = ""
|
||||
result.chatId = ""
|
||||
|
||||
proc toChatMessage*(payload: JsonNode): ChatMessage =
|
||||
result = ChatMessage(
|
||||
chatId: payload["chatId"].str,
|
||||
userName: payload["alias"].str,
|
||||
message: payload["text"].str,
|
||||
timestamp: $payload["timestamp"],
|
||||
|
@ -42,6 +45,7 @@ proc toChatMessage*(payload: JsonNode): ChatMessage =
|
|||
|
||||
proc toChatMessage*(message: Message): ChatMessage =
|
||||
result = ChatMessage(
|
||||
chatId: message.chatId,
|
||||
userName: message.alias,
|
||||
clock: message.clock,
|
||||
fromAuthor: message.fromAuthor,
|
||||
|
|
|
@ -22,10 +22,6 @@ ScrollView {
|
|||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
|
||||
function scrollToBottom(goToBottom) {
|
||||
chatLogView.positionViewAtEnd();
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
|
@ -33,26 +29,26 @@ ScrollView {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
onCountChanged: {
|
||||
scrollToBottom();
|
||||
if (!this.atYEnd) {
|
||||
// User has scrolled up, we don't want to scroll back
|
||||
return
|
||||
}
|
||||
|
||||
Qt.callLater( chatLogView.positionViewAtEnd )
|
||||
}
|
||||
model: messageListDelegate
|
||||
section.property: "userName"
|
||||
section.criteria: ViewSection.FullString
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: messageListDelegate
|
||||
model: messageList
|
||||
delegate: Message {
|
||||
userName: model.userName
|
||||
message: model.message
|
||||
identicon: model.identicon
|
||||
isCurrentUser: model.isCurrentUser
|
||||
repeatMessageInfo: model.repeatMessageInfo
|
||||
timestamp: model.timestamp
|
||||
sticker: model.sticker
|
||||
contentType: model.contentType
|
||||
}
|
||||
property var lessThan: [
|
||||
function(left, right) { return left.clock < right.clock }
|
||||
]
|
||||
|
||||
property var lessThan: function(left, right) { return left.clock < right.clock }
|
||||
property int sortOrder: 0
|
||||
onSortOrderChanged: items.setGroups(0, items.count, "unsorted")
|
||||
|
||||
function insertPosition(lessThan, item) {
|
||||
var lower = 0
|
||||
|
@ -73,23 +69,37 @@ ScrollView {
|
|||
while (unsortedItems.count > 0) {
|
||||
var item = unsortedItems.get(0)
|
||||
var index = insertPosition(lessThan, item)
|
||||
|
||||
item.groups = "items"
|
||||
items.move(item.itemsIndex, index)
|
||||
}
|
||||
}
|
||||
|
||||
items.includeByDefault: false
|
||||
|
||||
groups: DelegateModelGroup {
|
||||
id: unsortedItems
|
||||
name: "unsorted"
|
||||
includeByDefault: true
|
||||
onChanged: {
|
||||
messageListDelegate.sort(messageListDelegate.lessThan)
|
||||
scrollToBottom();
|
||||
if (messageListDelegate.sortOrder == messageListDelegate.lessThan.length)
|
||||
setGroups(0, count, "items")
|
||||
else {
|
||||
messageListDelegate.sort(messageListDelegate.lessThan[messageListDelegate.sortOrder])
|
||||
}
|
||||
}
|
||||
}
|
||||
model: messageList
|
||||
delegate: Message {
|
||||
id: msgDelegate
|
||||
userName: model.userName
|
||||
message: model.message
|
||||
identicon: model.identicon
|
||||
isCurrentUser: model.isCurrentUser
|
||||
timestamp: model.timestamp
|
||||
sticker: model.sticker
|
||||
contentType: model.contentType
|
||||
authorCurrentMsg: msgDelegate.ListView.section
|
||||
authorPrevMsg: msgDelegate.ListView.previousSection
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,14 +12,15 @@ Item {
|
|||
property string message: "That's right. We're friends... Of justice, that is."
|
||||
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
|
||||
property bool isCurrentUser: false
|
||||
property bool repeatMessageInfo: true
|
||||
property int timestamp: 1234567
|
||||
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"
|
||||
property int contentType: 1 // constants don't work in default props
|
||||
|
||||
width: parent.width
|
||||
height: contentType == Constants.stickerType ? stickerId.height : (isCurrentUser || (!isCurrentUser && !repeatMessageInfo) ? chatBox.height : 24 + chatBox.height)
|
||||
property string authorCurrentMsg: "authorCurrentMsg"
|
||||
property string authorPrevMsg: "authorPrevMsg"
|
||||
|
||||
width: parent.width
|
||||
height: contentType == Constants.stickerType ? stickerId.height + 50 : (isCurrentUser || (!isCurrentUser && authorCurrentMsg == authorPrevMsg) ? chatBox.height : 24 + chatBox.height)
|
||||
ProfilePopup {
|
||||
id: profilePopup
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ Item {
|
|||
anchors.top: parent.top
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: identicon
|
||||
visible: repeatMessageInfo && !isCurrentUser
|
||||
visible: authorCurrentMsg != authorPrevMsg && !isCurrentUser
|
||||
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
@ -57,7 +58,7 @@ Item {
|
|||
readOnly: true
|
||||
wrapMode: Text.WordWrap
|
||||
selectByMouse: true
|
||||
visible: repeatMessageInfo && !isCurrentUser
|
||||
visible: authorCurrentMsg != authorPrevMsg && !isCurrentUser
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -74,7 +75,7 @@ Item {
|
|||
anchors.leftMargin: !isCurrentUser ? 8 : 0
|
||||
anchors.right: !isCurrentUser ? undefined : parent.right
|
||||
anchors.rightMargin: !isCurrentUser ? 0 : Theme.padding
|
||||
anchors.top: repeatMessageInfo && !isCurrentUser ? chatImage.top : parent.top
|
||||
anchors.top: authorCurrentMsg != authorPrevMsg && !isCurrentUser ? chatImage.top : parent.top
|
||||
anchors.topMargin: 0
|
||||
|
||||
// Thi`s rectangle's only job is to mask the corner to make it less rounded... yep
|
||||
|
|
Loading…
Reference in New Issue