fix(@desktop/Chat): Group chat popup member list doesn't have proper visuals

fixes #4176
This commit is contained in:
Khushboo Mehta 2021-11-30 11:50:53 +01:00 committed by Khushboo-dev-cpp
parent 33c3f2278b
commit 0fbdbdbd15
6 changed files with 202 additions and 305 deletions

@ -1 +1 @@
Subproject commit 419b73845646354ea103b665ed8379b591ebc8e8
Subproject commit e54211cb994ee8a650c49553c1e761670ea3d4f1

View File

@ -1,47 +1,54 @@
import QtQuick 2.13
import QtQuick.Controls 2.3
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import utils 1.0
import "../controls"
ScrollView {
property alias membersData: membersData
id: contactListPanel
property alias model: groupMembers.model
property string searchString
property bool selectMode: true
property var onItemChecked
anchors.fill: parent
id: root
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: groupMembers.contentHeight > groupMembers.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView {
id: groupMembers
anchors.fill: parent
model: ListModel {
id: membersData
}
spacing: 0
clip: true
id: groupMembers
delegate: Contact {
isVisible: {
delegate: StatusListItem {
id: contactDelegate
property bool isChecked: false
title: !model.name.endsWith(".eth") && !!model.localNickname ?
model.localNickname : Utils.removeStatusEns(model.name)
image.source: appMain.getProfileImage(model.pubKey) || model.identicon
image.isIdenticon: !!model.identicon
visible: {
if (selectMode) {
return !searchString || model.name.toLowerCase().includes(searchString)
}
return isChecked || isUser
return checkbox.checked || model.isUser
}
showCheckbox: root.selectMode
pubKey: model.pubKey
isContact: !!model.isContact
isUser: model.isUser
name: !model.name.endsWith(".eth") && !!model.localNickname ?
model.localNickname : Utils.removeStatusEns(model.name)
address: model.address
identicon: model.thumbnailImage || model.identicon
onItemChecked: function (pubKey, itemChecked) {
root.onItemChecked(pubKey, itemChecked)
components: [
StatusCheckBox {
id: checkbox
visible: contactListPanel.selectMode && !model.isUser
checked: contactDelegate.isChecked
onClicked: {
contactDelegate.isChecked = !contactDelegate.isChecked
onItemChecked(model.pubKey, contactDelegate.isChecked)
}
}
]
onClicked: {
contactDelegate.isChecked = !contactDelegate.isChecked
onItemChecked(model.pubKey, contactDelegate.isChecked)
}
}
}

View File

@ -32,16 +32,16 @@ ModalPopup {
memberCount = 1;
pubKeys = [];
contactList.membersData.clear();
popup.store.addToGroupContacts.clear();
getContactListObject(contactList.membersData)
getContactListObject(popup.store.addToGroupContacts)
contactList.membersData.append({
popup.store.addToGroupContacts.append({
//% "(You)"
name: userProfile.username + " " + qsTrId("(you)"),
pubKey: userProfile.pubKey,
address: "",
identicon: userProfile.identicon,
identicon: "",
thumbnailImage: userProfile.thumbnailImage,
isUser: true
});
@ -135,6 +135,8 @@ ModalPopup {
ContactListPanel {
id: contactList
anchors.fill: parent
model: popup.store.addToGroupContacts
searchString: searchBox.text.toLowerCase()
selectMode: selectChatMembers && memberCount < maxMembers
anchors.topMargin: 50

View File

@ -2,22 +2,23 @@ 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 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 {
StatusModal {
id: popup
enum ChannelType {
ActiveChannel,
ContextChannel
@ -34,24 +35,45 @@ ModalPopup {
property Component pinnedMessagesPopupComponent
function resetSelectedMembers(){
pubKeys = [];
pubKeys = []
memberCount = channel ? channel.members.rowCount() : 0;
currMemberCount = memberCount;
contactList.membersData.clear();
memberCount = channel ? channel.members.rowCount() : 0
currMemberCount = memberCount
popup.store.addToGroupContacts.clear()
popup.store.reCalculateAddToGroupContacts(channel)
}
const contacts = getContactListObject()
function doAddMembers(){
if(pubKeys.length === 0) return;
if (popup.channel) {
chatsModel.groups.addMembers(popup.channel.id, JSON.stringify(pubKeys));
}
popup.close();
}
if (channel) {
contacts.forEach(function (contact) {
if(popup.channel.contains(contact.publicKey) ||
!contact.isContact) {
return;
}
contactList.membersData.append(contact)
})
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();
@ -66,147 +88,57 @@ ModalPopup {
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 {
ColumnLayout {
id: addMembersItem
anchors.fill: parent
SearchBox {
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
StatusBaseInput {
id: searchBox
visible: addMembers
iconWidth: 17
iconHeight: 17
customHeight: 44
fontPixelSize: 15
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
}
NoFriendsRectangle {
visible: contactList.membersData.count === 0 && memberCount === 0
anchors.top: searchBox.bottom
anchors.topMargin: Style.current.xlPadding
anchors.horizontalCenter: parent.horizontalCenter
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: contactList.membersData.count === 0 && memberCount > 0
width: 340
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
anchors.top: searchBox.bottom
anchors.topMargin: Style.current.xlPadding
anchors.horizontalCenter: parent.horizontalCenter
Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
Layout.bottomMargin: childrenRect.height
}
ContactListPanel {
id: contactList
visible: addMembers && contactList.membersData.count > 0
anchors.fill: parent
anchors.topMargin: 50
anchors.top: searchBox.bottom
visible: popup.store.addToGroupContacts.count > 0
Layout.fillHeight: true
Layout.fillWidth: true
model: popup.store.addToGroupContacts
selectMode: memberCount < maxMembers
searchString: searchBox.text.toLowerCase()
onItemChecked: function(pubKey, itemChecked){
@ -226,32 +158,26 @@ ModalPopup {
}
}
Item {
ColumnLayout {
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
}
width: parent.width - 2*Style.current.padding
height: parent.height
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
visible: !addMembers
spacing: 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")
}
@ -259,12 +185,6 @@ ModalPopup {
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 {
@ -285,154 +205,106 @@ ModalPopup {
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 {
delegate: StatusListItem {
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
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: appMain.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)
}
cursorShape: Qt.PointingHandCursor
// TODO: replace with StatusPopupMenu
PopupMenu {
StatusPopupMenu {
id: contextMenu
Action {
icon.source: Style.svg("make-admin")
StatusMenuItem {
icon.name: "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")
StatusMenuItem {
icon.name: "remove-contact"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
type: StatusMenuItem.Type.Danger
//% "Remove From Group"
text: qsTrId("remove-from-group")
onTriggered: popup.store.chatsModelInst.groups.kickMember(popup.channel.id, model.publicKey)
}
}
}
]
onTitleClicked: {
const userProfileImage = appMain.getProfileImage(model.publicKey)
openProfilePopup(model.userName, model.publicKey, userProfileImage || model.identicon, '', contactRow.nickname, popup)
}
}
}
}
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
leftButtons: [
StatusRoundButton {
visible: popup.addMembers
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
icon.rotation: 180
onClicked : {
addMembers = false;
resetSelectedMembers();
onClicked: {
popup.addMembers = false;
popup.resetSelectedMembers();
}
}
]
StatusQControls.StatusButton {
rightButtons: [
StatusButton {
visible: !popup.addMembers
//% "Add members"
text: qsTrId("add-members")
onClicked: {
popup.addMembers = true;
}
},
StatusButton {
id: btnSelectMembers
visible: addMembers
enabled: memberCount >= currMemberCount
anchors.right: parent.right
visible: popup.addMembers
enabled: popup.memberCount >= popup.currMemberCount
//% "Add selected"
text: qsTrId("add-selected")
anchors.bottom: parent.bottom
onClicked: doAddMembers()
onClicked: popup.doAddMembers()
}
]
RenameGroupPopup {
id: renameGroupPopup
activeChannelName: popup.store.chatsModelInst.channelView.activeChannel.name
onDoRename: {
popup.store.chatsModelInst.groups.rename(groupName)
popup.header.title = groupName
close()
}
}
content: addMembers ? addMembersItem : groupInfoItem
}

View File

@ -38,8 +38,8 @@ StatusModal {
anchors.topMargin: Style.current.padding
//% "Group name"
placeholderText: qsTrId("group-name")
Keys.onEnterPressed: doRename()
Keys.onReturnPressed: doRename()
Keys.onEnterPressed: doRename(groupName.text)
Keys.onReturnPressed: doRename(groupName.text)
}
}
@ -48,7 +48,7 @@ StatusModal {
id: saveBtn
//% "Save"
text: qsTrId("save")
onClicked : { doRename(groupName.text); }
onClicked : { doRename(groupName.text) }
}
]
}

View File

@ -23,6 +23,22 @@ QtObject {
property var currentAccount: walletSectionCurrent
property var currentCurrency: walletSection.currentCurrency
property ListModel addToGroupContacts: ListModel {}
function reCalculateAddToGroupContacts(channel) {
const contacts = getContactListObject()
if (channel) {
contacts.forEach(function (contact) {
if(channel.contains(contact.pubKey) ||
!contact.isContact) {
return;
}
addToGroupContacts.append(contact)
})
}
}
function copyToClipboard(text) {
chatsModelInst.copyToClipboard(text);
}