Spectral/imports/Spectral/Panel/RoomPanel.qml

303 lines
8.9 KiB
QML
Raw Normal View History

2018-12-07 01:18:42 +00:00
import QtQuick 2.12
2018-12-22 14:25:03 +00:00
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls.Material 2.12
2018-12-06 11:12:42 +00:00
import Qt.labs.qmlmodels 1.0
2018-11-17 14:39:34 +00:00
import Spectral.Component 2.0
import Spectral.Component.Emoji 2.0
import Spectral.Component.Timeline 2.0
import Spectral.Effect 2.0
import Spectral 0.1
import Spectral.Setting 0.1
import SortFilterProxyModel 0.2
Item {
property var currentRoom: null
id: root
MessageEventModel {
id: messageEventModel
room: currentRoom
}
2019-04-30 09:02:00 +00:00
Column {
2018-11-17 14:39:34 +00:00
anchors.centerIn: parent
2019-04-30 09:02:00 +00:00
spacing: 16
2018-11-17 14:39:34 +00:00
visible: !currentRoom
2019-04-30 09:02:00 +00:00
Image {
anchors.horizontalCenter: parent.horizontalCenter
width: 240
fillMode: Image.PreserveAspectFit
source: "qrc:/assets/img/matrix.svg"
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: "Welcome to Matrix, a new era of instant messaging."
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: "To start chatting, select a room from the room list."
}
2018-11-17 14:39:34 +00:00
}
Image {
anchors.fill: parent
2019-04-30 09:02:00 +00:00
visible: currentRoom && MSettings.timelineBackground
2019-04-30 09:02:00 +00:00
source: MSettings.timelineBackground
2018-11-17 14:39:34 +00:00
fillMode: Image.PreserveAspectCrop
}
Rectangle {
anchors.fill: parent
visible: currentRoom && !MSettings.timelineBackground
color: MSettings.darkTheme ? "#242424" : "#EBEFF2"
}
2018-11-17 14:39:34 +00:00
ColumnLayout {
anchors.fill: parent
spacing: 0
visible: currentRoom
RoomHeader {
Layout.fillWidth: true
Layout.preferredHeight: 64
z: 10
id: roomHeader
onClicked: roomDrawer.visible ? roomDrawer.close() : roomDrawer.open()
}
2018-12-23 03:24:01 +00:00
ColumnLayout {
2018-11-17 14:39:34 +00:00
Layout.fillWidth: true
Layout.fillHeight: true
2018-12-23 03:24:01 +00:00
Layout.maximumWidth: 960
Layout.alignment: Qt.AlignHCenter
2018-11-17 14:39:34 +00:00
Layout.leftMargin: 16
Layout.rightMargin: 16
2018-12-23 03:24:01 +00:00
Layout.bottomMargin: 16
width: Math.min(parent.width - 32, 960)
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
spacing: 16
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
2018-12-23 03:24:01 +00:00
id: messageListView
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
spacing: 4
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
displayMarginBeginning: 100
displayMarginEnd: 100
verticalLayoutDirection: ListView.BottomToTop
highlightMoveDuration: 500
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
boundsBehavior: Flickable.DragOverBounds
model: SortFilterProxyModel {
id: sortedMessageEventModel
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
sourceModel: messageEventModel
filters: [
ExpressionFilter {
expression: marks !== 0x10 && eventType !== "other"
}
]
2018-12-23 03:24:01 +00:00
onModelReset: {
if (currentRoom) {
var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex())
messageListView.currentIndex = lastScrollPosition
if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20)
currentRoom.getPreviousContent(50)
}
2018-11-17 14:39:34 +00:00
}
}
2018-12-23 03:24:01 +00:00
property int largestVisibleIndex: count > 0 ? indexAt(contentX, contentY + height - 1) : -1
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
onContentYChanged: {
if(currentRoom && contentY - 5000 < originY)
currentRoom.getPreviousContent(20);
}
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
displaced: Transition {
NumberAnimation {
property: "y"; duration: 200
easing.type: Easing.OutQuad
}
2018-11-17 14:39:34 +00:00
}
2018-12-23 03:24:01 +00:00
delegate: DelegateChooser {
role: "eventType"
2018-12-07 01:18:42 +00:00
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "state"
delegate: StateDelegate {
anchors.horizontalCenter: parent.horizontalCenter
2018-12-07 01:18:42 +00:00
width: Math.min(implicitWidth, parent.width)
2018-12-07 01:18:42 +00:00
}
}
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "emote"
delegate: StateDelegate {
anchors.horizontalCenter: parent.horizontalCenter
2018-12-07 01:18:42 +00:00
width: Math.min(implicitWidth, parent.width)
2018-12-07 01:18:42 +00:00
}
}
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "message"
delegate: MessageDelegate {
anchors.right: sentByMe ? parent.right : undefined
2018-12-07 01:18:42 +00:00
}
}
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "notice"
delegate: MessageDelegate {
anchors.right: sentByMe ? parent.right : undefined
2018-12-07 01:18:42 +00:00
}
}
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "image"
delegate: ImageDelegate {
Layout.maximumWidth: parent.width
2018-12-22 14:25:03 +00:00
}
}
2018-12-23 03:24:01 +00:00
DelegateChoice {
roleValue: "file"
delegate: FileDelegate {
Layout.maximumWidth: parent.width
2018-12-07 01:18:42 +00:00
}
}
2019-05-06 01:31:57 +00:00
DelegateChoice {
roleValue: "other"
delegate: Item {}
}
2018-12-07 01:18:42 +00:00
}
2018-11-17 14:39:34 +00:00
2019-03-17 11:49:06 +00:00
Button {
2018-12-23 03:24:01 +00:00
anchors.top: parent.top
2019-03-17 11:49:06 +00:00
anchors.horizontalCenter: parent.horizontalCenter
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
visible: currentRoom && currentRoom.hasUnreadMessages
2018-11-17 14:39:34 +00:00
2019-03-17 11:49:06 +00:00
topPadding: 8
bottomPadding: 8
leftPadding: 24
rightPadding: 24
2018-11-17 14:39:34 +00:00
2019-03-17 11:49:06 +00:00
Material.foreground: MPalette.foreground
Material.background: MPalette.background
2018-11-17 14:39:34 +00:00
2019-03-17 11:49:06 +00:00
text: "Go to read marker"
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
onClicked: goToEvent(currentRoom.readMarkerEventId)
}
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
RoundButton {
width: 64
height: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
id: goTopFab
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
visible: !messageListView.atYEnd
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
contentItem: MaterialIcon {
anchors.fill: parent
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
icon: "\ue313"
color: "white"
}
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
Material.background: Material.accent
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
onClicked: messageListView.positionViewAtBeginning()
}
}
Control {
Layout.maximumWidth: parent.width * 0.8
visible: currentRoom && currentRoom.hasUsersTyping
padding: 8
contentItem: RowLayout {
spacing: 8
Repeater {
model: currentRoom && currentRoom.hasUsersTyping ? currentRoom.usersTyping : null
delegate: Avatar {
Layout.preferredWidth: 24
Layout.preferredHeight: 24
2019-01-04 12:17:26 +00:00
source: modelData.avatarMediaId
2018-12-23 03:24:01 +00:00
hint: modelData.displayName
}
}
BusyIndicator {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
2018-12-23 03:24:01 +00:00
}
}
background: Rectangle {
color: MPalette.background
2018-12-23 03:24:01 +00:00
radius: height / 2
2018-11-17 14:39:34 +00:00
}
}
2018-12-23 03:24:01 +00:00
RoomPanelInput {
Layout.fillWidth: true
2018-11-17 14:39:34 +00:00
2018-12-23 03:24:01 +00:00
id: roomPanelInput
}
2018-11-17 14:39:34 +00:00
}
}
2018-10-22 01:48:37 +00:00
function goToEvent(eventID) {
var index = messageEventModel.eventIDToIndex(eventID)
if (index === -1) return
2018-12-06 11:12:42 +00:00
// messageListView.currentIndex = sortedMessageEventModel.mapFromSource(index)
2019-05-06 13:32:16 +00:00
messageListView.positionViewAtIndex(sortedMessageEventModel.mapFromSource(index), ListView.Contain)
2018-10-22 01:48:37 +00:00
}
2018-11-02 11:05:15 +00:00
function saveReadMarker(room) {
var readMarker = sortedMessageEventModel.get(messageListView.largestVisibleIndex).eventId
if (!readMarker) return
room.readMarkerEventId = readMarker
currentRoom.saveViewport(sortedMessageEventModel.mapToSource(messageListView.indexAt(messageListView.contentX, messageListView.contentY)), sortedMessageEventModel.mapToSource(messageListView.largestVisibleIndex))
2018-11-02 11:05:15 +00:00
}
}