feat(ProfileShowcase): Component managing all models required by Profile Showcase settings UI
Closes: #13435 Closes: #13490 Closes: #13494
This commit is contained in:
parent
809af0ac90
commit
ac266bb997
|
@ -0,0 +1,324 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQml 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import AppLayouts.Profile.helpers 1.0
|
||||
|
||||
ColumnLayout {
|
||||
ListModel {
|
||||
id: accountsModel
|
||||
|
||||
ListElement { key: "1"; name: "Crypto Kitties" }
|
||||
ListElement { key: "2"; name: "Status" }
|
||||
ListElement { key: "3"; name: "Fun Stuff" }
|
||||
ListElement { key: "4"; name: "Other Stuff" }
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: accountsShowcaseModel
|
||||
|
||||
ListElement { key: "1"; visibility: 1; position: 0 }
|
||||
ListElement { key: "3"; visibility: 2; position: 9 }
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: collectiblesModel
|
||||
|
||||
ListElement { key: "1"; name: "Collectible 1"; accounts: "1:3" }
|
||||
ListElement { key: "2"; name: "Collectible 2"; accounts: "3" }
|
||||
ListElement { key: "3"; name: "Collectible 3"; accounts: "1:2:3" }
|
||||
ListElement { key: "4"; name: "Collectible 4"; accounts: "1:4" }
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: collectiblesShowcaseModel
|
||||
|
||||
ListElement { key: "1"; visibility: 1; position: 0 }
|
||||
ListElement { key: "2"; visibility: 2; position: 2 }
|
||||
ListElement { key: "3"; visibility: 2; position: 1 }
|
||||
}
|
||||
|
||||
ProfileShowcaseModels {
|
||||
id: showcaseModels
|
||||
|
||||
accountsSourceModel: accountsModel
|
||||
accountsShowcaseModel: accountsShowcaseModel
|
||||
|
||||
collectiblesSourceModel: collectiblesModel
|
||||
collectiblesShowcaseModel: collectiblesShowcaseModel
|
||||
}
|
||||
|
||||
MovableModel {
|
||||
id: accountsMovableModel
|
||||
|
||||
sourceModel: showcaseModels.accountsVisibleModel
|
||||
}
|
||||
|
||||
MovableModel {
|
||||
id: collectiblesMovableModel
|
||||
|
||||
sourceModel: showcaseModels.collectiblesVisibleModel
|
||||
}
|
||||
|
||||
component VisibilityComboBox: ComboBox {
|
||||
model: ListModel {
|
||||
ListElement { text: "contacts"; value: 1 }
|
||||
ListElement { text: "verified"; value: 2 }
|
||||
ListElement { text: "all"; value: 3 }
|
||||
}
|
||||
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
}
|
||||
|
||||
Flickable {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 10
|
||||
|
||||
contentWidth: grid.width
|
||||
contentHeight: grid.height
|
||||
|
||||
clip: true
|
||||
|
||||
Grid {
|
||||
id: grid
|
||||
|
||||
rows: 3
|
||||
columns: 4
|
||||
|
||||
spacing: 10
|
||||
|
||||
flow: Grid.TopToBottom
|
||||
|
||||
Label {
|
||||
text: "Backend models"
|
||||
font.pixelSize: 22
|
||||
padding: 10
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 200
|
||||
height: 300
|
||||
|
||||
model: accountsModel
|
||||
label: "ACCOUNTS MODEL"
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 200
|
||||
height: 300
|
||||
|
||||
model: accountsShowcaseModel
|
||||
label: "SHOWCASE MODEL"
|
||||
roles: ["key", "visibility", "position"]
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Display models"
|
||||
font.pixelSize: 22
|
||||
padding: 10
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 420
|
||||
height: 300
|
||||
|
||||
model: accountsMovableModel
|
||||
label: "IN SHOWCASE"
|
||||
movable: true
|
||||
roles: ["key", "visibility", "position"]
|
||||
|
||||
onMoveRequested: {
|
||||
accountsMovableModel.move(from, to)
|
||||
|
||||
const key = ModelUtils.get(accountsMovableModel, to, "key")
|
||||
showcaseModels.changeAccountPosition(key, to);
|
||||
}
|
||||
|
||||
insetComponent: RowLayout {
|
||||
readonly property var topModel: model
|
||||
|
||||
RoundButton {
|
||||
text: "❌"
|
||||
onClicked: showcaseModels.setAccountVisibility(
|
||||
model.key, 0)
|
||||
}
|
||||
|
||||
VisibilityComboBox {
|
||||
property bool completed: false
|
||||
|
||||
onCurrentValueChanged: {
|
||||
if (!completed || topModel.index < 0)
|
||||
return
|
||||
|
||||
showcaseModels.setAccountVisibility(
|
||||
topModel.key, currentValue)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
currentIndex = indexOfValue(topModel.visibility)
|
||||
completed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 420
|
||||
height: 300
|
||||
|
||||
model: showcaseModels.accountsHiddenModel
|
||||
|
||||
label: "HIDDEN"
|
||||
|
||||
roles: ["key", "visibility", "position"]
|
||||
|
||||
insetComponent: Button {
|
||||
text: "unhide"
|
||||
|
||||
onClicked: showcaseModels.setAccountVisibility(
|
||||
model.key, 1)
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Backend models"
|
||||
font.pixelSize: 22
|
||||
padding: 10
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 270
|
||||
height: 300
|
||||
|
||||
model: collectiblesModel
|
||||
label: "COLLECTIBLES MODEL"
|
||||
|
||||
roles: ["key", "name", "accounts"]
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 270
|
||||
height: 300
|
||||
|
||||
model: collectiblesShowcaseModel
|
||||
label: "SHOWCASE MODEL"
|
||||
roles: ["key", "visibility", "position"]
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Display models"
|
||||
font.pixelSize: 22
|
||||
padding: 10
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 610
|
||||
height: 300
|
||||
|
||||
model: collectiblesMovableModel
|
||||
label: "IN SHOWCASE"
|
||||
movable: true
|
||||
roles: ["key", "visibility", "position", "accounts", "maxVisibility"]
|
||||
|
||||
onMoveRequested: {
|
||||
collectiblesMovableModel.move(from, to)
|
||||
|
||||
const key = ModelUtils.get(collectiblesMovableModel, to, "key")
|
||||
showcaseModels.changeCollectiblePosition(key, to);
|
||||
}
|
||||
|
||||
insetComponent: RowLayout {
|
||||
readonly property var topModel: model
|
||||
|
||||
RoundButton {
|
||||
text: "❌"
|
||||
onClicked: showcaseModels.setCollectibleVisibility(
|
||||
model.key, 0)
|
||||
}
|
||||
|
||||
VisibilityComboBox {
|
||||
property bool completed: false
|
||||
|
||||
onCurrentValueChanged: {
|
||||
if (!completed || topModel.index < 0)
|
||||
return
|
||||
|
||||
showcaseModels.setCollectibleVisibility(
|
||||
topModel.key, currentValue)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
currentIndex = indexOfValue(topModel.visibility)
|
||||
completed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenericListView {
|
||||
width: 610
|
||||
height: 300
|
||||
|
||||
model: showcaseModels.collectiblesHiddenModel
|
||||
|
||||
label: "HIDDEN"
|
||||
|
||||
roles: ["key", "visibility", "position",
|
||||
"accounts", "maxVisibility"]
|
||||
|
||||
insetComponent: Button {
|
||||
text: "unhide"
|
||||
|
||||
onClicked: showcaseModels.setCollectibleVisibility(
|
||||
model.key, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: `accounts in showcase: [${showcaseModels.visibleAccountsList}]`
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
readonly property string visibilities:
|
||||
JSON.stringify(showcaseModels.accountsVisibilityMap)
|
||||
|
||||
text: `accounts visibilities: [${visibilities}]`
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "SAVE"
|
||||
|
||||
onClicked: {
|
||||
const accountsToBeSaved = showcaseModels.accountsCurrentState()
|
||||
const collectiblesToBeSaved = showcaseModels.collectiblesCurrentState()
|
||||
|
||||
accountsMovableModel.syncOrder()
|
||||
collectiblesMovableModel.syncOrder()
|
||||
|
||||
accountsShowcaseModel.clear()
|
||||
accountsShowcaseModel.append(accountsToBeSaved)
|
||||
|
||||
collectiblesShowcaseModel.clear()
|
||||
collectiblesShowcaseModel.append(collectiblesToBeSaved)
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.margins: 10
|
||||
}
|
||||
}
|
||||
|
||||
// category: Models
|
|
@ -0,0 +1,163 @@
|
|||
import QtQml 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
QObject {
|
||||
id: root
|
||||
|
||||
// COMMUNITIES
|
||||
|
||||
// Input models
|
||||
property alias communitiesSourceModel: communities.sourceModel
|
||||
property alias communitiesShowcaseModel: communities.showcaseModel
|
||||
|
||||
// Output models
|
||||
readonly property alias communitiesVisibleModel: communities.visibleModel
|
||||
readonly property alias communitiesHiddenModel: communities.hiddenModel
|
||||
|
||||
// Methods
|
||||
function communitiesCurrentState() {
|
||||
return communities.currentState()
|
||||
}
|
||||
|
||||
function setCommunityVisibility(key, visibility) {
|
||||
communities.setVisibility(key, visibility)
|
||||
}
|
||||
|
||||
function changeCommunityPosition(key, to) {
|
||||
communities.changePosition(key, to)
|
||||
}
|
||||
|
||||
// ACCOUNTS
|
||||
|
||||
// Input models
|
||||
property alias accountsSourceModel: accounts.sourceModel
|
||||
property alias accountsShowcaseModel: accounts.showcaseModel
|
||||
|
||||
// Output models
|
||||
readonly property alias accountsVisibleModel: accounts.visibleModel
|
||||
readonly property alias accountsHiddenModel: accounts.hiddenModel
|
||||
|
||||
// Methods
|
||||
function accountsCurrentState() {
|
||||
return accounts.currentState()
|
||||
}
|
||||
|
||||
function setAccountVisibility(key, visibility) {
|
||||
accounts.setVisibility(key, visibility)
|
||||
}
|
||||
|
||||
function changeAccountPosition(key, to) {
|
||||
accounts.changePosition(key, to)
|
||||
}
|
||||
|
||||
// Other
|
||||
readonly property alias visibleAccountsList:
|
||||
visibleAccountsConnections.visibleAccountsList
|
||||
|
||||
readonly property alias accountsVisibilityMap:
|
||||
visibleAccountsConnections.accountsVisibilityMap
|
||||
|
||||
// COLLECTIBLES
|
||||
|
||||
// Input models
|
||||
property alias collectiblesSourceModel: collectiblesFilter.sourceModel
|
||||
property alias collectiblesShowcaseModel: collectibles.showcaseModel
|
||||
|
||||
// Output models
|
||||
readonly property alias collectiblesVisibleModel: collectibles.visibleModel
|
||||
readonly property alias collectiblesHiddenModel: collectibles.hiddenModel
|
||||
|
||||
// Methods
|
||||
function collectiblesCurrentState() {
|
||||
return collectibles.currentState()
|
||||
}
|
||||
|
||||
function setCollectibleVisibility(key, visibility) {
|
||||
collectibles.setVisibility(key, visibility)
|
||||
}
|
||||
|
||||
function changeCollectiblePosition(key, to) {
|
||||
collectibles.changePosition(key, to)
|
||||
}
|
||||
|
||||
ProfileShowcaseDirtyState {
|
||||
id: communities
|
||||
}
|
||||
|
||||
ProfileShowcaseDirtyState {
|
||||
id: accounts
|
||||
}
|
||||
|
||||
ProfileShowcaseDirtyState {
|
||||
id: collectibles
|
||||
|
||||
sourceModel: collectiblesFilter
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: collectiblesFilter
|
||||
|
||||
delayed: true
|
||||
|
||||
proxyRoles: FastExpressionRole {
|
||||
name: "maxVisibility"
|
||||
|
||||
expression: {
|
||||
const m = root.accountsVisibilityMap
|
||||
const accounts = model.accounts.split(":")
|
||||
const visibilities = accounts.map(e => m[e]).filter(e => e)
|
||||
|
||||
return visibilities.length ? Math.min(...visibilities) : 0
|
||||
}
|
||||
|
||||
expectedRoles: ["accounts"]
|
||||
}
|
||||
|
||||
filters: RangeFilter {
|
||||
roleName: "maxVisibility"
|
||||
minimumValue: 1
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: visibleAccountsConnections
|
||||
|
||||
target: accounts.visibleModel
|
||||
|
||||
property var visibleAccountsList: []
|
||||
property var accountsVisibilityMap: ({})
|
||||
|
||||
function updateAccountsList() {
|
||||
const keysAndVisibility = ModelUtils.modelToArray(
|
||||
accounts.visibleModel, ["key", "visibility"])
|
||||
|
||||
visibleAccountsList = keysAndVisibility.map(e => e.key)
|
||||
|
||||
accountsVisibilityMap = keysAndVisibility.reduce(
|
||||
(acc, val) => Object.assign(
|
||||
acc, {[val.key]: val.visibility}), {})
|
||||
}
|
||||
|
||||
function onDataChanged() {
|
||||
updateAccountsList()
|
||||
}
|
||||
|
||||
function onRowsInserted() {
|
||||
updateAccountsList()
|
||||
}
|
||||
|
||||
function onRowsRemoved() {
|
||||
updateAccountsList()
|
||||
}
|
||||
|
||||
function onModelReset() {
|
||||
updateAccountsList()
|
||||
}
|
||||
|
||||
Component.onCompleted: updateAccountsList()
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
ProfileShowcaseDirtyState 1.0 ProfileShowcaseDirtyState.qml
|
||||
ProfileShowcaseModels 1.0 ProfileShowcaseModels.qml
|
||||
VisibilityAndPositionDirtyStateModel 1.0 VisibilityAndPositionDirtyStateModel.qml
|
||||
|
|
Loading…
Reference in New Issue