summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim.cournoyer@gmail.com>2022-01-27 10:27:14 -0500
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>2022-01-27 10:51:54 -0500
commit95a74533f12a2636caafc93f24a8058adc8d27c9 (patch)
tree81de286849b6749729d36b043c0484ab9c7cc576
parent649a4e9c9c0f6f03f5c7529f2373bb8d550f6e32 (diff)
downloadguix-95a74533f12a2636caafc93f24a8058adc8d27c9.tar.gz
gnu: jami: Reduce memory consumption in conversation view.
This fixes <https://git.jami.net/savoirfairelinux/jami-client-qt/-/issues/649>.

* gnu/packages/patches/jami-images-loading.patch: New patch.
* gnu/packages/patches/jami-memory-usage.patch: Likewise.
* gnu/local.mk (dist_patch_DATA): Register them.
* gnu/packages/jami.scm (jami)[source]: Apply them.
-rw-r--r--gnu/local.mk2
-rw-r--r--gnu/packages/jami.scm4
-rw-r--r--gnu/packages/patches/jami-images-loading.patch152
-rw-r--r--gnu/packages/patches/jami-memory-usage.patch70
4 files changed, 227 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 76354b5ea1..b52e7b29cb 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1299,6 +1299,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/json-c-0.12-CVE-2020-12762.patch	\
   %D%/packages/patches/jsoncpp-pkg-config-version.patch		\
   %D%/packages/patches/jami-fix-crash-on-quit.patch		\
+  %D%/packages/patches/jami-images-loading.patch		\
+  %D%/packages/patches/jami-memory-usage.patch			\
   %D%/packages/patches/jamvm-1.5.1-aarch64-support.patch	\
   %D%/packages/patches/jamvm-1.5.1-armv7-support.patch	\
   %D%/packages/patches/jamvm-2.0.0-aarch64-support.patch	\
