Display room messages and other events
This commit is contained in:
45
harmonyqml/components/chat/EventContent.qml
Normal file
45
harmonyqml/components/chat/EventContent.qml
Normal file
@@ -0,0 +1,45 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.4
|
||||
import "../base" as Base
|
||||
import "get_event_text.js" as GetEventTextJS
|
||||
|
||||
Row {
|
||||
id: row
|
||||
spacing: standardSpacing
|
||||
layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight
|
||||
anchors.right: isOwn ? parent.right : undefined
|
||||
|
||||
readonly property string contentText:
|
||||
(isMessage || isUndecryptableEvent) ?
|
||||
"" :
|
||||
GetEventTextJS.get_event_text(type, dict)
|
||||
|
||||
Base.Avatar {
|
||||
id: avatar
|
||||
name: displayName
|
||||
invisible: combine
|
||||
dimmension: 28
|
||||
}
|
||||
|
||||
Base.HLabel {
|
||||
id: contentLabel
|
||||
text: "<font color=gray>" +
|
||||
displayName + " " + contentText +
|
||||
" <font size=" + smallSize + "px>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
"</font></font>"
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
leftPadding: horizontalPadding
|
||||
rightPadding: horizontalPadding
|
||||
topPadding: verticalPadding
|
||||
bottomPadding: verticalPadding
|
||||
|
||||
Layout.maximumWidth: Math.min(
|
||||
600, messageListView.width - avatar.width - row.spacing
|
||||
)
|
||||
}
|
||||
}
|
61
harmonyqml/components/chat/MessageContent.qml
Normal file
61
harmonyqml/components/chat/MessageContent.qml
Normal file
@@ -0,0 +1,61 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.4
|
||||
import "../base" as Base
|
||||
|
||||
Row {
|
||||
id: row
|
||||
spacing: standardSpacing
|
||||
layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight
|
||||
anchors.right: isOwn ? parent.right : undefined
|
||||
|
||||
Base.Avatar { id: avatar; invisible: combine; name: displayName }
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
Base.HLabel {
|
||||
visible: ! combine
|
||||
id: nameLabel
|
||||
text: displayName
|
||||
background: Rectangle {color: "#DDD"}
|
||||
color: isOwn ? "teal" : "purple"
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.preferredWidth: contentLabel.width
|
||||
horizontalAlignment: isOwn ? Text.AlignRight : Text.AlignLeft
|
||||
|
||||
leftPadding: horizontalPadding
|
||||
rightPadding: horizontalPadding
|
||||
topPadding: verticalPadding
|
||||
}
|
||||
|
||||
Base.HLabel {
|
||||
id: contentLabel
|
||||
//text: (isOwn ? "" : content + " ") +
|
||||
//"<font size=" + smallSize + "px color=gray>" +
|
||||
//Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
//"</font>" +
|
||||
// (isOwn ? " " + content : "")
|
||||
|
||||
text: (isUndecryptableEvent ?
|
||||
"<font color=darkred>Missing decryption keys for this message.</font>" :
|
||||
dict.formatted_body || dict.body) +
|
||||
" <font size=" + smallSize + "px color=gray>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
"</font>"
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
leftPadding: horizontalPadding
|
||||
rightPadding: horizontalPadding
|
||||
bottomPadding: verticalPadding
|
||||
|
||||
Layout.minimumWidth: nameLabel.implicitWidth
|
||||
Layout.maximumWidth: Math.min(
|
||||
600, messageListView.width - avatar.width - row.spacing
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,11 +10,16 @@ Column {
|
||||
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
|
||||
}
|
||||
|
||||
readonly property bool isMessage: type.startsWith("RoomMessage")
|
||||
|
||||
readonly property bool isUndecryptableEvent:
|
||||
type === "OlmEvent" || type === "MegolmEvent"
|
||||
|
||||
readonly property string displayName:
|
||||
Backend.getUser(chatPage.room.room_id, sender_id).display_name
|
||||
Backend.getUser(dict.sender).display_name
|
||||
|
||||
readonly property bool isOwn:
|
||||
chatPage.user.user_id === sender_id
|
||||
chatPage.user_id === dict.sender
|
||||
|
||||
readonly property var previousData:
|
||||
index > 0 ? messageListView.model.get(index - 1) : null
|
||||
@@ -23,7 +28,8 @@ Column {
|
||||
|
||||
readonly property bool combine:
|
||||
! isFirstMessage &&
|
||||
previousData.sender_id == sender_id &&
|
||||
previousData.isMessage === isMessage &&
|
||||
previousData.dict.sender === dict.sender &&
|
||||
mins_between(previousData.date_time, date_time) <= 5
|
||||
|
||||
readonly property bool dayBreak:
|
||||
@@ -49,59 +55,7 @@ Column {
|
||||
|
||||
Daybreak { visible: dayBreak }
|
||||
|
||||
MessageContent { visible: isMessage || isUndecryptableEvent }
|
||||
|
||||
Row {
|
||||
id: row
|
||||
spacing: standardSpacing
|
||||
layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight
|
||||
anchors.right: isOwn ? parent.right : undefined
|
||||
|
||||
Base.Avatar { id: avatar; invisible: combine; name: displayName }
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
Base.HLabel {
|
||||
visible: ! combine
|
||||
id: nameLabel
|
||||
text: displayName
|
||||
background: Rectangle {color: "#DDD"}
|
||||
color: isOwn ? "teal" : "purple"
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.preferredWidth: contentLabel.width
|
||||
horizontalAlignment: isOwn ? Text.AlignRight : Text.AlignLeft
|
||||
|
||||
leftPadding: horizontalPadding
|
||||
rightPadding: horizontalPadding
|
||||
topPadding: verticalPadding
|
||||
}
|
||||
|
||||
Base.HLabel {
|
||||
id: contentLabel
|
||||
//text: (isOwn ? "" : content + " ") +
|
||||
//"<font size=" + smallSize + "px color=gray>" +
|
||||
//Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
//"</font>" +
|
||||
// (isOwn ? " " + content : "")
|
||||
|
||||
text: content +
|
||||
" <font size=" + smallSize + "px color=gray>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
"</font>"
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
leftPadding: horizontalPadding
|
||||
rightPadding: horizontalPadding
|
||||
bottomPadding: verticalPadding
|
||||
|
||||
Layout.minimumWidth: nameLabel.implicitWidth
|
||||
Layout.maximumWidth: Math.min(
|
||||
600, messageListView.width - avatar.width - row.spacing
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
EventContent { visible: ! (isMessage || isUndecryptableEvent) }
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ Rectangle {
|
||||
ListView {
|
||||
id: messageListView
|
||||
anchors.fill: parent
|
||||
model: Backend.models.messages.get(chatPage.room.room_id)
|
||||
model: Backend.models.roomEvents.get(chatPage.room.room_id)
|
||||
delegate: MessageDelegate {}
|
||||
//highlight: Rectangle {color: "lightsteelblue"; radius: 5}
|
||||
|
||||
|
@@ -33,7 +33,7 @@ Rectangle {
|
||||
|
||||
Base.HLabel {
|
||||
id: "roomDescription"
|
||||
text: chatPage.room.description
|
||||
text: chatPage.room.description || ""
|
||||
font.pixelSize: smallSize
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
|
@@ -3,7 +3,7 @@ import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
|
||||
ColumnLayout {
|
||||
property var user: null
|
||||
property var user_id: null
|
||||
property var room: null
|
||||
|
||||
id: chatPage
|
||||
|
@@ -20,7 +20,7 @@ Rectangle {
|
||||
|
||||
Base.Avatar {
|
||||
id: "avatar"
|
||||
name: chatPage.user.display_name
|
||||
name: Backend.getUser(chatPage.user_id).display_name
|
||||
dimmension: root.Layout.minimumHeight
|
||||
//visible: textArea.text === ""
|
||||
visible: textArea.height <= root.Layout.minimumHeight
|
||||
|
122
harmonyqml/components/chat/get_event_text.js
Normal file
122
harmonyqml/components/chat/get_event_text.js
Normal file
@@ -0,0 +1,122 @@
|
||||
function get_event_text(type, dict) {
|
||||
switch (type) {
|
||||
case "RoomCreateEvent":
|
||||
return (dict.federate ? "allowed" : "blocked") +
|
||||
" users on other matrix servers " +
|
||||
(dict.federate ? "to join" : "from joining") +
|
||||
" this room."
|
||||
break
|
||||
|
||||
case "RoomGuestAccessEvent":
|
||||
return (dict.guest_access === "can_join" ? "allowed " : "forbad") +
|
||||
"guests to join the room."
|
||||
break
|
||||
|
||||
case "RoomJoinRulesEvent":
|
||||
return "made the room " +
|
||||
(dict.join_rule === "public." ? "public" : "invite only.")
|
||||
break
|
||||
|
||||
case "RoomHistoryVisibilityEvent":
|
||||
return get_history_visibility_event_text(dict)
|
||||
break
|
||||
|
||||
case "PowerLevelsEvent":
|
||||
return "changed the room's permissions."
|
||||
|
||||
case "RoomMemberEvent":
|
||||
return get_member_event_text(dict)
|
||||
break
|
||||
|
||||
case "RoomAliasEvent":
|
||||
return "set the room's main address to " +
|
||||
dict.canonical_alias + "."
|
||||
break
|
||||
|
||||
case "RoomNameEvent":
|
||||
return "changed the room's name to \"" + dict.name + "\"."
|
||||
break
|
||||
|
||||
case "RoomTopicEvent":
|
||||
return "changed the room's topic to \"" + dict.topic + "\"."
|
||||
break
|
||||
|
||||
case "RoomEncryptionEvent":
|
||||
return "turned on encryption for this room."
|
||||
break
|
||||
|
||||
default:
|
||||
console.log(type + "\n" + JSON.stringify(dict, null, 4) + "\n")
|
||||
return "did something this client does not understand."
|
||||
|
||||
//case "CallEvent": TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_history_visibility_event_text(dict) {
|
||||
switch (dict.history_visibility) {
|
||||
case "shared":
|
||||
var end = "all room members."
|
||||
break
|
||||
|
||||
case "world_readable":
|
||||
var end = "any member or outsider."
|
||||
break
|
||||
|
||||
case "joined":
|
||||
var end = "all room members since they joined."
|
||||
break
|
||||
|
||||
case "invited":
|
||||
var end = "all room members since they were invited."
|
||||
break
|
||||
}
|
||||
|
||||
return "made future history visible to " + end
|
||||
}
|
||||
|
||||
|
||||
function get_member_event_text(dict) {
|
||||
var info = dict.content, prev = dict.prev_content
|
||||
|
||||
if (! prev || (info.membership != prev.membership)) {
|
||||
switch (info.membership) {
|
||||
case "join":
|
||||
return "joined the room."
|
||||
break
|
||||
|
||||
case "invite":
|
||||
var name = Backend.getUser(dict.state_key).display_name
|
||||
var name = name === dict.state_key ? info.displayname : name
|
||||
return "invited " + name + " to the room."
|
||||
break
|
||||
|
||||
case "leave":
|
||||
return "left the room."
|
||||
break
|
||||
|
||||
case "ban":
|
||||
return "was banned from the room."
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var changed = []
|
||||
|
||||
if (prev && (info.avatar_url != prev.avatar_url)) {
|
||||
changed.push("profile picture")
|
||||
}
|
||||
|
||||
if (prev && (info.displayname != prev.displayname)) {
|
||||
changed.push("display name from \"" +
|
||||
(prev.displayname || dict.state_key) + '" to "' +
|
||||
(info.displayname || dict.state_key) + '"')
|
||||
}
|
||||
|
||||
if (changed.length > 0) {
|
||||
return "changed their " + changed.join(" and ") + "."
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
Reference in New Issue
Block a user