249 lines
6.8 KiB
QML
249 lines
6.8 KiB
QML
import QtQuick 2.12
|
|
import QtQuick.Controls 2.12 as Controls
|
|
import QtQuick.Layouts 1.12
|
|
import Qt.labs.qmlmodels 1.0
|
|
|
|
import org.kde.kirigami 2.4 as Kirigami
|
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
import Spectral.Component 2.0
|
|
import Spectral.Component.Timeline 2.0
|
|
import Spectral 0.1
|
|
|
|
Kirigami.ScrollablePage {
|
|
property var currentRoom
|
|
|
|
id: page
|
|
|
|
title: "Messages"
|
|
|
|
actions {
|
|
main: Kirigami.Action {
|
|
iconName: "document-edit"
|
|
}
|
|
contextualActions: []
|
|
}
|
|
|
|
MessageEventModel {
|
|
id: messageEventModel
|
|
|
|
room: currentRoom
|
|
}
|
|
|
|
SortFilterProxyModel {
|
|
id: sortedMessageEventModel
|
|
|
|
sourceModel: messageEventModel
|
|
|
|
filters: [
|
|
ExpressionFilter {
|
|
expression: marks !== 0x10 && eventType !== "other"
|
|
}
|
|
]
|
|
}
|
|
|
|
ListView {
|
|
readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1
|
|
readonly property bool noNeedMoreContent: !currentRoom || currentRoom.eventsHistoryJob || currentRoom.allHistoryLoaded
|
|
|
|
readonly property bool isLoaded: page.width * page.height > 10
|
|
|
|
id: messageListView
|
|
|
|
spacing: Kirigami.Units.smallSpacing
|
|
|
|
displayMarginBeginning: 100
|
|
displayMarginEnd: 100
|
|
verticalLayoutDirection: ListView.BottomToTop
|
|
highlightMoveDuration: 500
|
|
|
|
model: !isLoaded ? undefined : sortedMessageEventModel
|
|
|
|
onContentYChanged: {
|
|
if(!noNeedMoreContent && contentY - 5000 < originY)
|
|
currentRoom.getPreviousContent(20);
|
|
}
|
|
|
|
// populate: Transition {
|
|
// NumberAnimation {
|
|
// property: "opacity"; from: 0; to: 1
|
|
// duration: 200
|
|
// }
|
|
// }
|
|
|
|
// add: Transition {
|
|
// NumberAnimation {
|
|
// property: "opacity"; from: 0; to: 1
|
|
// duration: 200
|
|
// }
|
|
// }
|
|
|
|
// move: Transition {
|
|
// NumberAnimation {
|
|
// property: "y"; duration: 200
|
|
// }
|
|
// NumberAnimation {
|
|
// property: "opacity"; to: 1
|
|
// }
|
|
// }
|
|
|
|
// displaced: Transition {
|
|
// NumberAnimation {
|
|
// property: "y"; duration: 200
|
|
// easing.type: Easing.OutQuad
|
|
// }
|
|
// NumberAnimation {
|
|
// property: "opacity"; to: 1
|
|
// }
|
|
// }
|
|
|
|
delegate: DelegateChooser {
|
|
role: "eventType"
|
|
|
|
DelegateChoice {
|
|
roleValue: "state"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: StateDelegate {
|
|
Layout.maximumWidth: parent.width
|
|
Layout.alignment: Qt.AlignHCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "emote"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: StateDelegate {
|
|
Layout.maximumWidth: parent.width
|
|
Layout.alignment: Qt.AlignHCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "message"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: TextDelegate {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "notice"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: TextDelegate {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "image"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: ImageDelegate {
|
|
Layout.preferredWidth: Math.min(320, info.w)
|
|
Layout.preferredHeight: Math.min(320, info.h)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "audio"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: AudioDelegate {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "video"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: AudioDelegate {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "file"
|
|
delegate: TimelineContainer {
|
|
width: messageListView.width
|
|
|
|
innerObject: MessageDelegate {
|
|
Layout.fillWidth: true
|
|
|
|
innerObject: FileDelegate {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "other"
|
|
delegate: Item {}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
if (currentRoom) {
|
|
if (currentRoom.timelineSize < 20)
|
|
currentRoom.getPreviousContent(50)
|
|
}
|
|
|
|
positionViewAtBeginning()
|
|
}
|
|
}
|
|
|
|
footer: RowLayout {
|
|
Controls.ToolButton {
|
|
contentItem: Kirigami.Icon {
|
|
source: "mail-attachment"
|
|
}
|
|
}
|
|
|
|
Controls.TextField {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
|
|
background: Item {}
|
|
}
|