diff --git a/TODO.md b/TODO.md index cbabb1cf..64254cdb 100644 --- a/TODO.md +++ b/TODO.md @@ -6,6 +6,7 @@ - Better names and organization for the Message components - Bug fixes + - 100% CPU usage when hitting top edge to trigger messages loading - Fix tooltip hide() - Sending `![A picture](https://picsum.photos/256/256)` → not clickable? - Icons aren't reloaded @@ -13,7 +14,10 @@ - HStyle singleton isn't reloaded - UI + - Server selection - Register/Forgot? for SignIn dialog + - Scaling + - See [Text.fontSizeMode](https://doc.qt.io/qt-5/qml-qtquick-text.html#fontSizeMode-prop) - Test HGlassRectangle elements when no effects are available - Leave room - Forget room warning popup diff --git a/harmonyqml/components/base/Avatar.qml b/harmonyqml/components/base/Avatar.qml index 3fd581d6..310799df 100644 --- a/harmonyqml/components/base/Avatar.qml +++ b/harmonyqml/components/base/Avatar.qml @@ -1,6 +1,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.4 +import "../base" as Base Item { property bool invisible: false @@ -22,13 +23,18 @@ Item { anchors.fill: parent visible: ! invisible && imageSource === null color: resolvedName === "?" ? - Qt.hsla(0, 0, 0.22, 1) : - Qt.hsla(Backend.hueFromString(resolvedName), 0.22, 0.5, 1) + Base.HStyle.avatar.background.unknown : + Qt.hsla( + Backend.hueFromString(resolvedName), + Base.HStyle.avatar.background.saturation, + Base.HStyle.avatar.background.lightness, + Base.HStyle.avatar.background.alpha + ) HLabel { anchors.centerIn: parent text: resolvedName.charAt(0) - color: "white" + color: Base.HStyle.avatar.letter font.pixelSize: letterRectangle.height / 1.4 } } diff --git a/harmonyqml/components/base/HGlassRectangle.qml b/harmonyqml/components/base/HGlassRectangle.qml index c686e7a7..72ecd152 100644 --- a/harmonyqml/components/base/HGlassRectangle.qml +++ b/harmonyqml/components/base/HGlassRectangle.qml @@ -2,6 +2,8 @@ import QtQuick 2.7 import QtGraphicalEffects 1.0 Item { + property bool isPageStackDescendant: true + default property alias children: rectangle.children property alias color: rectangle.color property alias gradient: rectangle.gradient @@ -14,16 +16,18 @@ Item { sourceItem: mainUIBackground anchors.fill: parent sourceRect: Qt.rect( - pageStack.x + parent.x, pageStack.y + parent.y, width, height + (isPageStackDescendant ? pageStack.x : 0) + parent.x, + (isPageStackDescendant ? pageStack.y : 0) + parent.y, + width, + height ) } FastBlur { id: fastBlur - cached: true anchors.fill: effectSource source: effectSource - radius: 8 + radius: rectangle.color == "#00000000" ? 0 : 8 } Rectangle { diff --git a/harmonyqml/components/base/HNoticeLabel.qml b/harmonyqml/components/base/HNoticeLabel.qml new file mode 100644 index 00000000..ba8a759f --- /dev/null +++ b/harmonyqml/components/base/HNoticeLabel.qml @@ -0,0 +1,31 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.4 +import "../base" as Base + +Base.HRowLayout { + property alias text: noticeLabel.text + property alias color: noticeLabel.color + property alias font: noticeLabel.font + property alias backgroundColor: noticeLabelBackground.color + property alias radius: noticeLabelBackground.radius + + Base.HLabel { + id: noticeLabel + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + padding: 3 + leftPadding: 10 + rightPadding: 10 + + Layout.margins: 10 + Layout.alignment: Qt.AlignCenter + Layout.maximumWidth: parent.width - Layout.margins * 2 + + background: Rectangle { + id: noticeLabelBackground + color: Base.HStyle.box.background + radius: Base.HStyle.box.radius + } + } +} diff --git a/harmonyqml/components/base/HScalingBox.qml b/harmonyqml/components/base/HScalingBox.qml index 6248d8c0..cb4f02bc 100644 --- a/harmonyqml/components/base/HScalingBox.qml +++ b/harmonyqml/components/base/HScalingBox.qml @@ -8,7 +8,7 @@ HGlassRectangle { readonly property int baseWidth: baseHeight * widthForHeight readonly property int margins: baseHeight * 0.03 - color: HStyle.boxes.background + color: HStyle.box.background height: Math.min(parent.height, baseHeight) width: Math.min(parent.width, baseWidth) scale: Math.max(1, parent.height / startScalingUpAboveHeight) diff --git a/harmonyqml/components/base/HStyle.qml b/harmonyqml/components/base/HStyle.qml index fabf91f4..bd065d2c 100644 --- a/harmonyqml/components/base/HStyle.qml +++ b/harmonyqml/components/base/HStyle.qml @@ -2,6 +2,8 @@ pragma Singleton import QtQuick 2.7 QtObject { + id: style + readonly property QtObject fontSize: QtObject { property int smallest: 6 property int smaller: 8 @@ -19,19 +21,78 @@ QtObject { } readonly property QtObject colors: QtObject { - property color background0: Qt.hsla(1, 1, 1, 0.4) + property color background0: Qt.hsla(0, 0, 0.8, 0.7) + property color foreground: "black" + property color foregroundDim: Qt.hsla(0, 0, 0.2, 1) + property color foregroundError: Qt.hsla(0.95, 0.64, 0.32, 1) } + property int radius: 5 + readonly property QtObject sidePane: QtObject { property color background: colors.background0 } - readonly property QtObject boxes: QtObject { - property color background: colors.background0 - property int radius: 5 + readonly property QtObject chat: QtObject { + readonly property QtObject roomHeader: QtObject { + property color background: colors.background0 + } + + readonly property QtObject messageList: QtObject { + property color background: colors.background0 + } + + readonly property QtObject message: QtObject { + property color background: colors.background0 + property color body: colors.foreground + property color date: colors.foregroundDim + } + + readonly property QtObject event: QtObject { + property color background: colors.background0 + property real saturation: 0.22 + property real lightness: 0.24 + property color date: colors.foregroundDim + } + + readonly property QtObject daybreak: QtObject { + property color background: colors.background0 + property color foreground: colors.foreground + property int radius: style.radius + } + + readonly property QtObject inviteBanner: QtObject { + property color background: colors.background0 + } + + readonly property QtObject leftBanner: QtObject { + property color background: colors.background0 + } + + readonly property QtObject sendBox: QtObject { + property color background: colors.background0 + } } - readonly property QtObject avatars: QtObject { - property int radius: 5 + readonly property QtObject box: QtObject { + property color background: colors.background0 + property int radius: style.radius + } + + readonly property QtObject avatar: QtObject { + property int radius: style.radius + property color letter: "white" + + readonly property QtObject background: QtObject { + property real saturation: 0.22 + property real lightness: 0.5 + property real alpha: 1 + property color unknown: Qt.hsla(0, 0, 0.22, 1) + } + } + + readonly property QtObject displayName: QtObject { + property real saturation: 0.32 + property real lightness: 0.3 } } diff --git a/harmonyqml/components/chat/Banner.qml b/harmonyqml/components/chat/Banner.qml index 9147d469..db469a0e 100644 --- a/harmonyqml/components/chat/Banner.qml +++ b/harmonyqml/components/chat/Banner.qml @@ -3,11 +3,10 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.4 import "../base" as Base -Rectangle { +Base.HGlassRectangle { id: banner Layout.fillWidth: true Layout.preferredHeight: 32 - color: "#BBB" signal buttonClicked(string signalId) diff --git a/harmonyqml/components/chat/Daybreak.qml b/harmonyqml/components/chat/Daybreak.qml index baa85e2c..867f3eff 100644 --- a/harmonyqml/components/chat/Daybreak.qml +++ b/harmonyqml/components/chat/Daybreak.qml @@ -1,21 +1,14 @@ import QtQuick 2.7 import "../base" as Base -Base.HLabel { - property bool isToday: { - const today = new Date() - return dateTime.getDate() == today.getDate() && - dateTime.getMonth() == today.getMonth() && - dateTime.getFullYear() == today.getFullYear() - } +Base.HNoticeLabel { + text: dateTime.toLocaleDateString() + color: Base.HStyle.chat.daybreak.foreground + backgroundColor: Base.HStyle.chat.daybreak.background + radius: Base.HStyle.chat.daybreak.radius width: messageDelegate.width - topPadding: messageDelegate.isFirstMessage ? - 0 : messageDelegate.standardSpacing - bottomPadding: messageDelegate.standardSpacing - - text: dateTime.toLocaleDateString() + (isToday ? qsTr(" (Today)") : "") - horizontalAlignment: Text.AlignHCenter - font.pixelSize: Base.HStyle.fontSize.big - color: "darkolivegreen" + //topPadding: messageDelegate.isFirstMessage ? + //0 : messageDelegate.standardSpacing + //bottomPadding: messageDelegate.standardSpacing } diff --git a/harmonyqml/components/chat/EventContent.qml b/harmonyqml/components/chat/EventContent.qml index e8e6d82b..e57cab48 100644 --- a/harmonyqml/components/chat/EventContent.qml +++ b/harmonyqml/components/chat/EventContent.qml @@ -23,16 +23,23 @@ RowLayout { Base.HLabel { id: contentLabel text: "" + - (displayName.value || dict.sender) + - (contentText.startsWith("'s ") ? "" : " ") + + Qt.hsla(Backend.hueFromString(displayName.value || dict.sender), + Base.HStyle.chat.event.saturation, + Base.HStyle.chat.event.lightness, + 1) + + "'>" + + (displayName.value || dict.sender) + " " + contentText + - "  " + + + "  " + + "" + Qt.formatDateTime(dateTime, "hh:mm:ss") + - "" + " " + + "" + textFormat: Text.RichText - background: Rectangle {color: "#DDD"} + background: Rectangle {color: Base.HStyle.chat.event.background} wrapMode: Text.Wrap leftPadding: horizontalPadding diff --git a/harmonyqml/components/chat/InviteBanner.qml b/harmonyqml/components/chat/InviteBanner.qml index 7f952950..b61d204e 100644 --- a/harmonyqml/components/chat/InviteBanner.qml +++ b/harmonyqml/components/chat/InviteBanner.qml @@ -6,6 +6,8 @@ import "../base" as Base Banner { property var inviter: null + color: Base.HStyle.chat.inviteBanner.background + avatarName: inviter ? inviter.displayname : "" //avatarSource: inviter ? inviter.avatar_url : "" diff --git a/harmonyqml/components/chat/LeftBanner.qml b/harmonyqml/components/chat/LeftBanner.qml index b4aace11..02822d38 100644 --- a/harmonyqml/components/chat/LeftBanner.qml +++ b/harmonyqml/components/chat/LeftBanner.qml @@ -7,6 +7,8 @@ import "utils.js" as ChatJS Banner { property var leftEvent: null + color: Base.HStyle.chat.leftBanner.background + onButtonClicked: if (signalId === "forget") { chatPage.canLoadPastEvents = false pageStack.clear() diff --git a/harmonyqml/components/chat/MessageContent.qml b/harmonyqml/components/chat/MessageContent.qml index f59304a0..2ac9d182 100644 --- a/harmonyqml/components/chat/MessageContent.qml +++ b/harmonyqml/components/chat/MessageContent.qml @@ -18,8 +18,11 @@ Row { visible: ! combine id: nameLabel text: displayName.value || dict.sender - background: Rectangle {color: "#DDD"} - color: Qt.hsla(Backend.hueFromString(text), 0.22, 0.4, 1) + background: Rectangle {color: Base.HStyle.chat.message.background} + color: Qt.hsla(Backend.hueFromString(text), + Base.HStyle.displayName.saturation, + Base.HStyle.displayName.lightness, + 1) elide: Text.ElideRight maximumLineCount: 1 Layout.preferredWidth: contentLabel.width @@ -36,14 +39,15 @@ Row { Backend.htmlFilter.filter(dict.formatted_body) : dict.body) + "  " + + "px color=" + Base.HStyle.chat.message.date + ">" + Qt.formatDateTime(dateTime, "hh:mm:ss") + "" + (isLocalEcho ? " " : "") textFormat: Text.RichText - background: Rectangle {color: "#DDD"} + background: Rectangle {color: Base.HStyle.chat.message.background} + color: Base.HStyle.chat.message.body wrapMode: Text.Wrap leftPadding: horizontalPadding diff --git a/harmonyqml/components/chat/MessageDelegate.qml b/harmonyqml/components/chat/MessageDelegate.qml index f38a1100..7789baef 100644 --- a/harmonyqml/components/chat/MessageDelegate.qml +++ b/harmonyqml/components/chat/MessageDelegate.qml @@ -67,12 +67,19 @@ Column { topPadding: isFirstEvent ? 0 : + dayBreak ? standardSpacing * 2 : talkBreak ? standardSpacing * 3 : combine ? standardSpacing / 4 : standardSpacing Daybreak { visible: dayBreak } + Item { + visible: dayBreak + width: parent.width + height: topPadding + } + MessageContent { visible: isMessage } EventContent { visible: ! isMessage } diff --git a/harmonyqml/components/chat/MessageList.qml b/harmonyqml/components/chat/MessageList.qml index 36add807..de3e1c08 100644 --- a/harmonyqml/components/chat/MessageList.qml +++ b/harmonyqml/components/chat/MessageList.qml @@ -3,21 +3,24 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.4 import "../base" as Base -Rectangle { +Base.HGlassRectangle { property bool canLoadPastEvents: true property int space: 8 + color: "transparent" + Layout.fillWidth: true Layout.fillHeight: true - Layout.leftMargin: space - Layout.rightMargin: space ListView { id: messageListView - anchors.fill: parent delegate: MessageDelegate {} model: Backend.models.roomEvents.get(chatPage.roomId) + anchors.fill: parent + anchors.leftMargin: space + anchors.rightMargin: space + clip: true topMargin: space bottomMargin: space @@ -45,7 +48,7 @@ Rectangle { topPadding: padding / 3 bottomPadding: topPadding background: Rectangle { - color: "lightgray" + color: Base.HStyle.chat.messageList.background radius: 5 } } diff --git a/harmonyqml/components/chat/RoomHeader.qml b/harmonyqml/components/chat/RoomHeader.qml index e104838b..713b7e27 100644 --- a/harmonyqml/components/chat/RoomHeader.qml +++ b/harmonyqml/components/chat/RoomHeader.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.4 import "../base" as Base -Rectangle { +Base.HGlassRectangle { property string displayName: "" property string topic: "" @@ -11,7 +11,7 @@ Rectangle { Layout.fillWidth: true Layout.minimumHeight: 36 Layout.maximumHeight: Layout.minimumHeight - color: "#BBB" + color: Base.HStyle.chat.roomHeader.background RowLayout { id: row diff --git a/harmonyqml/components/chat/SendBox.qml b/harmonyqml/components/chat/SendBox.qml index 80734900..4e321ba4 100644 --- a/harmonyqml/components/chat/SendBox.qml +++ b/harmonyqml/components/chat/SendBox.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.4 import "../base" as Base -Rectangle { +Base.HGlassRectangle { function setFocus() { textArea.forceActiveFocus() } id: root @@ -12,7 +12,7 @@ Rectangle { Layout.preferredHeight: textArea.implicitHeight // parent.height / 2 causes binding loop? Layout.maximumHeight: pageStack.height / 2 - color: "#BBB" + color: Base.HStyle.chat.sendBox.background RowLayout { anchors.fill: parent diff --git a/harmonyqml/components/pages/Default.qml b/harmonyqml/components/pages/Default.qml index f4aa9919..fb5decef 100644 --- a/harmonyqml/components/pages/Default.qml +++ b/harmonyqml/components/pages/Default.qml @@ -3,21 +3,6 @@ import QtQuick.Controls 2.2 import QtQuick.Layouts 1.4 import "../base" as Base -Base.HRowLayout { - Base.HLabel { - text: "Select or add a room to start." - wrapMode: Text.Wrap - padding: 3 - leftPadding: 10 - rightPadding: 10 - - Layout.margins: 10 - Layout.alignment: Qt.AlignCenter - Layout.maximumWidth: parent.width - Layout.margins * 2 - - background: Rectangle { - color: Base.HStyle.boxes.background - radius: Base.HStyle.boxes.radius - } - } +Base.HNoticeLabel { + text: "Select or add a room to start." } diff --git a/harmonyqml/components/sidePane/RoomCategoryDelegate.qml b/harmonyqml/components/sidePane/RoomCategoryDelegate.qml index 9545c0f1..291cb05d 100644 --- a/harmonyqml/components/sidePane/RoomCategoryDelegate.qml +++ b/harmonyqml/components/sidePane/RoomCategoryDelegate.qml @@ -11,5 +11,5 @@ Base.HLabel { elide: Text.ElideRight maximumLineCount: 1 - font.bold: true + font.weight: Font.DemiBold } diff --git a/harmonyqml/components/sidePane/Root.qml b/harmonyqml/components/sidePane/Root.qml index f8c5a935..bd6b5730 100644 --- a/harmonyqml/components/sidePane/Root.qml +++ b/harmonyqml/components/sidePane/Root.qml @@ -8,6 +8,8 @@ Base.HGlassRectangle { id: sidePane clip: true // Avoid artifacts when resizing pane width to minimum + isPageStackDescendant: false + ColumnLayout { anchors.fill: parent spacing: 0 diff --git a/harmonyqml/components/sidePane/utils.js b/harmonyqml/components/sidePane/utils.js index 3ce4ef2c..1b183f0f 100644 --- a/harmonyqml/components/sidePane/utils.js +++ b/harmonyqml/components/sidePane/utils.js @@ -19,21 +19,16 @@ function getLastRoomEventText(roomId, accountId) { var undecryptable = ev.type === "OlmEvent" || ev.type === "MegolmEvent" if (undecryptable || ev.type.startsWith("RoomMessage")) { - var color = ev.dict.sender === roomList.forUserId ? - "darkblue" : "purple" + var color = Qt.hsla(Backend.hueFromString(name), 0.32, 0.3, 1) - return "" + + return "" + name + ": " + (undecryptable ? - "Undecryptable" : + "" + qsTr("Undecryptable") + "" : ev.dict.body) } else { - return "" + + return "" + name + " " + ChatJS.getEventText(ev.type, ev.dict) + diff --git a/harmonyqml/images/.login_background.jpg-autosave.kra b/harmonyqml/images/.login_background.jpg-autosave.kra deleted file mode 100644 index 7275a9de..00000000 Binary files a/harmonyqml/images/.login_background.jpg-autosave.kra and /dev/null differ