feat(@desktop/wallet2): New collectibles API
This commit is contained in:
parent
681291b4b1
commit
98943f6d72
|
@ -3,16 +3,18 @@ import NimQml, chronicles, stint
|
|||
|
||||
import
|
||||
../../../status/[status, wallet],
|
||||
views/[accounts, account_list]
|
||||
views/[accounts, account_list, collectibles]
|
||||
|
||||
QtObject:
|
||||
type
|
||||
WalletView* = ref object of QAbstractListModel
|
||||
status: Status
|
||||
accountsView: AccountsView
|
||||
collectiblesView: CollectiblesView
|
||||
|
||||
proc delete(self: WalletView) =
|
||||
self.accountsView.delete
|
||||
self.collectiblesView.delete
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: WalletView) =
|
||||
|
@ -22,21 +24,28 @@ QtObject:
|
|||
new(result, delete)
|
||||
result.status = status
|
||||
result.accountsView = newAccountsView(status)
|
||||
result.collectiblesView = newCollectiblesView(status)
|
||||
result.setup
|
||||
|
||||
proc getAccounts(self: WalletView): QVariant {.slot.} = newQVariant(self.accountsView)
|
||||
QtProperty[QVariant] accountsView:
|
||||
read = getAccounts
|
||||
|
||||
proc getCollectibles(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.collectiblesView)
|
||||
|
||||
QtProperty[QVariant] collectiblesView:
|
||||
read = getCollectibles
|
||||
|
||||
proc updateView*(self: WalletView) =
|
||||
# TODO:
|
||||
self.accountsView.triggerUpdateAccounts()
|
||||
|
||||
|
||||
proc setCurrentAccountByIndex*(self: WalletView, index: int) {.slot.} =
|
||||
if self.accountsView.setCurrentAccountByIndex(index):
|
||||
let selectedAccount = self.accountsView.accounts.getAccount(index)
|
||||
# TODO: load account details/transactions/collectibles/etc
|
||||
self.collectiblesView.loadCollections(selectedAccount)
|
||||
# TODO: load account details/transactions/etc
|
||||
|
||||
proc addAccountToList*(self: WalletView, account: WalletAccount) =
|
||||
self.accountsView.addAccountToList(account)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import NimQml, Tables
|
||||
from ../../../../status/wallet import OpenseaAsset
|
||||
|
||||
type
|
||||
AssetRoles {.pure.} = enum
|
||||
Id = UserRole + 1,
|
||||
Name = UserRole + 2,
|
||||
Description = UserRole + 3,
|
||||
Permalink = UserRole + 4,
|
||||
ImageUrl = UserRole + 5,
|
||||
|
||||
QtObject:
|
||||
type AssetList* = ref object of QAbstractListModel
|
||||
assets*: seq[OpenseaAsset]
|
||||
|
||||
proc setup(self: AssetList) = self.QAbstractListModel.setup
|
||||
|
||||
proc delete(self: AssetList) =
|
||||
self.assets = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newAssetList*(): AssetList =
|
||||
new(result, delete)
|
||||
result.assets = @[]
|
||||
result.setup
|
||||
|
||||
proc assetsChanged*(self: AssetList) {.signal.}
|
||||
|
||||
proc getAsset*(self: AssetList, index: int): OpenseaAsset = self.assets[index]
|
||||
|
||||
proc rowData(self: AssetList, index: int, column: string): string {.slot.} =
|
||||
if (index >= self.assets.len):
|
||||
return
|
||||
|
||||
let asset = self.assets[index]
|
||||
case column:
|
||||
of "name": result = asset.name
|
||||
of "imageUrl": result = asset.imageUrl
|
||||
|
||||
method rowCount*(self: AssetList, index: QModelIndex = nil): int =
|
||||
return self.assets.len
|
||||
|
||||
method data(self: AssetList, index: QModelIndex, role: int): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
|
||||
if index.row < 0 or index.row >= self.assets.len:
|
||||
return
|
||||
|
||||
let asset = self.assets[index.row]
|
||||
let assetRole = role.AssetRoles
|
||||
case assetRole:
|
||||
of AssetRoles.Id: result = newQVariant(asset.id)
|
||||
of AssetRoles.Name: result = newQVariant(asset.name)
|
||||
of AssetRoles.Description: result = newQVariant(asset.description)
|
||||
of AssetRoles.Permalink: result = newQVariant(asset.permalink)
|
||||
of AssetRoles.ImageUrl: result = newQVariant(asset.imageUrl)
|
||||
|
||||
method roleNames(self: AssetList): Table[int, string] =
|
||||
{ AssetRoles.Id.int:"id",
|
||||
AssetRoles.Name.int:"name",
|
||||
AssetRoles.Description.int:"description",
|
||||
AssetRoles.Permalink.int:"permalink",
|
||||
AssetRoles.ImageUrl.int:"imageUrl"}.toTable
|
||||
|
||||
proc setData*(self: AssetList, assets: seq[OpenseaAsset]) =
|
||||
self.beginResetModel()
|
||||
self.assets = assets
|
||||
self.endResetModel()
|
||||
self.assetsChanged()
|
|
@ -0,0 +1,120 @@
|
|||
import NimQml, Tables, json, chronicles
|
||||
|
||||
import
|
||||
../../../../status/[status, wallet],
|
||||
../../../../status/tasks/[qt, task_runner_impl]
|
||||
|
||||
import collection_list, asset_list
|
||||
|
||||
logScope:
|
||||
topics = "collectibles-view"
|
||||
|
||||
type
|
||||
LoadCollectionsTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
|
||||
const loadCollectionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[LoadCollectionsTaskArg](argEncoded)
|
||||
let output = wallet.getOpenseaCollections(arg.address)
|
||||
arg.finish(output)
|
||||
|
||||
proc loadCollections[T](self: T, slot: string, address: string) =
|
||||
let arg = LoadCollectionsTaskArg(
|
||||
tptr: cast[ByteAddress](loadCollectionsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, address: address,
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
type
|
||||
LoadAssetsTaskArg = ref object of QObjectTaskArg
|
||||
address: string
|
||||
collectionSlug: string
|
||||
limit: int
|
||||
|
||||
const loadAssetsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[LoadAssetsTaskArg](argEncoded)
|
||||
let output = %*{
|
||||
"collectionSlug": arg.collectionSlug,
|
||||
"assets": parseJson(wallet.getOpenseaAssets(arg.address, arg.collectionSlug, arg.limit)),
|
||||
}
|
||||
arg.finish(output)
|
||||
|
||||
proc loadAssets[T](self: T, slot: string, address: string, collectionSlug: string) =
|
||||
let arg = LoadAssetsTaskArg(
|
||||
tptr: cast[ByteAddress](loadAssetsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: slot, address: address, collectionSlug: collectionSlug, limit: 200
|
||||
)
|
||||
self.status.tasks.threadpool.start(arg)
|
||||
|
||||
QtObject:
|
||||
type CollectiblesView* = ref object of QObject
|
||||
status: Status
|
||||
collections: CollectionList
|
||||
isLoading: bool
|
||||
assets: Table[string, AssetList]
|
||||
|
||||
proc setup(self: CollectiblesView) = self.QObject.setup
|
||||
|
||||
proc delete(self: CollectiblesView) =
|
||||
self.collections.delete
|
||||
for list in self.assets.values:
|
||||
list.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newCollectiblesView*(status: Status): CollectiblesView =
|
||||
new(result, delete)
|
||||
result.status = status
|
||||
result.collections = newCollectionList()
|
||||
result.assets = initTable[string, AssetList]()
|
||||
result.isLoading = false
|
||||
result.setup
|
||||
|
||||
proc getIsLoading*(self: CollectiblesView): QVariant {.slot.} = newQVariant(self.isLoading)
|
||||
|
||||
proc isLoadingChanged*(self: CollectiblesView) {.signal.}
|
||||
|
||||
QtProperty[QVariant] isLoading:
|
||||
read = getIsLoading
|
||||
notify = isLoadingChanged
|
||||
|
||||
proc loadCollections*(self: CollectiblesView, account: WalletAccount) =
|
||||
self.isLoading = true
|
||||
self.isLoadingChanged()
|
||||
self.assets = initTable[string, AssetList]()
|
||||
self.loadCollections("setCollectionsList", account.address)
|
||||
|
||||
proc setCollectionsList(self: CollectiblesView, raw: string) {.slot.} =
|
||||
var newData: seq[OpenseaCollection] = @[]
|
||||
let collectionsJSON = parseJson(raw)
|
||||
if collectionsJSON["result"].kind != JNull:
|
||||
for jsonOpenseaCollection in collectionsJSON{"result"}:
|
||||
let collection = jsonOpenseaCollection.toOpenseaCollection()
|
||||
newData.add(collection)
|
||||
self.assets[collection.slug] = newAssetList()
|
||||
|
||||
self.collections.setData(newData)
|
||||
self.isLoading = false
|
||||
self.isLoadingChanged()
|
||||
|
||||
proc getCollectionsList(self: CollectiblesView): QVariant {.slot.} =
|
||||
return newQVariant(self.collections)
|
||||
|
||||
QtProperty[QVariant] collections:
|
||||
read = getCollectionsList
|
||||
|
||||
proc loadAssets*(self: CollectiblesView, address: string, collectionSlug: string) {.slot.} =
|
||||
self.loadAssets("setAssetsList", address, collectionSlug)
|
||||
|
||||
proc setAssetsList(self: CollectiblesView, raw: string) {.slot.} =
|
||||
var newData: seq[OpenseaAsset] = @[]
|
||||
let assetsJSON = parseJson(raw)
|
||||
if assetsJSON{"assets"}{"result"}.kind != JNull:
|
||||
for jsonOpenseaAsset in assetsJSON{"assets"}{"result"}:
|
||||
newData.add(jsonOpenseaAsset.toOpenseaAsset())
|
||||
|
||||
self.assets[assetsJSON["collectionSlug"].getStr].setData(newData)
|
||||
|
||||
proc getAssetsList(self: CollectiblesView, collectionSlug: string): QObject {.slot.} =
|
||||
return self.assets[collectionSlug]
|
|
@ -0,0 +1,66 @@
|
|||
import NimQml, Tables
|
||||
from ../../../../status/wallet import OpenseaCollection
|
||||
|
||||
type
|
||||
CollectionRoles {.pure.} = enum
|
||||
Name = UserRole + 1,
|
||||
Slug = UserRole + 2,
|
||||
ImageUrl = UserRole + 3,
|
||||
OwnedAssetCount = UserRole + 4
|
||||
|
||||
QtObject:
|
||||
type CollectionList* = ref object of QAbstractListModel
|
||||
collections*: seq[OpenseaCollection]
|
||||
|
||||
proc setup(self: CollectionList) = self.QAbstractListModel.setup
|
||||
|
||||
proc delete(self: CollectionList) =
|
||||
self.collections = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newCollectionList*(): CollectionList =
|
||||
new(result, delete)
|
||||
result.collections = @[]
|
||||
result.setup
|
||||
|
||||
proc getCollection*(self: CollectionList, index: int): OpenseaCollection = self.collections[index]
|
||||
|
||||
proc rowData(self: CollectionList, index: int, column: string): string {.slot.} =
|
||||
if (index >= self.collections.len):
|
||||
return
|
||||
|
||||
let collection = self.collections[index]
|
||||
case column:
|
||||
of "name": result = collection.name
|
||||
of "slug": result = collection.slug
|
||||
of "imageUrl": result = collection.imageUrl
|
||||
of "ownedAssetCount": result = $collection.ownedAssetCount
|
||||
|
||||
method rowCount*(self: CollectionList, index: QModelIndex = nil): int =
|
||||
return self.collections.len
|
||||
|
||||
method data(self: CollectionList, index: QModelIndex, role: int): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
|
||||
if index.row < 0 or index.row >= self.collections.len:
|
||||
return
|
||||
|
||||
let collection = self.collections[index.row]
|
||||
let collectionRole = role.CollectionRoles
|
||||
case collectionRole:
|
||||
of CollectionRoles.Name: result = newQVariant(collection.name)
|
||||
of CollectionRoles.Slug: result = newQVariant(collection.slug)
|
||||
of CollectionRoles.ImageUrl: result = newQVariant(collection.imageUrl)
|
||||
of CollectionRoles.OwnedAssetCount: result = newQVariant(collection.ownedAssetCount)
|
||||
|
||||
method roleNames(self: CollectionList): Table[int, string] =
|
||||
{ CollectionRoles.Name.int:"name",
|
||||
CollectionRoles.Slug.int:"slug",
|
||||
CollectionRoles.ImageUrl.int:"imageUrl",
|
||||
CollectionRoles.OwnedAssetCount.int:"ownedAssetCount"}.toTable
|
||||
|
||||
proc setData*(self: CollectionList, collections: seq[OpenseaCollection]) =
|
||||
self.beginResetModel()
|
||||
self.collections = collections
|
||||
self.endResetModel()
|
|
@ -128,3 +128,11 @@ proc watchTransaction*(transactionHash: string): string =
|
|||
proc checkRecentHistory*(addresses: seq[string]): string =
|
||||
let payload = %* [addresses]
|
||||
result = callPrivateRPC("wallet_checkRecentHistory", payload)
|
||||
|
||||
proc getOpenseaCollections*(address: string): string =
|
||||
let payload = %* [address]
|
||||
result = callPrivateRPC("wallet_getOpenseaCollectionsByOwner", payload)
|
||||
|
||||
proc getOpenseaAssets*(address: string, collectionSlug: string, limit: int): string =
|
||||
let payload = %* [address, collectionSlug, limit]
|
||||
result = callPrivateRPC("wallet_getOpenseaAssetsByOwnerAndCollection", payload)
|
|
@ -398,3 +398,9 @@ proc watchTransaction*(transactionHash: string): string =
|
|||
|
||||
proc hex2Token*(self: WalletModel, input: string, decimals: int): string =
|
||||
result = status_wallet.hex2Token(input, decimals)
|
||||
|
||||
proc getOpenseaCollections*(address: string): string =
|
||||
result = status_wallet.getOpenseaCollections(address)
|
||||
|
||||
proc getOpenseaAssets*(address: string, collectionSlug: string, limit: int): string =
|
||||
result = status_wallet.getOpenseaAssets(address, collectionSlug, limit)
|
|
@ -1,6 +1,7 @@
|
|||
import options, json, strformat
|
||||
|
||||
from ../../eventemitter import Args
|
||||
import ../types
|
||||
import options
|
||||
|
||||
type CollectibleList* = ref object
|
||||
collectibleType*, collectiblesJSON*, error*: string
|
||||
|
@ -9,6 +10,14 @@ type CollectibleList* = ref object
|
|||
type Collectible* = ref object
|
||||
name*, image*, id*, collectibleType*, description*, externalUrl*: string
|
||||
|
||||
type OpenseaCollection* = ref object
|
||||
name*, slug*, imageUrl*: string
|
||||
ownedAssetCount*: int
|
||||
|
||||
type OpenseaAsset* = ref object
|
||||
id*: int
|
||||
name*, description*, permalink*, imageThumbnailUrl*, imageUrl*, address*: string
|
||||
|
||||
type CurrencyArgs* = ref object of Args
|
||||
currency*: string
|
||||
|
||||
|
@ -26,3 +35,28 @@ type WalletAccount* = ref object
|
|||
|
||||
type AccountArgs* = ref object of Args
|
||||
account*: WalletAccount
|
||||
|
||||
proc `$`*(self: OpenseaCollection): string =
|
||||
return fmt"OpenseaCollection(name:{self.name}, slug:{self.slug}, owned asset count:{self.ownedAssetCount})"
|
||||
|
||||
proc `$`*(self: OpenseaAsset): string =
|
||||
return fmt"OpenseaAsset(id:{self.id}, name:{self.name}, address:{self.address}, imageUrl: {self.imageUrl}, imageThumbnailUrl: {self.imageThumbnailUrl})"
|
||||
|
||||
proc toOpenseaCollection*(jsonCollection: JsonNode): OpenseaCollection =
|
||||
return OpenseaCollection(
|
||||
name: jsonCollection{"name"}.getStr,
|
||||
slug: jsonCollection{"slug"}.getStr,
|
||||
imageUrl: jsonCollection{"image_url"}.getStr,
|
||||
ownedAssetCount: jsonCollection{"owned_asset_count"}.getInt
|
||||
)
|
||||
|
||||
proc toOpenseaAsset*(jsonAsset: JsonNode): OpenseaAsset =
|
||||
return OpenseaAsset(
|
||||
id: jsonAsset{"id"}.getInt,
|
||||
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
|
||||
)
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import "../../../imports"
|
||||
import "../../../shared"
|
||||
import "../../../shared/status/core"
|
||||
import "./components"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
sourceComponent: {
|
||||
if (walletV2Model.collectiblesView.isLoading) {
|
||||
return loading
|
||||
}
|
||||
if (walletV2Model.collectiblesView.collections.rowCount() == 0) {
|
||||
return empty
|
||||
}
|
||||
|
||||
return loaded
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loading
|
||||
|
||||
Item {
|
||||
StatusLoadingIndicator {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 20
|
||||
height: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: empty
|
||||
Item {
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Style.current.secondaryText
|
||||
text: qsTr("Collectibles will appear here")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CollectibleModal {
|
||||
id: collectibleModalComponent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loaded
|
||||
|
||||
ScrollView {
|
||||
id: scrollView
|
||||
clip: true
|
||||
|
||||
Column {
|
||||
id: collectiblesSection
|
||||
spacing: Style.current.halfPadding
|
||||
width: root.width
|
||||
|
||||
Repeater {
|
||||
id: collectionsRepeater
|
||||
model: walletV2Model.collectiblesView.collections
|
||||
|
||||
CollectibleCollection {
|
||||
name: model.name
|
||||
imageUrl: model.imageUrl
|
||||
ownedAssetCount: model.ownedAssetCount
|
||||
slug: model.slug
|
||||
collectibleModal: collectibleModalComponent
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.bigPadding
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;autoSize:true;formeditorColor:"#ffffff";height:480;width:640}
|
||||
}
|
||||
##^##*/
|
|
@ -69,8 +69,36 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
StyledText {
|
||||
text: "TODO"
|
||||
TabBar {
|
||||
id: walletTabBar
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.bigPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.bigPadding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.padding
|
||||
height: collectiblesBtn.height
|
||||
background: Rectangle {
|
||||
color: Style.current.transparent
|
||||
}
|
||||
StatusTabButton {
|
||||
id: collectiblesBtn
|
||||
btnText: qsTr("Collectibles")
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackLayout
|
||||
anchors.top: walletTabBar.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
currentIndex: walletTabBar.currentIndex
|
||||
|
||||
CollectiblesTab {
|
||||
id: collectiblesTab
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
import "../../../../shared/status/core"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string imageUrl: ""
|
||||
property string name: "CryptoKitties"
|
||||
property string slug: "cryptokitties"
|
||||
property int ownedAssetCount: 0
|
||||
property var collectibleModal
|
||||
property bool isOpened: false
|
||||
property bool assetsLoaded: false
|
||||
|
||||
width: parent.width
|
||||
height: {
|
||||
if (!isOpened) {
|
||||
return header.height
|
||||
}
|
||||
|
||||
return header.height + contentLoader.height
|
||||
}
|
||||
|
||||
function toggleCollection() {
|
||||
if (root.isOpened) {
|
||||
root.isOpened = false
|
||||
return
|
||||
}
|
||||
|
||||
walletV2Model.collectiblesView.loadAssets(walletV2Model.accountsView.currentAccount.address, root.slug)
|
||||
root.isOpened = true
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: walletV2Model.collectiblesView.getAssetsList(root.slug)
|
||||
onAssetsChanged: {
|
||||
root.assetsLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: header
|
||||
property bool hovered: false
|
||||
height: 64
|
||||
width: parent.width
|
||||
color: hovered ? Style.current.backgroundHover : Style.current.transparent
|
||||
border.width: 0
|
||||
radius: Style.current.radius
|
||||
|
||||
Image {
|
||||
id: image
|
||||
source: root.imageUrl
|
||||
width: 40
|
||||
height: 40
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.name
|
||||
anchors.left: image.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 17
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.right: header.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.verticalCenter: header.verticalCenter
|
||||
width: childrenRect.width
|
||||
height: count.height
|
||||
|
||||
StyledText {
|
||||
id: count
|
||||
color: Style.current.secondaryText
|
||||
text: root.ownedAssetCount
|
||||
font.pixelSize: 15
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
SVGImage {
|
||||
id: caretImg
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: "../../../img/caret.svg"
|
||||
width: 11
|
||||
anchors.left: count.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
ColorOverlay {
|
||||
anchors.fill: caretImg
|
||||
source: caretImg
|
||||
color: Style.current.black
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
header.hovered = true
|
||||
}
|
||||
onExited: {
|
||||
header.hovered = false
|
||||
}
|
||||
onClicked: {
|
||||
root.toggleCollection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
active: root.isOpened
|
||||
width: parent.width
|
||||
anchors.top: header.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
sourceComponent: root.assetsLoaded ? loaded : loading
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loading
|
||||
Item {
|
||||
id: loadingIndicator
|
||||
height: 164
|
||||
StatusLoadingIndicator {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 20
|
||||
height: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loaded
|
||||
ScrollView {
|
||||
height: contentRow.height
|
||||
width: parent.width
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||
clip: true
|
||||
|
||||
Row {
|
||||
id: contentRow
|
||||
bottomPadding: Style.current.padding
|
||||
spacing: Style.current.padding
|
||||
|
||||
Repeater {
|
||||
model: walletV2Model.collectiblesView.getAssetsList(root.slug)
|
||||
|
||||
Item {
|
||||
width: image.width
|
||||
height: image.height
|
||||
clip: true
|
||||
|
||||
RoundedImage {
|
||||
id: image
|
||||
width: 164
|
||||
height: 164
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
radius: 16
|
||||
source: model.imageUrl
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onClicked: {
|
||||
collectibleModal.openModal({
|
||||
name: model.name,
|
||||
collectibleId: model.id,
|
||||
description: model.description,
|
||||
permalink: model.permalink,
|
||||
imageUrl: model.imageUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
|
@ -0,0 +1,69 @@
|
|||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
import "../../../../shared/status"
|
||||
|
||||
ModalPopup {
|
||||
id: root
|
||||
property string name: "Furbeard"
|
||||
property string collectibleId: "1423"
|
||||
property url imageUrl: ""
|
||||
property string description: "Avast ye! I'm the dread pirate Furbeard, and I'll most likely sleep"
|
||||
property string permalink: "https://www.cryptokitties.co/"
|
||||
property var openModal: function (options) {
|
||||
root.name = options.name
|
||||
root.collectibleId = options.collectibleId
|
||||
root.description = options.description
|
||||
root.imageUrl = options.imageUrl
|
||||
root.permalink = options.permalink
|
||||
root.open()
|
||||
}
|
||||
|
||||
title: root.name || qsTr("unnamed")
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
|
||||
RoundedImage {
|
||||
id: collectibleImage
|
||||
width: 248
|
||||
height: 248
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
source: root.imageUrl
|
||||
radius: 16
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: idText
|
||||
label: qsTr("id")
|
||||
text: root.collectibleId
|
||||
anchors.top: collectibleImage.bottom
|
||||
anchors.topMargin:0
|
||||
}
|
||||
|
||||
|
||||
TextWithLabel {
|
||||
id: description
|
||||
visible: !!root.description
|
||||
label: qsTr("description")
|
||||
text: root.description
|
||||
anchors.top: idText.bottom
|
||||
anchors.topMargin: 0
|
||||
wrap: true
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
text: qsTr("View in Opensea")
|
||||
anchors.top: parent.top
|
||||
onClicked: {
|
||||
appMain.openLink(root.permalink)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,4 @@
|
|||
SendModalContent 1.0 SendModalContent.qml
|
||||
SetCurrencyModalContent 1.0 SetCurrencyModalContent.qml
|
||||
TokenSettingsModalContent 1.0 TokenSettingsModalContent.qml
|
||||
AddAccount 1.0 AddAccount.qml
|
||||
GenerateAccountModal 1.0 GenerateAccountModal.qml
|
||||
AddAccountWithSeed 1.0 AddAccountWithSeed.qml
|
||||
AddAccountWithPrivateKey 1.0 AddAccountWithPrivateKey.qml
|
||||
AddWatchOnlyAccount 1.0 AddWatchOnlyAccount.qml
|
||||
TransactionModal 1.0 TransactionModal.qml
|
||||
HeaderButton 1.0 HeaderButton.qml
|
||||
CollectibleCollection 1.0 CollectibleCollection.qml
|
||||
CollectibleModal 1.0 CollectibleModal.qml
|
|
@ -1 +1 @@
|
|||
Subproject commit b8959e3f66159b142fb6706b89f4ad8295944ee4
|
||||
Subproject commit 37484b28ebdab47092a96362d5a08f31ea88a4f3
|
Loading…
Reference in New Issue