Simplify section handling a bit

This commit is contained in:
Nicolas Werner 2021-01-19 23:58:25 +01:00
parent 9192dc8ae5
commit 32a20a5f8c
4 changed files with 49 additions and 73 deletions

View file

@ -136,9 +136,9 @@ Rectangle {
padding: 0 padding: 0
focus: true focus: true
onTextChanged: { onTextChanged: {
if (TimelineManager.timeline) { if (TimelineManager.timeline)
TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text); TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text);
}
} }
onCursorRectangleChanged: textInput.ensureVisible(cursorRectangle) onCursorRectangleChanged: textInput.ensureVisible(cursorRectangle)
onCursorPositionChanged: { onCursorPositionChanged: {

View file

@ -66,33 +66,25 @@ ListView {
} }
} }
section {
property: "section"
}
Component { Component {
id: sectionHeader id: sectionHeader
Column { Column {
property var modelData
property string section
property string nextSection
topPadding: 4 topPadding: 4
bottomPadding: 4 bottomPadding: 4
spacing: 8 spacing: 8
visible: !!modelData visible: modelData && (modelData.previousMessageUserId !== modelData.userId || modelData.previousMessageDay !== modelData.day)
width: parent.width width: parentWidth
height: (section.includes(" ") ? dateBubble.height + 8 + userName.height : userName.height) + 8 height: ((modelData && modelData.previousMessageDay !== modelData.day) ? dateBubble.height + 8 + userName.height : userName.height) + 8
Label { Label {
id: dateBubble id: dateBubble
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
visible: section.includes(" ") visible: modelData && modelData.previousMessageDay !== modelData.day
text: chat.model.formatDateSeparator(modelData.timestamp) text: modelData ? chat.model.formatDateSeparator(modelData.timestamp) : ""
color: colors.text color: colors.text
height: fontMetrics.height * 1.4 height: Math.round(fontMetrics.height * 1.4)
width: contentWidth * 1.2 width: contentWidth * 1.2
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -109,26 +101,19 @@ ListView {
spacing: 8 spacing: 8
Avatar { Avatar {
// MouseArea {
// anchors.fill: parent
// onClicked: chat.model.openUserProfile(modelData.userId)
// cursorShape: Qt.PointingHandCursor
// propagateComposedEvents: true
// }
width: avatarSize width: avatarSize
height: avatarSize height: avatarSize
url: chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") url: modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : ""
displayName: modelData.userName displayName: modelData ? modelData.userName : ""
userid: modelData.userId userid: modelData ? modelData.userId : ""
onClicked: chat.model.openUserProfile(modelData.userId) onClicked: chat.model.openUserProfile(modelData.userId)
} }
Label { Label {
id: userName id: userName
text: TimelineManager.escapeEmoji(modelData.userName) text: modelData ? TimelineManager.escapeEmoji(modelData.userName) : ""
color: TimelineManager.userColor(modelData.userId, colors.window) color: TimelineManager.userColor(modelData ? modelData.userId : "", colors.window)
textFormat: Text.RichText textFormat: Text.RichText
MouseArea { MouseArea {
@ -143,7 +128,7 @@ ListView {
Label { Label {
color: colors.buttonText color: colors.buttonText
text: TimelineManager.userStatus(modelData.userId) text: modelData ? TimelineManager.userStatus(modelData.userId) : ""
textFormat: Text.PlainText textFormat: Text.PlainText
elide: Text.ElideRight elide: Text.ElideRight
width: chat.delegateMaxWidth - parent.spacing * 2 - userName.implicitWidth - avatarSize width: chat.delegateMaxWidth - parent.spacing * 2 - userName.implicitWidth - avatarSize
@ -163,31 +148,26 @@ ListView {
delegate: Item { delegate: Item {
id: wrapper id: wrapper
// This would normally be previousSection, but our model's order is inverted.
property bool sectionBoundary: (ListView.nextSection != "" && ListView.nextSection !== ListView.section) || model.index === chat.count - 1
property Item section
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
width: chat.delegateMaxWidth width: chat.delegateMaxWidth
height: section ? section.height + timelinerow.height : timelinerow.height height: section ? section.height + timelinerow.height : timelinerow.height
onSectionBoundaryChanged: {
if (sectionBoundary) { Loader {
var properties = { id: section
"modelData": model.dump,
"section": ListView.section, property var modelData: model
"nextSection": ListView.nextSection property int parentWidth: parent.width
};
section = sectionHeader.createObject(wrapper, properties); active: model.previousMessageUserId !== undefined && model.previousMessageUserId !== model.userId || model.previousMessageDay !== model.day
} else { //asynchronous: true
section.destroy(); sourceComponent: sectionHeader
section = null; visible: status == Loader.Ready
}
} }
TimelineRow { TimelineRow {
id: timelinerow id: timelinerow
y: section ? section.y + section.height : 0 y: section.active && section.visible ? section.y + section.height : 0
} }
Connections { Connections {

View file

@ -265,14 +265,16 @@ QHash<int, QByteArray>
TimelineModel::roleNames() const TimelineModel::roleNames() const
{ {
return { return {
{Section, "section"},
{Type, "type"}, {Type, "type"},
{TypeString, "typeString"}, {TypeString, "typeString"},
{IsOnlyEmoji, "isOnlyEmoji"}, {IsOnlyEmoji, "isOnlyEmoji"},
{Body, "body"}, {Body, "body"},
{FormattedBody, "formattedBody"}, {FormattedBody, "formattedBody"},
{PreviousMessageUserId, "previousMessageUserId"},
{UserId, "userId"}, {UserId, "userId"},
{UserName, "userName"}, {UserName, "userName"},
{PreviousMessageDay, "previousMessageDay"},
{Day, "day"},
{Timestamp, "timestamp"}, {Timestamp, "timestamp"},
{Url, "url"}, {Url, "url"},
{ThumbnailUrl, "thumbnailUrl"}, {ThumbnailUrl, "thumbnailUrl"},
@ -323,6 +325,11 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
case UserName: case UserName:
return QVariant(displayName(QString::fromStdString(acc::sender(event)))); return QVariant(displayName(QString::fromStdString(acc::sender(event))));
case Day: {
QDateTime prevDate = origin_server_ts(event);
prevDate.setTime(QTime());
return QVariant(prevDate.toMSecsSinceEpoch());
}
case Timestamp: case Timestamp:
return QVariant(origin_server_ts(event)); return QVariant(origin_server_ts(event));
case Type: case Type:
@ -450,7 +457,6 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
QVariantMap m; QVariantMap m;
auto names = roleNames(); auto names = roleNames();
// m.insert(names[Section], data(id, static_cast<int>(Section)));
m.insert(names[Type], data(event, static_cast<int>(Type))); m.insert(names[Type], data(event, static_cast<int>(Type)));
m.insert(names[TypeString], data(event, static_cast<int>(TypeString))); m.insert(names[TypeString], data(event, static_cast<int>(TypeString)));
m.insert(names[IsOnlyEmoji], data(event, static_cast<int>(IsOnlyEmoji))); m.insert(names[IsOnlyEmoji], data(event, static_cast<int>(IsOnlyEmoji)));
@ -458,6 +464,7 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
m.insert(names[FormattedBody], data(event, static_cast<int>(FormattedBody))); m.insert(names[FormattedBody], data(event, static_cast<int>(FormattedBody)));
m.insert(names[UserId], data(event, static_cast<int>(UserId))); m.insert(names[UserId], data(event, static_cast<int>(UserId)));
m.insert(names[UserName], data(event, static_cast<int>(UserName))); m.insert(names[UserName], data(event, static_cast<int>(UserName)));
m.insert(names[Day], data(event, static_cast<int>(Day)));
m.insert(names[Timestamp], data(event, static_cast<int>(Timestamp))); m.insert(names[Timestamp], data(event, static_cast<int>(Timestamp)));
m.insert(names[Url], data(event, static_cast<int>(Url))); m.insert(names[Url], data(event, static_cast<int>(Url)));
m.insert(names[ThumbnailUrl], data(event, static_cast<int>(ThumbnailUrl))); m.insert(names[ThumbnailUrl], data(event, static_cast<int>(ThumbnailUrl)));
@ -498,30 +505,17 @@ TimelineModel::data(const QModelIndex &index, int role) const
if (!event) if (!event)
return ""; return "";
if (role == Section) { if (role == PreviousMessageDay || role == PreviousMessageUserId) {
QDateTime date = origin_server_ts(*event); int prevIdx = rowCount() - index.row() - 2;
date.setTime(QTime()); if (prevIdx < 0)
return QVariant();
std::string userId = acc::sender(*event); auto tempEv = events.get(prevIdx);
if (!tempEv)
for (int r = rowCount() - index.row(); r < events.size(); r++) { return QVariant();
auto tempEv = events.get(r); if (role == PreviousMessageUserId)
if (!tempEv) return data(*tempEv, UserId);
break; else
return data(*tempEv, Day);
QDateTime prevDate = origin_server_ts(*tempEv);
prevDate.setTime(QTime());
if (prevDate != date)
return QString("%2 %1")
.arg(date.toMSecsSinceEpoch())
.arg(QString::fromStdString(userId));
std::string prevUserId = acc::sender(*tempEv);
if (userId != prevUserId)
break;
}
return QString("%1").arg(QString::fromStdString(userId));
} }
return data(*event, role); return data(*event, role);

View file

@ -159,14 +159,16 @@ public:
enum Roles enum Roles
{ {
Section,
Type, Type,
TypeString, TypeString,
IsOnlyEmoji, IsOnlyEmoji,
Body, Body,
FormattedBody, FormattedBody,
PreviousMessageUserId,
UserId, UserId,
UserName, UserName,
PreviousMessageDay,
Day,
Timestamp, Timestamp,
Url, Url,
ThumbnailUrl, ThumbnailUrl,