feat(settings/profile): add social links' ui primitives
iterates: #6797
This commit is contained in:
parent
6783f3a321
commit
46e01afa04
|
@ -0,0 +1,91 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias hyperlink: hyperlinkInput.text
|
||||
property alias url: urlInput.text
|
||||
readonly property alias removeButton: removeButton
|
||||
|
||||
implicitHeight: layout.implicitHeight
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
id: leftLayout
|
||||
|
||||
spacing: 26
|
||||
|
||||
StatusInput {
|
||||
id: hyperlinkInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("Hyperlink Text")
|
||||
placeholderText: qsTr("Example: My Myspace Profile")
|
||||
charLimit: 24
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: urlInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("URL")
|
||||
placeholderText: qsTr("Link URL")
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 280
|
||||
Layout.fillHeight: true
|
||||
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
x: 64
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
spacing: 10
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Preview")
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
SocialLinkPreview {
|
||||
text: !!hyperlinkInput.text ? hyperlinkInput.text : qsTr("My Myspace Profile")
|
||||
url: !!urlInput.text ? urlInput.text : urlInput.placeholderText
|
||||
linkType: Constants.socialLinkType.custom
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusFlatButton {
|
||||
id: removeButton
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
icon.name: "delete"
|
||||
text: qsTr("Remove")
|
||||
size: StatusBaseButton.Small
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import QtQuick 2.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
StatusInput {
|
||||
id: root
|
||||
|
||||
property int linkType
|
||||
|
||||
placeholderText: {
|
||||
if (linkType === Constants.socialLinkType.twitter) return qsTr("Twitter Handle")
|
||||
if (linkType === Constants.socialLinkType.personalSite) return qsTr("Personal Site")
|
||||
if (linkType === Constants.socialLinkType.github) return qsTr("Github")
|
||||
if (linkType === Constants.socialLinkType.youtube) return qsTr("YouTube Channel")
|
||||
if (linkType === Constants.socialLinkType.discord) return qsTr("Discord Handle")
|
||||
if (linkType === Constants.socialLinkType.telegram) return qsTr("Telegram Handle")
|
||||
return ""
|
||||
}
|
||||
input.icon {
|
||||
name: {
|
||||
if (linkType === Constants.socialLinkType.twitter) return "twitter"
|
||||
if (linkType === Constants.socialLinkType.personalSite) return "language"
|
||||
if (linkType === Constants.socialLinkType.github) return "github"
|
||||
if (linkType === Constants.socialLinkType.youtube) return "youtube"
|
||||
if (linkType === Constants.socialLinkType.discord) return "discord"
|
||||
if (linkType === Constants.socialLinkType.telegram) return "telegram"
|
||||
return ""
|
||||
}
|
||||
width: 20
|
||||
height: 20
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import utils 1.0
|
||||
import "../controls"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias displayName: displayNameInput
|
||||
property alias bio: bioInput
|
||||
|
||||
property var socialLinksModel
|
||||
|
||||
signal socialLinkChanged(string uuid, string text, string url)
|
||||
signal addSocialLinksClicked
|
||||
|
||||
implicitHeight: layout.implicitHeight
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: 19 // by design
|
||||
|
||||
StatusInput {
|
||||
id: displayNameInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
label: qsTr("Display name")
|
||||
placeholderText: qsTr("Display Name")
|
||||
charLimit: 24
|
||||
validators: Constants.validators.displayName
|
||||
}
|
||||
|
||||
|
||||
StatusInput {
|
||||
id: bioInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 5 // by design
|
||||
|
||||
label: qsTr("Bio")
|
||||
placeholderText: qsTr("Tell us about yourself")
|
||||
charLimit: 240
|
||||
multiline: true
|
||||
minimumHeight: 108
|
||||
maximumHeight: 108
|
||||
input.verticalAlignment: TextEdit.AlignTop
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.socialLinksModel
|
||||
delegate: StaticSocialLinkInput {
|
||||
Layout.fillWidth: true
|
||||
linkType: model.linkType
|
||||
text: model.url
|
||||
|
||||
onTextChanged: root.socialLinkChanged(model.uuid, model.text, text)
|
||||
}
|
||||
}
|
||||
|
||||
StatusIconTextButton {
|
||||
Layout.topMargin: -8 // by design
|
||||
text: qsTr("Add more social links")
|
||||
onClicked: root.addSocialLinksClicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string text
|
||||
property string url
|
||||
property int linkType: 1
|
||||
|
||||
implicitWidth: layout.implicitWidth + 16
|
||||
implicitHeight: layout.implicitHeight + 10
|
||||
|
||||
color: "transparent"
|
||||
border {
|
||||
width: 1
|
||||
color: Theme.palette.baseColor2
|
||||
}
|
||||
radius: height/2
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
StatusIcon {
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
icon: {
|
||||
if (root.linkType === Constants.socialLinkType.twitter) return "twitter"
|
||||
if (root.linkType === Constants.socialLinkType.personalSite) return "language"
|
||||
if (root.linkType === Constants.socialLinkType.github) return "github"
|
||||
if (root.linkType === Constants.socialLinkType.youtube) return "youtube"
|
||||
if (root.linkType === Constants.socialLinkType.discord) return "discord"
|
||||
if (root.linkType === Constants.socialLinkType.telegram) return "telegram"
|
||||
return ""
|
||||
}
|
||||
visible: icon !== ""
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: root.linkType === Constants.socialLinkType.custom ? root.text : root.url
|
||||
color: Theme.palette.directColor4
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
id: toolTip
|
||||
|
||||
contentItem: RowLayout {
|
||||
StatusBaseText {
|
||||
Layout.fillHeight: true
|
||||
Layout.bottomMargin: 8
|
||||
|
||||
text: toolTip.text
|
||||
color: Theme.palette.white
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 13
|
||||
font.weight: Font.Medium
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
Layout.preferredHeight: 24
|
||||
Layout.preferredWidth: 24
|
||||
Layout.bottomMargin: 8
|
||||
icon.name: "copy"
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
type: StatusFlatRoundButton.Tertiary
|
||||
|
||||
onClicked: {
|
||||
globalUtils.copyToClipboard(toolTip.text)
|
||||
toolTip.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: toolTip.show(root.url, -1)
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
|
@ -25,3 +25,4 @@ TransactionDelegate 1.0 TransactionDelegate.qml
|
|||
TransactionFormGroup 1.0 TransactionFormGroup.qml
|
||||
EmojiHash 1.0 EmojiHash.qml
|
||||
InformationTile 1.0 InformationTile.qml
|
||||
SocialLinkPreview 1.0 SocialLinkPreview.qml
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import "../controls"
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string bio
|
||||
property string userSocialLinksJson
|
||||
|
||||
onUserSocialLinksJsonChanged: d.buildSocialLinksModel()
|
||||
|
||||
implicitWidth: layout.implicitWidth
|
||||
implicitHeight: layout.implicitHeight
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
function textToType(text) {
|
||||
if (text === "__twitter") return Constants.socialLinkType.twitter
|
||||
if (text === "__personal_site") return Constants.socialLinkType.personalSite
|
||||
if (text === "__github") return Constants.socialLinkType.github
|
||||
if (text === "__youtube") return Constants.socialLinkType.youtube
|
||||
if (text === "__discord") return Constants.socialLinkType.discord
|
||||
if (text === "__telegram") return Constants.socialLinkType.telegram
|
||||
return Constants.socialLinkType.custom
|
||||
}
|
||||
|
||||
// Unfortunately, nim can't expose temporary QObjects thorugh slots
|
||||
// The only way to expose static models on demand is through json strings (see getContactDetailsAsJson)
|
||||
// Model is built here manually, which I know is completely wrong..
|
||||
function buildSocialLinksModel() {
|
||||
socialLinksModel.clear()
|
||||
|
||||
if (root.userSocialLinksJson == "") return
|
||||
|
||||
try {
|
||||
let links = JSON.parse(root.userSocialLinksJson)
|
||||
for (let i=0; i<links.length; i++) {
|
||||
let obj = links[i]
|
||||
socialLinksModel.append({
|
||||
"text": obj.text,
|
||||
"url": obj.url,
|
||||
"linkType": textToType(obj.text)
|
||||
})
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.warn("can't parse userSocialLinksJson", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: socialLinksModel
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: sortedSocialLinksModel
|
||||
|
||||
function customsLastPredicate(linkTypeLeft, linkTypeRight) {
|
||||
if (linkTypeLeft === Constants.socialLinkType.custom) return false
|
||||
if (linkTypeRight === Constants.socialLinkType.custom) return true
|
||||
return linkTypeLeft < linkTypeRight
|
||||
}
|
||||
|
||||
sourceModel: socialLinksModel
|
||||
filters: ExpressionFilter {
|
||||
expression: model.text !== "" && model.url !== ""
|
||||
}
|
||||
sorters: [
|
||||
ExpressionSorter {
|
||||
expression: sortedSocialLinksModel.customsLastPredicate(modelLeft.linkType, modelRight.linkType)
|
||||
},
|
||||
StringSorter {
|
||||
roleName: "text"
|
||||
caseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: 20
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
text: root.bio
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 10
|
||||
Layout.rightMargin: 10
|
||||
|
||||
spacing: 16
|
||||
visible: repeater.count > 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
model: sortedSocialLinksModel
|
||||
delegate: SocialLinkPreview {
|
||||
text: model.text
|
||||
url: model.url
|
||||
linkType: model.linkType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ ImageLoader 1.0 ImageLoader.qml
|
|||
LabelValueRow 1.0 LabelValueRow.qml
|
||||
ModuleWarning 1.0 ModuleWarning.qml
|
||||
NotificationWindow 1.0 NotificationWindow.qml
|
||||
ProfileBioSocialsPanel 1.0 ProfileBioSocialsPanel.qml
|
||||
RoundedIcon 1.0 RoundedIcon.qml
|
||||
RoundedImage 1.0 RoundedImage.qml
|
||||
Separator 1.0 Separator.qml
|
||||
|
|
|
@ -345,6 +345,16 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
readonly property QtObject socialLinkType: QtObject {
|
||||
readonly property int custom: 0
|
||||
readonly property int twitter: 1
|
||||
readonly property int personalSite: 2
|
||||
readonly property int github: 3
|
||||
readonly property int youtube: 4
|
||||
readonly property int discord: 5
|
||||
readonly property int telegram: 6
|
||||
}
|
||||
|
||||
readonly property int communityImported: 0
|
||||
readonly property int communityImportingInProgress: 1
|
||||
readonly property int communityImportingError: 2
|
||||
|
|
Loading…
Reference in New Issue