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

439 lines
15 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import utils 1.0
import shared 1.0
import shared.views 1.0
import shared.panels 1.0
import shared.popups 1.0
import shared.status 1.0
import shared.controls 1.0
import StatusQ.Controls 0.1 as StatusQControls
import StatusQ.Components 0.1 as StatusQ
import "../panels"
// TODO: replace with StatusModal
ModalPopup {
id: popup
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: []
property int channelType: GroupInfoPopup.ChannelType.ActiveChannel
property QtObject channel
property bool isAdmin: false
property Component pinnedMessagesPopupComponent
function resetSelectedMembers(){
pubKeys = [];
memberCount = channel ? channel.members.rowCount() : 0;
currMemberCount = memberCount;
contactList.membersData.clear();
const contacts = getContactListObject()
if (channel) {
contacts.forEach(function (contact) {
if(popup.channel.contains(contact.publicKey) ||
!contact.isContact) {
return;
}
contactList.membersData.append(contact)
})
}
}
onClosed: {
popup.destroy();
}
onOpened: {
addMembers = false;
if (popup.channel) {
popup.isAdmin = popup.channel.isAdmin(userProfile.pubKey)
}
btnSelectMembers.enabled = false;
resetSelectedMembers();
}
function doAddMembers(){
if(pubKeys.length === 0) return;
if (popup.channel) {
chatsModel.groups.addMembers(popup.channel.id, JSON.stringify(pubKeys));
}
popup.close();
}
header: Item {
height: children[0].height
width: parent.width
StatusQ.StatusLetterIdenticon {
id: letterIdenticon
width: 36
height: 36
anchors.top: parent.top
color: popup.channel ? popup.channel.color : "transparent"
name: popup.channel ? popup.channel.name : ""
}
StyledTextEdit {
id: groupNameTxt
//% "Add members"
text: addMembers ? qsTrId("add-members")
: (popup.channel ? popup.channel.name : "")
anchors.top: parent.top
anchors.topMargin: 2
anchors.left: letterIdenticon.right
anchors.leftMargin: Style.current.smallPadding
font.bold: true
font.pixelSize: 14
readOnly: true
wrapMode: Text.WordWrap
}
StyledText {
text: {
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");
}
}
width: 160
anchors.left: letterIdenticon.right
anchors.leftMargin: Style.current.smallPadding
anchors.top: groupNameTxt.bottom
anchors.topMargin: 2
font.pixelSize: 14
color: Style.current.secondaryText
}
Rectangle {
id: editGroupNameBtn
visible: !addMembers && popup.isAdmin
height: 24
width: 24
anchors.verticalCenter: groupNameTxt.verticalCenter
anchors.leftMargin: Style.current.halfPadding
anchors.left: groupNameTxt.right
radius: 8
SVGImage {
id: editGroupImg
source: Style.svg("edit-group")
height: 16
width: 16
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
id: closeModalMouseArea
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onExited: {
editGroupNameBtn.color = Style.current.white
}
onEntered: {
editGroupNameBtn.color = Style.current.grey
}
onClicked: renameGroupPopup.open()
}
}
RenameGroupPopup {
id: renameGroupPopup
activeChannelName: popup.store.chatsModelInst.channelView.activeChannel.name
onDoRename: {
popup.store.chatsModelInst.groups.rename(groupName);
groupNameTxt.text = groupName
close();
}
}
}
Item {
id: addMembersItem
anchors.fill: parent
SearchBox {
id: searchBox
visible: addMembers
iconWidth: 17
iconHeight: 17
customHeight: 44
fontPixelSize: 15
}
NoFriendsRectangle {
visible: contactList.membersData.count === 0 && memberCount === 0
anchors.top: searchBox.bottom
anchors.topMargin: Style.current.xlPadding
anchors.horizontalCenter: parent.horizontalCenter
}
NoFriendsRectangle {
visible: contactList.membersData.count === 0 && memberCount > 0
width: 340
//% "All your contacts are already in the group"
text: qsTrId("group-chat-all-contacts-invited")
textColor: Style.current.textColor
anchors.top: searchBox.bottom
anchors.topMargin: Style.current.xlPadding
anchors.horizontalCenter: parent.horizontalCenter
}
ContactListPanel {
id: contactList
visible: addMembers && contactList.membersData.count > 0
anchors.fill: parent
anchors.topMargin: 50
anchors.top: searchBox.bottom
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;
btnSelectMembers.enabled = pubKeys.length > 0
}
}
}
Item {
id: groupInfoItem
anchors.fill: parent
Separator {
id: separator
visible: !addMembers
anchors.left: parent.left
anchors.leftMargin: -Style.current.padding
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
}
StatusSettingsLineButton {
property int pinnedCount: popup.store.chatsModelInst.messageView.pinnedMessagesList.count
id: pinnedMessagesBtn
visible: pinnedCount > 0
height: visible ? implicitHeight : 0
//% "Pinned messages"
text: qsTrId("pinned-messages")
currentValue: pinnedCount
anchors.top: separator.bottom
anchors.topMargin: visible ? Style.current.halfPadding : 0
anchors.leftMargin: 0
anchors.rightMargin: 0
onClicked: openPopup(pinnedMessagesPopupComponent)
iconSource: Style.svg("pin")
}
Separator {
id: separator2
visible: pinnedMessagesBtn.visible
anchors.left: parent.left
anchors.leftMargin: -Style.current.padding
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
anchors.top: pinnedMessagesBtn.bottom
anchors.topMargin: visible ? Style.current.halfPadding : 0
}
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()
}
}
}
ListView {
id: memberList
anchors.top: separator2.bottom
anchors.bottom: parent.bottom
anchors.topMargin: addMembers ? 30 : Style.current.padding
anchors.bottomMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
spacing: Style.current.padding
Layout.fillWidth: true
Layout.fillHeight: true
model: popup.channel? popup.channel.members : []
delegate: Item {
id: contactRow
width: parent.width
height: identicon.height
property string nickname: appMain.getUserNickname(model.publicKey)
StatusQ.StatusSmartIdenticon {
id: identicon
anchors.left: parent.left
image.source: appMain.getProfileImage(model.publicKey)|| model.identicon
image.isIdenticon: true
}
StyledText {
text: !model.userName.endsWith(".eth") && !!contactRow.nickname ?
contactRow.nickname : Utils.removeStatusEns(model.userName)
anchors.left: identicon.right
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 17
StyledText {
visible: model.publicKey === userProfile.pubKey
anchors.left: parent.right
anchors.leftMargin: 5
//% "(You)"
text: qsTrId("-you-")
color: Style.current.secondaryText
font.pixelSize: parent.font.pixelSize
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
const userProfileImage = appMain.getProfileImage(model.publicKey)
openProfilePopup(model.userName, model.publicKey, userProfileImage || model.identicon, '', contactRow.nickname, popup)
}
}
}
StyledText {
id: adminLabel
visible: model.isAdmin
//% "Admin"
text: qsTrId("group-chat-admin")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 13
color: Style.current.secondaryText
}
StyledText {
id: moreActionsBtn
visible: !model.isAdmin && popup.isAdmin
text: "..."
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 20
font.bold: true
color: Style.current.secondaryText
MouseArea {
anchors.fill: parent
onClicked: {
contextMenu.popup(-contextMenu.width / 2 + moreActionsBtn.width / 2, moreActionsBtn.height + 10)
}
cursorShape: Qt.PointingHandCursor
// TODO: replace with StatusPopupMenu
PopupMenu {
id: contextMenu
Action {
icon.source: Style.svg("make-admin")
icon.width: 16
icon.height: 16
//% "Make Admin"
text: qsTrId("make-admin")
onTriggered: popup.store.chatsModelInst.groups.makeAdmin(popup.channel.id, model.publicKey)
}
Action {
icon.source: Style.svg("remove-from-group")
icon.width: 16
icon.height: 16
icon.color: Style.current.red
//% "Remove From Group"
text: qsTrId("remove-from-group")
onTriggered: popup.store.chatsModelInst.groups.kickMember(popup.channel.id, model.publicKey)
}
}
}
}
}
}
}
footer: Item {
visible: popup.isAdmin
width: parent.width
height: children[0].height
StatusQControls.StatusButton {
visible: !addMembers
anchors.right: parent.right
//% "Add members"
text: qsTrId("add-members")
anchors.bottom: parent.bottom
onClicked: {
addMembers = true;
}
}
StatusQControls.StatusRoundButton {
id: btnBack
visible: addMembers
anchors.bottom: parent.bottom
anchors.left: parent.left
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
icon.rotation: 180
onClicked : {
addMembers = false;
resetSelectedMembers();
}
}
StatusQControls.StatusButton {
id: btnSelectMembers
visible: addMembers
enabled: memberCount >= currMemberCount
anchors.right: parent.right
//% "Add selected"
text: qsTrId("add-selected")
anchors.bottom: parent.bottom
onClicked: doAddMembers()
}
}
content: addMembers ? addMembersItem : groupInfoItem
}