Separate different delegates.

square-messages
Black Hat 2018-11-22 17:15:14 +08:00
parent 1248b6f334
commit 58593015c1
5 changed files with 147 additions and 154 deletions

View File

@ -0,0 +1,103 @@
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.2
import QtGraphicalEffects 1.0
import Spectral 0.1
import Spectral.Setting 0.1
import Spectral.Component 2.0
import Spectral.Font 0.1
ColumnLayout {
readonly property int alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft
readonly property bool avatarVisible: !sentByMe && (aboveAuthor !== author || aboveSection !== section || aboveEventType === "state" || aboveEventType === "emote" || aboveEventType === "other")
readonly property bool sentByMe: author === currentRoom.localUser
signal saveFileAs()
signal openExternally()
id: root
spacing: 0
Label {
Layout.leftMargin: 48
text: author.displayName
visible: avatarVisible
font.pixelSize: 13
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Layout.alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft
z: -5
id: messageRow
spacing: 4
ImageItem {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.alignment: Qt.AlignTop
visible: avatarVisible
hint: author.displayName
source: author.paintable
}
Label {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.alignment: Qt.AlignTop
visible: !(sentByMe || avatarVisible)
text: Qt.formatDateTime(time, "hh:mm")
color: "#5B7480"
font.pixelSize: 10
horizontalAlignment: Label.AlignHCenter
verticalAlignment: Label.AlignVCenter
}
Image {
Layout.maximumWidth: messageListView.width - (!sentByMe ? 32 + messageRow.spacing : 0) - 48
id: img
source: "image://mxc/" + (content.thumbnail_url ? content.thumbnail_url : content.url)
sourceSize.width: Math.min(256, messageListView.width)
sourceSize.height: 256
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: img.width
height: img.height
radius: 24
}
}
AutoMouseArea {
anchors.fill: parent
id: messageMouseArea
onSecondaryClicked: {
messageContextMenu.root = root
messageContextMenu.model = model
messageContextMenu.selectedText = ""
messageContextMenu.popup()
}
}
}
}
}

View File

