diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml index 38e45e35f7..a3e6180dcc 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml +++ b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml @@ -1,4 +1,5 @@ import QtQuick 2.12 +import QtQuick.Controls 2.12 import QtQuick.Dialogs 1.3 import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 @@ -17,25 +18,38 @@ ModalPopup { property string communityColor: "" property int nbMembers: community.nbMembers property bool isAdmin: false - height: (isAdmin ? 600 : 590) + descriptionText.height - + height: stack.currentItem.height + modalHeader.height + modalFooter.height + Style.current.padding*3 id: popup + onClosed: { + while (stack.depth > 1) { + stack.pop() + } + } + header: Item { + id: modalHeader height: childrenRect.height width: parent.width + property string title: stack.currentItem.headerTitle + property string description: stack.currentItem.headerDescription + property string imageSource: stack.currentItem.headerImageSource + property bool useLetterIdenticon: !!stack.currentItem.useLetterIdenticon + Loader { id: communityImg - sourceComponent: !!popup.source ? commmunityImgCmp : letterIdenticonCmp + sourceComponent: !modalHeader.useLetterIdenticon ? commmunityImgCmp : letterIdenticonCmp + active: !!modalHeader.imageSource || modalHeader.useLetterIdenticon } Component { id: commmunityImgCmp RoundedImage { - source: popup.source + source: modalHeader.imageSource width: 40 height: 40 + visible: !!modalHeader.imageSource } } @@ -47,34 +61,23 @@ ModalPopup { chatName: popup.name color: popup.communityColor } - } - + } StyledTextEdit { id: communityName - text: popup.name + text: modalHeader.title anchors.top: parent.top anchors.topMargin: 2 - anchors.left: communityImg.right - anchors.leftMargin: Style.current.smallPadding + anchors.left: communityImg.active ? communityImg.right : parent.left + anchors.leftMargin: communityImg.active ? Style.current.smallPadding : 0 font.bold: true font.pixelSize: 17 readOnly: true } StyledText { - text: { - switch(access) { - //% "Public community" - case Constants.communityChatPublicAccess: return qsTrId("public-community"); - //% "Invitation only community" - case Constants.communityChatInvitationOnlyAccess: return qsTrId("invitation-only-community"); - //% "On request community" - case Constants.communityChatOnRequestAccess: return qsTrId("on-request-community"); - //% "Unknown community" - default: return qsTrId("unknown-community"); - } - } + id: headerDescription + text: modalHeader.description anchors.left: communityName.left anchors.top: communityName.bottom anchors.topMargin: 2 @@ -84,7 +87,7 @@ ModalPopup { } Separator { - anchors.top: communityImg.bottom + anchors.top: headerDescription.bottom anchors.topMargin: Style.current.padding anchors.left: parent.left anchors.right: parent.right @@ -93,242 +96,61 @@ ModalPopup { } } - StyledText { - id: descriptionText - text: popup.description - wrapMode: Text.Wrap - width: parent.width - font.pixelSize: 15 - } + StackView { + id: stack + initialItem: profileOverview + anchors.fill: parent - Separator { - id: sep1 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: descriptionText.bottom - anchors.topMargin: Style.current.smallPadding - anchors.leftMargin: -Style.current.padding - anchors.rightMargin: -Style.current.padding - } + pushEnter: Transition { enabled: false } + pushExit: Transition { enabled: false } + popEnter: Transition { enabled: false } + popExit: Transition { enabled: false } - TextWithLabel { - id: shareCommunity - anchors.top: sep1.bottom - anchors.topMargin: Style.current.bigPadding - //% "Share community" - label: qsTrId("share-community") - text: "https://join.status.im/u/TODO" - textToCopy: text - } + Component { + id: membersList + CommunityProfilePopupMembersList { + headerTitle: qsTr("Members") + headerDescription: popup.nbMembers.toString() + } + } - Separator { - id: sep2 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: shareCommunity.bottom - anchors.topMargin: Style.current.smallPadding - anchors.leftMargin: -Style.current.padding - anchors.rightMargin: -Style.current.padding - } - - Column { - anchors.top: sep2.bottom - anchors.topMargin: Style.current.halfPadding - width: parent.width - - Loader { - active: isAdmin - width: parent.width - sourceComponent: Component { - CommunityPopupButton { - id: memberBtn - label: qsTr("Members") - iconName: "members" - txtColor: Style.current.textColor - onClicked: openPopup(communityMembersPopup) - - Component { - id: communityMembersPopup - CommunityMembersPopup {} - } - - Item { - property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests - - id: memberBlock - anchors.right: parent.right - anchors.rightMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - width: childrenRect.width - height: memberBtn.height - - StyledText { - id: nbMemberText - text: nbMembers.toString() - anchors.verticalCenter: parent.verticalCenter - padding: 0 - font.pixelSize: 15 - color: Style.current.secondaryText - } - - Rectangle { - id: badge - visible: memberBlock.nbRequests > 0 - anchors.left: nbMemberText.right - anchors.leftMargin: visible ? Style.current.halfPadding : 0 - anchors.verticalCenter: parent.verticalCenter - color: Style.current.blue - width: visible ? 22 : 0 - height: 22 - radius: width / 2 - Text { - font.pixelSize: 12 - color: Style.current.white - anchors.centerIn: parent - text: memberBlock.nbRequests - } - } - - SVGImage { - id: caret - anchors.left: badge.right - anchors.leftMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - source: "../../../img/caret.svg" - width: 13 - height: 7 - rotation: -90 - ColorOverlay { - anchors.fill: parent - source: parent - color: Style.current.secondaryText - } - } + Component { + id: profileOverview + CommunityProfilePopupOverview { + property bool useLetterIdenticon: !!!popup.source + headerTitle: popup.name + headerDescription: { + switch(access) { + //% "Public community" + case Constants.communityChatPublicAccess: return qsTrId("public-community"); + //% "Invitation only community" + case Constants.communityChatInvitationOnlyAccess: return qsTrId("invitation-only-community"); + //% "On request community" + case Constants.communityChatOnRequestAccess: return qsTrId("on-request-community"); + //% "Unknown community" + default: return qsTrId("unknown-community"); } } + headerImageSource: popup.source + description: popup.description } } + } - // TODO add this back when roles exist -// Loader { -// active: isAdmin -// width: parent.width -// sourceComponent: CommunityPopupButton { -// label: qsTr("Roles") -// iconName: "roles" -// width: parent.width -// onClicked: console.log("TODO:") -// txtColor: Style.current.textColor -// SVGImage { -// anchors.verticalCenter: parent.verticalCenter -// anchors.right: parent.right -// anchors.rightMargin: Style.current.padding -// source: "../../../img/caret.svg" -// width: 13 -// height: 7 -// rotation: -90 -// ColorOverlay { -// anchors.fill: parent -// source: parent -// color: Style.current.secondaryText -// } -// } -// } -// } - - CommunityPopupButton { - id: notificationsBtn - //% "Notifications" - label: qsTrId("notifications") - iconName: "notifications" - width: parent.width - txtColor: Style.current.textColor - onClicked: function(){ - notificationSwitch.checked = !notificationSwitch.checked - } - StatusSwitch { - id: notificationSwitch - anchors.right: parent.right - anchors.rightMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - onCheckedChanged: function(value) { - // TODO: enable/disable notifications - console.log("TODO: toggle") - } - } - } - - Item { - id: spacer1 - width: parent.width - height: Style.current.halfPadding - } - - Separator { + footer: Item { + id: modalFooter + visible: stack.depth > 1 + width: parent.width + height: modalFooter.visible ? btnBack.height : 0 + StatusRoundButton { + id: btnBack anchors.left: parent.left - anchors.right: parent.right - anchors.rightMargin: -Style.current.padding - anchors.leftMargin: -Style.current.padding - } - - Item { - id: spacer2 - width: parent.width - height: Style.current.halfPadding - } - - Loader { - active: isAdmin - width: parent.width - sourceComponent: CommunityPopupButton { - //% "Edit community" - label: qsTrId("edit-community") - iconName: "edit" - onClicked: openPopup(editCommunityPopup) - - Component { - id: editCommunityPopup - CreateCommunityPopup { - isEdit: true - } - } - } - } - - Loader { - active: isAdmin - width: parent.width - sourceComponent: CommunityPopupButton { - label: qsTr("Transfer ownership") - iconName: "../transfer" - onClicked: { - const exportResult = chatsModel.communities.exportComumnity() - openPopup(transferOwnershipPopup, {privateKey: exportResult}) - } - - Component { - id: transferOwnershipPopup - TransferOwnershipPopup {} - } - } - } - - CommunityPopupButton { - //% "Leave community" - label: qsTrId("leave-community") - iconName: "leave" - } - - Loader { - active: isAdmin - width: parent.width - sourceComponent: CommunityPopupButton { - id: deleteBtn - //% "Delete" - label: qsTrId("delete") - iconName: "delete" - txtColor: Style.current.danger - type: "warn" + icon.name: "arrow-right" + icon.width: 20 + icon.height: 16 + rotation: 180 + onClicked: { + stack.pop() } } } diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml new file mode 100644 index 0000000000..0470684c76 --- /dev/null +++ b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml @@ -0,0 +1,165 @@ +import QtQuick 2.13 +import QtQuick.Controls 2.13 +import QtQuick.Layouts 1.13 +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" +import "./" +import "../components" + +Item { + property string headerTitle: "" + property string headerDescription: "" + property string headerImageSource: "" + width: parent.width + height: childrenRect.height + + CommunityPopupButton { + id: inviteBtn + //% "Invite People" + label: qsTrId("invite-people") + width: parent.width + iconName: "invite" + onClicked: openPopup(inviteFriendsPopup) + Component { + id: inviteFriendsPopup + InviteFriendsToCommunityPopup { + onClosed: { + destroy() + } + } + } + } + Separator { + id: sep + anchors.left: parent.left + anchors.right: parent.right + anchors.top: inviteBtn.bottom + anchors.topMargin: Style.current.smallPadding + anchors.leftMargin: -Style.current.padding + anchors.rightMargin: -Style.current.padding + } + + MembershipRequestsButton { + id: membershipRequestsBtn + anchors.top: sep.bottom + anchors.topMargin: visible ? Style.current.smallPadding : 0 + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: -Style.current.padding + anchors.rightMargin: -Style.current.padding + } + + Separator { + id: sep2 + visible: membershipRequestsBtn.visible + anchors.left: parent.left + anchors.right: parent.right + anchors.top: membershipRequestsBtn.bottom + anchors.topMargin: Style.current.smallPadding + anchors.leftMargin: -Style.current.padding + anchors.rightMargin: -Style.current.padding + } + + ListView { + id: memberList + anchors.top: sep2.visible ? sep2.bottom : sep.bottom + anchors.topMargin: Style.current.smallPadding + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottomMargin: Style.current.halfPadding + spacing: 4 + model: community.members + delegate: Item { + id: contactRow + width: parent.width + height: identicon.height + + property string nickname: appMain.getUserNickname(model.pubKey) + + StatusImageIdenticon { + id: identicon + anchors.left: parent.left + source: model.identicon + } + + StyledText { + text: !model.userName.endsWith(".eth") && !!contactRow.nickname ? + contactRow.nickname : Utils.removeStatusEns(model.userName) + anchors.left: identicon.right + anchors.leftMargin: Style.current.smallPadding + anchors.right: parent.right + anchors.rightMargin: Style.current.smallPadding + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 13 + } + + StyledText { + id: moreActionsBtn + text: "..." + font.letterSpacing: 0.5 + font.bold: true + lineHeight: 1.4 + font.pixelSize: 25 + anchors.right: parent.right + anchors.rightMargin: Style.current.smallPadding + anchors.verticalCenter: parent.verticalCenter + MouseArea { + anchors.fill: parent + onClicked: contextMenu.popup(-contextMenu.width / 2 + moreActionsBtn.width / 2, moreActionsBtn.height) + cursorShape: Qt.PointingHandCursor + PopupMenu { + id: contextMenu + Action { + icon.source: "../../../img/communities/menu/view-profile.svg" + icon.width: 16 + icon.height: 16 + //% "View Profile" + text: qsTrId("view-profile") + onTriggered: openProfilePopup(model.userName, model.pubKey, model.identicon, '', contactRow.nickname) + } + Action { + icon.source: "../../../img/communities/menu/roles.svg" + icon.width: 16 + icon.height: 16 + //% "Roles" + text: qsTrId("roles") + onTriggered: console.log("TODO") + } + Separator {} + Action { + icon.source: "../../../img/communities/menu/kick.svg" + icon.width: 16 + icon.height: 16 + icon.color: Style.current.red + //% "Kick" + text: qsTrId("kick") + onTriggered: chatsModel.removeUserFromCommunity(model.pubKey) + } + Action { + icon.source: "../../../img/communities/menu/ban.svg" + icon.width: 16 + icon.height: 16 + icon.color: Style.current.red + //% "Ban" + text: qsTrId("ban") + onTriggered: console.log("TODO") + } + Separator {} + Action { + icon.source: "../../../img/communities/menu/transfer-ownership.svg" + icon.width: 16 + icon.height: 16 + icon.color: Style.current.red + //% "Transfer ownership" + text: qsTrId("transfer-ownership") + onTriggered: console.log("TODO") + } + } + } + } + } + } + +} diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupOverview.qml b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupOverview.qml new file mode 100644 index 0000000000..ded0cd94df --- /dev/null +++ b/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupOverview.qml @@ -0,0 +1,262 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.13 +import QtGraphicalEffects 1.13 +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" +import "../ContactsColumn" + +Item { + id: root + + property string headerTitle: "" + property string headerDescription: "" + property string headerImageSource: "" + property string description: "" + + width: parent.width + height: childrenRect.height + + StyledText { + id: descriptionText + text: root.description + wrapMode: Text.Wrap + width: parent.width + font.pixelSize: 15 + } + + Separator { + id: sep1 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: descriptionText.bottom + anchors.topMargin: Style.current.smallPadding + anchors.leftMargin: -Style.current.padding + anchors.rightMargin: -Style.current.padding + } + + TextWithLabel { + id: shareCommunity + anchors.top: sep1.bottom + anchors.topMargin: Style.current.bigPadding + //% "Share community" + label: qsTrId("share-community") + text: "https://join.status.im/u/TODO" + textToCopy: text + } + + Separator { + id: sep2 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: shareCommunity.bottom + anchors.topMargin: Style.current.smallPadding + anchors.leftMargin: -Style.current.padding + anchors.rightMargin: -Style.current.padding + } + + Column { + anchors.top: sep2.bottom + anchors.topMargin: Style.current.halfPadding + width: parent.width + + Loader { + active: isAdmin + width: parent.width + sourceComponent: Component { + CommunityPopupButton { + id: memberBtn + label: qsTr("Members") + iconName: "members" + txtColor: Style.current.textColor + //onClicked: openPopup(communityMembersPopup) + onClicked: stack.push(membersList) + + Component { + id: communityMembersPopup + CommunityMembersPopup {} + } + + Item { + property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests + + id: memberBlock + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + anchors.verticalCenter: parent.verticalCenter + width: childrenRect.width + height: memberBtn.height + + StyledText { + id: nbMemberText + text: nbMembers.toString() + anchors.verticalCenter: parent.verticalCenter + padding: 0 + font.pixelSize: 15 + color: Style.current.secondaryText + } + + Rectangle { + id: badge + visible: memberBlock.nbRequests > 0 + anchors.left: nbMemberText.right + anchors.leftMargin: visible ? Style.current.halfPadding : 0 + anchors.verticalCenter: parent.verticalCenter + color: Style.current.blue + width: visible ? 22 : 0 + height: 22 + radius: width / 2 + Text { + font.pixelSize: 12 + color: Style.current.white + anchors.centerIn: parent + text: memberBlock.nbRequests + } + } + + SVGImage { + id: caret + anchors.left: badge.right + anchors.leftMargin: Style.current.padding + anchors.verticalCenter: parent.verticalCenter + source: "../../../img/caret.svg" + width: 13 + height: 7 + rotation: -90 + ColorOverlay { + anchors.fill: parent + source: parent + color: Style.current.secondaryText + } + } + } + } + } + } + + // TODO add this back when roles exist +// Loader { +// active: isAdmin +// width: parent.width +// sourceComponent: CommunityPopupButton { +// label: qsTr("Roles") +// iconName: "roles" +// width: parent.width +// onClicked: console.log("TODO:") +// txtColor: Style.current.textColor +// SVGImage { +// anchors.verticalCenter: parent.verticalCenter +// anchors.right: parent.right +// anchors.rightMargin: Style.current.padding +// source: "../../../img/caret.svg" +// width: 13 +// height: 7 +// rotation: -90 +// ColorOverlay { +// anchors.fill: parent +// source: parent +// color: Style.current.secondaryText +// } +// } +// } +// } + + CommunityPopupButton { + id: notificationsBtn + //% "Notifications" + label: qsTrId("notifications") + iconName: "notifications" + width: parent.width + txtColor: Style.current.textColor + onClicked: function(){ + notificationSwitch.checked = !notificationSwitch.checked + } + StatusSwitch { + id: notificationSwitch + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + anchors.verticalCenter: parent.verticalCenter + onCheckedChanged: function(value) { + // TODO: enable/disable notifications + console.log("TODO: toggle") + } + } + } + + Item { + id: spacer1 + width: parent.width + height: Style.current.halfPadding + } + + Separator { + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: -Style.current.padding + anchors.leftMargin: -Style.current.padding + } + + Item { + id: spacer2 + width: parent.width + height: Style.current.halfPadding + } + + Loader { + active: isAdmin + width: parent.width + sourceComponent: CommunityPopupButton { + //% "Edit community" + label: qsTrId("edit-community") + iconName: "edit" + onClicked: openPopup(editCommunityPopup) + + Component { + id: editCommunityPopup + CreateCommunityPopup { + isEdit: true + } + } + } + } + + Loader { + active: isAdmin + width: parent.width + sourceComponent: CommunityPopupButton { + label: qsTr("Transfer ownership") + iconName: "../transfer" + onClicked: { + const exportResult = chatsModel.communities.exportComumnity() + openPopup(transferOwnershipPopup, {privateKey: exportResult}) + } + + Component { + id: transferOwnershipPopup + TransferOwnershipPopup {} + } + } + } + + CommunityPopupButton { + //% "Leave community" + label: qsTrId("leave-community") + iconName: "leave" + } + + Loader { + active: isAdmin + width: parent.width + sourceComponent: CommunityPopupButton { + id: deleteBtn + //% "Delete" + label: qsTrId("delete") + iconName: "delete" + txtColor: Style.current.danger + type: "warn" + } + } + } +}