diff --git a/.gitignore b/.gitignore
index 23b84039..0f61a911 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,9 @@ ui_*.h
*.qmlproject.user
*.qmlproject.user.*
+# Vim
+*.swp
+
#####=== CMake ===#####
CMakeCache.txt
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 3d4c1147..7ff51362 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -1,4 +1,6 @@
-import QtQuick 2.1
+import QtQuick 2.5
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.5
Rectangle {
anchors.fill: parent
@@ -17,9 +19,89 @@ Rectangle {
id: chat
model: timelineManager.timeline
- delegate: Text {
- height: contentHeight
- text: model.userId
+ delegate: RowLayout {
+ width: chat.width
+ Text {
+ Layout.fillWidth: true
+ height: contentHeight
+ text: model.userName
+ }
+
+ Button {
+ Layout.alignment: Qt.AlignRight
+ id: replyButton
+ flat: true
+ height: replyButtonImg.contentHeight
+ width: replyButtonImg.contentWidth
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("Reply")
+ Image {
+ id: replyButtonImg
+ // Workaround, can't get icon.source working for now...
+ anchors.fill: parent
+ source: "qrc:/icons/icons/ui/mail-reply.png"
+ }
+ }
+ Button {
+ Layout.alignment: Qt.AlignRight
+ id: optionsButton
+ flat: true
+ height: optionsButtonImg.contentHeight
+ width: optionsButtonImg.contentWidth
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("Options")
+ Image {
+ id: optionsButtonImg
+ // Workaround, can't get icon.source working for now...
+ anchors.fill: parent
+ source: "qrc:/icons/icons/ui/vertical-ellipsis.png"
+ }
+
+ onClicked: contextMenu.open()
+
+ Menu {
+ y: optionsButton.height
+ id: contextMenu
+
+ MenuItem {
+ text: "Read receipts"
+ }
+ MenuItem {
+ text: "Mark as read"
+ }
+ MenuItem {
+ text: "View raw message"
+ }
+ MenuItem {
+ text: "Redact message"
+ }
+ }
+ }
+
+ Text {
+ Layout.alignment: Qt.AlignRight
+ text: model.timestamp.toLocaleTimeString("HH:mm")
+ }
+ }
+
+ section {
+ property: "section"
+ delegate: Column {
+ width: parent.width
+ Label {
+ anchors.horizontalCenter: parent.horizontalCenter
+ visible: section.includes(" ")
+ text: Qt.formatDate(new Date(Number(section.split(" ")[1])))
+ height: contentHeight * 1.2
+ width: contentWidth * 1.2
+ horizontalAlignment: Text.AlignHCenter
+ background: Rectangle {
+ radius: parent.height / 2
+ color: "black"
+ }
+ }
+ Text { text: section.split(" ")[0] }
+ }
}
}
}
diff --git a/src/timeline/.TimelineItem.cpp.swp b/src/timeline/.TimelineItem.cpp.swp
deleted file mode 100644
index 75e03aeb..00000000
--- a/src/timeline/.TimelineItem.cpp.swp
+++ /dev/null
Binary files differdiff --git a/src/timeline2/TimelineModel.cpp b/src/timeline2/TimelineModel.cpp
index 10a5d3bf..8a74edaf 100644
--- a/src/timeline2/TimelineModel.cpp
+++ b/src/timeline2/TimelineModel.cpp
@@ -22,6 +22,13 @@ senderId(const T &event)
{
return QString::fromStdString(event.sender);
}
+
+template<class T>
+QDateTime
+eventTimestamp(const T &event)
+{
+ return QDateTime::fromMSecsSinceEpoch(event.origin_server_ts);
+}
}
TimelineModel::TimelineModel(QString room_id, QObject *parent)
@@ -36,6 +43,7 @@ QHash<int, QByteArray>
TimelineModel::roleNames() const
{
return {
+ {Section, "section"},
{Type, "type"},
{Body, "body"},
{FormattedBody, "formattedBody"},
@@ -55,16 +63,49 @@ TimelineModel::rowCount(const QModelIndex &parent) const
QVariant
TimelineModel::data(const QModelIndex &index, int role) const
{
- nhlog::ui()->info("data");
if (index.row() < 0 && index.row() >= (int)eventOrder.size())
return QVariant();
QString id = eventOrder[index.row()];
switch (role) {
+ case Section: {
+ QDateTime date = boost::apply_visitor(
+ [](const auto &e) -> QDateTime { return eventTimestamp(e); }, events.value(id));
+ date.setTime(QTime());
+
+ QString userId = boost::apply_visitor(
+ [](const auto &e) -> QString { return senderId(e); }, events.value(id));
+
+ for (int r = index.row() - 1; r > 0; r--) {
+ QDateTime prevDate = boost::apply_visitor(
+ [](const auto &e) -> QDateTime { return eventTimestamp(e); },
+ events.value(eventOrder[r]));
+ prevDate.setTime(QTime());
+ if (prevDate != date)
+ return QString("%2 %1").arg(date.toMSecsSinceEpoch()).arg(userId);
+
+ QString prevUserId =
+ boost::apply_visitor([](const auto &e) -> QString { return senderId(e); },
+ events.value(eventOrder[r]));
+ if (userId != prevUserId)
+ break;
+ }
+
+ return QString("%1").arg(userId);
+ }
case UserId:
return QVariant(boost::apply_visitor(
[](const auto &e) -> QString { return senderId(e); }, events.value(id)));
+ case UserName:
+ return QVariant(Cache::displayName(
+ room_id_,
+ boost::apply_visitor([](const auto &e) -> QString { return senderId(e); },
+ events.value(id))));
+
+ case Timestamp:
+ return QVariant(boost::apply_visitor(
+ [](const auto &e) -> QDateTime { return eventTimestamp(e); }, events.value(id)));
default:
return QVariant();
}
diff --git a/src/timeline2/TimelineModel.h b/src/timeline2/TimelineModel.h
index a4224538..41a25f61 100644
--- a/src/timeline2/TimelineModel.h
+++ b/src/timeline2/TimelineModel.h
@@ -15,6 +15,7 @@ public:
enum Roles
{
+ Section,
Type,
Body,
FormattedBody,
diff --git a/src/timeline2/TimelineViewManager.h b/src/timeline2/TimelineViewManager.h
index 7f760eac..ff976aad 100644
--- a/src/timeline2/TimelineViewManager.h
+++ b/src/timeline2/TimelineViewManager.h
@@ -34,7 +34,6 @@ public:
Q_INVOKABLE TimelineModel *activeTimeline() const
{
- nhlog::ui()->info("aaaa");
return timeline_;
}
|