From 69b5cb1988bc86cf4a6d21ef693de71c38bce060 Mon Sep 17 00:00:00 2001 From: Mikhail Rogachev Date: Tue, 14 Jun 2022 16:23:18 +0300 Subject: [PATCH] feat(StatusCommunityTags): Add community tags component (#718) --- sandbox/demoapp/data/Models.qml | 2 + sandbox/main.qml | 5 ++ sandbox/pages/StatusCommunityTagsPage.qml | 83 +++++++++++++++++++ .../Components/StatusCommunityTags.qml | 48 +++++++++++ src/StatusQ/Components/StatusEmoji.qml | 2 +- src/StatusQ/Components/qmldir | 1 + src/StatusQ/Controls/StatusCommunityTag.qml | 57 +++++++++++++ src/StatusQ/Controls/qmldir | 1 + 8 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 sandbox/pages/StatusCommunityTagsPage.qml create mode 100644 src/StatusQ/Components/StatusCommunityTags.qml create mode 100644 src/StatusQ/Controls/StatusCommunityTag.qml diff --git a/sandbox/demoapp/data/Models.qml b/sandbox/demoapp/data/Models.qml index 59e52f17..56a826eb 100644 --- a/sandbox/demoapp/data/Models.qml +++ b/sandbox/demoapp/data/Models.qml @@ -1478,4 +1478,6 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I ListElement { name: "enviroment"; emoji: "โ˜ ๏ธ"} ListElement { name: "privacy"; emoji: "๐Ÿ‘ป"} } + + property var communityTags :{"Activism":"โœŠ","Art":"๐ŸŽจ","Blockchain":"๐Ÿ”—","Books & blogs":"๐Ÿ“š","Career":"๐Ÿ’ผ","Collaboration":"๐Ÿค","Commerce":"๐Ÿ›’","Crypto":"ฮž","Culture":"๐ŸŽŽ","DAO":"๐Ÿš€","DIY":"๐Ÿ”จ","DeFi":"๐Ÿ“ˆ","Design":"๐Ÿงฉ","Education":"๐ŸŽ’","Entertainment":"๐Ÿฟ","Environment":"๐ŸŒฟ","Event":"๐Ÿ—“","Fantasy":"๐Ÿง™โ€โ™‚๏ธ","Fashion":"๐Ÿงฆ","Food":"๐ŸŒถ","Gaming":"๐ŸŽฎ","Global":"๐ŸŒ","Health":"๐Ÿง ","Hobby":"๐Ÿ“","Innovation":"๐Ÿงช","Language":"๐Ÿ“œ","Lifestyle":"โœจ","Local":"๐Ÿ“","Love":"โค๏ธ","Markets":"๐Ÿ’Ž","Movies & TV":"๐ŸŽž","Music":"๐ŸŽถ","NFT":"๐Ÿ–ผ","NSFW":"๐Ÿ†","News":"๐Ÿ—ž","Non-profit":"๐Ÿ™","Org":"๐Ÿข","Pets":"๐Ÿถ","Play":"๐ŸŽฒ","Podcast":"๐ŸŽ™๏ธ","Politics":"๐Ÿ—ณ๏ธ","Privacy":"๐Ÿ‘ป","Product":"๐Ÿฑ","Psyche":"๐Ÿ","Security":"๐Ÿ”’","Social":"โ˜•","Software dev":"๐Ÿ‘ฉโ€๐Ÿ’ป","Sports":"โšฝ๏ธ","Tech":"๐Ÿ“ฑ","Travel":"๐Ÿ—บ","Vehicles":"๐Ÿš•","Web3":"๐ŸŒ"} } diff --git a/sandbox/main.qml b/sandbox/main.qml index 14e03af0..f80da55a 100644 --- a/sandbox/main.qml +++ b/sandbox/main.qml @@ -289,6 +289,11 @@ StatusWindow { selected: viewLoader.source.toString().includes(title) onClicked: mainPageView.page(title); } + StatusNavigationListItem { + title: "StatusCommunityTags" + selected: viewLoader.source.toString().includes(title) + onClicked: mainPageView.page(title); + } StatusListSectionHeadline { text: "StatusQ.Popup" } StatusNavigationListItem { title: "StatusPopupMenu" diff --git a/sandbox/pages/StatusCommunityTagsPage.qml b/sandbox/pages/StatusCommunityTagsPage.qml new file mode 100644 index 00000000..b38614c2 --- /dev/null +++ b/sandbox/pages/StatusCommunityTagsPage.qml @@ -0,0 +1,83 @@ +import QtQuick 2.14 +import QtQuick.Controls 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.Components 0.1 + +import Sandbox 0.1 + +import "../demoapp/data" 1.0 + +Item { + + property int cntSelectedTags: 0 + property int maxSelectedTags: 4 + property ListModel tagsModel: ListModel {} + + Component.onCompleted: { + tagsModel.clear(); + for (const key of Object.keys(Models.communityTags)) { + tagsModel.append({ name: key, emoji: Models.communityTags[key], selected: false }); + } + } + + ColumnLayout { + id: column + anchors.centerIn: parent + width: 600 + height: 500 + spacing: 20 + + StatusInput { + id: tagsFilter + leftPadding: 0 + rightPadding: 0 + label: qsTr("Select tags that will fit your Community") + input.icon.name: "search" + input.placeholderText: qsTr("Search tags") + Layout.fillWidth: true + } + + StatusCommunityTags { + filterString: tagsFilter.text + model: tagsModel + enabled: cntSelectedTags < maxSelectedTags + onClicked: { + cntSelectedTags++; + item.selected = true; + } + Layout.fillWidth: true + } + + RowLayout { + StatusBaseText { + text: qsTr("Selected tags") + font.pixelSize: 15 + Layout.fillWidth: true + } + + StatusBaseText { + text: cntSelectedTags + "/" + maxSelectedTags + color: Theme.palette.baseColor1 + font.pixelSize: 13 + } + } + + StatusCommunityTags { + model: tagsModel + showOnlySelected: true + onClicked: { + cntSelectedTags--; + item.selected = false; + } + Layout.fillWidth: true + } + + Item { + Layout.fillHeight: true + } + } +} \ No newline at end of file diff --git a/src/StatusQ/Components/StatusCommunityTags.qml b/src/StatusQ/Components/StatusCommunityTags.qml new file mode 100644 index 00000000..ecde5406 --- /dev/null +++ b/src/StatusQ/Components/StatusCommunityTags.qml @@ -0,0 +1,48 @@ +import QtQuick 2.14 + +import StatusQ.Core 0.1 +import StatusQ.Controls 0.1 + +Item { + id: root + + property string filterString + property bool showOnlySelected: false + property bool active: true + + property alias model: repeater.model + property alias contentWidth: flow.width + + signal clicked(var item) + + implicitWidth: flow.implicitWidth + implicitHeight: flow.implicitHeight + + Flow { + id: flow + anchors.centerIn: parent + width: { + let itemsWidth = 0; + for (let i = 0; i < repeater.count; ++i) { + itemsWidth += spacing + repeater.itemAt(i).width; + } + return Math.min(parent.width, itemsWidth); + } + spacing: 10 + + Repeater { + id: repeater + + delegate: StatusCommunityTag { + emoji: model.emoji + name: model.name + visible: (root.showOnlySelected ? model.selected : !model.selected) && + (filterString == 0 || name.toUpperCase().indexOf(filterString.toUpperCase()) !== -1) + width: visible ? implicitWidth : -10 + height: visible ? implicitHeight : 0 + removable: root.showOnlySelected && root.active + onClicked: root.clicked(model) + } + } + } +} \ No newline at end of file diff --git a/src/StatusQ/Components/StatusEmoji.qml b/src/StatusQ/Components/StatusEmoji.qml index bf359830..53454d0b 100644 --- a/src/StatusQ/Components/StatusEmoji.qml +++ b/src/StatusQ/Components/StatusEmoji.qml @@ -6,7 +6,7 @@ Image { id: root property string emojiId: "" - + width: 14 height: 14 sourceSize.width: width diff --git a/src/StatusQ/Components/qmldir b/src/StatusQ/Components/qmldir index 68fa6784..4557806e 100644 --- a/src/StatusQ/Components/qmldir +++ b/src/StatusQ/Components/qmldir @@ -36,3 +36,4 @@ StatusWizardStepper 0.1 StatusWizardStepper.qml StatusImageCropPanel 0.1 StatusImageCropPanel.qml StatusColorSpace 0.0 StatusColorSpace.qml StatusCommunityCard 0.1 StatusCommunityCard.qml +StatusCommunityTags 0.1 StatusCommunityTags.qml diff --git a/src/StatusQ/Controls/StatusCommunityTag.qml b/src/StatusQ/Controls/StatusCommunityTag.qml new file mode 100644 index 00000000..d2afbde1 --- /dev/null +++ b/src/StatusQ/Controls/StatusCommunityTag.qml @@ -0,0 +1,57 @@ +import QtQuick 2.14 +import StatusQ.Core 0.1 +import StatusQ.Components 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Core.Utils 0.1 + +Rectangle { + id: root + + property string emoji + property string name + property bool removable: false + + signal clicked() + + implicitHeight: 32 + implicitWidth: row.width + 20 + radius: height / 2 + border.color: Theme.palette.baseColor2 + border.width: 1 + color: mouseArea.containsMouse ? Theme.palette.primaryColor2 : "transparent" + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: root.clicked() + } + + Row { + id: row + anchors.centerIn: parent + + StatusEmoji { + emojiId: root.emoji != "" ? Emoji.iconId(root.emoji) : "" + anchors.verticalCenter: parent.verticalCenter + } + + Item { + width: 5 + height: width + } + + StatusBaseText { + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 13 + color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1 + text: root.name + } + + StatusIcon { + visible: removable + color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1 + icon: "close" + } + } +} diff --git a/src/StatusQ/Controls/qmldir b/src/StatusQ/Controls/qmldir index 863dc519..ab39fcad 100644 --- a/src/StatusQ/Controls/qmldir +++ b/src/StatusQ/Controls/qmldir @@ -18,6 +18,7 @@ StatusButton 0.1 StatusButton.qml StatusFlatButton 0.1 StatusFlatButton.qml StatusRoundButton 0.1 StatusRoundButton.qml StatusFlatRoundButton 0.1 StatusFlatRoundButton.qml +StatusCommunityTag 0.1 StatusCommunityTag.qml StatusSwitch 0.1 StatusSwitch.qml StatusRadioButton 0.1 StatusRadioButton.qml StatusCheckBox 0.1 StatusCheckBox.qml