feat(@desktop/wallet): implement nested collectibles model
Part of #12072
This commit is contained in:
parent
61f3d903ce
commit
bad497cc90
|
@ -42,7 +42,11 @@ proc newModule*(
|
|||
result.view = newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = accountsc.newController(result, walletAccountService)
|
||||
result.collectiblesController = collectiblesc.newController(int32(backend_collectibles.CollectiblesRequestID.ProfileShowcase), events)
|
||||
result.collectiblesController = collectiblesc.newController(
|
||||
requestId = int32(backend_collectibles.CollectiblesRequestID.ProfileShowcase),
|
||||
autofetch = false,
|
||||
events = events
|
||||
)
|
||||
result.moduleLoaded = false
|
||||
|
||||
## Forward declarations
|
||||
|
@ -58,7 +62,7 @@ method getModuleAsVariant*(self: Module): QVariant =
|
|||
return self.viewVariant
|
||||
|
||||
method getCollectiblesModel*(self: Module): QVariant =
|
||||
return self.collectiblesController.getModel()
|
||||
return self.collectiblesController.getModelAsVariant()
|
||||
|
||||
method convertWalletAccountDtoToKeyPairAccountItem(self: Module, account: WalletAccountDto): KeyPairAccountItem =
|
||||
result = newKeyPairAccountItem(
|
||||
|
|
|
@ -122,7 +122,11 @@ proc newModule*(
|
|||
result.transactionService = transactionService
|
||||
result.activityController = activityc.newController(int32(ActivityID.History), currencyService, tokenService, events)
|
||||
result.tmpActivityController = activityc.newController(int32(ActivityID.Temporary), currencyService, tokenService, events)
|
||||
result.collectiblesController = collectiblesc.newController(int32(backend_collectibles.CollectiblesRequestID.WalletAccount), events)
|
||||
result.collectiblesController = collectiblesc.newController(
|
||||
requestId = int32(backend_collectibles.CollectiblesRequestID.WalletAccount),
|
||||
autofetch = false,
|
||||
events = events
|
||||
)
|
||||
result.collectibleDetailsController = collectible_detailsc.newController(int32(backend_collectibles.CollectiblesRequestID.WalletAccount), networkService, events)
|
||||
result.filter = initFilter(result.controller)
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import stint
|
||||
import ../../../shared_models/currency_amount
|
||||
import app_service/service/transaction/dto
|
||||
import app/modules/shared_models/collectibles_model as collectibles
|
||||
import app/modules/shared_models/collectibles_nested_model as nested_collectibles
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -57,3 +59,9 @@ method setSelectedReceiveAccountIndex*(self: AccessInterface, index: int) =
|
|||
|
||||
method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: seq[int]) =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCollectiblesModel*(self: AccessInterface): collectibles.Model =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getNestedCollectiblesModel*(self: AccessInterface): nested_collectibles.Model =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -13,6 +13,11 @@ import app/modules/shared/wallet_utils
|
|||
import app_service/service/transaction/dto
|
||||
import app/modules/shared_models/currency_amount
|
||||
|
||||
import app/modules/shared_modules/collectibles/controller as collectiblesc
|
||||
import app/modules/shared_models/collectibles_model as collectibles
|
||||
import app/modules/shared_models/collectibles_nested_model as nested_collectibles
|
||||
import backend/collectibles as backend_collectibles
|
||||
|
||||
export io_interface
|
||||
|
||||
const cancelledRequest* = "cancelled"
|
||||
|
@ -31,7 +36,10 @@ type
|
|||
delegate: delegate_interface.AccessInterface
|
||||
events: EventEmitter
|
||||
view: View
|
||||
controller: Controller
|
||||
controller: controller.Controller
|
||||
# Get the list of owned collectibles by the currently selected account
|
||||
collectiblesController: collectiblesc.Controller
|
||||
nestedCollectiblesModel: nested_collectibles.Model
|
||||
moduleLoaded: bool
|
||||
tmpSendTransactionDetails: TmpSendTransactionDetails
|
||||
senderCurrentAccountIndex: int
|
||||
|
@ -52,8 +60,15 @@ proc newModule*(
|
|||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.view = newView(result)
|
||||
result.controller = controller.newController(result, events, walletAccountService, networkService, currencyService, transactionService)
|
||||
result.collectiblesController = collectiblesc.newController(
|
||||
requestId = int32(backend_collectibles.CollectiblesRequestID.WalletSend),
|
||||
autofetch = true,
|
||||
events = events
|
||||
)
|
||||
result.nestedCollectiblesModel = nested_collectibles.newModel(result.collectiblesController.getModel())
|
||||
result.view = newView(result)
|
||||
|
||||
result.moduleLoaded = false
|
||||
result.senderCurrentAccountIndex = 0
|
||||
result.receiveCurrentAccountIndex = 0
|
||||
|
@ -61,6 +76,8 @@ proc newModule*(
|
|||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.controller.delete
|
||||
self.nestedCollectiblesModel.delete
|
||||
self.collectiblesController.delete
|
||||
|
||||
method convertSendToNetworkToNetworkItem(self: Module, network: SendToNetwork): NetworkItem =
|
||||
result = initNetworkItem(
|
||||
|
@ -297,8 +314,21 @@ method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int])
|
|||
self.view.switchSenderAccountByAddress(addresses[0])
|
||||
self.view.switchReceiveAccountByAddress(addresses[0])
|
||||
|
||||
proc updateCollectiblesFilter*(self: Module) =
|
||||
let addresses = @[self.view.getSenderAddressByIndex(self.senderCurrentAccountIndex)]
|
||||
let chainIds = self.controller.getChainIds()
|
||||
self.collectiblesController.globalFilterChanged(addresses, chainIds)
|
||||
|
||||
method setSelectedSenderAccountIndex*(self: Module, index: int) =
|
||||
self.senderCurrentAccountIndex = index
|
||||
self.updateCollectiblesFilter()
|
||||
|
||||
method setSelectedReceiveAccountIndex*(self: Module, index: int) =
|
||||
self.receiveCurrentAccountIndex = index
|
||||
|
||||
method getCollectiblesModel*(self: Module): collectibles.Model =
|
||||
return self.collectiblesController.getModel()
|
||||
|
||||
method getNestedCollectiblesModel*(self: Module): nested_collectibles.Model =
|
||||
return self.nestedCollectiblesModel
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ import NimQml, sequtils, strutils, stint, sugar
|
|||
|
||||
import ./io_interface, ./accounts_model, ./account_item, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes
|
||||
import app/modules/shared_models/token_model
|
||||
import app/modules/shared_models/collectibles_model as collectibles
|
||||
import app/modules/shared_models/collectibles_nested_model as nested_collectibles
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -10,6 +12,9 @@ QtObject:
|
|||
accounts: AccountsModel
|
||||
# this one doesn't include watch accounts and its what the user switches when using the sendModal
|
||||
senderAccounts: AccountsModel
|
||||
# list of collectibles owned by the selected sender account
|
||||
collectiblesModel: collectibles.Model
|
||||
nestedCollectiblesModel: nested_collectibles.Model
|
||||
# for send modal
|
||||
selectedSenderAccount: AccountItem
|
||||
fromNetworksModel: NetworkModel
|
||||
|
@ -43,6 +48,8 @@ QtObject:
|
|||
result.fromNetworksModel = newNetworkModel()
|
||||
result.toNetworksModel = newNetworkModel()
|
||||
result.transactionRoutes = newTransactionRoutes()
|
||||
result.collectiblesModel = delegate.getCollectiblesModel()
|
||||
result.nestedCollectiblesModel = delegate.getNestedCollectiblesModel()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
||||
|
@ -61,6 +68,20 @@ QtObject:
|
|||
read = getSenderAccounts
|
||||
notify = senderAccountsChanged
|
||||
|
||||
proc collectiblesModelChanged*(self: View) {.signal.}
|
||||
proc getCollectiblesModel(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.collectiblesModel)
|
||||
QtProperty[QVariant] collectiblesModel:
|
||||
read = getCollectiblesModel
|
||||
notify = collectiblesModelChanged
|
||||
|
||||
proc nestedCollectiblesModelChanged*(self: View) {.signal.}
|
||||
proc getNestedCollectiblesModel(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.nestedCollectiblesModel)
|
||||
QtProperty[QVariant] nestedCollectiblesModel:
|
||||
read = getNestedCollectiblesModel
|
||||
notify = nestedCollectiblesModelChanged
|
||||
|
||||
proc selectedSenderAccountChanged*(self: View) {.signal.}
|
||||
proc getSelectedSenderAccount(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.selectedSenderAccount)
|
||||
|
@ -72,6 +93,9 @@ QtObject:
|
|||
read = getSelectedSenderAccount
|
||||
notify = selectedSenderAccountChanged
|
||||
|
||||
proc getSenderAddressByIndex*(self: View, index: int): string {.slot.} =
|
||||
return self.senderAccounts.getItemByIndex(index).address()
|
||||
|
||||
proc selectedReceiveAccountChanged*(self: View) {.signal.}
|
||||
proc getSelectedReceiveAccount(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.selectedReceiveAccount)
|
||||
|
|
|
@ -11,6 +11,8 @@ type
|
|||
imageUrl: string
|
||||
backgroundColor: string
|
||||
collectionName: string
|
||||
collectionSlug: string
|
||||
collectionImageUrl: string
|
||||
isLoading: bool
|
||||
isPinned: bool
|
||||
|
||||
|
@ -24,6 +26,8 @@ proc initItem*(
|
|||
imageUrl: string,
|
||||
backgroundColor: string,
|
||||
collectionName: string,
|
||||
collectionSlug: string,
|
||||
collectionImageUrl: string,
|
||||
isPinned: bool
|
||||
): Item =
|
||||
result.chainId = chainId
|
||||
|
@ -35,11 +39,13 @@ proc initItem*(
|
|||
result.imageUrl = imageUrl
|
||||
result.backgroundColor = if (backgroundColor == ""): "transparent" else: ("#" & backgroundColor)
|
||||
result.collectionName = collectionName
|
||||
result.collectionSlug = collectionSlug
|
||||
result.collectionImageUrl = collectionImageUrl
|
||||
result.isLoading = false
|
||||
result.isPinned = isPinned
|
||||
|
||||
proc initItem*: Item =
|
||||
result = initItem(0, "", u256(0), "", "", "", "", "transparent", "Collectibles", false)
|
||||
result = initItem(0, "", u256(0), "", "", "", "", "transparent", "Collectibles", "", "", false)
|
||||
|
||||
proc initLoadingItem*: Item =
|
||||
result = initItem()
|
||||
|
@ -56,6 +62,8 @@ proc `$`*(self: Item): string =
|
|||
imageUrl: {self.imageUrl},
|
||||
backgroundColor: {self.backgroundColor},
|
||||
collectionName: {self.collectionName},
|
||||
collectionSlug: {self.collectionSlug},
|
||||
collectionImageUrl: {self.collectionImageUrl},
|
||||
isLoading: {self.isLoading},
|
||||
isPinned: {self.isPinned},
|
||||
]"""
|
||||
|
@ -88,9 +96,19 @@ proc getImageUrl*(self: Item): string =
|
|||
proc getBackgroundColor*(self: Item): string =
|
||||
return self.backgroundColor
|
||||
|
||||
# Unique ID to identify collection, generated by us
|
||||
proc getCollectionId*(self: Item): string =
|
||||
return fmt"{self.getChainId}+{self.getContractAddress}"
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ type
|
|||
MediaUrl
|
||||
MediaType
|
||||
BackgroundColor
|
||||
CollectionUid
|
||||
CollectionName
|
||||
CollectionSlug
|
||||
IsLoading
|
||||
IsPinned
|
||||
|
||||
|
@ -145,7 +147,9 @@ QtObject:
|
|||
CollectibleRole.MediaType.int:"mediaType",
|
||||
CollectibleRole.ImageUrl.int:"imageUrl",
|
||||
CollectibleRole.BackgroundColor.int:"backgroundColor",
|
||||
CollectibleRole.CollectionUid.int:"collectionUid",
|
||||
CollectibleRole.CollectionName.int:"collectionName",
|
||||
CollectibleRole.CollectionSlug.int:"collectionSlug",
|
||||
CollectibleRole.IsLoading.int:"isLoading",
|
||||
CollectibleRole.IsPinned.int:"isPinned",
|
||||
}.toTable
|
||||
|
@ -180,8 +184,12 @@ QtObject:
|
|||
result = newQVariant(item.getImageUrl())
|
||||
of CollectibleRole.BackgroundColor:
|
||||
result = newQVariant(item.getBackgroundColor())
|
||||
of CollectibleRole.CollectionUid:
|
||||
result = newQVariant(item.getCollectionId())
|
||||
of CollectibleRole.CollectionName:
|
||||
result = newQVariant(item.getCollectionName())
|
||||
of CollectibleRole.CollectionSlug:
|
||||
result = newQVariant(item.getCollectionSlug())
|
||||
of CollectibleRole.IsLoading:
|
||||
result = newQVariant(false)
|
||||
of CollectibleRole.IsPinned:
|
||||
|
@ -195,6 +203,26 @@ QtObject:
|
|||
error "Invalid role for loading item"
|
||||
result = newQVariant()
|
||||
|
||||
proc rowData(self: Model, index: int, column: string): string {.slot.} =
|
||||
if (index >= self.items.len):
|
||||
return
|
||||
let item = self.items[index]
|
||||
case column:
|
||||
of "uid": result = item.getId()
|
||||
of "chainId": result = $item.getChainId()
|
||||
of "contractAddress": result = item.getContractAddress()
|
||||
of "tokenId": result = item.getTokenId().toString()
|
||||
of "name": result = item.getName()
|
||||
of "mediaUrl": result = item.getMediaUrl()
|
||||
of "mediaType": result = item.getMediaType()
|
||||
of "imageUrl": result = item.getImageUrl()
|
||||
of "backgroundColor": result = item.getBackgroundColor()
|
||||
of "collectionUid": result = item.getCollectionId()
|
||||
of "collectionName": result = item.getCollectionName()
|
||||
of "collectionSlug": result = item.getCollectionSlug()
|
||||
of "isLoading": result = $false
|
||||
of "isPinned": result = $item.getIsPinned()
|
||||
|
||||
proc appendCollectibleItems(self: Model, newItems: seq[Item]) =
|
||||
if len(newItems) == 0:
|
||||
return
|
||||
|
@ -271,6 +299,9 @@ QtObject:
|
|||
else:
|
||||
self.removeLoadingItems()
|
||||
|
||||
proc getItems*(self: Model): seq[Item] =
|
||||
return self.items
|
||||
|
||||
proc setItems*(self: Model, newItems: seq[Item], offset: int, hasMore: bool) =
|
||||
if offset == 0:
|
||||
self.removeCollectibleItems()
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import strformat, stint
|
||||
|
||||
type
|
||||
Item* = object
|
||||
id: string # Collectible ID if isCollection=false, Collection Slug otherwise
|
||||
chainId: int
|
||||
name: string
|
||||
iconUrl: string
|
||||
collectionId: string
|
||||
collectionName: string
|
||||
isCollection: bool
|
||||
|
||||
proc initItem*(
|
||||
id: string,
|
||||
chainId: int,
|
||||
name: string,
|
||||
iconUrl: string,
|
||||
collectionId: string,
|
||||
collectionName: string,
|
||||
isCollection: bool
|
||||
): Item =
|
||||
result.id = id
|
||||
result.chainId = chainId
|
||||
result.name = name
|
||||
result.iconUrl = iconUrl
|
||||
result.collectionId = collectionId
|
||||
result.collectionName = collectionName
|
||||
result.isCollection = isCollection
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""CollectiblesNestedEntry(
|
||||
id: {self.id},
|
||||
chainId: {self.chainId},
|
||||
name: {self.name},
|
||||
iconUrl: {self.iconUrl},
|
||||
collectionId: {self.collectionId},
|
||||
collectionName: {self.collectionName},
|
||||
isCollection: {self.isCollection},
|
||||
]"""
|
||||
|
||||
proc getId*(self: Item): string =
|
||||
return self.id
|
||||
|
||||
proc getChainId*(self: Item): int =
|
||||
return self.chainId
|
||||
|
||||
proc getName*(self: Item): string =
|
||||
return self.name
|
||||
|
||||
proc getIconUrl*(self: Item): string =
|
||||
return self.iconUrl
|
||||
|
||||
proc getCollectionId*(self: Item): string =
|
||||
return self.collectionId
|
||||
|
||||
proc getCollectionName*(self: Item): string =
|
||||
return self.collectionName
|
||||
|
||||
proc getIsCollection*(self: Item): bool =
|
||||
return self.isCollection
|
|
@ -0,0 +1,166 @@
|
|||
import NimQml, Tables, strutils, strformat, sequtils, logging
|
||||
|
||||
import ./collectibles_model as flat_model
|
||||
import ./collectibles_item as flat_item
|
||||
import ./collectibles_nested_item as nested_item
|
||||
|
||||
import ./collectibles_nested_utils
|
||||
|
||||
type
|
||||
CollectiblesNestedRole {.pure.} = enum
|
||||
Uid = UserRole + 1,
|
||||
ChainId
|
||||
Name
|
||||
IconUrl
|
||||
CollectionUid
|
||||
CollectionName
|
||||
IsCollection
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
flatModel: flat_model.Model
|
||||
items: seq[nested_item.Item]
|
||||
currentCollectionUid: string
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newModel*(flatModel: flat_model.Model): Model =
|
||||
new(result, delete)
|
||||
result.flatModel = flatModel
|
||||
result.items = @[]
|
||||
result.currentCollectionUid = ""
|
||||
result.setup
|
||||
|
||||
signalConnect(result.flatModel, "countChanged()", result, "refreshItems()")
|
||||
|
||||
# Forward declaration
|
||||
proc refreshItems*(self: Model)
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
result = fmt"""CollectiblesNestedModel(
|
||||
flatModel: {self.flatModel},
|
||||
currentCollectionUid: {self.currentCollectionUid},
|
||||
]"""
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
proc getCount*(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
proc getCurrentCollectionUid*(self: Model): string {.slot.} =
|
||||
result = self.currentCollectionUid
|
||||
proc currentCollectionUidChanged(self: Model) {.signal.}
|
||||
proc setCurrentCollectionUid(self: Model, currentCollectionUid: string) {.slot.} =
|
||||
self.currentCollectionUid = currentCollectionUid
|
||||
self.currentCollectionUidChanged()
|
||||
self.refreshItems()
|
||||
QtProperty[string] currentCollectionUid:
|
||||
read = getCurrentCollectionUid
|
||||
write = setCurrentCollectionUid
|
||||
notify = currentCollectionUidChanged
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
CollectiblesNestedRole.Uid.int:"uid",
|
||||
CollectiblesNestedRole.ChainId.int:"chainId",
|
||||
CollectiblesNestedRole.Name.int:"name",
|
||||
CollectiblesNestedRole.IconUrl.int:"iconUrl",
|
||||
CollectiblesNestedRole.CollectionUid.int:"collectionUid",
|
||||
CollectiblesNestedRole.CollectionName.int:"collectionName",
|
||||
CollectiblesNestedRole.IsCollection.int:"isCollection",
|
||||
}.toTable
|
||||
|
||||
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 item = self.items[index.row]
|
||||
let enumRole = role.CollectiblesNestedRole
|
||||
|
||||
case enumRole:
|
||||
of CollectiblesNestedRole.Uid:
|
||||
result = newQVariant(item.getId())
|
||||
of CollectiblesNestedRole.ChainId:
|
||||
result = newQVariant(item.getChainId())
|
||||
of CollectiblesNestedRole.Name:
|
||||
result = newQVariant(item.getName())
|
||||
of CollectiblesNestedRole.IconUrl:
|
||||
result = newQVariant(item.getIconUrl())
|
||||
of CollectiblesNestedRole.CollectionUid:
|
||||
result = newQVariant(item.getCollectionId())
|
||||
of CollectiblesNestedRole.CollectionName:
|
||||
result = newQVariant(item.getCollectionName())
|
||||
of CollectiblesNestedRole.IsCollection:
|
||||
result = newQVariant(item.getIsCollection())
|
||||
|
||||
proc rowData(self: Model, index: int, column: string): string {.slot.} =
|
||||
if (index >= self.items.len):
|
||||
return
|
||||
let item = self.items[index]
|
||||
case column:
|
||||
of "uid": result = item.getId()
|
||||
of "chainId": result = $item.getChainId()
|
||||
of "name": result = item.getName()
|
||||
of "iconUrl": result = item.getIconUrl()
|
||||
of "collectionUid": result = item.getCollectionId()
|
||||
of "collectionName": result = item.getCollectionName()
|
||||
of "isCollection": result = $item.getIsCollection()
|
||||
|
||||
proc getCollectiblesPerCollectionId(items: seq[flat_item.Item]): Table[string, seq[flat_item.Item]] =
|
||||
var collectiblesPerCollection = initTable[string, seq[flat_item.Item]]()
|
||||
|
||||
for item in items:
|
||||
let collectionId = item.getCollectionId()
|
||||
if not collectiblesPerCollection.hasKey(collectionId):
|
||||
collectiblesPerCollection[collectionId] = @[]
|
||||
collectiblesPerCollection[collectionId].add(item)
|
||||
|
||||
return collectiblesPerCollection
|
||||
|
||||
proc refreshItems*(self: Model) {.slot.} =
|
||||
self.beginResetModel()
|
||||
self.items = @[]
|
||||
|
||||
var collectiblesPerCollection = getCollectiblesPerCollectionId(self.flatModel.getItems())
|
||||
for collectionId, collectionCollectibles in collectiblesPerCollection.pairs:
|
||||
if self.currentCollectionUid == "":
|
||||
# No collection selected
|
||||
# If the collection contains more than 1 collectible, we add a single collection item
|
||||
# Otherwise, we add the collectible
|
||||
if collectionCollectibles.len > 1:
|
||||
let collectionItem = collectibleToCollectionNestedItem(collectionCollectibles[0])
|
||||
self.items.add(collectionItem)
|
||||
else:
|
||||
for collectible in collectionCollectibles:
|
||||
let collectibleItem = collectibleToCollectibleNestedItem(collectible)
|
||||
self.items.add(collectibleItem)
|
||||
else:
|
||||
if self.currentCollectionUid == collectionId:
|
||||
for collectible in collectionCollectibles:
|
||||
let collectibleItem = collectibleToCollectibleNestedItem(collectible)
|
||||
self.items.add(collectibleItem)
|
||||
# No need to keep looking
|
||||
break
|
||||
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
||||
|
||||
proc resetModel*(self: Model) =
|
||||
self.beginResetModel()
|
||||
self.items = @[]
|
||||
self.endResetModel()
|
||||
self.countChanged()
|
|
@ -0,0 +1,25 @@
|
|||
import sequtils, sugar, times
|
||||
import collectibles_item as flat_item
|
||||
import collectibles_nested_item as nested_item
|
||||
|
||||
proc collectibleToCollectibleNestedItem*(flatItem: flat_item.Item): nested_item.Item =
|
||||
return nested_item.initItem(
|
||||
flatItem.getId(),
|
||||
flatItem.getChainId(),
|
||||
flatItem.getName(),
|
||||
flatItem.getImageUrl(),
|
||||
flatItem.getCollectionId(),
|
||||
flatItem.getCollectionName(),
|
||||
false
|
||||
)
|
||||
|
||||
proc collectibleToCollectionNestedItem*(flatItem: flat_item.Item): nested_item.Item =
|
||||
return nested_item.initItem(
|
||||
flatItem.getCollectionId(),
|
||||
flatItem.getChainId(),
|
||||
flatItem.getCollectionName(),
|
||||
flatItem.getCollectionImageUrl(),
|
||||
flatItem.getCollectionId(),
|
||||
flatItem.getCollectionName(),
|
||||
true
|
||||
)
|
|
@ -19,5 +19,7 @@ proc collectibleToItem*(c: backend.CollectibleHeader, isPinned: bool = false) :
|
|||
c.imageUrl,
|
||||
c.backgroundColor,
|
||||
c.collectionName,
|
||||
c.collectionSlug,
|
||||
c.collectionImageUrl,
|
||||
isPinned
|
||||
)
|
||||
|
|
|
@ -23,6 +23,7 @@ QtObject:
|
|||
chainIds: seq[int]
|
||||
|
||||
requestId: int32
|
||||
autofetch: bool
|
||||
|
||||
proc setup(self: Controller) =
|
||||
self.QObject.setup
|
||||
|
@ -30,33 +31,15 @@ QtObject:
|
|||
proc delete*(self: Controller) =
|
||||
self.QObject.delete
|
||||
|
||||
proc getModel*(self: Controller): QVariant {.slot.} =
|
||||
proc getModel*(self: Controller): Model =
|
||||
return self.model
|
||||
|
||||
proc getModelAsVariant*(self: Controller): QVariant {.slot.} =
|
||||
return newQVariant(self.model)
|
||||
|
||||
QtProperty[QVariant] model:
|
||||
read = getModel
|
||||
read = getModelAsVariant
|
||||
|
||||
proc processFilterOwnedCollectiblesResponse(self: Controller, response: JsonNode) =
|
||||
defer: self.model.setIsFetching(false)
|
||||
|
||||
let res = fromJson(response, backend_collectibles.FilterOwnedCollectiblesResponse)
|
||||
|
||||
let isError = res.errorCode != ErrorCodeSuccess
|
||||
defer: self.model.setIsError(isError)
|
||||
|
||||
if isError:
|
||||
error "error fetching collectibles entries: ", res.errorCode
|
||||
return
|
||||
|
||||
try:
|
||||
let items = res.collectibles.map(header => collectibleToItem(header))
|
||||
self.model.setItems(items, res.offset, res.hasMore)
|
||||
except Exception as e:
|
||||
error "Error converting activity entries: ", e.msg
|
||||
|
||||
proc resetModel*(self: Controller) {.slot.} =
|
||||
self.model.setItems(@[], 0, true)
|
||||
self.fetchFromStart = true
|
||||
|
||||
proc loadMoreItems(self: Controller) {.slot.} =
|
||||
if self.model.getIsFetching():
|
||||
|
@ -77,6 +60,33 @@ QtObject:
|
|||
self.fetchFromStart = true
|
||||
error "error fetching collectibles entries: ", response.error
|
||||
|
||||
proc processFilterOwnedCollectiblesResponse(self: Controller, response: JsonNode) =
|
||||
defer: self.model.setIsFetching(false)
|
||||
|
||||
let res = fromJson(response, backend_collectibles.FilterOwnedCollectiblesResponse)
|
||||
|
||||
let isError = res.errorCode != ErrorCodeSuccess
|
||||
defer: self.model.setIsError(isError)
|
||||
|
||||
if isError:
|
||||
error "error fetching collectibles entries: ", res.errorCode
|
||||
return
|
||||
|
||||
try:
|
||||
let items = res.collectibles.map(header => collectibleToItem(header))
|
||||
self.model.setItems(items, res.offset, res.hasMore)
|
||||
except Exception as e:
|
||||
error "Error converting activity entries: ", e.msg
|
||||
|
||||
if self.autofetch and res.hasMore:
|
||||
self.loadMoreItems()
|
||||
|
||||
proc resetModel*(self: Controller) {.slot.} =
|
||||
self.model.setItems(@[], 0, true)
|
||||
self.fetchFromStart = true
|
||||
if self.autofetch:
|
||||
self.loadMoreItems()
|
||||
|
||||
proc setupEventHandlers(self: Controller) =
|
||||
self.eventsHandler.onOwnedCollectiblesFilteringDone(proc (jsonObj: JsonNode) =
|
||||
self.processFilterOwnedCollectiblesResponse(jsonObj)
|
||||
|
@ -87,14 +97,15 @@ QtObject:
|
|||
)
|
||||
|
||||
self.eventsHandler.onCollectiblesOwnershipUpdateFinished(proc () =
|
||||
self.resetModel()
|
||||
self.model.setIsUpdating(false)
|
||||
self.resetModel()
|
||||
)
|
||||
|
||||
proc newController*(requestId: int32, events: EventEmitter): Controller =
|
||||
proc newController*(requestId: int32, autofetch: bool, events: EventEmitter): Controller =
|
||||
new(result, delete)
|
||||
|
||||
result.requestId = requestId
|
||||
result.autofetch = autofetch
|
||||
|
||||
result.model = newModel()
|
||||
result.fetchFromStart = true
|
||||
|
|
|
@ -12,6 +12,7 @@ type
|
|||
CollectiblesRequestID* = enum
|
||||
WalletAccount
|
||||
ProfileShowcase
|
||||
WalletSend
|
||||
|
||||
# Declared in services/wallet/collectibles/service.go
|
||||
const eventCollectiblesOwnershipUpdateStarted*: string = "wallet-collectibles-ownership-update-started"
|
||||
|
@ -40,7 +41,6 @@ type
|
|||
collectibles*: seq[CollectibleDetails]
|
||||
errorCode*: ErrorCode
|
||||
|
||||
|
||||
# Responses
|
||||
proc fromJson*(e: JsonNode, T: typedesc[FilterOwnedCollectiblesResponse]): FilterOwnedCollectiblesResponse {.inline.} =
|
||||
var collectibles: seq[CollectibleHeader]
|
||||
|
|
|
@ -54,6 +54,8 @@ type
|
|||
animationMediaType*: string
|
||||
backgroundColor*: string
|
||||
collectionName*: string
|
||||
collectionSlug*: string
|
||||
collectionImageUrl*: string
|
||||
|
||||
# Mirrors services/wallet/collectibles/types.go CollectibleDetails
|
||||
CollectibleDetails* = ref object of RootObj
|
||||
|
@ -250,7 +252,9 @@ proc `$`*(self: CollectibleHeader): string =
|
|||
animationUrl:{self.animationUrl},
|
||||
animationMediaType:{self.animationMediaType},
|
||||
backgroundColor:{self.backgroundColor},
|
||||
collectionName:{self.collectionName}
|
||||
collectionName:{self.collectionName},
|
||||
collectionSlug:{self.collectionSlug},
|
||||
collectionImageUrl:{self.collectionImageUrl}
|
||||
)"""
|
||||
|
||||
proc fromJson*(t: JsonNode, T: typedesc[CollectibleHeader]): CollectibleHeader {.inline.} =
|
||||
|
@ -262,6 +266,8 @@ proc fromJson*(t: JsonNode, T: typedesc[CollectibleHeader]): CollectibleHeader {
|
|||
result.animationMediaType = t["animation_media_type"].getStr()
|
||||
result.backgroundColor = t["background_color"].getStr()
|
||||
result.collectionName = t["collection_name"].getStr()
|
||||
result.collectionSlug = t["collection_slug"].getStr()
|
||||
result.collectionImageUrl = t["collection_image_url"].getStr()
|
||||
|
||||
# CollectibleDetails
|
||||
proc `$`*(self: CollectibleDetails): string =
|
||||
|
@ -276,7 +282,7 @@ proc `$`*(self: CollectibleDetails): string =
|
|||
backgroundColor:{self.backgroundColor},
|
||||
collectionName:{self.collectionName},
|
||||
collectionSlug:{self.collectionSlug},
|
||||
collectionImageUrl:{self.collectionImageUrl},
|
||||
collectionImageUrl:{self.collectionImageUrl}
|
||||
)"""
|
||||
|
||||
proc fromJson*(t: JsonNode, T: typedesc[CollectibleDetails]): CollectibleDetails {.inline.} =
|
||||
|
|
Loading…
Reference in New Issue