Implement basic ImageMessages in qml timeline

I suck at sizing so the images in the message are currently hardcoded to
300 pixels in width...
This commit is contained in:
Nicolas Werner 2019-09-08 12:44:46 +02:00
parent ebeb1eb772
commit 86f4119a05
6 changed files with 90 additions and 2 deletions

View file

@ -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"

View file

@ -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
}
}

View file

@ -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>

View file

@ -45,4 +45,3 @@ public:
private:
QThreadPool pool;
};

View file

@ -58,6 +58,20 @@ eventFormattedBody(const mtx::events::RoomEvent<T> &e)
return QString::fromStdString(e.content.body);
}
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();
}

View file

@ -82,6 +82,10 @@ public:
UserId,
UserName,
Timestamp,
Url,
Height,
Width,
ProportionalHeight,
};
QHash<int, QByteArray> roleNames() const override;