From d234a6c3d417872274ad1529280f069d8cfd8a85 Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Fri, 30 Jan 2026 16:17:21 +0100 Subject: [PATCH] check if safe connection is being destroyed before trying lock Add apply button and success/error toast for managing chatroom participants debug logs --- Linphone/core/chat/ChatCore.cpp | 13 +++-- Linphone/core/chat/ChatCore.hpp | 1 + Linphone/data/languages/de.ts | 52 ++++++++++++++----- Linphone/data/languages/en.ts | 52 ++++++++++++++----- Linphone/data/languages/fr.ts | 52 ++++++++++++++----- Linphone/model/chat/ChatModel.cpp | 12 +++-- Linphone/model/chat/ChatModel.hpp | 3 +- Linphone/tool/thread/SafeConnection.hpp | 3 +- .../Page/Layout/Chat/ManageParticipants.qml | 25 ++++++++- 9 files changed, 168 insertions(+), 45 deletions(-) diff --git a/Linphone/core/chat/ChatCore.cpp b/Linphone/core/chat/ChatCore.cpp index 27e3ef7b4..cf2180e09 100644 --- a/Linphone/core/chat/ChatCore.cpp +++ b/Linphone/core/chat/ChatCore.cpp @@ -231,10 +231,8 @@ void ChatCore::setSelf(const QSharedPointer &me) { return; } if (mChatModel->getMonitor() != chatRoom) return; - lDebug() << log().arg("CHAT MESSAGE RECEIVED IN CHATROOM") << this << mChatModel->getTitle(); lInfo() << log().arg("Chat message received in chatroom") << this << mChatModel->getTitle(); - lInfo() << log().arg("Safe Connection =") << mChatModelConnection.get(); - lInfo() << log().arg("this =") << this; + lInfo() << log().arg("Connection =") << mChatModelConnection.get(); QList> list; for (auto &e : eventsLog) { if (!e) { @@ -391,6 +389,15 @@ void ChatCore::setSelf(const QSharedPointer &me) { setMeAdmin(meAdmin); }); }); + mChatModelConnection->makeConnectToModel( + &ChatModel::participantAddressesChanged, + [this](const std::shared_ptr &chatRoom, bool success) { + if (!success) { + auto participants = buildParticipants(chatRoom); + mChatModelConnection->invokeToCore([this, participants] { setParticipants(participants); }); + } + mChatModelConnection->invokeToCore([this, success] { emit participantAddressesChanged(success); }); + }); mChatModelConnection->makeConnectToCore(&ChatCore::lRemoveParticipantAtIndex, [this](int index) { mChatModelConnection->invokeToModel([this, index]() { mChatModel->removeParticipantAtIndex(index); }); }); diff --git a/Linphone/core/chat/ChatCore.hpp b/Linphone/core/chat/ChatCore.hpp index d8100cd79..992009cad 100644 --- a/Linphone/core/chat/ChatCore.hpp +++ b/Linphone/core/chat/ChatCore.hpp @@ -175,6 +175,7 @@ signals: void fileListChanged(); void isSecuredChanged(); void conferenceJoined(); + void participantAddressesChanged(bool success); void lDeleteMessage(ChatMessageGui *message); void lDelete(); diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index ddcdc28ae..8d3a2c0c5 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -2472,44 +2472,44 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message Nachricht suchen - + info_popup_no_result_message No result found Keine Ergebnisse gefunden - + info_popup_first_result_message First result reached Erstes Ergebnis erreicht - + info_popup_last_result_message Last result reached Letztes Ergebnis erreicht - + chat_message_list_encrypted_header_title End to end encrypted chat Ende-zu-Ende-verschlüsselter Chat - + unencrypted_conversation_warning This conversation is not encrypted ! Dieser Chat ist nicht verschlüsselt! - + chat_message_list_encrypted_header_message Messages in this conversation are e2e encrypted. Only your correspondent can decrypt them. @@ -2517,7 +2517,7 @@ Error Nur Ihr Gesprächspartner kann sie entschlüsseln. - + chat_message_list_not_encrypted_header_message Messages are not end to end encrypted, may sure you don't share any sensitive information ! @@ -2525,7 +2525,7 @@ Nur Ihr Gesprächspartner kann sie entschlüsseln. Stellen Sie sicher, dass Sie keine sensiblen Informationen teilen! - + chat_message_is_writing_info %1 is writing… %1 schreibt… @@ -4362,7 +4362,7 @@ Ablauf: %1 MagicSearchList - + device_id Telefon @@ -4606,10 +4606,38 @@ Ablauf: %1 ManageParticipants - + + info_popup_error_title + Fehler + + + + info_popup_manage_participant_error_message + Error while setting participants ! + + + + + info_popup_success_title + + + + + info_popup_manage_participant_updated_message + Participants updated + + + + group_infos_manage_participants Teilnehmer + + + apply_button_text + Apply + + MeetingForm diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index 0868d4d70..f89595b8b 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -2430,44 +2430,44 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message Find message - + info_popup_no_result_message No result found No result found - + info_popup_first_result_message First result reached First result reached - + info_popup_last_result_message Last result reached Last result reached - + chat_message_list_encrypted_header_title End to end encrypted chat End to end encrypted chat - + unencrypted_conversation_warning This conversation is not encrypted ! This conversation is not encrypted ! - + chat_message_list_encrypted_header_message Messages in this conversation are e2e encrypted. Only your correspondent can decrypt them. @@ -2475,7 +2475,7 @@ Error Only your correspondent can decrypt them. - + chat_message_list_not_encrypted_header_message Messages are not end to end encrypted, may sure you don't share any sensitive information ! @@ -2483,7 +2483,7 @@ Only your correspondent can decrypt them. may sure you don't share any sensitive information ! - + chat_message_is_writing_info %1 is writing… %1 is writing… @@ -4260,7 +4260,7 @@ Expiration : %1 MagicSearchList - + device_id Phone @@ -4504,10 +4504,38 @@ Expiration : %1 ManageParticipants - + + info_popup_error_title + Error + + + + info_popup_manage_participant_error_message + Error while setting participants ! + + + + + info_popup_success_title + + + + + info_popup_manage_participant_updated_message + Participants updated + + + + group_infos_manage_participants Participants + + + apply_button_text + Apply + + MeetingForm diff --git a/Linphone/data/languages/fr.ts b/Linphone/data/languages/fr.ts index bb3004257..5050aa80d 100644 --- a/Linphone/data/languages/fr.ts +++ b/Linphone/data/languages/fr.ts @@ -2405,44 +2405,44 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message Trouver un message - + info_popup_no_result_message No result found Aucun résultat trouvé - + info_popup_first_result_message First result reached Premier résultat atteint - + info_popup_last_result_message Last result reached Dernier résultat atteint - + chat_message_list_encrypted_header_title End to end encrypted chat Conversation chiffrée de bout en bout - + unencrypted_conversation_warning This conversation is not encrypted ! Cette conversation n'est pas chiffrée ! - + chat_message_list_encrypted_header_message Messages in this conversation are e2e encrypted. Only your correspondent can decrypt them. @@ -2450,7 +2450,7 @@ Error en bout. Seul votre correspondant peut les déchiffrer. - + chat_message_list_not_encrypted_header_message Messages are not end to end encrypted, may sure you don't share any sensitive information ! @@ -2458,7 +2458,7 @@ en bout. Seul votre correspondant peut les déchiffrer. assurez-vous de ne pas partager d’informations sensibles ! - + chat_message_is_writing_info %1 is writing… %1 est en train d'écrire… @@ -4235,7 +4235,7 @@ Expiration : %1 MagicSearchList - + device_id Téléphone @@ -4475,10 +4475,38 @@ Expiration : %1 ManageParticipants - + + info_popup_error_title + Erreur + + + + info_popup_manage_participant_error_message + Error while setting participants ! + Erreur lors de la modification des participants ! + + + + info_popup_success_title + Enregistré + + + + info_popup_manage_participant_updated_message + Participants updated + Participants mis à jour + + + group_infos_manage_participants Participants + + + apply_button_text + Apply + Appliquer + MeetingForm diff --git a/Linphone/model/chat/ChatModel.cpp b/Linphone/model/chat/ChatModel.cpp index 88bd69e07..9a982e822 100644 --- a/Linphone/model/chat/ChatModel.cpp +++ b/Linphone/model/chat/ChatModel.cpp @@ -232,17 +232,23 @@ void ChatModel::toggleParticipantAdminStatusAtIndex(int index) const { mMonitor->setParticipantAdminStatus(participant, !participant->isAdmin()); } -void ChatModel::setParticipantAddresses(const QStringList &addresses) const { +void ChatModel::setParticipantAddresses(const QStringList &addresses) { QSet s{addresses.cbegin(), addresses.cend()}; + bool soFarSoGood = true; for (auto p : mMonitor->getParticipants()) { auto address = Utils::coreStringToAppString(p->getAddress()->asStringUriOnly()); if (s.contains(address)) s.remove(address); - else mMonitor->removeParticipant(p); + else { + mMonitor->removeParticipants({p}); + } } for (const auto &a : s) { auto address = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(a)); - if (address) mMonitor->addParticipant(address); + if (address) { + soFarSoGood &= mMonitor->addParticipants({address}); + } } + emit participantAddressesChanged(mMonitor, soFarSoGood); } //---------------------------------------------------------------// diff --git a/Linphone/model/chat/ChatModel.hpp b/Linphone/model/chat/ChatModel.hpp index 9ed20975f..93c78b5de 100644 --- a/Linphone/model/chat/ChatModel.hpp +++ b/Linphone/model/chat/ChatModel.hpp @@ -83,7 +83,7 @@ public: void setEphemeralLifetime(int time); void setSubject(QString subject) const; void removeParticipantAtIndex(int index) const; - void setParticipantAddresses(const QStringList &addresses) const; + void setParticipantAddresses(const QStringList &addresses); void toggleParticipantAdminStatusAtIndex(int index) const; signals: @@ -93,6 +93,7 @@ signals: void mutedChanged(bool muted); void ephemeralEnableChanged(bool enable); void ephemeralLifetimeChanged(int time); + void participantAddressesChanged(const std::shared_ptr &chatRoom, bool success); private: DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/tool/thread/SafeConnection.hpp b/Linphone/tool/thread/SafeConnection.hpp index 854c67934..e6b28e17f 100644 --- a/Linphone/tool/thread/SafeConnection.hpp +++ b/Linphone/tool/thread/SafeConnection.hpp @@ -66,7 +66,7 @@ template class SafeConnection : public QObject { // Use create functions. protected: - SafeConnection(const QSharedPointer &a, std::shared_ptr b) + SafeConnection(QSharedPointer a, std::shared_ptr b) : mCore(a), mModel(b), mCoreObject(a.get()), mModelObject(b.get()) { } SafeConnection(QSharedPointer a, QSharedPointer b) @@ -150,6 +150,7 @@ public: } bool tryLock() { + if (!this) return false; mLocker.lock(); auto coreLocked = mCore.lock(); auto modelLocked = mModel.lock(); diff --git a/Linphone/view/Page/Layout/Chat/ManageParticipants.qml b/Linphone/view/Page/Layout/Chat/ManageParticipants.qml index 9962e331d..6a37f6dbe 100644 --- a/Linphone/view/Page/Layout/Chat/ManageParticipants.qml +++ b/Linphone/view/Page/Layout/Chat/ManageParticipants.qml @@ -22,6 +22,22 @@ Rectangle { height: participantAddColumn.implicitHeight signal done() + Connections { + enabled: chatGui !== null + target: chatGui.core + function onParticipantAddressesChanged(success) { + if (!success) UtilsCpp.showInformationPopup(qsTr("info_popup_error_title"), + //: Error while setting participants ! + qsTr("info_popup_manage_participant_error_message"), false) + else { + mainItem.done() + UtilsCpp.showInformationPopup(qsTr("info_popup_success_title"), + //: Participants updated + qsTr("info_popup_manage_participant_updated_message"), true) + } + } + } + ColumnLayout { id: participantAddColumn anchors.fill: parent @@ -36,7 +52,6 @@ Rectangle { style: ButtonStyle.noBackground icon.source: AppIcons.leftArrow onClicked: { - mainItem.chatGui.core.lSetParticipantsAddresses(manageParticipantsLayout.selectedParticipants) mainItem.done() } } @@ -47,6 +62,14 @@ Rectangle { font: Typography.h4 Layout.fillWidth: true } + MediumButton { + id: manageParticipantsApplyButton + //: Apply + text: qsTr("apply_button_text") + onClicked: { + mainItem.chatGui.core.lSetParticipantsAddresses(manageParticipantsLayout.selectedParticipants) + } + } } AddParticipantsForm { id: manageParticipantsLayout