mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-11-04 08:10:18 +08:00
Compare commits
6 Commits
beta/20250
...
stable/202
| Author | SHA1 | Date | |
|---|---|---|---|
| bd3552a049 | |||
| 03bcd905e5 | |||
| 9bfd149d45 | |||
| 6c5ab1e483 | |||
| faba758254 | |||
| d8f548261d |
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>
|
||||
|
||||
@ -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