refactor(Communities): use `StatusModal` in `CreateCommunityPopup`

This replaces the modal popup with `StatusModal` in the `CreateCommunityPopup`
and also ensures that it adheres to the design.

There are still things to be refactored in here, primarily form control components.
Those will be tackled in future commits once they have been built in StatusQ

Closes #2882
This commit is contained in:
Pascal Precht 2021-07-16 12:11:03 +02:00 committed by Iuri Matias
parent 9795890544
commit 9eb752885d
3 changed files with 301 additions and 298 deletions

View File

@ -4,9 +4,14 @@ import QtGraphicalEffects 1.13
import QtQuick.Dialogs 1.3
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
ModalPopup {
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
StatusModal {
property QtObject community: chatsModel.communities.activeCommunity
property bool isEdit: false
@ -23,72 +28,81 @@ ModalPopup {
| Utils.Validate.TextHexColor
id: popup
height: 600
onOpened: {
if (isEdit) {
nameInput.text = community.name;
descriptionTextArea.text = community.description;
colorPicker.defaultColor = community.communityColor;
contentComponent.communityName.text = community.name;
contentComponent.communityDescription.text = community.description;
contentComponent.communityColor.color = community.communityColor;
contentComponent.communityColor.colorSelected = true
if (community.largeImage) {
addImageButton.selectedImage = community.largeImage
contentComponent.communityImage.selectedImage = community.largeImage
}
membershipRequirementSettingPopup.checkedMembership = community.access
}
nameInput.forceActiveFocus(Qt.MouseFocusReason)
contentComponent.communityName.forceActiveFocus(Qt.MouseFocusReason)
}
onClosed: destroy()
function isFormValid() {
return Utils.validateAndReturnError(nameInput.text,
return Utils.validateAndReturnError(contentComponent.communityName.text,
communityNameValidator,
//% "community name"
qsTrId("community-name"),
maxCommunityNameLength) === ""
&& Utils.validateAndReturnError(descriptionTextArea.text,
&& Utils.validateAndReturnError(contentComponent.communityDescription.text,
communityDescValidator,
//% "community decription"
qsTrId("community-decription"),
maxCommunityDescLength) === ""
&& Utils.validateAndReturnError(colorPicker.text,
&& Utils.validateAndReturnError(contentComponent.communityColor.color.toString().toUpperCase(),
communityColorValidator) === ""
}
title: isEdit ?
header.title: isEdit ?
//% "Edit community"
qsTrId("edit-community") :
//% "New community"
qsTrId("new-community")
ScrollView {
property ScrollBar vScrollBar: ScrollBar.vertical
content: ScrollView {
id: scrollView
anchors.fill: parent
rightPadding: Style.current.padding
anchors.rightMargin: -Style.current.padding
anchors.topMargin: -Style.current.padding
leftPadding: Style.current.padding
topPadding: Style.current.padding
anchors.leftMargin: -Style.current.padding
property ScrollBar vScrollBar: ScrollBar.vertical
property alias communityName: nameInput
property alias communityDescription: descriptionTextArea
property alias communityColor: colorDialog
property alias communityImage: addImageButton
property alias imageCropperModal: imageCropperModal
contentHeight: content.height
bottomPadding: 8
height: Math.min(content.height, 432)
width: popup.width
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
clip: true
function scrollBackUp() {
vScrollBar.setPosition(0)
}
Item {
Column {
id: content
height: childrenRect.height + 100 // Bottom padding
width: parent.width
width: popup.width
Item {
width: parent.width
height: 76
Input {
id: nameInput
//% "Name your community"
label: qsTrId("name-your-community")
width: parent.width - 32
anchors.centerIn: parent
//% "A catchy name"
placeholderText: qsTrId("name-your-community-placeholder")
maxLength: maxCommunityNameLength
@ -96,21 +110,26 @@ ModalPopup {
onTextEdited: {
validationError = Utils.validateAndReturnError(text,
communityNameValidator,
//% "community name"
qsTrId("community-name"),
qsTr("community name"),
maxCommunityNameLength)
}
}
}
Item {
height: descriptionTextArea.height + 26
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
StyledTextArea {
id: descriptionTextArea
//% "Give it a short description"
label: qsTrId("give-a-short-description-community")
label: qsTr("Description")
//% "What your community is about"
placeholderText: qsTrId("what-your-community-is-about")
anchors.top: nameInput.bottom
anchors.topMargin: Style.current.bigPadding
customHeight: 88
textField.wrapMode: TextEdit.Wrap
@ -123,8 +142,7 @@ ModalPopup {
validationError = Utils.validateAndReturnError(text,
communityDescValidator,
//% "community decription"
qsTrId("community-decription"),
qsTr("community decription"),
maxCommunityDescLength)
}
}
@ -132,24 +150,25 @@ ModalPopup {
StyledText {
id: charLimit
text: `${descriptionTextArea.text.length}/${maxCommunityDescLength}`
anchors.top: descriptionTextArea.bottom
anchors.topMargin: !descriptionTextArea.validationError ? 5 : - Style.current.smallPadding
anchors.right: descriptionTextArea.right
font.pixelSize: 12
color: !descriptionTextArea.validationError ? Style.current.textColor : Style.current.danger
}
}
StyledText {
StatusBaseText {
id: thumbnailText
//% "Thumbnail image"
text: qsTrId("thumbnail-image")
anchors.top: charLimit.bottom
anchors.topMargin: Style.current.smallPadding
font.pixelSize: 13
color: Style.current.textColor
font.weight: Font.Medium
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.leftMargin: 16
}
Item {
width: parent.width
height: addImageButton.height + 32
Rectangle {
id: addImageButton
@ -157,12 +176,9 @@ ModalPopup {
width: 128
height: width
radius: width / 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: thumbnailText.bottom
anchors.topMargin: Style.current.padding
anchors.centerIn: parent
property string selectedImage: ""
FileDialog {
id: imageDialog
//% "Please choose an image"
@ -210,8 +226,7 @@ ModalPopup {
visible: !imagePreview.visible
width: uploadText.width
height: childrenRect.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.centerIn: parent
SVGImage {
id: imageImg
@ -232,25 +247,18 @@ ModalPopup {
}
}
Rectangle {
color: Style.current.primary
width: 40
height: width
radius: width / 2
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "add"
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: Style.current.halfPadding
SVGImage {
source: "../../../img/plusSign.svg"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 13
height: 13
}
highlighted: sensor.containsMouse
}
MouseArea {
id: sensor
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: imageDialog.open()
@ -261,82 +269,72 @@ ModalPopup {
selectedImage: addImageButton.selectedImage
ratio: "1:1"
}
}
StyledText {
id: imageValidation
visible: text && text !== ""
anchors.top: addImageButton.bottom
anchors.topMargin: Style.current.smallPadding
}
StatusBaseText {
text: qsTr("Community colour")
font.pixelSize: 13
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
color: Style.current.danger
anchors.leftMargin: 16
}
Input {
property string defaultColor: Style.current.blue
Item {
anchors.horizontalCenter: parent.horizontalCenter
height: colorSelectorButton.height + 16
width: parent.width - 32
id: colorPicker
//% "Community color"
label: qsTrId("community-color")
//% "Pick a color"
placeholderText: qsTrId("pick-a-color")
anchors.top: imageValidation.bottom
anchors.topMargin: Style.current.smallPadding
textField.text: defaultColor
textField.onReleased: colorDialog.open()
StatusPickerButton {
id: colorSelectorButton
anchors.top: parent.top
anchors.topMargin: 10
property string validationError: ""
bgColor: colorDialog.colorSelected ?
colorDialog.color : Theme.palette.baseColor2
contentColor: colorDialog.colorSelected ? Theme.palette.indirectColor1 : Theme.palette.baseColor1
text: colorDialog.colorSelected ?
colorDialog.color.toString().toUpperCase() :
qsTr("Pick a color")
onClicked: colorDialog.open();
onTextChanged: {
if (colorDialog.colorSelected) {
validationError = Utils.validateAndReturnError(text, communityColorValidator)
}
StatusIconButton {
icon.name: "caret"
iconRotation: -90
iconColor: Style.current.textColor
icon.width: 13
icon.height: 7
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.top: parent.top
anchors.topMargin: colorPicker.textField.height / 2 - height / 2 + Style.current.bigPadding
onClicked: colorDialog.open()
}
ColorDialog {
id: colorDialog
//% "Please choose a color"
title: qsTrId("please-choose-a-color")
color: colorPicker.defaultColor
onAccepted: {
colorPicker.text = colorDialog.color
}
property bool colorSelected: false
color: Theme.palette.primaryColor1
onAccepted: colorSelected = true
}
}
Separator {
id: separator1
anchors.top: colorPicker.bottom
anchors.topMargin: isEdit ? 0 : Style.current.bigPadding
anchors.left: parent.left
anchors.leftMargin: -Style.current.padding
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
StatusBaseText {
text: colorSelectorButton.validationError
visible: !!text
color: Theme.palette.dangerColor1
anchors.top: colorSelectorButton.bottom
anchors.topMargin: 4
anchors.right: colorSelectorButton.right
}
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
visible: !isEdit
}
StatusSettingsLineButton {
id: membershipRequirementSetting
// TODO: remove 'isEnabled: false' when we no longer need to force
// "request access" membership
isEnabled: false
anchors.top: separator1.bottom
anchors.topMargin: Style.current.halfPadding
//% "Membership requirement"
text: qsTrId("membership-title")
currentValue: {
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: !isEdit
title: qsTr("Membership requirement")
label: {
switch (membershipRequirementSettingPopup.checkedMembership) {
//% "Require invite from another member"
case Constants.communityChatInvitationOnlyAccess: return qsTrId("membership-invite")
@ -346,23 +344,26 @@ ModalPopup {
default: return qsTrId("membership-free")
}
}
onClicked: {
membershipRequirementSettingPopup.open()
sensor.onClicked: membershipRequirementSettingPopup.open()
components: [
StatusIcon {
icon: "chevron-down"
rotation: 270
color: Theme.palette.baseColor1
}
]
}
StyledText {
StatusBaseText {
visible: !isEdit
height: visible ? implicitHeight : 0
id: privateExplanation
anchors.top: membershipRequirementSetting.bottom
wrapMode: Text.WordWrap
anchors.topMargin: isEdit ? 0 : Style.current.halfPadding
font.pixelSize: 13
color: Style.current.secondaryText
color: Theme.palette.baseColor1
width: parent.width * 0.78
//% "You can require new members to meet certain criteria before they can join. This can be changed at any time"
text: qsTrId("membership-none-placeholder")
text: qsTr("You can require new members to meet certain criteria before they can join. This can be changed at any time")
anchors.left: parent.left
anchors.leftMargin: 16
}
// Feature commented temporarily
@ -410,23 +411,11 @@ ModalPopup {
*/
}
MembershipRequirementPopup {
id: membershipRequirementSettingPopup
// TODO: remove the 'checkedMemership' setting when we no longer need
// to force "require approval" membership
checkedMembership: Constants.communityChatOnRequestAccess
}
}
footer: Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: btnCreateEdit.height
leftButtons: [
StatusRoundButton {
id: btnBack
anchors.left: parent.left
visible: isEdit
icon.name: "arrow-right"
icon.width: 20
@ -434,6 +423,9 @@ ModalPopup {
rotation: 180
onClicked: popup.destroy()
}
]
rightButtons: [
StatusButton {
id: btnCreateEdit
enabled: isFormValid()
@ -442,38 +434,42 @@ ModalPopup {
qsTrId("Save") :
//% "Create"
qsTrId("create")
anchors.right: parent.right
onClicked: {
if (!isFormValid()) {
scrollView.scrollBackUp()
popup.contentComponent.scrollBackUp()
return
}
let error = false;
if(isEdit) {
error = chatsModel.communities.editCommunity(community.id,
Utils.filterXSS(nameInput.text),
Utils.filterXSS(descriptionTextArea.text),
error = chatsModel.communities.editCommunity(
community.id,
Utils.filterXSS(popup.contentComponent.communityName.text),
Utils.filterXSS(popup.contentComponent.communityDescription.text),
membershipRequirementSettingPopup.checkedMembership,
false,
colorPicker.text,
popup.contentComponent.communityColor.color.toString().toUpperCase(),
// to retain the existing image, pass "" for the image path
addImageButton.selectedImage === community.largeImage ? "" : addImageButton.selectedImage,
imageCropperModal.aX,
imageCropperModal.aY,
imageCropperModal.bX,
imageCropperModal.bY)
popup.contentComponent.communityImage.selectedImage === community.largeImage ? "" :
popup.contentComponent.communityImage.selectedImage,
popup.contentComponent.imageCropperModal.aX,
popup.contentComponent.imageCropperModal.aY,
popup.contentComponent.imageCropperModal.bX,
popup.contentComponent.imageCropperModal.bY
)
} else {
error = chatsModel.communities.createCommunity(Utils.filterXSS(nameInput.text),
Utils.filterXSS(descriptionTextArea.text),
error = chatsModel.communities.createCommunity(
Utils.filterXSS(popup.contentComponent.communityName.text),
Utils.filterXSS(popup.contentComponent.communityDescription.text),
membershipRequirementSettingPopup.checkedMembership,
false, // ensOnlySwitch.switchChecked, // TODO:
colorPicker.text,
addImageButton.selectedImage,
imageCropperModal.aX,
imageCropperModal.aY,
imageCropperModal.bX,
imageCropperModal.bY)
popup.contentComponent.communityColor.color.toString().toUpperCase(),
popup.contentComponent.communityImage.selectedImage,
popup.contentComponent.imageCropperModal.aX,
popup.contentComponent.imageCropperModal.aY,
popup.contentComponent.imageCropperModal.bX,
popup.contentComponent.imageCropperModal.bY
)
}
if (error) {
@ -483,6 +479,8 @@ ModalPopup {
popup.close()
}
}
]
MessageDialog {
id: creatingError
@ -491,7 +489,12 @@ ModalPopup {
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
}
MembershipRequirementPopup {
id: membershipRequirementSettingPopup
// TODO: remove the 'checkedMemership' setting when we no longer need
// to force "require approval" membership
checkedMembership: Constants.communityChatOnRequestAccess
}
}

View File

@ -210,6 +210,7 @@ Item {
Component {
id: createCommunitiesPopupComponent
CreateCommunityPopup {
anchors.centerIn: parent
onClosed: {
destroy()
}

View File

@ -174,9 +174,8 @@ StatusAppLayout {
}
StatusMenuItem {
enabled: false//chatsModel.communities.observedCommunity.admin
//% "Edit Community"
text: qsTrId("edit-community")
enabled: chatsModel.communities.observedCommunity.admin
text: qsTr("Edit Community")
icon.name: "edit"
onTriggered: openPopup(editCommunityPopup, {community: chatsModel.communities.observedCommunity})
}