feat(communities/portal): add tags filtering

This commit is contained in:
Patryk Osmaczko 2022-10-17 12:03:08 +02:00 committed by osmaczko
parent 534a0d0f45
commit 27a9133882
6 changed files with 91 additions and 22 deletions

View File

@ -68,7 +68,7 @@ Item {
StatusCommunityTags {
model: tagsModel
showOnlySelected: true
mode: StatusCommunityTags.ShowSelectedOnly
onClicked: {
cntSelectedTags--;
item.selected = false;

View File

@ -3,14 +3,22 @@ import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import SortFilterProxyModel 0.2
Item {
id: root
property string filterString
property bool showOnlySelected: false
property bool active: true
property alias model: repeater.model
enum Mode {
ShowUnselectedOnly,
ShowSelectedOnly,
Highlight
}
property int mode: StatusCommunityTags.ShowUnselectedOnly
property var model
property alias contentWidth: flow.width
readonly property int itemsWidth: {
@ -35,16 +43,41 @@ Item {
Repeater {
id: repeater
model: SortFilterProxyModel {
id: filterModel
sourceModel: root.model
function selectionPredicate(selected) {
return root.mode === StatusCommunityTags.ShowSelectedOnly ? selected : !selected
}
filters: [
ExpressionFilter {
enabled: root.filterString !== ""
expression: {
root.filterString
return model.name.toUpperCase().indexOf(root.filterString.toUpperCase()) !== -1
}
},
ExpressionFilter {
enabled: root.mode !== StatusCommunityTags.Highlight
expression: {
root.mode
return filterModel.selectionPredicate(model.selected)
}
}
]
}
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 : -flow.spacing
height: visible ? implicitHeight : 0
removable: root.showOnlySelected && root.active
removable: root.mode === StatusCommunityTags.ShowSelectedOnly && root.active
highlighted: root.mode === StatusCommunityTags.Highlight && model.selected
onClicked: root.clicked(model)
}
}
}
}
}

View File

@ -10,6 +10,7 @@ Rectangle {
property string emoji
property string name
property bool removable: false
property bool highlighted: false
signal clicked()
@ -18,7 +19,7 @@ Rectangle {
radius: height / 2
border.color: Theme.palette.baseColor2
border.width: 1
color: mouseArea.containsMouse ? Theme.palette.primaryColor2 : "transparent"
color: root.highlighted || mouseArea.containsMouse ? Theme.palette.primaryColor2 : "transparent"
MouseArea {
id: mouseArea

View File

@ -59,17 +59,32 @@ StatusSectionLayout {
}
SortFilterProxyModel {
id: searchModel
id: filteredCommunitiesModel
function selectedTagsPredicate(selectedTagsNames, tagsJSON) {
const tags = JSON.parse(tagsJSON)
for (const i in tags) {
selectedTagsNames = selectedTagsNames.filter(name => name !== tags[i].name)
}
return selectedTagsNames.length === 0
}
sourceModel: root.communitiesStore.curatedCommunitiesModel
filters: ExpressionFilter {
enabled: d.searchMode
expression: {
searcher.text
return name.toLowerCase().includes(searcher.text.toLowerCase())
filters: [
ExpressionFilter {
enabled: d.searchMode
expression: {
searcher.text
return name.toLowerCase().includes(searcher.text.toLowerCase())
}
},
ExpressionFilter {
expression: {
return filteredCommunitiesModel.selectedTagsPredicate(communityTags.selectedTagsNames, model.tags)
}
}
}
]
}
centerPanel: Item {
@ -137,8 +152,10 @@ StatusSectionLayout {
}
CommunityTagsRow {
tags: root.communitiesStore.communityTags
id: communityTags
Layout.fillWidth: true
tags: root.communitiesStore.communityTags
}
Item {
@ -158,7 +175,7 @@ StatusSectionLayout {
bottomPadding: d.layoutBottomMargin
locale: communitiesStore.locale
model: searchModel
model: filteredCommunitiesModel
searchLayout: d.searchMode
onCardClicked: d.navigateToCommunity(communityId)
@ -168,7 +185,7 @@ StatusSectionLayout {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: parent.height / 3.1
visible: d.searchMode && searchModel.count === 0
visible: d.searchMode && filteredCommunitiesModel.count === 0
text: qsTr("No communities found")
color: Theme.palette.baseColor1
font.pixelSize: 15
@ -223,7 +240,7 @@ StatusSectionLayout {
CommunityBanner {
property bool importInProgress: root.communitiesStore.discordImportInProgress && !root.communitiesStore.discordImportCancelled
text: importInProgress ?
qsTr("'%1' import in progress...").arg(root.communitiesStore.discordImportCommunityName) :
qsTr("'%1' import in progress...").arg(root.communitiesStore.discordImportCommunityName) :
qsTr("Import existing Discord community into Status")
buttonText: qsTr("Import existing")
icon.name: "download"

View File

@ -11,6 +11,7 @@ StatusRollArea {
id: root
property string tags
property var selectedTagsNames: []
onTagsChanged: {
var obj = JSON.parse(tags);
@ -19,16 +20,33 @@ StatusRollArea {
for (const key of Object.keys(obj)) {
d.tagsModel.append({ name: key, emoji: obj[key], selected: false });
}
d.evaluateSelectedTags()
}
QtObject {
id: d
property ListModel tagsModel: ListModel {}
function evaluateSelectedTags() {
let selectedTagsNames = []
for(let i = 0; i < tagsModel.count; i++) {
let tag = tagsModel.get(i)
if (tag.selected) selectedTagsNames.push(tag.name)
}
root.selectedTagsNames = selectedTagsNames
}
}
content: StatusCommunityTags {
id: tagsFlow
model: d.tagsModel
mode: StatusCommunityTags.Highlight
onClicked: {
item.selected = !item.selected
d.evaluateSelectedTags()
}
}
}

View File

@ -126,7 +126,7 @@ StatusScrollView {
StatusCommunityTags {
model: d.tagsModel
showOnlySelected: true
mode: StatusCommunityTags.ShowSelectedOnly
onClicked: {
d.cntSelectedTags--;
item.selected = false;