From 8c75ac8a1f6bef8e4ed623fc225783c873cafae9 Mon Sep 17 00:00:00 2001
From: Xavier Jouslin de Noray <xavier.jouslindenoray@savoirfairelinux.com>
Date: Thu, 2 Nov 2023 06:53:20 -0400
Subject: [PATCH] UpdateManager: fix to be able to update if needed

Gitlab: #1426

Change-Id: Ib6bda9d03fad23fe896ad76bda3d6fd52a1e2dbb
---
 src/app/pluginlistmodel.cpp                   | 13 +++--
 src/app/pluginlistmodel.h                     |  2 +
 src/app/pluginversionmanager.cpp              | 50 +++++++++++++------
 src/app/pluginversionmanager.h                |  1 +
 .../components/PluginItemDelegate.qml         | 30 +++++++++--
 .../components/PluginListView.qml             |  3 +-
 6 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/src/app/pluginlistmodel.cpp b/src/app/pluginlistmodel.cpp
index a63ffb4a6..e0040bbaa 100644
--- a/src/app/pluginlistmodel.cpp
+++ b/src/app/pluginlistmodel.cpp
@@ -218,10 +218,12 @@ void
 PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status)
 {
     auto pluginIndex = -1;
-    for (auto& p : installedPlugins_) {
+    QString pluginModelId = "";
+    for (const auto& p : installedPlugins_) {
         auto details = lrcInstance_->pluginModel().getPluginDetails(p);
-        if (details.name == pluginId) {
+        if (details.id == pluginId) {
             pluginIndex = installedPlugins_.indexOf(p, -1);
+            pluginModelId = p;
             break;
         }
     }
@@ -229,6 +231,10 @@ PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::R
     case PluginStatus::INSTALLED:
         addPlugin();
         break;
+    case PluginStatus::FAILED:
+        errorOccurred(pluginId);
+        status = PluginStatus::UPDATABLE;
+        break;
     default:
         break;
     }
@@ -236,7 +242,8 @@ PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::R
     if (pluginIndex == -1) {
         return;
     }
-    pluginStatus_[pluginId] = status;
+    pluginStatus_[pluginModelId] = status;
+    pluginChanged(pluginIndex);
     switch (status) {
     case PluginStatus::INSTALLABLE:
         removePlugin(pluginIndex);
diff --git a/src/app/pluginlistmodel.h b/src/app/pluginlistmodel.h
index 8bf2a0776..ff41cad17 100644
--- a/src/app/pluginlistmodel.h
+++ b/src/app/pluginlistmodel.h
@@ -72,6 +72,8 @@ Q_SIGNALS:
     void setVersionStatus(const QString& pluginId, PluginStatus::Role status);
     void autoUpdateChanged(bool state);
     void disabled(const QString& pluginId);
+    void errorOccurred(const QString& pluginId);
+
 public Q_SLOTS:
     void onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status);
     void onNewVersionAvailable(const QString& pluginId, const QString& version);
diff --git a/src/app/pluginversionmanager.cpp b/src/app/pluginversionmanager.cpp
index a08518fc3..1e4e5a9f4 100644
--- a/src/app/pluginversionmanager.cpp
+++ b/src/app/pluginversionmanager.cpp
@@ -21,6 +21,8 @@
 #include "lrcinstance.h"
 #include "api/pluginmodel.h"
 
+#include <QJsonArray>
+#include <QJsonDocument>
 #include <QMap>
 #include <QTimer>
 #include <QDir>
@@ -101,21 +103,20 @@ public:
             Q_EMIT parent_.versionStatusChanged(plugin.id, PluginStatus::Role::FAILED);
             return;
         }
-
-        parent_.sendGetRequest(QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString()
-                                    + "/versions/" + plugin.id + "?arch="
-                                    + lrcInstance_->pluginModel().getPlatformInfo()["os"]),
-                               [this, plugin](const QByteArray& data) {
-                                   // `data` represents the version in this case.
-                                   if (plugin.version < data) {
-                                       if (isAutoUpdaterEnabled()) {
-                                           installRemotePlugin(plugin.id);
-                                           return;
-                                       }
-                                   }
-                                   parent_.versionStatusChanged(plugin.id,
-                                                                PluginStatus::Role::UPDATABLE);
-                               });
+        parent_.sendGetRequest(
+            QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString() + "/versions/"
+                 + plugin.id + "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"]),
+            [this, plugin](const QByteArray& data) {
+                // `data` represents the version in this case.
+                auto result = QJsonDocument::fromJson(data).array().toVariantList()[0].toMap();
+                if (parent_.checkVersion(plugin.version, result["version"].toString())) {
+                    if (isAutoUpdaterEnabled()) {
+                        installRemotePlugin(plugin.id);
+                        return;
+                    }
+                    parent_.versionStatusChanged(plugin.id, PluginStatus::Role::UPDATABLE);
+                }
+            });
     }
 
     void installRemotePlugin(const QString& pluginId)
