From 9c78604c1ce66d259aa01332c70eac9915c32810 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Thu, 1 Sep 2022 15:21:58 -0400
Subject: [PATCH] mainapplication: handle jami: URIs

Asking jami to launch another instance with ./jami-qt jami:xxx
will search for "xxx" inside the application and select the
conversation if found.
This allow to support webpage with <a href="jami:username">

For GNU/Linux, in the .desktop file, x-scheme-handler/jami is
added.
For packaging, we will need to determine if the scheme is handled
automatically. For now, to test, we need to add:

x-scheme-handler/jami=jami-qt.desktop;

in "~/.config/mimeapps.list" (and jami-qt.desktop) should
be in a valid path.

Change-Id: Ibbb6e8942f1873d81a57640bdf6f839885981be3
GitLab: #655
---
 jami-qt.desktop                       |  1 +
 src/app/MainApplicationWindow.qml     |  4 ++++
 src/app/conversationsadapter.cpp      | 22 ++++++++++++++++++++++
 src/app/conversationsadapter.h        |  4 ++++
 src/app/mainapplication.cpp           |  2 +-
 src/app/mainapplication.h             |  1 +
 src/libclient/api/conversationmodel.h |  1 +
 src/libclient/conversationmodel.cpp   |  1 +
 8 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/jami-qt.desktop b/jami-qt.desktop
index b8d54fdf0..7fe6a43f2 100644
--- a/jami-qt.desktop
+++ b/jami-qt.desktop
@@ -11,3 +11,4 @@ Terminal=false
 Type=Application
 Categories=Network;Telephony;
 Keywords=Qt;chat;talk;im;message;voip;
+MimeType=x-scheme-handler/jami;
\ No newline at end of file
diff --git a/src/app/MainApplicationWindow.qml b/src/app/MainApplicationWindow.qml
index 0011976b8..db1bbe17c 100644
--- a/src/app/MainApplicationWindow.qml
+++ b/src/app/MainApplicationWindow.qml
@@ -191,6 +191,10 @@ ApplicationWindow {
         function onCloseRequested() {
             close(true)
         }
+
+        function onSearchAndSelect(request) {
+            ConversationsAdapter.setFilterAndSelect(request)
+        }
     }
 
     Connections {
diff --git a/src/app/conversationsadapter.cpp b/src/app/conversationsadapter.cpp
index cd1bf5def..6c06fe374 100644
--- a/src/app/conversationsadapter.cpp
+++ b/src/app/conversationsadapter.cpp
@@ -308,6 +308,15 @@ ConversationsAdapter::onSearchResultUpdated()
     searchSrcModel_->onSearchResultsUpdated();
 }
 
+void
+ConversationsAdapter::onSearchResultEnded()
+{
+    if (selectFirst_.exchange(false)) {
+        convModel_->select(0);
+        searchModel_->select(0);
+    }
+}
+
 void
 ConversationsAdapter::onConversationReady(const QString& convId)
 {
@@ -376,6 +385,13 @@ ConversationsAdapter::updateConversationFilterData()
         set_filterRequests(false);
 }
 
+void
+ConversationsAdapter::setFilterAndSelect(const QString& filterString)
+{
+    selectFirst_ = true;
+    setFilter(filterString);
+}
+
 void
 ConversationsAdapter::setFilter(const QString& filterString)
 {
@@ -578,6 +594,12 @@ ConversationsAdapter::connectConversationModel()
                      &ConversationsAdapter::onSearchResultUpdated,
                      Qt::UniqueConnection);
 
+    QObject::connect(currentConversationModel,
+                     &ConversationModel::searchResultEnded,
+                     this,
+                     &ConversationsAdapter::onSearchResultEnded,
+                     Qt::UniqueConnection);
+
     QObject::connect(currentConversationModel,
                      &ConversationModel::conversationReady,
                      this,
diff --git a/src/app/conversationsadapter.h b/src/app/conversationsadapter.h
index 0319b3980..0685f1032 100644
--- a/src/app/conversationsadapter.h
+++ b/src/app/conversationsadapter.h
@@ -53,6 +53,7 @@ public:
                                  const QString& avatar,
                                  const VectorString& participants);
     Q_INVOKABLE void setFilter(const QString& filterString);
+    Q_INVOKABLE void setFilterAndSelect(const QString& filterString);
     Q_INVOKABLE void ignoreFiltering(const QVariant& hightlighted);
     Q_INVOKABLE QVariantMap getConvInfoMap(const QString& convId);
     Q_INVOKABLE void restartConversation(const QString& convId);
@@ -93,6 +94,7 @@ private Q_SLOTS:
     void onConversationCleared(const QString&);
     void onSearchStatusChanged(const QString&);
     void onSearchResultUpdated();
+    void onSearchResultEnded();
     void onConversationReady(const QString&);
     void onBannedStatusChanged(const QString&, bool);
 
@@ -106,4 +108,6 @@ private:
     QScopedPointer<ConversationListProxyModel> convModel_;
     QScopedPointer<SearchResultsListModel> searchSrcModel_;
     QScopedPointer<SelectableListProxyModel> searchModel_;
+
+    std::atomic_bool selectFirst_ {false};
 };
diff --git a/src/app/mainapplication.cpp b/src/app/mainapplication.cpp
index ffd799c95..9c95d9fe8 100644
--- a/src/app/mainapplication.cpp
+++ b/src/app/mainapplication.cpp
@@ -227,8 +227,8 @@ MainApplication::handleUriAction(const QString& arg)
     } else if (!arg.isEmpty()) {
         uri = arg;
         qDebug() << "URI action invoked by secondary instance" << uri;
+        Q_EMIT searchAndSelect(uri.replace("jami:", ""));
     }
-    // TODO: implement URI protocol handling.
 }
 
 void
diff --git a/src/app/mainapplication.h b/src/app/mainapplication.h
index 8d6f90fad..c5fabe268 100644
--- a/src/app/mainapplication.h
+++ b/src/app/mainapplication.h
@@ -95,6 +95,7 @@ public:
 
 Q_SIGNALS:
     void closeRequested();
+    void searchAndSelect(const QString& request);
 
 private:
     void initLrc(const QString& downloadUrl, ConnectivityMonitor* cm, bool logDaemon);
diff --git a/src/libclient/api/conversationmodel.h b/src/libclient/api/conversationmodel.h
index f0307d969..cb5595031 100644
--- a/src/libclient/api/conversationmodel.h
+++ b/src/libclient/api/conversationmodel.h
@@ -502,6 +502,7 @@ Q_SIGNALS:
      * Emitted when search result has been updated
      */
     void searchResultUpdated() const;
+    void searchResultEnded() const;
     /**
      * Emitted when finish loading messages for conversation
      * @param loadingRequestId  loading request id
diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp
index 0bfff1e8b..6f3dbefbf 100644
--- a/src/libclient/conversationmodel.cpp
+++ b/src/libclient/conversationmodel.cpp
@@ -2944,6 +2944,7 @@ ConversationModelPimpl::slotContactModelUpdated(const QString& uri)
         searchResults.emplace_front(std::move(conversationInfo));
     }
     Q_EMIT linked.searchResultUpdated();
+    Q_EMIT linked.searchResultEnded();
 }
 
 void
-- 
GitLab