Capitalization, list model and room header work
- Standardized capitalization for variables and file names everywhere in QML and JS, get rid of mixed camelCase/snakeCase, use camelCase like everywhere in Qt - ListModel items are now stored and returned as real QObjects with PyQt properties and signals. This makes dynamic property binding a lot easier and eliminates the need for many hacks. - New update(), updateOrAppendWhere() methods and roles property for ListModel - RoomHeader now properly updates when the room title or topic changes - Add Backend.pdb(), to make it easier to start the debugger from QML
This commit is contained in:
@@ -2,12 +2,13 @@ import QtQuick 2.7
|
||||
import "../base" as Base
|
||||
|
||||
Base.HLabel {
|
||||
text: date_time.toLocaleDateString()
|
||||
width: messageDelegate.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
topPadding: messageDelegate.isFirstMessage ?
|
||||
0 : messageDelegate.standardSpacing
|
||||
bottomPadding: messageDelegate.standardSpacing
|
||||
|
||||
text: dateTime.toLocaleDateString()
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: normalSize * 1.1
|
||||
color: "darkolivegreen"
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ RowLayout {
|
||||
anchors.right: isOwn ? parent.right : undefined
|
||||
|
||||
readonly property string contentText:
|
||||
isMessage ? "" : ChatJS.get_event_text(type, dict)
|
||||
isMessage ? "" : ChatJS.getEventText(type, dict)
|
||||
|
||||
Base.Avatar {
|
||||
id: avatar
|
||||
@@ -26,7 +26,7 @@ RowLayout {
|
||||
(isUndecryptableEvent ? "darkred" : "gray") + "'>" +
|
||||
(displayName.value || dict.sender) + " " + contentText +
|
||||
" <font size=" + smallSize + "px color='gray'>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
Qt.formatDateTime(dateTime, "hh:mm:ss") +
|
||||
"</font></font>"
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
|
@@ -32,19 +32,13 @@ Row {
|
||||
|
||||
Base.RichLabel {
|
||||
id: contentLabel
|
||||
//text: (isOwn ? "" : content + " ") +
|
||||
//"<font size=" + smallSize + "px color=gray>" +
|
||||
//Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
//"</font>" +
|
||||
// (isOwn ? " " + content : "")
|
||||
//
|
||||
text: (dict.formatted_body ?
|
||||
Backend.htmlFilter.filter(dict.formatted_body) :
|
||||
dict.body) +
|
||||
" <font size=" + smallSize + "px color=gray>" +
|
||||
Qt.formatDateTime(date_time, "hh:mm:ss") +
|
||||
Qt.formatDateTime(dateTime, "hh:mm:ss") +
|
||||
"</font>" +
|
||||
(is_local_echo ?
|
||||
(isLocalEcho ?
|
||||
" <font size=" + smallSize + "px>⏳</font>" : "")
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
|
@@ -7,22 +7,22 @@ import "utils.js" as ChatJS
|
||||
Column {
|
||||
id: "messageDelegate"
|
||||
|
||||
function mins_between(date1, date2) {
|
||||
function minsBetween(date1, date2) {
|
||||
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
|
||||
}
|
||||
|
||||
function is_message(type_) { return type_.startsWith("RoomMessage") }
|
||||
function getIsMessage(type_) { return type_.startsWith("RoomMessage") }
|
||||
|
||||
function get_previous_item() {
|
||||
function getPreviousItem() {
|
||||
return index < messageListView.model.count - 1 ?
|
||||
messageListView.model.get(index + 1) : null
|
||||
}
|
||||
|
||||
property var previousItem: get_previous_item()
|
||||
property var previousItem: getPreviousItem()
|
||||
signal reloadPreviousItem()
|
||||
onReloadPreviousItem: previousItem = get_previous_item()
|
||||
onReloadPreviousItem: previousItem = getPreviousItem()
|
||||
|
||||
readonly property bool isMessage: is_message(type)
|
||||
readonly property bool isMessage: getIsMessage(type)
|
||||
|
||||
readonly property bool isUndecryptableEvent:
|
||||
type === "OlmEvent" || type === "MegolmEvent"
|
||||
@@ -31,7 +31,7 @@ Column {
|
||||
Backend.getUserDisplayName(dict.sender)
|
||||
|
||||
readonly property bool isOwn:
|
||||
chatPage.user_id === dict.sender
|
||||
chatPage.userId === dict.sender
|
||||
|
||||
readonly property bool isFirstEvent: type == "RoomCreateEvent"
|
||||
|
||||
@@ -39,19 +39,19 @@ Column {
|
||||
previousItem &&
|
||||
! talkBreak &&
|
||||
! dayBreak &&
|
||||
is_message(previousItem.type) === isMessage &&
|
||||
getIsMessage(previousItem.type) === isMessage &&
|
||||
previousItem.dict.sender === dict.sender &&
|
||||
mins_between(previousItem.date_time, date_time) <= 5
|
||||
minsBetween(previousItem.dateTime, dateTime) <= 5
|
||||
|
||||
readonly property bool dayBreak:
|
||||
isFirstEvent ||
|
||||
previousItem &&
|
||||
date_time.getDay() != previousItem.date_time.getDay()
|
||||
dateTime.getDay() != previousItem.dateTime.getDay()
|
||||
|
||||
readonly property bool talkBreak:
|
||||
previousItem &&
|
||||
! dayBreak &&
|
||||
mins_between(previousItem.date_time, date_time) >= 20
|
||||
minsBetween(previousItem.dateTime, dateTime) >= 20
|
||||
|
||||
|
||||
property int standardSpacing: 16
|
||||
@@ -59,8 +59,8 @@ Column {
|
||||
property int verticalPadding: 5
|
||||
|
||||
ListView.onAdd: {
|
||||
var next_delegate = messageListView.contentItem.children[index]
|
||||
if (next_delegate) { next_delegate.reloadPreviousItem() }
|
||||
var nextDelegate = messageListView.contentItem.children[index]
|
||||
if (nextDelegate) { nextDelegate.reloadPreviousItem() }
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
|
@@ -14,8 +14,7 @@ Rectangle {
|
||||
id: messageListView
|
||||
anchors.fill: parent
|
||||
delegate: MessageDelegate {}
|
||||
model: Backend.models.roomEvents.get(chatPage.room.room_id)
|
||||
//highlight: Rectangle {color: "lightsteelblue"; radius: 5}
|
||||
model: Backend.models.roomEvents.get(chatPage.roomId)
|
||||
|
||||
clip: true
|
||||
topMargin: space
|
||||
@@ -31,7 +30,7 @@ Rectangle {
|
||||
|
||||
onYPosChanged: {
|
||||
if (yPos <= 0.1) {
|
||||
Backend.loadPastEvents(chatPage.room.room_id)
|
||||
Backend.loadPastEvents(chatPage.roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,10 @@ import QtQuick.Layouts 1.4
|
||||
import "../base" as Base
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
property string displayName: ""
|
||||
property string topic: ""
|
||||
|
||||
id: "root"
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 36
|
||||
Layout.maximumHeight: Layout.minimumHeight
|
||||
@@ -19,21 +22,23 @@ Rectangle {
|
||||
id: "avatar"
|
||||
Layout.alignment: Qt.AlignTop
|
||||
dimmension: root.Layout.minimumHeight
|
||||
name: chatPage.room.display_name
|
||||
name: displayName
|
||||
}
|
||||
|
||||
Base.HLabel {
|
||||
id: "roomName"
|
||||
text: chatPage.room.display_name
|
||||
text: displayName
|
||||
font.pixelSize: bigSize
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth: row.width - row.spacing * (row.children.length - 1) - avatar.width
|
||||
Layout.maximumWidth:
|
||||
row.width - row.spacing * (row.children.length - 1) -
|
||||
avatar.width
|
||||
}
|
||||
|
||||
Base.HLabel {
|
||||
id: "roomDescription"
|
||||
text: chatPage.room.description || ""
|
||||
id: "roomTopic"
|
||||
text: topic
|
||||
font.pixelSize: smallSize
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
|
@@ -3,16 +3,23 @@ import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
|
||||
ColumnLayout {
|
||||
property var user_id: null
|
||||
property var room: null
|
||||
property var userId: null
|
||||
property var roomId: null
|
||||
|
||||
property var roomInfo:
|
||||
Backend.models.rooms.get(userId).getWhere("roomId", roomId)
|
||||
|
||||
id: chatPage
|
||||
id: "chatPage"
|
||||
spacing: 0
|
||||
onFocusChanged: sendBox.setFocus()
|
||||
|
||||
RoomHeader {}
|
||||
RoomHeader {
|
||||
id: "roomHeader"
|
||||
displayName: roomInfo.displayName
|
||||
topic: roomInfo.topic
|
||||
}
|
||||
|
||||
MessageList {}
|
||||
TypingUsersBar {}
|
||||
SendBox { id: sendBox }
|
||||
SendBox { id: "sendBox" }
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ Rectangle {
|
||||
|
||||
Base.Avatar {
|
||||
id: "avatar"
|
||||
name: Backend.getUserDisplayName(chatPage.user_id)
|
||||
name: Backend.getUserDisplayName(chatPage.userId)
|
||||
dimmension: root.Layout.minimumHeight
|
||||
//visible: textArea.text === ""
|
||||
visible: textArea.height <= root.Layout.minimumHeight
|
||||
@@ -43,13 +43,13 @@ Rectangle {
|
||||
font.pixelSize: 16
|
||||
focus: true
|
||||
|
||||
function set_typing(typing) {
|
||||
Backend.clientManager.clients[chatPage.user_id]
|
||||
.setTypingState(chatPage.room.room_id, typing)
|
||||
function setTyping(typing) {
|
||||
Backend.clientManager.clients[chatPage.userId]
|
||||
.setTypingState(chatPage.roomId, typing)
|
||||
}
|
||||
|
||||
onTypedTextChanged: set_typing(Boolean(text))
|
||||
onEditingFinished: set_typing(false) // when lost focus
|
||||
onTypedTextChanged: setTyping(Boolean(text))
|
||||
onEditingFinished: setTyping(false) // when lost focus
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
event.accepted = true
|
||||
@@ -62,8 +62,8 @@ Rectangle {
|
||||
}
|
||||
|
||||
if (textArea.text === "") { return }
|
||||
Backend.clientManager.clients[chatPage.user_id]
|
||||
.sendMarkdown(chatPage.room.room_id, textArea.text)
|
||||
Backend.clientManager.clients[chatPage.userId]
|
||||
.sendMarkdown(chatPage.roomId, textArea.text)
|
||||
textArea.clear()
|
||||
}
|
||||
|
||||
|
@@ -11,19 +11,12 @@ Rectangle {
|
||||
Layout.maximumHeight: Layout.minimumHeight
|
||||
color: "#BBB"
|
||||
|
||||
property var typingUsers: chatPage.roomInfo.typingUsers
|
||||
|
||||
Base.HLabel {
|
||||
id: "usersLabel"
|
||||
anchors.fill: parent
|
||||
|
||||
Timer {
|
||||
interval: 500
|
||||
repeat: true
|
||||
running: true
|
||||
triggeredOnStart: true
|
||||
onTriggered: usersLabel.text = ChatJS.get_typing_users_text(
|
||||
chatPage.user_id, chatPage.room.room_id
|
||||
)
|
||||
}
|
||||
text: ChatJS.getTypingUsersText(typingUsers, chatPage.userId)
|
||||
|
||||
elide: Text.ElideMiddle
|
||||
maximumLineCount: 1
|
||||
|
@@ -1,4 +1,4 @@
|
||||
function get_event_text(type, dict) {
|
||||
function getEventText(type, dict) {
|
||||
switch (type) {
|
||||
case "RoomCreateEvent":
|
||||
return (dict.federate ? "allowed" : "blocked") +
|
||||
@@ -18,14 +18,14 @@ function get_event_text(type, dict) {
|
||||
break
|
||||
|
||||
case "RoomHistoryVisibilityEvent":
|
||||
return get_history_visibility_event_text(dict)
|
||||
return getHistoryVisibilityEventText(dict)
|
||||
break
|
||||
|
||||
case "PowerLevelsEvent":
|
||||
return "changed the room's permissions."
|
||||
|
||||
case "RoomMemberEvent":
|
||||
return get_member_event_text(dict)
|
||||
return getMemberEventText(dict)
|
||||
break
|
||||
|
||||
case "RoomAliasEvent":
|
||||
@@ -58,7 +58,7 @@ function get_event_text(type, dict) {
|
||||
}
|
||||
|
||||
|
||||
function get_history_visibility_event_text(dict) {
|
||||
function getHistoryVisibilityEventText(dict) {
|
||||
switch (dict.history_visibility) {
|
||||
case "shared":
|
||||
var end = "all room members."
|
||||
@@ -81,7 +81,7 @@ function get_history_visibility_event_text(dict) {
|
||||
}
|
||||
|
||||
|
||||
function get_member_event_text(dict) {
|
||||
function getMemberEventText(dict) {
|
||||
var info = dict.content, prev = dict.prev_content
|
||||
|
||||
if (! prev || (info.membership != prev.membership)) {
|
||||
@@ -127,15 +127,12 @@ function get_member_event_text(dict) {
|
||||
}
|
||||
|
||||
|
||||
function get_typing_users_text(account_id, room_id) {
|
||||
function getTypingUsersText(users, ourAccountId) {
|
||||
var names = []
|
||||
var room = Backend.models.rooms.get(account_id)
|
||||
.getWhere("room_id", room_id)
|
||||
|
||||
for (var i = 0; i < room.typing_users.length; i++) {
|
||||
if (room.typing_users[i] !== account_id) {
|
||||
names.push(Backend.getUserDisplayName(room.typing_users[i], false)
|
||||
.result())
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
if (users[i] !== ourAccountId) {
|
||||
names.push(Backend.getUserDisplayName(users[i], false).result())
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user