diff --git a/Linphone/model/CMakeLists.txt b/Linphone/model/CMakeLists.txt
index f09f9486a..b7d394a30 100644
--- a/Linphone/model/CMakeLists.txt
+++ b/Linphone/model/CMakeLists.txt
@@ -22,7 +22,8 @@ list(APPEND _LINPHONEAPP_SOURCES
model/core/CoreModel.cpp
model/friend/FriendModel.cpp
-
+ model/friend/FriendsManager.cpp
+
model/listener/Listener.hpp
model/logger/LoggerModel.cpp
diff --git a/Linphone/model/friend/FriendsManager.cpp b/Linphone/model/friend/FriendsManager.cpp
new file mode 100644
index 000000000..b36a77aa3
--- /dev/null
+++ b/Linphone/model/friend/FriendsManager.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010-2024 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#include "FriendsManager.hpp"
+
+#include "model/core/CoreModel.hpp"
+#include "tool/Utils.hpp"
+#include
+#include
+
+DEFINE_ABSTRACT_OBJECT(FriendsManager)
+
+std::shared_ptr FriendsManager::gFriendsManager;
+FriendsManager::FriendsManager(QObject *parent) : QObject(parent) {
+ moveToThread(CoreModel::getInstance()->thread());
+}
+
+FriendsManager::~FriendsManager() {
+}
+
+std::shared_ptr FriendsManager::create(QObject *parent) {
+ auto model = std::make_shared(parent);
+ return model;
+}
+
+std::shared_ptr FriendsManager::getInstance() {
+ if (!gFriendsManager) gFriendsManager = FriendsManager::create(nullptr);
+ return gFriendsManager;
+}
+
+QVariantMap FriendsManager::getKnownFriends() const {
+ return mKnownFriends;
+}
+
+QVariantMap FriendsManager::getUnknownFriends() const {
+ return mUnknownFriends;
+}
+
+QStringList FriendsManager::getOtherAddresses() const {
+ return mOtherAddresses;
+}
+
+std::shared_ptr FriendsManager::getKnownFriendAtKey(const QString& key) {
+ if (isInKnownFriends(key)) {
+ return mKnownFriends.value(key).value>();
+ } else return nullptr;
+}
+
+std::shared_ptr FriendsManager::getUnknownFriendAtKey(const QString& key) {
+ if (isInUnknownFriends(key)) {
+ return mUnknownFriends.value(key).value>();
+ } else return nullptr;
+}
+
+bool FriendsManager::isInKnownFriends(const QString& key) {
+ return mKnownFriends.contains(key);
+}
+
+bool FriendsManager::isInUnknownFriends(const QString& key) {
+ return mUnknownFriends.contains(key);
+}
+
+bool FriendsManager::isInOtherAddresses(const QString& key) {
+ return mOtherAddresses.contains(key);
+}
+
+void FriendsManager::appendKnownFriend(std::shared_ptr address, std::shared_ptr f) {
+ auto key = Utils::coreStringToAppString(address->asStringUriOnly());
+ if (mKnownFriends.contains(key)) {
+ qDebug() << "friend is already in konwn list, return";
+ return;
+ }
+ mKnownFriends.insert(key, QVariant::fromValue(f));
+}
+
+
+void FriendsManager::appendUnknownFriend(std::shared_ptr address, std::shared_ptr f) {
+ auto key = Utils::coreStringToAppString(address->asStringUriOnly());
+ if (mUnknownFriends.contains(key)) {
+ qDebug() << "friend is already in unkonwn list, return";
+ return;
+ }
+ mUnknownFriends.insert(key, QVariant::fromValue(f));
+}
+
+
+void FriendsManager::appendOtherAddress(QString address) {
+ if (mOtherAddresses.contains(address)) {
+ qDebug() << "friend is already in other addresses, return";
+ return;
+ }
+ mOtherAddresses.append(address);
+}
+
+void FriendsManager::removeUnknownFriend(const QString& key) {
+ mUnknownFriends.remove(key);
+}
+
+void FriendsManager::removeOtherAddress(const QString& key) {
+ mOtherAddresses.removeAll(key);
+}
diff --git a/Linphone/model/friend/FriendsManager.hpp b/Linphone/model/friend/FriendsManager.hpp
new file mode 100644
index 000000000..c2656288d
--- /dev/null
+++ b/Linphone/model/friend/FriendsManager.hpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010-2024 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * 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 .
+ */
+
+#ifndef FRIENDS_MANAGER_H_
+#define FRIENDS_MANAGER_H_
+
+#include
+#include
+#include
+#include
+#include
+#include "tool/AbstractObject.hpp"
+
+class FriendsManager : public QObject, public AbstractObject {
+ Q_OBJECT
+
+public:
+ FriendsManager(QObject *parent);
+ ~FriendsManager();
+ static std::shared_ptr create(QObject *parent);
+ static std::shared_ptr getInstance();
+
+ QVariantMap getKnownFriends() const;
+ QVariantMap getUnknownFriends() const;
+ QStringList getOtherAddresses() const;
+
+ std::shared_ptr getKnownFriendAtKey(const QString& key);
+ std::shared_ptr getUnknownFriendAtKey(const QString& key);
+
+ bool isInKnownFriends(const QString& key);
+ bool isInUnknownFriends(const QString& key);
+ bool isInOtherAddresses(const QString& key);
+
+ void appendKnownFriend(std::shared_ptr address, std::shared_ptr f);
+ void appendUnknownFriend(std::shared_ptr address, std::shared_ptr f);
+ void appendOtherAddress(QString address);
+
+ void removeUnknownFriend(const QString& key);
+ void removeOtherAddress(const QString& key);
+
+private:
+ static std::shared_ptr gFriendsManager;
+ QVariantMap mKnownFriends;
+ QVariantMap mUnknownFriends;
+ QStringList mOtherAddresses;
+ //core model connection + reset unknown et other quand friend ajouté, supprimé, updated
+ DECLARE_ABSTRACT_OBJECT
+};
+
+#endif
diff --git a/Linphone/model/search/MagicSearchModel.cpp b/Linphone/model/search/MagicSearchModel.cpp
index cd2f085fe..34ef0ab99 100644
--- a/Linphone/model/search/MagicSearchModel.cpp
+++ b/Linphone/model/search/MagicSearchModel.cpp
@@ -23,6 +23,7 @@
#include
#include "model/core/CoreModel.hpp"
+#include "model/friend/FriendsManager.hpp"
#include "model/setting/SettingsModel.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp"
@@ -83,6 +84,15 @@ void MagicSearchModel::onSearchResultsReceived(const std::shared_ptrgetFriend();
+ auto friendsManager = FriendsManager::getInstance();
+ if (f) {
+ qDebug() << "friend exists, append to unknown map";
+ auto friendAddress = f->getAddress();
+ friendsManager->appendUnknownFriend(friendAddress->clone(), f);
+ if (friendsManager->isInOtherAddresses(Utils::coreStringToAppString(friendAddress->asStringUriOnly()))) {
+ friendsManager->removeOtherAddress(Utils::coreStringToAppString(friendAddress->asStringUriOnly()));
+ }
+ }
auto fList = f ? f->getFriendList() : nullptr;
// qDebug() << log().arg("") << (f ? f->getName().c_str() : "NoFriend") << ", "
diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp
index 0d830590b..6c5c61044 100644
--- a/Linphone/model/tool/ToolModel.cpp
+++ b/Linphone/model/tool/ToolModel.cpp
@@ -22,6 +22,7 @@
#include "core/App.hpp"
#include "core/path/Paths.hpp"
#include "model/core/CoreModel.hpp"
+#include "model/friend/FriendsManager.hpp"
#include "tool/Utils.hpp"
#include
#include
@@ -126,8 +127,29 @@ std::shared_ptr ToolModel::findFriendByAddress(const QString &
}
std::shared_ptr ToolModel::findFriendByAddress(std::shared_ptr linphoneAddr) {
+ auto friendsManager = FriendsManager::getInstance();
+ QString key = Utils::coreStringToAppString(linphoneAddr->asStringUriOnly());
+ if (friendsManager->isInKnownFriends(key)) {
+ qDebug() << "Friend have been found in known friend, return it";
+ return friendsManager->getKnownFriendAtKey(key);
+ } else if (friendsManager->isInUnknownFriends(key)) {
+ qDebug() << "Friend have been found in unknown friend, return it";
+ return friendsManager->getUnknownFriendAtKey(key);
+ }
auto f = CoreModel::getInstance()->getCore()->findFriend(linphoneAddr);
+ if (f) {
+ if (friendsManager->isInUnknownFriends(key)) {
+ friendsManager->removeUnknownFriend(key);
+ }
+ qDebug() << "found friend, add to known map";
+ friendsManager->appendKnownFriend(linphoneAddr, f);
+ }
if (!f) {
+ if (friendsManager->isInOtherAddresses(key)) {
+ qDebug() << "A magic search has already be done for this address and nothing was found, return";
+ return nullptr;
+ }
+ friendsManager->appendOtherAddress(key);
qDebug() << "Couldn't find friend" << linphoneAddr->asStringUriOnly() << "in core, use magic search";
CoreModel::getInstance()->searchInMagicSearch(Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()),
(int)linphone::MagicSearch::Source::LdapServers
diff --git a/Linphone/view/Page/Form/Call/NewCallForm.qml b/Linphone/view/Page/Form/Call/NewCallForm.qml
index c8d7dd27a..5844cea31 100644
--- a/Linphone/view/Page/Form/Call/NewCallForm.qml
+++ b/Linphone/view/Page/Form/Call/NewCallForm.qml
@@ -55,90 +55,82 @@ FocusScope {
}
}
- Control.Control {
- id: listLayout
- Layout.fillWidth: true
- Layout.fillHeight: true
- background: Item {
- anchors.fill: parent
- }
- onVisibleChanged: if (!visible) mainItem.numPadPopup.close()
- contentItem: ColumnLayout {
- spacing: Math.round(38 * DefaultStyle.dp)
- SearchBar {
- id: searchBar
- Layout.alignment: Qt.AlignTop
- Layout.fillWidth: true
- Layout.rightMargin: Math.round(39 * DefaultStyle.dp)
- focus: true
- color: mainItem.searchBarColor
- borderColor: mainItem.searchBarBorderColor
- //: "Rechercher un contact"
- placeholderText: qsTr("search_bar_look_for_contact_text")
- numericPadPopup: mainItem.numPadPopup
- KeyNavigation.down: grouCallButton
- }
- ColumnLayout {
- id: content
- spacing: Math.round(32 * DefaultStyle.dp)
- Button {
- id: grouCallButton
- visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
- Layout.preferredWidth: Math.round(320 * DefaultStyle.dp)
- Layout.preferredHeight: Math.round(44 * DefaultStyle.dp)
- padding: 0
- KeyNavigation.up: searchBar
- KeyNavigation.down: contactList
- onClicked: mainItem.groupCallCreationRequested()
- background: Rectangle {
- anchors.fill: parent
- radius: Math.round(50 * DefaultStyle.dp)
- gradient: Gradient {
- orientation: Gradient.Horizontal
- GradientStop { position: 0.0; color: DefaultStyle.main2_100}
- GradientStop { position: 1.0; color: DefaultStyle.grey_0}
- }
- }
- contentItem: RowLayout {
- spacing: Math.round(16 * DefaultStyle.dp)
- anchors.verticalCenter: parent.verticalCenter
- Image {
- source: AppIcons.groupCall
- Layout.preferredWidth: Math.round(44 * DefaultStyle.dp)
- sourceSize.width: Math.round(44 * DefaultStyle.dp)
- fillMode: Image.PreserveAspectFit
- }
- Text {
- text: qsTr("call_start_group_call_title")
- color: DefaultStyle.grey_1000
- font {
- pixelSize: Typography.h4.pixelSize
- weight: Typography.h4.weight
- }
- }
- Item {
- Layout.fillWidth: true
- }
- EffectImage {
- imageSource: AppIcons.rightArrow
- Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
- Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
- colorizationColor: DefaultStyle.main2_500main
- }
- }
- }
- AllContactListView{
- id: contactList
- Layout.fillWidth: true
- Layout.fillHeight: true
- showContactMenu: false
- searchBarText: searchBar.text
- onContactSelected: (contact) => {
- mainItem.contactClicked(contact)
- }
- }
- }
- }
- }
- }
+ ColumnLayout {
+ onVisibleChanged: if (!visible) mainItem.numPadPopup.close()
+ spacing: Math.round(38 * DefaultStyle.dp)
+ SearchBar {
+ id: searchBar
+ Layout.alignment: Qt.AlignTop
+ Layout.fillWidth: true
+ Layout.rightMargin: Math.round(39 * DefaultStyle.dp)
+ focus: true
+ color: mainItem.searchBarColor
+ borderColor: mainItem.searchBarBorderColor
+ //: "Rechercher un contact"
+ placeholderText: qsTr("search_bar_look_for_contact_text")
+ numericPadPopup: mainItem.numPadPopup
+ KeyNavigation.down: grouCallButton
+ }
+ ColumnLayout {
+ id: content
+ spacing: Math.round(32 * DefaultStyle.dp)
+ Button {
+ id: grouCallButton
+ visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
+ Layout.preferredWidth: Math.round(320 * DefaultStyle.dp)
+ Layout.preferredHeight: Math.round(44 * DefaultStyle.dp)
+ padding: 0
+ KeyNavigation.up: searchBar
+ KeyNavigation.down: contactList
+ onClicked: mainItem.groupCallCreationRequested()
+ background: Rectangle {
+ anchors.fill: parent
+ radius: Math.round(50 * DefaultStyle.dp)
+ gradient: Gradient {
+ orientation: Gradient.Horizontal
+ GradientStop { position: 0.0; color: DefaultStyle.main2_100}
+ GradientStop { position: 1.0; color: DefaultStyle.grey_0}
+ }
+ }
+ contentItem: RowLayout {
+ spacing: Math.round(16 * DefaultStyle.dp)
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: AppIcons.groupCall
+ Layout.preferredWidth: Math.round(44 * DefaultStyle.dp)
+ sourceSize.width: Math.round(44 * DefaultStyle.dp)
+ fillMode: Image.PreserveAspectFit
+ }
+ Text {
+ text: qsTr("call_start_group_call_title")
+ color: DefaultStyle.grey_1000
+ font {
+ pixelSize: Typography.h4.pixelSize
+ weight: Typography.h4.weight
+ }
+ }
+ Item {
+ Layout.fillWidth: true
+ }
+ EffectImage {
+ imageSource: AppIcons.rightArrow
+ Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
+ Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
+ colorizationColor: DefaultStyle.main2_500main
+ }
+ }
+ }
+ AllContactListView{
+ id: contactList
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ showContactMenu: false
+ searchBarText: searchBar.text
+ onContactSelected: (contact) => {
+ mainItem.contactClicked(contact)
+ }
+ }
+ }
+ }
+ }
}