From c52d288c769b9aa5fdfc755a0df731aa51069dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Fri, 17 Dec 2021 15:52:30 -0500 Subject: [PATCH] messagesadapter: add kick member GitLab: #340 Change-Id: I4cfdc6392c8b6de573f8d4471b7b5501f393379b --- qml.qrc | 1 + src/constant/JamiStrings.qml | 5 + src/mainview/components/SwarmDetailsPanel.qml | 121 ++++++++++++------ .../SwarmParticipantContextMenu.qml | 76 +++++++++++ src/messagesadapter.cpp | 7 + src/messagesadapter.h | 1 + 6 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 src/mainview/components/SwarmParticipantContextMenu.qml diff --git a/qml.qrc b/qml.qrc index fd9a00373..2d10eef93 100644 --- a/qml.qrc +++ b/qml.qrc @@ -109,6 +109,7 @@ <file>src/mainview/components/SidePanelTabBar.qml</file> <file>src/mainview/components/WelcomePageQrDialog.qml</file> <file>src/mainview/components/ConversationSmartListContextMenu.qml</file> + <file>src/mainview/components/SwarmParticipantContextMenu.qml</file> <file>src/mainview/components/CallViewContextMenu.qml</file> <file>src/mainview/components/UserProfile.qml</file> <file>src/mainview/components/SwarmDetailsPanel.qml</file> diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml index 4a88a1ed8..bb1a7917e 100644 --- a/src/constant/JamiStrings.qml +++ b/src/constant/JamiStrings.qml @@ -623,4 +623,9 @@ Item { // NewSwarmPage property string createTheSwarm: qsTr("Create the swarm") + property string goToConversation: qsTr("Go to conversation") + property string promoteAdministrator: qsTr("Promote to administrator") + property string kickMember: qsTr("Kick member") + property string administrator: qsTr("Administrator") + property string invited: qsTr("Invited") } diff --git a/src/mainview/components/SwarmDetailsPanel.qml b/src/mainview/components/SwarmDetailsPanel.qml index 12bab5f76..8cac190c8 100644 --- a/src/mainview/components/SwarmDetailsPanel.qml +++ b/src/mainview/components/SwarmDetailsPanel.qml @@ -48,6 +48,8 @@ Rectangle { Layout.alignment: Qt.AlignCenter Layout.preferredWidth: JamiTheme.avatarSizeInCall Layout.preferredHeight: JamiTheme.avatarSizeInCall + Layout.topMargin: JamiTheme.swarmDetailsPageTopMargin + Layout.bottomMargin: JamiTheme.preferredMarginSize imageId: LRCInstance.selectedConvUid @@ -164,50 +166,97 @@ Rectangle { spacing: JamiTheme.preferredMarginSize anchors.topMargin: JamiTheme.preferredMarginSize - model: CurrentConversation.uris - delegate: RowLayout { - spacing: 10 + SwarmParticipantContextMenu { + id: contextMenu - Avatar { - width: JamiTheme.smartListAvatarSize - height: JamiTheme.smartListAvatarSize - z: -index + function openMenuAt(x, y, participantUri) { + contextMenu.x = x + contextMenu.y = y + contextMenu.conversationId = CurrentConversation.id + contextMenu.participantUri = participantUri - imageId: CurrentAccount.uri == modelData ? CurrentAccount.id : modelData - showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, modelData) - mode: CurrentAccount.uri == modelData ? Avatar.Mode.Account : Avatar.Mode.Contact + openMenu() } + } - ElidedTextLabel { - id: bestName - - Layout.preferredWidth: JamiTheme.preferredFieldWidth - Layout.preferredHeight: JamiTheme.preferredFieldHeight - - eText: UtilsAdapter.getContactBestName(CurrentAccount.id, modelData) - maxWidth: JamiTheme.preferredFieldWidth + model: CurrentConversation.uris + delegate: Item { - font.pointSize: JamiTheme.participantFontSize - color: JamiTheme.primaryForegroundColor - font.kerning: true + width: members.width + height: JamiTheme.smartListItemHeight - verticalAlignment: Text.AlignVCenter + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: function (mouse) { + contextMenu.openMenuAt(x + mouse.x, y + mouse.y, modelData) + } } - ElidedTextLabel { - id: role - - Layout.preferredHeight: JamiTheme.preferredFieldHeight - - eText: UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData) - maxWidth: JamiTheme.preferredFieldWidth - - font.pointSize: JamiTheme.participantFontSize - color: JamiTheme.textColorHovered - font.kerning: true - - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter + RowLayout { + spacing: 10 + + Avatar { + width: JamiTheme.smartListAvatarSize + height: JamiTheme.smartListAvatarSize + Layout.leftMargin: JamiTheme.preferredMarginSize + z: -index + opacity: { + var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData) + return role === Member.Role.INVITED ? 0.5 : 1 + } + + imageId: CurrentAccount.uri == modelData ? CurrentAccount.id : modelData + showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, modelData) + mode: CurrentAccount.uri == modelData ? Avatar.Mode.Account : Avatar.Mode.Contact + } + + ElidedTextLabel { + id: bestName + + Layout.preferredWidth: JamiTheme.preferredFieldWidth + Layout.preferredHeight: JamiTheme.preferredFieldHeight + + eText: UtilsAdapter.getContactBestName(CurrentAccount.id, modelData) + maxWidth: JamiTheme.preferredFieldWidth + + font.pointSize: JamiTheme.participantFontSize + color: JamiTheme.primaryForegroundColor + opacity: { + var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData) + return role === Member.Role.INVITED ? 0.5 : 1 + } + font.kerning: true + + verticalAlignment: Text.AlignVCenter + } + + ElidedTextLabel { + id: role + + Layout.preferredHeight: JamiTheme.preferredFieldHeight + + eText: { + var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData) + if (role === Member.Role.ADMIN) + return JamiStrings.administrator + if (role === Member.Role.INVITED) + return JamiStrings.invited + return "" + } + maxWidth: JamiTheme.preferredFieldWidth + + font.pointSize: JamiTheme.participantFontSize + color: JamiTheme.textColorHovered + opacity: { + var role = UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, modelData) + return role === Member.Role.INVITED ? 0.5 : 1 + } + font.kerning: true + + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } } } } diff --git a/src/mainview/components/SwarmParticipantContextMenu.qml b/src/mainview/components/SwarmParticipantContextMenu.qml new file mode 100644 index 000000000..17f0df985 --- /dev/null +++ b/src/mainview/components/SwarmParticipantContextMenu.qml @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 by Savoir-faire Linux + * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +import QtQuick + +import net.jami.Models 1.1 +import net.jami.Adapters 1.1 +import net.jami.Constants 1.1 + +import "../../commoncomponents" +import "../../commoncomponents/contextmenu" + +ContextMenuAutoLoader { + id: root + property var conversationId: "" + property var participantUri: "" + + // TODO get authorization + + property list<GeneralMenuItem> menuItems: [ + GeneralMenuItem { + id: startVideoCallItem + itemName: JamiStrings.startVideoCall + onClicked: { + } + }, + GeneralMenuItem { + id: startAudioCall + itemName: JamiStrings.startAudioCall + onClicked: { + } + }, + GeneralMenuItem { + id: goToConversation + + itemName: JamiStrings.goToConversation + onClicked: { + } + }, + GeneralMenuItem { + id: promoteAdministrator + itemName: JamiStrings.promoteAdministrator + }, + GeneralMenuItem { + id: blockContact + itemName: JamiStrings.blockContact + iconSource: JamiResources.block_black_24dp_svg + }, + GeneralMenuItem { + id: kickMember + itemName: JamiStrings.kickMember + + // TODO can trigger (enough permission for self and member accepted) + onClicked: { + MessagesAdapter.removeConversationMember(conversationId, participantUri) + } + } + ] + + Component.onCompleted: menuItemsToLoad = menuItems +} diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp index 64ed54c7f..fb4a4c0a8 100644 --- a/src/messagesadapter.cpp +++ b/src/messagesadapter.cpp @@ -384,6 +384,13 @@ MessagesAdapter::removeConversation(const QString& convUid) accInfo.conversationModel->removeConversation(convUid); } +void +MessagesAdapter::removeConversationMember(const QString& convUid, const QString& memberUri) +{ + auto& accInfo = lrcInstance_->getCurrentAccountInfo(); + accInfo.conversationModel->removeConversationMember(convUid, memberUri); +} + void MessagesAdapter::removeContact(const QString& convUid, bool banContact) { diff --git a/src/messagesadapter.h b/src/messagesadapter.h index c64cef545..1840cb6aa 100644 --- a/src/messagesadapter.h +++ b/src/messagesadapter.h @@ -85,6 +85,7 @@ protected: Q_INVOKABLE void connectConversationModel(); Q_INVOKABLE void sendConversationRequest(); Q_INVOKABLE void removeConversation(const QString& convUid); + Q_INVOKABLE void removeConversationMember(const QString& convUid, const QString& participantUri); Q_INVOKABLE void removeContact(const QString& convUid, bool banContact = false); Q_INVOKABLE void clearConversationHistory(const QString& accountId, const QString& convUid); Q_INVOKABLE void acceptInvitation(const QString& convId = {}); -- GitLab