diff --git a/storybook/pages/CommunitiesPortalLayoutPage.qml b/storybook/pages/CommunitiesPortalLayoutPage.qml index 3da9252e96..235f2fc188 100644 --- a/storybook/pages/CommunitiesPortalLayoutPage.qml +++ b/storybook/pages/CommunitiesPortalLayoutPage.qml @@ -3,55 +3,70 @@ import QtQuick 2.14 import QtQuick.Controls 2.14 import QtQuick.Layouts 1.14 +import StatusQ.Popups.Dialog 0.1 + import AppLayouts.CommunitiesPortal 1.0 import AppLayouts.CommunitiesPortal.stores 1.0 import SortFilterProxyModel 0.2 -ColumnLayout{ +SplitView { anchors.fill: parent - CommunitiesPortalLayout { - Layout.fillWidth: true - Layout.fillHeight: true + ColumnLayout { + SplitView.fillWidth: true - 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 { + CommunitiesPortalLayout { + Layout.fillWidth: true + Layout.fillHeight: true - 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 { - inverted: true - minimumIndex: Math.floor(slider.value) + sourceModel: CommunitiesPortalDummyModel { id: mockedModel } + + 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 { - color: 'gray' - Layout.preferredHeight: 1 - Layout.fillWidth: true - } + Control { + SplitView.minimumWidth: 300 + SplitView.preferredWidth: 300 - Pane { - Row { - Text { - anchors.verticalCenter: parent.verticalCenter - text: "number of communities:" - } + font.pixelSize: 13 - Slider { - id: slider - value: 9 - from: 0 - to: 9 - } + CommunitiesPortalModelEditor { + anchors.fill: parent + model: mockedModel } } } - diff --git a/storybook/pages/CommunitiesPortalModelEditor.qml b/storybook/pages/CommunitiesPortalModelEditor.qml new file mode 100644 index 0000000000..3ec9f090aa --- /dev/null +++ b/storybook/pages/CommunitiesPortalModelEditor.qml @@ -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 + } + } + } + } +} diff --git a/storybook/pages/ImageSelectPopup.qml b/storybook/pages/ImageSelectPopup.qml new file mode 100644 index 0000000000..8b259851cf --- /dev/null +++ b/storybook/pages/ImageSelectPopup.qml @@ -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) + } + } + } + } + } + } +} diff --git a/storybook/qml.qrc b/storybook/qml.qrc index cb959ff355..a3cb07fabc 100644 --- a/storybook/qml.qrc +++ b/storybook/qml.qrc @@ -3,5 +3,7 @@ main.qml pages/CommunitiesPortalLayoutPage.qml pages/CommunitiesPortalDummyModel.qml + pages/CommunitiesPortalModelEditor.qml + pages/ImageSelectPopup.qml