diff --git a/CMakeLists.txt b/CMakeLists.txt
index 245f39ab89d3891bbb529a565b81bc46b1192a6d..8f12eeb4ab2c88c8655c14d279cfa07446792cbf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -111,8 +111,8 @@ set(COMMON_SOURCES
     ${SRC_DIR}/contactadapter.cpp
     ${SRC_DIR}/pluginadapter.cpp
     ${SRC_DIR}/deviceitemlistmodel.cpp
-    ${SRC_DIR}/pluginitemlistmodel.cpp
-    ${SRC_DIR}/pluginhandleritemlistmodel.cpp
+    ${SRC_DIR}/pluginlistmodel.cpp
+    ${SRC_DIR}/pluginhandlerlistmodel.cpp
     ${SRC_DIR}/preferenceitemlistmodel.cpp
     ${SRC_DIR}/mediacodeclistmodel.cpp
     ${SRC_DIR}/currentaccounttomigrate.cpp
@@ -165,8 +165,8 @@ set(COMMON_HEADERS
     ${SRC_DIR}/contactadapter.h
     ${SRC_DIR}/pluginadapter.h
     ${SRC_DIR}/deviceitemlistmodel.h
-    ${SRC_DIR}/pluginitemlistmodel.h
-    ${SRC_DIR}/pluginhandleritemlistmodel.h
+    ${SRC_DIR}/pluginlistmodel.h
+    ${SRC_DIR}/pluginhandlerlistmodel.h
     ${SRC_DIR}/preferenceitemlistmodel.h
     ${SRC_DIR}/mediacodeclistmodel.h
     ${SRC_DIR}/currentaccounttomigrate.h
diff --git a/src/commoncomponents/PreferenceItemDelegate.qml b/src/commoncomponents/PreferenceItemDelegate.qml
index 6f4c7e8eb5bdacf24e4f02154b2eba6c643c8e7e..e3ad6b38384e04078153fce6ba8ca2da89448c5a 100644
--- a/src/commoncomponents/PreferenceItemDelegate.qml
+++ b/src/commoncomponents/PreferenceItemDelegate.qml
@@ -30,14 +30,6 @@ import "../settingsview/components"
 ItemDelegate {
     id: root
 
-    enum Type {
-        LIST,
-        PATH,
-        EDITTEXT,
-        SWITCH,
-        DEFAULT
-    }
-
     property string preferenceName: ""
     property string preferenceSummary: ""
     property string preferenceKey: ""
@@ -54,12 +46,12 @@ ItemDelegate {
 
     function getNewPreferenceValueSlot(index) {
         switch (preferenceType) {
-            case PreferenceItemDelegate.LIST:
+            case PreferenceItemListModel.LIST:
                 pluginListPreferenceModel.idx = index
                 preferenceNewValue = pluginListPreferenceModel.preferenceNewValue
                 btnPreferenceClicked()
                 break
-            case PreferenceItemDelegate.PATH:
+            case PreferenceItemListModel.PATH:
                 if (index === 0) {
                     preferenceFilePathDialog.title = qsTr("Select An Image to " + preferenceName)
                     preferenceFilePathDialog.nameFilters = fileFilters
@@ -69,11 +61,11 @@ ItemDelegate {
                 else
                     btnPreferenceClicked()
                 break
-            case PreferenceItemDelegate.EDITTEXT:
+            case PreferenceItemListModel.EDITTEXT:
                 preferenceNewValue = editTextPreference.text
                 btnPreferenceClicked()
                 break
-            case PreferenceItemDelegate.SWITCH:
+            case PreferenceItemListModel.SWITCH:
                 preferenceNewValue = index ? "1" : "0"
                 btnPreferenceClicked()
                 break
@@ -116,7 +108,7 @@ ItemDelegate {
         PushButton {
             id: btnPreferenceDefault
 
-            visible: preferenceType === PreferenceItemDelegate.DEFAULT
+            visible: preferenceType === PreferenceItemListModel.DEFAULT
             normalColor: JamiTheme.primaryBackgroundColor
 
             Layout.alignment: Qt.AlignRight | Qt.AlingVCenter
@@ -134,7 +126,7 @@ ItemDelegate {
         ToggleSwitch {
             id: btnPreferenceSwitch
 
-            visible: preferenceType === PreferenceItemDelegate.SWITCH
+            visible: preferenceType === PreferenceItemListModel.SWITCH
             Layout.alignment: Qt.AlignRight | Qt.AlingVCenter
             Layout.rightMargin: 16
             Layout.preferredHeight: 30
@@ -148,7 +140,7 @@ ItemDelegate {
         SettingParaCombobox {
             id: listPreferenceComboBox
 
-            visible: preferenceType === PreferenceItemDelegate.LIST
+            visible: preferenceType === PreferenceItemListModel.LIST
             Layout.preferredWidth: root.width / 2 - 8
             Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
             Layout.rightMargin: 4
@@ -168,7 +160,7 @@ ItemDelegate {
         MaterialButton {
             id: pathPreferenceButton
 
-            visible: preferenceType === PreferenceItemDelegate.PATH
+            visible: preferenceType === PreferenceItemListModel.PATH
 
             preferredWidth: root.width / 2 - 8
             preferredHeight: 30
@@ -195,7 +187,7 @@ ItemDelegate {
             Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
             Layout.rightMargin: 4
 
-            visible: preferenceType === PreferenceItemDelegate.EDITTEXT
+            visible: preferenceType === PreferenceItemListModel.EDITTEXT
             width: root.width / 2 - 8
             padding: 8
 
diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml
index de2f5f83b363734be36815cecece0074ac71b0cb..832e170f8558fd1b435b523ad1ea61f1d78bbceb 100644
--- a/src/constant/JamiStrings.qml
+++ b/src/constant/JamiStrings.qml
@@ -493,9 +493,15 @@ Item {
     property string enable: qsTr("Enable")
 
     // PluginListPreferencesView
+    property string pluginPreferences: qsTr("%1\nPreferences")
     property string reset: qsTr("Reset")
+    property string uninstall: qsTr("Uninstall")
+    property string resetPreferences: qsTr("Reset Preferences")
     property string selectPluginInstall: qsTr("Select a plugin to install")
     property string installPlugin: qsTr("Install plugin")
+    property string uninstallPlugin: qsTr("Uninstall plugin")
+    property string pluginResetConfirmation: qsTr("Are you sure you wish to reset %1 preferences?")
+    property string pluginUninstallConfirmation: qsTr("Are you sure you wish to uninstall %1?")
 
     // PluginItemDelegate
     property string showHidePrefs: qsTr("Display or hide preferences")
diff --git a/src/mainview/components/CallActionBar.qml b/src/mainview/components/CallActionBar.qml
index 26704e1c4a0cb940ab97414a7bee7f8ab47a202d..9f062447921345f419871b546d2fa3b41fe8044e 100644
--- a/src/mainview/components/CallActionBar.qml
+++ b/src/mainview/components/CallActionBar.qml
@@ -313,7 +313,7 @@ Control {
             icon.source: JamiResources.plugins_24dp_svg
             icon.color: "white"
             text: JamiStrings.viewPlugin
-            enabled: PluginAdapter.callMediaHandlersListCount
+            enabled: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
         }
     ]
 
diff --git a/src/mainview/components/CallViewContextMenu.qml b/src/mainview/components/CallViewContextMenu.qml
index 355fe9b8a7472a306432574e2a7e8c8dc2dda0a2..b9555dffd8d30449ad1266b2115173ff9851dea8 100644
--- a/src/mainview/components/CallViewContextMenu.qml
+++ b/src/mainview/components/CallViewContextMenu.qml
@@ -179,7 +179,7 @@ ContextMenuAutoLoader {
         GeneralMenuItem {
             id: viewPlugin
 
-            canTrigger: PluginAdapter.callMediaHandlersListCount
+            canTrigger: PluginAdapter.isEnabled && PluginAdapter.callMediaHandlersListCount
             itemName: JamiStrings.viewPlugin
             iconSource: JamiResources.extension_24dp_svg
             onClicked: {
diff --git a/src/mainview/components/ChatViewHeader.qml b/src/mainview/components/ChatViewHeader.qml
index 8f150f711a3231914fff6475db2e0fccdf72c1a3..3ad3baacab595e37c20902f7694a439996bea285 100644
--- a/src/mainview/components/ChatViewHeader.qml
+++ b/src/mainview/components/ChatViewHeader.qml
@@ -194,7 +194,7 @@ Rectangle {
             PushButton {
                 id: selectPluginButton
 
-                visible: PluginAdapter.chatHandlersListCount &&
+                visible: PluginAdapter.isEnabled && PluginAdapter.chatHandlersListCount &&
                          interactionButtonsVisibility
 
                 source: JamiResources.plugins_24dp_svg
diff --git a/src/mainview/components/PluginHandlerPicker.qml b/src/mainview/components/PluginHandlerPicker.qml
index 1f6769caf46f7de93c4197c4337de95065a0c2b3..39f5d944fb3e337a38b916361e86b7d258079254 100644
--- a/src/mainview/components/PluginHandlerPicker.qml
+++ b/src/mainview/components/PluginHandlerPicker.qml
@@ -32,7 +32,6 @@ Popup {
     property bool isCall
     property string pluginId: ""
     property string handlerName: ""
-    signal updateProperties
 
     width: JamiTheme.preferredDialogWidth
     height: JamiTheme.pluginHandlersPopupViewHeight + JamiTheme.pluginHandlersPopupViewDelegateHeight
@@ -57,29 +56,23 @@ Popup {
                 target: root
 
                 function onAboutToShow(visible) {
+                    // Reset the model on each show.
                     if (isCall) {
-                        // Reset the model on each show.
-                        var callId = UtilsAdapter.getCallId(callStackView.responsibleAccountId,
-                                                            callStackView.responsibleConvUid)
-                        pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(callId)
+                        pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
                     } else {
-                        // Reset the model on each show.
-                        var accountId = LRCInstance.currentAccountId
-                        var peerId = UtilsAdapter.getPeerUri(accountId, LRCInstance.selectedConvUid)
-                        pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(accountId, peerId)
+                        var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
+                        pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
                     }
                 }
             }
 
             function toggleHandlerSlot(handlerId, isLoaded) {
                 if (isCall) {
-                    var callId = UtilsAdapter.getCallId(callStackView.responsibleAccountId,
-                                                        callStackView.responsibleConvUid)
-                    PluginModel.toggleCallMediaHandler(handlerId, callId, !isLoaded)
-                    pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(callId)
+                    PluginModel.toggleCallMediaHandler(handlerId, CurrentConversation.callId, !isLoaded)
+                    pluginhandlerPickerListView.model = PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
                 } else {
                     var accountId = LRCInstance.currentAccountId
-                    var peerId = UtilsAdapter.getPeerUri(accountId, LRCInstance.selectedConvUid)
+                    var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
                     PluginModel.toggleChatHandler(handlerId, accountId, peerId, !isLoaded)
                     pluginhandlerPickerListView.model = PluginAdapter.getChatHandlerSelectableModel(accountId, peerId)
                 }
@@ -132,13 +125,10 @@ Popup {
 
                     model: {
                         if (isCall) {
-                            var callId = UtilsAdapter.getCallId(callStackView.responsibleAccountId,
-                                                                callStackView.responsibleConvUid)
-                            return PluginAdapter.getMediaHandlerSelectableModel(callId)
+                            return PluginAdapter.getMediaHandlerSelectableModel(CurrentConversation.callId)
                         } else {
-                            var accountId = LRCInstance.currentAccountId
-                            var peerId = UtilsAdapter.getPeerUri(accountId, LRCInstance.selectedConvUid)
-                            return PluginAdapter.getChatHandlerSelectableModel(accountId, peerId)
+                            var peerId = CurrentConversation.isSwarm ? CurrentConversation.id : CurrentConversation.uris[0]
+                            return PluginAdapter.getChatHandlerSelectableModel(LRCInstance.currentAccountId, peerId)
                         }
                     }
 
@@ -159,10 +149,9 @@ Popup {
                         }
 
                         onOpenPreferences: {
-                            root.pluginId = pluginId
                             root.handlerName = handlerName
+                            root.pluginId = pluginId
                             stack.push(pluginhandlerPreferenceStack2, StackView.Immediate)
-                            updateProperties()
                         }
                     }
                 }
@@ -178,16 +167,6 @@ Popup {
             radius: 10
             anchors.fill: parent
 
-            Connections {
-                target: root
-
-                function onUpdateProperties() {
-                    pluginhandlerPreferencePickerListView.pluginId = root.pluginId
-                    pluginhandlerPreferencePickerListView.handlerName = root.handlerName
-                    pluginhandlerPreferencePickerListView.model = PluginAdapter.getHandlerPreferencesModel(root.pluginId, root.handlerName)
-                }
-            }
-
             ColumnLayout {
                 anchors.fill: parent
                 anchors.bottomMargin: 5
@@ -244,10 +223,12 @@ Popup {
                     Layout.fillWidth: true
                     Layout.fillHeight: true
 
-                    property string pluginId: ""
-                    property string handlerName: ""
-
-                    model: PluginAdapter.getHandlerPreferencesModel(pluginId, handlerName)
+                    model: PreferenceItemListModel {
+                        id: handlerPickerPrefsModel
+                        lrcInstance: LRCInstance
+                        mediaHandlerName_: handlerName
+                        pluginId_: pluginId
+                    }
 
                     delegate: PreferenceItemDelegate {
                         id: pluginHandlerPreferenceDelegate
@@ -275,9 +256,8 @@ Popup {
                         onClicked:  pluginhandlerPreferencePickerListView.currentIndex = index
 
                         onBtnPreferenceClicked: {
-                            PluginModel.setPluginPreference(pluginId, preferenceKey, preferenceNewValue)
-                            PluginAdapter.preferenceChanged(pluginId)
-                            pluginhandlerPreferencePickerListView.model = PluginAdapter.getHandlerPreferencesModel(pluginId, pluginhandlerPreferencePickerListView.handlerName)
+                            PluginModel.setPluginPreference(pluginId, "", preferenceKey, preferenceNewValue)
+                            handlerPickerPrefsModel.reset()
                         }
                     }
                 }
diff --git a/src/pluginadapter.cpp b/src/pluginadapter.cpp
index a55375dc88c56d2b47feb7397e4a395345b284ec..4d34dadcca797913770a4a0c281881889ae7955b 100644
--- a/src/pluginadapter.cpp
+++ b/src/pluginadapter.cpp
@@ -23,56 +23,30 @@
 PluginAdapter::PluginAdapter(LRCInstance* instance, QObject* parent)
     : QmlAdapterBase(instance, parent)
 {
+    set_isEnabled(lrcInstance_->pluginModel().getPluginsEnabled());
     updateHandlersListCount();
     connect(&lrcInstance_->pluginModel(),
             &lrc::api::PluginModel::modelUpdated,
             this,
             &PluginAdapter::updateHandlersListCount);
+    connect(this, &PluginAdapter::isEnabledChanged, this, &PluginAdapter::updateHandlersListCount);
 }
 
 QVariant
 PluginAdapter::getMediaHandlerSelectableModel(const QString& callId)
 {
     pluginHandlerListModel_.reset(
-        new PluginHandlerItemListModel(this, callId, QString(""), lrcInstance_));
+        new PluginHandlerListModel(this, callId, QString(""), lrcInstance_));
     return QVariant::fromValue(pluginHandlerListModel_.get());
 }
 
 QVariant
 PluginAdapter::getChatHandlerSelectableModel(const QString& accountId, const QString& peerId)
 {
-    pluginHandlerListModel_.reset(
-        new PluginHandlerItemListModel(this, accountId, peerId, lrcInstance_));
+    pluginHandlerListModel_.reset(new PluginHandlerListModel(this, accountId, peerId, lrcInstance_));
     return QVariant::fromValue(pluginHandlerListModel_.get());
 }
 
-QVariant
-PluginAdapter::getPluginSelectableModel()
-{
-    pluginItemListModel_.reset(new PluginItemListModel(this, lrcInstance_));
-    return QVariant::fromValue(pluginItemListModel_.get());
-}
-
-QVariant
-PluginAdapter::getPluginPreferencesModel(const QString& pluginId, const QString& category)
-{
-    preferenceItemListModel_.reset(new PreferenceItemListModel(this, lrcInstance_));
-    preferenceItemListModel_->setCategory(category);
-    preferenceItemListModel_->setPluginId(pluginId);
-
-    return QVariant::fromValue(preferenceItemListModel_.get());
-}
-
-QVariant
-PluginAdapter::getHandlerPreferencesModel(const QString& pluginId, const QString& mediaHandlerName)
-{
-    preferenceItemListModel_.reset(new PreferenceItemListModel(this, lrcInstance_));
-    preferenceItemListModel_->setMediaHandlerName(mediaHandlerName);
-    preferenceItemListModel_->setPluginId(pluginId);
-
-    return QVariant::fromValue(preferenceItemListModel_.get());
-}
-
 QVariant
 PluginAdapter::getPluginPreferencesCategories(const QString& pluginId, bool removeLast)
 {
diff --git a/src/pluginadapter.h b/src/pluginadapter.h
index 86e7bba0a486a169326a1e538aeea147b6d0a63a..a1a5c7cbdc1a43a82b08deb42d4a85c3390b87ea 100644
--- a/src/pluginadapter.h
+++ b/src/pluginadapter.h
@@ -19,8 +19,8 @@
 #pragma once
 
 #include "qmladapterbase.h"
-#include "pluginitemlistmodel.h"
-#include "pluginhandleritemlistmodel.h"
+#include "pluginlistmodel.h"
+#include "pluginhandlerlistmodel.h"
 #include "pluginlistpreferencemodel.h"
 #include "preferenceitemlistmodel.h"
 
@@ -33,6 +33,7 @@ class PluginAdapter final : public QmlAdapterBase
     Q_OBJECT
     QML_PROPERTY(int, callMediaHandlersListCount)
     QML_PROPERTY(int, chatHandlersListCount)
+    QML_PROPERTY(bool, isEnabled)
 
 public:
     explicit PluginAdapter(LRCInstance* instance, QObject* parent = nullptr);
@@ -44,23 +45,13 @@ protected:
     Q_INVOKABLE QVariant getMediaHandlerSelectableModel(const QString& callId);
     Q_INVOKABLE QVariant getChatHandlerSelectableModel(const QString& accountId,
                                                        const QString& peerId);
-    Q_INVOKABLE QVariant getPluginSelectableModel();
-    Q_INVOKABLE QVariant getPluginPreferencesModel(const QString& pluginId,
-                                                   const QString& category = "all");
-    Q_INVOKABLE QVariant getHandlerPreferencesModel(const QString& pluginId,
-                                                    const QString& mediaHandlerName = "");
     Q_INVOKABLE QVariant getPluginPreferencesCategories(const QString& pluginId,
                                                         bool removeLast = false);
 
-Q_SIGNALS:
-    void pluginHandlersUpdateStatus();
-    void preferenceChanged(QString pluginId);
-    void pluginUninstalled();
-
 private:
     void updateHandlersListCount();
 
-    std::unique_ptr<PluginHandlerItemListModel> pluginHandlerListModel_;
-    std::unique_ptr<PreferenceItemListModel> preferenceItemListModel_;
-    std::unique_ptr<PluginItemListModel> pluginItemListModel_;
+    std::unique_ptr<PluginHandlerListModel> pluginHandlerListModel_;
+
+    std::mutex mtx_;
 };
diff --git a/src/pluginhandleritemlistmodel.cpp b/src/pluginhandlerlistmodel.cpp
similarity index 66%
rename from src/pluginhandleritemlistmodel.cpp
rename to src/pluginhandlerlistmodel.cpp
index 16d1f431348bcc75c2d4878542cf0fa2d0d31c97..4bed82fb3555812888c407ff89a6d3fbbfc4709a 100644
--- a/src/pluginhandleritemlistmodel.cpp
+++ b/src/pluginhandlerlistmodel.cpp
@@ -16,34 +16,34 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "pluginhandleritemlistmodel.h"
+#include "pluginhandlerlistmodel.h"
 
 #include "lrcinstance.h"
 
 #include "api/pluginmodel.h"
 
-PluginHandlerItemListModel::PluginHandlerItemListModel(QObject* parent,
-                                                       const QString& accountId,
-                                                       const QString& peerId,
-                                                       LRCInstance* instance)
+PluginHandlerListModel::PluginHandlerListModel(QObject* parent,
+                                               const QString& accountId,
+                                               const QString& peerId,
+                                               LRCInstance* instance)
     : AbstractListModelBase(parent)
 {
     lrcInstance_ = instance;
 
     if (!peerId.isEmpty()) {
-        accountId_ = accountId;
-        peerId_ = peerId;
+        set_accountId(accountId);
+        set_peerId(peerId);
         isMediaHandler_ = false;
     } else {
-        callId_ = accountId;
+        set_callId(accountId);
         isMediaHandler_ = true;
     }
 }
 
-PluginHandlerItemListModel::~PluginHandlerItemListModel() {}
+PluginHandlerListModel::~PluginHandlerListModel() {}
 
 int
-PluginHandlerItemListModel::rowCount(const QModelIndex& parent) const
+PluginHandlerListModel::rowCount(const QModelIndex& parent) const
 {
     if (!parent.isValid() && lrcInstance_) {
         /*
@@ -61,7 +61,7 @@ PluginHandlerItemListModel::rowCount(const QModelIndex& parent) const
 }
 
 int
-PluginHandlerItemListModel::columnCount(const QModelIndex& parent) const
+PluginHandlerListModel::columnCount(const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
     /*
@@ -71,7 +71,7 @@ PluginHandlerItemListModel::columnCount(const QModelIndex& parent) const
 }
 
 QVariant
-PluginHandlerItemListModel::data(const QModelIndex& index, int role) const
+PluginHandlerListModel::data(const QModelIndex& index, int role) const
 {
     QString name {""};
     QString id {""};
@@ -138,7 +138,7 @@ PluginHandlerItemListModel::data(const QModelIndex& index, int role) const
 }
 
 QHash<int, QByteArray>
-PluginHandlerItemListModel::roleNames() const
+PluginHandlerListModel::roleNames() const
 {
     QHash<int, QByteArray> roles;
     roles[HandlerName] = "HandlerName";
@@ -150,76 +150,9 @@ PluginHandlerItemListModel::roleNames() const
     return roles;
 }
 
-QModelIndex
-PluginHandlerItemListModel::index(int row, int column, const QModelIndex& parent) const
-{
-    Q_UNUSED(parent);
-    if (column != 0) {
-        return QModelIndex();
-    }
-
-    if (row >= 0 && row < rowCount()) {
-        return createIndex(row, column);
-    }
-    return QModelIndex();
-}
-
-QModelIndex
-PluginHandlerItemListModel::parent(const QModelIndex& child) const
-{
-    Q_UNUSED(child);
-    return QModelIndex();
-}
-
-Qt::ItemFlags
-PluginHandlerItemListModel::flags(const QModelIndex& index) const
-{
-    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
-    if (!index.isValid()) {
-        return QAbstractItemModel::flags(index);
-    }
-    return flags;
-}
-
 void
-PluginHandlerItemListModel::reset()
+PluginHandlerListModel::reset()
 {
     beginResetModel();
     endResetModel();
 }
-
-QString
-PluginHandlerItemListModel::callId()
-{
-    return callId_;
-}
-
-void
-PluginHandlerItemListModel::setCallId(QString callId)
-{
-    callId_ = callId;
-}
-
-QString
-PluginHandlerItemListModel::accountId()
-{
-    return accountId_;
-}
-
-void
-PluginHandlerItemListModel::setAccountId(QString accountId)
-{
-    accountId_ = accountId;
-}
-
-QString
-PluginHandlerItemListModel::peerId()
-{
-    return peerId_;
-}
-
-void
-PluginHandlerItemListModel::setPeerId(QString peerId)
-{
-    peerId_ = peerId;
-}
diff --git a/src/pluginhandleritemlistmodel.h b/src/pluginhandlerlistmodel.h
similarity index 73%
rename from src/pluginhandleritemlistmodel.h
rename to src/pluginhandlerlistmodel.h
index ead992cc0f7bbbc06be0f5d41f275380fe1bb11f..808a35c009804a78c54fe8421b3cfb5fbe9fb24f 100644
--- a/src/pluginhandleritemlistmodel.h
+++ b/src/pluginhandlerlistmodel.h
@@ -22,20 +22,23 @@
 
 class LRCInstance;
 
-class PluginHandlerItemListModel : public AbstractListModelBase
+class PluginHandlerListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
+    QML_PROPERTY(QString, callId)
+    QML_PROPERTY(QString, peerId)
+    QML_PROPERTY(QString, accountId)
 public:
     enum Role { HandlerName = Qt::UserRole + 1, HandlerId, HandlerIcon, IsLoaded, PluginId };
     Q_ENUM(Role)
 
-    explicit PluginHandlerItemListModel(
+    explicit PluginHandlerListModel(
         QObject* parent = nullptr,
         const QString& accountId = QString(""),
         const QString& peerId = QString(""),
         LRCInstance* instance = nullptr); // for calls, accountId is the callId and peerId is null
-    ~PluginHandlerItemListModel();
+    ~PluginHandlerListModel();
 
     /*
      * QAbstractListModel override.
@@ -47,25 +50,12 @@ public:
      * Override role name as access point in qml.
      */
     QHash<int, QByteArray> roleNames() const override;
-    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
-    QModelIndex parent(const QModelIndex& child) const;
-    Qt::ItemFlags flags(const QModelIndex& index) const;
 
     /*
      * This function is to reset the model when there's new account added.
      */
     Q_INVOKABLE void reset();
 
-    QString callId();
-    void setCallId(QString callId);
-    QString accountId();
-    void setAccountId(QString accountId);
-    QString peerId();
-    void setPeerId(QString peerId);
-
 private:
-    QString callId_ = QString("");
-    QString accountId_ = QString("");
-    QString peerId_ = QString("");
     bool isMediaHandler_;
 };
diff --git a/src/pluginitemlistmodel.cpp b/src/pluginlistmodel.cpp
similarity index 53%
rename from src/pluginitemlistmodel.cpp
rename to src/pluginlistmodel.cpp
index c20714760682c11db004d908bf7a2557a85d9f8f..d8724c814ce1bf500625c5d092991ef2ee7b1582 100644
--- a/src/pluginitemlistmodel.cpp
+++ b/src/pluginlistmodel.cpp
@@ -16,33 +16,31 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "pluginitemlistmodel.h"
+#include "pluginlistmodel.h"
 
 #include "lrcinstance.h"
 
 #include "api/pluginmodel.h"
 
-PluginItemListModel::PluginItemListModel(QObject* parent, LRCInstance* instance)
+PluginListModel::PluginListModel(QObject* parent)
     : AbstractListModelBase(parent)
-{
-    lrcInstance_ = instance;
-}
+{}
 
-PluginItemListModel::~PluginItemListModel() {}
+PluginListModel::~PluginListModel() {}
 
 int
-PluginItemListModel::rowCount(const QModelIndex& parent) const
+PluginListModel::rowCount(const QModelIndex& parent) const
 {
     if (!parent.isValid() && lrcInstance_) {
         /// Count
-        return lrcInstance_->pluginModel().getInstalledPlugins().size();
+        return installedPlugins_.size();
     }
     /// A valid QModelIndex returns 0 as no entry has sub-elements.
     return 0;
 }
 
 int
-PluginItemListModel::columnCount(const QModelIndex& parent) const
+PluginListModel::columnCount(const QModelIndex& parent) const
 {
     Q_UNUSED(parent);
     /// Only need one column.
@@ -50,20 +48,19 @@ PluginItemListModel::columnCount(const QModelIndex& parent) const
 }
 
 QVariant
-PluginItemListModel::data(const QModelIndex& index, int role) const
+PluginListModel::data(const QModelIndex& index, int role) const
 {
-    auto pluginList = lrcInstance_->pluginModel().getInstalledPlugins();
-    if (!index.isValid() || pluginList.size() <= index.row()) {
+    if (!index.isValid() || installedPlugins_.size() <= index.row()) {
         return QVariant();
     }
 
-    auto details = lrcInstance_->pluginModel().getPluginDetails(pluginList.at(index.row()));
+    auto details = lrcInstance_->pluginModel().getPluginDetails(installedPlugins_.at(index.row()));
 
     switch (role) {
     case Role::PluginName:
         return QVariant(details.name);
     case Role::PluginId:
-        return QVariant(pluginList.at(index.row()));
+        return QVariant(installedPlugins_.at(index.row()));
     case Role::PluginIcon:
         return QVariant(details.iconPath);
     case Role::IsLoaded:
@@ -73,7 +70,7 @@ PluginItemListModel::data(const QModelIndex& index, int role) const
 }
 
 QHash<int, QByteArray>
-PluginItemListModel::roleNames() const
+PluginListModel::roleNames() const
 {
     QHash<int, QByteArray> roles;
     roles[PluginName] = "PluginName";
@@ -84,46 +81,44 @@ PluginItemListModel::roleNames() const
     return roles;
 }
 
-QModelIndex
-PluginItemListModel::index(int row, int column, const QModelIndex& parent) const
+void
+PluginListModel::reset()
 {
-    Q_UNUSED(parent);
-    if (column != 0) {
-        return QModelIndex();
-    }
-
-    if (row >= 0 && row < rowCount()) {
-        return createIndex(row, column);
-    }
-    return QModelIndex();
+    beginResetModel();
+    installedPlugins_.clear();
+    installedPlugins_ = lrcInstance_->pluginModel().getInstalledPlugins();
+    endResetModel();
 }
 
-QModelIndex
-PluginItemListModel::parent(const QModelIndex& child) const
+void
+PluginListModel::removePlugin(int index)
 {
-    Q_UNUSED(child);
-    return QModelIndex();
+    beginRemoveRows(QModelIndex(), index, index);
+    installedPlugins_.removeAt(index);
+    endRemoveRows();
 }
 
-Qt::ItemFlags
-PluginItemListModel::flags(const QModelIndex& index) const
+void
+PluginListModel::pluginChanged(int index)
 {
-    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
-    if (!index.isValid()) {
-        return QAbstractItemModel::flags(index);
-    }
-    return flags;
+    Q_EMIT dataChanged(createIndex(index, 0), createIndex(index, 0));
 }
 
 void
-PluginItemListModel::reset()
+PluginListModel::addPlugin()
 {
-    beginResetModel();
-    endResetModel();
-}
+    auto newList = lrcInstance_->pluginModel().getInstalledPlugins();
+    if (newList.size() <= installedPlugins_.size())
+        return;
+
+    int index = 0;
+    for (auto item : newList) {
+        if (installedPlugins_.indexOf(item) == -1)
+            break;
+        index++;
+    }
 
-int
-PluginItemListModel::pluginsCount()
-{
-    return lrcInstance_->pluginModel().getInstalledPlugins().size();
-}
+    beginInsertRows(QModelIndex(), index, index);
+    installedPlugins_ = lrcInstance_->pluginModel().getInstalledPlugins();
+    endInsertRows();
+}
\ No newline at end of file
diff --git a/src/pluginitemlistmodel.h b/src/pluginlistmodel.h
similarity index 76%
rename from src/pluginitemlistmodel.h
rename to src/pluginlistmodel.h
index df5b91fa351ba68356078e3a479fea8d2d40db8b..dd9412b01c565920e451ebf0892303dc673b1fc2 100644
--- a/src/pluginitemlistmodel.h
+++ b/src/pluginlistmodel.h
@@ -22,17 +22,16 @@
 
 class LRCInstance;
 
-class PluginItemListModel : public AbstractListModelBase
+class PluginListModel : public AbstractListModelBase
 {
     Q_OBJECT
-    Q_PROPERTY(int pluginsCount READ pluginsCount)
 
 public:
     enum Role { PluginName = Qt::UserRole + 1, PluginId, PluginIcon, IsLoaded };
     Q_ENUM(Role)
 
-    explicit PluginItemListModel(QObject* parent = nullptr, LRCInstance* instance = nullptr);
-    ~PluginItemListModel();
+    explicit PluginListModel(QObject* parent = nullptr);
+    ~PluginListModel();
 
     /*
      * QAbstractListModel override.
@@ -44,13 +43,15 @@ public:
      * Override role name as access point in qml.
      */
     QHash<int, QByteArray> roleNames() const override;
-    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
-    QModelIndex parent(const QModelIndex& child) const;
-    Qt::ItemFlags flags(const QModelIndex& index) const;
 
-    int pluginsCount();
     /*
      * This function is to reset the model when there's new account added.
      */
     Q_INVOKABLE void reset();
+    Q_INVOKABLE void removePlugin(int index);
+    Q_INVOKABLE void pluginChanged(int index);
+    Q_INVOKABLE void addPlugin();
+
+private:
+    VectorString installedPlugins_ {};
 };
diff --git a/src/pluginlistpreferencemodel.h b/src/pluginlistpreferencemodel.h
index 08e62135b1d03bde1db52805df327d9386c2ed80..a364b8dfde437ee5db943a5a6c26cd8fb973b5ac 100644
--- a/src/pluginlistpreferencemodel.h
+++ b/src/pluginlistpreferencemodel.h
@@ -87,7 +87,8 @@ public:
     }
     QString preferenceCurrentValue()
     {
-        return lrcInstance_->pluginModel().getPluginPreferencesValues(pluginId_)[preferenceKey_];
+        return lrcInstance_->pluginModel().getPluginPreferencesValues(pluginId_,
+                                                                      accountId_)[preferenceKey_];
     }
 
     QString preferenceNewValue()
@@ -115,4 +116,5 @@ private:
     QStringList preferenceValuesList_;
     QStringList preferenceList_;
     int idx_ = 0;
+    QString accountId_ = "";
 };
diff --git a/src/preferenceitemlistmodel.cpp b/src/preferenceitemlistmodel.cpp
index 81fe1b6f760c31119fc74147eedabd1f7da19483..2fa13a3a9d6f6ffa6400624ed8e6c578c1252a6a 100644
--- a/src/preferenceitemlistmodel.cpp
+++ b/src/preferenceitemlistmodel.cpp
@@ -31,11 +31,9 @@ std::map<QString, int> mapType {{QString("List"), PreferenceItemListModel::Type:
                                 {QString("EditText"), PreferenceItemListModel::Type::EDITTEXT},
                                 {QString("Switch"), PreferenceItemListModel::Type::SWITCH}};
 
-PreferenceItemListModel::PreferenceItemListModel(QObject* parent, LRCInstance* instance)
+PreferenceItemListModel::PreferenceItemListModel(QObject* parent)
     : AbstractListModelBase(parent)
-{
-    lrcInstance_ = instance;
-}
+{}
 
 PreferenceItemListModel::~PreferenceItemListModel() {}
 
@@ -72,8 +70,8 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
     bool checkImage = false;
 
     auto details = preferenceList_.at(index.row());
-    preferenceCurrent = lrcInstance_->pluginModel().getPluginPreferencesValues(
-        pluginId_)[details["key"]];
+    preferenceCurrent = lrcInstance_->pluginModel()
+                            .getPluginPreferencesValues(pluginId__, accountId__)[details["key"]];
     auto it = mapType.find(details["type"]);
     if (it != mapType.end()) {
         type = mapType[details["type"]];
@@ -90,8 +88,9 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
         }
     }
     const auto dependsOn = details["dependsOn"].split(",");
-    const auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
-    const auto prefValues = lrcInstance_->pluginModel().getPluginPreferencesValues(pluginId_);
+    const auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId__);
+    const auto prefValues = lrcInstance_->pluginModel().getPluginPreferencesValues(pluginId__,
+                                                                                   accountId__);
     bool enabled = true;
     for (auto& preference : preferences) {
         auto key = preference["key"];
@@ -119,7 +118,7 @@ PreferenceItemListModel::data(const QModelIndex& index, int role) const
     case Role::PreferenceType:
         return QVariant(type);
     case Role::PluginId:
-        return QVariant(pluginId_);
+        return QVariant(pluginId__);
     case Role::PreferenceCurrentValue:
         return QVariant(preferenceCurrent);
     case Role::CurrentPath:
@@ -152,79 +151,29 @@ PreferenceItemListModel::roleNames() const
     return roles;
 }
 
-QModelIndex
-PreferenceItemListModel::index(int row, int column, const QModelIndex& parent) const
-{
-    Q_UNUSED(parent);
-    if (column != 0) {
-        return QModelIndex();
-    }
-
-    if (row >= 0 && row < rowCount()) {
-        return createIndex(row, column);
-    }
-    return QModelIndex();
-}
-
-QModelIndex
-PreferenceItemListModel::parent(const QModelIndex& child) const
-{
-    Q_UNUSED(child);
-    return QModelIndex();
-}
-
-Qt::ItemFlags
-PreferenceItemListModel::flags(const QModelIndex& index) const
-{
-    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
-    if (!index.isValid()) {
-        return QAbstractItemModel::flags(index);
-    }
-    return flags;
-}
-
 void
 PreferenceItemListModel::reset()
 {
     beginResetModel();
+    preferenceList_.clear();
+    preferencesCount();
     endResetModel();
 }
 
 QString
-PreferenceItemListModel::pluginId() const
+PreferenceItemListModel::pluginId_() const
 {
-    return pluginId_;
+    return pluginId__;
 }
 
 void
 PreferenceItemListModel::setPluginId(const QString& pluginId)
 {
-    pluginId_ = pluginId;
+    beginResetModel();
+    pluginId__ = pluginId;
+    preferenceList_.clear();
     preferencesCount();
-}
-
-QString
-PreferenceItemListModel::mediaHandlerName() const
-{
-    return mediaHandlerName_;
-}
-
-void
-PreferenceItemListModel::setMediaHandlerName(const QString mediaHandlerName)
-{
-    mediaHandlerName_ = mediaHandlerName;
-}
-
-QString
-PreferenceItemListModel::category() const
-{
-    return category_;
-}
-
-void
-PreferenceItemListModel::setCategory(const QString category)
-{
-    category_ = category;
+    endResetModel();
 }
 
 int
@@ -232,21 +181,21 @@ PreferenceItemListModel::preferencesCount()
 {
     if (!preferenceList_.isEmpty())
         return preferenceList_.size();
-    if (mediaHandlerName_.isEmpty()) {
-        auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
-        if (category_ != "all")
+    if (mediaHandlerName__.isEmpty()) {
+        auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId__);
+        if (category__ != "all")
             for (auto& preference : preferences) {
-                if (preference["category"] == category_)
+                if (preference["category"] == category__)
                     preferenceList_.push_back(preference);
             }
         else
             preferenceList_ = preferences;
         return preferenceList_.size();
     } else {
-        auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId_);
+        auto preferences = lrcInstance_->pluginModel().getPluginPreferences(pluginId__);
         for (auto& preference : preferences) {
             QStringList scopeList = preference["scope"].split(",");
-            if (scopeList.contains(mediaHandlerName_))
+            if (scopeList.contains(mediaHandlerName__))
                 preferenceList_.push_back(preference);
         }
         return preferenceList_.size();
diff --git a/src/preferenceitemlistmodel.h b/src/preferenceitemlistmodel.h
index d3902f52f771c4d2ccb949e407daf2f6e35a7bc6..6be16f8bd3b3e50d35525289047b355849dd3f8f 100644
--- a/src/preferenceitemlistmodel.h
+++ b/src/preferenceitemlistmodel.h
@@ -26,9 +26,11 @@ class PreferenceItemListModel : public AbstractListModelBase
 {
     Q_OBJECT
 
-    Q_PROPERTY(QString pluginId READ pluginId WRITE setPluginId)
-    Q_PROPERTY(QString mediaHandlerName READ mediaHandlerName WRITE setMediaHandlerName)
-    Q_PROPERTY(int preferencesCount READ preferencesCount)
+    Q_PROPERTY(QString pluginId_ READ pluginId_ WRITE setPluginId)
+    QML_PROPERTY(QString, category_)
+    QML_PROPERTY(QString, mediaHandlerName_)
+    QML_PROPERTY(QString, accountId_)
+    QML_RO_PROPERTY(int, preferencesCount_)
 public:
     enum Role {
         PreferenceKey = Qt::UserRole + 1,
@@ -52,8 +54,9 @@ public:
     } Type;
 
     Q_ENUM(Role)
+    Q_ENUM(Type)
 
-    explicit PreferenceItemListModel(QObject* parent = nullptr, LRCInstance* instance = nullptr);
+    explicit PreferenceItemListModel(QObject* parent = nullptr);
     ~PreferenceItemListModel();
 
     /*
@@ -66,26 +69,18 @@ public:
      * Override role name as access point in qml.
      */
     QHash<int, QByteArray> roleNames() const override;
-    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
-    QModelIndex parent(const QModelIndex& child) const;
-    Qt::ItemFlags flags(const QModelIndex& index) const;
 
     /*
      * This function is to reset the model when there's new plugin added or modified.
      */
     Q_INVOKABLE void reset();
 
-    QString pluginId() const;
+    QString pluginId_() const;
     void setPluginId(const QString& pluginId);
-    QString mediaHandlerName() const;
-    void setMediaHandlerName(const QString mediaHandlerName);
-    QString category() const;
-    void setCategory(const QString category);
-    int preferencesCount();
 
 private:
-    QString pluginId_;
-    QString mediaHandlerName_ = "";
+    int preferencesCount();
+
+    QString pluginId__;
     VectorMapStringString preferenceList_;
-    QString category_ = "all";
 };
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index dc4ccf169bb2d8d8292b4807b62324841c159741..64b8a7571f2faa26e88764aabb5c2ba076ec645a 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -50,7 +50,9 @@
 #include "mainapplication.h"
 #include "namedirectory.h"
 #include "updatemanager.h"
+#include "pluginlistmodel.h"
 #include "pluginlistpreferencemodel.h"
+#include "preferenceitemlistmodel.h"
 #include "version.h"
 #include "wizardviewstepmodel.h"
 
@@ -154,6 +156,8 @@ registerTypes(QQmlEngine* engine,
     QML_REGISTERTYPE(NS_MODELS, MediaCodecListModel);
     QML_REGISTERTYPE(NS_MODELS, AudioDeviceModel);
     QML_REGISTERTYPE(NS_MODELS, AudioManagerListModel);
+    QML_REGISTERTYPE(NS_MODELS, PluginListModel);
+    QML_REGISTERTYPE(NS_MODELS, PreferenceItemListModel);
     QML_REGISTERTYPE(NS_MODELS, PluginListPreferenceModel);
     QML_REGISTERTYPE(NS_MODELS, FilesToSendListModel);
     QML_REGISTERTYPE(NS_MODELS, SmartListModel);
diff --git a/src/settingsview/SettingsView.qml b/src/settingsview/SettingsView.qml
index 6b08dc06ac7d8983fb87b39607446d68556ffad7..8980674f30c06e38886043ed5dd60c80c98d0a2e 100644
--- a/src/settingsview/SettingsView.qml
+++ b/src/settingsview/SettingsView.qml
@@ -61,7 +61,6 @@ Rectangle {
                 break
             case SettingsView.Plugin:
                 selectedMenu = sel
-                pluginSettings.populatePluginSettings()
                 break
         }
     }
diff --git a/src/settingsview/components/PluginItemDelegate.qml b/src/settingsview/components/PluginItemDelegate.qml
index cc115181ca2566a9b1fff43610bc7b79437e8433..54cb8b0f1219c779f9430d7d7359ff163e661500 100644
--- a/src/settingsview/components/PluginItemDelegate.qml
+++ b/src/settingsview/components/PluginItemDelegate.qml
@@ -33,31 +33,14 @@ ItemDelegate {
     property string pluginId: ""
     property string pluginIcon: ""
     property bool isLoaded: false
-    property int rowHeight: implicitHeight
-
-    signal btnLoadPluginToggled
-
-    function btnPreferencesPluginClicked() {
-        pluginListPreferencesView.visible = !pluginListPreferencesView.visible
-        pluginListPreferencesView.updateProperties(root.pluginName, root.pluginIcon, root.pluginId, root.isLoaded)
-    }
-
-    Connections {
-        target: enabledplugin
-
-        function onHidePreferences() {
-            pluginListPreferencesView.visible = false
-            pluginListPreferencesView.updatePluginPrefListView()
-        }
-    }
+    height: pluginListPreferencesView.visible ? implicitHeight + pluginListPreferencesView.effectiveHeight : implicitHeight
 
     ColumnLayout {
         anchors.fill: parent
-        implicitHeight: childrenRect.height
 
         RowLayout {
             Layout.fillWidth: true
-            Layout.preferredHeight: root.rowHeight
+            Layout.preferredHeight: implicitHeight
 
             Label {
                 id: pluginImage
@@ -107,8 +90,11 @@ ItemDelegate {
 
                 checked: isLoaded
                 onSwitchToggled: {
-                    btnLoadPluginToggled()
-                    pluginListPreferencesView.isLoaded = root.isLoaded
+                    if (isLoaded)
+                        PluginModel.unloadPlugin(pluginId)
+                    else
+                        PluginModel.loadPlugin(pluginId)
+                    installedPluginsModel.pluginChanged(index)
                 }
             }
 
@@ -124,7 +110,7 @@ ItemDelegate {
                 imageColor: JamiTheme.textColor
                 toolTipText: JamiStrings.showHidePrefs
 
-                onClicked: btnPreferencesPluginClicked()
+                onClicked: pluginListPreferencesView.visible = !pluginListPreferencesView.visible
             }
         }
 
@@ -134,15 +120,7 @@ ItemDelegate {
             Layout.fillWidth: true
             Layout.leftMargin: JamiTheme.preferredMarginSize
             Layout.rightMargin: JamiTheme.preferredMarginSize
-            Layout.minimumHeight: 1
-            Layout.preferredHeight: childrenRect.height
-
-            onUpdatePluginPrefListView: {
-                if (pluginListPreferencesView.visible)
-                    root.implicitHeight = root.rowHeight + pluginListPreferencesView.childrenRect.height
-                else
-                    root.implicitHeight = root.rowHeight
-            }
+            Layout.preferredHeight: effectiveHeight
         }
     }
 }
diff --git a/src/settingsview/components/PluginListPreferencesView.qml b/src/settingsview/components/PluginListPreferencesView.qml
index f63d2b2cccfcfd48e75e0218f189a7c131394288..16409c286f84cf00dbadfdec6d115728bd380729 100644
--- a/src/settingsview/components/PluginListPreferencesView.qml
+++ b/src/settingsview/components/PluginListPreferencesView.qml
@@ -29,122 +29,35 @@ import "../../commoncomponents"
 Rectangle {
     id: root
 
-    enum Type {
-        LIST,
-        PATH,
-        EDITTEXT,
-        DEFAULT
-    }
-
-    property string pluginName: ""
-    property string pluginIcon: ""
-    property string pluginId: ""
-    property bool isLoaded: false
-    property string category: ""
-    property var categories: ["all"]
-    property string generalCategory: ""
-
-    visible: false
-    color: "transparent"
-
-    signal uninstalled
-    signal updatePluginPrefListView
-
-    function updateProperties(name, icon, path, status) {
-        root.pluginName = name
-        root.pluginIcon = icon
-        root.pluginId = path
-        root.isLoaded = status
-        root.categories = PluginAdapter.getPluginPreferencesCategories(path)
-        if (root.category === "" && root.categories.length > 0)
-            root.category = root.categories[0]
-        resetModels()
-    }
-
-    function resetModels() {
-        updatePluginPrefListView()
-        root.categories = PluginAdapter.getPluginPreferencesCategories(root.pluginId)
-        if (root.categories.length <= 1) {
-            root.generalCategory = "all"
-            categoriesGrid.visible = false
-            prefsByCategory.visible = false
+    property int effectiveHeight: visible ? implicitHeight : 0
+    implicitHeight: childrenRect.height
+    onVisibleChanged: {
+        if (visible) {
+            preferencesPerCategoryModel.reset()
+            generalPreferencesModel.reset()
         }
-        else {
-            gridModel.model = root.categories
-            if (root.categories.length % 2 == 1) {
-                gridModel.model = PluginAdapter.getPluginPreferencesCategories(pluginId, true)
-                oddCategoryButton.text = root.categories[root.categories.length - 1]
-                oddCategoryButton.highlighted = root.category == oddCategoryButton.text
-            }
-            oddCategoryButton.visible = root.categories.length % 2 == 1
-            root.generalCategory = ""
-        }
-        pluginPreferenceView.model = PluginAdapter.getPluginPreferencesModel(root.pluginId, root.generalCategory)
-        pluginPreferenceViewCategory.model = PluginAdapter.getPluginPreferencesModel(root.pluginId, root.category)
-        updatePluginPrefListView()
     }
 
-    Connections {
-        target: PluginAdapter
-
-        function onPreferenceChanged(pluginId) {
-            if (root.pluginId === pluginId)
-                resetModels()
-        }
-    }
-
-    function resetPluginSlot() {
-        msgDialog.buttonCallBacks = [function () {
-            resetPlugin()
-        }]
-        msgDialog.openWithParameters(qsTr("Reset preferences"),
-                                     qsTr("Are you sure you wish to reset "+ pluginName +
-                                          " preferences?"))
-    }
-
-    function resetPlugin() {
-        if (isLoaded) {
-            PluginModel.unloadPlugin(pluginId)
-            PluginModel.resetPluginPreferencesValues(pluginId)
-            PluginModel.loadPlugin(pluginId)
-        } else {
-            PluginModel.resetPluginPreferencesValues(pluginId)
-        }
-        pluginPreferenceView.model = PluginAdapter.getPluginPreferencesModel(root.pluginId, root.generalCategory)
-        pluginPreferenceViewCategory.model = PluginAdapter.getPluginPreferencesModel(root.pluginId, root.category)
-        PluginAdapter.pluginHandlersUpdateStatus()
-    }
-
-    function uninstallPluginSlot() {
-        msgDialog.buttonCallBacks = [function () {
-            uninstallPlugin()
-        }]
-        msgDialog.openWithParameters(qsTr("Uninstall plugin"),
-                                     qsTr("Are you sure you wish to uninstall " + pluginName + " ?"))
-    }
+    property string category: categories.length > 0 ? categories[0] : category ? category : ""
+    property var categories: PluginAdapter.getPluginPreferencesCategories(pluginId)
+    property string generalCategory: categories.length <= 1 ? "all" : ""
 
-    function uninstallPlugin() {
-        PluginModel.uninstallPlugin(root.pluginId)
-        PluginAdapter.pluginUninstalled()
-        PluginAdapter.pluginHandlersUpdateStatus()
-        root.visible = false
-    }
+    visible: false
 
     function setPreference(pluginId, preferenceKey, preferenceNewValue)
     {
         if (isLoaded) {
             PluginModel.unloadPlugin(pluginId)
-            PluginModel.setPluginPreference(pluginId, preferenceKey, preferenceNewValue)
+            PluginModel.setPluginPreference(pluginId, "", preferenceKey, preferenceNewValue)
             PluginModel.loadPlugin(pluginId)
         } else
-            PluginModel.setPluginPreference(pluginId, preferenceKey, preferenceNewValue)
-        PluginAdapter.pluginHandlersUpdateStatus()
+            PluginModel.setPluginPreference(pluginId, "", preferenceKey, preferenceNewValue)
     }
 
     SimpleMessageDialog {
         id: msgDialog
 
-        buttonTitles: [qsTr("Ok"), qsTr("Cancel")]
+        buttonTitles: [JamiStrings.optionOk, JamiStrings.optionCancel]
         buttonStyles: [SimpleMessageDialog.ButtonStyle.TintedBlue,
                        SimpleMessageDialog.ButtonStyle.TintedBlack]
     }
@@ -175,7 +88,7 @@ Rectangle {
             Layout.topMargin: 24
             height: JamiTheme.preferredFieldHeight
 
-            text: qsTr(pluginName + "\nPreferences")
+            text: JamiStrings.pluginPreferences.arg(pluginName)
             font.pointSize: JamiTheme.headerFontSize
             font.kerning: true
             color: JamiTheme.textColor
@@ -186,6 +99,9 @@ Rectangle {
 
         Rectangle {
             id: prefsByCategory
+
+            visible: categories.length > 1
+
             Layout.topMargin: 24
             Layout.fillWidth: true
             implicitHeight: childrenRect.height
@@ -197,15 +113,16 @@ Rectangle {
 
                 GridLayout {
                     id: categoriesGrid
+
                     Layout.fillWidth: true
-                    implicitHeight: childrenRect.height
+                    implicitHeight: gridModel.count * JamiTheme.preferredFieldHeight
                     columns: 2
                     columnSpacing: 0
                     rowSpacing: 0
 
                     Repeater {
                         id: gridModel
-                        model: root.categories
+                        model: categories.length % 2 === 1 ? PluginAdapter.getPluginPreferencesCategories(pluginId, true) : root.categories
                         Button {
                             id: repDelegate
                             Layout.fillWidth: true
@@ -215,7 +132,6 @@ Rectangle {
                             flat: true
                             onClicked: {
                                 root.category = modelData
-                                PluginAdapter.preferenceChanged(root.pluginId)
                             }
                             background: Rectangle {
                                 anchors.fill: parent
@@ -241,10 +157,13 @@ Rectangle {
                     Layout.fillWidth: true
                     Layout.preferredHeight: JamiTheme.preferredFieldHeight
                     flat: true
-                    visible: false
+                    visible: categories.length % 2 === 1
+
+                    text: categories[categories.length - 1]
+                    highlighted: category === text
+
                     onClicked: {
                         root.category = oddCategoryButton.text
-                        PluginAdapter.preferenceChanged(root.pluginId)
                     }
                     background: Rectangle {
                         anchors.fill: parent
@@ -268,11 +187,18 @@ Rectangle {
                     Layout.fillWidth: true
                     Layout.minimumHeight: 1
                     Layout.preferredHeight: childrenRect.height
-                    implicitHeight: childrenRect.height
 
-                    model: PluginAdapter.getPluginPreferencesModel(root.pluginId, root.category)
+                    model: PreferenceItemListModel {
+                        id: preferencesPerCategoryModel
+                        lrcInstance: LRCInstance
+                        category_: category
+                        pluginId_: pluginId
+
+                        onCategory_Changed: {
+                            this.reset()
+                        }
+                    }
                     interactive: false
-                    maximumFlickVelocity: 1024
 
                     delegate: PreferenceItemDelegate {
                         id: preferenceItemDelegateCategory
@@ -300,7 +226,7 @@ Rectangle {
 
                         onBtnPreferenceClicked: {
                             setPreference(pluginId, preferenceKey, preferenceNewValue)
-                            pluginPreferenceViewCategory.model = PluginAdapter.getPluginPreferencesModel(pluginId, root.category)
+                            preferencesPerCategoryModel.reset()
                         }
 
                         background: Rectangle {
@@ -314,15 +240,22 @@ Rectangle {
 
         ListView {
             id: pluginPreferenceView
+
             Layout.fillWidth: true
             Layout.minimumHeight: 1
-
-            implicitHeight: childrenRect.height
             Layout.preferredHeight: childrenRect.height
 
-            model: PluginAdapter.getPluginPreferencesModel(root.pluginId)
+            model: PreferenceItemListModel {
+                id: generalPreferencesModel
+                lrcInstance: LRCInstance
+                category_: generalCategory
+                pluginId_: pluginId
+
+                onCategory_Changed: {
+                    this.reset()
+                }
+            }
             interactive: false
-            maximumFlickVelocity: 1024
 
             delegate: PreferenceItemDelegate {
                 id: preferenceItemDelegate
@@ -350,12 +283,7 @@ Rectangle {
 
                 onBtnPreferenceClicked: {
                     setPreference(pluginId, preferenceKey, preferenceNewValue)
-                    pluginPreferenceView.model = PluginAdapter.getPluginPreferencesModel(pluginId, generalCategory)
-                }
-
-                background: Rectangle {
-                    anchors.fill: parent
-                    color: "transparent"
+                    generalPreferencesModel.reset()
                 }
             }
         }
@@ -381,7 +309,21 @@ Rectangle {
 
                 text: JamiStrings.reset
 
-                onClicked: resetPluginSlot()
+                onClicked: {
+                    msgDialog.buttonCallBacks = [function () {
+                        if (isLoaded) {
+                            PluginModel.unloadPlugin(pluginId)
+                            PluginModel.resetPluginPreferencesValues(pluginId, "")
+                            PluginModel.loadPlugin(pluginId)
+                        } else {
+                            PluginModel.resetPluginPreferencesValues(pluginId, "")
+                        }
+                        preferencesPerCategoryModel.reset()
+                        generalPreferencesModel.reset()
+                    }]
+                    msgDialog.openWithParameters(JamiStrings.resetPreferences,
+                                                 JamiStrings.pluginResetConfirmation.arg(pluginName))
+                }
             }
 
             MaterialButton {
@@ -397,14 +339,20 @@ Rectangle {
 
                 iconSource: JamiResources.delete_24dp_svg
 
-                text: qsTr("Uninstall")
+                text: JamiStrings.uninstall
 
-                onClicked: uninstallPluginSlot()
+                onClicked: {
+                    msgDialog.buttonCallBacks = [function () {
+                        PluginModel.uninstallPlugin(pluginId)
+                        installedPluginsModel.removePlugin(index)
+                    }]
+                    msgDialog.openWithParameters(JamiStrings.uninstallPlugin,
+                                                 JamiStrings.pluginUninstallConfirmation.arg(pluginName))
+                }
             }
         }
 
         Rectangle {
-            id: endline
             Layout.bottomMargin: 10
             height: 2
             Layout.fillWidth: true
diff --git a/src/settingsview/components/PluginListSettingsView.qml b/src/settingsview/components/PluginListSettingsView.qml
index 835e3207fd419951f9146fe8edd14d4a586e9a71..4eab6ed6fc0bf01ac6ca3b1b9ee90c8b85adf5ae 100644
--- a/src/settingsview/components/PluginListSettingsView.qml
+++ b/src/settingsview/components/PluginListSettingsView.qml
@@ -30,32 +30,9 @@ import "../../commoncomponents"
 Rectangle {
     id: root
 
-    Connections {
-        target: PluginAdapter
-
-        function onPluginUninstalled() {
-            pluginListView.model = PluginAdapter.getPluginSelectableModel()
-        }
-    }
-
     visible: false
     color: JamiTheme.secondaryBackgroundColor
 
-    function openPluginFileSlot() {
-        pluginPathDialog.open()
-    }
-
-    function loadPluginSlot(pluginId, isLoaded) {
-        var loaded = false
-        if (isLoaded)
-            PluginModel.unloadPlugin(pluginId)
-        else
-            loaded = PluginModel.loadPlugin(pluginId)
-        pluginListView.model = PluginAdapter.getPluginSelectableModel()
-        PluginAdapter.pluginHandlersUpdateStatus()
-        return loaded
-    }
-
     JamiFileDialog {
         id: pluginPathDialog
 
@@ -69,8 +46,7 @@ Rectangle {
         onAccepted: {
             var url = UtilsAdapter.getAbsPath(file.toString())
             PluginModel.installPlugin(url, true)
-            pluginListView.model = PluginAdapter.getPluginSelectableModel()
-            PluginAdapter.pluginHandlersUpdateStatus()
+            installedPluginsModel.addPlugin()
         }
     }
 
@@ -111,7 +87,7 @@ Rectangle {
 
             text: JamiStrings.installPlugin
 
-            onClicked: openPluginFileSlot()
+            onClicked: pluginPathDialog.open()
         }
 
         ListView {
@@ -122,14 +98,21 @@ Rectangle {
             Layout.preferredHeight: childrenRect.height
             Layout.bottomMargin: 10
 
-            model: PluginAdapter.getPluginSelectableModel()
+            model: PluginListModel {
+                id: installedPluginsModel
+
+                lrcInstance: LRCInstance
+                onLrcInstanceChanged: {
+                    this.reset()
+                }
+            }
+
             maximumFlickVelocity: 1024
 
             delegate: PluginItemDelegate {
                 id: pluginItemDelegate
 
                 width: pluginListView.width
-                rowHeight: 40
                 implicitHeight: 40
 
                 pluginName: PluginName
@@ -137,10 +120,6 @@ Rectangle {
                 pluginIcon: PluginIcon
                 isLoaded: IsLoaded
 
-                onBtnLoadPluginToggled: {
-                    isLoaded = loadPluginSlot(pluginId, isLoaded)
-                }
-
                 background: Rectangle {
                     anchors.fill: parent
                     color: "transparent"
diff --git a/src/settingsview/components/PluginSettingsPage.qml b/src/settingsview/components/PluginSettingsPage.qml
index 0428aa92fb68eeaaa27b86354014d3a90f8a978c..3c0e401b4aa9846b92e47099d05078f776953cfe 100644
--- a/src/settingsview/components/PluginSettingsPage.qml
+++ b/src/settingsview/components/PluginSettingsPage.qml
@@ -32,16 +32,6 @@ Rectangle {
     property int contentWidth: pluginSettingsColumnLayout.width
     property int preferredHeight: pluginSettingsColumnLayout.implicitHeight
 
-    function populatePluginSettings() {
-        enabledplugin.checked = PluginModel.getPluginsEnabled()
-        pluginListSettingsView.visible = enabledplugin.checked
-    }
-
-    function slotSetPluginEnabled(state) {
-        PluginModel.setPluginsEnabled(state)
-        PluginAdapter.pluginHandlersUpdateStatus()
-    }
-
     color: JamiTheme.secondaryBackgroundColor
 
     ColumnLayout {
@@ -54,7 +44,7 @@ Rectangle {
         ToggleSwitch {
             id: enabledplugin
 
-            signal hidePreferences
+            checked: PluginAdapter.isEnabled
 
             Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
             Layout.fillWidth: true
@@ -65,19 +55,14 @@ Rectangle {
             labelText: JamiStrings.enable
             fontPointSize: JamiTheme.headerFontSize
 
-            onSwitchToggled: {
-                slotSetPluginEnabled(checked)
-
-                pluginListSettingsView.visible = checked
-                if (!pluginListSettingsView.visible) {
-                    hidePreferences()
-                }
-            }
+            onSwitchToggled: PluginAdapter.isEnabled = checked
         }
 
         PluginListSettingsView {
             id: pluginListSettingsView
 
+            visible: PluginAdapter.isEnabled
+
             Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
             Layout.fillWidth: true
             Layout.leftMargin: JamiTheme.preferredMarginSize
diff --git a/src/utilsadapter.cpp b/src/utilsadapter.cpp
index 356e92bd9739de07712327e584d5ace607998827..449fd1e1b91db7ecb47d7c43bf9ca51aa72fc039 100644
--- a/src/utilsadapter.cpp
+++ b/src/utilsadapter.cpp
@@ -572,4 +572,4 @@ bool
 UtilsAdapter::luma(const QColor& color) const
 {
     return (0.2126 * color.red() + 0.7152 * color.green() + 0.0722 * color.blue()) > .6;
-}
\ No newline at end of file
+}