diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 35dcae03..c4750ddf 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -111,6 +111,7 @@ Rectangle {
case MtxEvent.NoticeMessage: return "delegates/NoticeMessage.qml"
case MtxEvent.TextMessage: return "delegates/TextMessage.qml"
case MtxEvent.ImageMessage: return "delegates/ImageMessage.qml"
+ case MtxEvent.FileMessage: return "delegates/FileMessage.qml"
//case MtxEvent.VideoMessage: return "delegates/VideoMessage.qml"
case MtxEvent.Redacted: return "delegates/Redacted.qml"
default: return "delegates/placeholder.qml"
diff --git a/resources/qml/delegates/FileMessage.qml b/resources/qml/delegates/FileMessage.qml
new file mode 100644
index 00000000..3099acaa
--- /dev/null
+++ b/resources/qml/delegates/FileMessage.qml
@@ -0,0 +1,57 @@
+import QtQuick 2.6
+
+Row {
+Rectangle {
+ radius: 10
+ color: colors.dark
+ height: row.height
+ width: row.width
+
+ Row {
+ id: row
+
+ spacing: 15
+ padding: 12
+
+ Rectangle {
+ color: colors.light
+ radius: 22
+ height: 44
+ width: 44
+ Image {
+ id: img
+ anchors.centerIn: parent
+
+ source: "qrc:/icons/icons/ui/arrow-pointing-down.png"
+ fillMode: Image.Pad
+
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: timelineManager.saveMedia(eventData.url, eventData.filename, eventData.mimetype, eventData.type)
+ cursorShape: Qt.PointingHandCursor
+ }
+ }
+ Column {
+ TextEdit {
+ text: eventData.body
+ textFormat: TextEdit.PlainText
+ readOnly: true
+ wrapMode: Text.Wrap
+ selectByMouse: true
+ color: colors.text
+ }
+ TextEdit {
+ text: eventData.filesize
+ textFormat: TextEdit.PlainText
+ readOnly: true
+ wrapMode: Text.Wrap
+ selectByMouse: true
+ color: colors.text
+ }
+ }
+ }
+}
+Rectangle {
+}
+}
diff --git a/resources/res.qrc b/resources/res.qrc
index 02b4c0c0..c865200c 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -122,6 +122,7 @@
qml/delegates/TextMessage.qml
qml/delegates/NoticeMessage.qml
qml/delegates/ImageMessage.qml
+ qml/delegates/FileMessage.qml
qml/delegates/Redacted.qml
qml/delegates/placeholder.qml
diff --git a/src/timeline2/TimelineModel.cpp b/src/timeline2/TimelineModel.cpp
index 83d1e417..d624c938 100644
--- a/src/timeline2/TimelineModel.cpp
+++ b/src/timeline2/TimelineModel.cpp
@@ -87,8 +87,9 @@ eventFormattedBody(const mtx::events::RoomEvent &e)
if (pos != std::string::npos)
temp.erase(pos, std::string("").size());
return QString::fromStdString(temp);
- } else
- return QString::fromStdString(e.content.body);
+ } else {
+ return QString::fromStdString(e.content.body).toHtmlEscaped().replace("\n", "
");
+ }
}
template
@@ -138,6 +139,20 @@ eventFilename(const mtx::events::RoomEvent &e)
return QString::fromStdString(e.content.body);
}
+template
+auto
+eventFilesize(const mtx::events::RoomEvent &e) -> decltype(e.content.info.size)
+{
+ return e.content.info.size;
+}
+
+template
+int64_t
+eventFilesize(const T &)
+{
+ return 0;
+}
+
template
QString
eventMimeType(const T &)
@@ -341,6 +356,7 @@ TimelineModel::roleNames() const
{Timestamp, "timestamp"},
{Url, "url"},
{Filename, "filename"},
+ {Filesize, "filesize"},
{MimeType, "mimetype"},
{Height, "height"},
{Width, "width"},
@@ -423,6 +439,12 @@ TimelineModel::data(const QModelIndex &index, int role) const
case Filename:
return QVariant(boost::apply_visitor(
[](const auto &e) -> QString { return eventFilename(e); }, event));
+ case Filesize:
+ return QVariant(boost::apply_visitor(
+ [](const auto &e) -> QString {
+ return utils::humanReadableFileSize(eventFilesize(e));
+ },
+ event));
case MimeType:
return QVariant(boost::apply_visitor(
[](const auto &e) -> QString { return eventMimeType(e); }, event));
diff --git a/src/timeline2/TimelineModel.h b/src/timeline2/TimelineModel.h
index 10f3c490..b00988f8 100644
--- a/src/timeline2/TimelineModel.h
+++ b/src/timeline2/TimelineModel.h
@@ -130,6 +130,7 @@ public:
Timestamp,
Url,
Filename,
+ Filesize,
MimeType,
Height,
Width,