@@ -222,3 +223,22 @@ PluginVersionManager::installRemotePlugin(const QString& pluginId)
 {
     pimpl_->installRemotePlugin(pluginId);
 }
+
+bool
+PluginVersionManager::checkVersion(const QString& installedVersion,
+                                   const QString& remoteVersion) const
+{
+    auto installedVersionDetails = installedVersion.split(".");
+    auto remoteVersionDetails = remoteVersion.split(".");
+    if (remoteVersionDetails.size() != installedVersionDetails.size()) {
+        return false;
+    }
+    for (int i = 0; i < installedVersionDetails.size(); i++) {
+        if (installedVersionDetails[i].toInt() < remoteVersionDetails[i].toInt()) {
+            return true;
+        } else if (installedVersionDetails[i].toInt() > remoteVersionDetails[i].toInt()) {
+            return false;
+        }
+    }
+    return false;
+}
\ No newline at end of file
diff --git a/src/app/pluginversionmanager.h b/src/app/pluginversionmanager.h
index 9aff2feaf..34a406dc6 100644
--- a/src/app/pluginversionmanager.h
+++ b/src/app/pluginversionmanager.h
@@ -69,6 +69,7 @@ Q_SIGNALS:
     void newVersionAvailable(const QString& pluginId, const QString& version);
 
 private:
+    bool checkVersion(const QString& installedVersion, const QString& remoteVersion) const;
     QString baseUrl;
     bool autoUpdateCheck = false;
     QMap<QString, int> pluginRepliesId {};
diff --git a/src/app/settingsview/components/PluginItemDelegate.qml b/src/app/settingsview/components/PluginItemDelegate.qml
index 139a225cd..f8eaae835 100644
--- a/src/app/settingsview/components/PluginItemDelegate.qml
+++ b/src/app/settingsview/components/PluginItemDelegate.qml
@@ -27,24 +27,43 @@ import "../../commoncomponents"
 ItemDelegate {
     id: root
     property string pluginName: ""
-    property string pluginId: ""
+    property string pluginPath: ""
     property string pluginIcon: ""
+    property string pluginId: ""
     property int pluginStatus
     property bool isLoaded: false
     height: implicitHeight
     Connections {
         target: PluginListModel
         function onDisabled(id) {
-            if (root.pluginId === id) {
+            if (root.pluginPath === id) {
                 isLoaded = false;
                 loadSwitch.checked = false;
             }
         }
+        function onErrorOccurred(id) {
+            if (root.pluginId !== id) {
+                return;
+            }
+            presentErrorMessage();
+        }
     }
-
     onClicked: {
         pluginListView.currentIndex = index;
     }
+    Component.onCompleted: {
+        PluginAdapter.checkVersionStatus(pluginPath);
+    }
+
+    function presentErrorMessage() {
+        viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
+                "title": JamiStrings.installationFailed,
+                "infoText": JamiStrings.pluginInstallationFailed,
+                "buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue],
+                "buttonTitles": [JamiStrings.optionOk],
+                "buttonCallBacks": []
+            });
+    }
 
     Rectangle {
         id: mask
@@ -121,6 +140,7 @@ ItemDelegate {
                 preferredWidth: updateTextSize.width
                 text: JamiStrings.updateDialogTitle
                 fontSize: 15
+                onClicked: PluginAdapter.installRemotePlugin(pluginId)
             }
             Item {
                 id: itemSwitch
@@ -140,9 +160,9 @@ ItemDelegate {
                     checked: isLoaded
                     onSwitchToggled: {
                         if (isLoaded)
-                            PluginModel.unloadPlugin(pluginId);
+                            PluginModel.unloadPlugin(pluginPath);
                         else
-                            PluginModel.loadPlugin(pluginId);
+                            PluginModel.loadPlugin(pluginPath);
                         PluginListModel.pluginChanged(index);
                     }
                 }
diff --git a/src/app/settingsview/components/PluginListView.qml b/src/app/settingsview/components/PluginListView.qml
index 5c337960a..93540dc3f 100644
--- a/src/app/settingsview/components/PluginListView.qml
+++ b/src/app/settingsview/components/PluginListView.qml
@@ -109,10 +109,11 @@ Rectangle {
                     implicitHeight: 50
 
                     pluginName: PluginName
-                    pluginId: PluginId
+                    pluginPath: PluginId
                     pluginIcon: PluginIcon
                     pluginStatus: Status
                     isLoaded: IsLoaded
+                    pluginId: Id
                     HoverHandler {
                         id: pluginHover
                         target: parent
-- 
GitLab