mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Simplify section handling a bit
This commit is contained in:
parent
9192dc8ae5
commit
32a20a5f8c
4 changed files with 49 additions and 73 deletions
|
@ -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: {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
for (int r = rowCount() - index.row(); r < events.size(); r++) {
|
|
||||||
auto tempEv = events.get(r);
|
|
||||||
if (!tempEv)
|
if (!tempEv)
|
||||||
break;
|
return QVariant();
|
||||||
|
if (role == PreviousMessageUserId)
|
||||||
QDateTime prevDate = origin_server_ts(*tempEv);
|
return data(*tempEv, UserId);
|
||||||
prevDate.setTime(QTime());
|
else
|
||||||
if (prevDate != date)
|
return data(*tempEv, Day);
|
||||||
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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue