Spectral/imports/Spectral/Panel/RoomPanel.qml

372 lines
11 KiB
QML
Raw Normal View History

2018-12-07 01:18:42 +00:00
import QtQuick 2.12
import QtQuick.Controls 2.4
2018-11-17 14:39:34 +00:00
import QtQuick.Layouts 1.3
2018-12-07 01:18:42 +00:00
import QtQuick.Controls.Material 2.4
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
import "qrc:/js/md.js" as Markdown
Item {
property var currentRoom: null
id: root
MessageEventModel {
id: messageEventModel
room: currentRoom
}
2018-11-17 14:39:34 +00:00
RoomDrawer {
width: Math.min(root.width * 0.7, 480)
height: root.height
id: roomDrawer
room: currentRoom
}
Label {
anchors.centerIn: parent
visible: !currentRoom
text: "Please choose a room."
}
Image {
anchors.fill: parent
2018-11-26 10:49:03 +00:00
visible: currentRoom && MSettings.enableTimelineBackground
2018-11-26 10:49:03 +00:00
source: MSettings.timelineBackground || MSettings.darkTheme ? "qrc:/assets/img/roompanel-dark.svg" : "qrc:/assets/img/roompanel.svg"
2018-11-17 14:39:34 +00:00
fillMode: Image.PreserveAspectCrop
}
ColumnLayout {
anchors.fill: parent
spacing: 0
visible: currentRoom
RoomHeader {
Layout.fillWidth: true
Layout.preferredHeight: 64
z: 10
id: roomHeader
avatar: currentRoom ? currentRoom.avatarUrl : ""
2018-11-17 14:39:34 +00:00
topic: currentRoom ? (currentRoom.topic).replace(/(\r\n\t|\n|\r\t)/gm,"") : ""
atTop: messageListView.atYBeginning
onClicked: roomDrawer.open()
}
2018-11-17 14:39:34 +00:00
AutoListView {
Layout.fillWidth: true
Layout.maximumWidth: 960
Layout.fillHeight: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.alignment: Qt.AlignHCenter
id: messageListView
spacing: 4
2018-11-17 14:39:34 +00:00
displayMarginBeginning: 100
displayMarginEnd: 100
verticalLayoutDirection: ListView.BottomToTop
highlightMoveDuration: 500
2018-11-17 14:39:34 +00:00
boundsBehavior: Flickable.DragOverBounds
model: SortFilterProxyModel {
id: sortedMessageEventModel
sourceModel: messageEventModel
filters: ExpressionFilter {
2018-11-22 00:01:07 +00:00
expression: marks !== 0x10 && eventType !== "other"
2018-11-17 14:39:34 +00:00
}
onModelReset: {
if (currentRoom) {
var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex())
messageListView.currentIndex = lastScrollPosition
if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20)
2018-11-22 09:15:14 +00:00
currentRoom.getPreviousContent(50)
2018-11-17 14:39:34 +00:00
}
}
}
property int largestVisibleIndex: count > 0 ? indexAt(contentX, contentY + height - 1) : -1
onContentYChanged: {
if(currentRoom && contentY - 5000 < originY)
2018-11-22 09:15:14 +00:00
currentRoom.getPreviousContent(20);
2018-11-17 14:39:34 +00:00
}
displaced: Transition {
NumberAnimation {
property: "y"; duration: 200
easing.type: Easing.OutQuad
}
}
2018-12-07 01:18:42 +00:00
delegate: DelegateChooser {
role: "eventType"
DelegateChoice {
roleValue: "state"
delegate: ColumnLayout {
width: messageListView.width
spacing: 4
SectionDelegate {
Layout.alignment: Qt.AlignHCenter
Layout.margins: 4
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
StateDelegate {
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignHCenter
}
}
}
DelegateChoice {
roleValue: "emote"
delegate: ColumnLayout {
width: messageListView.width
spacing: 4
SectionDelegate {
Layout.alignment: Qt.AlignHCenter
Layout.margins: 4
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
StateDelegate {
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignHCenter
}
}
}
DelegateChoice {
roleValue: "message"
delegate: ColumnLayout {
width: messageListView.width
spacing: 4
SectionDelegate {
Layout.alignment: Qt.AlignHCenter
Layout.margins: 4
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
MessageDelegate {
}
}
}
DelegateChoice {
roleValue: "notice"
delegate: ColumnLayout {
width: messageListView.width
spacing: 4
SectionDelegate {
Layout.alignment: Qt.AlignHCenter
Layout.margins: 4
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
MessageDelegate {
}
}
}
DelegateChoice {
roleValue: "image"
delegate: ColumnLayout {
width: messageListView.width
spacing: 4
SectionDelegate {
Layout.alignment: Qt.AlignHCenter
Layout.margins: 4
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
ImageDelegate {
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignHCenter
}
}
}
}
2018-11-17 14:39:34 +00:00
RoundButton {
width: 64
height: 64
anchors.right: parent.right
anchors.top: parent.top
id: goBottomFab
visible: currentRoom && currentRoom.hasUnreadMessages
contentItem: MaterialIcon {
anchors.fill: parent
icon: "\ue316"
color: "white"
}
Material.background: Material.accent
onClicked: goToEvent(currentRoom.readMarkerEventId)
}
RoundButton {
width: 64
height: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
id: goTopFab
visible: !messageListView.atYEnd
contentItem: MaterialIcon {
anchors.fill: parent
icon: "\ue313"
color: "white"
}
Material.background: Material.accent
onClicked: messageListView.positionViewAtBeginning()
}
Popup {
property string sourceText
2018-12-06 11:12:42 +00:00
anchors.centerIn: parent
2018-11-17 14:39:34 +00:00
width: 480
id: sourceDialog
parent: ApplicationWindow.overlay
padding: 16
closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside
contentItem: ScrollView {
2018-12-06 11:12:42 +00:00
clip: true
2018-11-17 14:39:34 +00:00
TextArea {
readOnly: true
selectByMouse: true
text: sourceDialog.sourceText
}
}
}
Popup {
property alias listModel: readMarkerListView.model
x: (window.width - width) / 2
y: (window.height - height) / 2
width: 320
id: readMarkerDialog
parent: ApplicationWindow.overlay
modal: true
padding: 16
closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside
contentItem: AutoListView {
implicitHeight: Math.min(window.height - 64,
readMarkerListView.contentHeight)
id: readMarkerListView
clip: true
boundsBehavior: Flickable.DragOverBounds
delegate: ItemDelegate {
width: parent.width
height: 48
RowLayout {
anchors.fill: parent
anchors.margins: 8
spacing: 12
Avatar {
2018-11-17 14:39:34 +00:00
Layout.preferredWidth: height
Layout.fillHeight: true
source: modelData.avatar
2018-11-17 14:39:34 +00:00
hint: modelData.displayName
}
Label {
Layout.fillWidth: true
text: modelData.displayName
}
}
}
ScrollBar.vertical: ScrollBar {}
}
}
}
2018-11-17 14:39:34 +00:00
RoomPanelInput {
Layout.fillWidth: true
Layout.margins: 16
Layout.maximumWidth: 960
Layout.alignment: Qt.AlignHCenter
id: roomPanelInput
}
}
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)
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
}
}