2023-03-08 01:56:41 +00:00
|
|
|
|
import QtQuick 2.15
|
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
|
import QtQuick.Layouts 1.15
|
|
|
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
2024-03-08 09:27:45 +00:00
|
|
|
|
import StatusQ.Core.Utils 0.1
|
2023-03-08 01:56:41 +00:00
|
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
|
import StatusQ.Components 0.1
|
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
|
|
2023-05-02 08:01:04 +00:00
|
|
|
|
import shared.controls 1.0
|
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
import utils 1.0
|
|
|
|
|
|
|
|
|
|
import AppLayouts.Profile.popups 1.0
|
|
|
|
|
|
|
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
|
|
|
|
|
|
Control {
|
|
|
|
|
id: root
|
2024-03-08 09:27:45 +00:00
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
property var socialLinksModel
|
2024-03-08 20:11:48 +00:00
|
|
|
|
property int showcaseLimit: 20
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
|
|
background: null
|
|
|
|
|
|
2024-03-08 09:27:45 +00:00
|
|
|
|
signal addSocialLink(string url, string text)
|
|
|
|
|
signal updateSocialLink(int index, string url, string text)
|
|
|
|
|
signal removeSocialLink(int index)
|
|
|
|
|
signal changePosition(int from, int to)
|
|
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
|
id: d
|
|
|
|
|
|
|
|
|
|
function containsSocialLink(text, url) {
|
|
|
|
|
return ModelUtils.contains(socialLinksModel, "text", text, Qt.CaseInsensitive) &&
|
|
|
|
|
ModelUtils.contains(socialLinksModel, "url", url, Qt.CaseInsensitive)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
Component {
|
|
|
|
|
id: addSocialLinkModalComponent
|
|
|
|
|
AddSocialLinkModal {
|
2024-03-08 09:27:45 +00:00
|
|
|
|
containsSocialLink: d.containsSocialLink
|
|
|
|
|
onAddLinkRequested: root.addSocialLink(linkUrl, linkText)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Component {
|
|
|
|
|
id: modifySocialLinkModal
|
|
|
|
|
ModifySocialLinkModal {
|
2024-03-08 09:27:45 +00:00
|
|
|
|
containsSocialLink: d.containsSocialLink
|
|
|
|
|
onUpdateLinkRequested: root.updateSocialLink(index, linkUrl, linkText)
|
|
|
|
|
onRemoveLinkRequested: root.removeSocialLink(index)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contentItem: ColumnLayout {
|
|
|
|
|
id: layout
|
2024-10-15 19:26:12 +00:00
|
|
|
|
spacing: Theme.halfPadding
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
|
Layout.fillWidth: true
|
2024-10-15 19:26:12 +00:00
|
|
|
|
Layout.bottomMargin: Theme.padding
|
2023-03-08 01:56:41 +00:00
|
|
|
|
StatusBaseText {
|
2024-03-03 12:06:52 +00:00
|
|
|
|
text: qsTr("In showcase")
|
|
|
|
|
color: Theme.palette.directColor1
|
2023-03-08 01:56:41 +00:00
|
|
|
|
}
|
|
|
|
|
Item { Layout.fillWidth: true }
|
2023-06-06 11:59:50 +00:00
|
|
|
|
StatusBaseText {
|
2024-03-08 09:27:45 +00:00
|
|
|
|
text: qsTr("%1 / %2").arg(linksView.count).arg(root.showcaseLimit)
|
2023-06-06 11:59:50 +00:00
|
|
|
|
color: Theme.palette.baseColor1
|
2024-03-03 12:06:52 +00:00
|
|
|
|
font.pixelSize: Theme.tertiaryTextFontSize
|
2023-03-08 01:56:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// empty placeholder when no links; dashed rounded rectangle
|
|
|
|
|
ShapeRectangle {
|
2024-03-08 09:27:45 +00:00
|
|
|
|
readonly property bool maxReached: linksView.count === root.showcaseLimit
|
2023-06-06 11:59:50 +00:00
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
|
Layout.preferredWidth: parent.width - 4 // the rectangular path is rendered outside
|
2024-03-03 12:06:52 +00:00
|
|
|
|
Layout.preferredHeight: 48
|
|
|
|
|
|
2024-03-08 20:11:48 +00:00
|
|
|
|
text: maxReached ? qsTr("Link limit of %1 reached").arg(root.showcaseLimit) : ""
|
2024-03-03 12:06:52 +00:00
|
|
|
|
path.strokeColor: maxReached ? "transparent" : Theme.palette.baseColor2
|
|
|
|
|
path.fillColor: maxReached ? Theme.palette.baseColor4 : "transparent"
|
|
|
|
|
font.pixelSize: Theme.tertiaryTextFontSize
|
2023-06-06 11:59:50 +00:00
|
|
|
|
|
|
|
|
|
StatusLinkText {
|
|
|
|
|
objectName: "addMoreSocialLinks"
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
visible: !parent.maxReached
|
|
|
|
|
text: qsTr("+ Add a link")
|
|
|
|
|
color: Theme.palette.primaryColor1
|
|
|
|
|
font.pixelSize: Theme.tertiaryTextFontSize
|
|
|
|
|
font.weight: Font.Normal
|
|
|
|
|
onClicked: Global.openPopup(addSocialLinkModalComponent)
|
|
|
|
|
}
|
2023-03-08 01:56:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StatusListView {
|
|
|
|
|
id: linksView
|
2024-03-03 12:06:52 +00:00
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
Layout.fillWidth: true
|
2023-03-20 12:29:05 +00:00
|
|
|
|
Layout.preferredHeight: contentHeight
|
2024-03-03 12:06:52 +00:00
|
|
|
|
Layout.bottomMargin: ProfileUtils.defaultDelegateHeight / 2
|
|
|
|
|
|
2023-03-08 01:56:41 +00:00
|
|
|
|
model: root.socialLinksModel
|
2023-03-20 12:29:05 +00:00
|
|
|
|
interactive: false
|
2024-10-15 19:26:12 +00:00
|
|
|
|
spacing: Theme.halfPadding
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
|
|
displaced: Transition {
|
|
|
|
|
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delegate: DropArea {
|
|
|
|
|
id: delegateRoot
|
|
|
|
|
|
|
|
|
|
property int visualIndex: index
|
|
|
|
|
|
|
|
|
|
width: ListView.view.width
|
|
|
|
|
height: draggableDelegate.height
|
|
|
|
|
|
|
|
|
|
keys: ["x-status-draggable-list-item-internal"]
|
|
|
|
|
|
|
|
|
|
onEntered: function(drag) {
|
|
|
|
|
const from = drag.source.visualIndex
|
|
|
|
|
const to = draggableDelegate.visualIndex
|
|
|
|
|
if (to === from)
|
|
|
|
|
return
|
2024-03-08 09:27:45 +00:00
|
|
|
|
root.changePosition(from, to)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
drag.accept()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StatusDraggableListItem {
|
|
|
|
|
id: draggableDelegate
|
|
|
|
|
|
2024-03-08 09:27:45 +00:00
|
|
|
|
readonly property string asideText: ProfileUtils.stripSocialLinkPrefix(model.url, draggableDelegate.linkType)
|
|
|
|
|
readonly property int linkType: ProfileUtils.linkTextToType(model.text)
|
|
|
|
|
readonly property string iconName: ProfileUtils.linkTypeToIcon(draggableDelegate.linkType)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
|
|
visible: !!asideText
|
|
|
|
|
width: parent.width
|
2024-03-03 12:06:52 +00:00
|
|
|
|
height: visible ? ProfileUtils.defaultDelegateHeight : 0
|
|
|
|
|
topInset: 0
|
|
|
|
|
bottomInset: 0
|
2023-03-08 01:56:41 +00:00
|
|
|
|
|
|
|
|
|
anchors {
|
|
|
|
|
horizontalCenter: parent.horizontalCenter
|
|
|
|
|
verticalCenter: parent.verticalCenter
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dragParent: linksView
|
|
|
|
|
visualIndex: delegateRoot.visualIndex
|
|
|
|
|
draggable: linksView.count > 1
|
2024-03-08 09:27:45 +00:00
|
|
|
|
title: ProfileUtils.linkTypeToShortText(draggableDelegate.linkType) || model.text
|
2023-03-20 12:29:05 +00:00
|
|
|
|
hasIcon: true
|
2024-03-08 09:27:45 +00:00
|
|
|
|
icon.name: draggableDelegate.iconName
|
|
|
|
|
icon.color: ProfileUtils.linkTypeColor(draggableDelegate.linkType)
|
|
|
|
|
assetBgColor: ProfileUtils.linkTypeBgColor(draggableDelegate.linkType)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
actions: [
|
|
|
|
|
StatusLinkText {
|
|
|
|
|
Layout.fillWidth: true
|
2023-03-20 12:29:05 +00:00
|
|
|
|
Layout.maximumWidth: Math.ceil(implicitWidth)
|
2023-03-08 01:56:41 +00:00
|
|
|
|
Layout.alignment: Qt.AlignRight
|
|
|
|
|
horizontalAlignment: Text.AlignRight
|
|
|
|
|
font.pixelSize: Theme.primaryTextFontSize
|
|
|
|
|
font.weight: Font.Normal
|
|
|
|
|
text: draggableDelegate.asideText
|
|
|
|
|
onClicked: Global.openLink(model.url)
|
|
|
|
|
},
|
|
|
|
|
StatusFlatRoundButton {
|
|
|
|
|
icon.name: "edit_pencil"
|
|
|
|
|
Layout.preferredWidth: 24
|
|
|
|
|
Layout.preferredHeight: 24
|
|
|
|
|
icon.width: 16
|
|
|
|
|
icon.height: 16
|
|
|
|
|
type: StatusFlatRoundButton.Type.Tertiary
|
|
|
|
|
tooltip.text: qsTr("Edit link")
|
|
|
|
|
onClicked: Global.openPopup(modifySocialLinkModal,
|
2024-03-08 09:27:45 +00:00
|
|
|
|
{linkType: draggableDelegate.linkType, icon: draggableDelegate.iconName, index: delegateRoot.visualIndex,
|
2023-03-08 01:56:41 +00:00
|
|
|
|
linkText: model.text, linkUrl: draggableDelegate.asideText})
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|