Update/refactor Chat components and banner

This commit is contained in:
miruka 2019-04-28 14:20:30 -04:00
parent bf9eb7dbc9
commit 99ab6a817a
15 changed files with 89 additions and 118 deletions

View File

@ -11,8 +11,10 @@
- Icons aren't reloaded - Icons aren't reloaded
- Bug when resizing window being tiled (i3), can't figure it out - Bug when resizing window being tiled (i3), can't figure it out
- HStyle singleton isn't reloaded - HStyle singleton isn't reloaded
- `MessageDelegate.qml:63: TypeError: 'reloadPreviousItem' not a function`
- UI - UI
- Use nested listview for categories instead of section property
- Server selection - Server selection
- Register/Forgot? for SignIn dialog - Register/Forgot? for SignIn dialog
- Scaling - Scaling

View File

@ -4,7 +4,7 @@
import time import time
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from threading import Event from threading import Event
from typing import Any, DefaultDict, Dict, Optional, Tuple from typing import DefaultDict, Tuple
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
@ -78,16 +78,6 @@ class Client(QObject):
return self.nio.user_id return self.nio.user_id
@pyqtSlot(str, result="QVariant")
@pyqtSlot(str, list, result="QVariant")
@pyqtSlot(str, list, "QVariantMap", result="QVariant")
def call(self,
method: str,
args: Optional[list] = None,
kwargs: Optional[Dict[str, Any]] = None) -> Any:
return getattr(self, method)(*args or [], **kwargs or {})
@pyqtSlot(str, result="QVariant") @pyqtSlot(str, result="QVariant")
@pyqtSlot(str, str, result="QVariant") @pyqtSlot(str, str, result="QVariant")
@futurize() @futurize()
@ -246,19 +236,19 @@ class Client(QObject):
return send(self) return send(self)
@pyqtSlot(str) @pyqtSlot(str, result="QVariant")
@futurize() @futurize()
def joinRoom(self, room_id: str) -> None: def joinRoom(self, room_id: str) -> None:
return self.net.talk(self.nio.join, room_id=room_id) return self.net.talk(self.nio.join, room_id=room_id)
@pyqtSlot(str) @pyqtSlot(str, result="QVariant")
@futurize() @futurize()
def leaveRoom(self, room_id: str) -> None: def leaveRoom(self, room_id: str) -> None:
return self.net.talk(self.nio.room_leave, room_id=room_id) return self.net.talk(self.nio.room_leave, room_id=room_id)
@pyqtSlot(str) @pyqtSlot(str, result="QVariant")
@futurize() @futurize()
def forgetRoom(self, room_id: str) -> None: def forgetRoom(self, room_id: str) -> None:
self.roomAboutToBeForgotten.emit(room_id) self.roomAboutToBeForgotten.emit(room_id)

View File

