2023-03-08 01:56:41 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
|
|
|
|
|
|
|
import utils 1.0
|
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
import StatusQ.Controls 0.1
|
2023-06-06 11:59:50 +00:00
|
|
|
import StatusQ.Controls.Validators 0.1
|
2023-03-08 01:56:41 +00:00
|
|
|
import StatusQ.Components 0.1
|
|
|
|
import StatusQ.Popups 0.1
|
|
|
|
|
|
|
|
import AppLayouts.Profile.controls 1.0
|
|
|
|
|
|
|
|
StatusStackModal {
|
|
|
|
id: root
|
|
|
|
|
2023-06-06 11:59:50 +00:00
|
|
|
property var containsSocialLink: function (text, url) {return false}
|
2023-03-08 01:56:41 +00:00
|
|
|
signal addLinkRequested(string linkText, string linkUrl, int linkType, string linkIcon)
|
|
|
|
|
|
|
|
implicitWidth: 480 // design
|
|
|
|
implicitHeight: 512 // design
|
|
|
|
anchors.centerIn: parent
|
2024-10-15 19:26:12 +00:00
|
|
|
padding: currentIndex === 0 ? 0 : Theme.padding
|
2023-03-08 01:56:41 +00:00
|
|
|
|
2024-03-03 12:06:52 +00:00
|
|
|
headerSettings.title: currentIndex === 0 ? qsTr("Add a link") :
|
|
|
|
qsTr("Add %1 link").arg(ProfileUtils.linkTypeToText(d.selectedLinkType) || qsTr("custom"))
|
2023-03-08 01:56:41 +00:00
|
|
|
rightButtons: [finishButton]
|
|
|
|
finishButton: StatusButton {
|
|
|
|
text: qsTr("Add")
|
2024-05-20 10:11:37 +00:00
|
|
|
objectName: "addButton"
|
2023-06-06 11:59:50 +00:00
|
|
|
enabled: linkTarget.valid && (!customTitle.visible || customTitle.valid)
|
2023-03-08 01:56:41 +00:00
|
|
|
onClicked: {
|
|
|
|
root.addLinkRequested(d.selectedLinkTypeText || customTitle.text, // text for custom link, otherwise the link typeId
|
|
|
|
ProfileUtils.addSocialLinkPrefix(linkTarget.text, d.selectedLinkType),
|
|
|
|
d.selectedLinkType, d.selectedIcon)
|
|
|
|
root.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
showFooter: currentIndex > 0
|
|
|
|
|
|
|
|
onClosed: destroy()
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: d
|
|
|
|
|
|
|
|
property int selectedLinkIndex: -1
|
|
|
|
readonly property int selectedLinkType: d.selectedLinkIndex !== -1 ? staticLinkTypesModel.get(d.selectedLinkIndex).type : 0
|
|
|
|
readonly property string selectedLinkTypeText: d.selectedLinkIndex !== -1 ? staticLinkTypesModel.get(d.selectedLinkIndex).text : ""
|
|
|
|
readonly property string selectedIcon: d.selectedLinkIndex !== -1 ? staticLinkTypesModel.get(d.selectedLinkIndex).icon : ""
|
|
|
|
|
|
|
|
readonly property var staticLinkTypesModel: ListModel {
|
|
|
|
readonly property var data: [
|
2024-03-03 12:06:52 +00:00
|
|
|
{ type: Constants.socialLinkType.twitter, icon: "xtwitter", text: "__twitter" },
|
2023-03-08 01:56:41 +00:00
|
|
|
{ type: Constants.socialLinkType.personalSite, icon: "language", text: "__personal_site" },
|
|
|
|
{ type: Constants.socialLinkType.github, icon: "github", text: "__github" },
|
|
|
|
{ type: Constants.socialLinkType.youtube, icon: "youtube", text: "__youtube" },
|
|
|
|
{ type: Constants.socialLinkType.discord, icon: "discord", text: "__discord" },
|
|
|
|
{ type: Constants.socialLinkType.telegram, icon: "telegram", text: "__telegram" },
|
|
|
|
{ type: Constants.socialLinkType.custom, icon: "link", text: "" }
|
|
|
|
]
|
|
|
|
Component.onCompleted: append(data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onCurrentIndexChanged: {
|
|
|
|
//StatusAnimatedStack doesn't handle well items' visibility,
|
|
|
|
//keeping this solution for now until #8024 is fixed
|
|
|
|
if (currentIndex === 1) {
|
|
|
|
customTitle.input.edit.clear()
|
|
|
|
linkTarget.input.edit.clear()
|
|
|
|
if (d.selectedLinkType === Constants.socialLinkType.custom)
|
|
|
|
customTitle.input.edit.forceActiveFocus()
|
|
|
|
else
|
|
|
|
linkTarget.input.edit.forceActiveFocus()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stackItems: [
|
|
|
|
StatusListView {
|
|
|
|
width: root.availableWidth
|
|
|
|
height: root.availableHeight
|
|
|
|
model: d.staticLinkTypesModel
|
|
|
|
delegate: StatusListItem {
|
|
|
|
width: ListView.view.width
|
|
|
|
title: ProfileUtils.linkTypeToText(model.type) || qsTr("Custom link")
|
|
|
|
asset.name: model.icon
|
|
|
|
asset.color: ProfileUtils.linkTypeColor(model.type)
|
2024-03-03 12:06:52 +00:00
|
|
|
asset.bgColor: ProfileUtils.linkTypeBgColor(model.type)
|
2023-03-08 01:56:41 +00:00
|
|
|
onClicked: {
|
2023-06-06 11:59:50 +00:00
|
|
|
customTitle.reset()
|
|
|
|
linkTarget.reset()
|
2023-03-08 01:56:41 +00:00
|
|
|
d.selectedLinkIndex = index
|
|
|
|
root.currentIndex++
|
|
|
|
}
|
|
|
|
components: [
|
|
|
|
StatusIcon {
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
icon: "next"
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ColumnLayout {
|
|
|
|
width: root.availableWidth
|
2024-10-15 19:26:12 +00:00
|
|
|
spacing: Theme.halfPadding
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
StaticSocialLinkInput {
|
|
|
|
id: customTitle
|
|
|
|
Layout.fillWidth: true
|
|
|
|
visible: d.selectedLinkType === Constants.socialLinkType.custom
|
|
|
|
placeholderText: ""
|
2024-03-03 12:06:52 +00:00
|
|
|
label: qsTr("Title")
|
2023-03-08 01:56:41 +00:00
|
|
|
linkType: Constants.socialLinkType.custom
|
|
|
|
icon: "language"
|
|
|
|
charLimit: Constants.maxSocialLinkTextLength
|
|
|
|
input.tabNavItem: linkTarget.input.edit
|
2023-06-06 11:59:50 +00:00
|
|
|
validators: [
|
|
|
|
StatusValidator {
|
|
|
|
name: "text-validation"
|
|
|
|
validate: (value) => {
|
|
|
|
return value.trim() !== ""
|
|
|
|
}
|
|
|
|
errorMessage: qsTr("Invalid title")
|
|
|
|
},
|
|
|
|
StatusValidator {
|
|
|
|
name: "check-social-link-existence"
|
|
|
|
validate: (value) => {
|
|
|
|
return !root.containsSocialLink(value,
|
|
|
|
ProfileUtils.addSocialLinkPrefix(linkTarget.text, d.selectedLinkType))
|
|
|
|
}
|
|
|
|
errorMessage: d.selectedLinkType === Constants.socialLinkType.custom?
|
2024-03-03 12:06:52 +00:00
|
|
|
qsTr("Ttile and link combination already added") :
|
|
|
|
qsTr("Username already added")
|
2023-06-06 11:59:50 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
onValidChanged: {linkTarget.validate(true)}
|
|
|
|
onTextChanged: {linkTarget.validate(true)}
|
2023-03-08 01:56:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StaticSocialLinkInput {
|
|
|
|
id: linkTarget
|
|
|
|
Layout.fillWidth: true
|
2024-10-15 19:26:12 +00:00
|
|
|
Layout.topMargin: customTitle.visible ? Theme.padding : 0
|
2023-03-08 01:56:41 +00:00
|
|
|
placeholderText: ""
|
2024-03-03 12:06:52 +00:00
|
|
|
label: linkType === Constants.socialLinkType.custom ? qsTr("Link") : qsTr("Username")
|
2023-03-08 01:56:41 +00:00
|
|
|
linkType: d.selectedLinkType
|
|
|
|
icon: d.selectedIcon
|
|
|
|
input.tabNavItem: customTitle.input.edit
|
2023-06-06 11:59:50 +00:00
|
|
|
|
|
|
|
validators: [
|
|
|
|
StatusValidator {
|
|
|
|
name: "link-validation"
|
|
|
|
validate: (value) => {
|
|
|
|
return value.trim() !== "" && Utils.validLink(ProfileUtils.addSocialLinkPrefix(value, d.selectedLinkType))
|
|
|
|
}
|
|
|
|
errorMessage: qsTr("Invalid %1").arg(ProfileUtils.linkTypeToDescription(linkTarget.linkType).toLowerCase() || qsTr("link"))
|
|
|
|
},
|
|
|
|
StatusValidator {
|
|
|
|
name: "check-social-link-existence"
|
|
|
|
validate: (value) => {
|
|
|
|
return !root.containsSocialLink(d.selectedLinkTypeText || customTitle.text,
|
|
|
|
ProfileUtils.addSocialLinkPrefix(value, d.selectedLinkType))
|
|
|
|
}
|
|
|
|
errorMessage: d.selectedLinkType === Constants.socialLinkType.custom?
|
2024-03-03 12:06:52 +00:00
|
|
|
qsTr("Title and link combination already added") :
|
|
|
|
qsTr("Username already added")
|
2023-06-06 11:59:50 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
onValidChanged: {customTitle.validate(true)}
|
|
|
|
onTextChanged: {customTitle.validate(true)}
|
2023-03-08 01:56:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|