show date headers, and fix sending replies only when they are enabled

This commit is contained in:
Richard Ramos 2020-07-11 21:03:39 -04:00 committed by Iuri Matias
parent 221d3b9628
commit ceb5873272
7 changed files with 90 additions and 25 deletions

View File

@ -24,6 +24,7 @@ type
OutgoingStatus = UserRole + 13 OutgoingStatus = UserRole + 13
ResponseTo = UserRole + 14 ResponseTo = UserRole + 14
PlainText = UserRole + 15 PlainText = UserRole + 15
Index = UserRole + 16
QtObject: QtObject:
type type
@ -80,6 +81,7 @@ QtObject:
of ChatMessageRoles.Id: result = newQVariant(message.id) of ChatMessageRoles.Id: result = newQVariant(message.id)
of ChatMessageRoles.OutgoingStatus: result = newQVariant(message.outgoingStatus) of ChatMessageRoles.OutgoingStatus: result = newQVariant(message.outgoingStatus)
of ChatMessageRoles.ResponseTo: result = newQVariant(message.responseTo) of ChatMessageRoles.ResponseTo: result = newQVariant(message.responseTo)
of ChatMessageRoles.Index: result = newQVariant(index.row)
method roleNames(self: ChatMessageList): Table[int, string] = method roleNames(self: ChatMessageList): Table[int, string] =
{ {
@ -97,20 +99,25 @@ QtObject:
ChatMessageRoles.SectionIdentifier.int: "sectionIdentifier", ChatMessageRoles.SectionIdentifier.int: "sectionIdentifier",
ChatMessageRoles.Id.int: "messageId", ChatMessageRoles.Id.int: "messageId",
ChatMessageRoles.OutgoingStatus.int: "outgoingStatus", ChatMessageRoles.OutgoingStatus.int: "outgoingStatus",
ChatMessageRoles.ResponseTo.int: "responseTo" ChatMessageRoles.ResponseTo.int: "responseTo",
ChatMessageRoles.Index.int: "index"
}.toTable }.toTable
proc getMessageIndex(self: ChatMessageList, messageId: string): int {.slot.} = proc getMessageIndex(self: ChatMessageList, messageId: string): int {.slot.} =
if not self.messageIndex.hasKey(messageId): return -1 if not self.messageIndex.hasKey(messageId): return -1
result = self.messageIndex[messageId] result = self.messageIndex[messageId]
proc getReplyData(self: ChatMessageList, index: int, data: string): string {.slot.} = # TODO: see how to use data() instead of this function
proc getMessageData(self: ChatMessageList, index: int, data: string): string {.slot.} =
if index < 0 or index >= self.messages.len: return ("")
let message = self.messages[index] let message = self.messages[index]
case data: case data:
of "userName": result = message.alias of "userName": result = (message.alias)
of "message": result = message.text of "message": result = (message.text)
of "identicon": result = message.identicon of "identicon": result = (message.identicon)
else: result = "" of "timestamp": result = $(message.timestamp)
else: result = ("")
proc add*(self: ChatMessageList, message: Message) = proc add*(self: ChatMessageList, message: Message) =
if self.messageIndex.hasKey(message.id): return # duplicated msg if self.messageIndex.hasKey(message.id): return # duplicated msg
@ -141,7 +148,6 @@ QtObject:
m.outgoingStatus = "sent" m.outgoingStatus = "sent"
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.OutgoingStatus.int]) self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.OutgoingStatus.int])
proc updateUsernames*(self: ChatMessageList, contacts: seq[Profile]) = proc updateUsernames*(self: ChatMessageList, contacts: seq[Profile]) =
let topLeft = self.createIndex(0, 0, nil) let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.messages.len, 0, nil) let bottomRight = self.createIndex(self.messages.len, 0, nil)

View File

