parent
6ec562c6b2
commit
30294f97fe
|
@ -30,23 +30,14 @@ proc newController*(
|
|||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc refreshCollections*(self: Controller, chainId: int, address: string) =
|
||||
let collections = self.collectibleService.getOwnedCollections(chainId, address)
|
||||
self.delegate.setCollections(collections)
|
||||
proc refreshCollectibles*(self: Controller, chainId: int, address: string) =
|
||||
let collectibles = self.collectibleService.getOwnedCollectibles(chainId, address)
|
||||
self.delegate.refreshCollectibles(chainId, address, collectibles)
|
||||
|
||||
proc refreshCollectibles*(self: Controller, chainId: int, address: string, collectionSlug: string) =
|
||||
let collection = self.collectibleService.getOwnedCollection(chainId, address, collectionSlug)
|
||||
self.delegate.updateCollection(collection)
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_OWNED_COLLECTIONS_UPDATED) do(e:Args):
|
||||
let args = OwnedCollectionsUpdateArgs(e)
|
||||
self.refreshCollections(args.chainId, args.address)
|
||||
self.collectibleService.fetchAllOwnedCollectibles(args.chainId, args.address)
|
||||
|
||||
self.events.on(SIGNAL_OWNED_COLLECTIBLES_UPDATED) do(e:Args):
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_OWNED_COLLECTIBLES_UPDATE_FINISHED) do(e:Args):
|
||||
let args = OwnedCollectiblesUpdateArgs(e)
|
||||
self.refreshCollectibles(args.chainId, args.address, args.collectionSlug)
|
||||
self.refreshCollectibles(args.chainId, args.address)
|
||||
|
||||
proc getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto =
|
||||
return self.walletAccountService.getWalletAccount(accountIndex)
|
||||
|
@ -54,8 +45,14 @@ proc getWalletAccount*(self: Controller, accountIndex: int): wallet_account_serv
|
|||
proc getNetwork*(self: Controller): network_service.NetworkDto =
|
||||
return self.networkService.getNetworkForCollectibles()
|
||||
|
||||
proc fetchOwnedCollections*(self: Controller, chainId: int, address: string) =
|
||||
self.collectibleService.fetchOwnedCollections(chainId, address)
|
||||
proc resetOwnedCollectibles*(self: Controller, chainId: int, address: string) =
|
||||
self.collectibleService.resetOwnedCollectibles(chainId, address)
|
||||
|
||||
proc fetchOwnedCollectibles*(self: Controller, chainId: int, address: string, collectionSlug: string) =
|
||||
self.collectibleService.fetchOwnedCollectibles(chainId, address, collectionSlug)
|
||||
proc fetchOwnedCollectibles*(self: Controller, chainId: int, address: string, limit: int) =
|
||||
self.collectibleService.fetchOwnedCollectibles(chainId, address, limit)
|
||||
|
||||
proc getCollectible*(self: Controller, chainId: int, id: UniqueID) : CollectibleDto =
|
||||
self.collectibleService.getCollectible(chainId, id)
|
||||
|
||||
proc getCollection*(self: Controller, chainId: int, slug: string) : CollectionDto =
|
||||
self.collectibleService.getCollection(chainId, slug)
|
||||
|
|
|
@ -29,6 +29,7 @@ method setCurrentAddress*(self: Controller, network: network_dto.NetworkDto, add
|
|||
self.network = network
|
||||
self.address = address
|
||||
|
||||
proc update*(self: Controller, collectionSlug: string, id: int) =
|
||||
let collection = self.collectibleService.getOwnedCollection(self.network.chainId, self.address, collectionSlug)
|
||||
self.delegate.setData(collection.collection, collection.collectibles[id], self.network)
|
||||
proc update*(self: Controller, id: collectible_service.UniqueID) =
|
||||
let collectible = self.collectibleService.getCollectible(self.network.chainId, id)
|
||||
let collection = self.collectibleService.getCollection(self.network.chainId, collectible.collectionSlug)
|
||||
self.delegate.setData(collection, collectible, self.network)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import stint
|
||||
import ../../../../../../app_service/service/network/dto as network_dto
|
||||
import ../../../../../../app_service/service/collectible/dto as collectible_dto
|
||||
|
||||
|
@ -17,7 +18,7 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
|||
method setCurrentAddress*(self: AccessInterface, network: network_dto.NetworkDto, address: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method update*(self: AccessInterface, collectionSlug: string, id: int) {.base.} =
|
||||
method update*(self: AccessInterface, address: string, tokenId: Uint256) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setData*(self: AccessInterface, collection: collectible_dto.CollectionDto, collectible: collectible_dto.CollectibleDto, network: network_dto.NetworkDto) {.base.} =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, sequtils, sugar
|
||||
import NimQml, sequtils, sugar, stint
|
||||
|
||||
import ../../../../../global/global_singleton
|
||||
|
||||
|
@ -8,6 +8,9 @@ import ../../../../../../app_service/service/collectible/service as collectible_
|
|||
import ../../../../../../app_service/service/collectible/dto as collectible_dto
|
||||
import ../../../../../../app_service/service/network/dto as network_dto
|
||||
|
||||
import ../models/collectibles_item as collectibles_item
|
||||
import ../models/collectibles_utils
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
|
@ -45,8 +48,13 @@ method viewDidLoad*(self: Module) =
|
|||
method setCurrentAddress*(self: Module, network: network_dto.NetworkDto, address: string) =
|
||||
self.controller.setCurrentAddress(network, address)
|
||||
|
||||
method update*(self: Module, collectionSlug: string, id: int) =
|
||||
self.controller.update(collectionSlug, id)
|
||||
method update*(self: Module, address: string, tokenId: Uint256) =
|
||||
let id = collectible_dto.UniqueID(
|
||||
contractAddress: address,
|
||||
tokenId: tokenId
|
||||
)
|
||||
self.controller.update(id)
|
||||
|
||||
method setData*(self: Module, collection: collectible_dto.CollectionDto, collectible: collectible_dto.CollectibleDto, network: network_dto.NetworkDto) =
|
||||
self.view.setData(collection, collectible, network)
|
||||
let item = collectibleToItem(collectible, collection)
|
||||
self.view.setData(item, network)
|
||||
|
|
|
@ -2,7 +2,7 @@ import NimQml, sequtils, sugar, stint
|
|||
|
||||
import ./io_interface
|
||||
import ../../../../../../app_service/service/network/dto as network_dto
|
||||
import ../../../../../../app_service/service/collectible/dto as collectible_dto
|
||||
import ../models/collectibles_item
|
||||
import ../models/collectible_trait_item
|
||||
import ../models/collectible_trait_model
|
||||
|
||||
|
@ -15,16 +15,7 @@ QtObject:
|
|||
networkColor: string
|
||||
networkIconUrl: string
|
||||
|
||||
collectionName: string
|
||||
collectionImageUrl: string
|
||||
|
||||
name: string
|
||||
id: string
|
||||
tokenId: string
|
||||
description: string
|
||||
backgroundColor: string
|
||||
imageUrl: string
|
||||
permalink: string
|
||||
collectible: Item
|
||||
propertiesModel: TraitModel
|
||||
rankingsModel: TraitModel
|
||||
statsModel: TraitModel
|
||||
|
@ -39,8 +30,7 @@ QtObject:
|
|||
new(result, delete)
|
||||
result.setup()
|
||||
result.delegate = delegate
|
||||
result.description = "Collectibles"
|
||||
result.backgroundColor = "transparent"
|
||||
result.collectible = initItem()
|
||||
result.propertiesModel = newTraitModel()
|
||||
result.rankingsModel = newTraitModel()
|
||||
result.statsModel = newTraitModel()
|
||||
|
@ -76,7 +66,7 @@ QtObject:
|
|||
notify = networkIconUrlChanged
|
||||
|
||||
proc getName(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.name)
|
||||
return newQVariant(self.collectible.getName())
|
||||
|
||||
proc nameChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -85,7 +75,7 @@ QtObject:
|
|||
notify = nameChanged
|
||||
|
||||
proc getID(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.id)
|
||||
return newQVariant(self.collectible.getId())
|
||||
|
||||
proc idChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -94,7 +84,7 @@ QtObject:
|
|||
notify = idChanged
|
||||
|
||||
proc getTokenID(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.tokenId)
|
||||
return newQVariant(self.collectible.getTokenId().toString())
|
||||
|
||||
proc tokenIdChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -103,7 +93,7 @@ QtObject:
|
|||
notify = tokenIdChanged
|
||||
|
||||
proc getDescription(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.description)
|
||||
return newQVariant(self.collectible.getDescription())
|
||||
|
||||
proc descriptionChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -112,7 +102,7 @@ QtObject:
|
|||
notify = descriptionChanged
|
||||
|
||||
proc getBackgroundColor(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.backgroundColor)
|
||||
return newQVariant(self.collectible.getBackgroundColor())
|
||||
|
||||
proc backgroundColorChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -121,7 +111,7 @@ QtObject:
|
|||
notify = backgroundColorChanged
|
||||
|
||||
proc getImageUrl(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.imageUrl)
|
||||
return newQVariant(self.collectible.getImageUrl())
|
||||
|
||||
proc imageUrlChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -130,7 +120,7 @@ QtObject:
|
|||
notify = imageUrlChanged
|
||||
|
||||
proc getCollectionName(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.collectionName)
|
||||
return newQVariant(self.collectible.getCollectionName())
|
||||
|
||||
proc collectionNameChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -139,7 +129,7 @@ QtObject:
|
|||
notify = collectionNameChanged
|
||||
|
||||
proc getCollectionImageUrl(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.collectionImageUrl)
|
||||
return newQVariant(self.collectible.getCollectionImageUrl())
|
||||
|
||||
proc collectionImageUrlChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -148,7 +138,7 @@ QtObject:
|
|||
notify = collectionImageUrlChanged
|
||||
|
||||
proc getPermalink(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.permalink)
|
||||
return newQVariant(self.collectible.getPermalink())
|
||||
|
||||
proc permalinkChanged(self: View) {.signal.}
|
||||
|
||||
|
@ -179,14 +169,14 @@ QtObject:
|
|||
proc getStats*(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.statsModel)
|
||||
|
||||
QtProperty[QVariant] rankings:
|
||||
QtProperty[QVariant] stats:
|
||||
read = getStats
|
||||
notify = statsChanged
|
||||
|
||||
proc update*(self: View, collectionSlug: string, id: int) {.slot.} =
|
||||
self.delegate.update(collectionSlug, id)
|
||||
proc update*(self: View, address: string, tokenId: string) {.slot.} =
|
||||
self.delegate.update(address, parse(tokenId, Uint256))
|
||||
|
||||
proc setData*(self: View, collection: collectible_dto.CollectionDto, collectible: collectible_dto.CollectibleDto, network: network_dto.NetworkDto) =
|
||||
proc setData*(self: View, collectible: Item, network: network_dto.NetworkDto) =
|
||||
if (self.networkShortName != network.shortName):
|
||||
self.networkShortName = network.shortName
|
||||
self.networkShortNameChanged()
|
||||
|
@ -199,46 +189,21 @@ QtObject:
|
|||
self.networkIconUrl = network.iconURL
|
||||
self.networkIconUrlChanged()
|
||||
|
||||
if (self.collectionName != collection.name):
|
||||
self.collectionName = collection.name
|
||||
self.collectionNameChanged()
|
||||
self.collectible = collectible
|
||||
self.collectionNameChanged()
|
||||
self.collectionImageUrlChanged()
|
||||
self.nameChanged()
|
||||
self.idChanged()
|
||||
self.tokenIdChanged()
|
||||
self.descriptionChanged()
|
||||
self.backgroundColorChanged()
|
||||
self.imageUrlChanged()
|
||||
|
||||
if (self.collectionImageUrl != collection.imageUrl):
|
||||
self.collectionImageUrl = collection.imageUrl
|
||||
self.collectionImageUrlChanged()
|
||||
|
||||
if (self.name != collectible.name):
|
||||
self.name = collectible.name
|
||||
self.nameChanged()
|
||||
|
||||
let idString = $collectible.id
|
||||
if (self.id != idString):
|
||||
self.id = idString
|
||||
self.idChanged()
|
||||
|
||||
let tokenIdString = collectible.tokenId.toString()
|
||||
if (self.tokenId != tokenIdString):
|
||||
self.tokenId = tokenIdString
|
||||
self.tokenIdChanged()
|
||||
|
||||
if (self.description != collectible.description):
|
||||
self.description = collectible.description
|
||||
self.descriptionChanged()
|
||||
|
||||
let backgroundColor = if (collectible.backgroundColor == ""): "transparent" else: ("#" & collectible.backgroundColor)
|
||||
if (self.backgroundColor != backgroundColor):
|
||||
self.backgroundColor = backgroundColor
|
||||
self.backgroundColorChanged()
|
||||
|
||||
if (self.imageUrl != collectible.imageUrl):
|
||||
self.imageUrl = collectible.imageUrl
|
||||
self.imageUrlChanged()
|
||||
|
||||
self.propertiesModel.setItems(collectible.properties.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)))
|
||||
self.propertiesModel.setItems(collectible.getProperties())
|
||||
self.propertiesChanged()
|
||||
|
||||
self.rankingsModel.setItems(collectible.rankings.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)))
|
||||
self.rankingsModel.setItems(collectible.getRankings())
|
||||
self.rankingsChanged()
|
||||
|
||||
self.statsModel.setItems(collectible.statistics.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)))
|
||||
self.statsModel.setItems(collectible.getStats())
|
||||
self.statsChanged()
|
||||
|
|
|
@ -16,16 +16,10 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
|||
method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method fetchOwnedCollections*(self: AccessInterface) {.base.} =
|
||||
method fetchOwnedCollectibles*(self: AccessInterface, limit: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method setCollections*(self: AccessInterface, collections: CollectionsData) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method fetchOwnedCollectibles*(self: AccessInterface, collectionSlug: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateCollection*(self: AccessInterface, collection: CollectionData) {.base.} =
|
||||
method refreshCollectibles*(self: AccessInterface, chainId: int, address: string, collectibles: CollectiblesData) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
|
@ -35,8 +29,5 @@ method viewDidLoad*(self: AccessInterface) {.base.} =
|
|||
method collectiblesModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method collectionsModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method currentCollectibleModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -1,221 +0,0 @@
|
|||
import NimQml, Tables, strutils
|
||||
|
||||
import ./collections_model as collections_model
|
||||
import ./collectibles_model as collectibles_model
|
||||
|
||||
type
|
||||
ModelRole* {.pure.} = enum
|
||||
CollectionName = UserRole + 1,
|
||||
CollectionSlug
|
||||
CollectionImageUrl
|
||||
CollectionOwnedAssetCount
|
||||
CollectionCollectiblesCount
|
||||
CollectionCollectiblesLoaded
|
||||
Id
|
||||
Name
|
||||
ImageUrl
|
||||
BackgroundColor
|
||||
Description
|
||||
Permalink
|
||||
Properties
|
||||
Rankings
|
||||
Stats
|
||||
|
||||
const COLLECTION_ROLE_TO_PROXY_ROLE = {
|
||||
CollectionRole.Name: ModelRole.CollectionName,
|
||||
CollectionRole.Slug: ModelRole.CollectionSlug,
|
||||
CollectionRole.ImageUrl: ModelRole.CollectionImageUrl,
|
||||
CollectionRole.OwnedAssetCount: ModelRole.CollectionOwnedAssetCount,
|
||||
CollectionRole.CollectiblesLoaded: ModelRole.CollectionCollectiblesLoaded,
|
||||
}.toTable()
|
||||
|
||||
const COLLECTIBLE_ROLE_TO_PROXY_ROLE = {
|
||||
CollectibleRole.Id: ModelRole.Id,
|
||||
CollectibleRole.Name: ModelRole.Name,
|
||||
CollectibleRole.ImageUrl: ModelRole.ImageUrl,
|
||||
CollectibleRole.BackgroundColor: ModelRole.BackgroundColor,
|
||||
CollectibleRole.Description: ModelRole.Description,
|
||||
CollectibleRole.Permalink: ModelRole.Permalink,
|
||||
CollectibleRole.Properties: ModelRole.Properties,
|
||||
CollectibleRole.Rankings: ModelRole.Rankings,
|
||||
CollectibleRole.Stats: ModelRole.Stats,
|
||||
}.toTable()
|
||||
|
||||
type
|
||||
Index = tuple
|
||||
collectionIdx: int
|
||||
collectibleIdx: int
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
collectionsModel: collections_model.Model
|
||||
sourceIndexToRow: Table[Index, int]
|
||||
collectionToRows: Table[int, (int, int)]
|
||||
rowToSourceIndex: Table[int, Index]
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.collectionsModel = nil
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
proc getCount(self: Model): int {.slot.} =
|
||||
self.sourceIndexToRow.len
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
proc collectionsLoadedChanged(self: Model) {.signal.}
|
||||
proc getCollectionsLoaded*(self: Model): bool {.slot.} =
|
||||
self.collectionsModel.getCollectionsLoaded()
|
||||
QtProperty[bool] collectionsLoaded:
|
||||
read = getCollectionsLoaded
|
||||
notify = collectionsLoadedChanged
|
||||
|
||||
proc collectionCountChanged(self: Model) {.signal.}
|
||||
proc getCollectionCount*(self: Model): int {.slot.} =
|
||||
self.collectionsModel.getCount()
|
||||
QtProperty[int] collectionCount:
|
||||
read = getCollectionCount
|
||||
notify = collectionCountChanged
|
||||
|
||||
proc rebuildMap(self: Model) =
|
||||
self.beginResetModel()
|
||||
self.sourceIndexToRow.clear()
|
||||
self.collectionToRows.clear()
|
||||
self.rowToSourceIndex.clear()
|
||||
var proxy_row = 0
|
||||
for i in 0 ..< self.collectionsModel.getCount():
|
||||
let collectiblesModel = self.collectionsModel.getCollectiblesModel(i)
|
||||
let collectionIndexStart = proxy_row
|
||||
for j in 0 ..< collectiblesModel.getCount():
|
||||
let idx = (collectionIdx: i, collectibleIdx: j)
|
||||
self.sourceIndexToRow[idx] = proxy_row
|
||||
self.rowToSourceIndex[proxy_row] = idx
|
||||
proxy_row += 1
|
||||
self.collectionToRows[i] = (collectionIndexStart, proxy_row - 1)
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
||||
|
||||
proc newModel*(collectionsModel: collections_model.Model): Model =
|
||||
new(result, delete)
|
||||
|
||||
result.collectionsModel = collectionsModel
|
||||
result.setup
|
||||
|
||||
result.rebuildMap()
|
||||
|
||||
signalConnect(result.collectionsModel, "collectionsLoadedChanged()", result, "onCollectionsLoadedChanged()")
|
||||
signalConnect(result.collectionsModel, "countChanged()", result, "onCollectionCountChanged()")
|
||||
signalConnect(result.collectionsModel, "signalDataChanged(int, int, int)", result, "onDataChanged(int, int, int)")
|
||||
|
||||
proc onCollectionsLoadedChanged(self: Model) {.slot.} =
|
||||
self.collectionsLoadedChanged()
|
||||
|
||||
proc onCollectionCountChanged(self: Model) {.slot.} =
|
||||
self.collectionCountChanged()
|
||||
self.rebuildMap()
|
||||
|
||||
proc onDataChanged(self: Model,
|
||||
top: int,
|
||||
bottom: int,
|
||||
role: int) {.slot.} =
|
||||
var topRow = self.collectionToRows[top][0]
|
||||
var bottomRow = self.collectionToRows[bottom][1]
|
||||
|
||||
let topIndex = self.createIndex(topRow, 0, nil)
|
||||
let bottomIndex = self.createIndex(bottomRow, 0, nil)
|
||||
|
||||
if (COLLECTION_ROLE_TO_PROXY_ROLE.hasKey(role.CollectionRole)):
|
||||
self.dataChanged(topIndex, bottomIndex, @[COLLECTION_ROLE_TO_PROXY_ROLE[role.CollectionRole].int])
|
||||
elif role == CollectionRole.CollectiblesModel.int:
|
||||
self.rebuildMap()
|
||||
|
||||
method rowCount*(self: Model, index: QModelIndex = nil): int =
|
||||
return self.getCount()
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.CollectionName.int:"collectionName",
|
||||
ModelRole.CollectionSlug.int:"collectionSlug",
|
||||
ModelRole.CollectionImageUrl.int:"collectionImageUrl",
|
||||
ModelRole.CollectionOwnedAssetCount.int:"collectionOwnedAssetCount",
|
||||
ModelRole.CollectionCollectiblesCount.int:"collectionCollectiblesCount",
|
||||
ModelRole.CollectionCollectiblesLoaded.int:"collectionCollectiblesLoaded",
|
||||
ModelRole.Id.int:"id",
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.ImageUrl.int:"imageUrl",
|
||||
ModelRole.BackgroundColor.int:"backgroundColor",
|
||||
ModelRole.Description.int:"description",
|
||||
ModelRole.Permalink.int:"permalink",
|
||||
ModelRole.Properties.int:"properties",
|
||||
ModelRole.Rankings.int:"rankings",
|
||||
ModelRole.Stats.int:"stats",
|
||||
}.toTable
|
||||
|
||||
proc mapFromSource(self: Model, index: Index): QModelIndex =
|
||||
if not self.sourceIndexToRow.hasKey(index):
|
||||
return QModelIndex()
|
||||
let proxyIndex = self.sourceIndexToRow[index]
|
||||
return self.createIndex(proxyIndex, 0, nil)
|
||||
|
||||
proc mapToSource(self: Model, index: QModelIndex): Index =
|
||||
if not self.rowToSourceIndex.hasKey(index.row):
|
||||
return (collectionIdx: -1, collectibleIdx: -1)
|
||||
return self.rowToSourceIndex[index.row]
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.getCount()):
|
||||
return
|
||||
|
||||
let sourceIndex = self.mapToSource(index)
|
||||
|
||||
let collectionIndex = self.collectionsModel.createIndex(sourceIndex.collectionIdx, 0, nil)
|
||||
let enumRole = role.ModelRole
|
||||
|
||||
case enumRole:
|
||||
of ModelRole.CollectionName:
|
||||
result = self.collectionsModel.data(collectionIndex, CollectionRole.Name.int)
|
||||
of ModelRole.CollectionSlug:
|
||||
result = self.collectionsModel.data(collectionIndex, CollectionRole.Slug.int)
|
||||
of ModelRole.CollectionImageUrl:
|
||||
result = self.collectionsModel.data(collectionIndex, CollectionRole.ImageUrl.int)
|
||||
of ModelRole.CollectionOwnedAssetCount:
|
||||
result = self.collectionsModel.data(collectionIndex, CollectionRole.OwnedAssetCount.int)
|
||||
of ModelRole.CollectionCollectiblesLoaded:
|
||||
result = self.collectionsModel.data(collectionIndex, CollectionRole.CollectiblesLoaded.int)
|
||||
else:
|
||||
let collectiblesModel = self.collectionsModel.getCollectiblesModel(sourceIndex.collectionIdx)
|
||||
let collectibleIndex = collectiblesModel.createIndex(sourceIndex.collectibleIdx, 0, nil)
|
||||
case enumRole:
|
||||
of ModelRole.CollectionCollectiblesCount:
|
||||
result = newQVariant(collectiblesModel.getCount())
|
||||
of ModelRole.Id:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Id.int)
|
||||
of ModelRole.Name:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Name.int)
|
||||
of ModelRole.ImageUrl:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.ImageUrl.int)
|
||||
of ModelRole.BackgroundColor:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.BackgroundColor.int)
|
||||
of ModelRole.Description:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Description.int)
|
||||
of ModelRole.Permalink:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Permalink.int)
|
||||
of ModelRole.Properties:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Properties.int)
|
||||
of ModelRole.Rankings:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Rankings.int)
|
||||
of ModelRole.Stats:
|
||||
result = collectiblesModel.data(collectibleIndex, CollectibleRole.Stats.int)
|
||||
else:
|
||||
return
|
||||
|
||||
proc data*(self: Model, row: int, role: ModelRole): QVariant =
|
||||
return self.data(self.createIndex(row, 0, nil), role.int)
|
|
@ -4,6 +4,7 @@ import ./collectible_trait_item
|
|||
type
|
||||
Item* = object
|
||||
id: int
|
||||
address: string
|
||||
tokenId: UInt256
|
||||
name: string
|
||||
imageUrl: string
|
||||
|
@ -13,9 +14,14 @@ type
|
|||
properties: seq[CollectibleTrait]
|
||||
rankings: seq[CollectibleTrait]
|
||||
stats: seq[CollectibleTrait]
|
||||
collectionName: string
|
||||
collectionSlug: string
|
||||
collectionImageUrl: string
|
||||
isLoading: bool
|
||||
|
||||
proc initItem*(
|
||||
id: int,
|
||||
address: string,
|
||||
tokenId: UInt256,
|
||||
name: string,
|
||||
imageUrl: string,
|
||||
|
@ -24,11 +30,15 @@ proc initItem*(
|
|||
permalink: string,
|
||||
properties: seq[CollectibleTrait],
|
||||
rankings: seq[CollectibleTrait],
|
||||
stats: seq[CollectibleTrait]
|
||||
stats: seq[CollectibleTrait],
|
||||
collectionName: string,
|
||||
collectionSlug: string,
|
||||
collectionImageUrl: string
|
||||
): Item =
|
||||
result.id = id
|
||||
result.address = address
|
||||
result.tokenId = tokenId
|
||||
result.name = name
|
||||
result.name = if (name != ""): name else: ("#" & tokenId.toString())
|
||||
result.imageUrl = imageUrl
|
||||
result.backgroundColor = if (backgroundColor == ""): "transparent" else: ("#" & backgroundColor)
|
||||
result.description = description
|
||||
|
@ -36,24 +46,39 @@ proc initItem*(
|
|||
result.properties = properties
|
||||
result.rankings = rankings
|
||||
result.stats = stats
|
||||
result.collectionName = collectionName
|
||||
result.collectionSlug = collectionSlug
|
||||
result.collectionImageUrl = collectionImageUrl
|
||||
result.isLoading = false
|
||||
|
||||
proc initItem*: Item =
|
||||
result = initItem(-1, u256(0), "", "", "transparent", "Collectibles", "", @[], @[], @[])
|
||||
result = initItem(-1, "", u256(0), "", "", "transparent", "Collectibles", "", @[], @[], @[], "", "", "")
|
||||
|
||||
proc initLoadingItem*: Item =
|
||||
result = initItem()
|
||||
result.isLoading = true
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""Collectibles(
|
||||
id: {self.id},
|
||||
address: {self.address},
|
||||
tokenId: {self.tokenId},
|
||||
name: {self.name},
|
||||
imageUrl: {self.imageUrl},
|
||||
backgroundColor: {self.backgroundColor},
|
||||
description: {self.description},
|
||||
permalink: {self.permalink},
|
||||
collectionName: {self.collectionName},
|
||||
collectionSlug: {self.collectionSlug},
|
||||
collectionImageUrl: {self.collectionImageUrl},
|
||||
]"""
|
||||
|
||||
proc getId*(self: Item): int =
|
||||
return self.id
|
||||
|
||||
proc getAddress*(self: Item): string =
|
||||
return self.address
|
||||
|
||||
proc getTokenId*(self: Item): UInt256 =
|
||||
return self.tokenId
|
||||
|
||||
|
@ -80,3 +105,15 @@ proc getRankings*(self: Item): seq[CollectibleTrait] =
|
|||
|
||||
proc getStats*(self: Item): seq[CollectibleTrait] =
|
||||
return self.stats
|
||||
|
||||
proc getCollectionName*(self: Item): string =
|
||||
return self.collectionName
|
||||
|
||||
proc getCollectionSlug*(self: Item): string =
|
||||
return self.collectionSlug
|
||||
|
||||
proc getCollectionImageUrl*(self: Item): string =
|
||||
return self.collectionImageUrl
|
||||
|
||||
proc getIsLoading*(self: Item): bool =
|
||||
return self.isLoading
|
||||
|
|
|
@ -5,6 +5,7 @@ import ./collectibles_item, ./collectible_trait_model
|
|||
type
|
||||
CollectibleRole* {.pure.} = enum
|
||||
Id = UserRole + 1,
|
||||
Address
|
||||
TokenId
|
||||
Name
|
||||
ImageUrl
|
||||
|
@ -14,11 +15,23 @@ type
|
|||
Properties
|
||||
Rankings
|
||||
Stats
|
||||
CollectionName
|
||||
CollectionSlug
|
||||
CollectionImageUrl
|
||||
IsLoading
|
||||
|
||||
# Maximum number of owned collectibles to be fetched at a time
|
||||
const ownedCollectiblesFetchLimit = 200
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
items: seq[Item]
|
||||
allCollectiblesLoaded: bool
|
||||
isFetching: bool
|
||||
|
||||
proc addLoadingItems(self: Model)
|
||||
proc removeLoadingItems(self: Model)
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
|
@ -27,13 +40,12 @@ QtObject:
|
|||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newModel*(items: seq[Item]): Model =
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
result.items = items
|
||||
|
||||
proc newModel*(): Model =
|
||||
return newModel(@[])
|
||||
result.items = @[]
|
||||
result.allCollectiblesLoaded = false
|
||||
result.isFetching = true
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
|
@ -46,12 +58,50 @@ QtObject:
|
|||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
proc isFetchingChanged(self: Model) {.signal.}
|
||||
proc getIsFetching*(self: Model): bool {.slot.} =
|
||||
self.isFetching
|
||||
QtProperty[bool] isFetching:
|
||||
read = getIsFetching
|
||||
notify = isFetchingChanged
|
||||
proc setIsFetching(self: Model, value: bool) =
|
||||
if value == self.isFetching:
|
||||
return
|
||||
if value:
|
||||
self.addLoadingItems()
|
||||
else:
|
||||
self.removeLoadingItems()
|
||||
self.isFetching = value
|
||||
self.isFetchingChanged()
|
||||
|
||||
proc allCollectiblesLoadedChanged(self: Model) {.signal.}
|
||||
proc getAllCollectiblesLoaded*(self: Model): bool {.slot.} =
|
||||
self.allCollectiblesLoaded
|
||||
QtProperty[bool] allCollectiblesLoaded:
|
||||
read = getAllCollectiblesLoaded
|
||||
notify = allCollectiblesLoadedChanged
|
||||
proc setAllCollectiblesLoaded*(self: Model, value: bool) =
|
||||
if value == self.allCollectiblesLoaded:
|
||||
return
|
||||
self.allCollectiblesLoaded = value
|
||||
self.allCollectiblesLoadedChanged()
|
||||
|
||||
method canFetchMore*(self: Model, parent: QModelIndex): bool =
|
||||
return not self.allCollectiblesLoaded and not self.isFetching
|
||||
|
||||
proc requestFetch(self: Model, limit: int) {.signal.}
|
||||
method fetchMore*(self: Model, parent: QModelIndex) =
|
||||
if not self.isFetching:
|
||||
self.setIsFetching(true)
|
||||
self.requestFetch(ownedCollectiblesFetchLimit)
|
||||
|
||||
method rowCount*(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
CollectibleRole.Id.int:"id",
|
||||
CollectibleRole.Address.int:"address",
|
||||
CollectibleRole.TokenId.int:"tokenId",
|
||||
CollectibleRole.Name.int:"name",
|
||||
CollectibleRole.ImageUrl.int:"imageUrl",
|
||||
|
@ -61,6 +111,10 @@ QtObject:
|
|||
CollectibleRole.Properties.int:"properties",
|
||||
CollectibleRole.Rankings.int:"rankings",
|
||||
CollectibleRole.Stats.int:"stats",
|
||||
CollectibleRole.CollectionName.int:"collectionName",
|
||||
CollectibleRole.CollectionSlug.int:"collectionSlug",
|
||||
CollectibleRole.CollectionImageUrl.int:"collectionImageUrl",
|
||||
CollectibleRole.IsLoading.int:"isLoading",
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -76,6 +130,8 @@ QtObject:
|
|||
case enumRole:
|
||||
of CollectibleRole.Id:
|
||||
result = newQVariant(item.getId())
|
||||
of CollectibleRole.Address:
|
||||
result = newQVariant(item.getAddress())
|
||||
of CollectibleRole.TokenId:
|
||||
result = newQVariant(item.getTokenId().toString())
|
||||
of CollectibleRole.Name:
|
||||
|
@ -100,15 +156,45 @@ QtObject:
|
|||
let traits = newTraitModel()
|
||||
traits.setItems(item.getStats())
|
||||
result = newQVariant(traits)
|
||||
of CollectibleRole.CollectionName:
|
||||
result = newQVariant(item.getCollectionName())
|
||||
of CollectibleRole.CollectionSlug:
|
||||
result = newQVariant(item.getCollectionSlug())
|
||||
of CollectibleRole.CollectionImageUrl:
|
||||
result = newQVariant(item.getCollectionImageUrl())
|
||||
of CollectibleRole.IsLoading:
|
||||
result = newQVariant(item.getIsLoading())
|
||||
|
||||
proc getItem*(self: Model, index: int): Item =
|
||||
return self.items[index]
|
||||
proc addLoadingItems(self: Model) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
||||
self.items = items
|
||||
self.endResetModel()
|
||||
let loadingItem = initLoadingItem()
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len + ownedCollectiblesFetchLimit - 1)
|
||||
for i in 1..ownedCollectiblesFetchLimit:
|
||||
self.items.add(loadingItem)
|
||||
self.endInsertRows()
|
||||
self.countChanged()
|
||||
|
||||
proc appendItems*(self: Model, items: seq[Item]) =
|
||||
self.setItems(concat(self.items, items))
|
||||
proc removeLoadingItems(self: Model) =
|
||||
for i in 0 ..< self.items.len:
|
||||
if self.items[i].getIsLoading():
|
||||
self.beginRemoveRows(newQModelIndex(), i, self.items.len-1)
|
||||
self.items.delete(i, self.items.len-1)
|
||||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
return
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item], append: bool) =
|
||||
self.setIsFetching(false)
|
||||
if append:
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len + items.len - 1)
|
||||
self.items = concat(self.items, items)
|
||||
self.endInsertRows()
|
||||
else:
|
||||
self.beginResetModel()
|
||||
self.items = items
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
||||
|
|
|
@ -2,9 +2,10 @@ import sequtils, sugar
|
|||
import ../../../../../../app_service/service/collectible/dto
|
||||
import collectibles_item, collectible_trait_item
|
||||
|
||||
proc collectibleToItem*(c: CollectibleDto) : Item =
|
||||
proc collectibleToItem*(c: CollectibleDto, co: CollectionDto) : Item =
|
||||
return initItem(
|
||||
c.id,
|
||||
c.address,
|
||||
c.tokenId,
|
||||
c.name,
|
||||
c.imageUrl,
|
||||
|
@ -13,5 +14,8 @@ proc collectibleToItem*(c: CollectibleDto) : Item =
|
|||
c.permalink,
|
||||
c.properties.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)),
|
||||
c.rankings.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)),
|
||||
c.statistics.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue))
|
||||
c.statistics.map(t => initTrait(t.traitType, t.value, t.displayType, t.maxValue)),
|
||||
co.name,
|
||||
co.slug,
|
||||
co.imageUrl
|
||||
)
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
import strformat, stint
|
||||
import ./collectibles_model as collectibles_model
|
||||
import ./collectibles_item as collectibles_item
|
||||
|
||||
type
|
||||
Item* = object
|
||||
name: string
|
||||
slug: string
|
||||
imageUrl: string
|
||||
ownedAssetCount: Uint256
|
||||
collectiblesLoaded*: bool
|
||||
collectiblesModel: collectibles_model.Model
|
||||
|
||||
proc initItem*(name, slug, imageUrl: string, ownedAssetCount: Uint256, collectiblesLoaded: bool, collectibles: seq[collectibles_item.Item]): Item =
|
||||
result.name = name
|
||||
result.slug = slug
|
||||
result.imageUrl = imageUrl
|
||||
result.ownedAssetCount = ownedAssetCount
|
||||
result.collectiblesLoaded = collectiblesLoaded
|
||||
result.collectiblesModel = collectibles_model.newModel(collectibles)
|
||||
|
||||
proc initItem*(): Item =
|
||||
result = initItem("", "", "", u256(0), false, @[])
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""CollectibleCollection(
|
||||
name: {self.name},
|
||||
slug: {self.slug},
|
||||
imageUrl: {self.imageUrl},
|
||||
ownedAssetCount: {self.ownedAssetCount},
|
||||
collectiblesLoaded: {self.collectiblesLoaded},
|
||||
collectibles: {self.collectiblesModel}
|
||||
]"""
|
||||
|
||||
proc getName*(self: Item): string =
|
||||
return self.name
|
||||
|
||||
proc getSlug*(self: Item): string =
|
||||
return self.slug
|
||||
|
||||
proc getImageUrl*(self: Item): string =
|
||||
return self.imageUrl
|
||||
|
||||
proc getOwnedAssetCount*(self: Item): Uint256 =
|
||||
return self.ownedAssetCount
|
||||
|
||||
proc getCollectiblesLoaded*(self: Item): bool =
|
||||
return self.collectiblesLoaded
|
||||
|
||||
proc getCollectiblesModel*(self: Item): collectibles_model.Model =
|
||||
return self.collectiblesModel
|
|
@ -1,131 +0,0 @@
|
|||
import NimQml, Tables, strutils, strformat, stint
|
||||
|
||||
import ./collections_item as collections_item
|
||||
|
||||
import ./collectibles_model as collectibles_model
|
||||
import ./collectibles_item as collectibles_item
|
||||
|
||||
type
|
||||
CollectionRole* {.pure.} = enum
|
||||
Name = UserRole + 1,
|
||||
Slug
|
||||
ImageUrl
|
||||
OwnedAssetCount
|
||||
CollectiblesLoaded
|
||||
CollectiblesModel
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
items: seq[collections_item.Item]
|
||||
collectionsLoaded: bool
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
self.collectionsLoaded = false
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""[{i}]:({$self.items[i]})"""
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
proc getCount*(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
proc collectionsLoadedChanged(self: Model) {.signal.}
|
||||
proc getCollectionsLoaded*(self: Model): bool {.slot.} =
|
||||
self.collectionsLoaded
|
||||
QtProperty[bool] collectionsLoaded:
|
||||
read = getCollectionsLoaded
|
||||
notify = collectionsLoadedChanged
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
CollectionRole.Name.int:"name",
|
||||
CollectionRole.Slug.int:"slug",
|
||||
CollectionRole.ImageUrl.int:"imageUrl",
|
||||
CollectionRole.OwnedAssetCount.int:"ownedAssetCount",
|
||||
CollectionRole.CollectiblesLoaded.int:"collectiblesLoaded",
|
||||
CollectionRole.CollectiblesModel.int:"collectiblesModel"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.items.len):
|
||||
return
|
||||
|
||||
let item = self.items[index.row]
|
||||
let enumRole = role.CollectionRole
|
||||
|
||||
case enumRole:
|
||||
of CollectionRole.Name:
|
||||
result = newQVariant(item.getName())
|
||||
of CollectionRole.Slug:
|
||||
result = newQVariant(item.getSlug())
|
||||
of CollectionRole.ImageUrl:
|
||||
result = newQVariant(item.getImageUrl())
|
||||
of CollectionRole.OwnedAssetCount:
|
||||
result = newQVariant(item.getOwnedAssetCount().toString())
|
||||
of CollectionRole.CollectiblesLoaded:
|
||||
result = newQVariant(item.getCollectiblesLoaded())
|
||||
of CollectionRole.CollectiblesModel:
|
||||
result = newQVariant(item.getCollectiblesModel())
|
||||
|
||||
proc setCollections*(self: Model, items: seq[collections_item.Item], collectionsLoaded: bool) =
|
||||
self.beginResetModel()
|
||||
self.items = items
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
||||
if self.collectionsLoaded != collectionsLoaded:
|
||||
self.collectionsLoaded = collectionsLoaded
|
||||
self.collectionsLoadedChanged()
|
||||
|
||||
proc getCollectionItem*(self: Model, index: int) : collections_item.Item =
|
||||
return self.items[index]
|
||||
|
||||
proc getCollectiblesModel*(self: Model, index: int) : collectibles_model.Model =
|
||||
if index < self.items.len:
|
||||
return self.items[index].getCollectiblesModel()
|
||||
echo "getCollectiblesModel: Invalid index ", index, " with len ", self.items.len
|
||||
return collectibles_model.newModel()
|
||||
|
||||
proc findIndexBySlug(self: Model, slug: string): int =
|
||||
for i in 0 ..< self.items.len:
|
||||
if self.items[i].getSlug() == slug:
|
||||
return i
|
||||
return -1
|
||||
|
||||
proc signalDataChanged(self: Model, top: int, bottom: int, roles: int) {.signal.}
|
||||
|
||||
proc emitDataChanged(self: Model, top: int, bottom: int, role: int) =
|
||||
let topIndex = self.createIndex(top, 0, nil)
|
||||
let bottomIndex = self.createIndex(bottom, 0, nil)
|
||||
self.dataChanged(topIndex, bottomIndex, @[role])
|
||||
self.signalDataChanged(top, bottom, role)
|
||||
|
||||
proc updateCollectionCollectibles*(self: Model, slug: string, collectibles: seq[collectibles_item.Item], collectiblesLoaded: bool) =
|
||||
let idx = self.findIndexBySlug(slug)
|
||||
if idx > -1:
|
||||
let collectiblesModel = self.items[idx].getCollectiblesModel()
|
||||
collectiblesModel.setItems(collectibles)
|
||||
self.emitDataChanged(idx, idx, CollectionRole.CollectiblesModel.int)
|
||||
|
||||
if self.items[idx].getCollectiblesLoaded() != collectiblesLoaded:
|
||||
self.items[idx].collectiblesLoaded = collectiblesLoaded
|
||||
self.emitDataChanged(idx, idx, CollectionRole.CollectiblesLoaded.int)
|
|
@ -1,13 +0,0 @@
|
|||
import sequtils, sugar, Tables
|
||||
import ../../../../../../app_service/service/collectible/service
|
||||
import collections_item, collectibles_utils
|
||||
|
||||
proc collectionToItem*(collection: CollectionData) : Item =
|
||||
return initItem(
|
||||
collection.collection.name,
|
||||
collection.collection.slug,
|
||||
collection.collection.imageUrl,
|
||||
collection.collection.ownedAssetCount,
|
||||
collection.collectiblesLoaded,
|
||||
toSeq(collection.collectibles.values).map(c => collectibleToItem(c))
|
||||
)
|
|
@ -11,8 +11,6 @@ import ../../../../../app_service/service/network/service as network_service
|
|||
|
||||
import ./current_collectible/module as current_collectible_module
|
||||
|
||||
import ./models/collections_item as collections_item
|
||||
import ./models/collections_utils
|
||||
import ./models/collectibles_item as collectibles_item
|
||||
import ./models/collectible_trait_item as collectible_trait_item
|
||||
import ./models/collectibles_utils
|
||||
|
@ -45,7 +43,6 @@ proc newModule*(
|
|||
result.moduleLoaded = false
|
||||
result.currentCollectibleModule = currentCollectibleModule.newModule(result, collectibleService)
|
||||
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.currentCollectibleModule.delete
|
||||
|
@ -76,6 +73,9 @@ method viewDidLoad*(self: Module) =
|
|||
method currentCollectibleModuleDidLoad*(self: Module) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method fetchOwnedCollectibles*(self: Module, limit: int) =
|
||||
self.controller.fetchOwnedCollectibles(self.chainId, self.address, limit)
|
||||
|
||||
method switchAccount*(self: Module, accountIndex: int) =
|
||||
let network = self.controller.getNetwork()
|
||||
let account = self.controller.getWalletAccount(accountIndex)
|
||||
|
@ -83,40 +83,30 @@ method switchAccount*(self: Module, accountIndex: int) =
|
|||
self.chainId = network.chainId
|
||||
self.address = account.address
|
||||
|
||||
self.controller.refreshCollections(self.chainId, self.address)
|
||||
self.controller.fetchOwnedCollections(self.chainId, self.address)
|
||||
# TODO: Implement a way to reduce the number of full re-fetches. It could be only
|
||||
# when NFT activity was detected for the given account, or if a certain amount of
|
||||
# time has passed. For now, we fetch every time we select the account.
|
||||
self.controller.resetOwnedCollectibles(self.chainId, self.address)
|
||||
|
||||
self.controller.refreshCollectibles(self.chainId, self.address)
|
||||
|
||||
self.currentCollectibleModule.setCurrentAddress(network, self.address)
|
||||
|
||||
proc collectionToItem(self: Module, collection: CollectionData) : collections_item.Item =
|
||||
var item = collectionToItem(collection)
|
||||
#[ Skeleton items are disabled until problem with OpenSea API is researched.
|
||||
OpenSea is telling us the address owns a certain amount of NFTs from a certain collection, but
|
||||
it doesn't give us the NFTs from that collection when trying to fetch them.
|
||||
# Append skeleton collectibles if not yet fetched
|
||||
let model = item.getCollectiblesModel()
|
||||
let unfetchedCollectiblesCount = item.getOwnedAssetCount() - model.getCount()
|
||||
if unfetchedCollectiblesCount > 0:
|
||||
echo "unfetchedCollectiblesCount = ", unfetchedCollectiblesCount, " ", item.getSlug()
|
||||
let skeletonItems = newSeqWith(unfetchedCollectiblesCount, collectibles_item.initItem())
|
||||
model.appendItems(skeletonItems)
|
||||
]#
|
||||
return item
|
||||
method refreshCollectibles*(self: Module, chainId: int, address: string, collectibles: CollectiblesData) =
|
||||
if self.chainId == chainId and self.address == address:
|
||||
var idsToAdd = newSeq[UniqueID]()
|
||||
let append = not collectibles.lastLoadWasFromStart
|
||||
|
||||
method setCollections*(self: Module, collections: CollectionsData) =
|
||||
self.view.setCollections(
|
||||
toSeq(collections.collections.values).map(c => self.collectionToItem(c)),
|
||||
collections.collectionsLoaded
|
||||
)
|
||||
var startIdx = 0
|
||||
if append:
|
||||
for i in collectibles.ids.len - collectibles.lastLoadCount ..< collectibles.ids.len:
|
||||
idsToAdd.add(collectibles.ids[i])
|
||||
else:
|
||||
idsToAdd = collectibles.ids
|
||||
|
||||
method updateCollection*(self: Module, collection: CollectionData) =
|
||||
self.view.setCollectibles(collection.collection.slug,
|
||||
toSeq(collection.collectibles.values).map(c => collectibleToItem(c)),
|
||||
collection.collectiblesLoaded
|
||||
)
|
||||
|
||||
method fetchOwnedCollections*(self: Module) =
|
||||
self.controller.fetchOwnedCollections(self.chainId, self.address)
|
||||
|
||||
method fetchOwnedCollectibles*(self: Module, collectionSlug: string) =
|
||||
self.controller.fetchOwnedCollectibles(self.chainId, self.address, collectionSlug)
|
||||
var newCollectibles = idsToAdd.map(id => (block:
|
||||
let c = self.controller.getCollectible(self.chainId, id)
|
||||
let co = self.controller.getCollection(self.chainId, c.collectionSlug)
|
||||
return collectibleToItem(c, co)
|
||||
))
|
||||
self.view.setCollectibles(newCollectibles, append, collectibles.allLoaded)
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import NimQml
|
||||
|
||||
import ./models/collections_model as collections_model
|
||||
import ./models/collectibles_flat_proxy_model as flat_model
|
||||
import ./models/collections_item as collections_item
|
||||
import ./models/collectibles_item as collectibles_item
|
||||
import ./models/collectibles_model
|
||||
import ./models/collectibles_item
|
||||
import ./io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: collections_model.Model
|
||||
flatModel: flat_model.Model
|
||||
model: Model
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.flatModel.delete
|
||||
self.model.delete
|
||||
self.QObject.delete
|
||||
|
||||
|
@ -23,7 +19,7 @@ QtObject:
|
|||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
result.flatModel = flat_model.newModel(result.model)
|
||||
signalConnect(result.model, "requestFetch(int)", result, "fetchMoreOwnedCollectibles(int)")
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
@ -35,21 +31,9 @@ QtObject:
|
|||
read = getModel
|
||||
notify = modelChanged
|
||||
|
||||
proc flatModelChanged*(self: View) {.signal.}
|
||||
proc getFlatModel(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.flatModel)
|
||||
QtProperty[QVariant] flatModel:
|
||||
read = getFlatModel
|
||||
notify = flatModelChanged
|
||||
proc fetchMoreOwnedCollectibles*(self: View, limit: int) {.slot.} =
|
||||
self.delegate.fetchOwnedCollectibles(limit)
|
||||
|
||||
proc fetchOwnedCollections*(self: View) {.slot.} =
|
||||
self.delegate.fetchOwnedCollections()
|
||||
|
||||
proc fetchOwnedCollectibles*(self: View, collectionSlug: string) {.slot.} =
|
||||
self.delegate.fetchOwnedCollectibles(collectionSlug)
|
||||
|
||||
proc setCollections*(self: View, collections: seq[collections_item.Item], collectionsLoaded: bool) =
|
||||
self.model.setCollections(collections, collectionsLoaded)
|
||||
|
||||
proc setCollectibles*(self: View, collectionsSlug: string, collectibles: seq[collectibles_item.Item], collectiblesLoaded: bool) =
|
||||
self.model.updateCollectionCollectibles(collectionsSlug, collectibles, collectiblesLoaded)
|
||||
proc setCollectibles*(self: View, collectibles: seq[Item], append: bool, allLoaded: bool) =
|
||||
self.model.setItems(collectibles, append)
|
||||
self.model.setAllCollectiblesLoaded(allLoaded)
|
||||
|
|
|
@ -1,28 +1,8 @@
|
|||
type
|
||||
FetchOwnedCollectionsTaskArg = ref object of QObjectTaskArg
|
||||
chainId*: int
|
||||
address*: string
|
||||
|
||||
const fetchOwnedCollectionsTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[FetchOwnedCollectionsTaskArg](argEncoded)
|
||||
let output = %* {
|
||||
"chainId": arg.chainId,
|
||||
"address": arg.address,
|
||||
"collections": ""
|
||||
}
|
||||
try:
|
||||
let response = collectibles.getOpenseaCollectionsByOwner(arg.chainId, arg.address)
|
||||
output["collections"] = response.result
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error fetchOwnedCollectionsTaskArg: ", errDesription
|
||||
arg.finish(output)
|
||||
|
||||
type
|
||||
FetchOwnedCollectiblesTaskArg = ref object of QObjectTaskArg
|
||||
chainId*: int
|
||||
address*: string
|
||||
collectionSlug: string
|
||||
cursor: string
|
||||
limit: int
|
||||
|
||||
const fetchOwnedCollectiblesTaskArg: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
|
@ -30,11 +10,11 @@ const fetchOwnedCollectiblesTaskArg: Task = proc(argEncoded: string) {.gcsafe, n
|
|||
let output = %* {
|
||||
"chainId": arg.chainId,
|
||||
"address": arg.address,
|
||||
"collectionSlug": arg.collectionSlug,
|
||||
"cursor": arg.cursor,
|
||||
"collectibles": ""
|
||||
}
|
||||
try:
|
||||
let response = collectibles.getOpenseaAssetsByOwnerAndCollection(arg.chainId, arg.address, arg.collectionSlug, arg.limit)
|
||||
let response = collectibles.getOpenseaAssetsByOwnerWithCursor(arg.chainId, arg.address, arg.cursor, arg.limit)
|
||||
output["collectibles"] = response.result
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import json, Tables, stint, strformat, strutils
|
||||
|
||||
# Unique identifier for collectible on a specific chain
|
||||
type
|
||||
UniqueID* = object
|
||||
contractAddress*: string
|
||||
tokenId*: UInt256
|
||||
|
||||
type CollectibleTraitType* {.pure.} = enum
|
||||
Properties = 0,
|
||||
|
@ -11,7 +16,6 @@ type CollectionTrait* = ref object
|
|||
|
||||
type CollectionDto* = ref object
|
||||
name*, slug*, imageUrl*: string
|
||||
ownedAssetCount*: Uint256
|
||||
trait*: Table[string, CollectionTrait]
|
||||
|
||||
type CollectibleTrait* = ref object
|
||||
|
@ -20,7 +24,7 @@ type CollectibleTrait* = ref object
|
|||
type CollectibleDto* = ref object
|
||||
id*: int
|
||||
tokenId*: Uint256
|
||||
name*, description*, permalink*, imageThumbnailUrl*, imageUrl*, address*, backgroundColor*: string
|
||||
address*, collectionSlug*, name*, description*, permalink*, imageThumbnailUrl*, imageUrl*, backgroundColor*: string
|
||||
properties*, rankings*, statistics*: seq[CollectibleTrait]
|
||||
|
||||
proc newCollectibleDto*: CollectibleDto =
|
||||
|
@ -31,6 +35,14 @@ proc newCollectibleDto*: CollectibleDto =
|
|||
proc isValid*(self: CollectibleDto): bool =
|
||||
return self.id >= 0
|
||||
|
||||
proc newCollectionDto*: CollectionDto =
|
||||
return CollectionDto(
|
||||
slug: ""
|
||||
)
|
||||
|
||||
proc isValid*(self: CollectionDto): bool =
|
||||
return self.slug != ""
|
||||
|
||||
proc isNumeric(s: string): bool =
|
||||
try:
|
||||
discard s.parseFloat()
|
||||
|
@ -39,14 +51,14 @@ proc isNumeric(s: string): bool =
|
|||
result = false
|
||||
|
||||
proc `$`*(self: CollectionDto): string =
|
||||
return fmt"CollectionDto(name:{self.name}, slug:{self.slug}, owned asset count:{self.ownedAssetCount})"
|
||||
return fmt"CollectionDto(name:{self.name}, slug:{self.slug})"
|
||||
|
||||
proc `$`*(self: CollectibleDto): string =
|
||||
return fmt"CollectibleDto(id:{self.id}, token_id:{self.tokenId}, name:{self.name}, description:{self.description}, permalink:{self.permalink}, address:{self.address}, imageUrl: {self.imageUrl}, imageThumbnailUrl: {self.imageThumbnailUrl}, backgroundColor: {self.backgroundColor})"
|
||||
return fmt"CollectibleDto(id:{self.id}, address:{self.address}, tokenId:{self.tokenId}, collectionSlug:{self.collectionSlug}, name:{self.name}, description:{self.description}, permalink:{self.permalink}, imageUrl: {self.imageUrl}, imageThumbnailUrl: {self.imageThumbnailUrl}, backgroundColor: {self.backgroundColor})"
|
||||
|
||||
proc getCollectionTraits*(jsonCollection: JsonNode): Table[string, CollectionTrait] =
|
||||
var traitList: Table[string, CollectionTrait] = initTable[string, CollectionTrait]()
|
||||
for key, value in jsonCollection{"traits"}:
|
||||
for key, value in jsonCollection{"traits"}.getFields():
|
||||
traitList[key] = CollectionTrait(min: value{"min"}.getFloat, max: value{"max"}.getFloat)
|
||||
return traitList
|
||||
|
||||
|
@ -55,7 +67,6 @@ proc toCollectionDto*(jsonCollection: JsonNode): CollectionDto =
|
|||
name: jsonCollection{"name"}.getStr,
|
||||
slug: jsonCollection{"slug"}.getStr,
|
||||
imageUrl: jsonCollection{"image_url"}.getStr,
|
||||
ownedAssetCount: stint.parse(jsonCollection{"owned_asset_count"}.getStr, Uint256),
|
||||
trait: getCollectionTraits(jsonCollection)
|
||||
)
|
||||
|
||||
|
@ -79,13 +90,14 @@ proc getTrait*(jsonAsset: JsonNode, traitType: CollectibleTraitType): seq[Collec
|
|||
proc toCollectibleDto*(jsonAsset: JsonNode): CollectibleDto =
|
||||
return CollectibleDto(
|
||||
id: jsonAsset{"id"}.getInt,
|
||||
address: jsonAsset{"asset_contract"}{"address"}.getStr,
|
||||
tokenId: stint.parse(jsonAsset{"token_id"}.getStr, Uint256),
|
||||
collectionSlug: jsonAsset{"collection"}{"slug"}.getStr,
|
||||
name: jsonAsset{"name"}.getStr,
|
||||
description: jsonAsset{"description"}.getStr,
|
||||
permalink: jsonAsset{"permalink"}.getStr,
|
||||
imageThumbnailUrl: jsonAsset{"image_thumbnail_url"}.getStr,
|
||||
imageUrl: jsonAsset{"image_url"}.getStr,
|
||||
address: jsonAsset{"asset_contract"}{"address"}.getStr,
|
||||
backgroundColor: jsonAsset{"background_color"}.getStr,
|
||||
properties: getTrait(jsonAsset, CollectibleTraitType.Properties),
|
||||
rankings: getTrait(jsonAsset, CollectibleTraitType.Rankings),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables, chronicles, sequtils, json, sugar, stint, hashes
|
||||
import NimQml, Tables, chronicles, sequtils, json, sugar, stint, hashes, strformat, times
|
||||
import ../../../app/core/eventemitter
|
||||
import ../../../app/core/tasks/[qt, threadpool]
|
||||
|
||||
|
@ -16,29 +16,14 @@ logScope:
|
|||
topics = "collectible-service"
|
||||
|
||||
# Signals which may be emitted by this service:
|
||||
const SIGNAL_OWNED_COLLECTIONS_UPDATED* = "ownedCollectionsUpdated"
|
||||
const SIGNAL_OWNED_COLLECTIBLES_UPDATED* = "ownedCollectiblesUpdated"
|
||||
const SIGNAL_OWNED_COLLECTIBLES_UPDATE_STARTED* = "ownedCollectiblesUpdateStarted"
|
||||
const SIGNAL_OWNED_COLLECTIBLES_UPDATE_FINISHED* = "ownedCollectiblesUpdateFinished"
|
||||
const SIGNAL_COLLECTIBLES_UPDATED* = "collectiblesUpdated"
|
||||
|
||||
# Maximum number of collectibles to be fetched at a time
|
||||
const limit = 200
|
||||
|
||||
# Unique identifier for collectible in a specific chain
|
||||
type
|
||||
UniqueID* = object
|
||||
contractAddress*: string
|
||||
tokenId*: UInt256
|
||||
|
||||
type
|
||||
OwnedCollectionsUpdateArgs* = ref object of Args
|
||||
chainId*: int
|
||||
address*: string
|
||||
|
||||
type
|
||||
OwnedCollectiblesUpdateArgs* = ref object of Args
|
||||
chainId*: int
|
||||
address*: string
|
||||
collectionSlug*: string
|
||||
|
||||
type
|
||||
CollectiblesUpdateArgs* = ref object of Args
|
||||
|
@ -46,32 +31,47 @@ type
|
|||
ids*: seq[UniqueID]
|
||||
|
||||
type
|
||||
CollectionData* = ref object
|
||||
collection*: CollectionDto
|
||||
collectiblesLoaded*: bool
|
||||
collectibles*: OrderedTableRef[int, CollectibleDto] # [collectibleId, CollectibleDto]
|
||||
|
||||
proc newCollectionData*(collection: CollectionDto): CollectionData =
|
||||
new(result)
|
||||
result.collection = collection
|
||||
result.collectiblesLoaded = false
|
||||
result.collectibles = newOrderedTable[int, CollectibleDto]()
|
||||
|
||||
type
|
||||
CollectionsData* = ref object
|
||||
collectionsLoaded*: bool
|
||||
collections*: OrderedTableRef[string, CollectionData] # [collectionSlug, CollectionData]
|
||||
CollectiblesData* = ref object
|
||||
isFetching*: bool
|
||||
allLoaded*: bool
|
||||
lastLoadWasFromStart*: bool
|
||||
lastLoadFromStartTimestamp*: DateTime
|
||||
lastLoadCount*: int
|
||||
previousCursor*: string
|
||||
nextCursor*: string
|
||||
ids*: seq[UniqueID]
|
||||
|
||||
proc newCollectionsData*(): CollectionsData =
|
||||
proc newCollectiblesData*(): CollectiblesData =
|
||||
new(result)
|
||||
result.collectionsLoaded = false
|
||||
result.collections = newOrderedTable[string, CollectionData]()
|
||||
result.isFetching = false
|
||||
result.allLoaded = false
|
||||
result.lastLoadWasFromStart = false
|
||||
result.lastLoadFromStartTimestamp = now() - initDuration(weeks = 1)
|
||||
result.lastLoadCount = 0
|
||||
result.previousCursor = ""
|
||||
result.nextCursor = ""
|
||||
result.ids = @[]
|
||||
|
||||
proc `$`*(self: CollectiblesData): string =
|
||||
return fmt"""CollectiblesData(
|
||||
isFetching:{self.isFetching},
|
||||
allLoaded:{self.allLoaded},
|
||||
lastLoadWasFromStart:{self.lastLoadWasFromStart},
|
||||
lastLoadFromStartTimestamp:{self.lastLoadFromStartTimestamp},
|
||||
lastLoadCount:{self.lastLoadCount},
|
||||
previousCursor:{self.previousCursor},
|
||||
nextCursor:{self.nextCursor},
|
||||
ids:{self.ids}
|
||||
)"""
|
||||
|
||||
type
|
||||
AdressesData* = TableRef[string, CollectionsData] # [address, CollectionsData]
|
||||
AdressesData = TableRef[string, CollectiblesData] # [address, CollectiblesData]
|
||||
|
||||
type
|
||||
ChainsData* = TableRef[int, AdressesData] # [chainId, AdressesData]
|
||||
ChainsData = TableRef[int, AdressesData] # [chainId, AdressesData]
|
||||
|
||||
type
|
||||
CollectiblesResult = tuple[success: bool, collectibles: seq[CollectibleDto], collections: seq[CollectionDto], previousCursor: string, nextCursor: string]
|
||||
|
||||
proc hash(x: UniqueID): Hash =
|
||||
result = x.contractAddress.hash !& x.tokenId.hash
|
||||
|
@ -84,7 +84,8 @@ QtObject:
|
|||
threadpool: ThreadPool
|
||||
networkService: network_service.Service
|
||||
ownershipData: ChainsData
|
||||
data: TableRef[int, TableRef[UniqueID, CollectibleDto]] # [chainId, [UniqueID, CollectibleDto]]
|
||||
collectibles: TableRef[int, TableRef[UniqueID, CollectibleDto]] # [chainId, [UniqueID, CollectibleDto]]
|
||||
collections: TableRef[int, TableRef[string, CollectionDto]] # [chainId, [slug, CollectionDto]]
|
||||
|
||||
proc delete*(self: Service) =
|
||||
self.QObject.delete
|
||||
|
@ -100,115 +101,126 @@ QtObject:
|
|||
result.threadpool = threadpool
|
||||
result.networkService = networkService
|
||||
result.ownershipData = newTable[int, AdressesData]()
|
||||
result.data = newTable[int, TableRef[UniqueID, CollectibleDto]]()
|
||||
result.collectibles = newTable[int, TableRef[UniqueID, CollectibleDto]]()
|
||||
result.collections = newTable[int, TableRef[string, CollectionDto]]()
|
||||
|
||||
proc init*(self: Service) =
|
||||
discard
|
||||
|
||||
proc insertAddressIfNeeded*(self: Service, chainId: int, address: string) =
|
||||
proc prepareOwnershipData(self: Service, chainId: int, address: string, reset: bool = false) =
|
||||
if not self.ownershipData.hasKey(chainId):
|
||||
self.ownershipData[chainId] = newTable[string, CollectionsData]()
|
||||
self.ownershipData[chainId] = newTable[string, CollectiblesData]()
|
||||
|
||||
let chainData = self.ownershipData[chainId]
|
||||
if not chainData.hasKey(address):
|
||||
chainData[address] = newCollectionsData()
|
||||
if reset or not chainData.hasKey(address):
|
||||
chainData[address] = newCollectiblesData()
|
||||
|
||||
proc updateOwnedCollectionsCache*(self: Service, chainId: int, address: string, collections: seq[CollectionDto]) =
|
||||
let addressData = self.ownershipData[chainId][address]
|
||||
addressData.lastLoadWasFromStart = reset
|
||||
if reset:
|
||||
addressData.lastLoadFromStartTimestamp = now()
|
||||
|
||||
|
||||
proc updateOwnedCollectibles(self: Service, chainId: int, address: string, previousCursor: string, nextCursor: string, collectibles: seq[CollectibleDto]) =
|
||||
try:
|
||||
let oldAddressData = self.ownershipData[chainId][address]
|
||||
|
||||
# Start with empty object. Only add newly received collections, so removed ones are discarded
|
||||
let newAddressData = newCollectionsData()
|
||||
for collection in collections:
|
||||
newAddressData.collections[collection.slug] = newCollectionData(collection)
|
||||
if oldAddressData.collections.hasKey(collection.slug):
|
||||
let oldCollection = oldAddressData.collections[collection.slug]
|
||||
let newCollection = newAddressData.collections[collection.slug]
|
||||
# Take collectibles from old collection
|
||||
newCollection.collectiblesLoaded = oldCollection.collectiblesLoaded
|
||||
newCollection.collectibles = oldCollection.collectibles
|
||||
|
||||
newAddressData.collectionsLoaded = true
|
||||
self.ownershipData[chainId][address] = newAddressData
|
||||
|
||||
var data = OwnedCollectionsUpdateArgs()
|
||||
data.chainId = chainId
|
||||
data.address = address
|
||||
|
||||
self.events.emit(SIGNAL_OWNED_COLLECTIONS_UPDATED, data)
|
||||
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
|
||||
proc updateOwnedCollectiblesCache*(self: Service, chainId: int, address: string, collectionSlug: string, collectibles: seq[CollectibleDto]) =
|
||||
try:
|
||||
let collection = self.ownershipData[chainId][address].collections[collectionSlug]
|
||||
collection.collectibles.clear()
|
||||
let collectiblesData = self.ownershipData[chainId][address]
|
||||
collectiblesData.previousCursor = previousCursor
|
||||
collectiblesData.nextCursor = nextCursor
|
||||
collectiblesData.allLoaded = (nextCursor == "")
|
||||
|
||||
var count = 0
|
||||
for collectible in collectibles:
|
||||
collection.collectibles[collectible.id] = collectible
|
||||
collection.collectiblesLoaded = true
|
||||
|
||||
var data = OwnedCollectiblesUpdateArgs()
|
||||
data.chainId = chainId
|
||||
data.address = address
|
||||
data.collectionSlug = collectionSlug
|
||||
self.events.emit(SIGNAL_OWNED_COLLECTIBLES_UPDATED, data)
|
||||
let newId = UniqueID(
|
||||
contractAddress: collectible.address,
|
||||
tokenId: collectible.tokenId
|
||||
)
|
||||
if not collectiblesData.ids.any(id => newId == id):
|
||||
collectiblesData.ids.add(newId)
|
||||
count = count + 1
|
||||
collectiblesData.lastLoadCount = count
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
|
||||
proc updateCollectiblesCache*(self: Service, chainId: int, collectibles: seq[CollectibleDto]) =
|
||||
if not self.data.hasKey(chainId):
|
||||
self.data[chainId] = newTable[UniqueID, CollectibleDto]()
|
||||
proc updateCollectiblesCache*(self: Service, chainId: int, collectibles: seq[CollectibleDto], collections: seq[CollectionDto]) =
|
||||
if not self.collectibles.hasKey(chainId):
|
||||
self.collectibles[chainId] = newTable[UniqueID, CollectibleDto]()
|
||||
|
||||
if not self.collections.hasKey(chainId):
|
||||
self.collections[chainId] = newTable[string, CollectionDto]()
|
||||
|
||||
var data = CollectiblesUpdateArgs()
|
||||
data.chainId = chainId
|
||||
|
||||
for collection in collections:
|
||||
let slug = collection.slug
|
||||
self.collections[chainId][slug] = collection
|
||||
|
||||
|
||||
for collectible in collectibles:
|
||||
let id = UniqueID(
|
||||
contractAddress: collectible.address,
|
||||
tokenId: collectible.tokenId
|
||||
)
|
||||
self.data[chainId][id] = collectible
|
||||
self.collectibles[chainId][id] = collectible
|
||||
data.ids.add(id)
|
||||
|
||||
self.events.emit(SIGNAL_COLLECTIBLES_UPDATED, data)
|
||||
|
||||
proc getOwnedCollections*(self: Service, chainId: int, address: string) : CollectionsData =
|
||||
proc getOwnedCollectibles*(self: Service, chainId: int, address: string) : CollectiblesData =
|
||||
try:
|
||||
return self.ownershipData[chainId][address]
|
||||
except:
|
||||
discard
|
||||
return newCollectionsData()
|
||||
|
||||
proc getOwnedCollection*(self: Service, chainId: int, address: string, collectionSlug: string) : CollectionData =
|
||||
try:
|
||||
return self.ownershipData[chainId][address].collections[collectionSlug]
|
||||
except:
|
||||
discard
|
||||
return newCollectionData(CollectionDto())
|
||||
return newCollectiblesData()
|
||||
|
||||
proc getCollectible*(self: Service, chainId: int, id: UniqueID) : CollectibleDto =
|
||||
try:
|
||||
return self.data[chainId][id]
|
||||
return self.collectibles[chainId][id]
|
||||
except:
|
||||
discard
|
||||
return newCollectibleDto()
|
||||
|
||||
proc onRxCollectibles*(self: Service, response: string) {.slot.} =
|
||||
proc getCollection*(self: Service, chainId: int, slug: string) : CollectionDto =
|
||||
try:
|
||||
return self.collections[chainId][slug]
|
||||
except:
|
||||
discard
|
||||
return newCollectionDto()
|
||||
|
||||
proc processCollectiblesResult(responseObj: JsonNode) : CollectiblesResult =
|
||||
result.success = false
|
||||
let collectiblesContainerJson = responseObj["collectibles"]
|
||||
if collectiblesContainerJson.kind == JObject:
|
||||
let previousCursorJson = collectiblesContainerJson["previous"]
|
||||
let nextCursorJson = collectiblesContainerJson["next"]
|
||||
let collectiblesJson = collectiblesContainerJson["assets"]
|
||||
|
||||
if previousCursorJson.kind == JString and nextCursorJson.kind == JString:
|
||||
result.previousCursor = previousCursorJson.getStr()
|
||||
result.nextCursor = nextCursorJson.getStr()
|
||||
for collectibleJson in collectiblesJson.getElems():
|
||||
if collectibleJson.kind == JObject:
|
||||
result.collectibles.add(collectibleJson.toCollectibleDto())
|
||||
let collectionJson = collectibleJson["collection"]
|
||||
if collectionJson.kind == JObject:
|
||||
result.collections.add(collectionJson.toCollectionDto())
|
||||
else:
|
||||
return
|
||||
else:
|
||||
return
|
||||
result.success = true
|
||||
|
||||
proc onRxCollectibles(self: Service, response: string) {.slot.} =
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind == JObject):
|
||||
let chainIdJson = responseObj["chainId"]
|
||||
let collectiblesJson = responseObj["collectibles"]
|
||||
|
||||
if (chainIdJson.kind == JInt and
|
||||
collectiblesJson.kind == JArray):
|
||||
if chainIdJson.kind == JInt:
|
||||
let chainId = chainIdJson.getInt()
|
||||
let collectibles = map(collectiblesJson.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
||||
self.updateCollectiblesCache(chainId, collectibles)
|
||||
let (success, collectibles, collections, _, _) = processCollectiblesResult(responseObj)
|
||||
if success:
|
||||
self.updateCollectiblesCache(chainId, collectibles, collections)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error onRxCollectibles: ", errDescription
|
||||
|
@ -223,95 +235,63 @@ QtObject:
|
|||
contractAddress: id.contractAddress,
|
||||
tokenID: id.tokenId.toString()
|
||||
)),
|
||||
limit: limit
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc onRxOwnedCollections*(self: Service, response: string) {.slot.} =
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind == JObject):
|
||||
let chainIdJson = responseObj["chainId"]
|
||||
let addressJson = responseObj["address"]
|
||||
|
||||
let validAccount = (chainIdJson.kind == JInt and
|
||||
addressJson.kind == JString)
|
||||
if (validAccount):
|
||||
let chainId = chainIdJson.getInt()
|
||||
let address = addressJson.getStr()
|
||||
|
||||
var collections: seq[CollectionDto]
|
||||
let collectionsJson = responseObj["collections"]
|
||||
if (collectionsJson.kind == JArray):
|
||||
collections = map(collectionsJson.getElems(), proc(x: JsonNode): CollectionDto = x.toCollectionDto())
|
||||
|
||||
self.updateOwnedCollectionsCache(chainId, address, collections)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error onRxOwnedCollections: ", errDescription
|
||||
|
||||
proc fetchOwnedCollections*(self: Service, chainId: int, address: string) =
|
||||
self.insertAddressIfNeeded(chainId, address)
|
||||
|
||||
let arg = FetchOwnedCollectionsTaskArg(
|
||||
tptr: cast[ByteAddress](fetchOwnedCollectionsTaskArg),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onRxOwnedCollections",
|
||||
chainId: chainId,
|
||||
address: address,
|
||||
limit: len(ids)
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc onRxOwnedCollectibles*(self: Service, response: string) {.slot.} =
|
||||
proc onRxOwnedCollectibles(self: Service, response: string) {.slot.} =
|
||||
var data = OwnedCollectiblesUpdateArgs()
|
||||
try:
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind == JObject):
|
||||
let chainIdJson = responseObj["chainId"]
|
||||
let addressJson = responseObj["address"]
|
||||
let collectionSlugJson = responseObj["collectionSlug"]
|
||||
|
||||
let validCollection = (chainIdJson.kind == JInt and
|
||||
addressJson.kind == JString and
|
||||
collectionSlugJson.kind == JString)
|
||||
if (validCollection):
|
||||
let chainId = chainIdJson.getInt()
|
||||
let address = addressJson.getStr()
|
||||
let collectionSlug = collectionSlugJson.getStr()
|
||||
|
||||
var collectibles: seq[CollectibleDto]
|
||||
let collectiblesJson = responseObj["collectibles"]
|
||||
if (collectiblesJson.kind == JArray):
|
||||
collectibles = map(collectiblesJson.getElems(), proc(x: JsonNode): CollectibleDto = x.toCollectibleDto())
|
||||
self.updateOwnedCollectiblesCache(chainId, address, collectionSlug, collectibles)
|
||||
self.updateCollectiblesCache(data.chainId, collectibles)
|
||||
if (chainIdJson.kind == JInt and
|
||||
addressJson.kind == JString):
|
||||
data.chainId = chainIdJson.getInt()
|
||||
data.address = addressJson.getStr()
|
||||
self.ownershipData[data.chainId][data.address].isFetching = false
|
||||
let (success, collectibles, collections, prevCursor, nextCursor) = processCollectiblesResult(responseObj)
|
||||
if success:
|
||||
self.updateCollectiblesCache(data.chainId, collectibles, collections)
|
||||
self.updateOwnedCollectibles(data.chainId, data.address, prevCursor, nextCursor, collectibles)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error onRxOwnedCollectibles: ", errDescription
|
||||
self.events.emit(SIGNAL_OWNED_COLLECTIBLES_UPDATE_FINISHED, data)
|
||||
|
||||
proc fetchOwnedCollectibles*(self: Service, chainId: int, address: string, collectionSlug: string) =
|
||||
self.insertAddressIfNeeded(chainId, address)
|
||||
let collections = self.ownershipData[chainId][address].collections
|
||||
proc resetOwnedCollectibles*(self: Service, chainId: int, address: string) =
|
||||
self.prepareOwnershipData(chainId, address, true)
|
||||
var data = OwnedCollectiblesUpdateArgs()
|
||||
data.chainId = chainId
|
||||
data.address = address
|
||||
self.events.emit(SIGNAL_OWNED_COLLECTIBLES_UPDATE_FINISHED, data)
|
||||
|
||||
if not collections.hasKey(collectionSlug):
|
||||
error "error fetchOwnedCollectibles: Attempting to fetch collectibles from unknown collection: ", collectionSlug
|
||||
proc fetchOwnedCollectibles*(self: Service, chainId: int, address: string, limit: int) =
|
||||
self.prepareOwnershipData(chainId, address, false)
|
||||
|
||||
let collectiblesData = self.ownershipData[chainId][address]
|
||||
|
||||
if collectiblesData.isFetching:
|
||||
return
|
||||
|
||||
if collectiblesData.allLoaded:
|
||||
return
|
||||
|
||||
collectiblesData.isFetching = true
|
||||
|
||||
var data = OwnedCollectiblesUpdateArgs()
|
||||
data.chainId = chainId
|
||||
data.address = address
|
||||
self.events.emit(SIGNAL_OWNED_COLLECTIBLES_UPDATE_STARTED, data)
|
||||
|
||||
let arg = FetchOwnedCollectiblesTaskArg(
|
||||
tptr: cast[ByteAddress](fetchOwnedCollectiblesTaskArg),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onRxOwnedCollectibles",
|
||||
chainId: chainId,
|
||||
address: address,
|
||||
collectionSlug: collectionSlug,
|
||||
cursor: collectiblesData.nextCursor,
|
||||
limit: limit
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc fetchAllOwnedCollectibles*(self: Service, chainId: int, address: string) =
|
||||
try:
|
||||
for collectionSlug, _ in self.ownershipData[chainId][address].collections:
|
||||
self.fetchOwnedCollectibles(chainId, address, collectionSlug)
|
||||
except Exception as e:
|
||||
let errDescription = e.msg
|
||||
error "error fetchAllOwnedCollectibles: ", errDescription
|
||||
|
|
|
@ -217,8 +217,12 @@ QtObject:
|
|||
for tx in historyData["history"].getElems():
|
||||
transactions.add(tx.toTransactionDto())
|
||||
|
||||
for c in historyData["collectibles"].getElems():
|
||||
collectibles.add(c.toCollectibleDto())
|
||||
let collectiblesContainerJson = historyData["collectibles"]
|
||||
if collectiblesContainerJson.kind == JObject:
|
||||
let collectiblesJson = collectiblesContainerJson["assets"]
|
||||
if collectiblesJson.kind == JArray:
|
||||
for c in collectiblesJson.getElems():
|
||||
collectibles.add(c.toCollectibleDto())
|
||||
|
||||
if self.allTxLoaded.hasKey(address):
|
||||
self.allTxLoaded[address] = self.allTxLoaded[address] and allTxLoaded
|
||||
|
|
|
@ -18,14 +18,10 @@ proc `==`*(a, b: NFTUniqueID): bool =
|
|||
result = a.contractAddress == b.contractAddress and
|
||||
a.tokenID == b.tokenID
|
||||
|
||||
rpc(getOpenseaCollectionsByOwner, "wallet"):
|
||||
rpc(getOpenseaAssetsByOwnerWithCursor, "wallet"):
|
||||
chainId: int
|
||||
address: string
|
||||
|
||||
rpc(getOpenseaAssetsByOwnerAndCollection, "wallet"):
|
||||
chainId: int
|
||||
address: string
|
||||
collectionSlug: string
|
||||
cursor: string
|
||||
limit: int
|
||||
|
||||
rpc(getOpenseaAssetsByNFTUniqueID, "wallet"):
|
||||
|
|
|
@ -33,6 +33,7 @@ ColumnLayout {
|
|||
font.pixelSize: isNarrowMode ? 15 : 22
|
||||
lineHeight: isNarrowMode ? 22 : 30
|
||||
lineHeightMode: Text.FixedHeight
|
||||
elide: Text.ElideRight
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +58,7 @@ ColumnLayout {
|
|||
id: collectibleIdTopRow
|
||||
sourceComponent: collectibleIdComponent
|
||||
visible: !root.isNarrowMode
|
||||
Layout.fillWidth: true
|
||||
|
||||
Binding {
|
||||
target: collectibleIdTopRow.item
|
||||
|
@ -74,6 +76,7 @@ ColumnLayout {
|
|||
id: collectibleIdBottomRow
|
||||
sourceComponent: collectibleIdComponent
|
||||
visible: root.isNarrowMode
|
||||
Layout.maximumWidth: root.width - parent.spacing - networkTag.width
|
||||
|
||||
Binding {
|
||||
target: collectibleIdBottomRow.item
|
||||
|
|
|
@ -28,8 +28,7 @@ QtObject {
|
|||
property string signingPhrase: walletSection.signingPhrase
|
||||
property string mnemonicBackedUp: walletSection.isMnemonicBackedUp
|
||||
|
||||
property var collections: walletSectionCollectibles.model
|
||||
property var flatCollectibles: walletSectionCollectibles.flatModel
|
||||
property var flatCollectibles: walletSectionCollectibles.model
|
||||
property var currentCollectible: walletSectionCurrentCollectible
|
||||
|
||||
property var savedAddresses: SortFilterProxyModel {
|
||||
|
@ -185,10 +184,6 @@ QtObject {
|
|||
return globalUtils.hex2Dec(value)
|
||||
}
|
||||
|
||||
function fetchOwnedCollectibles(slug) {
|
||||
walletSectionCollectibles.fetchOwnedCollectibles(slug)
|
||||
}
|
||||
|
||||
function getCollectionMaxValue(traitType, value, maxValue, collectionIndex) {
|
||||
// Not Refactored Yet
|
||||
// if(maxValue !== "")
|
||||
|
@ -198,8 +193,8 @@ QtObject {
|
|||
// walletModelV2Inst.collectiblesView.collections.getCollectionTraitMaxValue(collectionIndex, traitType).toString();
|
||||
}
|
||||
|
||||
function selectCollectible(slug, id) {
|
||||
walletSectionCurrentCollectible.update(slug, id)
|
||||
function selectCollectible(address, tokenId) {
|
||||
walletSectionCurrentCollectible.update(address, tokenId)
|
||||
}
|
||||
|
||||
function getNameForSavedWalletAddress(address) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import QtQuick.Controls 2.13
|
|||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.panels 1.0
|
||||
import utils 1.0
|
||||
|
@ -15,9 +16,7 @@ Item {
|
|||
property var collectiblesModel
|
||||
width: parent.width
|
||||
|
||||
signal collectibleClicked(string collectionSlug, int collectibleId)
|
||||
|
||||
readonly property bool areCollectionsLoaded: root.collectiblesModel.collectionsLoaded
|
||||
signal collectibleClicked(string address, string tokenId)
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
|
@ -25,7 +24,7 @@ Item {
|
|||
height: parent.height
|
||||
|
||||
sourceComponent: {
|
||||
if (root.areCollectionsLoaded && root.collectiblesModel.collectionCount === 0)
|
||||
if (root.collectiblesModel.allCollectiblesLoaded && root.collectiblesModel.count === 0)
|
||||
return empty;
|
||||
return loaded;
|
||||
}
|
||||
|
@ -49,18 +48,19 @@ Item {
|
|||
StatusGridView {
|
||||
id: gridView
|
||||
anchors.fill: parent
|
||||
model: root.areCollectionsLoaded ? root.collectiblesModel : Constants.dummyModelItems
|
||||
model: root.collectiblesModel
|
||||
cellHeight: 229
|
||||
cellWidth: 176
|
||||
delegate: CollectibleView {
|
||||
height: gridView.cellHeight
|
||||
width: gridView.cellWidth
|
||||
collectibleModel: root.areCollectionsLoaded ? model : undefined
|
||||
isLoadingDelegate: !root.areCollectionsLoaded
|
||||
collectibleModel: model
|
||||
onCollectibleClicked: {
|
||||
root.collectibleClicked(slug, collectibleId);
|
||||
root.collectibleClicked(address, tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: StatusScrollBar {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ Item {
|
|||
CollectiblesView {
|
||||
collectiblesModel: RootStore.flatCollectibles
|
||||
onCollectibleClicked: {
|
||||
RootStore.selectCollectible(collectionSlug, collectibleId)
|
||||
RootStore.selectCollectible(address, tokenId)
|
||||
stack.currentIndex = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import StatusQ.Components 0.1
|
|||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
import utils 1.0
|
||||
import shared.controls 1.0
|
||||
|
@ -26,7 +27,7 @@ Item {
|
|||
asset.name: currentCollectible.collectionImageUrl
|
||||
asset.isImage: true
|
||||
primaryText: currentCollectible.collectionName
|
||||
secondaryText: currentCollectible.id
|
||||
secondaryText: "#" + currentCollectible.tokenId
|
||||
isNarrowMode: root.isNarrowMode
|
||||
networkShortName: currentCollectible.networkShortName
|
||||
networkColor: currentCollectible.networkColor
|
||||
|
|
|
@ -15,14 +15,12 @@ Item {
|
|||
id: root
|
||||
|
||||
property var collectibleModel
|
||||
property bool isLoadingDelegate
|
||||
|
||||
signal collectibleClicked(string slug, int collectibleId)
|
||||
signal collectibleClicked(string address, string tokenId)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property bool modeDataValid: !!root.collectibleModel && root.collectibleModel !== undefined
|
||||
readonly property bool isLoaded: modeDataValid ? root.collectibleModel.collectionCollectiblesLoaded : false
|
||||
readonly property bool modeDataValid: !!root.collectibleModel && root.collectibleModel !== undefined && root.collectibleModel.id >= 0
|
||||
}
|
||||
|
||||
implicitHeight: 225
|
||||
|
@ -48,7 +46,7 @@ Item {
|
|||
color: d.modeDataValid ? root.collectibleModel.backgroundColor : "transparent"
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: root.isLoadingDelegate
|
||||
active: root.collectibleModel.isLoading
|
||||
sourceComponent: LoadingComponent {radius: image.radius}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +55,7 @@ Item {
|
|||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.leftMargin: 8
|
||||
Layout.topMargin: 9
|
||||
Layout.preferredWidth: isLoadingDelegate ? 134 : 144
|
||||
Layout.preferredWidth: root.collectibleModel.isLoading ? 134 : 144
|
||||
Layout.preferredHeight: 21
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
@ -65,22 +63,22 @@ Item {
|
|||
customColor: Theme.palette.directColor1
|
||||
font.weight: Font.DemiBold
|
||||
elide: Text.ElideRight
|
||||
text: isLoadingDelegate ? Constants.dummyText : d.isLoaded && d.modeDataValid ? root.collectibleModel.name : "..."
|
||||
loading: root.isLoadingDelegate
|
||||
text: root.collectibleModel.isLoading ? Constants.dummyText : d.modeDataValid ? root.collectibleModel.name : "..."
|
||||
loading: root.collectibleModel.isLoading
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: collectionLabel
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.leftMargin: 8
|
||||
Layout.preferredWidth: isLoadingDelegate ? 88 : 144
|
||||
Layout.preferredWidth: root.collectibleModel.isLoading ? 88 : 144
|
||||
Layout.preferredHeight: 18
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 13
|
||||
customColor: Theme.palette.baseColor1
|
||||
elide: Text.ElideRight
|
||||
text: isLoadingDelegate ? Constants.dummyText : d.modeDataValid ? root.collectibleModel.collectionName : ""
|
||||
loading: root.isLoadingDelegate
|
||||
text: root.collectibleModel.isLoading ? Constants.dummyText : d.modeDataValid ? root.collectibleModel.collectionName : "..."
|
||||
loading: root.collectibleModel.isLoading
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,15 +88,15 @@ Item {
|
|||
border.width: 1
|
||||
border.color: Theme.palette.primaryColor1
|
||||
color: Theme.palette.indirectColor3
|
||||
visible: d.isLoaded && mouse.containsMouse
|
||||
visible: !root.collectibleModel.isLoading && mouse.containsMouse
|
||||
}
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
if (d.isLoaded) {
|
||||
root.collectibleClicked(root.collectibleModel.collectionSlug, root.collectibleModel.id);
|
||||
if (d.modeDataValid && !root.collectibleModel.isLoading) {
|
||||
root.collectibleClicked(root.collectibleModel.address, root.collectibleModel.tokenId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f60716412259aece88d899d09fc71de4c4ba5d2e
|
||||
Subproject commit 5ecb7b68eefada3725c360f68fba7ac92b612c82
|
Loading…
Reference in New Issue