From 6b3bf5149fcd35b3e881151faa92ad9c57cc85cb Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Tue, 3 Aug 2021 15:10:58 -0400
Subject: [PATCH] misc: add a qml adapter class to represent the current
 conversation

Provides observable property representations of a conversation info
structure. Is updated when the selected conversation Id changes.

This object is only exposed in this commit, and will be used in
subsequent commits to introduce a more declarative approach in the
UI code.

Change-Id: I25be0f6b82cf9341b67fbf04fdeb04bffbf8ab24
---
 CMakeLists.txt              |  6 ++-
 src/currentconversation.cpp | 94 +++++++++++++++++++++++++++++++++++++
 src/currentconversation.h   | 58 +++++++++++++++++++++++
 src/qmlregister.cpp         |  3 ++
 4 files changed, 159 insertions(+), 2 deletions(-)
 create mode 100644 src/currentconversation.cpp
 create mode 100644 src/currentconversation.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42449864e..70e8291f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,7 +87,8 @@ set(COMMON_SOURCES
     ${SRC_DIR}/calloverlaymodel.cpp
     ${SRC_DIR}/filestosendlistmodel.cpp
     ${SRC_DIR}/wizardviewstepmodel.cpp
-    ${SRC_DIR}/avatarregistry.cpp)
+    ${SRC_DIR}/avatarregistry.cpp
+    ${SRC_DIR}/currentconversation.cpp)
 
 set(COMMON_HEADERS
     ${SRC_DIR}/avatarimageprovider.h
@@ -145,7 +146,8 @@ set(COMMON_HEADERS
     ${SRC_DIR}/calloverlaymodel.h
     ${SRC_DIR}/filestosendlistmodel.h
     ${SRC_DIR}/wizardviewstepmodel.h
-    ${SRC_DIR}/avatarregistry.h)
+    ${SRC_DIR}/avatarregistry.h
+    ${SRC_DIR}/currentconversation.h)
 
 set(QML_LIBS
     Qt5::Quick
diff --git a/src/currentconversation.cpp b/src/currentconversation.cpp
new file mode 100644
index 000000000..515ac4de3
--- /dev/null
+++ b/src/currentconversation.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "currentconversation.h"
+
+CurrentConversation::CurrentConversation(LRCInstance* lrcInstance, QObject* parent)
+    : QObject(parent)
+    , lrcInstance_(lrcInstance)
+{
+    // whenever the account changes, reconnect the new conversation model
+    // for updates to the conversation and call state/id
+    connect(lrcInstance_,
+            &LRCInstance::currentAccountIdChanged,
+            this,
+            &CurrentConversation::connectModel);
+    connectModel();
+
+    // update when the conversation itself changes
+    connect(lrcInstance_,
+            &LRCInstance::selectedConvUidChanged,
+            this,
+            &CurrentConversation::updateData);
+    updateData();
+}
+
+void
+CurrentConversation::updateData()
+{
+    auto convId = lrcInstance_->get_selectedConvUid();
+    if (convId.isEmpty())
+        return;
+    set_id(convId);
+    try {
+        auto accountId = lrcInstance_->get_currentAccountId();
+        const auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
+        if (auto optConv = accInfo.conversationModel->getConversationForUid(convId)) {
+            set_title(accInfo.conversationModel->title(convId));
+            set_uris(accInfo.conversationModel->peersForConversation(convId).toList());
+            set_isSwarm(optConv->get().isSwarm());
+            set_isLegacy(optConv->get().isLegacy());
+            set_isCoreDialog(optConv->get().isCoreDialog());
+            set_isRequest(optConv->get().isRequest);
+            set_readOnly(optConv->get().readOnly);
+            set_needsSyncing(optConv->get().needsSyncing);
+            set_isSip(accInfo.profileInfo.type == profile::Type::SIP);
+            set_callId(optConv->get().getCallId());
+            if (accInfo.callModel->hasCall(callId_)) {
+                set_callState(accInfo.callModel->getCall(callId_).status);
+            } else {
+                set_callState(call::Status::INVALID);
+            }
+        }
+    } catch (...) {
+        qWarning() << "Can't update current conversation data for" << convId;
+    }
+}
+
+void
+CurrentConversation::onConversationUpdated(const QString& convId)
+{
+    // filter for our currently set id
+    if (id_ != convId)
+        return;
+    updateData();
+}
+
+void
+CurrentConversation::connectModel()
+{
+    auto convModel = lrcInstance_->getCurrentConversationModel();
+    if (!convModel)
+        return;
+
+    connect(lrcInstance_->getCurrentConversationModel(),
+            &ConversationModel::conversationUpdated,
+            this,
+            &CurrentConversation::onConversationUpdated,
+            Qt::UniqueConnection);
+}
diff --git a/src/currentconversation.h b/src/currentconversation.h
new file mode 100644
index 000000000..35404d81a
--- /dev/null
+++ b/src/currentconversation.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 by Savoir-faire Linux
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "lrcinstance.h"
+
+#include <QObject>
+#include <QString>
+
+// an adapter object to expose a conversation::Info struct
+// as a group of observable properties
+// Note: this is a view item and will always use the current accountId
+class CurrentConversation final : public QObject
+{
+    Q_OBJECT
+    QML_PROPERTY(QString, id)
+    QML_PROPERTY(QString, title)
+    QML_PROPERTY(QStringList, uris)
+    QML_PROPERTY(bool, isSwarm)
+    QML_PROPERTY(bool, isLegacy)
+    QML_PROPERTY(bool, isCoreDialog)
+    QML_PROPERTY(bool, isRequest)
+    QML_PROPERTY(bool, readOnly)
+    QML_PROPERTY(bool, needsSyncing)
+    QML_PROPERTY(bool, isSip)
+    QML_PROPERTY(QString, callId)
+    QML_PROPERTY(call::Status, callState)
+    QML_PROPERTY(bool, inCall)
+
+public:
+    explicit CurrentConversation(LRCInstance* lrcInstance, QObject* parent = nullptr);
+    ~CurrentConversation() = default;
+
+private Q_SLOTS:
+    void updateData();
+    void onConversationUpdated(const QString& convId);
+
+private:
+    LRCInstance* lrcInstance_;
+
+    void connectModel();
+};
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 891761daf..07b9ce582 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -27,6 +27,7 @@
 #include "settingsadapter.h"
 #include "utilsadapter.h"
 #include "conversationsadapter.h"
+#include "currentconversation.h"
 
 #include "accountlistmodel.h"
 #include "accountstomigratelistmodel.h"
@@ -114,6 +115,7 @@ registerTypes(QQmlEngine* engine,
     auto utilsAdapter = new UtilsAdapter(systemTray, lrcInstance, parent);
     auto settingsAdapter = new SettingsAdapter(appSettingsManager, lrcInstance, parent);
     auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
+    auto currentConversation = new CurrentConversation(lrcInstance, parent);
 
     // qml adapter registration
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, callAdapter, "CallAdapter");
@@ -125,6 +127,7 @@ registerTypes(QQmlEngine* engine,
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, utilsAdapter, "UtilsAdapter");
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, settingsAdapter, "SettingsAdapter");
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, pluginAdapter, "PluginAdapter");
+    QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentConversation, "CurrentConversation");
 
     // TODO: remove these
     QML_REGISTERSINGLETONTYPE_CUSTOM(NS_MODELS, AVModel, &lrcInstance->avModel())
-- 
GitLab