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