status-desktop/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml

413 lines
15 KiB
QML

import QtQuick 2.12
import QtQuick.Controls 2.3
import QtGraphicalEffects 1.13
import QtQuick.Dialogs 1.3
import utils 1.0
import shared.panels 1.0
import shared.popups 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Popups 0.1
StatusModal {
id: popup
height: 509
property var store
property var communitySectionModule
property bool isEdit: false
property QtObject community: null
property var onSave: () => {}
readonly property int maxCommunityNameLength: 30
readonly property int maxCommunityDescLength: 140
readonly property var communityColorValidator: Utils.Validate.NoEmpty
| Utils.Validate.TextHexColor
onOpened: {
if (isEdit) {
contentItem.communityName.input.text = community.name;
contentItem.communityDescription.input.text = community.description;
contentItem.communityColor.color = community.color;
contentItem.communityColor.colorSelected = true
if (community.largeImage) {
contentItem.communityImage.selectedImage = community.largeImage
}
requestToJoinCheckbox.checked = community.access === Constants.communityChatOnRequestAccess
}
contentItem.communityName.input.edit.forceActiveFocus()
}
onClosed: destroy()
function isFormValid() {
return contentItem.communityName.valid && contentItem.communityDescription.valid &&
Utils.validateAndReturnError(contentItem.communityColor.color.toString().toUpperCase(),
communityColorValidator) === ""
}
header.title: isEdit ?
qsTr("Edit Community") :
qsTr("Create New Community")
contentItem: ScrollView {
id: scrollView
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
property alias historyArchiveSupportToggle: historyArchiveSupportToggle
contentHeight: content.height
bottomPadding: 8
width: popup.width
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
function scrollBackUp() {
vScrollBar.setPosition(0)
}
Column {
id: content
width: popup.width
spacing: 8
Item {
height: 8
width: parent.width
}
StatusInput {
id: nameInput
label: qsTr("Name your community")
charLimit: maxCommunityNameLength
input.placeholderText: qsTr("A catchy name")
validators: [
StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(nameInput.errors, "community name")
},
StatusRegularExpressionValidator {
regularExpression: /^[^<>]+$/
errorMessage: qsTr("This is not a valid community name")
}
]
validationMode: StatusInput.ValidationMode.Always
}
StatusInput {
id: descriptionTextArea
label: qsTr("Give it a short description")
charLimit: maxCommunityDescLength
input.placeholderText: qsTr("What your community is about")
input.multiline: true
input.implicitHeight: 88
input.verticalAlignment: TextEdit.AlignTop
validators: [StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(descriptionTextArea.errors, "community description")
}]
validationMode: StatusInput.ValidationMode.Always
}
StatusBaseText {
id: thumbnailText
//% "Thumbnail image"
text: qsTrId("thumbnail-image")
font.pixelSize: 15
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.leftMargin: 16
anchors.topMargin: 8
}
Item {
width: parent.width
height: addImageButton.height + 32
Rectangle {
id: addImageButton
color: imagePreview.visible ? "transparent" : Style.current.inputBackground
width: 128
height: width
radius: width / 2
anchors.centerIn: parent
property string selectedImage: ""
FileDialog {
id: imageDialog
//% "Please choose an image"
title: qsTrId("please-choose-an-image")
folder: shortcuts.pictures
nameFilters: [
//% "Image files (*.jpg *.jpeg *.png)"
qsTrId("image-files----jpg---jpeg---png-")
]
onAccepted: {
addImageButton.selectedImage = imageDialog.fileUrls[0]
imageCropperModal.open()
}
}
Rectangle {
id: imagePreviewCropper
clip: true
width: parent.width
height: parent.height
radius: parent.width / 2
visible: !!addImageButton.selectedImage
Image {
id: imagePreview
visible: !!addImageButton.selectedImage
source: addImageButton.selectedImage
fillMode: Image.PreserveAspectFit
width: parent.width
height: parent.height
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
anchors.centerIn: parent
width: imageCropperModal.width
height: imageCropperModal.height
radius: width / 2
}
}
}
Item {
id: addImageCenter
visible: !imagePreview.visible
width: uploadText.width
height: childrenRect.height
anchors.centerIn: parent
SVGImage {
id: imageImg
source: Style.svg("images_icon")
width: 20
height: 18
anchors.horizontalCenter: parent.horizontalCenter
}
StatusBaseText {
id: uploadText
//% "Upload"
text: qsTrId("upload")
anchors.top: imageImg.bottom
anchors.topMargin: 5
font.pixelSize: 15
color: Theme.palette.baseColor1
}
}
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "add"
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: Style.current.halfPadding
highlighted: sensor.containsMouse
}
MouseArea {
id: sensor
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: imageDialog.open()
}
ImageCropperModal {
id: imageCropperModal
selectedImage: addImageButton.selectedImage
ratio: "1:1"
}
}
}
StatusBaseText {
text: qsTr("Community colour")
font.pixelSize: 15
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.leftMargin: 16
}
Item {
anchors.horizontalCenter: parent.horizontalCenter
height: colorSelectorButton.height + 16
width: parent.width - 32
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 colour")
onClicked: colorDialog.open();
onTextChanged: {
if (colorDialog.colorSelected) {
validationError = Utils.validateAndReturnError(text, communityColorValidator)
}
}
ColorDialog {
id: colorDialog
property bool colorSelected: false
color: Theme.palette.primaryColor1
onAccepted: colorSelected = true
}
}
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
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: popup.store.isCommunityHistoryArchiveSupportEnabled
title: qsTr("Community history service")
sensor.onClicked: {
if (popup.store.isCommunityHistoryArchiveSupportEnabled) {
historyArchiveSupportToggle.checked = !historyArchiveSupportToggle.checked
}
}
components: [
StatusCheckBox {
id: historyArchiveSupportToggle
enabled: popup.store.isCommunityHistoryArchiveSupportEnabled
checked: isEdit ? community.historyArchiveSupportEnabled : false
}
]
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: qsTr("Request to join required")
sensor.onClicked: {
requestToJoinCheckbox.checked = !requestToJoinCheckbox.checked
}
components: [
StatusCheckBox {
id: requestToJoinCheckbox
checked: true
}
]
}
}
}
leftButtons: [
StatusRoundButton {
id: btnBack
visible: isEdit
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
rotation: 180
onClicked: popup.destroy()
}
]
rightButtons: [
StatusButton {
id: btnCreateEdit
enabled: isFormValid()
text: isEdit ?
//% "Save"
qsTrId("Save") :
//% "Create"
qsTrId("create")
onClicked: {
if (!isFormValid()) {
popup.contentItem.scrollBackUp()
return
}
let error = false;
if(isEdit) {
error = communitySectionModule.editCommunity(
Utils.filterXSS(popup.contentItem.communityName.input.text),
Utils.filterXSS(popup.contentItem.communityDescription.input.text),
requestToJoinCheckbox.checked ? Constants.communityChatOnRequestAccess : Constants.communityChatPublicAccess,
popup.contentItem.communityColor.color.toString().toUpperCase(),
// to retain the existing image, pass "" for the image path
popup.contentItem.communityImage.selectedImage === community.largeImage ? "" :
popup.contentItem.communityImage.selectedImage,
popup.contentItem.imageCropperModal.aX,
popup.contentItem.imageCropperModal.aY,
popup.contentItem.imageCropperModal.bX,
popup.contentItem.imageCropperModal.bY,
popup.contentItem.historyArchiveSupportToggle.checked
)
} else {
error = popup.store.createCommunity(
Utils.filterXSS(popup.contentItem.communityName.input.text),
Utils.filterXSS(popup.contentItem.communityDescription.input.text),
requestToJoinCheckbox.checked ? Constants.communityChatOnRequestAccess : Constants.communityChatPublicAccess,
popup.contentItem.communityColor.color.toString().toUpperCase(),
popup.contentItem.communityImage.selectedImage,
popup.contentItem.imageCropperModal.aX,
popup.contentItem.imageCropperModal.aY,
popup.contentItem.imageCropperModal.bX,
popup.contentItem.imageCropperModal.bY,
popup.contentItem.historyArchiveSupportToggle.checked
)
}
if (error) {
creatingError.text = error.error
return creatingError.open()
}
popup.onSave()
popup.close()
}
}
]
MessageDialog {
id: creatingError
//% "Error creating the community"
title: qsTrId("error-creating-the-community")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
}