chore(CommunitiesPortalLayoutPage): model editor added

Closes: #7816, #7819
This commit is contained in:
Michał Cieślak 2022-10-10 16:12:23 +02:00 committed by Michał
parent 2716e8a7c9
commit 347c9b2fc3
4 changed files with 326 additions and 32 deletions

View File

@ -3,55 +3,70 @@ import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.14
import StatusQ.Popups.Dialog 0.1
import AppLayouts.CommunitiesPortal 1.0 import AppLayouts.CommunitiesPortal 1.0
import AppLayouts.CommunitiesPortal.stores 1.0 import AppLayouts.CommunitiesPortal.stores 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
ColumnLayout{ SplitView {
anchors.fill: parent anchors.fill: parent
CommunitiesPortalLayout { ColumnLayout {
Layout.fillWidth: true SplitView.fillWidth: true
Layout.fillHeight: true
communitiesStore: CommunitiesStore { CommunitiesPortalLayout {
readonly property string locale: "" Layout.fillWidth: true
readonly property int unreadNotificationsCount: 42 Layout.fillHeight: true
readonly property string communityTags:
JSON.stringify({"Activism":"✊","Art":"🎨","Blockchain":"🔗","Books & blogs":"📚","Career":"💼"})
readonly property var curatedCommunitiesModel: SortFilterProxyModel {
sourceModel: CommunitiesPortalDummyModel {} communitiesStore: CommunitiesStore {
readonly property string locale: ""
readonly property int unreadNotificationsCount: 42
readonly property string communityTags:
JSON.stringify({"Activism":"✊","Art":"🎨","Blockchain":"🔗","Books & blogs":"📚","Career":"💼"})
readonly property var curatedCommunitiesModel: SortFilterProxyModel {
filters: IndexFilter { sourceModel: CommunitiesPortalDummyModel { id: mockedModel }
inverted: true
minimumIndex: Math.floor(slider.value) filters: IndexFilter {
inverted: true
minimumIndex: Math.floor(slider.value)
}
}
}
}
StatusDialogDivider {
Layout.fillWidth: true
}
Pane {
Row {
Text {
anchors.verticalCenter: parent.verticalCenter
text: "number of communities:"
}
Slider {
id: slider
value: 9
from: 0
to: 9
} }
} }
} }
} }
Rectangle { Control {
color: 'gray' SplitView.minimumWidth: 300
Layout.preferredHeight: 1 SplitView.preferredWidth: 300
Layout.fillWidth: true
}
Pane { font.pixelSize: 13
Row {
Text {
anchors.verticalCenter: parent.verticalCenter
text: "number of communities:"
}
Slider { CommunitiesPortalModelEditor {
id: slider anchors.fill: parent
value: 9 model: mockedModel
from: 0
to: 9
}
} }
} }
} }

View File

@ -0,0 +1,218 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
ListView {
id: root
spacing: 25
ScrollBar.vertical: ScrollBar { }
function singleShotConnection(prop, handler) {
const internalHandler = (...args) => {
handler(...args)
prop.disconnect(internalHandler)
}
prop.connect(internalHandler)
}
ImageSelectPopup {
id: iconSelector
parent: root
anchors.centerIn: parent
width: parent.width * 0.8
height: parent.height * 0.8
model: ListModel {
id: iconsModel
}
Component.onCompleted: {
const model = root.model
const icons = []
for (let i = 0; i < model.count; i++) {
icons.push(model.get(i).icon)
}
const onlyUnique = (value, index, self) => self.indexOf(value) === index
const uniqueIcons = icons.filter(onlyUnique)
uniqueIcons.map(image => iconsModel.append( { image }))
}
}
ImageSelectPopup {
id: bannerSelector
parent: root
anchors.centerIn: parent
width: parent.width * 0.8
height: parent.height * 0.8
model: ListModel {
id: bannersModel
}
Component.onCompleted: {
const model = root.model
const banners = []
for (let i = 0; i < model.count; i++) {
banners.push(model.get(i).banner)
}
const onlyUnique = (value, index, self) => self.indexOf(value) === index
const uniqueBanners = banners.filter(onlyUnique)
uniqueBanners.map(image => bannersModel.append( { image }))
}
}
delegate: Rectangle {
width: parent.width
height: column.implicitHeight
ColumnLayout {
id: column
width: parent.width
spacing: 2
Label {
text: "community id: " + model.communityId
font.weight: Font.Bold
}
TextField {
Layout.fillWidth: true
text: model.name
onTextChanged: model.name = text
}
TextField {
Layout.fillWidth: true
text: model.description
onTextChanged: model.description = text
}
Flow {
Layout.fillWidth: true
CheckBox {
text: "featured"
checked: model.featured
onCheckedChanged: model.featured = checked
}
CheckBox {
text: "available"
checked: model.available
onCheckedChanged: model.available = checked
}
CheckBox {
text: "loaded"
checked: model.loaded
onCheckedChanged: model.loaded = checked
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 50
Rectangle {
border.color: 'gray'
Layout.preferredWidth: root.width / 2
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.icon
}
MouseArea {
anchors.fill: parent
onClicked: {
iconSelector.open()
singleShotConnection(iconSelector.selected, icon => {
model.icon = icon
iconSelector.close()
})
}
}
}
Rectangle {
border.color: 'gray'
Layout.preferredWidth: root.width / 2
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.banner
}
MouseArea {
anchors.fill: parent
onClicked: {
bannerSelector.open()
singleShotConnection(bannerSelector.selected, banner => {
model.banner = banner
bannerSelector.close()
})
}
}
}
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.icon
onTextChanged: model.icon = text
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.banner
onTextChanged: model.banner = text
}
Row {
spacing: 4
Label {
anchors.verticalCenter: parent.verticalCenter
text: "members:\t"
}
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.members
onValueChanged: model.members = value
}
}
Row {
spacing: 4
Label {
anchors.verticalCenter: parent.verticalCenter
text: "popularity:\t"
}
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.popularity
onValueChanged: model.popularity = value
}
}
}
}
}

View File

@ -0,0 +1,59 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
Popup {
id: root
property alias model: repeater.model
signal selected(string icon)
Flickable {
id: flickable
anchors.fill: parent
clip: true
contentWidth: width
contentHeight: flow.implicitHeight
Flow {
id: flow
width: flickable.width
Button {
text: "NO IMAGE"
onClicked: {
root.selected("")
}
}
Repeater {
id: repeater
delegate: Item {
width: iconImage.width + 10
height: iconImage.height + 10
Rectangle {
anchors.fill: iconImage
anchors.margins: -1
border.color: 'gray'
}
Image {
id: iconImage
source: model.image
anchors.centerIn: parent
asynchronous: true
MouseArea {
id: ma
anchors.fill: parent
onClicked: root.selected(model.image)
}
}
}
}
}
}
}

View File

@ -3,5 +3,7 @@
<file>main.qml</file> <file>main.qml</file>
<file>pages/CommunitiesPortalLayoutPage.qml</file> <file>pages/CommunitiesPortalLayoutPage.qml</file>
<file>pages/CommunitiesPortalDummyModel.qml</file> <file>pages/CommunitiesPortalDummyModel.qml</file>
<file>pages/CommunitiesPortalModelEditor.qml</file>
<file>pages/ImageSelectPopup.qml</file>
</qresource> </qresource>
</RCC> </RCC>