diff --git a/gnu/packages/jami.scm b/gnu/packages/jami.scm
index 9fcf55815b..c4300daf1b 100644
--- a/gnu/packages/jami.scm
+++ b/gnu/packages/jami.scm
@@ -568,7 +568,9 @@ decentralized calling using P2P-DHT.")
     (version %jami-version)
     (source (origin
               (inherit %jami-sources)
-              (patches (search-patches "jami-fix-crash-on-quit.patch"))))
+              (patches (search-patches "jami-fix-crash-on-quit.patch"
+                                       "jami-images-loading.patch"
+                                       "jami-memory-usage.patch"))))
     (build-system qt-build-system)
     (outputs '("out" "debug"))
     (arguments
diff --git a/gnu/packages/patches/jami-images-loading.patch b/gnu/packages/patches/jami-images-loading.patch
new file mode 100644
index 0000000000..caf9e1e198
--- /dev/null
+++ b/gnu/packages/patches/jami-images-loading.patch
@@ -0,0 +1,152 @@
+From be9dd0d0d8cb4556cd930edd783c0a1699565ac0 Mon Sep 17 00:00:00 2001
+From: kkostiuk <kateryna.kostiuk@savoirfairelinux.com>
+Date: Mon, 1 Nov 2021 17:39:23 -0400
+Subject: [PATCH] conversation: fix long loading time for images
+
+Change-Id: Id88cfbd571f4b504f258758bd13b4e4a91bf1b49
+---
+ .../DataTransferMessageDelegate.qml           | 52 +++++++++++++++++--
+ src/messagesadapter.cpp                       | 20 +++++--
+ src/messagesadapter.h                         |  2 +-
+ 3 files changed, 66 insertions(+), 8 deletions(-)
+
+diff --git a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
+index 7875e01..2e7dcc0 100644
+--- a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
++++ b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
+@@ -252,10 +252,11 @@ Loader {
+                 Loader {
+                     id: localMediaCompLoader
+                     anchors.right: isOutgoing ? parent.right : undefined
++                    asynchronous: true
+                     width: sourceComponent.width
+                     height: sourceComponent.height
+                     sourceComponent: mediaInfo.isImage !== undefined ?
+-                                         imageComp :
++                                         imageComp : mediaInfo.isAnimatedImage !== undefined ? animatedImageComp :
+                                          avComp
+                     Component {
+                         id: avComp
+@@ -302,9 +303,9 @@ Loader {
+                         }
+                     }
+                     Component {
+-                        id: imageComp
++                        id: animatedImageComp
+                         AnimatedImage {
+-                            id: img
++                            id: animatedImg
+                             anchors.right: isOutgoing ? parent.right : undefined
+                             property real minSize: 192
+                             property real maxSize: 256
+@@ -327,6 +328,51 @@ Loader {
+                                 anchors.fill: parent
+                             }
+                             layer.enabled: true
++                            layer.effect: OpacityMask {
++                                maskSource: MessageBubble {
++                                    out: isOutgoing
++                                    type: seq
++                                    width: animatedImg.width
++                                    height: animatedImg.height
++                                    radius: msgRadius
++                                }
++                            }
++                            HoverHandler {
++                                target : parent
++                                onHoveredChanged: {
++                                    localMediaMsgItem.hoveredLink = hovered ? animatedImg.source : ""
++                                }
++                                cursorShape: Qt.PointingHandCursor
++                            }
++                        }
++                    }
++
++                    Component {
++                        id: imageComp
++                        Image {
++                            id: img
++                            anchors.right: isOutgoing ? parent.right : undefined
++                            property real minSize: 192
++                            property real maxSize: 256
++                            cache: true
++                            fillMode: Image.PreserveAspectCrop
++                            mipmap: true
++                            antialiasing: true
++                            autoTransform: false
++                            asynchronous: true
++                            source: "file:///" + Body
++                            property real aspectRatio: implicitWidth / implicitHeight
++                            property real adjustedWidth: Math.min(maxSize,
++                                                                  Math.max(minSize,
++                                                                           innerContent.width - senderMargin))
++                            width: adjustedWidth
++                            height: Math.ceil(adjustedWidth / aspectRatio)
++                            Rectangle {
++                                color: JamiTheme.previewImageBackgroundColor
++                                z: -1
++                                anchors.fill: parent
++                            }
++                            layer.enabled: true
+                             layer.effect: OpacityMask {
+                                 maskSource: MessageBubble {
+                                     out: isOutgoing
+diff --git a/client-qt/src/messagesadapter.cpp b/client-qt/src/messagesadapter.cpp
+index 91f8eed..ba38e53 100644
+--- a/client-qt/src/messagesadapter.cpp
++++ b/client-qt/src/messagesadapter.cpp
+@@ -458,13 +458,24 @@ MessagesAdapter::conversationTypersUrlToName(const QSet<QString>& typersSet)
+     return nameList;
+ }
+ 
+-bool
++QVariantMap
+ MessagesAdapter::isLocalImage(const QString& msg)
+ {
+     QImageReader reader;
+     reader.setDecideFormatFromContent(true);
+     reader.setFileName(msg);
+-    return !reader.read().isNull();
++    QByteArray fileFormat = reader.format();
++    if (fileFormat == "gif") {
++        return {{"isAnimatedImage", true}};
++    }
++    QList<QByteArray> supportedFormats = reader.supportedImageFormats();
++    auto iterator = std::find_if(supportedFormats.begin(),
++                                 supportedFormats.end(),
++                                 [fileFormat](QByteArray format) { return format == fileFormat; });
++    if (iterator != supportedFormats.end()) {
++        return {{"isImage", true}};
++    }
++    return {{"isImage", false}};
+ }
+ 
+ QVariantMap
+@@ -476,8 +487,9 @@ MessagesAdapter::getMediaInfo(const QString& msg)
+           "<%1 style='width:100%;height:%2;outline:none;background-color:#f1f3f4;"
+           "object-fit:cover;' "
+           "controls controlsList='nodownload' src='file://%3' type='%4'/></body>";
+-    if (isLocalImage(msg)) {
+-        return {{"isImage", true}};
++    QVariantMap fileInfo = isLocalImage(msg);
++    if (fileInfo["isImage"].toBool() || fileInfo["isAnimatedImage"].toBool()) {
++        return fileInfo;
+     }
+     QRegularExpression vPattern("[^\\s]+(.*?)\\.(avi|mov|webm|webp|rmvb)$",
+                                 QRegularExpression::CaseInsensitiveOption);
+diff --git a/client-qt/src/messagesadapter.h b/client-qt/src/messagesadapter.h
+index bfa4e62..1965c5e 100644
+--- a/client-qt/src/messagesadapter.h
++++ b/client-qt/src/messagesadapter.h
+@@ -101,7 +101,7 @@ protected:
+     Q_INVOKABLE void deleteInteraction(const QString& interactionId);
+     Q_INVOKABLE void copyToDownloads(const QString& interactionId, const QString& displayName);
+     Q_INVOKABLE void userIsComposing(bool isComposing);
+-    Q_INVOKABLE bool isLocalImage(const QString& msg);
++    Q_INVOKABLE QVariantMap isLocalImage(const QString& msg);
+     Q_INVOKABLE QVariantMap getMediaInfo(const QString& msg);
+     Q_INVOKABLE bool isRemoteImage(const QString& msg);
+     Q_INVOKABLE QString getFormattedTime(const quint64 timestamp);
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/jami-memory-usage.patch b/gnu/packages/patches/jami-memory-usage.patch
new file mode 100644
index 0000000000..75fcde8d0a
--- /dev/null
+++ b/gnu/packages/patches/jami-memory-usage.patch
@@ -0,0 +1,70 @@
+From e796b3325d95b5ddd6162b5513c8325210f41fc5 Mon Sep 17 00:00:00 2001
+From: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+Date: Wed, 26 Jan 2022 11:37:07 -0500
+Subject: [PATCH] datatransferimage: improve memory usage
+
++ Reduce listview caching' size by 50%
++ use sourceSize to compress images and speedup loading
++ use autoTransform: true to rotate images when needed
+
+Change-Id: Idf1babdc73f43aa6a79b89428c25c5d06856c0ef
+GitLab: #649
+---
+
+diff --git a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
+index d017c03..ca5913e 100644
+--- a/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
++++ b/client-qt/src/commoncomponents/DataTransferMessageDelegate.qml
+@@ -255,9 +255,13 @@
+                     asynchronous: true
+                     width: sourceComponent.width
+                     height: sourceComponent.height
+-                    sourceComponent: mediaInfo.isImage !== undefined ?
+-                                         imageComp : mediaInfo.isAnimatedImage !== undefined ? animatedImageComp :
+-                                         avComp
++                    sourceComponent: {
++                        if (mediaInfo.isImage)
++                            return imageComp
++                        if (mediaInfo.isAnimatedImage)
++                            return animatedImageComp
++                        return avComp
++                    }
+                     Component {
+                         id: avComp
+                         WebEngineView {
+@@ -316,7 +320,7 @@
+                             fillMode: Image.PreserveAspectCrop
+                             mipmap: true
+                             antialiasing: true
+-                            autoTransform: false
++                            autoTransform: true
+                             asynchronous: true
+                             source: "file:///" + Body
+                             property real aspectRatio: implicitWidth / implicitHeight
+@@ -361,8 +365,10 @@
+                             fillMode: Image.PreserveAspectCrop
+                             mipmap: true
+                             antialiasing: true
+-                            autoTransform: false
++                            autoTransform: true
+                             asynchronous: true
++                            sourceSize.width: width
++                            sourceSize.height: height
+                             source: "file:///" + Body
+                             property real aspectRatio: implicitWidth / implicitHeight
+                             property real adjustedWidth: Math.min(maxSize,
+diff --git a/client-qt/src/mainview/components/MessageListView.qml b/client-qt/src/mainview/components/MessageListView.qml
+index 2b7c326..f65e67b 100644
+--- a/client-qt/src/mainview/components/MessageListView.qml
++++ b/client-qt/src/mainview/components/MessageListView.qml
+@@ -174,8 +174,8 @@
+     width: parent.width
+     // this offscreen caching is pretty huge
+     // displayMarginEnd may be removed
+-    displayMarginBeginning: 4096
+-    displayMarginEnd: 4096
++    displayMarginBeginning: 2048
++    displayMarginEnd: 2048
+     maximumFlickVelocity: 2048
+     verticalLayoutDirection: ListView.BottomToTop
+     boundsBehavior: Flickable.StopAtBounds