feat(communities/portal): add tags filtering
This commit is contained in:
parent
534a0d0f45
commit
27a9133882
|
@ -68,7 +68,7 @@ Item {
|
|||
|
||||
StatusCommunityTags {
|
||||
model: tagsModel
|
||||
showOnlySelected: true
|
||||
mode: StatusCommunityTags.ShowSelectedOnly
|
||||
onClicked: {
|
||||
cntSelectedTags--;
|
||||
item.selected = false;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ StatusScrollView {
|
|||
|
||||
StatusCommunityTags {
|
||||
model: d.tagsModel
|
||||
showOnlySelected: true
|
||||
mode: StatusCommunityTags.ShowSelectedOnly
|
||||
onClicked: {
|
||||
d.cntSelectedTags--;
|
||||
item.selected = false;
|
||||
|
|
Loading…
Reference in New Issue