@ -9,6 +9,7 @@ Rectangle {
property var imageSource: null property var imageSource: null
property int dimension: 48 property int dimension: 48
readonly property string resolvedName: readonly property string resolvedName:
! name ? "?" : ! name ? "?" :
typeof(name) == "string" ? name : typeof(name) == "string" ? name :
@ -16,6 +17,9 @@ Rectangle {
width: dimension width: dimension
height: hidden ? 1 : dimension height: hidden ? 1 : dimension
implicitWidth: dimension
implicitHeight: hidden ? 1 : dimension
opacity: hidden ? 0 : 1 opacity: hidden ? 0 : 1
color: resolvedName === "?" ? color: resolvedName === "?" ?

View File

@ -15,6 +15,9 @@ Button {
property int contentWidth: 0 property int contentWidth: 0
readonly property alias visibility: button.visible
onVisibilityChanged: if (! visibility) { loading = false }
signal canceled signal canceled
signal clicked signal clicked
signal doubleClicked signal doubleClicked
@ -30,7 +33,6 @@ Button {
} }
id: button id: button
display: Button.TextBesideIcon
background: Rectangle { background: Rectangle {
id: buttonBackground id: buttonBackground

View File

@ -21,7 +21,8 @@ QtObject {
} }
readonly property QtObject colors: QtObject { readonly property QtObject colors: QtObject {
property color background0: Qt.hsla(0, 0, 0.8, 0.7) property color background0: Qt.hsla(0, 0, 0.8, 0.5)
property color background1: Qt.hsla(0, 0, 0.8, 0.7)
property color foreground: "black" property color foreground: "black"
property color foregroundDim: Qt.hsla(0, 0, 0.2, 1) property color foregroundDim: Qt.hsla(0, 0, 0.2, 1)
property color foregroundError: Qt.hsla(0.95, 0.64, 0.32, 1) property color foregroundError: Qt.hsla(0.95, 0.64, 0.32, 1)
@ -30,52 +31,56 @@ QtObject {
property int radius: 5 property int radius: 5
readonly property QtObject sidePane: QtObject { readonly property QtObject sidePane: QtObject {
property color background: colors.background0 property color background: colors.background1
} }
readonly property QtObject chat: QtObject { readonly property QtObject chat: QtObject {
readonly property QtObject roomHeader: QtObject { readonly property QtObject roomHeader: QtObject {
property color background: colors.background0 property color background: colors.background1
} }
readonly property QtObject messageList: QtObject { readonly property QtObject messageList: QtObject {
property color background: colors.background0 property color background: "transparent"
} }
readonly property QtObject message: QtObject { readonly property QtObject message: QtObject {
property color background: colors.background0 property color background: colors.background1
property color body: colors.foreground property color body: colors.foreground
property color date: colors.foregroundDim property color date: colors.foregroundDim
} }
readonly property QtObject event: QtObject { readonly property QtObject event: QtObject {
property color background: colors.background0 property color background: colors.background1
property real saturation: 0.22 property real saturation: 0.22
property real lightness: 0.24 property real lightness: 0.24
property color date: colors.foregroundDim property color date: colors.foregroundDim
} }
readonly property QtObject daybreak: QtObject { readonly property QtObject daybreak: QtObject {
property color background: colors.background0 property color background: colors.background1
property color foreground: colors.foreground property color foreground: colors.foreground
property int radius: style.radius property int radius: style.radius
} }
readonly property QtObject inviteBanner: QtObject { readonly property QtObject inviteBanner: QtObject {
property color background: colors.background0 property color background: colors.background1
} }
readonly property QtObject leftBanner: QtObject { readonly property QtObject leftBanner: QtObject {
property color background: colors.background1
}
readonly property QtObject typingUsers: QtObject {
property color background: colors.background0 property color background: colors.background0
} }
readonly property QtObject sendBox: QtObject { readonly property QtObject sendBox: QtObject {
property color background: colors.background0 property color background: colors.background1
} }
} }
readonly property QtObject box: QtObject { readonly property QtObject box: QtObject {
property color background: colors.background0 property color background: colors.background1
property int radius: style.radius property int radius: style.radius
} }

View File

@ -8,12 +8,11 @@ Base.HGlassRectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 32 Layout.preferredHeight: 32
signal buttonClicked(string signalId)
property alias avatarName: bannerAvatar.name property alias avatarName: bannerAvatar.name
property alias avatarSource: bannerAvatar.imageSource property alias avatarSource: bannerAvatar.imageSource
property alias labelText: bannerLabel.text property alias labelText: bannerLabel.text
property alias buttonModel: bannerRepeater.model property alias buttonModel: bannerRepeater.model
property var buttonCallbacks: []
Base.HRowLayout { Base.HRowLayout {
id: bannerRow id: bannerRow
@ -66,48 +65,15 @@ Base.HGlassRectangle {
bannerLabel.Layout.rightMargin + bannerLabel.Layout.rightMargin +
getButtonsWidth() getButtonsWidth()
property int displayMode:
compact ? Button.IconOnly : Button.TextBesideIcon
Repeater { Repeater {
id: bannerRepeater id: bannerRepeater
model: [] model: []
Base.HButton { Base.HButton {
property bool alreadyClicked: false id: button
text: modelData.text text: modelData.text
iconName: modelData.iconName iconName: modelData.iconName
display: bannerButtons.displayMode onClicked: buttonCallbacks[modelData.name](button)
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: {
if (alreadyClicked) { return }
iconName = "hourglass"
alreadyClicked = true
// modelData might be undefined after Backend call
var signalId = modelData.signalId
var isForget =
modelData.clientFunction === "forgetRoom"
var future =
Backend.clientManager.clients[chatPage.userId].
call(modelData.clientFunction,
modelData.clientArgs)
if (! isForget) {
future.onGotResult.connect(function() {
iconName = modelData.iconName
})
}
if (signalId) { buttonClicked(signalId) }
}
}
Layout.maximumWidth: bannerButtons.compact ? height : -1 Layout.maximumWidth: bannerButtons.compact ? height : -1
Layout.fillHeight: true Layout.fillHeight: true

View File

@ -13,7 +13,6 @@ ColumnLayout {
Component.onCompleted: console.log("replaced") Component.onCompleted: console.log("replaced")
id: chatPage id: chatPage
spacing: 0 spacing: 0
onFocusChanged: sendBox.setFocus() onFocusChanged: sendBox.setFocus()

View File

@ -8,7 +8,4 @@ Base.HNoticeLabel {
radius: Base.HStyle.chat.daybreak.radius radius: Base.HStyle.chat.daybreak.radius
width: messageDelegate.width width: messageDelegate.width
//topPadding: messageDelegate.isFirstMessage ?
//0 : messageDelegate.standardSpacing
//bottomPadding: messageDelegate.standardSpacing
} }

View File

@ -18,18 +18,30 @@ Banner {
buttonModel: [ buttonModel: [
{ {
text: "Accept", name: "accept",
text: qsTr("Accept"),
iconName: "invite_accept", iconName: "invite_accept",
//iconColor: Qt.hsla(0.45, 0.9, 0.3, 1),
clientFunction: "joinRoom",
clientArgs: [chatPage.roomId],
}, },
{ {
text: "Decline", name: "decline",
text: qsTr("Decline"),
iconName: "invite_decline", iconName: "invite_decline",
//iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
clientFunction: "leaveRoom",
clientArgs: [chatPage.roomId],
} }
] ]
buttonCallbacks: {
"accept": function(button) {
button.loading = true
Backend.clientManager.clients[chatPage.userId].joinRoom(
chatPage.roomId
)
},
"decline": function(button) {
button.loading = true
Backend.clientManager.clients[chatPage.userId].leaveRoom(
chatPage.roomId
)
}
}
} }

View File

@ -9,22 +9,25 @@ Banner {
color: Base.HStyle.chat.leftBanner.background color: Base.HStyle.chat.leftBanner.background
onButtonClicked: if (signalId === "forget") {
chatPage.canLoadPastEvents = false
pageStack.clear()
}
avatarName: ChatJS.getLeftBannerAvatarName(leftEvent, chatPage.userId) avatarName: ChatJS.getLeftBannerAvatarName(leftEvent, chatPage.userId)
labelText: ChatJS.getLeftBannerText(leftEvent) labelText: ChatJS.getLeftBannerText(leftEvent)
buttonModel: [ buttonModel: [
{ {
signalId: "forget", name: "forget",
text: "Forget", text: qsTr("Forget"),
iconName: "forget_room", iconName: "forget_room",
//iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
clientFunction: "forgetRoom",
clientArgs: [chatPage.roomId],
} }
] ]
buttonCallbacks: {
"forget": function(button) {
button.loading = true
chatPage.canLoadPastEvents = false
Backend.clientManager.clients[chatPage.userId].forgetRoom(
chatPage.roomId
)
pageStack.clear()
},
}
} }

View File

@ -7,7 +7,7 @@ Base.HGlassRectangle {
property bool canLoadPastEvents: true property bool canLoadPastEvents: true
property int space: 8 property int space: 8
color: "transparent" color: Base.HStyle.chat.messageList.background
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
@ -40,16 +40,10 @@ Base.HGlassRectangle {
} }
} }
Base.HLabel { Base.HNoticeLabel {
text: qsTr("Nothing to show here yet...")
visible: messageListView.model.count < 1 visible: messageListView.model.count < 1
anchors.centerIn: parent anchors.centerIn: parent
text: qsTr("Nothing to see here yet…")
padding: 10
topPadding: padding / 3
bottomPadding: topPadding
background: Rectangle {
color: Base.HStyle.chat.messageList.background
radius: 5
}
} }
} }

View File

@ -7,22 +7,22 @@ Base.HGlassRectangle {
property string displayName: "" property string displayName: ""
property string topic: "" property string topic: ""
id: root id: roomHeader
Layout.fillWidth: true
Layout.minimumHeight: 36
Layout.maximumHeight: Layout.minimumHeight
color: Base.HStyle.chat.roomHeader.background color: Base.HStyle.chat.roomHeader.background
RowLayout { Layout.fillWidth: true
Layout.preferredHeight: 32
Base.HRowLayout {
id: row id: row
spacing: 12 spacing: 8
anchors.fill: parent anchors.fill: parent
Base.HAvatar { Base.HAvatar {
id: avatar id: avatar
Layout.alignment: Qt.AlignTop
dimension: root.Layout.minimumHeight
name: displayName name: displayName
dimension: roomHeader.height
Layout.alignment: Qt.AlignTop
} }
Base.HLabel { Base.HLabel {
@ -31,9 +31,7 @@ Base.HGlassRectangle {
font.pixelSize: Base.HStyle.fontSize.big font.pixelSize: Base.HStyle.fontSize.big
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
Layout.maximumWidth: Layout.maximumWidth: row.width - row.totalSpacing - avatar.width
row.width - row.spacing * (row.children.length - 1) -
avatar.width
} }
Base.HLabel { Base.HLabel {
@ -43,10 +41,7 @@ Base.HGlassRectangle {
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
Layout.maximumWidth: Layout.maximumWidth:
row.width - row.width - row.totalSpacing - avatar.width - roomName.width
row.spacing * (row.children.length - 1) -
avatar.width -
roomName.width
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }

View File

@ -4,20 +4,20 @@ import QtQuick.Layouts 1.4
import "../Base" as Base import "../Base" as Base
import "utils.js" as ChatJS import "utils.js" as ChatJS
Rectangle { Base.HGlassRectangle {
id: root property var typingUsers: chatPage.roomInfo.typingUsers
color: Base.HStyle.chat.typingUsers.background
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumHeight: usersLabel.text ? usersLabel.implicitHeight : 0 Layout.minimumHeight: usersLabel.text ? usersLabel.implicitHeight : 0
Layout.maximumHeight: Layout.minimumHeight Layout.maximumHeight: Layout.minimumHeight
color: "#BBB"
property var typingUsers: chatPage.roomInfo.typingUsers
Base.HLabel { Base.HLabel {
id: usersLabel id: usersLabel
anchors.fill: parent anchors.fill: parent
text: ChatJS.getTypingUsersText(typingUsers, chatPage.userId)
text: ChatJS.getTypingUsersText(typingUsers, chatPage.userId)
elide: Text.ElideMiddle elide: Text.ElideMiddle
maximumLineCount: 1 maximumLineCount: 1
} }

View File

@ -9,7 +9,7 @@ ListView {
spacing: 8 spacing: 8
Layout.leftMargin: spacing Layout.leftMargin: spacing
topMargin: spacing topMargin: spacing
bottomMargin: spacing bottomMargin: topMargin
model: Backend.models.accounts model: Backend.models.accounts
delegate: AccountDelegate {} delegate: AccountDelegate {}

View File

@ -21,8 +21,10 @@ Item {
anchors.fill: parent anchors.fill: parent
SidePane.SidePane { SidePane.SidePane {
property int parentWidth: parent.width
onParentWidthChanged: width = Math.min(parent.width * 0.3, 300)
Layout.minimumWidth: 36 Layout.minimumWidth: 36
width: Math.min(parent.width * 0.33, 300)
Layout.maximumWidth: parent.width Layout.maximumWidth: parent.width
visible: accountsLoggedIn visible: accountsLoggedIn
} }
@ -38,7 +40,7 @@ Item {
function showRoom(userId, roomId) { function showRoom(userId, roomId) {
pageStack.replace( pageStack.replace(
"Chat/Root.qml", { userId: userId, roomId: roomId } "Chat/Chat.qml", { userId: userId, roomId: roomId }
) )
} }