summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--resources/qml/TimelineView.qml6
-rw-r--r--resources/qml/delegates/ImageMessage.qml14
-rw-r--r--resources/res.qrc1
-rw-r--r--src/MxcImageProvider.h1
-rw-r--r--src/timeline2/TimelineModel.cpp66
-rw-r--r--src/timeline2/TimelineModel.h4
6 files changed, 90 insertions, 2 deletions
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 0151686a..399e85eb 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -23,6 +23,8 @@ Rectangle {
 	ListView {
 		id: chat
 
+		cacheBuffer: 4*parent.height
+
 		visible: timelineManager.timeline != null
 		anchors.fill: parent
 
@@ -40,12 +42,14 @@ Rectangle {
 			anchors.left: parent.left
 			anchors.right: parent.right
 			anchors.rightMargin: scrollbar.width
+			height: loader.height
 
 			Loader {
 				id: loader
+				asynchronous: false
 				Layout.fillWidth: true
-				height: item.height
 				Layout.alignment: Qt.AlignTop
+				height: item.height
 
 				source: switch(model.type) {
 					case MtxEvent.Aliases: return "delegates/Aliases.qml"
diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml
new file mode 100644
index 00000000..a3bc78e5
--- /dev/null
+++ b/resources/qml/delegates/ImageMessage.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.6
+
+Item {
+	width: 300
+	height: 300 * eventData.proportionalHeight
+
+	Image {
+		anchors.fill: parent
+
+		source: eventData.url.replace("mxc://", "image://MxcImage/")
+		asynchronous: true
+		fillMode: Image.PreserveAspectFit
+	}
+}
diff --git a/resources/res.qrc b/resources/res.qrc
index 6f6d480a..62ed53e5 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -119,5 +119,6 @@
         <file>qml/Avatar.qml</file>
         <file>qml/delegates/TextMessage.qml</file>
         <file>qml/delegates/NoticeMessage.qml</file>
+        <file>qml/delegates/ImageMessage.qml</file>
     </qresource>
 </RCC>
diff --git a/src/MxcImageProvider.h b/src/MxcImageProvider.h
index 8710171c..19d8a74e 100644
--- a/src/MxcImageProvider.h
+++ b/src/MxcImageProvider.h
@@ -45,4 +45,3 @@ public:
 private:
         QThreadPool pool;
 };
-
diff --git a/src/timeline2/TimelineModel.cpp b/src/timeline2/TimelineModel.cpp
index 310494b4..16f1dfe6 100644
--- a/src/timeline2/TimelineModel.cpp
+++ b/src/timeline2/TimelineModel.cpp
@@ -59,6 +59,20 @@ eventFormattedBody(const mtx::events::RoomEvent<T> &e)
 }
 
 template<class T>
+QString
+eventUrl(const T &)
+{
+        return "";
+}
+template<class T>
+auto
+eventUrl(const mtx::events::RoomEvent<T> &e)
+  -> std::enable_if_t<std::is_same<decltype(e.content.url), std::string>::value, QString>
+{
+        return QString::fromStdString(e.content.url);
+}
+
+template<class T>
 qml_mtx_events::EventType
 toRoomEventType(const mtx::events::Event<T> &e)
 {
@@ -146,6 +160,41 @@ toRoomEventType(const mtx::events::Event<mtx::events::msg::Video> &)
 }
 // ::EventType::Type toRoomEventType(const Event<mtx::events::msg::Location> &e) { return
 // ::EventType::LocationMessage; }
+
+template<class T>
+uint64_t
+eventHeight(const mtx::events::Event<T> &)
+{
+        return -1;
+}
+template<class T>
+auto
+eventHeight(const mtx::events::RoomEvent<T> &e) -> decltype(e.content.info.h)
+{
+        return e.content.info.h;
+}
+template<class T>
+uint64_t
+eventWidth(const mtx::events::Event<T> &)
+{
+        return -1;
+}
+template<class T>
+auto
+eventWidth(const mtx::events::RoomEvent<T> &e) -> decltype(e.content.info.w)
+{
+        return e.content.info.w;
+}
+
+template<class T>
+double
+eventPropHeight(const mtx::events::RoomEvent<T> &e)
+{
+        auto w = eventWidth(e);
+        if (w == 0)
+                w = 1;
+        return eventHeight(e) / (double)w;
+}
 }
 
 TimelineModel::TimelineModel(QString room_id, QObject *parent)
@@ -167,6 +216,10 @@ TimelineModel::roleNames() const
           {UserId, "userId"},
           {UserName, "userName"},
           {Timestamp, "timestamp"},
+          {Url, "url"},
+          {Height, "height"},
+          {Width, "width"},
+          {ProportionalHeight, "proportionalHeight"},
         };
 }
 int
@@ -228,6 +281,19 @@ TimelineModel::data(const QModelIndex &index, int role) const
                 return QVariant(utils::replaceEmoji(boost::apply_visitor(
                   [](const auto &e) -> QString { return eventFormattedBody(e); },
                   events.value(id))));
+        case Url:
+                return QVariant(boost::apply_visitor(
+                  [](const auto &e) -> QString { return eventUrl(e); }, events.value(id)));
+        case Height:
+                return QVariant(boost::apply_visitor(
+                  [](const auto &e) -> qulonglong { return eventHeight(e); }, events.value(id)));
+        case Width:
+                return QVariant(boost::apply_visitor(
+                  [](const auto &e) -> qulonglong { return eventWidth(e); }, events.value(id)));
+        case ProportionalHeight:
+                return QVariant(boost::apply_visitor(
+                  [](const auto &e) -> double { return eventPropHeight(e); }, events.value(id)));
+
         default:
                 return QVariant();
         }
diff --git a/src/timeline2/TimelineModel.h b/src/timeline2/TimelineModel.h
index 954da5eb..66d03cf5 100644
--- a/src/timeline2/TimelineModel.h
+++ b/src/timeline2/TimelineModel.h
@@ -82,6 +82,10 @@ public:
                 UserId,
                 UserName,
                 Timestamp,
+                Url,
+                Height,
+                Width,
+                ProportionalHeight,
         };
 
         QHash<int, QByteArray> roleNames() const override;