Restyle the chat UI

This commit is contained in:
miruka 2019-04-28 11:01:38 -04:00
parent f65ea9dd0d
commit 5650234e3b
21 changed files with 182 additions and 77 deletions

View File

@ -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

View File

@ -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
}
}

View File

@ -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 {

View File

@ -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
}
}
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -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)

View File

@ -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
}

View File

@ -23,16 +23,23 @@ RowLayout {
Base.HLabel {
id: contentLabel
text: "<font color='" +
(isUndecryptableEvent ? "darkred" : "gray") + "'>" +
(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 +
"&nbsp;&nbsp;<font size=" + Base.HStyle.fontSize.small +
"px color='gray'>" +
"&nbsp;&nbsp;" +
"<font size=" + Base.HStyle.fontSize.small + "px " +
"color=" + Base.HStyle.chat.event.date + ">" +
Qt.formatDateTime(dateTime, "hh:mm:ss") +
"</font></font>"
"</font> " +
"</font>"
textFormat: Text.RichText
background: Rectangle {color: "#DDD"}
background: Rectangle {color: Base.HStyle.chat.event.background}
wrapMode: Text.Wrap
leftPadding: horizontalPadding

View File

@ -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 : ""

View File

@ -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()

View File

@ -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) +
"&nbsp;&nbsp;<font size=" + Base.HStyle.fontSize.small +
"px color=gray>" +
"px color=" + Base.HStyle.chat.message.date + ">" +
Qt.formatDateTime(dateTime, "hh:mm:ss") +
"</font>" +
(isLocalEcho ?
"&nbsp;<font size=" + Base.HStyle.fontSize.small +
"px>⏳</font>" : "")
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

View File

@ -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 }

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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."
}

View File

@ -11,5 +11,5 @@ Base.HLabel {
elide: Text.ElideRight
maximumLineCount: 1
font.bold: true
font.weight: Font.DemiBold
}

View File

@ -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

View File

@ -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 "<font color='" +
color +
"'>" +
return "<font color='" + color + "'>" +
name +
":</font> " +
(undecryptable ?
"<font color='darkred'>Undecryptable<font>" :
"<font color='darkred'>" + qsTr("Undecryptable") + "<font>" :
ev.dict.body)
} else {
return "<font color='" +
(undecryptable ? "darkred" : "#444") +
"'>" +
return "<font color='" + (undecryptable ? "darkred" : "#444") + "'>" +
name +
" " +
ChatJS.getEventText(ev.type, ev.dict) +