status-desktop/ui/app/AppLayouts/Chat/popups/GroupInfoPopup.qml

316 lines
10 KiB
QML
Raw Normal View History

2020-06-17 19:18:31 +00:00
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.views 1.0
import shared.panels 1.0
import shared.status 1.0
import "../panels"
2020-06-11 17:50:36 +00:00
StatusModal {
2020-06-11 17:50:36 +00:00
id: popup
fix: kick and re-invite user to group chat Fixes: #2601. Kicking a user and re-inviting them now correctly redisplays the join/decline options. Other combinations of User B leaving or declining an invitation are not handled. Please see the notes below for clarification. Additionally, the group invite popup (that shows the list of members belonging to the group) correctly shows when a user is kicked or when a user leaves the group in real time. Previously, the popup needed to be reopened to display this. fix: decline invitation crash Declining a group invitation was crashing the app. This has been fixed. ### NOTES 1. In the case where User A invites User B to a group, but User B declines (or User B joins, then leaves), then from a status-go standpoint, User B is still part of the group, but the chat is marked as `active: false` for User B. This creates a situation where User B cannot re-join the group once s/he has declined the invitation. @cammellos mentioned there possibly will need to be a refactor of https://github.com/status-im/status-go/blob/cab6281dc520c24912de5b5226b42a2f8415aa40/protocol/messenger.go#L1710 (which, by retaining User B as a member, effectively prevents the re-invitation) once “swipe to delete” is implemented on mobile. There is an activity center notification received for User B that is meant to allow re-joining of the group when the notification is accepted. The activity center notification received from status-go looks like the following: ```json "activityCenterNotifications": [ { "id": "0x0e342d33", "chatId": "e342d33f-dd05-4d7b-b14e-b5335e1a3ee9-0x043bf46aa874c377a34946eab67a32cf36c15907b328216dfce375d169fed7d81c21cada3229db1fd37c762d2c02702111a646657feca6621e2e948febcf378fb4", "name": "test-22", "type": 2, "lastMessage": null, "message": null, "timestamp": 1623305612000, "read": false, "dismissed": false, "accepted": false } ] ```
2021-06-10 07:29:05 +00:00
enum ChannelType {
ActiveChannel,
ContextChannel
}
property var store
property bool addMembers: false
property int currMemberCount: 1
property int memberCount: 1
readonly property int maxMembers: 10
property var pubKeys: []
fix: kick and re-invite user to group chat Fixes: #2601. Kicking a user and re-inviting them now correctly redisplays the join/decline options. Other combinations of User B leaving or declining an invitation are not handled. Please see the notes below for clarification. Additionally, the group invite popup (that shows the list of members belonging to the group) correctly shows when a user is kicked or when a user leaves the group in real time. Previously, the popup needed to be reopened to display this. fix: decline invitation crash Declining a group invitation was crashing the app. This has been fixed. ### NOTES 1. In the case where User A invites User B to a group, but User B declines (or User B joins, then leaves), then from a status-go standpoint, User B is still part of the group, but the chat is marked as `active: false` for User B. This creates a situation where User B cannot re-join the group once s/he has declined the invitation. @cammellos mentioned there possibly will need to be a refactor of https://github.com/status-im/status-go/blob/cab6281dc520c24912de5b5226b42a2f8415aa40/protocol/messenger.go#L1710 (which, by retaining User B as a member, effectively prevents the re-invitation) once “swipe to delete” is implemented on mobile. There is an activity center notification received for User B that is meant to allow re-joining of the group when the notification is accepted. The activity center notification received from status-go looks like the following: ```json "activityCenterNotifications": [ { "id": "0x0e342d33", "chatId": "e342d33f-dd05-4d7b-b14e-b5335e1a3ee9-0x043bf46aa874c377a34946eab67a32cf36c15907b328216dfce375d169fed7d81c21cada3229db1fd37c762d2c02702111a646657feca6621e2e948febcf378fb4", "name": "test-22", "type": 2, "lastMessage": null, "message": null, "timestamp": 1623305612000, "read": false, "dismissed": false, "accepted": false } ] ```
2021-06-10 07:29:05 +00:00
property int channelType: GroupInfoPopup.ChannelType.ActiveChannel
property QtObject channel
property bool isAdmin: false
2021-05-25 19:38:18 +00:00
property Component pinnedMessagesPopupComponent
function resetSelectedMembers(){
pubKeys = []
memberCount = channel ? channel.members.rowCount() : 0
currMemberCount = memberCount
popup.store.addToGroupContacts.clear()
popup.store.reCalculateAddToGroupContacts(channel)
}
2020-12-11 20:38:10 +00:00
function doAddMembers(){
if(pubKeys.length === 0) return;
if (popup.channel) {
// Not Refactored Yet
// chatsModel.groups.addMembers(popup.channel.id, JSON.stringify(pubKeys));
}
popup.close();
}
2020-12-11 20:38:10 +00:00
height: 504
anchors.centerIn: parent
//% "Add members"
header.title: addMembers ? qsTrId("add-members") : (popup.channel ? popup.channel.name : "")
header.subTitle: {
let cnt = memberCount;
if(addMembers){
//% "%1 / 10 members"
return qsTrId("%1-/-10-members").arg(cnt)
} else {
//% "%1 members"
if(cnt > 1) return qsTrId("%1-members").arg(cnt);
//% "1 member"
return qsTrId("1-member");
}
}
header.editable: !addMembers && popup.isAdmin
header.icon.isLetterIdenticon: true
header.icon.name: popup.channel ? popup.channel.name : ""
header.icon.background.color: popup.channel ? popup.channel.color : "transparent"
onEditButtonClicked: renameGroupPopup.open()
onClosed: {
popup.destroy();
}
onOpened: {
addMembers = false;
if (popup.channel) {
popup.isAdmin = popup.channel.isAdmin(userProfile.pubKey)
}
btnSelectMembers.enabled = false;
resetSelectedMembers();
}
ColumnLayout {
id: addMembersItem
width: parent.width - 2*Style.current.padding
height: parent.height
anchors.top: parent.top
anchors.topMargin: Style.current.halfPadding
anchors.horizontalCenter: parent.horizontalCenter
visible: addMembers
spacing: Style.current.padding
2020-06-15 12:51:04 +00:00
StatusBaseInput {
id: searchBox
implicitHeight: 36
//% "Search"
placeholderText: qsTrId("search")
placeholderFont.pixelSize: 15
icon.name: "search"
icon.width: 17
icon.height: 17
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
}
2020-12-11 20:38:10 +00:00
NoFriendsRectangle {
visible: popup.store.addToGroupContacts.count === 0 && memberCount === 0
Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
Layout.bottomMargin: childrenRect.height
}
NoFriendsRectangle {
visible: popup.store.addToGroupContacts.count === 0 && memberCount > 0
//% "All your contacts are already in the group"
text: qsTrId("group-chat-all-contacts-invited")
textColor: Style.current.textColor
Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
Layout.bottomMargin: childrenRect.height
}
ContactListPanel {
2020-12-11 20:38:10 +00:00
id: contactList
visible: popup.store.addToGroupContacts.count > 0
Layout.fillHeight: true
Layout.fillWidth: true
model: popup.store.addToGroupContacts
2020-12-11 20:38:10 +00:00
selectMode: memberCount < maxMembers
searchString: searchBox.text.toLowerCase()
onItemChecked: function(pubKey, itemChecked){
var idx = pubKeys.indexOf(pubKey)
if(itemChecked){
if(idx === -1){
pubKeys.push(pubKey)
}
} else {
if(idx > -1){
pubKeys.splice(idx, 1);
}
}
memberCount = popup.channel.members.rowCount() + pubKeys.length;
2020-12-11 20:38:10 +00:00
btnSelectMembers.enabled = pubKeys.length > 0
}
}
}
2020-06-11 17:50:36 +00:00
ColumnLayout {
id: groupInfoItem
2020-06-11 17:50:36 +00:00
width: parent.width - 2*Style.current.padding
height: parent.height - 2*Style.current.padding
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
visible: !addMembers
spacing: Style.current.padding
2020-06-11 17:50:36 +00:00
2021-05-25 19:38:18 +00:00
StatusSettingsLineButton {
// Not Refactored Yet
property int pinnedCount: 0 // popup.store.chatsModelInst.messageView.pinnedMessagesList.count
2021-05-25 19:38:18 +00:00
id: pinnedMessagesBtn
visible: pinnedCount > 0
//% "Pinned messages"
text: qsTrId("pinned-messages")
2021-05-25 19:38:18 +00:00
currentValue: pinnedCount
onClicked: Global.openPopup(pinnedMessagesPopupComponent)
iconSource: Style.svg("pin")
2021-05-25 19:38:18 +00:00
}
Separator {
id: separator2
visible: pinnedMessagesBtn.visible
}
// Not Refactored Yet
// Connections {
// target: popup.store.chatsModelInst.channelView
// onActiveChannelChanged: {
// if (popup.channelType === GroupInfoPopup.ChannelType.ActiveChannel) {
// popup.channel = popup.store.chatsModelInst.channelView.activeChannel
// resetSelectedMembers()
// }
// }
// onContextChannelChanged: {
// if (popup.channelType === GroupInfoPopup.ChannelType.ContextChannel) {
// popup.channel = popup.store.chatsModelInst.channelView.contextChannel
// resetSelectedMembers()
// }
// }
// }
fix: kick and re-invite user to group chat Fixes: #2601. Kicking a user and re-inviting them now correctly redisplays the join/decline options. Other combinations of User B leaving or declining an invitation are not handled. Please see the notes below for clarification. Additionally, the group invite popup (that shows the list of members belonging to the group) correctly shows when a user is kicked or when a user leaves the group in real time. Previously, the popup needed to be reopened to display this. fix: decline invitation crash Declining a group invitation was crashing the app. This has been fixed. ### NOTES 1. In the case where User A invites User B to a group, but User B declines (or User B joins, then leaves), then from a status-go standpoint, User B is still part of the group, but the chat is marked as `active: false` for User B. This creates a situation where User B cannot re-join the group once s/he has declined the invitation. @cammellos mentioned there possibly will need to be a refactor of https://github.com/status-im/status-go/blob/cab6281dc520c24912de5b5226b42a2f8415aa40/protocol/messenger.go#L1710 (which, by retaining User B as a member, effectively prevents the re-invitation) once “swipe to delete” is implemented on mobile. There is an activity center notification received for User B that is meant to allow re-joining of the group when the notification is accepted. The activity center notification received from status-go looks like the following: ```json "activityCenterNotifications": [ { "id": "0x0e342d33", "chatId": "e342d33f-dd05-4d7b-b14e-b5335e1a3ee9-0x043bf46aa874c377a34946eab67a32cf36c15907b328216dfce375d169fed7d81c21cada3229db1fd37c762d2c02702111a646657feca6621e2e948febcf378fb4", "name": "test-22", "type": 2, "lastMessage": null, "message": null, "timestamp": 1623305612000, "read": false, "dismissed": false, "accepted": false } ] ```
2021-06-10 07:29:05 +00:00
2020-06-11 17:50:36 +00:00
ListView {
id: memberList
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
model: popup.channel? popup.channel.members : []
delegate: StatusListItem {
id: contactRow
property string nickname: Utils.getContactDetailsAsJson(model.publicKey).localNickname
title: !model.userName.endsWith(".eth") && !!contactRow.nickname ?
contactRow.nickname : Utils.removeStatusEns(model.userName)
//% "(You)"
titleAsideText: model.publicKey === userProfile.pubKey ? qsTrId("-you-") : ""
//% "Admin"
statusListItemTitle.font.pixelSize: 17
statusListItemTitleAside.font.pixelSize: 17
label: model.isAdmin ? qsTrId("group-chat-admin"): ""
image.source: Global.getProfileImage(model.publicKey) || model.identicon
image.isIdenticon: model.identicon
components: [
StatusFlatRoundButton {
id: moreActionsBtn
type: StatusFlatRoundButton.Type.Tertiary
color: "transparent"
icon.name: "more"
icon.color: Theme.palette.baseColor1
visible: !model.isAdmin && popup.isAdmin
onClicked: {
contextMenu.popup(-contextMenu.width / 2 + moreActionsBtn.width / 2, moreActionsBtn.height + 10)
}
StatusPopupMenu {
id: contextMenu
StatusMenuItem {
icon.name: "admin"
icon.width: 16
icon.height: 16
//% "Make Admin"
text: qsTrId("make-admin")
// Not Refactored Yet
// onTriggered: popup.store.chatsModelInst.groups.makeAdmin(popup.channel.id, model.publicKey)
}
StatusMenuItem {
icon.name: "remove-contact"
icon.width: 16
icon.height: 16
type: StatusMenuItem.Type.Danger
//% "Remove From Group"
text: qsTrId("remove-from-group")
// Not Refactored Yet
// onTriggered: popup.store.chatsModelInst.groups.kickMember(popup.channel.id, model.publicKey)
}
}
2020-06-11 17:50:36 +00:00
}
]
onTitleClicked: {
Global.openProfilePopup(model.publicKey, popup)
2020-06-11 17:50:36 +00:00
}
}
}
}
leftButtons: [
StatusRoundButton {
visible: popup.addMembers
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
icon.rotation: 180
onClicked: {
popup.addMembers = false;
popup.resetSelectedMembers();
}
}
]
rightButtons: [
StatusButton {
visible: !popup.addMembers
//% "Add members"
text: qsTrId("add-members")
onClicked: {
popup.addMembers = true;
}
},
StatusButton {
id: btnSelectMembers
visible: popup.addMembers
enabled: popup.memberCount >= popup.currMemberCount
//% "Add selected"
text: qsTrId("add-selected")
onClicked: popup.doAddMembers()
}
]
RenameGroupPopup {
id: renameGroupPopup
// Not Refactored Yet
// activeChannelName: popup.store.chatsModelInst.channelView.activeChannel.name
// onDoRename: {
// popup.store.chatsModelInst.groups.rename(groupName)
// popup.header.title = groupName
// close()
// }
}
2020-06-11 17:50:36 +00:00
}