diff --git a/resources/icons/plugins_default_icon.svg b/resources/icons/plugins_default_icon.svg index cf331309b01781bc9d2f21895c79318f37b2de34..9bd21e8867502fceb1d5ac9f0c2faae3454c933a 100644 --- a/resources/icons/plugins_default_icon.svg +++ b/resources/icons/plugins_default_icon.svg @@ -8,28 +8,34 @@ .st2{fill:url(#SVGID_3_);} .st3{fill:url(#SVGID_4_);} </style> -<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-12.6549" y1="165.4979" x2="165.4206" y2="343.5734"> - <stop offset="0" style="stop-color:#3A3A3A"/> - <stop offset="1" style="stop-color:#818181"/> +<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-12.625" y1="262.475" x2="165.425" y2="84.425" gradientTransform="matrix(1 0 0 -1 0 428)"> + <stop offset="0" style="stop-color:#7E7E7E"/> + <stop offset="1" style="stop-color:#E9FFFF"/> </linearGradient> -<path class="st0" d="M1.6,154v21.5v1.4c0.2,0,0.4,0,0.6,0c21.8,0,39.5,17.7,39.5,39.5c0,21.8-17.7,39.5-39.5,39.5 - c-0.2,0-0.4,0-0.6,0V408H101V152c0.2,0.1,0.3,0.1,0.5,0.2V51.4L1.6,154z"/> -<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="227.3426" y1="84.8295" x2="405.4313" y2="262.9182"> - <stop offset="0" style="stop-color:#3A3A3A"/> - <stop offset="1" style="stop-color:#717171"/> +<path class="st0" d="M1.6,154v21.5v1.4c0.2,0,0.4,0,0.6,0c21.8,0,39.5,17.7,39.5,39.5S24,255.9,2.2,255.9c-0.2,0-0.4,0-0.6,0V408 + H101V152c0.2,0.1,0.3,0.1,0.5,0.2V51.4L1.6,154z"/> +<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="227.375" y1="343.175" x2="405.475" y2="165.075" gradientTransform="matrix(1 0 0 -1 0 428)"> + <stop offset="0" style="stop-color:#999999"/> + <stop offset="0.3476" style="stop-color:#9B9B9B"/> + <stop offset="0.525" style="stop-color:#A1A3A3"/> + <stop offset="0.6639" style="stop-color:#ABB0B0"/> + <stop offset="0.7828" style="stop-color:#BAC3C3"/> + <stop offset="0.8889" style="stop-color:#CDDCDC"/> + <stop offset="0.9845" style="stop-color:#E5F9F9"/> + <stop offset="1" style="stop-color:#E9FFFF"/> </linearGradient> -<path class="st1" d="M386.9,176.8L386.9,176.8l0-157.8h-93.7v256c-0.1-0.1-0.3-0.1-0.4-0.2v100.8l94.2-96.7v-23.2h0 +<path class="st1" d="M386.9,176.8L386.9,176.8V19h-93.7v256c-0.1-0.1-0.3-0.1-0.4-0.2v100.8l94.2-96.7v-23.2l0,0 c21.8,0,39.5-17.7,39.5-39.5C426.4,194.5,408.7,176.8,386.9,176.8z"/> -<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1.6097" y1="86.4966" x2="395.2845" y2="86.4966"> - <stop offset="0" style="stop-color:#818181"/> - <stop offset="1" style="stop-color:#3A3A3A"/> +<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1.6" y1="341.5" x2="395.2748" y2="341.5" gradientTransform="matrix(1 0 0 -1 0 428)"> + <stop offset="0" style="stop-color:#999999"/> + <stop offset="0.9889" style="stop-color:#E9FFFF"/> </linearGradient> <path class="st2" d="M181.3,19C126.4,19,1.6,31.5,1.6,154c0,0,49.3-42.7,136.9-25s160.9-0.7,207.6-49.1 c18.6-19.3,32.4-39.6,40.2-60.9H181.3z"/> -<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-553.2536" y1="-1072.2665" x2="-159.5788" y2="-1072.2665" gradientTransform="matrix(-1 0 0 -1 -166.3346 -728.8083)"> - <stop offset="0" style="stop-color:#818181"/> - <stop offset="1" style="stop-color:#3A3A3A"/> +<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="-723.2346" y1="1360.2583" x2="-329.5598" y2="1360.2583" gradientTransform="matrix(-1 0 0 1 -336.3346 -1016.8083)"> + <stop offset="0" style="stop-color:#E9FFFF"/> + <stop offset="1" style="stop-color:#999999"/> </linearGradient> -<path class="st3" d="M207.2,408c54.9,0,179.7-11.9,179.7-129.1c0,0-49.3,40.8-136.9,23.9c-87.6-16.9-160.9,0.7-207.6,47 +<path class="st3" d="M207.2,408c54.9,0,179.7-11.9,179.7-129.1c0,0-49.3,40.8-136.9,23.9s-160.9,0.7-207.6,47 C23.8,368.3,10.1,387.6,2.2,408H207.2z"/> </svg> \ No newline at end of file diff --git a/resources/images/default_plugin_background.jpg b/resources/images/default_plugin_background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e19b43022dfdb3d0d71b676ac4fcc42a96556207 Binary files /dev/null and b/resources/images/default_plugin_background.jpg differ diff --git a/src/app/commoncomponents/PreferenceItemDelegate.qml b/src/app/commoncomponents/PreferenceItemDelegate.qml index b1f2f9a397161146135528890d2bd5b6c7ff25c3..b9aa0349ffa8cebb99a2f1a3407232cb6ddfb073 100644 --- a/src/app/commoncomponents/PreferenceItemDelegate.qml +++ b/src/app/commoncomponents/PreferenceItemDelegate.qml @@ -85,7 +85,7 @@ ItemDelegate { id: prefLlabel Layout.fillWidth: true Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.leftMargin: 8 + Layout.leftMargin: 20 text: preferenceName color: JamiTheme.textColor @@ -103,7 +103,7 @@ ItemDelegate { normalColor: JamiTheme.primaryBackgroundColor Layout.alignment: Qt.AlignRight | Qt.AlingVCenter - Layout.rightMargin: 8 + Layout.rightMargin: 20 Layout.preferredWidth: preferredSize Layout.preferredHeight: preferredSize imageColor: JamiTheme.textColor @@ -119,7 +119,7 @@ ItemDelegate { visible: preferenceType === PreferenceItemListModel.SWITCH Layout.alignment: Qt.AlignRight | Qt.AlingVCenter - Layout.rightMargin: 16 + Layout.rightMargin: 20 Layout.preferredHeight: 30 Layout.preferredWidth: 30 checked: preferenceCurrentValue === "1" @@ -134,7 +134,7 @@ ItemDelegate { visible: preferenceType === PreferenceItemListModel.LIST Layout.preferredWidth: root.width / 2 - 8 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - Layout.rightMargin: 4 + Layout.rightMargin: 20 font.pointSize: JamiTheme.settingsFontSize font.kerning: true @@ -157,7 +157,7 @@ ItemDelegate { buttontextHeightMargin: JamiTheme.buttontextHeightMargin Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - Layout.rightMargin: 4 + Layout.rightMargin: 20 text: UtilsAdapter.fileName(preferenceCurrentValue) toolTipText: JamiStrings.chooseImageFile @@ -176,7 +176,7 @@ ItemDelegate { Layout.preferredWidth: root.width / 2 - 8 Layout.preferredHeight: 30 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - Layout.rightMargin: 4 + Layout.rightMargin: 20 visible: preferenceType === PreferenceItemListModel.EDITTEXT width: root.width / 2 - 8 diff --git a/src/app/commoncomponents/ResponsiveImage.qml b/src/app/commoncomponents/ResponsiveImage.qml index 4ba42732226f68a6d2035ab2e422f6431da19208..74be0ae3f7765161a4c26ca5a0906dcbf3431d85 100644 --- a/src/app/commoncomponents/ResponsiveImage.qml +++ b/src/app/commoncomponents/ResponsiveImage.qml @@ -31,7 +31,9 @@ Item { property alias source: image.source property alias status: image.status + property alias fillMode: image.fillMode property alias cache: image.cache + property alias image: image property alias mirror: image.mirror property string color: "transparent" property bool hovered: false diff --git a/src/app/constant/JamiStrings.qml b/src/app/constant/JamiStrings.qml index ad3f25cae2b273d3178576e905bc66814852e8ba..bb0245a8a293f32f605aa24bbcfb05f5dd33b5f1 100644 --- a/src/app/constant/JamiStrings.qml +++ b/src/app/constant/JamiStrings.qml @@ -427,7 +427,6 @@ Item { property string linkDescription: qsTr("This account is created and stored locally, if you want to use it on another device you have to link the new device to this account.") property string linkAnotherDevice: qsTr("Link device") - // NameRegistrationDialog property string setUsername: qsTr("Set username") property string registeringName: qsTr("Registering name") @@ -625,9 +624,13 @@ Item { property string editPreference: qsTr("Edit preference") property string onOff: qsTr("On/Off") property string choosePlugin: qsTr("Choose Plugin") - + property string versionPlugin: qsTr("Version %1") + property string lastUpdate: qsTr("Last update %1") + property string by: qsTr("By %1") + property string proposedBy: qsTr("Proposed by %1") // ProfilePage property string information: qsTr("Information") + property string moreInformation: qsTr("More information") property string profile: qsTr("Profile") // RevokeDevicePasswordDialog diff --git a/src/app/constant/JamiTheme.qml b/src/app/constant/JamiTheme.qml index e4fe70b1573b48be2da73b2afef7db6834dc36f9..d963a50b709d29dab96cbd1e2477904a26744603 100644 --- a/src/app/constant/JamiTheme.qml +++ b/src/app/constant/JamiTheme.qml @@ -58,10 +58,12 @@ Item { property color blackColor: "#000000" property color redColor: "red" property color whiteColor: "#ffffff" + property color darkBlueGreen: "#123F4A" property color darkGreyColor: "#272727" + property color darkGreyColorOpacityFade: "#cc000000" // 80% property color darkGreyColorOpacity: "#be272727" // 77% property color tintedBlue: darkTheme ? lightTintedBlue : darkTintedBlue - property color lightTintedBlue:"#03B9E9" + property color lightTintedBlue: "#03B9E9" property color darkTintedBlue: "#005699" property color sysColor: "#F0EFEF" @@ -386,8 +388,12 @@ Item { property real pluginHandlersPopupViewHeight: 200 property real pluginHandlersPopupViewDelegateHeight: 50 property color pluginDefaultBackgroundColor: "#666666" - property real remotePluginWidthDelegate: 350 - property real remotePluginHeightDelegate: 400 + property real remotePluginMinimumDelegateWidth: 430 + property real remotePluginMinimumDelegateHeight: 260 + property real remotePluginMaximumDelegateWidth: 645 + property real remotePluginMaximumDelegateHeight: 390 + property real remotePluginDelegateWidth: remotePluginMinimumDelegateWidth * baseZoom + property real remotePluginDelegateHeight: remotePluginMinimumDelegateHeight * baseZoom property color pluginViewBackgroundColor: darkTheme ? "#000000" : "#F0EFEF" property real secondaryDialogDimension: 500 diff --git a/src/app/mainview/components/CachedImage.qml b/src/app/mainview/components/CachedImage.qml index 4d770c0b5280a52f6ea3fba244d3240e417b7368..618277b165a8477a990f0b726ba6184c954e11c7 100644 --- a/src/app/mainview/components/CachedImage.qml +++ b/src/app/mainview/components/CachedImage.qml @@ -29,9 +29,11 @@ Item { property alias source: image.source property string defaultImage: "" property string downloadUrl: "" + property alias imageLayer: image.layer property string fileExtension: downloadUrl.substring(downloadUrl.lastIndexOf("."), downloadUrl.length) property string localPath: "" property int imageFillMode: 0 + property alias image: image AnimatedImage { id: image diff --git a/src/app/mainview/components/CallActionBar.qml b/src/app/mainview/components/CallActionBar.qml index b64632bc52eecc601e6be8586b1e9c114d50c66d..c4c28dc1b783cacffb36c6682caf20462900aa78 100644 --- a/src/app/mainview/components/CallActionBar.qml +++ b/src/app/mainview/components/CallActionBar.qml @@ -420,7 +420,7 @@ Control { icon.source: JamiResources.plugins_24dp_svg icon.color: "white" text: JamiStrings.viewPlugin - enabled: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount + enabled: PluginAdapter.callMediaHandlersListCount onEnabledChanged: CallOverlayModel.setEnabled(this, pluginsAction.enabled) }, Action { diff --git a/src/app/mainview/components/ChatViewHeader.qml b/src/app/mainview/components/ChatViewHeader.qml index dbf46c8c09f8f745b6fb62525e935a0e059cef13..648aab36da1befb2b0cd78bbb2241586a3b9cb1f 100644 --- a/src/app/mainview/components/ChatViewHeader.qml +++ b/src/app/mainview/components/ChatViewHeader.qml @@ -221,7 +221,7 @@ Rectangle { JamiPushButton { id: selectPluginButton - visible: PluginAdapter.isEnabled && PluginAdapter.chatHandlersListCount && interactionButtonsVisibility + visible: PluginAdapter.chatHandlersListCount && interactionButtonsVisibility source: JamiResources.plugins_24dp_svg toolTipText: JamiStrings.showPlugins diff --git a/src/app/mainview/components/PluginHandlerPicker.qml b/src/app/mainview/components/PluginHandlerPicker.qml index 064017925df812a47c4d5bb7e123115116818c4e..7d1b5b69ae728a6e276b58cc3ed4f57dd4b53737 100644 --- a/src/app/mainview/components/PluginHandlerPicker.qml +++ b/src/app/mainview/components/PluginHandlerPicker.qml @@ -131,7 +131,6 @@ Popup { delegate: PluginHandlerItemDelegate { id: pluginHandlerItemDelegate - visible: PluginModel.getPluginsEnabled() width: pluginhandlerPickerListView.width height: JamiTheme.pluginHandlersPopupViewDelegateHeight diff --git a/src/app/pluginadapter.cpp b/src/app/pluginadapter.cpp index bbf5ee606521df792d1c75294a8d291a1417353a..50f615e6ddeaf517d744b20b399d928363cf1b3b 100644 --- a/src/app/pluginadapter.cpp +++ b/src/app/pluginadapter.cpp @@ -44,13 +44,11 @@ PluginAdapter::PluginAdapter(LRCInstance* instance, QObject* parent, QString bas { QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, pluginStoreListModel_, "PluginStoreListModel"); QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, pluginListModel_, "PluginListModel") - set_isEnabled(lrcInstance_->pluginModel().getPluginsEnabled()); updateHandlersListCount(); connect(&lrcInstance_->pluginModel(), &lrc::api::PluginModel::modelUpdated, this, &PluginAdapter::updateHandlersListCount); - connect(this, &PluginAdapter::isEnabledChanged, this, &PluginAdapter::updateHandlersListCount); connect(pluginVersionManager_, &PluginVersionManager::versionStatusChanged, pluginListModel_, @@ -75,6 +73,10 @@ PluginAdapter::PluginAdapter(LRCInstance* instance, QObject* parent, QString bas &PluginListModel::setVersionStatus, pluginStoreListModel_, &PluginStoreListModel::onVersionStatusChanged); + connect(pluginVersionManager_, + &PluginVersionManager::newVersionAvailable, + pluginListModel_, + &PluginListModel::onNewVersionAvailable); getPluginsFromStore(); } @@ -177,13 +179,8 @@ PluginAdapter::getPluginPreferencesCategories(const QString& pluginId, void PluginAdapter::updateHandlersListCount() { - if (isEnabled_) { - set_callMediaHandlersListCount(lrcInstance_->pluginModel().getCallMediaHandlers().size()); - set_chatHandlersListCount(lrcInstance_->pluginModel().getChatHandlers().size()); - } else { - set_callMediaHandlersListCount(0); - set_chatHandlersListCount(0); - } + set_callMediaHandlersListCount(lrcInstance_->pluginModel().getCallMediaHandlers().size()); + set_chatHandlersListCount(lrcInstance_->pluginModel().getChatHandlers().size()); } void @@ -203,3 +200,9 @@ PluginAdapter::getIconUrl(const QString& pluginId) const { return baseUrl_ + "/icons/" + pluginId + "?arch=" + Utils::getPlatformString(); } + +QString +PluginAdapter::getBackgroundImageUrl(const QString& pluginId) const +{ + return baseUrl_ + "/backgrounds/" + pluginId + "?arch=" + Utils::getPlatformString(); +} diff --git a/src/app/pluginadapter.h b/src/app/pluginadapter.h index f168726f677efbaf36a493058ca64cf6435aa4d4..c7039d2eea032cb4ee2d0a3d5f496cd762d2ace7 100644 --- a/src/app/pluginadapter.h +++ b/src/app/pluginadapter.h @@ -38,7 +38,6 @@ class PluginAdapter final : public QmlAdapterBase Q_OBJECT QML_PROPERTY(int, callMediaHandlersListCount) QML_PROPERTY(int, chatHandlersListCount) - QML_PROPERTY(bool, isEnabled) public: explicit PluginAdapter(LRCInstance* instance, @@ -55,6 +54,7 @@ public: Q_INVOKABLE void cancelDownload(const QString& pluginId); Q_INVOKABLE void setAutoUpdate(bool state); Q_INVOKABLE QString getIconUrl(const QString& pluginId) const; + Q_INVOKABLE QString getBackgroundImageUrl(const QString& pluginId) const; protected: Q_INVOKABLE QVariant getMediaHandlerSelectableModel(const QString& callId); diff --git a/src/app/pluginlistmodel.cpp b/src/app/pluginlistmodel.cpp index 670ee5c8c204702591328b5efa5bba71d8375e72..74e2f9d6aa9fd83a2d29b9f5c2867c1acc195f36 100644 --- a/src/app/pluginlistmodel.cpp +++ b/src/app/pluginlistmodel.cpp @@ -62,16 +62,24 @@ PluginListModel::data(const QModelIndex& index, int role) const switch (role) { case Role::PluginName: return QVariant(details.name); + case Role::PluginVersion: + return QVariant(details.version); case Role::PluginDescription: return QVariant(details.description); case Role::PluginId: return QVariant(installedPlugins_.at(index.row())); case Role::PluginIcon: return QVariant(details.iconPath); + case Role::PluginImage: + return QVariant(details.imagePath); case Role::IsLoaded: return QVariant(details.loaded); + case Role::PluginAuthor: + return QVariant(details.author); case Role::Status: return QVariant(pluginStatus_.value(installedPlugins_.at(index.row()))); + case Role::NewPluginAvailable: + return QVariant(newVersionAvailable_.value(installedPlugins_.at(index.row()))); } return QVariant(); } @@ -83,9 +91,13 @@ PluginListModel::roleNames() const roles[PluginName] = "PluginName"; roles[PluginId] = "PluginId"; roles[PluginIcon] = "PluginIcon"; + roles[PluginImage] = "PluginImage"; + roles[PluginVersion] = "PluginVersion"; + roles[PluginAuthor] = "PluginAuthor"; roles[IsLoaded] = "IsLoaded"; roles[Status] = "Status"; roles[PluginDescription] = "PluginDescription"; + roles[NewPluginAvailable] = "NewPluginAvailable"; return roles; } @@ -164,6 +176,41 @@ PluginListModel::filterPlugins(VectorString& list) const list.cend()); } +void +PluginListModel::onNewVersionAvailable(const QString& pluginId, const QString& version) +{ + // check if pluginId exists in installedPlugins_ + auto pluginIndex = -1; + for (auto& p : installedPlugins_) { + auto details = lrcInstance_->pluginModel().getPluginDetails(p); + if (details.name == pluginId) { + pluginIndex = installedPlugins_.indexOf(p, -1); + break; + } + } + if (pluginIndex == -1) { + return; + } + newVersionAvailable_[pluginId] = version; + pluginChanged(pluginIndex); +} + +void +PluginListModel::deleteLatestVersion(const QString& pluginId) +{ + auto pluginIndex = -1; + for (auto& p : installedPlugins_) { + auto details = lrcInstance_->pluginModel().getPluginDetails(p); + if (details.name == pluginId) { + pluginIndex = installedPlugins_.indexOf(p, -1); + break; + } + } + if (pluginIndex == -1) { + return; + } + newVersionAvailable_.remove(pluginId); +} void PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status) { diff --git a/src/app/pluginlistmodel.h b/src/app/pluginlistmodel.h index 84dd1c01013548a910b1cb64baf58bd6b9304279..9605b3004342b2f738542a4b0e6172c2d355b490 100644 --- a/src/app/pluginlistmodel.h +++ b/src/app/pluginlistmodel.h @@ -32,7 +32,11 @@ public: PluginName = Qt::UserRole + 1, PluginDescription, PluginId, + PluginVersion, + PluginAuthor, + PluginImage, PluginIcon, + NewPluginAvailable, IsLoaded, Status }; @@ -60,6 +64,7 @@ public: Q_INVOKABLE void pluginChanged(int index); Q_INVOKABLE void addPlugin(); Q_INVOKABLE void disableAllPlugins(); + Q_INVOKABLE void deleteLatestVersion(const QString& pluginId); Q_SIGNALS: void versionCheckRequested(const QString& pluginId); @@ -68,10 +73,12 @@ Q_SIGNALS: void disabled(const QString& pluginId); public Q_SLOTS: void onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status); + void onNewVersionAvailable(const QString& pluginId, const QString& version); private: LRCInstance* lrcInstance_ = nullptr; void filterPlugins(VectorString& list) const; VectorString installedPlugins_ {}; QMap<QString, PluginStatus::Role> pluginStatus_ {}; + QMap<QString, QString> newVersionAvailable_ {}; }; diff --git a/src/app/pluginversionmanager.h b/src/app/pluginversionmanager.h index a56a2a079eb47062d419b4387ed8346c4614536f..cf03b0b8525e4d74c4a2a900a7a4a5700cb90795 100644 --- a/src/app/pluginversionmanager.h +++ b/src/app/pluginversionmanager.h @@ -68,6 +68,7 @@ public Q_SLOTS: Q_SIGNALS: void versionStatusChanged(const QString& pluginId, PluginStatus::Role status); + void newVersionAvailable(const QString& pluginId, const QString& version); private: QString baseUrl; diff --git a/src/app/settingsview/components/PluginAvailableDelagate.qml b/src/app/settingsview/components/PluginAvailableDelegate.qml similarity index 70% rename from src/app/settingsview/components/PluginAvailableDelagate.qml rename to src/app/settingsview/components/PluginAvailableDelegate.qml index 7907315bfe7436513502ecbcc5a063de119f3c6e..709c8db4cbcd2363a1bc93cffbea9afc113ee4e7 100644 --- a/src/app/settingsview/components/PluginAvailableDelagate.qml +++ b/src/app/settingsview/components/PluginAvailableDelegate.qml @@ -34,6 +34,9 @@ ItemDelegate { property string pluginAuthor property string pluginShortDescription property int pluginStatus + property string backgroundLocalPath: UtilsAdapter.getCachePath() + '/backgrounds/' + pluginName + '.jpg' + property string iconLocalPath: UtilsAdapter.getCachePath() + '/icons/' + pluginName + '.svg' + readonly property real scalingFactor: 1 + hovered * 0.02 property string installButtonStatus: { switch (pluginStatus) { case PluginStatus.DOWNLOADING: @@ -52,8 +55,6 @@ ItemDelegate { } } - background: null - function presentErrorMessage() { viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", { "title": JamiStrings.installationFailed, @@ -69,9 +70,35 @@ ItemDelegate { anchors.fill: parent radius: 5 } + + background: null + Page { id: plugin anchors.fill: parent + background: CachedImage { + id: background + defaultImage: JamiResources.default_plugin_background_jpg + downloadUrl: PluginAdapter.getBackgroundImageUrl(pluginName) + anchors.fill: parent + localPath: root.localPath === undefined ? '' : root.localPath + imageFillMode: Image.PreserveAspectCrop + LinearGradient { + id: gradient + anchors.fill: parent + start: Qt.point(0, height / 3) + gradient: Gradient { + GradientStop { + position: 0.0 + color: JamiTheme.transparentColor + } + GradientStop { + position: 1.0 + color: JamiTheme.darkGreyColorOpacityFade + } + } + } + } layer { enabled: true effect: OpacityMask { @@ -81,12 +108,8 @@ ItemDelegate { header: Control { leftPadding: 20 rightPadding: 5 - bottomPadding: 20 topPadding: 5 - background: Rectangle { - id: headerBackground - color: hovered ? Qt.lighter(pluginBackground, 1.9) : Qt.lighter(pluginBackground, 2) - } + bottomPadding: 20 contentItem: ColumnLayout { SpinningAnimation { id: buttonContainer @@ -96,7 +119,7 @@ ItemDelegate { Layout.topMargin: 2 Layout.preferredHeight: install.height Layout.preferredWidth: install.width - color: "black" + color: JamiTheme.whiteColor outerCutRadius: install.radius spinningAnimationDuration: 5000 mode: { @@ -109,9 +132,10 @@ ItemDelegate { MaterialButton { id: install + hoverEnabled: pluginStatus !== PluginStatus.INSTALLING - secHoveredColor: Qt.darker(headerBackground.color, 1.1) buttontextHeightMargin: 10.0 + secHoveredColor: JamiTheme.darkBlueGreen radius: JamiTheme.chatViewHeaderButtonRadius TextMetrics { id: installTextSize @@ -120,7 +144,7 @@ ItemDelegate { font.capitalization: Font.Medium text: install.text } - contentColorProvider: "black" + contentColorProvider: JamiTheme.whiteColor onClicked: installPlugin() secondary: true preferredWidth: installTextSize.width + JamiTheme.buttontextWizzardPadding @@ -139,56 +163,24 @@ ItemDelegate { } } RowLayout { - spacing: 10 + Layout.alignment: Qt.AlignCenter CachedImage { id: icon defaultImage: JamiResources.plugins_default_icon_svg - onSourceChanged: { - if (source == defaultImage) { - pluginBackground = JamiTheme.pluginDefaultBackgroundColor; - return; - } - pluginBackground = PluginStoreListModel.computeAverageColorOfImage(source); - } - width: 55 - height: 55 + width: 65 + height: 65 downloadUrl: PluginAdapter.getIconUrl(pluginName) - fileExtension: '.svg' - localPath: UtilsAdapter.getCachePath() + '/plugins/' + pluginName + '.svg' - } - ColumnLayout { - width: parent.width - Label { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - text: pluginName - font.kerning: true - color: "black" - font.pointSize: JamiTheme.tinyCreditsTextSize - textFormat: Text.PlainText - wrapMode: Text.WrapAnywhere - } - // Label { - // Layout.fillWidth: true - // color: "black" - // text: pluginShortDescription - // font.pointSize: JamiTheme.settingsFontSize - // textFormat: Text.PlainText - // wrapMode: Text.WordWrap - // } + localPath: root.iconLocalPath } } } } - Rectangle { - id: contentContainer - anchors.fill: parent - color: hovered ? JamiTheme.smartListHoveredColor : JamiTheme.pluginViewBackgroundColor - } JamiFlickable { anchors.fill: parent - anchors.margins: 20 - contentHeight: description.height + anchors.rightMargin: 20 + anchors.leftMargin: 20 + anchors.bottomMargin: 5 + contentHeight: body.height clip: true flickableDirection: Flickable.VerticalFlick ScrollBar.vertical: JamiScrollBar { @@ -197,12 +189,24 @@ ItemDelegate { } ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ColumnLayout { + id: body width: parent.width + Label { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + text: pluginName + font.kerning: true + font.bold: true + color: JamiTheme.whiteColor + font.pixelSize: hovered ? JamiTheme.popuptextSize * scalingFactor : JamiTheme.popuptextSize + textFormat: Text.PlainText + wrapMode: Text.WrapAnywhere + } Text { id: description - Layout.preferredWidth: contentContainer.width - font.pixelSize: JamiTheme.popuptextSize - color: JamiTheme.textColor + Layout.fillWidth: true + font.pixelSize: hovered ? JamiTheme.popuptextSize * scalingFactor : JamiTheme.popuptextSize + color: JamiTheme.whiteColor text: pluginDescription wrapMode: Text.WordWrap horizontalAlignment: Qt.AlignLeft @@ -213,21 +217,19 @@ ItemDelegate { } } footer: Control { - padding: 20 - background: Rectangle { - color: hovered ? JamiTheme.smartListHoveredColor : JamiTheme.pluginViewBackgroundColor - } + leftPadding: 20 + bottomPadding: 20 + rightPadding: 20 contentItem: Text { Layout.fillWidth: true Layout.preferredHeight: implicitHeight - Layout.topMargin: 8 Layout.leftMargin: 8 - color: JamiTheme.textColor + color: JamiTheme.whiteColor - font.pointSize: JamiTheme.settingsFontSize + font.pixelSize: hovered ? JamiTheme.settingsFontSize * scalingFactor : JamiTheme.settingsFontSize font.kerning: true font.italic: true - text: "By " + pluginAuthor + text: JamiStrings.by.arg(pluginAuthor) wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter } diff --git a/src/app/settingsview/components/PluginListView.qml b/src/app/settingsview/components/PluginListView.qml index 0818654303a4706aecc92ad15332cd183b7c4e94..5c337960ad0668865c38a513a72ddeecbbfd588a 100644 --- a/src/app/settingsview/components/PluginListView.qml +++ b/src/app/settingsview/components/PluginListView.qml @@ -32,13 +32,13 @@ Rectangle { if (pluginLoader.item !== undefined) { return -1; } else { - if (pluginListView.currentIndex === null) { + if (pluginListView.currentIndex === 0) { return -1; } return pluginListView.currentIndex; } } - visible: PluginAdapter.isEnabled && count + visible: count color: JamiTheme.secondaryBackgroundColor ColumnLayout { @@ -48,7 +48,6 @@ Rectangle { RowLayout { Layout.preferredHeight: JamiTheme.settingsHeaderpreferredHeight Layout.fillWidth: true - Layout.bottomMargin: 20 Layout.alignment: Qt.AlignRight Label { Layout.fillWidth: true @@ -58,7 +57,7 @@ Rectangle { color: JamiTheme.textColor horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter + verticalAlignment: Text.AlignBottom } HeaderToggleSwitch { labelText: "auto update" diff --git a/src/app/settingsview/components/PluginPreferencesListView.qml b/src/app/settingsview/components/PluginPreferencesListView.qml index 456a08895177101e3ac4abb9f1c678f746a72b39..b47bc3ef19d8c1efc212226334e24606e871dd56 100644 --- a/src/app/settingsview/components/PluginPreferencesListView.qml +++ b/src/app/settingsview/components/PluginPreferencesListView.qml @@ -27,6 +27,7 @@ Rectangle { id: root property string accountId: "" required property string pluginId + required property bool isLoaded width: parent.width property int count: pluginPreferenceView.count + pluginPreferenceViewCategory.count @@ -274,7 +275,7 @@ Rectangle { onClicked: viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", { "title": JamiStrings.resetPreferences, - "infoText": JamiStrings.pluginResetConfirmation.arg(pluginName), + "infoText": JamiStrings.pluginResetConfirmation.arg(pluginId), "buttonTitles": [JamiStrings.optionOk, JamiStrings.optionCancel], "buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlack], "buttonCallBacks": [function () { diff --git a/src/app/settingsview/components/PluginPreferencesView.qml b/src/app/settingsview/components/PluginPreferencesView.qml index 82bf989c508ea53eaa67bb4ee4980f5e4c32815c..35b185b502c725a6f9c78a7b85567fc9c5b6bc00 100644 --- a/src/app/settingsview/components/PluginPreferencesView.qml +++ b/src/app/settingsview/components/PluginPreferencesView.qml @@ -18,11 +18,13 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import net.jami.Adapters 1.1 +import Qt5Compat.GraphicalEffects import SortFilterProxyModel 0.2 import net.jami.Models 1.1 +import net.jami.Adapters 1.1 import net.jami.Constants 1.1 import "../../commoncomponents" +import "../../mainview/components" Item { id: root @@ -49,21 +51,47 @@ Item { color: JamiTheme.pluginViewBackgroundColor } header: Control { - padding: 10 - background: Rectangle { - color: JamiTheme.pluginViewBackgroundColor + id: preferenceHeader + width: root.width + background: ResponsiveImage { + id: background + anchors.fill: preferenceHeader + fillMode: Image.PreserveAspectCrop + source: PluginImage === "" ? JamiResources.default_plugin_background_jpg : "file:" + PluginImage + FastBlur { + anchors.fill: parent + source: background.image + radius: 64 + } + LinearGradient { + id: gradient + anchors.fill: parent + start: Qt.point(0, height / 3) + gradient: Gradient { + GradientStop { + position: 0.0 + color: JamiTheme.transparentColor + } + GradientStop { + position: 1.0 + color: JamiTheme.darkGreyColorOpacityFade + } + } + } } contentItem: ColumnLayout { width: parent.width - PushButton { + JamiPushButton { id: closeButton - normalColor: "transparent" - hoveredColor: JamiTheme.smartListHoveredColor + normalColor: Qt.rgba(124, 124, 124, 0.36) + hoveredColor: Qt.rgba(124, 124, 124, 0.75) Layout.alignment: Qt.AlignRight + Layout.topMargin: 10 + Layout.rightMargin: 35 Layout.preferredWidth: JamiTheme.preferredFieldHeight Layout.preferredHeight: childrenRect.height - imageColor: JamiTheme.textColor + imageColor: JamiTheme.blackColor toolTipText: JamiStrings.closeSettings preferredSize: 32 @@ -73,54 +101,36 @@ Item { } } - RowLayout { - Layout.preferredWidth: parent.width - ResponsiveImage { - Layout.bottomMargin: 10 - Layout.rightMargin: 10 - containerWidth: 64 - containerHeight: 64 - source: PluginIcon === "" ? JamiResources.plugins_default_icon_svg : "file:" + PluginIcon - } - Label { - text: PluginName - font.pixelSize: JamiTheme.settingsTitlePixelSize - font.kerning: true - color: JamiTheme.textColor - textFormat: Text.PlainText - } + ResponsiveImage { + Layout.bottomMargin: 10 + Layout.rightMargin: 10 + Layout.alignment: Qt.AlignCenter + containerWidth: 100 + containerHeight: 100 + source: PluginIcon === "" ? JamiResources.plugins_default_icon_svg : "file:" + PluginIcon + } - Item { - Layout.fillHeight: true - Layout.fillWidth: true - MaterialButton { - id: update - anchors.right: parent.right - buttontextHeightMargin: 0.0 - TextMetrics { - id: updateTextSize - font.weight: Font.Bold - font.pixelSize: JamiTheme.wizardViewButtonFontPixelSize - font.capitalization: Font.AllUppercase - text: JamiStrings.updateDialogTitle - } - visible: Status === PluginStatus.UPDATABLE - secondary: true - preferredWidth: updateTextSize.width - text: JamiStrings.updateDialogTitle - fontSize: 15 - } - } + Label { + Layout.leftMargin: 20 + text: PluginName + font.pixelSize: JamiTheme.settingsDescriptionPixelSize + font.kerning: true + font.bold: true + color: JamiTheme.whiteColor + textFormat: Text.PlainText } JamiFlickable { - Layout.fillWidth: true + Layout.leftMargin: 20 + Layout.bottomMargin: 20 + Layout.preferredWidth: root.width Layout.preferredHeight: childrenRect.height Layout.minimumHeight: childrenRect.height Layout.maximumHeight: 88 contentWidth: description.width contentHeight: description.height clip: true + boundsBehavior: Flickable.StopAtBounds flickableDirection: Flickable.VerticalFlick ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.vertical: ScrollBar { @@ -129,12 +139,12 @@ Item { } Text { id: description - width: settings.width - 2 * scrollBar.width + width: settings.width - (2 * scrollBar.width + 20) text: PluginDescription font.pixelSize: JamiTheme.popuptextSize - color: JamiTheme.textColor + color: JamiTheme.whiteColor wrapMode: Text.WordWrap - textFormat: Text.PlainText + textFormat: Text.MarkdownText } } } @@ -145,26 +155,121 @@ Item { } JamiFlickable { anchors.fill: parent + width: root.width contentHeight: contentItem.childrenRect.height - topMargin: JamiTheme.preferredSettingsBottomMarginSize + topMargin: 20 bottomMargin: JamiTheme.preferredSettingsBottomMarginSize + boundsBehavior: Flickable.StopAtBounds ScrollBar.horizontal.visible: false contentItem.children: ColumnLayout { width: root.width - PluginPreferencesListView { - id: pluginGeneralSettingsView - Layout.fillWidth: true - pluginId: PluginId + ColumnLayout { + width: parent.width + Label { + Layout.leftMargin: 20 + Layout.fillWidth: true + text: JamiStrings.settings + font.pixelSize: JamiTheme.settingsDescriptionPixelSize + font.bold: true + font.kerning: true + color: JamiTheme.textColor + } + PluginPreferencesListView { + id: pluginGeneralSettingsView + Layout.fillWidth: true + pluginId: PluginId + isLoaded: IsLoaded + } + PluginPreferencesListView { + id: pluginAccountSettingsView + Layout.fillWidth: true + accountId: LRCInstance.currentAccountId + pluginId: PluginId + isLoaded: IsLoaded + } } - PluginPreferencesListView { - id: pluginAccountSettingsView - Layout.fillWidth: true - accountId: LRCInstance.currentAccountId - pluginId: PluginId + Rectangle { + width: parent.width + height: childrenRect.height + 40 + Layout.topMargin: 20 + color: JamiTheme.pluginViewBackgroundColor + ColumnLayout { + width: parent.width + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: 20 + anchors.bottomMargin: 20 + anchors.leftMargin: 20 + Label { + Layout.fillWidth: true + text: JamiStrings.moreInformation + font.pixelSize: JamiTheme.settingsDescriptionPixelSize + font.bold: true + font.kerning: true + color: JamiTheme.textColor + } + Label { + Layout.fillWidth: true + text: JamiStrings.versionPlugin.arg(PluginVersion) + font.pixelSize: JamiTheme.headerFontSize + font.kerning: true + color: JamiTheme.textColor + } + Item { + width: parent.width + height: childrenRect.height + visible: Status === PluginStatus.UPDATABLE + Label { + width: parent.width + text: JamiStrings.lastUpdate.arg(NewPluginAvailable) + font.pixelSize: JamiTheme.headerFontSize + font.kerning: true + color: JamiTheme.textColor + } + Item { + width: parent.width + height: childrenRect.height + anchors.right: parent.right + anchors.rightMargin: 40 + MaterialButton { + id: update + anchors.right: parent.right + buttontextHeightMargin: 0.0 + TextMetrics { + id: updateTextSize + font.weight: Font.Bold + font.pixelSize: JamiTheme.wizardViewButtonFontPixelSize + font.capitalization: Font.AllUppercase + text: JamiStrings.updateDialogTitle + } + + secondary: true + preferredWidth: updateTextSize.width + text: JamiStrings.updateDialogTitle + fontSize: 15 + onClicked: { + PluginModel.deleteLatestVersion(PluginName); + PluginAdapter.installRemotePlugin(PluginName); + } + } + } + } + Label { + visible: PluginAuthor !== '' + Layout.fillWidth: true + color: JamiTheme.textColor + font.pointSize: JamiTheme.settingsFontSize + font.kerning: true + font.italic: true + text: JamiStrings.proposedBy.arg(PluginAuthor) + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + } + } } MaterialButton { id: uninstallButton - + Layout.topMargin: 20 Layout.alignment: Qt.AlignCenter preferredWidth: JamiTheme.preferredFieldWidth diff --git a/src/app/settingsview/components/PluginSettingsPage.qml b/src/app/settingsview/components/PluginSettingsPage.qml index e9afdc7d1477284e42509153d66087bc49367020..79f94d78fb94f2ed0ede772e0cbcd9417cd686bf 100644 --- a/src/app/settingsview/components/PluginSettingsPage.qml +++ b/src/app/settingsview/components/PluginSettingsPage.qml @@ -33,7 +33,28 @@ SettingsPageBase { anchors.leftMargin: JamiTheme.preferredSettingsMarginSize ColumnLayout { id: generalSettings - Layout.maximumWidth: 3 * (JamiTheme.remotePluginWidthDelegate + 20) + Layout.maximumWidth: { + let width = 0; + if (JamiTheme.remotePluginDelegateWidth < JamiTheme.remotePluginMinimumDelegateWidth) { + width = 3 * (JamiTheme.remotePluginMinimumDelegateWidth + 20); + } else if (JamiTheme.remotePluginDelegateWidth > JamiTheme.remotePluginMaximumDelegateWidth) { + width = 3 * (JamiTheme.remotePluginMaximumDelegateWidth + 20); + } else { + width = 3 * (JamiTheme.remotePluginDelegateWidth + 20); + } + return pluginRemoteList.remotePluginHovered ? width + 10 : width; + } + Layout.minimumWidth: { + let width = 0; + if (JamiTheme.remotePluginDelegateWidth < JamiTheme.remotePluginMinimumDelegateWidth) { + width = JamiTheme.remotePluginMinimumDelegateWidth + 10; + } else if (JamiTheme.remotePluginDelegateWidth > JamiTheme.remotePluginMaximumDelegateWidth) { + width = JamiTheme.remotePluginMaximumDelegateWidth + 10; + } else { + width = JamiTheme.remotePluginDelegateWidth + 10; + } + return pluginRemoteList.remotePluginHovered ? width + 10 : width; + } Layout.preferredWidth: parent.width Layout.rightMargin: 80 spacing: JamiTheme.settingsBlockSpacing @@ -52,6 +73,7 @@ SettingsPageBase { } // View of available plugins in the store PluginStoreListView { + id: pluginRemoteList Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter Layout.fillWidth: true } diff --git a/src/app/settingsview/components/PluginStoreListView.qml b/src/app/settingsview/components/PluginStoreListView.qml index 2a32087fc6ab47db5979d653047b2a33c17784aa..17b385ece7d9d163f5d1d511e988cb1fa2dd25e2 100644 --- a/src/app/settingsview/components/PluginStoreListView.qml +++ b/src/app/settingsview/components/PluginStoreListView.qml @@ -25,7 +25,9 @@ import net.jami.Constants 1.1 import "../../commoncomponents" ColumnLayout { + id: root property bool storeAvailable: true + property bool remotePluginHovered: false Component.onCompleted: { PluginAdapter.getPluginsFromStore(); } @@ -53,20 +55,44 @@ ColumnLayout { sourceComponent: Flow { id: pluginStoreList height: childrenRect.height - spacing: 20 + spacing: 10 Repeater { model: PluginStoreListModel - - delegate: PluginAvailableDelagate { - id: pluginItemDelegate - width: JamiTheme.remotePluginWidthDelegate - height: JamiTheme.remotePluginHeightDelegate - pluginName: Name - pluginIcon: IconPath - pluginDescription: Description - pluginAuthor: Author - pluginShortDescription: "" - pluginStatus: Status + onCountChanged: { + root.visible = count > 0 + } + delegate: Item { + id: wrapper + function widthProvider() { + if (JamiTheme.remotePluginDelegateWidth < JamiTheme.remotePluginMinimumDelegateWidth) { + return JamiTheme.remotePluginMinimumDelegateWidth; + } else if (JamiTheme.remotePluginDelegateWidth > JamiTheme.remotePluginMaximumDelegateWidth) { + return JamiTheme.remotePluginMaximumDelegateWidth; + } + return JamiTheme.remotePluginDelegateWidth; + } + function heightProvider() { + if (JamiTheme.remotePluginDelegateHeight < JamiTheme.remotePluginMinimumDelegateHeight) { + return JamiTheme.remotePluginMinimumDelegateHeight; + } else if (JamiTheme.remotePluginDelegateHeight > JamiTheme.remotePluginMaximumDelegateHeight) { + return JamiTheme.remotePluginMaximumDelegateHeight; + } + return JamiTheme.remotePluginDelegateHeight; + } + width: widthProvider() + 10 + height: heightProvider() + 6 + PluginAvailableDelegate { + id: pluginItemDelegate + anchors.centerIn: parent + width: wrapper.widthProvider() * scalingFactor + height: wrapper.heightProvider() * scalingFactor + pluginName: Name + pluginIcon: IconPath + pluginDescription: Description + pluginAuthor: Author + pluginShortDescription: "" + pluginStatus: Status + } } } } diff --git a/src/libclient/api/pluginmodel.h b/src/libclient/api/pluginmodel.h index ad2234fef035e203a263858e7f82f00fec42bff1..d2176c5732ea7cc8e9106b5218fc08dead1f4a33 100644 --- a/src/libclient/api/pluginmodel.h +++ b/src/libclient/api/pluginmodel.h @@ -43,7 +43,9 @@ struct PluginDetails QString description = ""; QString path = ""; QString version = ""; + QString author = ""; QString iconPath = ""; + QString imagePath = ""; bool loaded = false; }; @@ -63,18 +65,6 @@ public: PluginModel(); ~PluginModel(); - /** - * Enable/disable plugins - * @param if plugin enabled - */ - Q_INVOKABLE void setPluginsEnabled(bool enable); - - /** - * Get if plugins are enabled - * @return plugins enabled - */ - Q_INVOKABLE bool getPluginsEnabled() const; - /** * Get list of installed plugins * @return plugins installed diff --git a/src/libclient/pluginmodel.cpp b/src/libclient/pluginmodel.cpp index 7c3232a0e333d1ea0968b633f2febf0f26473712..6175a83ec3258aea15eb9bb920e2b0dc7deb6509 100644 --- a/src/libclient/pluginmodel.cpp +++ b/src/libclient/pluginmodel.cpp @@ -67,24 +67,6 @@ PluginModel::PluginModel() PluginModel::~PluginModel() {} -void -PluginModel::setPluginsEnabled(bool enable) -{ - PluginManager::instance().setPluginsEnabled(enable); - if (!enable) - Q_EMIT chatHandlerStatusUpdated(false); - else - Q_EMIT chatHandlerStatusUpdated(getChatHandlers().size() > 0); - - Q_EMIT modelUpdated(); -} - -bool -PluginModel::getPluginsEnabled() const -{ - return PluginManager::instance().getPluginsEnabled(); -} - VectorString PluginModel::getInstalledPlugins() const { @@ -111,6 +93,8 @@ PluginModel::getPluginDetails(const QString& path) result.description = details["description"]; result.path = path; result.iconPath = details["iconPath"]; + result.imagePath = details["imagePath"]; + result.author = details["author"]; result.version = details["version"]; } if (!pluginsPath_.contains(result.id)) { @@ -127,32 +111,29 @@ PluginModel::getPluginDetails(const QString& path) bool PluginModel::installPlugin(const QString& jplPath, bool force) { - if (getPluginsEnabled()) { - auto result = PluginManager::instance().installPlugin(jplPath, force); - Q_EMIT modelUpdated(); - if (result != 0) { - switch (result) { - case PluginInstallStatus::PLUGIN_ALREADY_INSTALLED: - qWarning() << "Plugin already installed"; - break; - case PluginInstallStatus::PLUGIN_OLD_VERSION: - qWarning() << "Plugin already installed with a newer version"; - break; - case PluginInstallStatus::SIGNATURE_VERIFICATION_FAILED: - qWarning() << "Signature verification failed"; - break; - case PluginInstallStatus::CERTIFICATE_VERIFICATION_FAILED: - qWarning() << "Certificate verification failed"; - break; - case PluginInstallStatus::INVALID_PLUGIN: - qWarning() << "Invalid plugin"; - break; - } + auto result = PluginManager::instance().installPlugin(jplPath, force); + Q_EMIT modelUpdated(); + if (result != 0) { + switch (result) { + case PluginInstallStatus::PLUGIN_ALREADY_INSTALLED: + qWarning() << "Plugin already installed"; + break; + case PluginInstallStatus::PLUGIN_OLD_VERSION: + qWarning() << "Plugin already installed with a newer version"; + break; + case PluginInstallStatus::SIGNATURE_VERIFICATION_FAILED: + qWarning() << "Signature verification failed"; + break; + case PluginInstallStatus::CERTIFICATE_VERIFICATION_FAILED: + qWarning() << "Certificate verification failed"; + break; + case PluginInstallStatus::INVALID_PLUGIN: + qWarning() << "Invalid plugin"; + break; } - pluginsPath_[getPluginDetails(jplPath).id] = jplPath; - return result == 0; } - return false; + pluginsPath_[getPluginDetails(jplPath).id] = jplPath; + return result == 0; } bool @@ -196,7 +177,7 @@ PluginModel::loadPlugin(const QString& path) bool status = PluginManager::instance().loadPlugin(path); Q_EMIT modelUpdated(); if (getChatHandlers().size() > 0) - Q_EMIT chatHandlerStatusUpdated(getPluginsEnabled()); + Q_EMIT chatHandlerStatusUpdated(true); return status; } diff --git a/tests/qml/src/tst_CachedImage.qml b/tests/qml/src/tst_CachedImage.qml index af04a7dac75be0bf4138e82537030c7ceddb4515..ac0087d762830cf294a79047aab467506f2b987a 100644 --- a/tests/qml/src/tst_CachedImage.qml +++ b/tests/qml/src/tst_CachedImage.qml @@ -64,7 +64,6 @@ Item { spyDownloadSuccessful.wait() compare(findChild(cachedImage,"image").source, Qt.url("file://"+localPath), "image source") - compare(findChild(cachedImage,"default_img").visible,false, "default_img visible") } @@ -78,8 +77,7 @@ Item { spyDownloadFailed.wait() - compare(findChild(cachedImage,"image").source,"", "image source") - compare(findChild(cachedImage,"image").visible,true, "default_img visible") + compare(findChild(cachedImage,"image").source,cachedImage.defaultImage, "image source") } } }