summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-08-29 15:33:39 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-08-29 16:32:28 +0200
commit15bf643347e507513d6999dd346f0cce9c7952c8 (patch)
treef0b0470e0731e063021b57165391a2b5597ecaf3
parentcleanup QSettings usage a bit (diff)
downloadnheko-15bf643347e507513d6999dd346f0cce9c7952c8.tar.xz
Add option to only play animated images on hover
-rw-r--r--resources/qml/delegates/ImageMessage.qml1
-rw-r--r--src/UserSettingsPage.cpp21
-rw-r--r--src/UserSettingsPage.h7
-rw-r--r--src/ui/MxcAnimatedImage.cpp9
-rw-r--r--src/ui/MxcAnimatedImage.h12
5 files changed, 49 insertions, 1 deletions
diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml
index f39176b3..64e365c8 100644
--- a/resources/qml/delegates/ImageMessage.qml
+++ b/resources/qml/delegates/ImageMessage.qml
@@ -63,6 +63,7 @@ Item {
         visible: loaded
         anchors.fill: parent
         roomm: room
+        play: !Settings.animateImagesOnHover || mouseArea.hovered
         eventId: parent.eventId
     }
 
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index fa94616f..d55a0f61 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -79,6 +79,7 @@ UserSettings::load(std::optional<QString> profile)
         enlargeEmojiOnlyMessages_ =
           settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool();
         markdown_             = settings.value("user/markdown_enabled", true).toBool();
+        animateImagesOnHover_ = settings.value("user/animate_images_on_hover", false).toBool();
         typingNotifications_  = settings.value("user/typing_notifications", true).toBool();
         sortByImportance_     = settings.value("user/sort_by_unread", true).toBool();
         readReceipts_         = settings.value("user/read_receipts", true).toBool();
@@ -208,6 +209,16 @@ UserSettings::setMarkdown(bool state)
 }
 
 void
+UserSettings::setAnimateImagesOnHover(bool state)
+{
+        if (state == animateImagesOnHover_)
+                return;
+        animateImagesOnHover_ = state;
+        emit animateImagesOnHoverChanged(state);
+        save();
+}
+
+void
 UserSettings::setReadReceipts(bool state)
 {
         if (state == readReceipts_)
@@ -643,6 +654,7 @@ UserSettings::save()
         settings.setValue("group_view", groupView_);
         settings.setValue("hidden_tags", hiddenTags_);
         settings.setValue("markdown_enabled", markdown_);
+        settings.setValue("animate_images_on_hover", animateImagesOnHover_);
         settings.setValue("desktop_notifications", hasDesktopNotifications_);
         settings.setValue("alert_on_notification", hasAlertOnNotification_);
         settings.setValue("theme", theme());
@@ -747,6 +759,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
         sortByImportance_               = new Toggle{this};
         readReceipts_                   = new Toggle{this};
         markdown_                       = new Toggle{this};
+        animateImagesOnHover_           = new Toggle{this};
         desktopNotifications_           = new Toggle{this};
         alertOnNotification_            = new Toggle{this};
         useStunServer_                  = new Toggle{this};
@@ -779,6 +792,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
         sortByImportance_->setChecked(settings_->sortByImportance());
         readReceipts_->setChecked(settings_->readReceipts());
         markdown_->setChecked(settings_->markdown());
+        animateImagesOnHover_->setChecked(settings_->animateImagesOnHover());
         desktopNotifications_->setChecked(settings_->hasDesktopNotifications());
         alertOnNotification_->setChecked(settings_->hasAlertOnNotification());
         useStunServer_->setChecked(settings_->useStunServer());
@@ -973,6 +987,9 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
           markdown_,
           tr("Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain "
              "text."));
+        boxWrap(tr("Play animated images only on hover"),
+                animateImagesOnHover_,
+                tr("Plays media like GIFs or APNGs only when explicitly hovering over them."));
         boxWrap(tr("Desktop notifications"),
                 desktopNotifications_,
                 tr("Notify about received message when the client is not currently focused."));
@@ -1250,6 +1267,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
                 settings_->setMarkdown(enabled);
         });
 
+        connect(animateImagesOnHover_, &Toggle::toggled, this, [this](bool enabled) {
+                settings_->setAnimateImagesOnHover(enabled);
+        });
+
         connect(typingNotifications_, &Toggle::toggled, this, [this](bool enabled) {
                 settings_->setTypingNotifications(enabled);
         });
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index ab9c9a3b..93b53211 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -40,6 +40,8 @@ class UserSettings : public QObject
         Q_PROPERTY(bool startInTray READ startInTray WRITE setStartInTray NOTIFY startInTrayChanged)
         Q_PROPERTY(bool groupView READ groupView WRITE setGroupView NOTIFY groupViewStateChanged)
         Q_PROPERTY(bool markdown READ markdown WRITE setMarkdown NOTIFY markdownChanged)