@ -23,7 +23,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
onClicked: { onClicked: {
chatsModel.sendMessage(txtData.text, SelectedMessage.messageId) chatsModel.sendMessage(txtData.text, chatColumn.isReply ? SelectedMessage.messageId : "")
txtData.text = "" txtData.text = ""
} }
background: Rectangle { background: Rectangle {

View File

@ -34,7 +34,7 @@ Rectangle {
if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) { if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
if(txtData.text.trim().length > 0){ if(txtData.text.trim().length > 0){
let msg = interpretMessage(txtData.text.trim()) let msg = interpretMessage(txtData.text.trim())
chatsModel.sendMessage(msg, SelectedMessage.messageId); chatsModel.sendMessage(msg, chatColumn.isReply ? SelectedMessage.messageId : "");
txtData.text = ""; txtData.text = "";
event.accepted = true; event.accepted = true;
sendMessageSound.stop() sendMessageSound.stop()

View File

@ -111,7 +111,7 @@ ScrollView {
} }
model: messageList model: messageList
Message { delegate: Message {
id: msgDelegate id: msgDelegate
fromAuthor: model.fromAuthor fromAuthor: model.fromAuthor
chatId: model.chatId chatId: model.chatId
@ -129,6 +129,14 @@ ScrollView {
authorPrevMsg: msgDelegate.ListView.previousSection authorPrevMsg: msgDelegate.ListView.previousSection
profileClick: profilePopup.setPopupData.bind(profilePopup) profileClick: profilePopup.setPopupData.bind(profilePopup)
messageId: model.messageId messageId: model.messageId
prevMessageIndex: {
// This is used in order to have access to the previous message and determine the timestamp
// we can't rely on the index because the sequence of messages is not ordered on the nim side
if(msgDelegate.DelegateModel.itemsIndex > 0){
return messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index
}
return -1;
}
} }
} }

View File

@ -22,6 +22,7 @@ Item {
property string outgoingStatus: "" property string outgoingStatus: ""
property string responseTo: "" property string responseTo: ""
property string messageId: "" property string messageId: ""
property int prevMessageIndex: -1
property string authorCurrentMsg: "authorCurrentMsg" property string authorCurrentMsg: "authorCurrentMsg"
property string authorPrevMsg: "authorPrevMsg" property string authorPrevMsg: "authorPrevMsg"
@ -32,8 +33,8 @@ Item {
property bool isSticker: contentType === Constants.stickerType property bool isSticker: contentType === Constants.stickerType
property int replyMessageIndex: chatsModel.messageList.getMessageIndex(responseTo); property int replyMessageIndex: chatsModel.messageList.getMessageIndex(responseTo);
property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageList.getReplyData(replyMessageIndex, "userName") : ""; property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "userName") : "";
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageList.getReplyData(replyMessageIndex, "message") : ""; property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "message") : "";
property var profileClick: function () {} property var profileClick: function () {}
@ -43,9 +44,9 @@ Item {
case Constants.chatIdentifier: case Constants.chatIdentifier:
return parent.parent.height - 100 return parent.parent.height - 100
case Constants.stickerType: case Constants.stickerType:
return stickerId.height + 50 return stickerId.height + 50 + (dateGroupLbl.visible ? 50 : 0)
default: default:
return (isCurrentUser || (!isCurrentUser && authorCurrentMsg == authorPrevMsg) ? chatBox.height : 24 + chatBox.height) + 20 return childrenRect.height
} }
} }
@ -186,15 +187,64 @@ Item {
textFormat: Text.RichText textFormat: Text.RichText
} }
StyledText {
id: dateGroupLbl
font.pixelSize: 13
color: Style.current.darkGrey
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
text: {
if (prevMessageIndex == -1) return ""; // identifier
let now = new Date()
let yesterday = new Date()
yesterday.setDate(now.getDate()-1)
let prevMsgTimestamp = chatsModel.messageList.getMessageData(prevMessageIndex, "timestamp")
var currentMsgDate = new Date(parseInt(timestamp, 10));
var prevMsgDate = prevMsgTimestamp === "" ? new Date(0) : new Date(parseInt(prevMsgTimestamp, 10));
if(currentMsgDate.getDay() !== prevMsgDate.getDay()){
if (now.toDateString() === currentMsgDate.toDateString()) {
return qsTr("Today")
} else if (yesterday.toDateString() === currentMsgDate.toDateString()) {
//% "Yesterday"
return qsTrId("yesterday")
} else {
const monthNames = [
qsTr("January"),
qsTr("February"),
qsTr("March"),
qsTr("April"),
qsTr("May"),
qsTr("June"),
qsTr("July"),
qsTr("August"),
qsTr("September"),
qsTr("October"),
qsTr("November"),
qsTr("December")
];
return monthNames[currentMsgDate.getMonth()] + ", " + currentMsgDate.getDay()
}
} else {
return "";
}
}
anchors.top: parent.top
anchors.topMargin: 20
visible: text !== ""
}
// Messages // Messages
Image { Image {
id: chatImage id: chatImage
width: 36 width: 36
height: 36 height: 36
anchors.topMargin: 20
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Style.current.padding anchors.leftMargin: Style.current.padding
anchors.top: parent.top anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.topMargin: 20
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: identicon source: identicon
visible: (isMessage || isEmoji) && authorCurrentMsg != authorPrevMsg && !isCurrentUser visible: (isMessage || isEmoji) && authorCurrentMsg != authorPrevMsg && !isCurrentUser
@ -217,7 +267,7 @@ Item {
id: chatName id: chatName
text: userName text: userName
anchors.leftMargin: 20 anchors.leftMargin: 20
anchors.top: parent.top anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.topMargin: 0 anchors.topMargin: 0
anchors.left: chatImage.right anchors.left: chatImage.right
font.bold: true font.bold: true
@ -260,7 +310,7 @@ Item {
anchors.leftMargin: !isCurrentUser ? 8 : 0 anchors.leftMargin: !isCurrentUser ? 8 : 0
anchors.right: !isCurrentUser ? undefined : parent.right anchors.right: !isCurrentUser ? undefined : parent.right
anchors.rightMargin: !isCurrentUser ? 0 : Style.current.padding anchors.rightMargin: !isCurrentUser ? 0 : Style.current.padding
anchors.top: authorCurrentMsg != authorPrevMsg && !isCurrentUser ? chatImage.top : parent.top anchors.top: authorCurrentMsg != authorPrevMsg && !isCurrentUser ? chatImage.top : (dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top)
anchors.topMargin: 0 anchors.topMargin: 0
visible: isMessage || isEmoji visible: isMessage || isEmoji
@ -397,7 +447,7 @@ Item {
font.pixelSize: 10 font.pixelSize: 10
readOnly: true readOnly: true
selectByMouse: true selectByMouse: true
visible: true visible: (isEmoji || isMessage || isSticker)
} }
@ -415,13 +465,13 @@ Item {
anchors.rightMargin: 5 anchors.rightMargin: 5
font.pixelSize: 10 font.pixelSize: 10
readOnly: true readOnly: true
visible: isCurrentUser visible: isCurrentUser && (isEmoji || isMessage || isSticker)
} }
// This rectangle's only job is to mask the corner to make it less rounded... yep // This rectangle's only job is to mask the corner to make it less rounded... yep
Rectangle { Rectangle {
// TODO find a way to show the corner for stickers since they have a border // TODO find a way to show the corner for stickers since they have a border
visible: !isSticker visible: isMessage || isEmoji
color: chatBox.color color: chatBox.color
width: 18 width: 18
height: 18 height: 18

View File

@ -21,9 +21,9 @@ Rectangle {
let replyMessageIndex = chatsModel.messageList.getMessageIndex(SelectedMessage.messageId); let replyMessageIndex = chatsModel.messageList.getMessageIndex(SelectedMessage.messageId);
if (replyMessageIndex == -1) return; if (replyMessageIndex == -1) return;
userName = chatsModel.messageList.getReplyData(replyMessageIndex, "userName") userName = chatsModel.messageList.getMessageData(replyMessageIndex, "userName")
message = chatsModel.messageList.getReplyData(replyMessageIndex, "message") message = chatsModel.messageList.getMessageData(replyMessageIndex, "message")
identicon = chatsModel.messageList.getReplyData(replyMessageIndex, "identicon") identicon = chatsModel.messageList.getMessageData(replyMessageIndex, "identicon")
} }
function reset(){ function reset(){

1
vendor/edn.nim vendored Submodule

@ -0,0 +1 @@
Subproject commit 4cda60880e108f0cb7efe1c209308f2db03267d9