Refactor Chat/RoomSidePane
This commit is contained in:
parent
06a6a4c08d
commit
5609ae2817
18
TODO.md
18
TODO.md
@ -1,8 +1,8 @@
|
|||||||
- make pageup/down not slippery again
|
- make pageup/down not slippery again
|
||||||
- rename all setfocus() to takefocus()
|
- test sidepane opacity
|
||||||
- refactor roomsidepane too
|
|
||||||
- better pane minsize
|
|
||||||
- better cancel for all boxes
|
- better cancel for all boxes
|
||||||
|
- get rid of all currentSpacing stuff
|
||||||
|
|
||||||
- Media
|
- Media
|
||||||
- Confirmation box after picking file to upload
|
- Confirmation box after picking file to upload
|
||||||
- Handle set avatar upload errors
|
- Handle set avatar upload errors
|
||||||
@ -23,17 +23,13 @@
|
|||||||
- EventFile & Downloading (right click on media > save as...)
|
- EventFile & Downloading (right click on media > save as...)
|
||||||
|
|
||||||
- Refactoring
|
- Refactoring
|
||||||
|
- Replace all the `==` by `===`
|
||||||
- Use a singleton for utils.js
|
- Use a singleton for utils.js
|
||||||
- Room header elide detection
|
|
||||||
- Use HBox for Profile
|
- Use HBox for Profile
|
||||||
- Banners
|
- Banners
|
||||||
- Composer
|
- Composer
|
||||||
|
|
||||||
- Room Sidepane
|
- Room Sidepane save/load size
|
||||||
- Hide when window too small
|
|
||||||
- Also save/load its size
|
|
||||||
- Is auto-sizing actually needed, or can we just set a default manual size?
|
|
||||||
- Reducable room sidepane, swipe to show full-window
|
|
||||||
|
|
||||||
- Fixes
|
- Fixes
|
||||||
- Pausing uploads doesn't work well with matrix.org
|
- Pausing uploads doesn't work well with matrix.org
|
||||||
@ -118,9 +114,7 @@
|
|||||||
- Sidepane
|
- Sidepane
|
||||||
- Animate when logging out last account and sidepane turns invisible
|
- Animate when logging out last account and sidepane turns invisible
|
||||||
- Header back button when reduced
|
- Header back button when reduced
|
||||||
- Better look for arrows and option button when collapsed
|
- Better look when reduced to minimum size
|
||||||
- Show it when hovering/hitting focus keybind on the left when collapsed
|
|
||||||
- Ability to drag on any place of the pane to resize
|
|
||||||
|
|
||||||
- Server selection
|
- Server selection
|
||||||
- Register/Forgot? for SignIn dialog
|
- Register/Forgot? for SignIn dialog
|
||||||
|
@ -2,9 +2,5 @@ import QtQuick 2.12
|
|||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: columnLayout
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
property int totalSpacing:
|
|
||||||
spacing * Math.max(0, (columnLayout.visibleChildren.length - 1))
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,12 @@ import "../utils.js" as Utils
|
|||||||
Drawer {
|
Drawer {
|
||||||
id: drawer
|
id: drawer
|
||||||
implicitWidth: calculatedWidth
|
implicitWidth: calculatedWidth
|
||||||
implicitHeight: parent.height
|
implicitHeight: referenceSizeParent.height
|
||||||
|
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
|
||||||
// FIXME: https://bugreports.qt.io/browse/QTBUG-59141
|
// FIXME: https://bugreports.qt.io/browse/QTBUG-59141
|
||||||
// dragMargin: parent.width / 2
|
// dragMargin: parent.width / 2
|
||||||
@ -21,12 +26,15 @@ Drawer {
|
|||||||
|
|
||||||
signal userResized(int newWidth)
|
signal userResized(int newWidth)
|
||||||
|
|
||||||
|
property Item referenceSizeParent: parent
|
||||||
|
|
||||||
property int normalWidth: 300
|
property int normalWidth: 300
|
||||||
property int minNormalWidth: resizeAreaWidth
|
property int minNormalWidth: resizeAreaWidth
|
||||||
property int maxNormalWidth: parent.width
|
property int maxNormalWidth:
|
||||||
|
referenceSizeParent.width - theme.minimumSupportedWidth
|
||||||
|
|
||||||
property bool collapse: window.width < 400
|
property bool collapse: window.width < 400
|
||||||
property int collapseExpandedWidth: parent.width
|
property int collapseExpandedWidth: referenceSizeParent.width
|
||||||
|
|
||||||
property alias color: bg.color
|
property alias color: bg.color
|
||||||
property alias resizeAreaWidth: resizeArea.width
|
property alias resizeAreaWidth: resizeArea.width
|
||||||
@ -44,7 +52,7 @@ Drawer {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: resizeArea
|
id: resizeArea
|
||||||
anchors.right: parent.right
|
x: drawer.edge === Qt.LeftEdge ? drawer.width - width : 0
|
||||||
width: theme.spacing / 2
|
width: theme.spacing / 2
|
||||||
height: parent.height
|
height: parent.height
|
||||||
z: 9999
|
z: 9999
|
||||||
@ -63,8 +71,11 @@ Drawer {
|
|||||||
onReleased: { canResize = false; userResized(drawer.normalWidth) }
|
onReleased: { canResize = false; userResized(drawer.normalWidth) }
|
||||||
|
|
||||||
onMouseXChanged:
|
onMouseXChanged:
|
||||||
if (canResize)
|
if (canResize) {
|
||||||
drawer.normalWidth = drawer.calculatedWidth + mouseX
|
drawer.normalWidth =
|
||||||
|
drawer.calculatedWidth +
|
||||||
|
(drawer.edge === Qt.RightEdge ? -mouseX : mouseX)
|
||||||
|
}
|
||||||
|
|
||||||
property bool canResize: false
|
property bool canResize: false
|
||||||
}
|
}
|
||||||
|
36
src/qml/Base/HFlow.qml
Normal file
36
src/qml/Base/HFlow.qml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
populate: Transition {
|
||||||
|
id: addTrans
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
PropertyAction { property: "opacity"; value: 0 }
|
||||||
|
|
||||||
|
PauseAnimation {
|
||||||
|
duration:
|
||||||
|
addTrans.ViewTransition.index * theme.animationDuration / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelAnimation {
|
||||||
|
HNumberAnimation { property: "opacity"; to: 1 }
|
||||||
|
HNumberAnimation { properties: "x,y"; from: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
ParallelAnimation {
|
||||||
|
HNumberAnimation { property: "opacity"; to: 1 }
|
||||||
|
HNumberAnimation { properties: "x,y"; from: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
move: Transition {
|
||||||
|
ParallelAnimation {
|
||||||
|
// Ensure opacity goes to 1 if add transition is interrupted
|
||||||
|
HNumberAnimation { property: "opacity"; to: 1 }
|
||||||
|
HNumberAnimation { properties: "x,y" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,6 @@ import QtQuick 2.12
|
|||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: gridLayout
|
|
||||||
rowSpacing: 0
|
rowSpacing: 0
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
|
|
||||||
property int totalSpacing:
|
|
||||||
spacing * Math.max(0, (gridLayout.visibleChildren.length - 1))
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: loader
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: status == Loader.Ready
|
visible: status == Loader.Ready
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,5 @@ import QtQuick 2.12
|
|||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: rowLayout
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
property int totalSpacing:
|
|
||||||
spacing * Math.max(0, (rowLayout.visibleChildren.length - 1))
|
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import QtQuick 2.12
|
|
||||||
import QtQuick.Controls 1.4 as Controls1
|
|
||||||
|
|
||||||
//https://doc.qt.io/qt-5/qml-qtquick-controls-splitview.html
|
|
||||||
Controls1.SplitView {
|
|
||||||
id: splitView
|
|
||||||
|
|
||||||
property bool anyHovered: false
|
|
||||||
property bool anyPressed: false
|
|
||||||
property bool anyResizing: false
|
|
||||||
|
|
||||||
property bool manuallyResized: false
|
|
||||||
onAnyResizingChanged: manuallyResized = true
|
|
||||||
|
|
||||||
handleDelegate: Item {
|
|
||||||
readonly property bool hovered: styleData.hovered
|
|
||||||
readonly property bool pressed: styleData.pressed
|
|
||||||
readonly property bool resizing: styleData.resizing
|
|
||||||
|
|
||||||
onHoveredChanged: splitView.anyHovered = hovered
|
|
||||||
onPressedChanged: splitView.anyPressed = pressed
|
|
||||||
onResizingChanged: splitView.anyResizing = resizing
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,9 +3,9 @@ import "../../Base"
|
|||||||
import "../../utils.js" as Utils
|
import "../../utils.js" as Utils
|
||||||
|
|
||||||
Banner {
|
Banner {
|
||||||
property string inviterId: chatPage.roomInfo.inviter
|
property string inviterId: chat.roomInfo.inviter
|
||||||
property string inviterName: chatPage.roomInfo.inviter_name
|
property string inviterName: chat.roomInfo.inviter_name
|
||||||
property string inviterAvatar: chatPage.roomInfo.inviter_avatar
|
property string inviterAvatar: chat.roomInfo.inviter_avatar
|
||||||
|
|
||||||
color: theme.chat.inviteBanner.background
|
color: theme.chat.inviteBanner.background
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ Banner {
|
|||||||
accept: button => {
|
accept: button => {
|
||||||
button.loading = true
|
button.loading = true
|
||||||
py.callClientCoro(
|
py.callClientCoro(
|
||||||
chatPage.userId, "join", [chatPage.roomId], () => {
|
chat.userId, "join", [chat.roomId], () => {
|
||||||
button.loading = false
|
button.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -44,7 +44,7 @@ Banner {
|
|||||||
decline: button => {
|
decline: button => {
|
||||||
button.loading = true
|
button.loading = true
|
||||||
py.callClientCoro(
|
py.callClientCoro(
|
||||||
chatPage.userId, "room_leave", [chatPage.roomId], () => {
|
chat.userId, "room_leave", [chat.roomId], () => {
|
||||||
button.loading = false
|
button.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ Banner {
|
|||||||
color: theme.chat.leftBanner.background
|
color: theme.chat.leftBanner.background
|
||||||
|
|
||||||
// TODO: avatar func auto
|
// TODO: avatar func auto
|
||||||
avatar.userId: chatPage.userId
|
avatar.userId: chat.userId
|
||||||
avatar.displayName: chatPage.userInfo.display_name
|
avatar.displayName: chat.userInfo.display_name
|
||||||
avatar.mxc: chatPage.userInfo.avatar_url
|
avatar.mxc: chat.userInfo.avatar_url
|
||||||
labelText: qsTr("You are not part of this room anymore")
|
labelText: qsTr("You are not part of this room anymore")
|
||||||
|
|
||||||
buttonModel: [
|
buttonModel: [
|
||||||
@ -24,11 +24,11 @@ Banner {
|
|||||||
forget: button => {
|
forget: button => {
|
||||||
Utils.makePopup(
|
Utils.makePopup(
|
||||||
"Popups/ForgetRoomPopup.qml",
|
"Popups/ForgetRoomPopup.qml",
|
||||||
mainUI, // Must not be destroyed with chatPage
|
mainUI, // Must not be destroyed with chat
|
||||||
{
|
{
|
||||||
userId: chatPage.userId,
|
userId: chat.userId,
|
||||||
roomId: chatPage.roomId,
|
roomId: chat.roomId,
|
||||||
roomName: chatPage.roomInfo.display_name,
|
roomName: chat.roomInfo.display_name,
|
||||||
},
|
},
|
||||||
obj => {
|
obj => {
|
||||||
obj.onOk.connect(() => { button.loading = true })
|
obj.onOk.connect(() => { button.loading = true })
|
||||||
|
@ -2,14 +2,11 @@ import QtQuick 2.12
|
|||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
import "../Base"
|
import "../Base"
|
||||||
import "../utils.js" as Utils
|
import "../utils.js" as Utils
|
||||||
|
import "RoomSidePane"
|
||||||
|
|
||||||
HPage {
|
Item {
|
||||||
id: chatPage
|
id: chat
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
|
|
||||||
// The target will be our EventList, not the page itself
|
|
||||||
becomeKeyboardFlickableTarget: false
|
|
||||||
|
|
||||||
property string userId: ""
|
property string userId: ""
|
||||||
property string roomId: ""
|
property string roomId: ""
|
||||||
@ -39,26 +36,27 @@ HPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
readonly property bool hasUnknownDevices: false
|
HLoader {
|
||||||
|
anchors.rightMargin: roomSidePane.width * roomSidePane.position
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: ! roomSidePane.hidden || anchors.rightMargin < width
|
||||||
|
|
||||||
|
source: ready ? "ChatPage.qml" : ""
|
||||||
|
|
||||||
header: HLoader {
|
HLoader {
|
||||||
id: roomHeader
|
anchors.centerIn: parent
|
||||||
source: ready ? "RoomHeader.qml" : ""
|
width: 96 * theme.uiScale
|
||||||
|
height: width
|
||||||
|
|
||||||
clip: height < implicitHeight
|
source: opacity > 0 ? "../Base/HBusyIndicator.qml" : ""
|
||||||
width: parent.width
|
opacity: ready ? 0 : 1
|
||||||
height: ready ? implicitHeight : 0
|
|
||||||
Behavior on height { HNumberAnimation {} }
|
Behavior on opacity { HOpacityAnimator { factor: 2 } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HLoader {
|
RoomSidePane {
|
||||||
source: ready ? "ChatSplitView.qml" : "../Base/HBusyIndicator.qml"
|
id: roomSidePane
|
||||||
|
referenceSizeParent: chat
|
||||||
Layout.preferredWidth: ready ? -1 : 96 * theme.uiScale
|
|
||||||
Layout.preferredHeight: Layout.preferredWidth
|
|
||||||
Layout.fillWidth: ready
|
|
||||||
Layout.fillHeight: ready
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
64
src/qml/Chat/ChatPage.qml
Normal file
64
src/qml/Chat/ChatPage.qml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import "../Base"
|
||||||
|
import "../utils.js" as Utils
|
||||||
|
import "Banners"
|
||||||
|
import "Timeline"
|
||||||
|
import "FileTransfer"
|
||||||
|
|
||||||
|
HPage {
|
||||||
|
id: chatPage
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
|
||||||
|
// The target will be our EventList, not the page itself
|
||||||
|
becomeKeyboardFlickableTarget: false
|
||||||
|
|
||||||
|
Component.onCompleted: composer.takeFocus()
|
||||||
|
|
||||||
|
RoomHeader {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
EventList {
|
||||||
|
id: eventList
|
||||||
|
|
||||||
|
// Avoid a certain binding loop
|
||||||
|
Layout.minimumWidth: theme.minimumSupportedWidth
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TypingMembersBar {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TransferList {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: implicitHeight
|
||||||
|
Layout.preferredHeight: implicitHeight * transferCount
|
||||||
|
Layout.maximumHeight: chatPage.height / 6
|
||||||
|
|
||||||
|
Behavior on Layout.preferredHeight { HNumberAnimation {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
InviteBanner {
|
||||||
|
id: inviteBanner
|
||||||
|
visible: ! chat.roomInfo.left && inviterId
|
||||||
|
inviterId: chat.roomInfo.inviter_id
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Composer {
|
||||||
|
id: composer
|
||||||
|
visible: ! chat.roomInfo.left &&
|
||||||
|
! chat.roomInfo.inviter_id
|
||||||
|
}
|
||||||
|
|
||||||
|
LeftBanner {
|
||||||
|
id: leftBanner
|
||||||
|
visible: chat.roomInfo.left
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
@ -1,126 +0,0 @@
|
|||||||
import QtQuick 2.12
|
|
||||||
import QtQuick.Layouts 1.12
|
|
||||||
import "../Base"
|
|
||||||
import "Banners"
|
|
||||||
import "Timeline"
|
|
||||||
import "RoomSidePane"
|
|
||||||
import "FileTransfer"
|
|
||||||
|
|
||||||
HSplitView {
|
|
||||||
id: chatSplitView
|
|
||||||
Component.onCompleted: composer.takeFocus()
|
|
||||||
|
|
||||||
HColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
EventList {
|
|
||||||
id: eventList
|
|
||||||
|
|
||||||
// Avoid a certain binding loop
|
|
||||||
Layout.minimumWidth: theme.minimumSupportedWidth
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
|
|
||||||
TypingMembersBar {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
TransferList {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.minimumHeight: implicitHeight
|
|
||||||
Layout.preferredHeight: implicitHeight * transferCount
|
|
||||||
Layout.maximumHeight: chatSplitView.height / 6
|
|
||||||
|
|
||||||
Behavior on Layout.preferredHeight { HNumberAnimation {} }
|
|
||||||
}
|
|
||||||
|
|
||||||
InviteBanner {
|
|
||||||
id: inviteBanner
|
|
||||||
visible: ! chatPage.roomInfo.left && inviterId
|
|
||||||
inviterId: chatPage.roomInfo.inviter_id
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Composer {
|
|
||||||
id: composer
|
|
||||||
visible: ! chatPage.roomInfo.left &&
|
|
||||||
! chatPage.roomInfo.inviter_id
|
|
||||||
}
|
|
||||||
|
|
||||||
LeftBanner {
|
|
||||||
id: leftBanner
|
|
||||||
visible: chatPage.roomInfo.left
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RoomSidePane {
|
|
||||||
id: roomSidePane
|
|
||||||
|
|
||||||
activeView: roomHeader.item ? roomHeader.item.activeButton : null
|
|
||||||
|
|
||||||
property int oldWidth: width
|
|
||||||
onActiveViewChanged:
|
|
||||||
activeView ? restoreAnimation.start() : hideAnimation.start()
|
|
||||||
|
|
||||||
HNumberAnimation {
|
|
||||||
id: hideAnimation
|
|
||||||
target: roomSidePane
|
|
||||||
properties: "width"
|
|
||||||
from: target.width
|
|
||||||
to: 0
|
|
||||||
|
|
||||||
onStarted: {
|
|
||||||
target.oldWidth = target.width
|
|
||||||
target.Layout.minimumWidth = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HNumberAnimation {
|
|
||||||
id: restoreAnimation
|
|
||||||
target: roomSidePane
|
|
||||||
properties: "width"
|
|
||||||
from: 0
|
|
||||||
to: target.oldWidth
|
|
||||||
|
|
||||||
onStopped: target.Layout.minimumWidth = Qt.binding(
|
|
||||||
() => theme.controls.avatar.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
collapsed: width < theme.controls.avatar.size + theme.spacing
|
|
||||||
|
|
||||||
property bool wasSnapped: false
|
|
||||||
property int referenceWidth:
|
|
||||||
roomHeader.item ? roomHeader.item.buttonsWidth : 0
|
|
||||||
|
|
||||||
onReferenceWidthChanged: {
|
|
||||||
if (! chatSplitView.manuallyResized || wasSnapped) {
|
|
||||||
if (wasSnapped) { chatSplitView.manuallyResized = false }
|
|
||||||
width = referenceWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property int currentWidth: width
|
|
||||||
onCurrentWidthChanged: {
|
|
||||||
if (referenceWidth != width &&
|
|
||||||
referenceWidth - 15 < width &&
|
|
||||||
width < referenceWidth + 15)
|
|
||||||
{
|
|
||||||
currentWidth = referenceWidth
|
|
||||||
width = referenceWidth
|
|
||||||
wasSnapped = true
|
|
||||||
currentWidth = Qt.binding(() => roomSidePane.width)
|
|
||||||
} else {
|
|
||||||
wasSnapped = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
width: referenceWidth // Initial width
|
|
||||||
Layout.minimumWidth: theme.controls.avatar.size
|
|
||||||
Layout.maximumWidth:
|
|
||||||
parent.width - theme.minimumSupportedWidthPlusSpacing
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,7 +10,7 @@ Rectangle {
|
|||||||
property var aliases: window.settings.writeAliases
|
property var aliases: window.settings.writeAliases
|
||||||
property string toSend: ""
|
property string toSend: ""
|
||||||
|
|
||||||
property string writingUserId: chatPage.userId
|
property string writingUserId: chat.userId
|
||||||
readonly property var writingUserInfo:
|
readonly property var writingUserInfo:
|
||||||
Utils.getItem(modelSources["Account"] || [], "user_id", writingUserId)
|
Utils.getItem(modelSources["Account"] || [], "user_id", writingUserId)
|
||||||
|
|
||||||
@ -78,13 +78,13 @@ Rectangle {
|
|||||||
py.callClientCoro(
|
py.callClientCoro(
|
||||||
writingUserId,
|
writingUserId,
|
||||||
"room_typing",
|
"room_typing",
|
||||||
[chatPage.roomId, typing, 5000]
|
[chat.roomId, typing, 5000]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (Utils.isEmptyObject(aliases)) {
|
if (Utils.isEmptyObject(aliases)) {
|
||||||
writingUserId = Qt.binding(() => chatPage.userId)
|
writingUserId = Qt.binding(() => chat.userId)
|
||||||
toSend = text
|
toSend = text
|
||||||
setTyping(Boolean(text))
|
setTyping(Boolean(text))
|
||||||
textChangedSinceLostFocus = true
|
textChangedSinceLostFocus = true
|
||||||
@ -108,7 +108,7 @@ Rectangle {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
writingUserId = Qt.binding(() => chatPage.userId)
|
writingUserId = Qt.binding(() => chat.userId)
|
||||||
toSend = text
|
toSend = text
|
||||||
|
|
||||||
let vals = Object.values(aliases)
|
let vals = Object.values(aliases)
|
||||||
@ -168,7 +168,7 @@ Rectangle {
|
|||||||
|
|
||||||
if (textArea.text === "") { return }
|
if (textArea.text === "") { return }
|
||||||
|
|
||||||
let args = [chatPage.roomId, toSend]
|
let args = [chat.roomId, toSend]
|
||||||
py.callClientCoro(writingUserId, "send_text", args)
|
py.callClientCoro(writingUserId, "send_text", args)
|
||||||
|
|
||||||
area.clear()
|
area.clear()
|
||||||
@ -215,8 +215,8 @@ Rectangle {
|
|||||||
|
|
||||||
SendFilePicker {
|
SendFilePicker {
|
||||||
id: sendFilePicker
|
id: sendFilePicker
|
||||||
userId: chatPage.userId
|
userId: chat.userId
|
||||||
roomId: chatPage.roomId
|
roomId: chat.roomId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ Rectangle {
|
|||||||
|
|
||||||
model: HListModel {
|
model: HListModel {
|
||||||
keyField: "uuid"
|
keyField: "uuid"
|
||||||
source: modelSources[["Upload", chatPage.roomId]] || []
|
source: modelSources[["Upload", chat.roomId]] || []
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Transfer { width: transferList.width }
|
delegate: Transfer { width: transferList.width }
|
||||||
|
@ -3,135 +3,67 @@ import QtQuick.Layouts 1.12
|
|||||||
import "../Base"
|
import "../Base"
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property alias buttonsImplicitWidth: viewButtons.implicitWidth
|
|
||||||
property int buttonsWidth: viewButtons.Layout.preferredWidth
|
|
||||||
property var activeButton: "members"
|
|
||||||
|
|
||||||
property bool collapseButtons:
|
|
||||||
viewButtons.implicitWidth > width * 0.33 ||
|
|
||||||
width - viewButtons.implicitWidth <
|
|
||||||
theme.minimumSupportedWidthPlusSpacing
|
|
||||||
|
|
||||||
id: roomHeader
|
|
||||||
color: theme.chat.roomHeader.background
|
|
||||||
implicitHeight: theme.baseElementsHeight
|
implicitHeight: theme.baseElementsHeight
|
||||||
|
color: theme.chat.roomHeader.background
|
||||||
|
|
||||||
HRowLayout {
|
HRowLayout {
|
||||||
id: row
|
id: row
|
||||||
spacing: theme.spacing
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
HRoomAvatar {
|
HRoomAvatar {
|
||||||
id: avatar
|
id: avatar
|
||||||
displayName: chatPage.roomInfo.display_name
|
displayName: chat.roomInfo.display_name
|
||||||
mxc: chatPage.roomInfo.avatar_url
|
mxc: chat.roomInfo.avatar_url
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
}
|
}
|
||||||
|
|
||||||
HLabel {
|
HLabel {
|
||||||
id: roomName
|
id: nameLabel
|
||||||
text: chatPage.roomInfo.display_name || qsTr("Empty room")
|
text: chat.roomInfo.display_name || qsTr("Empty room")
|
||||||
font.pixelSize: theme.fontSize.big
|
font.pixelSize: theme.fontSize.big
|
||||||
color: theme.chat.roomHeader.name
|
color: theme.chat.roomHeader.name
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
leftPadding: theme.spacing
|
||||||
|
rightPadding: leftPadding
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.preferredWidth: Math.min(
|
||||||
Layout.maximumWidth: Math.max(
|
implicitWidth, row.width - row.spacing - avatar.width
|
||||||
0,
|
|
||||||
row.width - row.totalSpacing - avatar.width -
|
|
||||||
viewButtons.width -
|
|
||||||
(expandButton.visible ? expandButton.width : 0)
|
|
||||||
)
|
)
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
HoverHandler { id: nameHover }
|
HoverHandler { id: nameHover }
|
||||||
}
|
}
|
||||||
|
|
||||||
HRichLabel {
|
HRichLabel {
|
||||||
id: roomTopic
|
id: topicLabel
|
||||||
text: chatPage.roomInfo.topic
|
text: chat.roomInfo.topic
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
font.pixelSize: theme.fontSize.small
|
font.pixelSize: theme.fontSize.small
|
||||||
color: theme.chat.roomHeader.topic
|
color: theme.chat.roomHeader.topic
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
rightPadding: nameLabel.rightPadding
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.maximumWidth: Math.max(
|
|
||||||
0,
|
|
||||||
row.width - row.totalSpacing - avatar.width -
|
|
||||||
roomName.width - viewButtons.width -
|
|
||||||
(expandButton.visible ? expandButton.width : 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
HoverHandler { id: topicHover }
|
HoverHandler { id: topicHover }
|
||||||
}
|
}
|
||||||
|
|
||||||
HToolTip {
|
HToolTip {
|
||||||
text: name && topic ? (`${name}<br>${topic}`) : (name || topic)
|
|
||||||
label.textFormat: Text.StyledText
|
|
||||||
visible: text && (nameHover.hovered || topicHover.hovered)
|
visible: text && (nameHover.hovered || topicHover.hovered)
|
||||||
|
label.textFormat: Text.StyledText
|
||||||
|
text: name && topic ? (`${name}<br>${topic}`) : (name || topic)
|
||||||
|
|
||||||
readonly property string name:
|
readonly property string name:
|
||||||
roomName.truncated ?
|
nameLabel.truncated ?
|
||||||
(`<b>${chatPage.roomInfo.display_name}</b>`) : ""
|
(`<b>${chat.roomInfo.display_name}</b>`) : ""
|
||||||
|
|
||||||
readonly property string topic:
|
readonly property string topic:
|
||||||
roomTopic.truncated ? chatPage.roomInfo.topic : ""
|
topicLabel.truncated ? chat.roomInfo.topic : ""
|
||||||
}
|
|
||||||
|
|
||||||
HSpacer {}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: viewButtons
|
|
||||||
Layout.preferredWidth: collapseButtons ? 0 : implicitWidth
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: [
|
|
||||||
"members", "files", "notifications", "history", "settings"
|
|
||||||
]
|
|
||||||
HButton {
|
|
||||||
backgroundColor: "transparent"
|
|
||||||
icon.name: "room-view-" + modelData
|
|
||||||
height: parent.height
|
|
||||||
spacing: theme.spacing / 1.5
|
|
||||||
topPadding: 0
|
|
||||||
bottomPadding: topPadding
|
|
||||||
autoExclusive: true
|
|
||||||
checked: activeButton == modelData
|
|
||||||
enabled: modelData == "members"
|
|
||||||
toolTip.text: qsTr(
|
|
||||||
modelData.charAt(0).toUpperCase() + modelData.slice(1)
|
|
||||||
)
|
|
||||||
onClicked: activeButton =
|
|
||||||
activeButton == modelData ? null : modelData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on Layout.preferredWidth {
|
|
||||||
HNumberAnimation { id: buttonsAnimation }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HButton {
|
|
||||||
id: expandButton
|
|
||||||
z: 1
|
|
||||||
width: height
|
|
||||||
height: parent.height
|
|
||||||
spacing: theme.spacing / 1.5
|
|
||||||
topPadding: 0
|
|
||||||
bottomPadding: topPadding
|
|
||||||
anchors.right: parent.right
|
|
||||||
opacity: collapseButtons ? 1 : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
enabled: false // TODO
|
|
||||||
|
|
||||||
backgroundColor: "transparent"
|
|
||||||
icon.name: "reduced-room-buttons"
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
HOpacityAnimator { duration: buttonsAnimation.duration * 2 }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import "../../utils.js" as Utils
|
|||||||
|
|
||||||
HTileDelegate {
|
HTileDelegate {
|
||||||
id: memberDelegate
|
id: memberDelegate
|
||||||
spacing: roomSidePane.currentSpacing
|
|
||||||
backgroundColor: theme.chat.roomSidePane.member.background
|
backgroundColor: theme.chat.roomSidePane.member.background
|
||||||
|
|
||||||
image: HUserAvatar {
|
image: HUserAvatar {
|
||||||
|
@ -13,7 +13,7 @@ HColumnLayout {
|
|||||||
|
|
||||||
|
|
||||||
readonly property var originSource:
|
readonly property var originSource:
|
||||||
modelSources[["Member", chatPage.roomId]] || []
|
modelSources[["Member", chat.roomId]] || []
|
||||||
|
|
||||||
|
|
||||||
onOriginSourceChanged: filterLimiter.restart()
|
onOriginSourceChanged: filterLimiter.restart()
|
||||||
|
@ -2,17 +2,43 @@ import QtQuick 2.12
|
|||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
import "../../Base"
|
import "../../Base"
|
||||||
|
|
||||||
Rectangle {
|
HDrawer {
|
||||||
id: roomSidePane
|
id: roomSidePane
|
||||||
color: theme.chat.roomSidePane.background
|
color: theme.chat.roomSidePane.background
|
||||||
|
edge: Qt.RightEdge
|
||||||
|
normalWidth: buttonRepeater.childrenImplicitWidth
|
||||||
|
minNormalWidth:
|
||||||
|
buttonRepeater.count > 0 ? buttonRepeater.itemAt(0).implicitWidth : 0
|
||||||
|
|
||||||
property bool collapsed: false
|
HColumnLayout {
|
||||||
property var activeView: null
|
|
||||||
property int currentSpacing: collapsed ? 0 : theme.spacing
|
|
||||||
|
|
||||||
Behavior on currentSpacing { HNumberAnimation {} }
|
|
||||||
|
|
||||||
MembersView {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
HFlow {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
HRepeater {
|
||||||
|
id: buttonRepeater
|
||||||
|
model: [
|
||||||
|
"members", "files", "notifications", "history", "settings"
|
||||||
|
]
|
||||||
|
|
||||||
|
HButton {
|
||||||
|
height: theme.baseElementsHeight
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
icon.name: "room-view-" + modelData
|
||||||
|
autoExclusive: true
|
||||||
|
checked: modelData === "members"
|
||||||
|
enabled: modelData === "members"
|
||||||
|
toolTip.text: qsTr(
|
||||||
|
modelData.charAt(0).toUpperCase() + modelData.slice(1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MembersView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ HRowLayout {
|
|||||||
|
|
||||||
readonly property int messageBodyWidth:
|
readonly property int messageBodyWidth:
|
||||||
width - (avatarWrapper.visible ? avatarWrapper.width : 0) -
|
width - (avatarWrapper.visible ? avatarWrapper.width : 0) -
|
||||||
totalSpacing
|
spacing * Math.max(0, (visibleChildren.length - 1))
|
||||||
|
|
||||||
readonly property int xOffset:
|
readonly property int xOffset:
|
||||||
onRight ?
|
onRight ?
|
||||||
|
@ -28,7 +28,7 @@ Column {
|
|||||||
nextItem = eventList.model.get(model.index - 1)
|
nextItem = eventList.model.get(model.index - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool isOwn: chatPage.userId === model.sender_id
|
property bool isOwn: chat.userId === model.sender_id
|
||||||
property bool onRight: eventList.ownEventsOnRight && isOwn
|
property bool onRight: eventList.ownEventsOnRight && isOwn
|
||||||
property bool combine: eventList.canCombine(previousItem, model)
|
property bool combine: eventList.canCombine(previousItem, model)
|
||||||
property bool talkBreak: eventList.canTalkBreak(previousItem, model)
|
property bool talkBreak: eventList.canTalkBreak(previousItem, model)
|
||||||
@ -70,7 +70,7 @@ Column {
|
|||||||
{
|
{
|
||||||
"model": Utils.getItem(
|
"model": Utils.getItem(
|
||||||
modelSources[[
|
modelSources[[
|
||||||
"Event", chatPage.userId, chatPage.roomId
|
"Event", chat.userId, chat.roomId
|
||||||
]],
|
]],
|
||||||
"client_id",
|
"client_id",
|
||||||
model.client_id
|
model.client_id
|
||||||
@ -168,8 +168,8 @@ Column {
|
|||||||
text: qsTr("Clear messages")
|
text: qsTr("Clear messages")
|
||||||
onTriggered: Utils.makePopup(
|
onTriggered: Utils.makePopup(
|
||||||
"Popups/ClearMessagesPopup.qml",
|
"Popups/ClearMessagesPopup.qml",
|
||||||
chatPage,
|
chat,
|
||||||
{userId: chatPage.userId, roomId: chatPage.roomId},
|
{userId: chat.userId, roomId: chat.roomId},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ HMxcImage {
|
|||||||
let isMxc = toOpen.startsWith("mxc://")
|
let isMxc = toOpen.startsWith("mxc://")
|
||||||
|
|
||||||
isMxc ?
|
isMxc ?
|
||||||
py.callClientCoro(chatPage.userId, "mxc_to_http", [toOpen], callback) :
|
py.callClientCoro(chat.userId, "mxc_to_http", [toOpen], callback) :
|
||||||
callback(toOpen)
|
callback(toOpen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ Rectangle {
|
|||||||
Component.onCompleted: shortcuts.flickTarget = eventList
|
Component.onCompleted: shortcuts.flickTarget = eventList
|
||||||
|
|
||||||
|
|
||||||
property string inviter: chatPage.roomInfo.inviter || ""
|
property string inviter: chat.roomInfo.inviter || ""
|
||||||
property real yPos: visibleArea.yPosition
|
property real yPos: visibleArea.yPosition
|
||||||
property bool canLoad: true
|
property bool canLoad: true
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ Rectangle {
|
|||||||
eventList.canLoad = false
|
eventList.canLoad = false
|
||||||
|
|
||||||
py.callClientCoro(
|
py.callClientCoro(
|
||||||
chatPage.userId, "load_past_events", [chatPage.roomId],
|
chat.userId, "load_past_events", [chat.roomId],
|
||||||
moreToLoad => {
|
moreToLoad => {
|
||||||
try {
|
try {
|
||||||
eventList.canLoad = moreToLoad
|
eventList.canLoad = moreToLoad
|
||||||
@ -155,7 +155,7 @@ Rectangle {
|
|||||||
model: HListModel {
|
model: HListModel {
|
||||||
keyField: "client_id"
|
keyField: "client_id"
|
||||||
source: modelSources[[
|
source: modelSources[[
|
||||||
"Event", chatPage.userId, chatPage.roomId
|
"Event", chat.userId, chat.roomId
|
||||||
]] || []
|
]] || []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ Rectangle {
|
|||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
text: {
|
text: {
|
||||||
let tm = chatPage.roomInfo.typing_members
|
let tm = chat.roomInfo.typing_members
|
||||||
|
|
||||||
if (tm.length == 0) return ""
|
if (tm.length == 0) return ""
|
||||||
if (tm.length == 1) return qsTr("%1 is typing...").arg(tm[0])
|
if (tm.length == 1) return qsTr("%1 is typing...").arg(tm[0])
|
||||||
|
@ -5,10 +5,10 @@ import "../utils.js" as Utils
|
|||||||
|
|
||||||
HDrawer {
|
HDrawer {
|
||||||
id: sidePane
|
id: sidePane
|
||||||
clip: true
|
|
||||||
opacity: mainUI.accountsPresent ? 1 : 0
|
opacity: mainUI.accountsPresent ? 1 : 0
|
||||||
color: theme.sidePane.background
|
color: theme.sidePane.background
|
||||||
normalWidth: window.uiState.sidePaneManualWidth
|
normalWidth: window.uiState.sidePaneManualWidth
|
||||||
|
minNormalWidth: theme.controls.avatar.size + theme.spacing * 2
|
||||||
|
|
||||||
onUserResized: {
|
onUserResized: {
|
||||||
window.uiState.sidePaneManualWidth = newWidth
|
window.uiState.sidePaneManualWidth = newWidth
|
||||||
@ -48,6 +48,11 @@ HDrawer {
|
|||||||
SidePaneToolBar {
|
SidePaneToolBar {
|
||||||
id: toolBar
|
id: toolBar
|
||||||
sidePaneList: sidePaneList
|
sidePaneList: sidePaneList
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
Layout.preferredHeight: theme.baseElementsHeight
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,6 @@ HRowLayout {
|
|||||||
readonly property alias filterField: filterField
|
readonly property alias filterField: filterField
|
||||||
property alias roomFilter: filterField.text
|
property alias roomFilter: filterField.text
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.minimumHeight: theme.baseElementsHeight
|
|
||||||
Layout.maximumHeight: Layout.minimumHeight
|
|
||||||
|
|
||||||
HButton {
|
HButton {
|
||||||
id: addAccountButton
|
id: addAccountButton
|
||||||
icon.name: "add-account"
|
icon.name: "add-account"
|
||||||
|
@ -56,7 +56,6 @@ Item {
|
|||||||
|
|
||||||
SidePane {
|
SidePane {
|
||||||
id: sidePane
|
id: sidePane
|
||||||
maxNormalWidth: parent.width - theme.minimumSupportedWidth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HLoader {
|
HLoader {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user