matrixion/resources/qml/TimelineView.qml

351 lines
10 KiB
QML
Raw Normal View History

2021-03-05 02:35:15 +03:00
// SPDX-FileCopyrightText: 2021 Nheko Contributors
// SPDX-FileCopyrightText: 2022 Nheko Contributors
2021-03-14 04:45:20 +03:00
//
2021-03-05 02:35:15 +03:00
// SPDX-License-Identifier: GPL-3.0-or-later
import "./components"
2020-10-08 22:11:21 +03:00
import "./delegates"
import "./device-verification"
import "./emoji"
2021-03-12 07:09:57 +03:00
import "./ui"
2021-07-10 18:21:15 +03:00
import "./voip"
2021-03-15 00:22:52 +03:00
import Qt.labs.platform 1.1 as Platform
import QtQuick 2.9
2021-06-13 02:48:11 +03:00
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQuick.Window 2.13
import im.nheko 1.0
2020-05-14 03:19:15 +03:00
import im.nheko.EmojiModel 1.0
Item {
id: timelineView
2021-04-27 12:08:21 +03:00
property var room: null
property var roomPreview: null
2021-06-08 23:18:51 +03:00
property bool showBackButton: false
Label {
visible: !room && !TimelineManager.isInitialSync && (!roomPreview || !roomPreview.roomid)
anchors.centerIn: parent
text: qsTr("No room open")
font.pointSize: 24
color: Nheko.colors.text
2021-04-11 17:31:49 +03:00
}
2021-03-12 07:09:57 +03:00
Spinner {
2021-03-15 02:22:33 +03:00
visible: TimelineManager.isInitialSync
anchors.centerIn: parent
foreground: Nheko.colors.mid
running: TimelineManager.isInitialSync
2021-03-12 07:09:57 +03:00
// height is somewhat arbitrary here... don't set width because width scales w/ height
height: parent.height / 16
z: 3
}
ColumnLayout {
id: timelineLayout
2021-04-11 23:24:39 +03:00
2021-06-18 17:22:06 +03:00
visible: room != null && !room.isSpace
enabled: visible
2020-10-08 22:11:21 +03:00
anchors.fill: parent
spacing: 0
2021-01-12 22:22:52 +03:00
TopBar {
2021-06-08 23:18:51 +03:00
showBackButton: timelineView.showBackButton
2020-10-08 22:11:21 +03:00
}
Rectangle {
Layout.fillWidth: true
height: 1
2020-10-08 22:11:21 +03:00
z: 3
2021-05-15 00:35:34 +03:00
color: Nheko.theme.separator
2020-10-08 22:11:21 +03:00
}
Rectangle {
id: msgView
2021-01-26 08:03:09 +03:00
Layout.fillWidth: true
Layout.fillHeight: true
color: Nheko.colors.base
2020-10-08 22:11:21 +03:00
ColumnLayout {
anchors.fill: parent
spacing: 0
2020-11-15 06:52:49 +03:00
StackLayout {
id: stackLayout
2020-10-08 22:11:21 +03:00
currentIndex: 0
2020-11-15 06:52:49 +03:00
Connections {
function onRoomChanged() {
stackLayout.currentIndex = 0;
2020-10-08 22:11:21 +03:00
}
target: timelineView
}
2020-11-15 06:52:49 +03:00
2021-08-29 20:24:44 +03:00
MessageView {
implicitHeight: msgView.height - typingIndicator.height
Layout.fillWidth: true
}
2021-08-11 05:16:27 +03:00
Loader {
source: CallManager.isOnCall && CallManager.callType != CallType.VOICE ? "voip/VideoCall.qml" : ""
onLoaded: TimelineManager.setVideoCallItem()
2020-10-27 20:14:06 +03:00
}
2020-10-08 22:11:21 +03:00
}
TypingIndicator {
id: typingIndicator
}
2021-01-12 01:51:39 +03:00
2020-12-17 19:25:32 +03:00
}
}
2020-10-08 22:11:21 +03:00
CallInviteBar {
id: callInviteBar
2020-10-08 22:11:21 +03:00
Layout.fillWidth: true
z: 3
}
2020-10-26 15:50:44 +03:00
ActiveCallBar {
Layout.fillWidth: true
z: 3
}
Rectangle {
Layout.fillWidth: true
z: 3
height: 1
2021-05-15 00:35:34 +03:00
color: Nheko.theme.separator
}
2022-03-21 07:05:29 +03:00
Page {
id: uploadPopup
2022-03-21 00:49:33 +03:00
visible: room && room.input.uploads.length > 0
2022-03-21 07:05:29 +03:00
Layout.preferredHeight: 200
clip: true
Layout.fillWidth: true
padding: Nheko.paddingMedium
contentItem: ListView {
id: uploadsList
anchors.horizontalCenter: parent.horizontalCenter
boundsBehavior: Flickable.StopAtBounds
orientation: ListView.Horizontal
width: Math.min(contentWidth, parent.width)
model: room ? room.input.uploads : undefined
spacing: Nheko.paddingMedium
delegate: Pane {
padding: Nheko.paddingSmall
height: uploadPopup.availableHeight - buttons.height
width: uploadPopup.availableHeight - buttons.height
background: Rectangle {
color: Nheko.colors.window
radius: Nheko.paddingMedium
}
contentItem: ColumnLayout {
Image {
Layout.fillHeight: true
Layout.fillWidth: true
sourceSize.height: height
sourceSize.width: width
property string typeStr: switch(modelData.mediaType) {
case MediaUpload.Video: return "video-file";
case MediaUpload.Audio: return "music";
case MediaUpload.Image: return "image";
default: return "zip";
}
source: "image://colorimage/:/icons/icons/ui/"+typeStr+".svg?" + Nheko.colors.buttonText
}
MatrixTextField {
Layout.fillWidth: true
text: modelData.filename
onTextEdited: modelData.filename = text
}
}
}
}
footer: DialogButtonBox {
id: buttons
standardButtons: DialogButtonBox.Cancel
Button {
text: qsTr("Upload %n file(s)", "", (room ? room.input.uploads.length : 0))
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
}
onAccepted: room.input.acceptUploads()
onRejected: room.input.declineUploads()
}
background: Rectangle {
color: Nheko.colors.base
}
2022-03-21 00:49:33 +03:00
}
NotificationWarning {
}
ReplyPopup {
2021-02-03 03:30:03 +03:00
}
2020-10-26 15:50:44 +03:00
MessageInput {
2020-10-08 22:11:21 +03:00
}
}
2021-06-18 17:22:06 +03:00
ColumnLayout {
id: preview
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 : "")
property string avatarUrl: room ? room.roomAvatarUrl : (roomPreview ? roomPreview.roomAvatarUrl : "")
visible: room != null && room.isSpace || roomPreview != null
2021-06-18 17:22:06 +03:00
enabled: visible
anchors.fill: parent
anchors.margins: Nheko.paddingLarge
spacing: Nheko.paddingLarge
Item {
Layout.fillHeight: true
}
2021-06-18 17:22:06 +03:00
Avatar {
url: parent.avatarUrl.replace("mxc://", "image://MxcImage/")
2021-09-08 03:38:39 +03:00
roomid: parent.roomId
displayName: parent.roomName
2021-06-18 17:22:06 +03:00
height: 130
width: 130
Layout.alignment: Qt.AlignHCenter
enabled: false
}
2021-07-17 20:31:38 +03:00
2021-06-18 17:22:06 +03:00
MatrixText {
text: parent.roomName == "" ? qsTr("No preview available") : parent.roomName
2021-06-18 17:22:06 +03:00
font.pixelSize: 24
Layout.alignment: Qt.AlignHCenter
}
MatrixText {
visible: !!room
2021-06-18 17:22:06 +03:00
text: qsTr("%1 member(s)").arg(room ? room.roomMemberCount : 0)
Layout.alignment: Qt.AlignHCenter
}
ScrollView {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: Nheko.paddingLarge
Layout.rightMargin: Nheko.paddingLarge
2021-06-18 17:22:06 +03:00
TextArea {
text: TimelineManager.escapeEmoji(preview.roomTopic)
2021-06-18 17:22:06 +03:00
wrapMode: TextEdit.WordWrap
textFormat: TextEdit.RichText
readOnly: true
background: null
selectByMouse: true
color: Nheko.colors.text
horizontalAlignment: TextEdit.AlignHCenter
onLinkActivated: Nheko.openLink(link)
CursorShape {
anchors.fill: parent
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}
FlatButton {
visible: roomPreview && !roomPreview.isInvite
Layout.alignment: Qt.AlignHCenter
text: qsTr("join the conversation")
onClicked: Rooms.joinPreview(roomPreview.roomid)
}
FlatButton {
visible: roomPreview && roomPreview.isInvite
Layout.alignment: Qt.AlignHCenter
text: qsTr("accept invite")
onClicked: Rooms.acceptInvite(roomPreview.roomid)
}
FlatButton {
visible: roomPreview && roomPreview.isInvite
Layout.alignment: Qt.AlignHCenter
text: qsTr("decline invite")
onClicked: Rooms.declineInvite(roomPreview.roomid)
}
Item {
visible: room != null
Layout.preferredHeight: Math.ceil(fontMetrics.lineSpacing * 2)
}
2021-06-18 17:22:06 +03:00
Item {
Layout.fillHeight: true
}
}
ImageButton {
id: backToRoomsButton
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: Nheko.paddingMedium
width: Nheko.avatarSize
height: Nheko.avatarSize
visible: (room == null || room.isSpace) && showBackButton
enabled: visible
2021-11-14 04:23:10 +03:00
image: ":/icons/icons/ui/angle-arrow-left.svg"
ToolTip.visible: hovered
ToolTip.text: qsTr("Back to room list")
onClicked: Rooms.resetCurrentRoom()
}
NhekoDropArea {
anchors.fill: parent
2021-07-17 23:56:56 +03:00
roomid: room ? room.roomId : ""
}
Connections {
function onOpenReadReceiptsDialog(rr) {
var dialog = readReceiptsDialog.createObject(timelineRoot, {
"readReceipts": rr,
"room": room
});
dialog.show();
timelineRoot.destroyOnClose(dialog);
}
2021-07-31 05:13:58 +03:00
function onShowRawMessageDialog(rawMessage) {
var dialog = rawMessageDialog.createObject(timelineRoot, {
"rawMessage": rawMessage
});
dialog.show();
timelineRoot.destroyOnClose(dialog);
2021-07-31 05:13:58 +03:00
}
target: room
}
2019-08-30 20:29:25 +03:00
}