+        Q_PROPERTY(bool animateImagesOnHover READ animateImagesOnHover WRITE setAnimateImagesOnHover
+                     NOTIFY animateImagesOnHoverChanged)
         Q_PROPERTY(bool typingNotifications READ typingNotifications WRITE setTypingNotifications
                      NOTIFY typingNotificationsChanged)
         Q_PROPERTY(bool sortByImportance READ sortByImportance WRITE setSortByImportance NOTIFY
@@ -135,6 +137,7 @@ public:
         void setEmojiFontFamily(QString family);
         void setGroupView(bool state);
         void setMarkdown(bool state);
+        void setAnimateImagesOnHover(bool state);
         void setReadReceipts(bool state);
         void setTypingNotifications(bool state);
         void setSortByImportance(bool state);
@@ -181,6 +184,7 @@ public:
         bool privacyScreen() const { return privacyScreen_; }
         int privacyScreenTimeout() const { return privacyScreenTimeout_; }
         bool markdown() const { return markdown_; }
+        bool animateImagesOnHover() const { return animateImagesOnHover_; }
         bool typingNotifications() const { return typingNotifications_; }
         bool sortByImportance() const { return sortByImportance_; }
         bool buttonsInTimeline() const { return buttonsInTimeline_; }
@@ -236,6 +240,7 @@ signals:
         void trayChanged(bool state);
         void startInTrayChanged(bool state);
         void markdownChanged(bool state);
+        void animateImagesOnHoverChanged(bool state);
         void typingNotificationsChanged(bool state);
         void buttonInTimelineChanged(bool state);
         void readReceiptsChanged(bool state);
@@ -286,6 +291,7 @@ private:
         bool startInTray_;
         bool groupView_;
         bool markdown_;
+        bool animateImagesOnHover_;
         bool typingNotifications_;
         bool sortByImportance_;
         bool buttonsInTimeline_;
@@ -381,6 +387,7 @@ private:
         Toggle *sortByImportance_;
         Toggle *readReceipts_;
         Toggle *markdown_;
+        Toggle *animateImagesOnHover_;
         Toggle *desktopNotifications_;
         Toggle *alertOnNotification_;
         Toggle *avatarCircles_;
diff --git a/src/ui/MxcAnimatedImage.cpp b/src/ui/MxcAnimatedImage.cpp
index cfc03827..3c93cc2b 100644
--- a/src/ui/MxcAnimatedImage.cpp
+++ b/src/ui/MxcAnimatedImage.cpp
@@ -94,8 +94,12 @@ MxcAnimatedImage::startDownload()
                                           buffer.isOpen());
                         movie.setFormat(mimeType);
                         movie.setDevice(&buffer);
-                        movie.start();
+                        if (play_)
+                                movie.start();
+                        else
+                                movie.jumpToFrame(0);
                         emit loadedChanged();
+                        update();
                 });
         };
 
@@ -143,6 +147,9 @@ MxcAnimatedImage::startDownload()
 QSGNode *
 MxcAnimatedImage::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
 {
+        if (!imageDirty)
+                return oldNode;
+
         imageDirty      = false;
         QSGImageNode *n = static_cast<QSGImageNode *>(oldNode);
         if (!n)
diff --git a/src/ui/MxcAnimatedImage.h b/src/ui/MxcAnimatedImage.h
index 7b9502e0..2e0489ad 100644
--- a/src/ui/MxcAnimatedImage.h
+++ b/src/ui/MxcAnimatedImage.h
@@ -19,6 +19,7 @@ class MxcAnimatedImage : public QQuickItem
         Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
         Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged)
         Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
+        Q_PROPERTY(bool play READ play WRITE setPlay NOTIFY playChanged)
 public:
         MxcAnimatedImage(QQuickItem *parent = nullptr)
           : QQuickItem(parent)
@@ -32,6 +33,7 @@ public:
 
         bool animatable() const { return animatable_; }
         bool loaded() const { return buffer.size() > 0; }
+        bool play() const { return play_; }
         QString eventId() const { return eventId_; }
         TimelineModel *room() const { return room_; }
         void setEventId(QString newEventId)
@@ -48,6 +50,14 @@ public:
                         emit roomChanged();
                 }
         }
+        void setPlay(bool newPlay)
+        {
+                if (play_ != newPlay) {
+                        play_ = newPlay;
+                        movie.setPaused(!play_);
+                        emit playChanged();
+                }
+        }
 
         QSGNode *updatePaintNode(QSGNode *oldNode,
                                  QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
@@ -57,6 +67,7 @@ signals:
         void eventIdChanged();
         void animatableChanged();
         void loadedChanged();
+        void playChanged();
 
 private slots:
         void startDownload();
@@ -76,4 +87,5 @@ private:
         QMovie movie;
         int currentFrame = 0;
         bool imageDirty  = true;
+        bool play_       = true;
 };