mirror of
				https://git.jami.net/savoirfairelinux/jami-client-qt.git
				synced 2025-10-30 07:53:33 +08:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			ca02cf172a
			...
			bd3552a049
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bd3552a049 | |||
| 03bcd905e5 | |||
| 9bfd149d45 | |||
| 6c5ab1e483 | |||
| faba758254 | |||
| d8f548261d | |||
| fe504827fa | 
							
								
								
									
										2
									
								
								daemon
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								daemon
									
									
									
									
									
								
							 Submodule daemon updated: c53658e211...ce82bdbbf3
									
								
							| @ -87,12 +87,27 @@ | ||||
|   </developer> | ||||
|  | ||||
|   <releases> | ||||
|     <release version="20250912.0" date="2025-09-12"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250912</url> | ||||
|     </release> | ||||
|     <release version="20250815.1" date="2025-08-17"> | ||||
|       <url type="detials">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#stable-20250817</url> | ||||
|     </release> | ||||
|     <release version="20250718.0" date="2025-07-18"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250718</url> | ||||
|     </release> | ||||
|     <release version="20250613.0" date="2025-06-13"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250613</url> | ||||
|     </release> | ||||
|     <release version="20250610.0" date="2025-06-10"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250610</url> | ||||
|     </release> | ||||
|     <release version="20250523.0" date="2025-05-23"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250523</url> | ||||
|     </release> | ||||
|     <release version="20250430.1" date="2025-04-30"> | ||||
|       <url type="details">https://git.jami.net/savoirfairelinux/jami-client-qt/-/wikis/Changelog#nightlystable-20250430</url> | ||||
|     </release> | ||||
|   </releases> | ||||
|  | ||||
|   <branding> | ||||
|  | ||||
| @ -129,6 +129,11 @@ else | ||||
|     BUILD_DIR="build" | ||||
| fi | ||||
|  | ||||
| BUILD_TYPE="Release" | ||||
| if [ "${debug}" = "true" ]; then | ||||
|   BUILD_TYPE="Debug" | ||||
| fi | ||||
|  | ||||
| if [[ "$OSTYPE" == "darwin"* ]]; then | ||||
|     #detect arch for macos | ||||
|     CMAKE_OSX_ARCHITECTURES="arm64" | ||||
|  | ||||
| @ -45,6 +45,7 @@ Rectangle { | ||||
|     color: JamiTheme.chatviewBgColor | ||||
|  | ||||
|     property var mapPositions: PositionManager.mapStatus | ||||
|     property bool isConversationEndedFlag: false | ||||
|  | ||||
|     // The purpose of this alias is to make the message bar | ||||
|     // accessible to the EmojiPicker | ||||
| @ -85,6 +86,32 @@ Rectangle { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function isConversationEnded() { | ||||
|         if (!CurrentConversation.isSwarm) | ||||
|             return false; | ||||
|         var myRole = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, CurrentAccount.uri); | ||||
|         var info = ConversationsAdapter.getConvInfoMap(CurrentConversation.id); | ||||
|         var peers = info && info.uris ? info.uris : []; | ||||
|         peers = peers.filter(function(u) { return u !== CurrentAccount.uri; }); | ||||
|         for (var i = 0; i < peers.length; i++) { | ||||
|             var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, peers[i]); | ||||
|             if (!(role === Member.Role.LEFT || role === Member.Role.BANNED)) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         if (CurrentConversation.isCoreDialog) { | ||||
|             return true | ||||
|         } | ||||
|         return myRole !== Member.Role.ADMIN; | ||||
|     } | ||||
|  | ||||
|     function updateConversationEndedFlag() { | ||||
|         var newVal = isConversationEnded(); | ||||
|         if (isConversationEndedFlag !== newVal) { | ||||
|             isConversationEndedFlag = newVal; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Used externally to switch to a extras panel. | ||||
|     function switchToPanel(panel, toggle = true) { | ||||
|         extrasPanel.switchToPanel(panel, toggle); | ||||
| @ -102,16 +129,33 @@ Rectangle { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Connections { | ||||
|         target: LRCInstance | ||||
|         function onConversationUpdated(convId, accountId) { | ||||
|             if (convId === CurrentConversation.id) { | ||||
|                 updateConversationEndedFlag(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     Connections { | ||||
|         target: CurrentConversation.members | ||||
|         function onCountChanged() { | ||||
|             updateConversationEndedFlag(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Connections { | ||||
|         target: CurrentConversation | ||||
|         function onIdChanged() { | ||||
|             MessagesAdapter.loadMoreMessages(); | ||||
|             updateConversationEndedFlag(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onVisibleChanged: { | ||||
|         if (visible) { | ||||
|             chatViewSplitView.resolvePanes(true); | ||||
|             Qt.callLater(updateConversationEndedFlag); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -196,6 +240,29 @@ Rectangle { | ||||
|             visible: false | ||||
|         } | ||||
|  | ||||
|         Control { | ||||
|             id: conversationEndedBanner | ||||
|             Layout.fillWidth: true | ||||
|             visible: isConversationEndedFlag | ||||
|  | ||||
|             padding: 10 | ||||
|             background: Rectangle { | ||||
|                 color: JamiTheme.infoRectangleColor | ||||
|                 radius: 5 | ||||
|             } | ||||
|             contentItem: RowLayout { | ||||
|                 spacing: 8 | ||||
|                 Label { | ||||
|                     text: JamiStrings.conversationEnded | ||||
|                     color: JamiTheme.textColor | ||||
|                     wrapMode: Text.WordWrap | ||||
|                     horizontalAlignment: Text.AlignHCenter | ||||
|                     Layout.alignment: Qt.AlignHCenter | ||||
|                     Layout.fillWidth: true | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         NotificationArea { | ||||
|             id: notificationArea | ||||
|             Layout.fillWidth: true | ||||
| @ -333,6 +400,8 @@ Rectangle { | ||||
|                             return false; | ||||
|                         else if (CurrentConversation.isRequest) | ||||
|                             return false; | ||||
|                         else if (isConversationEndedFlag) | ||||
|                             return false; | ||||
|                         return CurrentConversation.isSwarm || CurrentConversation.isTemporary; | ||||
|                     } | ||||
|  | ||||
|  | ||||
| @ -73,28 +73,37 @@ ContextMenuAutoLoader { | ||||
|             onClicked: MessagesAdapter.clearConversationHistory(responsibleAccountId, responsibleConvUid) | ||||
|         }, | ||||
|         GeneralMenuItem { | ||||
|             id: removeContact | ||||
|             id: removeConversation | ||||
|  | ||||
|             canTrigger: !hasCall && !root.isBanned | ||||
|             itemName: { | ||||
|                 if (mode !== Conversation.Mode.NON_SWARM) | ||||
|                     return JamiStrings.removeConversation; | ||||
|                 else | ||||
|                     return JamiStrings.removeContact; | ||||
|             } | ||||
|             itemName: mode === Conversation.Mode.ONE_TO_ONE ? JamiStrings.removeConversation : JamiStrings.leaveGroup | ||||
|             iconSource: JamiResources.ic_hangup_participant_24dp_svg | ||||
|             onClicked: { | ||||
|                 var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", { | ||||
|                         "title": JamiStrings.confirmAction, | ||||
|                         "textLabel": JamiStrings.confirmLeaveConversation, | ||||
|                         "confirmLabel": JamiStrings.optionLeave | ||||
|                     }); | ||||
|                     "title": JamiStrings.confirmAction, | ||||
|                     "textLabel": mode === Conversation.Mode.ONE_TO_ONE ? JamiStrings.confirmRemoveOneToOneConversation : JamiStrings.confirmLeaveGroup, | ||||
|                     "confirmLabel": mode === Conversation.Mode.ONE_TO_ONE ? JamiStrings.optionRemove : JamiStrings.optionLeave | ||||
|                 }); | ||||
|                 dlg.accepted.connect(function () { | ||||
|                         if (mode !== Conversation.Mode.NON_SWARM) | ||||
|                             MessagesAdapter.removeConversation(responsibleConvUid); | ||||
|                         else | ||||
|                             MessagesAdapter.removeContact(responsibleConvUid); | ||||
|                     }); | ||||
|                     MessagesAdapter.removeConversation(responsibleConvUid, true); | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         GeneralMenuItem { | ||||
|             id: removeContact | ||||
|  | ||||
|             canTrigger: !hasCall && !root.isBanned && mode === Conversation.Mode.ONE_TO_ONE | ||||
|             itemName: JamiStrings.removeContact | ||||
|             iconSource: JamiResources.kick_member_svg | ||||
|             onClicked: { | ||||
|                 var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", { | ||||
|                     "title": JamiStrings.confirmAction, | ||||
|                     "textLabel": JamiStrings.confirmRemoveContact, | ||||
|                     "confirmLabel": JamiStrings.optionRemove | ||||
|                 }); | ||||
|                 dlg.accepted.connect(function () { | ||||
|                     MessagesAdapter.removeContact(responsibleConvUid); | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         GeneralMenuItem { | ||||
| @ -129,13 +138,13 @@ ContextMenuAutoLoader { | ||||
|             iconSource: JamiResources.block_black_24dp_svg | ||||
|             onClicked: { | ||||
|                 var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", { | ||||
|                         "title": JamiStrings.confirmAction, | ||||
|                         "textLabel": JamiStrings.confirmBlockConversation, | ||||
|                         "confirmLabel": JamiStrings.optionBlock | ||||
|                     }); | ||||
|                     "title": JamiStrings.confirmAction, | ||||
|                     "textLabel": JamiStrings.confirmBlockContact, | ||||
|                     "confirmLabel": JamiStrings.optionBlock | ||||
|                 }); | ||||
|                 dlg.accepted.connect(function () { | ||||
|                         MessagesAdapter.blockConversation(responsibleConvUid); | ||||
|                     }); | ||||
|                     MessagesAdapter.blockConversation(responsibleConvUid); | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         GeneralMenuItem { | ||||
| @ -155,11 +164,11 @@ ContextMenuAutoLoader { | ||||
|             onClicked: { | ||||
|                 if (isCoreDialog) { | ||||
|                     viewCoordinator.presentDialog(appWindow, "mainview/components/UserProfile.qml", { | ||||
|                             "aliasText": aliasText, | ||||
|                             "registeredNameText": registeredNameText, | ||||
|                             "idText": idText, | ||||
|                             "convId": responsibleConvUid | ||||
|                         }); | ||||
|                         "aliasText": aliasText, | ||||
|                         "registeredNameText": registeredNameText, | ||||
|                         "idText": idText, | ||||
|                         "convId": responsibleConvUid | ||||
|                     }); | ||||
|                 } else { | ||||
|                     root.showSwarmDetails(); | ||||
|                 } | ||||
|  | ||||
| @ -297,7 +297,7 @@ Rectangle { | ||||
|                             anchors.right: parent.right | ||||
|                             anchors.top: parent.top | ||||
|                             anchors.margins: JamiTheme.preferredMarginSize | ||||
|                             text: JamiStrings.leaveConversation | ||||
|                             text: CurrentConversation.modeString.indexOf("group") >= 0 ? JamiStrings.leaveGroup : JamiStrings.removeConversation | ||||
|                             font.pixelSize: JamiTheme.settingsDescriptionPixelSize | ||||
|                             font.kerning: true | ||||
|                             elide: Text.ElideRight | ||||
| @ -312,13 +312,49 @@ Rectangle { | ||||
|                             enabled: parent.visible | ||||
|                             onTapped: function onTapped(eventPoint) { | ||||
|                                 var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", { | ||||
|                                         "title": JamiStrings.confirmAction, | ||||
|                                         "textLabel": JamiStrings.confirmLeaveConversation, | ||||
|                                         "confirmLabel": JamiStrings.optionLeave | ||||
|                                     }); | ||||
|                                     "title": JamiStrings.confirmAction, | ||||
|                                     "textLabel": CurrentConversation.modeString.indexOf("group") >= 0 ? JamiStrings.confirmLeaveGroup : JamiStrings.confirmRemoveOneToOneConversation, | ||||
|                                     "confirmLabel": CurrentConversation.modeString.indexOf("group") >= 0 ? JamiStrings.optionLeave : JamiStrings.optionRemove | ||||
|                                 }); | ||||
|                                 dlg.accepted.connect(function () { | ||||
|                                         MessagesAdapter.removeConversation(LRCInstance.selectedConvUid); | ||||
|                                     }); | ||||
|                                     MessagesAdapter.removeConversation(LRCInstance.selectedConvUid, true); | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     SwarmDetailsItem { | ||||
|                         Layout.fillWidth: true | ||||
|                         Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4 | ||||
|                         visible: CurrentConversation.isCoreDialog | ||||
|  | ||||
|                         Text { | ||||
|                             anchors.left: parent.left | ||||
|                             anchors.right: parent.right | ||||
|                             anchors.top: parent.top | ||||
|                             anchors.margins: JamiTheme.preferredMarginSize | ||||
|                             text: JamiStrings.removeContact | ||||
|                             font.pixelSize: JamiTheme.settingsDescriptionPixelSize | ||||
|                             font.kerning: true | ||||
|                             elide: Text.ElideRight | ||||
|                             horizontalAlignment: Text.AlignLeft | ||||
|                             verticalAlignment: Text.AlignVCenter | ||||
|  | ||||
|                             color: JamiTheme.textColor | ||||
|                         } | ||||
|  | ||||
|                         TapHandler { | ||||
|                             target: parent | ||||
|                             enabled: parent.visible | ||||
|                             onTapped: function onTapped(eventPoint) { | ||||
|                                 var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", { | ||||
|                                     "title": JamiStrings.confirmAction, | ||||
|                                     "textLabel": JamiStrings.confirmRemoveContact, | ||||
|                                     "confirmLabel": JamiStrings.optionRemove | ||||
|                                 }); | ||||
|                                 dlg.accepted.connect(function () { | ||||
|                                     MessagesAdapter.removeConversation(LRCInstance.selectedConvUid); | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| @ -500,8 +536,6 @@ Rectangle { | ||||
|                             verticalAlignment: Text.AlignVCenter | ||||
|  | ||||
|                             color: JamiTheme.textColor | ||||
|  | ||||
|  | ||||
|                         } | ||||
|  | ||||
|                         Text { | ||||
|  | ||||
| @ -480,10 +480,10 @@ MessagesAdapter::clearConversationHistory(const QString& accountId, const QStrin | ||||
| } | ||||
|  | ||||
| void | ||||
| MessagesAdapter::removeConversation(const QString& convUid) | ||||
| MessagesAdapter::removeConversation(const QString& convUid, bool keepContact) | ||||
| { | ||||
|     auto& accInfo = lrcInstance_->getCurrentAccountInfo(); | ||||
|     accInfo.conversationModel->removeConversation(convUid); | ||||
|     accInfo.conversationModel->removeConversation(convUid, false, keepContact); | ||||
| } | ||||
|  | ||||
| void | ||||
|  | ||||
| @ -113,7 +113,7 @@ public: | ||||
|     Q_INVOKABLE void loadMoreMessages(); | ||||
|     Q_INVOKABLE void connectConversationModel(); | ||||
|     Q_INVOKABLE void sendConversationRequest(); | ||||
|     Q_INVOKABLE void removeConversation(const QString& convUid); | ||||
|     Q_INVOKABLE void removeConversation(const QString& convUid, bool keepContact = false); | ||||
|     Q_INVOKABLE void addConversationMember(const QString& convUid, const QString& participantUri); | ||||
|     Q_INVOKABLE void removeConversationMember(const QString& convUid, const QString& participantUri); | ||||
|     Q_INVOKABLE void removeContact(const QString& convUid, bool banContact = false); | ||||
|  | ||||
| @ -282,9 +282,13 @@ Item { | ||||
|     property string startVideoCall: qsTr("Start video call") | ||||
|     property string deleteConversation: qsTr("Delete conversation") | ||||
|     property string confirmAction: qsTr("Confirm action") | ||||
|     property string removeConversation: qsTr("Leave conversation") | ||||
|     property string confirmLeaveConversation: qsTr("Do you want to leave this conversation?") | ||||
|     property string confirmBlockConversation: qsTr("Do you want to block this conversation?") | ||||
|     property string removeConversation: qsTr("Remove conversation") | ||||
|     property string confirmRemoveConversation: qsTr("Do you want to leave this conversation?") | ||||
|     property string leaveGroup: qsTr("Leave group") | ||||
|     property string confirmLeaveGroup: qsTr("Are you sure you want to leave this group?") | ||||
|     property string confirmRemoveContact: qsTr("Do you want to remove this contact? The existing conversation will be deleted.") | ||||
|     property string confirmBlockContact: qsTr("Do you want to block this contact?") | ||||
|     property string confirmRemoveOneToOneConversation: qsTr("Are you sure you want to remove this conversation? The contact will not be removed.") | ||||
|     property string removeContact: qsTr("Remove contact") | ||||
|     property string blockContact: qsTr("Block contact") | ||||
|     property string convDetails: qsTr("Conversation details") | ||||
| @ -366,6 +370,9 @@ Item { | ||||
|     property string deletedMedia: qsTr("%1 deleted a media") | ||||
|     property string returnToCall: qsTr("Return to call") | ||||
|  | ||||
|     // Conversation ended banner | ||||
|     property string conversationEnded: qsTr("This conversation has ended.") | ||||
|  | ||||
|     // MessagesResearch | ||||
|     property string jumpTo: qsTr("Jump to") | ||||
|     property string messages: qsTr("Messages") | ||||
| @ -828,7 +835,6 @@ Item { | ||||
|     property string ignoreNotificationsTooltip: qsTr("Ignore all notifications from this conversation") | ||||
|     property string chooseAColor: qsTr("Color") | ||||
|     property string defaultCallHost: qsTr("Default host (calls)") | ||||
|     property string leaveConversation: qsTr("Leave conversation") | ||||
|     property string typeOfSwarm: qsTr("Conversation type") | ||||
|     property string none: qsTr("None") | ||||
|  | ||||
|  | ||||
| @ -191,8 +191,9 @@ public: | ||||
|      * Remove a conversation and the contact if it's a dialog | ||||
|      * @param uid of the conversation | ||||
|      * @param banned if we want to ban the contact. | ||||
|      * @param keepContact if we want to keep the contact. New conversation could be created | ||||
|      */ | ||||
|     void removeConversation(const QString& uid, bool banned = false); | ||||
|     void removeConversation(const QString& uid, bool banned = false,  bool keepContact = false); | ||||
|     /** | ||||
|      * Get the action wanted by the user when they click on the conversation | ||||
|      * @param uid of the conversation | ||||
|  | ||||
| @ -819,7 +819,7 @@ ConversationModel::selectConversation(const QString& uid) const | ||||
| } | ||||
|  | ||||
| void | ||||
| ConversationModel::removeConversation(const QString& uid, bool banned) | ||||
| ConversationModel::removeConversation(const QString& uid, bool banned, bool keepContact) | ||||
| { | ||||
|     // Get conversation | ||||
|     auto conversationIdx = pimpl_->indexOf(uid); | ||||
| @ -837,7 +837,7 @@ ConversationModel::removeConversation(const QString& uid, bool banned) | ||||
|                     "participant."; | ||||
|         return; | ||||
|     } | ||||
|     if (conversation.isSwarm() && !banned && !conversation.isCoreDialog()) { | ||||
|     if (conversation.isSwarm() && !banned && (!conversation.isCoreDialog() || keepContact)) { | ||||
|         if (conversation.isRequest) { | ||||
|             ConfigurationManager::instance().declineConversationRequest(owner.id, uid); | ||||
|         } else { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	