Refactor delegates

This commit is contained in:
Tobias Fella
2021-12-14 22:27:29 +00:00
parent ff707b7a58
commit 599ab11656
13 changed files with 583 additions and 586 deletions

View File

@@ -15,10 +15,15 @@ import NeoChat.Component 1.0
import NeoChat.Dialog 1.0 import NeoChat.Dialog 1.0
import NeoChat.Menu.Timeline 1.0 import NeoChat.Menu.Timeline 1.0
Control { TimelineContainer {
id: root id: audioDelegate
width: ListView.view.width
onReplyClicked: ListView.view.goToEvent(eventID)
hoverComponent: hoverActions
innerObject: Control {
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumWidth: audioDelegate.bubbleMaxWidth
Audio { Audio {
id: audio id: audio
@@ -26,6 +31,15 @@ Control {
autoLoad: false autoLoad: false
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
contentItem: ColumnLayout { contentItem: ColumnLayout {
RowLayout { RowLayout {
ToolButton { ToolButton {
@@ -59,4 +73,5 @@ Control {
} }
} }
} }
}
} }

View File

@@ -3,11 +3,16 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0 import org.kde.neochat 1.0
TextEdit { TimelineContainer {
id: encryptedDelegate
width: ListView.view.width
innerObject: TextEdit {
text: i18n("This message is encrypted and the sender has not shared the key with this device.") text: i18n("This message is encrypted and the sender has not shared the key with this device.")
color: Kirigami.Theme.disabledTextColor color: Kirigami.Theme.disabledTextColor
font.pointSize: Kirigami.Theme.defaultFont.pointSize font.pointSize: Kirigami.Theme.defaultFont.pointSize
@@ -15,4 +20,6 @@ TextEdit {
readOnly: true readOnly: true
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.RichText textFormat: Text.RichText
Layout.maximumWidth: encryptedDelegate.bubbleMaxWidth
}
} }

View File

@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
// SPDX-License-Identifier: GPL-3.0-only
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
DelegateChooser {
role: "eventType"
DelegateChoice {
roleValue: "state"
delegate: StateDelegate {}
}
DelegateChoice {
roleValue: "emote"
delegate: MessageDelegate {
isEmote: true
}
}
DelegateChoice {
roleValue: "message"
delegate: MessageDelegate {}
}
DelegateChoice {
roleValue: "notice"
delegate: MessageDelegate {}
}
DelegateChoice {
roleValue: "image"
delegate: ImageDelegate {}
}
DelegateChoice {
roleValue: "sticker"
delegate: ImageDelegate {
cardBackground: false
}
}
DelegateChoice {
roleValue: "audio"
delegate: AudioDelegate {}
}
DelegateChoice {
roleValue: "video"
delegate: VideoDelegate {}
}
DelegateChoice {
roleValue: "file"
delegate: FileDelegate {}
}
DelegateChoice {
roleValue: "encrypted"
delegate: EncryptedDelegate {}
}
DelegateChoice {
roleValue: "readMarker"
delegate: ReadMarkerDelegate {}
}
DelegateChoice {
roleValue: "other"
delegate: Item {}
}
}

View File

@@ -14,11 +14,19 @@ import NeoChat.Component 1.0
import NeoChat.Dialog 1.0 import NeoChat.Dialog 1.0
import NeoChat.Menu.Timeline 1.0 import NeoChat.Menu.Timeline 1.0
RowLayout { TimelineContainer {
id: root id: fileDelegate
width: ListView.view.width
onReplyClicked: ListView.view.goToEvent(eventID)
hoverComponent: hoverActions
innerObject: RowLayout {
property bool openOnFinished: false property bool openOnFinished: false
readonly property bool downloaded: progressInfo && progressInfo.completed readonly property bool downloaded: progressInfo && progressInfo.completed
Layout.fillWidth: true
Layout.maximumWidth: fileDelegate.bubbleMaxWidth
Layout.margins: Kirigami.Units.largeSpacing Layout.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
@@ -113,6 +121,15 @@ RowLayout {
} }
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
function saveFileAs() { function saveFileAs() {
var dialog = fileDialog.createObject(QQC2.ApplicationWindow.overlay) var dialog = fileDialog.createObject(QQC2.ApplicationWindow.overlay)
dialog.open() dialog.open()
@@ -123,4 +140,5 @@ RowLayout {
if (Qt.openUrlExternally(progressInfo.localPath)) return; if (Qt.openUrlExternally(progressInfo.localPath)) return;
if (Qt.openUrlExternally(progressInfo.localDir)) return; if (Qt.openUrlExternally(progressInfo.localDir)) return;
} }
}
} }

View File

@@ -12,7 +12,16 @@ import NeoChat.Component 1.0
import NeoChat.Dialog 1.0 import NeoChat.Dialog 1.0
import NeoChat.Menu.Timeline 1.0 import NeoChat.Menu.Timeline 1.0
Image {
TimelineContainer {
id: imageDelegate
width: ListView.view.width
onReplyClicked: ListView.view.goToEvent(eventID)
hoverComponent: hoverActions
innerObject: Image {
id: img id: img
property var content: model.content property var content: model.content
@@ -25,8 +34,8 @@ Image {
// readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info // readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info
readonly property var info: content.info readonly property var info: content.info
readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId
property bool readonly: false
Layout.maximumWidth: imageDelegate.bubbleMaxWidth
source: "image://mxc/" + mediaId source: "image://mxc/" + mediaId
Image { Image {
@@ -42,7 +51,6 @@ Image {
HoverHandler { HoverHandler {
id: hoverHandler id: hoverHandler
enabled: img.readonly
} }
Rectangle { Rectangle {
@@ -81,6 +89,25 @@ Image {
} }
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
onTapped: {
fullScreenImage.createObject(parent, {
filename: eventId,
localPath: currentRoom.urlToDownload(eventId),
blurhash: model.content.info["xyz.amorgan.blurhash"],
imageWidth: content.info.w,
imageHeight: content.info.h
}).showFullScreen();
}
}
function downloadAndOpen() function downloadAndOpen()
{ {
if (downloaded) openSavedFile() if (downloaded) openSavedFile()
@@ -96,4 +123,5 @@ Image {
if (Qt.openUrlExternally(progressInfo.localPath)) return; if (Qt.openUrlExternally(progressInfo.localPath)) return;
if (Qt.openUrlExternally(progressInfo.localDir)) return; if (Qt.openUrlExternally(progressInfo.localDir)) return;
} }
}
} }

View File

@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
// SPDX-License-Identifier: GPL-3.0-only
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
TimelineContainer {
id: messageDelegate
width: ListView.view.width
property bool isEmote: false
onReplyClicked: ListView.view.goToEvent(eventID)
hoverComponent: hoverActions
innerObject: TextDelegate {
isEmote: messageDelegate.isEmote
Layout.maximumWidth: messageDelegate.bubbleMaxWidth
onRequestOpenMessageContext: openMessageContext(model, parent.selectedText)
}
}

View File

@@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: GPL-3.0-only
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami
import org.kde.neochat 1.0
QQC2.ItemDelegate {
padding: Kirigami.Units.largeSpacing
topInset: Kirigami.Units.largeSpacing
topPadding: Kirigami.Units.largeSpacing * 2
width: ListView.view.width - Kirigami.Units.gridUnit
x: Kirigami.Units.gridUnit / 2
contentItem: QQC2.Label {
text: i18nc("Relative time since the room was last read", "Last read: %1", time)
}
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
opacity: 0.6
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: 1
}
Timer {
id: makeMeDisapearTimer
interval: Kirigami.Units.humanMoment * 2
onTriggered: if (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden) {
currentRoom.markAllMessagesAsRead();
}
}
ListView.onPooled: makeMeDisapearTimer.stop()
ListView.onAdd: {
const view = ListView.view;
if (view.atYEnd) {
makeMeDisapearTimer.start()
}
}
// When the read marker is visible and we are at the end of the list,
// start the makeMeDisapearTimer
Connections {
target: ListView.view
function onAtYEndChanged() {
makeMeDisapearTimer.start();
}
}
ListView.onRemove: {
const view = ListView.view;
if (view.atYEnd) {
// easy case just mark everything as read
if (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden) {
currentRoom.markAllMessagesAsRead();
}
return;
}
// mark the last visible index
const lastVisibleIdx = lastVisibleIndex();
if (lastVisibleIdx < index) {
currentRoom.readMarkerEventId = sortedMessageEventModel.data(sortedMessageEventModel.index(lastVisibleIdx, 0), MessageEventModel.EventIdRole)
}
}
}

View File

@@ -11,9 +11,9 @@ import NeoChat.Component 1.0
import NeoChat.Dialog 1.0 import NeoChat.Dialog 1.0
RowLayout { RowLayout {
id: row x: Kirigami.Units.gridUnit * 1.5 + Kirigami.Units.smallSpacing
height: label.contentHeight height: label.contentHeight
width: ListView.view.width - Kirigami.Units.largeSpacing - x
Kirigami.Avatar { Kirigami.Avatar {
id: icon id: icon

View File

@@ -15,7 +15,15 @@ import NeoChat.Component 1.0
import NeoChat.Dialog 1.0 import NeoChat.Dialog 1.0
import NeoChat.Menu.Timeline 1.0 import NeoChat.Menu.Timeline 1.0
Video { TimelineContainer {
id: videoDelegate
width: ListView.view.width
onReplyClicked: ListView.view.goToEvent(eventID)
hoverComponent: hoverActions
innerObject: Video {
id: vid id: vid
property bool playOnFinished: false property bool playOnFinished: false
@@ -23,6 +31,11 @@ Video {
property bool supportStreaming: true property bool supportStreaming: true
Layout.maximumWidth: videoDelegate.bubbleMaxWidth
Layout.fillWidth: true
Layout.maximumHeight: Kirigami.Units.gridUnit * 15
Layout.minimumHeight: Kirigami.Units.gridUnit * 5
onDownloadedChanged: { onDownloadedChanged: {
if (downloaded) { if (downloaded) {
vid.source = progressInfo.localPath vid.source = progressInfo.localPath
@@ -34,7 +47,6 @@ Video {
} }
} }
readonly property int maxWidth: 1000 // TODO messageListView.width readonly property int maxWidth: 1000 // TODO messageListView.width
Layout.preferredWidth: content.info.w > maxWidth ? maxWidth : content.info.w Layout.preferredWidth: content.info.w > maxWidth ? maxWidth : content.info.w
@@ -54,28 +66,22 @@ Video {
onDurationChanged: { onDurationChanged: {
if (!duration) { if (!duration) {
supportStreaming = false; vid.supportStreaming = false;
} }
} }
onErrorChanged: { onErrorChanged: {
if (error != MediaPlayer.NoError) { if (error != MediaPlayer.NoError) {
supportStreaming = false; vid.supportStreaming = false;
} }
} }
Image { Image {
readonly property bool isThumbnail: content.info.thumbnail_info && content.thumbnailMediaId
readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info
anchors.fill: parent anchors.fill: parent
visible: isThumbnail && (vid.playbackState == MediaPlayer.StoppedState || vid.error != MediaPlayer.NoError) visible: vid.playbackState == MediaPlayer.StoppedState || vid.error != MediaPlayer.NoError
source: "image://mxc/" + (isThumbnail ? content.thumbnailMediaId : "") source: "image://mxc/" + content.thumbnailMediaId
sourceSize.width: info.w
sourceSize.height: info.h
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
@@ -100,7 +106,7 @@ Video {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
visible: progressInfo.active && !downloaded visible: progressInfo.active && !vid.downloaded
color: "#BB000000" color: "#BB000000"
@@ -117,19 +123,29 @@ Video {
TapHandler { TapHandler {
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onTapped: if (supportStreaming || progressInfo.completed) { onTapped: if (vid.supportStreaming || progressInfo.completed) {
if (vid.playbackState == MediaPlayer.PlayingState) { if (vid.playbackState == MediaPlayer.PlayingState) {
vid.pause() vid.pause()
} else { } else {
vid.play() vid.play()
} }
} else { } else {
downloadAndPlay() vid.downloadAndPlay()
} }
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
function downloadAndPlay() { function downloadAndPlay() {
if (downloaded) { if (vid.downloaded) {
playSavedFile() playSavedFile()
} else { } else {
playOnFinished = true playOnFinished = true
@@ -141,4 +157,5 @@ Video {
vid.stop() vid.stop()
vid.play() vid.play()
} }
}
} }

View File

@@ -9,3 +9,6 @@ VideoDelegate 1.0 VideoDelegate.qml
ReactionDelegate 1.0 ReactionDelegate.qml ReactionDelegate 1.0 ReactionDelegate.qml
AudioDelegate 1.0 AudioDelegate.qml AudioDelegate 1.0 AudioDelegate.qml
EncryptedDelegate 1.0 EncryptedDelegate.qml EncryptedDelegate 1.0 EncryptedDelegate.qml
EventDelegate 1.0 EventDelegate.qml
MessageDelegate 1.0 MessageDelegate.qml
ReadMarkerDelegate 1.0 ReadMarkerDelegate.qml

View File

@@ -341,282 +341,7 @@ Kirigami.ScrollablePage {
sourceModel: messageEventModel sourceModel: messageEventModel
} }
delegate: DelegateChooser { delegate: EventDelegate {}
id: timelineDelegateChooser
role: "eventType"
DelegateChoice {
roleValue: "state"
delegate: QQC2.Control {
leftPadding: Kirigami.Units.gridUnit * 1.5 + Kirigami.Units.smallSpacing
topPadding: 0
bottomPadding: 0
height: contentItem.height
contentItem: StateDelegate { }
implicitWidth: messageListView.width - Kirigami.Units.largeSpacing
}
}
DelegateChoice {
roleValue: "emote"
delegate: TimelineContainer {
id: emoteContainer
width: messageListView.width
isEmote: true
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
innerObject: TextDelegate {
isEmote: true
Layout.maximumWidth: emoteContainer.bubbleMaxWidth
onRequestOpenMessageContext: openMessageContext(model, parent.selectedText)
}
}
}
DelegateChoice {
roleValue: "message"
delegate: TimelineContainer {
id: messageContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
innerObject: TextDelegate {
Layout.maximumWidth: messageContainer.bubbleMaxWidth
onRequestOpenMessageContext: openMessageContext(model, parent.selectedText)
}
}
}
DelegateChoice {
roleValue: "notice"
delegate: TimelineContainer {
id: noticeContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
innerObject: TextDelegate {
Layout.fillWidth: !Config.compactLayout
hasContextMenu: false
Layout.maximumWidth: noticeContainer.bubbleMaxWidth
}
}
}
DelegateChoice {
roleValue: "image"
delegate: TimelineContainer {
id: imageContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
innerObject: ImageDelegate {
Layout.preferredWidth: Kirigami.Units.gridUnit * 15
Layout.maximumWidth: imageContainer.bubbleMaxWidth
Layout.preferredHeight: info.h / info.w * width
Layout.maximumHeight: Kirigami.Units.gridUnit * 20
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
onTapped: {
fullScreenImage.createObject(parent, {
filename: eventId,
localPath: currentRoom.urlToDownload(eventId),
blurhash: model.content.info["xyz.amorgan.blurhash"],
imageWidth: content.info.w,
imageHeight: content.info.h
}).showFullScreen();
}
}
}
}
}
DelegateChoice {
roleValue: "sticker"
delegate: TimelineContainer {
width: messageListView.width
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
cardBackground: false
innerObject: ImageDelegate {
readonly: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 10
Layout.minimumWidth: Kirigami.Units.gridUnit * 10
Layout.preferredHeight: info.h / info.w * width
}
}
}
DelegateChoice {
roleValue: "audio"
delegate: TimelineContainer {
id: audioContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
innerObject: AudioDelegate {
Layout.fillWidth: true
Layout.maximumWidth: audioContainer.bubbleMaxWidth
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
}
}
}
DelegateChoice {
roleValue: "video"
delegate: TimelineContainer {
id: videoContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
hoverComponent: hoverActions
innerObject: VideoDelegate {
Layout.fillWidth: true
Layout.maximumWidth: videoContainer.bubbleMaxWidth
Layout.preferredHeight: content.info.h / content.info.w * width
Layout.maximumHeight: Kirigami.Units.gridUnit * 15
Layout.minimumHeight: Kirigami.Units.gridUnit * 5
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
}
}
}
DelegateChoice {
roleValue: "file"
delegate: TimelineContainer {
id: fileContainer
width: messageListView.width
onReplyClicked: goToEvent(eventID)
innerObject: FileDelegate {
Layout.fillWidth: true
Layout.maximumWidth: fileContainer.bubbleMaxWidth
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: openFileContext(model, parent)
}
TapHandler {
acceptedButtons: Qt.LeftButton
onLongPressed: openFileContext(model, parent)
}
}
}
}
DelegateChoice {
roleValue: "encrypted"
delegate: TimelineContainer {
id: encryptedContainer
width: messageListView.width
innerObject: EncryptedDelegate {
Layout.fillWidth: Config.compactLayout
Layout.maximumWidth: encryptedContainer.bubbleMaxWidth
Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
}
}
}
DelegateChoice {
roleValue: "readMarker"
delegate: QQC2.ItemDelegate {
padding: Kirigami.Units.largeSpacing
topInset: Kirigami.Units.largeSpacing
topPadding: Kirigami.Units.largeSpacing * 2
width: ListView.view.width - Kirigami.Units.gridUnit
x: Kirigami.Units.gridUnit / 2
contentItem: QQC2.Label {
text: i18nc("Relative time since the room was last read", "Last read: %1", time)
}
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
opacity: 0.6
radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: 1
}
Timer {
id: makeMeDisapearTimer
interval: Kirigami.Units.humanMoment * 2
onTriggered: if (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden) {
currentRoom.markAllMessagesAsRead();
}
}
ListView.onPooled: makeMeDisapearTimer.stop()
ListView.onAdd: {
const view = ListView.view;
if (view.atYEnd) {
makeMeDisapearTimer.start()
}
}
// When the read marker is visible and we are at the end of the list,
// start the makeMeDisapearTimer
Connections {
target: ListView.view
function onAtYEndChanged() {
makeMeDisapearTimer.start();
}
}
ListView.onRemove: {
const view = ListView.view;
if (view.atYEnd) {
// easy case just mark everything as read
if (QQC2.ApplicationWindow.window.visibility !== QQC2.ApplicationWindow.Hidden) {
currentRoom.markAllMessagesAsRead();
}
return;
}
// mark the last visible index
const lastVisibleIdx = lastVisibleIndex();
if (lastVisibleIdx < index) {
currentRoom.readMarkerEventId = sortedMessageEventModel.data(sortedMessageEventModel.index(lastVisibleIdx, 0), MessageEventModel.EventIdRole)
}
}
}
}
DelegateChoice {
roleValue: "other"
delegate: Item {}
}
}
QQC2.RoundButton { QQC2.RoundButton {
anchors.right: parent.right anchors.right: parent.right
@@ -631,7 +356,7 @@ Kirigami.ScrollablePage {
visible: currentRoom && currentRoom.hasUnreadMessages && currentRoom.readMarkerLoaded visible: currentRoom && currentRoom.hasUnreadMessages && currentRoom.readMarkerLoaded
action: Kirigami.Action { action: Kirigami.Action {
onTriggered: { onTriggered: {
goToEvent(currentRoom.readMarkerEventId) messageListView.goToEvent(currentRoom.readMarkerEventId)
} }
icon.name: "go-up" icon.name: "go-up"
} }
@@ -739,6 +464,9 @@ Kirigami.ScrollablePage {
} }
headerPositioning: ListView.OverlayHeader headerPositioning: ListView.OverlayHeader
function goToEvent(eventID) {
messageListView.positionViewAtIndex(eventToIndex(eventID), ListView.Contain)
}
} }
@@ -820,10 +548,6 @@ Kirigami.ScrollablePage {
messageListView.positionViewAtIndex(0, ListView.End) messageListView.positionViewAtIndex(0, ListView.End)
} }
function goToEvent(eventID) {
messageListView.positionViewAtIndex(eventToIndex(eventID), ListView.Contain)
}
function eventToIndex(eventID) { function eventToIndex(eventID) {
const index = messageEventModel.eventIDToIndex(eventID) const index = messageEventModel.eventIDToIndex(eventID)
if (index === -1) if (index === -1)

View File

@@ -42,6 +42,9 @@
<file>imports/NeoChat/Component/Timeline/FileDelegate.qml</file> <file>imports/NeoChat/Component/Timeline/FileDelegate.qml</file>
<file>imports/NeoChat/Component/Timeline/ImageDelegate.qml</file> <file>imports/NeoChat/Component/Timeline/ImageDelegate.qml</file>
<file>imports/NeoChat/Component/Timeline/EncryptedDelegate.qml</file> <file>imports/NeoChat/Component/Timeline/EncryptedDelegate.qml</file>
<file>imports/NeoChat/Component/Timeline/EventDelegate.qml</file>
<file>imports/NeoChat/Component/Timeline/MessageDelegate.qml</file>
<file>imports/NeoChat/Component/Timeline/ReadMarkerDelegate.qml</file>
<file>imports/NeoChat/Component/Login/qmldir</file> <file>imports/NeoChat/Component/Login/qmldir</file>
<file>imports/NeoChat/Component/Login/LoginStep.qml</file> <file>imports/NeoChat/Component/Login/LoginStep.qml</file>
<file>imports/NeoChat/Component/Login/Login.qml</file> <file>imports/NeoChat/Component/Login/Login.qml</file>

View File

@@ -423,8 +423,6 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
const KFormat format; const KFormat format;
return format.formatRelativeDateTime(eventDate, QLocale::ShortFormat); return format.formatRelativeDateTime(eventDate, QLocale::ShortFormat);
} }
case SpecialMarksRole:
return EventStatus::Hidden;
} }
return {}; return {};
} }