From bad7cff3168160bd14dcf27f2dcd004170ed53bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 9 Sep 2022 10:32:15 -0400
Subject: [PATCH] accountcombobox: show unread count

Change-Id: Ia6d7ba0ee9e32d5830b35b863b3981e2487df183
GitLab: #821
---
 src/app/accountadapter.cpp                          |  9 ++++++++-
 src/app/accountadapter.h                            |  3 +++
 src/app/accountlistmodel.cpp                        | 11 +++++++++++
 src/app/accountlistmodel.h                          |  3 +++
 src/app/conversationsadapter.cpp                    |  2 +-
 src/app/mainview/components/AccountItemDelegate.qml | 12 ++++++++++++
 src/app/qmlregister.cpp                             |  2 +-
 src/app/systemtray.cpp                              |  3 ++-
 src/app/systemtray.h                                |  5 ++++-
 tests/unittests/globaltestenvironment.h             |  5 ++++-
 10 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/app/accountadapter.cpp b/src/app/accountadapter.cpp
index bc6e4aa09..e7610a922 100644
--- a/src/app/accountadapter.cpp
+++ b/src/app/accountadapter.cpp
@@ -27,10 +27,12 @@
 #include <QtConcurrent/QtConcurrent>
 
 AccountAdapter::AccountAdapter(AppSettingsManager* settingsManager,
+                               SystemTray* systemTray,
                                LRCInstance* instance,
                                QObject* parent)
     : QmlAdapterBase(instance, parent)
     , settingsManager_(settingsManager)
+    , systemTray_(systemTray)
     , accountListModel_(new AccountListModel(instance))
     , deviceItemListModel_(new DeviceItemListModel(instance))
 {
@@ -46,6 +48,11 @@ AccountAdapter::AccountAdapter(AppSettingsManager* settingsManager,
             &AccountModel::profileUpdated,
             this,
             &AccountAdapter::accountStatusChanged);
+
+    connect(systemTray_,
+            &SystemTray::countChanged,
+            accountListModel_.get(),
+            &AccountListModel::updateNotifications);
 }
 
 AccountModel*
@@ -354,4 +361,4 @@ AccountAdapter::setArchivePasswordAsync(const QString& accountID, const QString&
         config.archivePassword = password;
         lrcInstance_->accountModel().setAccountConfig(accountID, config);
     });
-}
+}
\ No newline at end of file
diff --git a/src/app/accountadapter.h b/src/app/accountadapter.h
index 83052c4e6..a582a056c 100644
--- a/src/app/accountadapter.h
+++ b/src/app/accountadapter.h
@@ -22,6 +22,7 @@
 
 #include "accountlistmodel.h"
 #include "deviceitemlistmodel.h"
+#include "systemtray.h"
 #include "lrcinstance.h"
 #include "utils.h"
 
@@ -44,6 +45,7 @@ Q_SIGNALS:
 
 public:
     explicit AccountAdapter(AppSettingsManager* settingsManager,
+                            SystemTray* systemTray,
                             LRCInstance* instance,
                             QObject* parent = nullptr);
     ~AccountAdapter() = default;
@@ -102,6 +104,7 @@ private:
     QMetaObject::Connection registeredNameSavedConnection_;
 
     AppSettingsManager* settingsManager_;
+    SystemTray* systemTray_;
 
     QScopedPointer<AccountListModel> accountListModel_;
     QScopedPointer<DeviceItemListModel> deviceItemListModel_;
diff --git a/src/app/accountlistmodel.cpp b/src/app/accountlistmodel.cpp
index e86983655..9c6a73519 100644
--- a/src/app/accountlistmodel.cpp
+++ b/src/app/accountlistmodel.cpp
@@ -63,12 +63,23 @@ AccountListModel::data(const QModelIndex& index, int role) const
         return QVariant(static_cast<int>(accountInfo.profileInfo.type));
     case Role::Status:
         return QVariant(static_cast<int>(accountInfo.status));
+    case Role::NotificationCount:
+        return QVariant(static_cast<int>(accountInfo.conversationModel->notificationsCount()));
     case Role::ID:
         return QVariant(accountInfo.id);
     }
     return QVariant();
 }
 
