status-desktop/ui/app/AppLayouts/Wallet/adaptors/CollectiblesSelectionAdapto...

206 lines
7.2 KiB
QML

import QtQuick 2.15
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import SortFilterProxyModel 0.2
import utils 1.0
/**
Adaptor transforming input flat model of collectibles into grouped model,
grouped by communities and collections to form expected by components like
e.g. TokenSelector.
1. Ownership submodels filtered to have only entries for given `account`
2. Total balance calculated for remaining ownership entries in submodels
3. Balance exposed to the top level model
4. Grouping value exposed depending if token comes from community or not
(community collectibles are grouped by communtiyId, other by collectionId)
5. Entries with zero balance filtered out
6. Items are sorted by communityId and collectionId in order to group them correctly
7. Grouping by groupingValue
8. For community groups, group once again by collectionId
9. Expose groupName and type according of it's community group or collection
10. Expose sub-sub-groups count as a balance for sub-groups
**/
QObject {
id: root
/** Account key used for filtering **/
property string accountKey
/**
Expected model structure:
chainId [int] - network chain id
chainName [string] - name of network
iconUrl [string] - network icon url
**/
property var networksModel
/**
Expected model structure:
symbol [string] - unique identifier of a collectible
collectionUid [string] - unique identifier of a collection
contractAddress [string] - collectible's contract address
name [string] - collectible's name e.g. "Magicat"
collectionName [string] - collection name e.g. "Crypto Kitties"
mediaUrl [url] - collectible's media url
imageUrl [url] - collectible's image url
communityId [string] - unique identifier of a community for community collectible or empty
ownership [model] - submodel of balances per chain/account
balance [int] - balance (always 1 for ERC-721)
accountAddress [string] - unique identifier of an account
**/
property var collectiblesModel
/**
Model structure:
groupName [string] - group name (from collection or community name)
icon [url] - from imageUrl or mediaUrl
type [string] - can be "community" or "other"
subitems [model] - submodel of collectibles/collections of the group
key [string] - key of collection (community type) or collectible (other type)
name [string] - name of the subitem (of collectible or collection)
balance [int] - balance of collection (in case of community collectibles)
or collectible (in case of ERC-1155)
icon [url] - icon of the subitem
**/
readonly property alias model: communityGroupsGrouppedByCollection
LeftJoinModel {
id: jointCollectiblesByNwChainId
leftModel: collectiblesModel ?? null
rightModel: networksModel
joinRole: "chainId"
}
SortFilterProxyModel {
id: initiallyFilteredAndSorted
objectName: "collectiblesSelectionAdaptor_initiallyFilteredAndSorted"
sourceModel: ObjectProxyModel {
sourceModel: jointCollectiblesByNwChainId
delegate: QObject {
readonly property int balance: balanceAggregator.value /* 3 */
readonly property string groupingValue: model.communityId /* 4 */
? model.communityId
: model.collectionUid
readonly property string key: model.symbol
readonly property url icon:
model.imageUrl || model.mediaUrl || Theme.png("tokens/DEFAULT-TOKEN")
SortFilterProxyModel { /* 1 */
id: ownershipFiltered
sourceModel: model.ownership
filters: ValueFilter {
roleName: "accountAddress"
value: root.accountKey
}
}
SumAggregator { /* 2 */
id: balanceAggregator
model: ownershipFiltered
roleName: "balance"
}
}
expectedRoles: [
"ownership", "communityId", "collectionUid", "imageUrl",
"mediaUrl", "symbol"
]
exposedRoles: ["balance", "groupingValue", "icon", "key"]
}
filters: RangeFilter { /* 5 */
roleName: "balance"
minimumValue: 1
}
sorters: [ /* 6 */
RoleSorter {
roleName: "communityId"
sortOrder: Qt.DescendingOrder
},
RoleSorter {
roleName: "collectionUid"
}
]
}
GroupingModel { /* 7 */
id: grouppedByCollectionOrCommunity
objectName: "collectiblesSelectionAdaptor_grouppedByCollectionOrCommunity"
sourceModel: initiallyFilteredAndSorted
groupingRoleName: "groupingValue"
submodelRoleName: "subitems"
}
ObjectProxyModel {
id: communityGroupsGrouppedByCollection
objectName: "collectiblesSelectionAdaptor_communityGroupsGrouppedByCollection"
sourceModel: grouppedByCollectionOrCommunity
delegate: QObject {
readonly property var subitems:
model.communityId ? collectionCountProxyLoader.item
: model.subitems
readonly property string type: /* 9 */
model.communityId ? "community" : "other"
readonly property string groupName:
model.communityName || model.collectionName
readonly property url icon:
model.communityId ? model.communityImage
: (model.icon || Qt.resolvedUrl(""))
Loader {
id: collectionCountProxyLoader
active: !!model.communityId
sourceComponent: ObjectProxyModel {
sourceModel: GroupingModel { /* 8 */
sourceModel: model.communityId ? model.subitems : null
groupingRoleName: "collectionUid"
submodelRoleName: "subitems"
}
delegate: QtObject { /* 10 */
readonly property int balance: model.subitems.ModelCount.count
readonly property string key: model.collectionUid
}
expectedRoles: ["subitems", "collectionUid"]
exposedRoles: ["balance", "key"]
}
}
}
expectedRoles: [
"subitems", "collectionName", "communityId",
"communityName", "communityImage", "icon"
]
exposedRoles: ["subitems", "type", "groupName", "icon"]
}
}