From 0db34cc3c8ee6f08dd9182d066042b117282dcd7 Mon Sep 17 00:00:00 2001 From: miruka Date: Sat, 14 Sep 2019 00:36:19 -0400 Subject: [PATCH] Add EventMediaLoader Handles loading of URL previews and will handle all matrix media messages types. --- src/python/models/items.py | 2 +- src/qml/Base/HImage.qml | 6 +- src/qml/Chat/Timeline/EventContent.qml | 12 ++-- src/qml/Chat/Timeline/EventDelegate.qml | 3 +- src/qml/Chat/Timeline/EventMediaLoader.qml | 65 ++++++++++++++++++++++ src/qml/utils.js | 6 ++ 6 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 src/qml/Chat/Timeline/EventMediaLoader.qml diff --git a/src/python/models/items.py b/src/python/models/items.py index 2d469b3e..622f5893 100644 --- a/src/python/models/items.py +++ b/src/python/models/items.py @@ -166,7 +166,7 @@ class Event(ModelItem): return [] if isinstance(self.source, nio.RoomMessageMedia): - return [self.thumbnail_url or self.content] + return [self.media_url] return [link[2] for link in lxml.html.iterlinks(self.content)] diff --git a/src/qml/Base/HImage.qml b/src/qml/Base/HImage.qml index 7461bbc6..3738dffe 100644 --- a/src/qml/Base/HImage.qml +++ b/src/qml/Base/HImage.qml @@ -1,4 +1,5 @@ import QtQuick 2.12 +import "../utils.js" as Utils Image { id: image @@ -12,10 +13,7 @@ Image { property bool animate: true - readonly property bool animated: - image.source.toString() - .split("/").splice(-1)[0].split("?")[0].toLowerCase() - .endsWith(".gif") + readonly property bool animated: Utils.urlExtension(image.source) == "gif" Component { diff --git a/src/qml/Chat/Timeline/EventContent.qml b/src/qml/Chat/Timeline/EventContent.qml index 2c09f4ff..1f5a3a2f 100644 --- a/src/qml/Chat/Timeline/EventContent.qml +++ b/src/qml/Chat/Timeline/EventContent.qml @@ -148,15 +148,11 @@ Row { Repeater { id: previewLinksRepeater - model: eventDelegate.links + model: eventDelegate.currentItem.links - HLoader { - Component.onCompleted: { - setSource( - "EventImage.qml", - { source: modelData }, - ) - } + EventMediaLoader { + info: eventDelegate.currentItem + mediaUrl: modelData } } } diff --git a/src/qml/Chat/Timeline/EventDelegate.qml b/src/qml/Chat/Timeline/EventDelegate.qml index 815ea2f3..b1cd20f0 100644 --- a/src/qml/Chat/Timeline/EventDelegate.qml +++ b/src/qml/Chat/Timeline/EventDelegate.qml @@ -17,6 +17,7 @@ Column { // Remember timeline goes from newest message at index 0 to oldest property var previousItem: eventList.model.get(model.index + 1) property var nextItem: eventList.model.get(model.index - 1) + readonly property QtObject currentItem: model property int modelIndex: model.index onModelIndexChanged: { @@ -47,8 +48,6 @@ Column { readonly property bool unselectableNameLine: hideNameLine && ! (onRight && ! combine) - readonly property var links: model.links - function json() { return JSON.stringify( diff --git a/src/qml/Chat/Timeline/EventMediaLoader.qml b/src/qml/Chat/Timeline/EventMediaLoader.qml new file mode 100644 index 00000000..508a3187 --- /dev/null +++ b/src/qml/Chat/Timeline/EventMediaLoader.qml @@ -0,0 +1,65 @@ +import QtQuick 2.12 +import "../../Base" +import "../../utils.js" as Utils + +HLoader { + id: loader + + + enum Type { Page, File, Image, Video, Audio } + + property QtObject info + property url mediaUrl + + readonly property var imageExtensions: [ + "bmp", "gif", "jpg", "jpeg", "png", "pbm", "pgm", "ppm", "xbm", "xpm", + "tiff", "webp", "svg", + ] + + readonly property var videoExtensions: [ + "3gp", "avi", "flv", "m4p", "m4v", "mkv", "mov", "mp4", + "mpeg", "mpg", "ogv", "qt", "vob", "webm", "wmv", "yuv", + ] + + readonly property var audioExtensions: [ + "pcm", "wav", "raw", "aiff", "flac", "m4a", "tta", "aac", "mp3", + "ogg", "oga", "opus", + ] + + readonly property int type: { + let main_type = info.media_mime.split("/")[0].toLowerCase() + + if (main_type === "image") return EventMediaLoader.Type.Image + if (main_type === "video") return EventMediaLoader.Type.Video + if (main_type === "audio") return EventMediaLoader.Type.Audio + + if (info.event_type === "RoomMessageFile") + return EventMediaLoader.Type.File + + let ext = Utils.urlExtension(mediaUrl) + + if (imageExtensions.includes(ext)) return EventMediaLoader.Type.Image + if (videoExtensions.includes(ext)) return EventMediaLoader.Type.Video + if (audioExtensions.includes(ext)) return EventMediaLoader.Type.Audio + + return EventMediaLoader.Type.Page + } + + readonly property url previewUrl: ( + type === EventMediaLoader.Type.File || + type === EventMediaLoader.Type.Image ? + info.thumbnail_url : "" + ) || mediaUrl + + + onPreviewUrlChanged: { + if (type === EventMediaLoader.Type.Image) { + var file = "EventImage.qml" + var props = { source: previewUrl } + } else { + return + } + + loader.setSource(file, props) + } +} diff --git a/src/qml/utils.js b/src/qml/utils.js index 2764a103..80d44d54 100644 --- a/src/qml/utils.js +++ b/src/qml/utils.js @@ -250,3 +250,9 @@ function copyToClipboard(text) { window.pseudoClipboard.selectAll() window.pseudoClipboard.copy() } + + +function urlExtension(url) { + return url.toString().split("/").splice(-1)[0].split("?")[0].split(".") + .splice(-1)[0].toLowerCase() +}