diff --git a/src/gui/Pages/Chat/Banners/Banner.qml b/src/gui/Pages/Chat/Banners/Banner.qml deleted file mode 100644 index 59d4c54c..00000000 --- a/src/gui/Pages/Chat/Banners/Banner.qml +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright Mirage authors & contributors -// SPDX-License-Identifier: LGPL-3.0-or-later - -import QtQuick 2.12 -import QtQuick.Layouts 1.12 -import "../../../Base" - -Rectangle { - id: banner - - property alias avatar: bannerAvatar - property alias icon: bannerIcon - property alias labelText: bannerLabel.text - property alias buttonModel: bannerRepeater.model - property var buttonCallbacks: [] - - implicitHeight: childrenRect.height - color: theme.controls.box.background - - HGridLayout { - id: bannerGrid - width: parent.width - flow: bannerAvatarWrapper.width + - bannerIcon.width + - bannerLabel.implicitWidth + - bannerButtons.width > - parent.width ? - GridLayout.TopToBottom : GridLayout.LeftToRight - - HRowLayout { - id: bannerRow - - Rectangle { - id: bannerAvatarWrapper - color: "black" - - Layout.preferredWidth: bannerAvatar.width - Layout.minimumHeight: bannerAvatar.height - Layout.preferredHeight: bannerLabel.height - - HUserAvatar { - id: bannerAvatar - clientUserId: chat.userId - anchors.centerIn: parent - radius: 0 - } - } - - HIcon { - id: bannerIcon - visible: Boolean(svgName) - - Layout.leftMargin: theme.spacing / 2 - } - - HLabel { - id: bannerLabel - textFormat: Text.StyledText - wrapMode: HLabel.Wrap - - Layout.fillWidth: true - Layout.leftMargin: bannerIcon.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - } - - HSpacer {} - } - - HRowLayout { - HRowLayout { - id: bannerButtons - - Repeater { - id: bannerRepeater - model: [] - - HButton { - id: button - - readonly property bool shouldFocus: - banner.visible && model.index === 0 - - text: modelData.text - icon.name: modelData.iconName - icon.color: modelData.iconColor || theme.icons.colorize - onClicked: buttonCallbacks[modelData.name](button) - - Layout.preferredHeight: theme.baseElementsHeight - - onShouldFocusChanged: - if (shouldFocus) forceActiveFocus() - } - } - } - - Rectangle { - id: buttonsRightPadding - color: theme.controls.button.background - visible: bannerGrid.flow === GridLayout.TopToBottom - - Layout.fillWidth: true - Layout.fillHeight: true - } - } - } -} diff --git a/src/gui/Pages/Chat/Banners/InviteBanner.qml b/src/gui/Pages/Chat/Banners/InviteBanner.qml deleted file mode 100644 index 830ab35c..00000000 --- a/src/gui/Pages/Chat/Banners/InviteBanner.qml +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright Mirage authors & contributors -// SPDX-License-Identifier: LGPL-3.0-or-later - -import QtQuick 2.12 -import "../../../Base" - -Banner { - id: root - - property string inviterId: chat.roomInfo.inviter - property string inviterName: chat.roomInfo.inviter_name - property string inviterAvatar: chat.roomInfo.inviter_avatar - - color: theme.chat.inviteBanner.background - - avatar.userId: inviterId - avatar.displayName: inviterName - avatar.mxc: inviterAvatar - - labelText: qsTr("%1 invited you to this room").arg( - utils.coloredNameHtml(inviterName, inviterId) - ) - - buttonModel: [ - { - name: "accept", - text: qsTr("Join"), - iconName: "invite-accept", - iconColor: theme.colors.positiveBackground - }, - { - name: "decline", - text: qsTr("Decline"), - iconName: "invite-decline", - iconColor: theme.colors.negativeBackground - } - ] - - buttonCallbacks: ({ - accept: button => { - button.loading = true - py.callClientCoro( - chat.userId, "join", [chat.roomId], () => { - button.loading = false - }) - }, - - decline: button => { - window.makePopup( - "Popups/LeaveRoomPopup.qml", - { - userId: chat.userId, - roomId: chat.roomId, - roomName: chat.roomInfo.display_name, - inviterId: root.inviterId, - left: chat.roomInfo.left, - leftCallback: () => { button.loading = true }, - }, - ) - } - }) -} diff --git a/src/gui/Pages/Chat/Banners/LeftBanner.qml b/src/gui/Pages/Chat/Banners/LeftBanner.qml deleted file mode 100644 index 0949d221..00000000 --- a/src/gui/Pages/Chat/Banners/LeftBanner.qml +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright Mirage authors & contributors -// SPDX-License-Identifier: LGPL-3.0-or-later - -import QtQuick 2.12 -import "../../../Base" - -Banner { - color: theme.chat.leftBanner.background - - // TODO: avatar func auto - avatar.userId: chat.userId - avatar.displayName: chat.userInfo.display_name - avatar.mxc: chat.userInfo.avatar_url - labelText: qsTr("You are no longer part of this room") - - buttonModel: [ - { - name: "forget", - text: qsTr("Forget"), - iconName: "room-forget", - iconColor: theme.colors.negativeBackground - } - ] - - buttonCallbacks: ({ - forget: button => { - window.makePopup( - "Popups/LeaveRoomPopup.qml", - { - userId: chat.userId, - roomId: chat.roomId, - roomName: chat.roomInfo.display_name, - inviterId: chat.roomInfo.inviter_id, - left: true, - }, - obj => { - obj.onOk.connect(() => { button.loading = true }) // FIXME - }, - false, - ) - } - }) -} diff --git a/src/gui/Pages/Chat/Banners/UnknownDevicesBanner.qml b/src/gui/Pages/Chat/Banners/UnknownDevicesBanner.qml deleted file mode 100644 index e18e6ace..00000000 --- a/src/gui/Pages/Chat/Banners/UnknownDevicesBanner.qml +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright Mirage authors & contributors -// SPDX-License-Identifier: LGPL-3.0-or-later - -import QtQuick 2.12 -import "../../../Base" - -Banner { - color: theme.chat.unknownDevices.background - - avatar.visible: false - icon.svgName: "unknown-devices-warning" - labelText: qsTr("Unknown devices are present in this encrypted room") - - buttonModel: [ - { - name: "inspect", - text: qsTr("Inspect"), - iconName: "unknown-devices-inspect", - } - ] - - buttonCallbacks: ({ - inspect: button => { - print("show") - } - }) -} diff --git a/src/gui/Pages/Chat/ChatPage.qml b/src/gui/Pages/Chat/ChatPage.qml index c224acae..b63d03d5 100644 --- a/src/gui/Pages/Chat/ChatPage.qml +++ b/src/gui/Pages/Chat/ChatPage.qml @@ -5,7 +5,6 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 import "../../Base" import "AutoCompletion" -import "Banners" import "Composer" import "FileTransfer" import "Timeline" @@ -23,8 +22,6 @@ HColumnPage { readonly property alias reply: reply readonly property alias transfers: transfers readonly property alias userCompletion: userCompletion - readonly property alias inviteBanner: inviteBanner - readonly property alias leftBanner: leftBanner readonly property alias composer: composer readonly property DropArea uploadDropArea: UploadDropArea { @@ -118,26 +115,10 @@ HColumnPage { Layout.maximumHeight: chatPage.height / 4 } - InviteBanner { - id: inviteBanner - visible: ! chat.roomInfo.left && inviterId - inviterId: chat.roomInfo.inviter_id - - Layout.fillWidth: true - } - - LeftBanner { - id: leftBanner - visible: chat.roomInfo.left - - Layout.fillWidth: true - } - Composer { id: composer userCompletion: userCompletion eventList: eventList.eventList - visible: ! chat.roomInfo.left && ! chat.roomInfo.inviter_id Layout.fillWidth: true Layout.maximumHeight: parent.height / 2 diff --git a/src/gui/Pages/Chat/Composer/Composer.qml b/src/gui/Pages/Chat/Composer/Composer.qml index d8fe5190..6ddbda51 100644 --- a/src/gui/Pages/Chat/Composer/Composer.qml +++ b/src/gui/Pages/Chat/Composer/Composer.qml @@ -5,18 +5,33 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 import "../../.." import "../../../Base" +import "../../../Base/Buttons" import "../AutoCompletion" Rectangle { - id: composer + id: root property UserAutoCompletion userCompletion property alias eventList: messageArea.eventList - readonly property bool hasFocus: messageArea.activeFocus + readonly property bool widthStarved: width < 384 * theme.uiScale + readonly property bool parted: chat.roomInfo.left + readonly property string inviterId: chat.roomInfo.inviter_id + readonly property string inviterColoredName: + utils.coloredNameHtml(chat.roomInfo.inviter_name, inviterId) + + readonly property bool hasFocus: + messageArea.activeFocus || + joinButton.activeFocus || + exitButton.activeFocus + readonly property alias messageArea: messageArea - function takeFocus() { messageArea.forceActiveFocus() } + function takeFocus() { + joinButton.visible ? joinButton.forceActiveFocus() : + exitButton.visible ? exitButton.forceActiveFocus() : + messageArea.forceActiveFocus() + } implicitHeight: Math.max(theme.baseElementsHeight, row.implicitHeight) color: theme.chat.composer.background @@ -39,6 +54,10 @@ Rectangle { } HScrollView { + enabled: visible + visible: ! root.inviterId && ! root.parted + onVisibleChanged: if (root.hasFocus) root.takeFocus() + Layout.fillHeight: true Layout.fillWidth: true @@ -59,7 +78,85 @@ Rectangle { } UploadButton { + visible: ! root.inviterId && ! root.parted + onVisibleChanged: if (root.hasFocus) root.takeFocus() + Layout.fillHeight: true } + + HLabel { + textFormat: Text.StyledText + wrapMode: HLabel.Wrap + visible: root.inviterId || root.parted + verticalAlignment: HLabel.AlignVCenter + text: + root.parted && root.inviterId ? + qsTr("Declined %1's invite").arg(root.inviterColoredName) : + + root.parted ? + qsTr("No longer part of this room") : + + qsTr("Invited by %1").arg(root.inviterColoredName) + + leftPadding: theme.spacing + rightPadding: leftPadding + topPadding: theme.spacing / 2 + bottomPadding: topPadding + + + onVisibleChanged: if (root.hasFocus) root.takeFocus() + + Layout.fillWidth: true + Layout.fillHeight: true + } + + ApplyButton { + id: joinButton + icon.name: "invite-accept" + text: widthStarved ? "" : qsTr("Join") + visible: root.inviterId && ! root.parted + onVisibleChanged: if (root.hasFocus) root.takeFocus() + + onClicked: { + loading = true + function callback() { joinButton.loading = false } + py.callClientCoro(chat.userId, "join", [chat.roomId], callback) + } + + Layout.fillWidth: false + Layout.fillHeight: true + + Behavior on implicitWidth { HNumberAnimation {} } + } + + CancelButton { + id: exitButton + icon.name: root.parted ? "room-forget" : "invite-decline" + visible: root.inviterId || root.parted + text: + widthStarved ? "" : + root.parted ? qsTr("Forget") : + qsTr("Decline") + + onVisibleChanged: if (root.hasFocus) root.takeFocus() + + onClicked: { + loading = true + + window.makePopup("Popups/LeaveRoomPopup.qml", { + userId: chat.userId, + roomId: chat.roomId, + roomName: chat.roomInfo.display_name, + inviterId: root.inviterId, + left: root.parted, + doneCallback: () => { exitButton.loading = false }, + }) + } + + Layout.fillWidth: false + Layout.fillHeight: true + + Behavior on implicitWidth { HNumberAnimation {} } + } } } diff --git a/src/gui/Pages/Chat/UploadDropArea.qml b/src/gui/Pages/Chat/UploadDropArea.qml index 80ad89f9..b3139789 100644 --- a/src/gui/Pages/Chat/UploadDropArea.qml +++ b/src/gui/Pages/Chat/UploadDropArea.qml @@ -5,7 +5,6 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 import "../../Base" import "AutoCompletion" -import "Banners" import "Composer" import "FileTransfer" import "Timeline" diff --git a/src/gui/Popups/LeaveRoomPopup.qml b/src/gui/Popups/LeaveRoomPopup.qml index a4345f33..5a364048 100644 --- a/src/gui/Popups/LeaveRoomPopup.qml +++ b/src/gui/Popups/LeaveRoomPopup.qml @@ -14,7 +14,7 @@ HFlickableColumnPopup { property string roomName: "" property string inviterId: "" property bool left: false - property var leftCallback: null + property var doneCallback: null function ignoreInviter() { if (! inviterId) return @@ -23,7 +23,7 @@ HFlickableColumnPopup { function leave() { leaveButton.loading = true - py.callClientCoro(userId, "room_leave", [roomId], leftCallback) + py.callClientCoro(userId, "room_leave", [roomId], doneCallback) if (ignoreInviterCheck.checked) popup.ignoreInviter() popup.close() } @@ -67,6 +67,7 @@ HFlickableColumnPopup { } onOpened: leaveButton.forceActiveFocus() + onClosed: if (doneCallback) doneCallback() SummaryLabel { readonly property string roomText: