You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nheko/qml/TimelineView.qml

277 lines
8.3 KiB

// SPDX-FileCopyrightText: 2021 Nheko Contributors
// SPDX-FileCopyrightText: 2022 Nheko Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
import "components"
import "delegates"
import "device-verification"
import "emoji"
import "ui"
import "voip"
import Qt.labs.platform 1.1 as Platform
import QtQuick 2.15
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQuick.Window 2.13
import im.nheko
import im.nheko
Item {
id: timelineView
property var room: null
property var roomPreview: null
property bool showBackButton: false
clip: true
Shortcut {
sequence: StandardKey.Close
onActivated: Rooms.resetCurrentRoom()
}
Label {
anchors.centerIn: parent
color: timelineRoot.palette.text
font.pointSize: 24
text: qsTr("No room open")
visible: !room && !TimelineManager.isInitialSync && (!roomPreview || !roomPreview.roomid)
}
Spinner {
anchors.centerIn: parent
foreground: timelineRoot.palette.mid
// height is somewhat arbitrary here... don't set width because width scales w/ height
height: parent.height / 16
running: TimelineManager.isInitialSync
visible: TimelineManager.isInitialSync
z: 3
}
ColumnLayout {
id: timelineLayout
anchors.fill: parent
enabled: visible
spacing: 0
visible: room != null && !room.isSpace
TopBar {
showBackButton: timelineView.showBackButton
}
Rectangle {
Layout.fillWidth: true
color: Nheko.theme.separator
height: 1
z: 3
}
Rectangle {
id: msgView
Layout.fillHeight: true
Layout.fillWidth: true
color: timelineRoot.palette.base
ColumnLayout {
anchors.fill: parent
spacing: 0
StackLayout {
id: stackLayout
currentIndex: 0
Connections {
function onRoomChanged() {
stackLayout.currentIndex = 0;
}
target: timelineView
}
MessageView {
Layout.fillWidth: true
implicitHeight: msgView.height - typingIndicator.height
}
Loader {
source: CallManager.isOnCall && CallManager.callType != Voip.VOICE ? "voip/VideoCall.qml" : ""
onLoaded: TimelineManager.setVideoCallItem()
}
}
TypingIndicator {
id: typingIndicator
}
}
}
CallInviteBar {
id: callInviteBar
Layout.fillWidth: true
z: 3
}
ActiveCallBar {
Layout.fillWidth: true
z: 3
}
Rectangle {
Layout.fillWidth: true
color: Nheko.theme.separator
height: 1
z: 3
}
UploadBox {
}
NotificationWarning {
}
ReplyPopup {
}
MessageInput {
}
}
ColumnLayout {
id: preview
property string avatarUrl: room ? room.roomAvatarUrl : (roomPreview ? roomPreview.roomAvatarUrl : "")
property string roomId: room ? room.roomId : (roomPreview ? roomPreview.roomid : "")
property string roomName: room ? room.roomName : (roomPreview ? roomPreview.roomName : "")
property string roomTopic: room ? room.roomTopic : (roomPreview ? roomPreview.roomTopic : "")
anchors.fill: parent
anchors.margins: Nheko.paddingLarge
enabled: visible
spacing: Nheko.paddingLarge
visible: room != null && room.isSpace || roomPreview != null
Item {
Layout.fillHeight: true
}
Avatar {
Layout.alignment: Qt.AlignHCenter
displayName: parent.roomName
enabled: false
height: 130
roomid: parent.roomId
url: parent.avatarUrl.replace("mxc://", "image://MxcImage/")
width: 130
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Nheko.paddingMedium
MatrixText {
font.pixelSize: 24
text: preview.roomName == "" ? qsTr("No preview available") : preview.roomName
}
ImageButton {
ToolTip.text: qsTr("Settings")
ToolTip.visible: hovered
hoverEnabled: true
image: ":/icons/icons/ui/settings.svg"
visible: !!room
onClicked: TimelineManager.openRoomSettings(room.roomId)
}
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Nheko.paddingMedium
visible: !!room
MatrixText {
cursorShape: Qt.PointingHandCursor
text: qsTr("%1 member(s)").arg(room ? room.roomMemberCount : 0)
}
ImageButton {
ToolTip.text: qsTr("View members of %1").arg(room.roomName)
ToolTip.visible: hovered
hoverEnabled: true
image: ":/icons/icons/ui/people.svg"
onClicked: TimelineManager.openRoomMembers(room)
}
}
ScrollView {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: Nheko.paddingLarge
Layout.rightMargin: Nheko.paddingLarge
TextArea {
background: null
color: timelineRoot.palette.text
horizontalAlignment: TextEdit.AlignHCenter
readOnly: true
selectByMouse: true
text: TimelineManager.escapeEmoji(preview.roomTopic)
textFormat: TextEdit.RichText
wrapMode: TextEdit.WordWrap
onLinkActivated: Nheko.openLink(link)
NhekoCursorShape {
anchors.fill: parent
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}
FlatButton {
Layout.alignment: Qt.AlignHCenter
text: qsTr("join the conversation")
visible: roomPreview && !roomPreview.isInvite
onClicked: Rooms.joinPreview(roomPreview.roomid)
}
FlatButton {
Layout.alignment: Qt.AlignHCenter
text: qsTr("accept invite")
visible: roomPreview && roomPreview.isInvite
onClicked: Rooms.acceptInvite(roomPreview.roomid)
}
FlatButton {
Layout.alignment: Qt.AlignHCenter
text: qsTr("decline invite")
visible: roomPreview && roomPreview.isInvite
onClicked: Rooms.declineInvite(roomPreview.roomid)
}
Item {
Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 2)
visible: room != null
}
Item {
Layout.fillHeight: true
}
}
ImageButton {
id: backToRoomsButton
ToolTip.text: qsTr("Back to room list")
ToolTip.visible: hovered
anchors.left: parent.left
anchors.margins: Nheko.paddingMedium
anchors.top: parent.top
enabled: visible
height: Nheko.avatarSize
image: ":/icons/icons/ui/angle-arrow-left.svg"
visible: (room == null || room.isSpace) && showBackButton
width: Nheko.avatarSize
onClicked: Rooms.resetCurrentRoom()
}
NhekoDropArea {
anchors.fill: parent
roomid: room ? room.roomId : ""
}
Connections {
function onOpenReadReceiptsDialog(rr) {
var dialog = readReceiptsDialog.createObject(timelineRoot, {
"readReceipts": rr,
"room": room
});
dialog.show();
timelineRoot.destroyOnClose(dialog);
}
function onShowRawMessageDialog(rawMessage) {
var dialog = rawMessageDialog.createObject(timelineRoot, {
"rawMessage": rawMessage
});
dialog.show();
timelineRoot.destroyOnClose(dialog);
}
target: room
}
}