+void
+AccountListModel::updateNotifications()
+{
+    for (int i = 0; i < lrcInstance_->accountModel().getAccountList().size(); ++i) {
+        QModelIndex modelIndex = QAbstractListModel::index(i, 0);
+        Q_EMIT dataChanged(modelIndex, modelIndex, {Role::NotificationCount});
+    }
+}
+
 QHash<int, QByteArray>
 AccountListModel::roleNames() const
 {
diff --git a/src/app/accountlistmodel.h b/src/app/accountlistmodel.h
index f184b190d..e1df2c303 100644
--- a/src/app/accountlistmodel.h
+++ b/src/app/accountlistmodel.h
@@ -26,6 +26,7 @@
     X(Username) \
     X(Type) \
     X(Status) \
+    X(NotificationCount) \
     X(ID)
 
 namespace AccountList {
@@ -53,6 +54,8 @@ public:
     // reset the model when there's new account added
     Q_INVOKABLE void reset();
 
+    void updateNotifications();
+
 protected:
     using Role = AccountList::Role;
 };
diff --git a/src/app/conversationsadapter.cpp b/src/app/conversationsadapter.cpp
index 6c06fe374..02fa2368d 100644
--- a/src/app/conversationsadapter.cpp
+++ b/src/app/conversationsadapter.cpp
@@ -379,7 +379,7 @@ ConversationsAdapter::updateConversationFilterData()
     }
     set_totalUnreadMessageCount(totalUnreadMessages);
     set_pendingRequestCount(accountInfo.conversationModel->pendingRequestCount());
-    systemTray_->setCount(lrcInstance_->notificationsCount());
+    systemTray_->onNotificationCountChanged(lrcInstance_->notificationsCount());
 
     if (get_pendingRequestCount() == 0 && get_filterRequests())
         set_filterRequests(false);
diff --git a/src/app/mainview/components/AccountItemDelegate.qml b/src/app/mainview/components/AccountItemDelegate.qml
index 9f5dc0c06..b1835681c 100644
--- a/src/app/mainview/components/AccountItemDelegate.qml
+++ b/src/app/mainview/components/AccountItemDelegate.qml
@@ -91,5 +91,17 @@ ItemDelegate {
                 elide: Text.ElideRight
             }
         }
+
+        // unread message count
+        Item {
+            Layout.preferredWidth: childrenRect.width
+            Layout.preferredHeight: childrenRect.height
+            Layout.alignment: Qt.AlignRight
+            BadgeNotifier {
+                size: 20
+                count: NotificationCount
+                animate: index === 0
+            }
+        }
     }
 }
diff --git a/src/app/qmlregister.cpp b/src/app/qmlregister.cpp
index e9a931770..54ed58061 100644
--- a/src/app/qmlregister.cpp
+++ b/src/app/qmlregister.cpp
@@ -113,7 +113,7 @@ registerTypes(QQmlEngine* engine,
     auto conversationsAdapter = new ConversationsAdapter(systemTray, lrcInstance, parent);
     auto avAdapter = new AvAdapter(lrcInstance, parent);
     auto contactAdapter = new ContactAdapter(lrcInstance, parent);
-    auto accountAdapter = new AccountAdapter(settingsManager, lrcInstance, parent);
+    auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
     auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
     auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
     auto currentConversation = new CurrentConversation(lrcInstance, parent);
diff --git a/src/app/systemtray.cpp b/src/app/systemtray.cpp
index 5d6fe8052..e196da62e 100644
--- a/src/app/systemtray.cpp
+++ b/src/app/systemtray.cpp
@@ -138,13 +138,14 @@ SystemTray::~SystemTray()
 }
 
 void
-SystemTray::setCount(int count)
+SystemTray::onNotificationCountChanged(int count)
 {
     if (count == 0) {
         setIcon(QIcon(":/images/jami.svg"));
     } else {
         setIcon(QIcon(":/images/jami-new.svg"));
     }
+    Q_EMIT countChanged();
 }
 
 #ifdef Q_OS_LINUX
diff --git a/src/app/systemtray.h b/src/app/systemtray.h
index d386fd7d4..b9d263e86 100644
--- a/src/app/systemtray.h
+++ b/src/app/systemtray.h
@@ -37,7 +37,7 @@ public:
     explicit SystemTray(AppSettingsManager* settingsManager, QObject* parent = nullptr);
     ~SystemTray();
 
-    void setCount(int count);
+    void onNotificationCountChanged(int count);
 #ifdef Q_OS_LINUX
     bool hideNotification(const QString& id);
     void showNotification(const QString& id,
@@ -61,6 +61,9 @@ Q_SIGNALS:
     void setOnClickedCallback(Func&& onClickedCb);
 #endif // Q_OS_LINUX
 
+Q_SIGNALS:
+    void countChanged();
+
 private:
     QMetaObject::Connection messageClicked_;
     AppSettingsManager* settingsManager_;
diff --git a/tests/unittests/globaltestenvironment.h b/tests/unittests/globaltestenvironment.h
index ba083f701..58596be83 100644
--- a/tests/unittests/globaltestenvironment.h
+++ b/tests/unittests/globaltestenvironment.h
@@ -59,7 +59,10 @@ public:
         lrcInstance->subscribeToDebugReceived();
 
         // setup the adapters (their lifetimes are that of MainApplication)
-        accountAdapter.reset(new AccountAdapter(settingsManager.get(), lrcInstance.data(), nullptr));
+        accountAdapter.reset(new AccountAdapter(settingsManager.get(),
+                                                systemTray.get(),
+                                                lrcInstance.data(),
+                                                nullptr));
     }
 
     void TearDown()
-- 
GitLab