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

346 lines
13 KiB
QML

import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Dialogs 1.3
import utils 1.0
import shared.panels 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
StatusModal {
id: popup
property bool isEdit: false
property string chatId: ""
property string categoryId: ""
property string channelName: ""
property string channelDescription: ""
property string channelEmoji: ""
property string channelColor: ""
property bool emojiPopupOpened: false
property var emojiPopup: null
readonly property var communityColorValidator: Utils.Validate.NoEmpty
| Utils.Validate.TextHexColor
readonly property int maxChannelNameLength: 24
readonly property int maxChannelDescLength: 140
signal createCommunityChannel(string chName, string chDescription, string chEmoji,
string chColor, string chCategoryId)
signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chColor,
string chCategoryId)
//% "New channel"
header.title: qsTrId("create-channel-title")
onOpened: {
contentItem.channelName.input.text = ""
contentItem.channelName.input.icon.emoji = ""
contentItem.channelName.input.edit.forceActiveFocus(Qt.MouseFocusReason)
if (isEdit) {
//% "Edit #%1"
header.title = qsTrId("edit---1").arg(popup.channelName);
contentItem.channelName.input.text = popup.channelName
contentItem.channelDescription.input.text = popup.channelDescription
if (popup.channelEmoji) {
contentItem.channelName.input.icon.emoji = popup.channelEmoji
}
scrollView.channelColorDialog.color = popup.channelColor
} else {
contentItem.channelName.input.icon.isLetterIdenticon = true;
}
}
onClosed: destroy()
Connections {
enabled: popup.opened && popup.emojiPopupOpened
target: emojiPopup
onEmojiSelected: function (emojiText, atCursor) {
contentItem.channelName.input.icon.isLetterIdenticon = false;
scrollView.channelName.input.icon.emoji = emojiText
}
onClosed: {
popup.emojiPopupOpened = false
}
}
function isFormValid() {
return (scrollView.channelName.valid &&
scrollView.channelDescription.valid) &&
Utils.validateAndReturnError(scrollView.channelColorDialog.color.toString().toUpperCase(),
communityColorValidator) === ""
}
contentItem: ScrollView {
id: scrollView
property ScrollBar vScrollBar: ScrollBar.vertical
property alias channelName: nameInput
property alias channelDescription: descriptionTextArea
property alias channelColorDialog: colorDialog
contentHeight: content.height
height: Math.min(content.height, 432)
width: popup.width
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
function scrollBackUp() {
vScrollBar.setPosition(0)
}
Column {
id: content
width: popup.width
topPadding: 16
StatusInput {
id: nameInput
anchors.left: parent.left
anchors.leftMargin: 16
label: qsTr("Channel name")
charLimit: popup.maxChannelNameLength
input.placeholderText: qsTr("Name the channel")
input.onTextChanged: {
input.text = Utils.convertSpacesToDashesAndUpperToLowerCase(input.text);
input.cursorPosition = input.text.length
if (popup.channelEmoji === "") {
input.letterIconName = text;
}
}
input.icon.color: colorDialog.color.toString()
input.leftPadding: 16
input.rightComponent: StatusRoundButton {
implicitWidth: 20
implicitHeight: 20
icon.width: implicitWidth
icon.height: implicitHeight
icon.name: "smiley"
onClicked: {
popup.emojiPopupOpened = true;
popup.emojiPopup.open();
popup.emojiPopup.emojiSize = StatusQUtils.Emoji.size.verySmall;
popup.emojiPopup.x = popup.width - 2*Style.current.xlPadding;
popup.emojiPopup.y = popup.y + nameInput.height + 2*Style.current.xlPadding;
}
}
validationMode: StatusInput.ValidationMode.Always
validators: [
StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(nameInput.errors, qsTr("channel name"))
}
]
}
Item {
id: spacer1
height: 16
width: parent.width
}
StatusBaseText {
text: qsTr("Channel colour")
font.pixelSize: 15
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.leftMargin: 16
}
Item {
id: spacer2
height: 8
width: parent.width
}
Item {
anchors.horizontalCenter: parent.horizontalCenter
height: colorSelectorButton.height + 16
width: parent.width - 32
StatusPickerButton {
id: colorSelectorButton
property string validationError: ""
bgColor: colorDialog.colorSelected ?
colorDialog.color : Theme.palette.baseColor2
// TODO adjust text color depending on the background color to make it readable
// contentColor: colorDialog.colorSelected ? Theme.palette.indirectColor1 : Theme.palette.baseColor1
text: colorDialog.colorSelected ?
colorDialog.color.toString().toUpperCase() :
//% "Pick a color"
qsTrId("pick-a-color")
onClicked: colorDialog.open();
onTextChanged: {
if (colorDialog.colorSelected) {
validationError = Utils.validateAndReturnError(text, communityColorValidator)
}
}
}
StatusColorDialog {
id: colorDialog
anchors.centerIn: parent
property bool colorSelected: popup.isEdit && popup.channelColor
color: popup.isEdit && popup.channelColor ? popup.channelColor :
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
}
}
StatusInput {
id: descriptionTextArea
anchors.left: parent.left
anchors.leftMargin: 16
label: qsTr("Description")
charLimit: 140
input.placeholderText: qsTr("Describe the channel")
input.multiline: true
input.implicitHeight: 88
validationMode: StatusInput.ValidationMode.Always
validators: [StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(descriptionTextArea.errors, qsTr("channel description"))
}]
}
/* TODO: use the code below to enable private channels and message limit */
/* StatusListItem { */
/* width: parent.width */
/* height: 56 */
/* sensor.enabled: false */
//% "Private channel"
/* title: qsTrId("private-channel") */
/* components: [ */
/* StatusSwitch { */
/* id: privateSwitch */
/* } */
/* ] */
/* } */
/* StatusBaseText { */
/* width: parent.width - 32 */
/* anchors.left: parent.left */
/* anchors.right: parent.right */
/* anchors.rightMargin: 121 */
/* anchors.leftMargin: 16 */
/* color: Theme.palette.baseColor1 */
/* wrapMode: Text.WordWrap */
//% "By making a channel private, only members with selected permission will be able to access it"
/* text: qsTrId("by-making-a-channel-private--only-members-with-selected-permission-will-be-able-to-access-it") */
/* } */
/* StatusModalDivider { */
/* topPadding: 8 */
/* bottomPadding: 8 */
/* } */
/* StatusListItem { */
/* width: parent.width */
/* height: 56 */
/* sensor.enabled: false */
//% "Message limit"
/* title: qsTrId("message-limit") */
/* components: [ */
/* StatusSwitch {} */
/* ] */
/* } */
/* StatusBaseText { */
/* width: parent.width - 32 */
/* anchors.left: parent.left */
/* anchors.right: parent.right */
/* anchors.rightMargin: 121 */
/* anchors.leftMargin: 16 */
/* color: Theme.palette.baseColor1 */
/* wrapMode: Text.WordWrap */
//% "Limit channel members to sending one message per chose time interval"
/* text: qsTrId("limit-channel-members-to-sending-one-message-per-chose-time-interval") */
/* } */
Item {
width: parent.width
height: 8
}
}
}
rightButtons: [
StatusButton {
enabled: isFormValid()
text: isEdit ?
//% "Save"
qsTrId("save") :
//% "Create"
qsTrId("create")
onClicked: {
if (!isFormValid()) {
scrollView.scrollBackUp()
return
}
let error = "";
let emoji = StatusQUtils.Emoji.deparseFromParse(popup.contentItem.channelName.input.icon.emoji)
if (!isEdit) {
//popup.contentItem.communityColor.color.toString().toUpperCase()
popup.createCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text),
Utils.filterXSS(popup.contentItem.channelDescription.input.text),
emoji,
popup.contentItem.channelColorDialog.color.toString().toUpperCase(),
popup.categoryId)
} else {
popup.editCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text),
Utils.filterXSS(popup.contentItem.channelDescription.input.text),
emoji,
popup.contentItem.channelColorDialog.color.toString().toUpperCase(),
popup.categoryId)
}
if (error) {
const errorJson = JSON.parse(error)
creatingError.text = errorJson.error
return creatingError.open()
}
// TODO Open the community once we have designs for it
popup.close()
}
}
]
MessageDialog {
id: creatingError
//% "Error creating the community"
title: qsTrId("error-creating-the-community")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
}