@ -10,16 +10,14 @@ import Spectral.Component 2.0
import Spectral.Font 0.1
ColumnLayout {
readonly property int alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft
readonly property bool avatarVisible: !sentByMe && (aboveAuthor !== author || aboveSection !== section || aboveEventType === "state" || aboveEventType === "emote" || aboveEventType === "other")
readonly property bool highlighted: !(sentByMe || eventType === "notice" )
readonly property bool sentByMe: author === currentRoom.localUser
readonly property bool isText: eventType === "notice" || eventType === "message"
signal saveFileAs()
signal openExternally()
Layout.alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft
id: root
spacing: 0
@ -95,139 +93,30 @@ ColumnLayout {
}
}
contentItem: ColumnLayout {
id: messageColumn
contentItem: TextEdit {
Layout.fillWidth: true
spacing: 0
id: contentLabel
TextEdit {
Layout.fillWidth: true
text: "<style>a{color: white;} .user-pill{color: white}</style>" + display
id: contentLabel
color: "white"
text: "<style>a{color: white;} .user-pill{color: white}</style>" + display
font.family: CommonFont.font.family
font.pixelSize: 14
selectByMouse: true
readOnly: true
wrapMode: Label.Wrap
selectedTextColor: "white"
selectionColor: Material.accent
textFormat: Text.RichText
visible: isText
color: "white"
onLinkActivated: Qt.openUrlExternally(link)
font.family: CommonFont.font.family
font.pixelSize: 14
selectByMouse: true
readOnly: true
wrapMode: Label.Wrap
selectedTextColor: highlighted ? Material.accent : "white"
selectionColor: highlighted ? "white" : Material.accent
textFormat: Text.RichText
onLinkActivated: Qt.openUrlExternally(link)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
Loader {
sourceComponent: {
switch (eventType) {
case "image":
return imageComponent
case "file":
return fileComponent
case "audio":
return audioComponent
}
}
active: eventType === "image" || eventType === "file" || eventType === "audio"
}
}
Component {
id: imageComponent
DownloadableContent {
width: messageImage.width
height: messageImage.height
id: downloadable
TimelineImage {
z: -4
id: messageImage
sourceSize: 128
source: "image://mxc/" + (content.thumbnail_url ? content.thumbnail_url : content.url)
onClicked: downloadAndOpen()
}
Component.onCompleted: {
root.saveFileAs.connect(saveFileAs)
root.openExternally.connect(downloadAndOpen)
}
}
}
Component {
id: fileComponent
TimelineLabel {
Layout.fillWidth: true
id: downloadDelegate
text: "<b>File: </b>" + content.body
coloredBackground: highlighted
background: DownloadableContent {
id: downloadable
Component.onCompleted: {
root.saveFileAs.connect(saveFileAs)
root.openExternally.connect(downloadAndOpen)
}
}
}
}
Component {
id: audioComponent
TimelineLabel {
id: downloadDelegate
text: content.info.duration / 1000 + '"'
coloredBackground: highlighted
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: {
if (downloadable.downloaded)
spectralController.playAudio(progressInfo.localPath)
else
{
playOnFinished = true
currentRoom.downloadFile(eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + eventId.replace(":", "_") + ".tmp")
}
}
}
background: DownloadableContent {
id: downloadable
onDownloadedChanged: downloaded && playOnFinished ? spectralController.playAudio(progressInfo.localPath) : {}
Component.onCompleted: {
root.saveFileAs.connect(saveFileAs)
root.openExternally.connect(downloadAndOpen)
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}

View File

@ -6,6 +6,8 @@ import QtQuick.Controls.Material 2.2
import Spectral.Setting 0.1
Label {
readonly property int alignment: Qt.AlignHCenter
text: "<b>" + author.displayName + "</b> " + display
color: Material.accent

View File

@ -103,7 +103,7 @@ Item {
var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex())
messageListView.currentIndex = lastScrollPosition
if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20)
currentRoom.getPreviousContent(100)
currentRoom.getPreviousContent(50)
}
}
}
@ -112,7 +112,7 @@ Item {
onContentYChanged: {
if(currentRoom && contentY - 5000 < originY)
currentRoom.getPreviousContent(50);
currentRoom.getPreviousContent(20);
}
onMovementEnded: currentRoom.saveViewport(sortedMessageEventModel.mapToSource(indexAt(contentX, contentY)), sortedMessageEventModel.mapToSource(largestVisibleIndex))
@ -138,29 +138,27 @@ Item {
visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000
}
MessageDelegate {
visible: eventType === "notice" || eventType === "message"
|| eventType === "image" || eventType === "video"
|| eventType === "audio" || eventType === "file"
}
StateDelegate {
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignHCenter
visible: eventType === "emote" || eventType === "state"
}
Label {
Layout.alignment: Qt.AlignHCenter
visible: eventType === "other"
text: display
color: "grey"
font.italic: true
Loader {
Layout.maximumWidth: delegateColumn.width
Layout.alignment: item ? item.alignment : 0
source: {
switch (eventType) {
case "message":
case "notice":
return "qrc:/imports/Spectral/Component/Timeline/MessageDelegate.qml"
case "emote":
case "state":
return "qrc:/imports/Spectral/Component/Timeline/StateDelegate.qml"
case "image":
return "qrc:/imports/Spectral/Component/Timeline/ImageDelegate.qml"
default:
return ""
}
}
}
// Read marker
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter

View File

@ -46,5 +46,6 @@
<file>imports/Spectral/Effect/RippleEffect.qml</file>
<file>imports/Spectral/Effect/CircleMask.qml</file>
<file>assets/img/roompanel-dark.svg</file>
<file>imports/Spectral/Component/Timeline/ImageDelegate.qml</file>
</qresource>
</RCC>