status-desktop/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml

243 lines
8.0 KiB
QML

import QtQuick 2.13
import QtQuick.Layouts 1.13
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Layout 0.1
import utils 1.0
import shared.controls 1.0
import shared.popups 1.0
import shared.stores 1.0
import SortFilterProxyModel 0.2
import AppLayouts.Communities.controls 1.0
import AppLayouts.Communities.popups 1.0
import AppLayouts.Communities.views 1.0
import AppLayouts.Communities.panels 1.0
import AppLayouts.Communities.stores 1.0
StatusSectionLayout {
id: root
property CommunitiesStore communitiesStore
property var assetsModel
property var collectiblesModel
objectName: "communitiesPortalLayout"
onNotificationButtonClicked: Global.openActivityCenterPopup()
onVisibleChanged: {
if(visible)
searcher.input.edit.forceActiveFocus()
}
QtObject {
id: d
// values from the design
readonly property int layoutTopMargin: 10
readonly property int layoutBottomMargin: 249
readonly property int layoutHMargin: 64
readonly property int layoutWidth: 1037
readonly property int titlePixelSize: 28
readonly property int preventShadowClipMargin: 40
readonly property bool searchMode: searcher.text.length > 0
}
SortFilterProxyModel {
id: filteredCommunitiesModel
function selectedTagsPredicate(selectedTagsNames, tagsJSON) {
if (!tagsJSON) {
return true
}
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())
}
},
ExpressionFilter {
expression: {
return filteredCommunitiesModel.selectedTagsPredicate(communityTags.selectedTagsNames, model.tags)
}
},
FastExpressionFilter {
expression: !model.amIBanned
expectedRoles: ["amIBanned"]
}
]
}
centerPanel: Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
width: d.layoutWidth
anchors.topMargin: d.layoutTopMargin
anchors.leftMargin: d.layoutHMargin
ColumnLayout {
id: column
anchors.fill: parent
spacing: 18
StatusBaseText {
text: qsTr("Discover Communities")
font.weight: Font.Bold
font.pixelSize: d.titlePixelSize
color: Theme.palette.directColor1
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 38
spacing: Style.current.bigPadding
SearchBox {
id: searcher
implicitWidth: 327
Layout.alignment: Qt.AlignVCenter
topPadding: 0
bottomPadding: 0
minimumHeight: 36
maximumHeight: 36
}
// Just a row filler to fit design
Item { Layout.fillWidth: true }
StatusButton {
id: importBtn
Layout.preferredHeight: 38
text: qsTr("Import community")
verticalPadding: 0
onClicked: Global.importCommunityPopupRequested()
}
Loader {
Layout.preferredHeight: active ? 38 : 0
active: communitiesStore.createCommunityEnabled || communitiesStore.testEnvironment
sourceComponent: StatusButton {
id: createBtn
objectName: "createCommunityButton"
height: parent.height
verticalPadding: 0
text: qsTr("Create community")
onClicked: {
Global.openPopup(chooseCommunityCreationTypePopupComponent)
}
}
}
}
TagsRow {
id: communityTags
Layout.fillWidth: true
tags: root.communitiesStore.communityTags
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: -d.preventShadowClipMargin
Layout.rightMargin: -d.preventShadowClipMargin
clip: true
CommunitiesGridView {
id: communitiesGrid
anchors.fill: parent
anchors.rightMargin: d.preventShadowClipMargin
anchors.leftMargin: d.preventShadowClipMargin
padding: 0
bottomPadding: d.layoutBottomMargin
model: filteredCommunitiesModel
searchLayout: d.searchMode
assetsModel: root.assetsModel
collectiblesModel: root.collectiblesModel
onCardClicked: root.communitiesStore.navigateToCommunity(communityId)
}
StatusBaseText {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: parent.height / 3.1
visible: (d.searchMode && filteredCommunitiesModel.count === 0) || communitiesGrid.isEmpty
text: qsTr("No communities found")
color: Theme.palette.baseColor1
}
}
}
}
Component {
id: chooseCommunityCreationTypePopupComponent
StatusDialog {
id: chooseCommunityCreationTypePopup
title: qsTr("Create new community")
horizontalPadding: 40
verticalPadding: 60
footer: null
onClosed: destroy()
contentItem: RowLayout {
spacing: 20
BannerPanel {
objectName: "createCommunityBanner"
text: qsTr("Create a new Status community")
buttonText: qsTr("Create new")
icon.name: "favourite"
onButtonClicked: {
chooseCommunityCreationTypePopup.close()
Global.createCommunityPopupRequested(false /*isDiscordImport*/)
}
}
BannerPanel {
readonly property bool importInProgress: root.communitiesStore.discordImportInProgress && !root.communitiesStore.discordImportCancelled
text: importInProgress ?
qsTr("'%1' import in progress...").arg(root.communitiesStore.discordImportCommunityName || root.communitiesStore.discordImportChannelName) :
qsTr("Import existing Discord community into Status")
buttonText: qsTr("Import existing")
icon.name: "download"
buttonTooltipText: qsTr("Your current import must be finished or cancelled before a new import can be started.")
buttonLoading: importInProgress
onButtonClicked: {
chooseCommunityCreationTypePopup.close()
Global.createCommunityPopupRequested(true /*isDiscordImport*/)
}
}
}
}
}
}