refactor(community_tokens): only fetch holders when going to the page (#16308)
* refactor(community_tokens): only fetch holders when going to the page Fixes #16307 Instead of fetching community token holders each time members change, we fetch when the page for the token is opened. It shows a small loading text then the resulting holders. If the list is already available (fetched previously, we show it directly). There is still the timer to refresh the list if you stay on the page. * add loading property to storybook
This commit is contained in:
parent
ea8827ec97
commit
3f8dfee3cd
|
@ -178,9 +178,3 @@ proc declineOwnership*(self: Controller, communityId: string) =
|
||||||
|
|
||||||
proc asyncGetOwnerTokenOwnerAddress*(self: Controller, chainId: int, contractAddress: string) =
|
proc asyncGetOwnerTokenOwnerAddress*(self: Controller, chainId: int, contractAddress: string) =
|
||||||
self.communityTokensService.asyncGetOwnerTokenOwnerAddress(chainId, contractAddress)
|
self.communityTokensService.asyncGetOwnerTokenOwnerAddress(chainId, contractAddress)
|
||||||
|
|
||||||
proc startTokenHoldersManagement*(self: Controller, chainId: int, contractAddress: string) =
|
|
||||||
self.communityTokensService.startTokenHoldersManagement(chainId, contractAddress)
|
|
||||||
|
|
||||||
proc stopTokenHoldersManagement*(self: Controller) =
|
|
||||||
self.communityTokensService.stopTokenHoldersManagement()
|
|
|
@ -119,9 +119,3 @@ method onOwnerTokenOwnerAddress*(self: AccessInterface, chainId: int, contractAd
|
||||||
|
|
||||||
method asyncGetOwnerTokenDetails*(self: AccessInterface, communityId: string) {.base.} =
|
method asyncGetOwnerTokenDetails*(self: AccessInterface, communityId: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method startTokenHoldersManagement*(self: AccessInterface, chainId: int, contractAddress: string) {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
|
||||||
|
|
||||||
method stopTokenHoldersManagement*(self: AccessInterface) {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
|
|
@ -20,6 +20,7 @@ type
|
||||||
burnState*: ContractTransactionStatus
|
burnState*: ContractTransactionStatus
|
||||||
remoteDestructedAddresses*: seq[string]
|
remoteDestructedAddresses*: seq[string]
|
||||||
tokenOwnersModel*: token_owners_model.TokenOwnersModel
|
tokenOwnersModel*: token_owners_model.TokenOwnersModel
|
||||||
|
tokenHoldersLoading*: bool
|
||||||
|
|
||||||
proc initTokenItem*(
|
proc initTokenItem*(
|
||||||
tokenDto: CommunityTokenDto,
|
tokenDto: CommunityTokenDto,
|
||||||
|
@ -29,7 +30,7 @@ proc initTokenItem*(
|
||||||
burnState: ContractTransactionStatus,
|
burnState: ContractTransactionStatus,
|
||||||
remoteDestructedAddresses: seq[string],
|
remoteDestructedAddresses: seq[string],
|
||||||
remainingSupply: Uint256,
|
remainingSupply: Uint256,
|
||||||
destructedAmount: Uint256
|
destructedAmount: Uint256,
|
||||||
): TokenItem =
|
): TokenItem =
|
||||||
result.tokenDto = tokenDto
|
result.tokenDto = tokenDto
|
||||||
if network != nil:
|
if network != nil:
|
||||||
|
@ -45,6 +46,7 @@ proc initTokenItem*(
|
||||||
# TODO: provide number of messages here
|
# TODO: provide number of messages here
|
||||||
result = initTokenOwnersItem(owner.contactId, owner.name, owner.imageSource, 0, owner.collectibleOwner, remoteDestructedAddresses)
|
result = initTokenOwnersItem(owner.contactId, owner.name, owner.imageSource, 0, owner.collectibleOwner, remoteDestructedAddresses)
|
||||||
))
|
))
|
||||||
|
result.tokenHoldersLoading = false
|
||||||
|
|
||||||
proc `$`*(self: TokenItem): string =
|
proc `$`*(self: TokenItem): string =
|
||||||
result = fmt"""TokenItem(
|
result = fmt"""TokenItem(
|
||||||
|
@ -55,6 +57,7 @@ proc `$`*(self: TokenItem): string =
|
||||||
destructedAmount: {self.destructedAmount},
|
destructedAmount: {self.destructedAmount},
|
||||||
burnState: {self.burnState},
|
burnState: {self.burnState},
|
||||||
tokenOwnersModel: {self.tokenOwnersModel},
|
tokenOwnersModel: {self.tokenOwnersModel},
|
||||||
|
tokenHoldersLoading: {self.tokenHoldersLoading},
|
||||||
remoteDestructedAddresses: {self.remoteDestructedAddresses}
|
remoteDestructedAddresses: {self.remoteDestructedAddresses}
|
||||||
]"""
|
]"""
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ type
|
||||||
ChainName
|
ChainName
|
||||||
ChainIcon
|
ChainIcon
|
||||||
TokenOwnersModel
|
TokenOwnersModel
|
||||||
|
TokenHoldersLoading
|
||||||
AccountName
|
AccountName
|
||||||
AccountAddress
|
AccountAddress
|
||||||
RemainingSupply
|
RemainingSupply
|
||||||
|
@ -50,77 +51,106 @@ QtObject:
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.setup
|
result.setup
|
||||||
|
|
||||||
proc updateDeployState*(self: TokenModel, chainId: int, contractAddress: string, deployState: DeployState) =
|
proc getItemIndex(self: TokenModel, chainId: int, contractAddress: string): int =
|
||||||
for i in 0 ..< self.items.len:
|
for i in 0 ..< self.items.len:
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if self.items[i].tokenDto.address == contractAddress and self.items[i].tokenDto.chainId == chainId:
|
||||||
self.items[i].tokenDto.deployState = deployState
|
return i
|
||||||
let index = self.createIndex(i, 0, nil)
|
return -1
|
||||||
|
|
||||||
|
proc updateDeployState*(self: TokenModel, chainId: int, contractAddress: string, deployState: DeployState) =
|
||||||
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
|
if itemIdx == -1 and self.items[itemIdx].tokenDto.deployState == deployState:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.items[itemIdx].tokenDto.deployState = deployState
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.DeployState.int])
|
self.dataChanged(index, index, @[ModelRole.DeployState.int])
|
||||||
return
|
|
||||||
|
|
||||||
proc updateAddress*(self: TokenModel, chainId: int, oldContractAddress: string, newContractAddress: string) =
|
proc updateAddress*(self: TokenModel, chainId: int, oldContractAddress: string, newContractAddress: string) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, oldContractAddress)
|
||||||
if((self.items[i].tokenDto.address == oldContractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1 and self.items[itemIdx].tokenDto.address == newContractAddress:
|
||||||
self.items[i].tokenDto.address = newContractAddress
|
return
|
||||||
let index = self.createIndex(i, 0, nil)
|
|
||||||
|
self.items[itemIdx].tokenDto.address = newContractAddress
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.TokenAddress.int])
|
self.dataChanged(index, index, @[ModelRole.TokenAddress.int])
|
||||||
return
|
|
||||||
|
|
||||||
proc updateBurnState*(self: TokenModel, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) =
|
proc updateBurnState*(self: TokenModel, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1 and self.items[itemIdx].burnState == burnState:
|
||||||
self.items[i].burnState = burnState
|
return
|
||||||
let index = self.createIndex(i, 0, nil)
|
|
||||||
|
self.items[itemIdx].burnState = burnState
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.BurnState.int])
|
self.dataChanged(index, index, @[ModelRole.BurnState.int])
|
||||||
return
|
|
||||||
|
|
||||||
proc updateRemoteDestructedAddresses*(self: TokenModel, chainId: int, contractAddress: string, remoteDestructedAddresses: seq[string]) =
|
proc updateRemoteDestructedAddresses*(self: TokenModel, chainId: int, contractAddress: string, remoteDestructedAddresses: seq[string]) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1 and self.items[itemIdx].remoteDestructedAddresses == remoteDestructedAddresses:
|
||||||
self.items[i].remoteDestructedAddresses = remoteDestructedAddresses
|
return
|
||||||
let index = self.createIndex(i, 0, nil)
|
|
||||||
|
self.items[itemIdx].remoteDestructedAddresses = remoteDestructedAddresses
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.RemotelyDestructState.int])
|
self.dataChanged(index, index, @[ModelRole.RemotelyDestructState.int])
|
||||||
self.items[i].tokenOwnersModel.updateRemoteDestructState(remoteDestructedAddresses)
|
self.items[itemIdx].tokenOwnersModel.updateRemoteDestructState(remoteDestructedAddresses)
|
||||||
self.dataChanged(index, index, @[ModelRole.TokenOwnersModel.int])
|
self.dataChanged(index, index, @[ModelRole.TokenOwnersModel.int])
|
||||||
return
|
|
||||||
|
|
||||||
proc updateSupply*(self: TokenModel, chainId: int, contractAddress: string, supply: Uint256, destructedAmount: Uint256) =
|
proc updateSupply*(self: TokenModel, chainId: int, contractAddress: string, supply: Uint256, destructedAmount: Uint256) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1:
|
||||||
if self.items[i].tokenDto.supply != supply or self.items[i].destructedAmount != destructedAmount:
|
return
|
||||||
self.items[i].tokenDto.supply = supply
|
|
||||||
self.items[i].destructedAmount = destructedAmount
|
if self.items[itemIdx].tokenDto.supply != supply or self.items[itemIdx].destructedAmount != destructedAmount:
|
||||||
let index = self.createIndex(i, 0, nil)
|
self.items[itemIdx].tokenDto.supply = supply
|
||||||
|
self.items[itemIdx].destructedAmount = destructedAmount
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.Supply.int])
|
self.dataChanged(index, index, @[ModelRole.Supply.int])
|
||||||
return
|
|
||||||
|
|
||||||
proc updateRemainingSupply*(self: TokenModel, chainId: int, contractAddress: string, remainingSupply: Uint256) =
|
proc updateRemainingSupply*(self: TokenModel, chainId: int, contractAddress: string, remainingSupply: Uint256) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1 and self.items[itemIdx].remainingSupply == remainingSupply:
|
||||||
if self.items[i].remainingSupply != remainingSupply:
|
|
||||||
self.items[i].remainingSupply = remainingSupply
|
|
||||||
let index = self.createIndex(i, 0, nil)
|
|
||||||
defer: index.delete
|
|
||||||
self.dataChanged(index, index, @[ModelRole.RemainingSupply.int])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
proc setCommunityTokenOwners*(self: TokenModel, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) =
|
self.items[itemIdx].remainingSupply = remainingSupply
|
||||||
for i in 0 ..< self.items.len:
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
if((self.items[i].tokenDto.address == contractAddress) and (self.items[i].tokenDto.chainId == chainId)):
|
|
||||||
self.items[i].tokenOwnersModel.setItems(owners.map(proc(owner: CommunityCollectibleOwner): TokenOwnersItem =
|
|
||||||
# TODO: provide number of messages here
|
|
||||||
result = initTokenOwnersItem(owner.contactId, owner.name, owner.imageSource, 0, owner.collectibleOwner, self.items[i].remoteDestructedAddresses)
|
|
||||||
))
|
|
||||||
let index = self.createIndex(i, 0, nil)
|
|
||||||
defer: index.delete
|
defer: index.delete
|
||||||
self.dataChanged(index, index, @[ModelRole.TokenOwnersModel.int])
|
self.dataChanged(index, index, @[ModelRole.RemainingSupply.int])
|
||||||
|
|
||||||
|
proc hasTokenHolders*(self: TokenModel, chainId: int, contractAddress: string): bool =
|
||||||
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
|
if itemIdx == -1:
|
||||||
|
return false
|
||||||
|
return self.items[itemIdx].tokenOwnersModel.count > 0
|
||||||
|
|
||||||
|
proc setCommunityTokenOwners*(self: TokenModel, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) =
|
||||||
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
|
if itemIdx == -1:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.items[itemIdx].tokenHoldersLoading = false
|
||||||
|
self.items[itemIdx].tokenOwnersModel.setItems(owners.map(proc(owner: CommunityCollectibleOwner): TokenOwnersItem =
|
||||||
|
# TODO: provide number of messages here
|
||||||
|
result = initTokenOwnersItem(owner.contactId, owner.name, owner.imageSource, 0, owner.collectibleOwner, self.items[itemIdx].remoteDestructedAddresses)
|
||||||
|
))
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
|
defer: index.delete
|
||||||
|
self.dataChanged(index, index, @[ModelRole.TokenOwnersModel.int, ModelRole.TokenHoldersLoading.int])
|
||||||
|
|
||||||
|
proc setCommunityTokenHoldersLoading*(self: TokenModel, chainId: int, contractAddress: string, value: bool) =
|
||||||
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
|
if itemIdx == -1 and self.items[itemIdx].tokenHoldersLoading == value:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.items[itemIdx].tokenHoldersLoading = value
|
||||||
|
let index = self.createIndex(itemIdx, 0, nil)
|
||||||
|
defer: index.delete
|
||||||
|
self.dataChanged(index, index, @[ModelRole.TokenHoldersLoading.int])
|
||||||
|
|
||||||
proc countChanged(self: TokenModel) {.signal.}
|
proc countChanged(self: TokenModel) {.signal.}
|
||||||
|
|
||||||
proc setItems*(self: TokenModel, items: seq[TokenItem]) =
|
proc setItems*(self: TokenModel, items: seq[TokenItem]) =
|
||||||
|
@ -129,7 +159,6 @@ QtObject:
|
||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
self.countChanged()
|
self.countChanged()
|
||||||
|
|
||||||
|
|
||||||
proc getOwnerToken*(self: TokenModel): TokenItem =
|
proc getOwnerToken*(self: TokenModel): TokenItem =
|
||||||
for i in 0 ..< self.items.len:
|
for i in 0 ..< self.items.len:
|
||||||
if(self.items[i].tokenDto.privilegesLevel == PrivilegesLevel.Owner):
|
if(self.items[i].tokenDto.privilegesLevel == PrivilegesLevel.Owner):
|
||||||
|
@ -144,17 +173,18 @@ QtObject:
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
self.countChanged()
|
self.countChanged()
|
||||||
|
|
||||||
proc removeItemByChainIdAndAddress*(self: TokenModel, chainId: int, address: string) =
|
proc removeItemByChainIdAndAddress*(self: TokenModel, chainId: int, contractAddress: string) =
|
||||||
for i in 0 ..< self.items.len:
|
let itemIdx = self.getItemIndex(chainId, contractAddress)
|
||||||
if((self.items[i].tokenDto.address == address) and (self.items[i].tokenDto.chainId == chainId)):
|
if itemIdx == -1:
|
||||||
|
return
|
||||||
|
|
||||||
let parentModelIndex = newQModelIndex()
|
let parentModelIndex = newQModelIndex()
|
||||||
defer: parentModelIndex.delete
|
defer: parentModelIndex.delete
|
||||||
|
|
||||||
self.beginRemoveRows(parentModelIndex, i, i)
|
self.beginRemoveRows(parentModelIndex, itemIdx, itemIdx)
|
||||||
self.items.delete(i)
|
self.items.delete(itemIdx)
|
||||||
self.endRemoveRows()
|
self.endRemoveRows()
|
||||||
self.countChanged()
|
self.countChanged()
|
||||||
return
|
|
||||||
|
|
||||||
proc getCount*(self: TokenModel): int {.slot.} =
|
proc getCount*(self: TokenModel): int {.slot.} =
|
||||||
self.items.len
|
self.items.len
|
||||||
|
@ -184,6 +214,7 @@ QtObject:
|
||||||
ModelRole.ChainName.int:"chainName",
|
ModelRole.ChainName.int:"chainName",
|
||||||
ModelRole.ChainIcon.int:"chainIcon",
|
ModelRole.ChainIcon.int:"chainIcon",
|
||||||
ModelRole.TokenOwnersModel.int:"tokenOwnersModel",
|
ModelRole.TokenOwnersModel.int:"tokenOwnersModel",
|
||||||
|
ModelRole.TokenHoldersLoading.int:"tokenHoldersLoading",
|
||||||
ModelRole.AccountName.int:"accountName",
|
ModelRole.AccountName.int:"accountName",
|
||||||
ModelRole.AccountAddress.int:"accountAddress",
|
ModelRole.AccountAddress.int:"accountAddress",
|
||||||
ModelRole.RemainingSupply.int:"remainingSupply",
|
ModelRole.RemainingSupply.int:"remainingSupply",
|
||||||
|
@ -235,6 +266,8 @@ QtObject:
|
||||||
result = newQVariant(item.chainIcon)
|
result = newQVariant(item.chainIcon)
|
||||||
of ModelRole.TokenOwnersModel:
|
of ModelRole.TokenOwnersModel:
|
||||||
result = newQVariant(item.tokenOwnersModel)
|
result = newQVariant(item.tokenOwnersModel)
|
||||||
|
of ModelRole.TokenHoldersLoading:
|
||||||
|
result = newQVariant(item.tokenHoldersLoading)
|
||||||
of ModelRole.AccountName:
|
of ModelRole.AccountName:
|
||||||
result = newQVariant(item.accountName)
|
result = newQVariant(item.accountName)
|
||||||
of ModelRole.AccountAddress:
|
of ModelRole.AccountAddress:
|
||||||
|
|
|
@ -385,9 +385,3 @@ method onOwnerTokenOwnerAddress*(self: Module, chainId: int, contractAddress: st
|
||||||
"contractAddress": contractAddress
|
"contractAddress": contractAddress
|
||||||
}
|
}
|
||||||
self.view.setOwnerTokenDetails($jsonObj)
|
self.view.setOwnerTokenDetails($jsonObj)
|
||||||
|
|
||||||
method startTokenHoldersManagement*(self: Module, chainId: int, contractAddress: string) =
|
|
||||||
self.controller.startTokenHoldersManagement(chainId, contractAddress)
|
|
||||||
|
|
||||||
method stopTokenHoldersManagement*(self: Module) =
|
|
||||||
self.controller.stopTokenHoldersManagement()
|
|
|
@ -145,9 +145,3 @@ QtObject:
|
||||||
QtProperty[string] ownerTokenDetails:
|
QtProperty[string] ownerTokenDetails:
|
||||||
read = getOwnerTokenDetails
|
read = getOwnerTokenDetails
|
||||||
notify = ownerTokenDetailsChanged
|
notify = ownerTokenDetailsChanged
|
||||||
|
|
||||||
proc startTokenHoldersManagement*(self: View, chainId: int, contractAddress: string) {.slot.} =
|
|
||||||
self.communityTokensModule.startTokenHoldersManagement(chainId, contractAddress)
|
|
||||||
|
|
||||||
proc stopTokenHoldersManagement*(self: View) {.slot.} =
|
|
||||||
self.communityTokensModule.stopTokenHoldersManagement()
|
|
|
@ -392,6 +392,10 @@ proc init*(self: Controller) =
|
||||||
let args = CommunityTokenOwnersArgs(e)
|
let args = CommunityTokenOwnersArgs(e)
|
||||||
self.delegate.onCommunityTokenOwnersFetched(args.communityId, args.chainId, args.contractAddress, args.owners)
|
self.delegate.onCommunityTokenOwnersFetched(args.communityId, args.chainId, args.contractAddress, args.owners)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_COMMUNITY_TOKEN_OWNERS_LOADING_FAILED) do(e: Args):
|
||||||
|
let args = CommunityTokenOwnersArgs(e)
|
||||||
|
self.delegate.errorLoadingTokenHolders(args.communityId, args.chainId, args.contractAddress, args.error)
|
||||||
|
|
||||||
self.events.on(SIGNAL_ACCEPT_REQUEST_TO_JOIN_LOADING) do(e: Args):
|
self.events.on(SIGNAL_ACCEPT_REQUEST_TO_JOIN_LOADING) do(e: Args):
|
||||||
var args = CommunityMemberArgs(e)
|
var args = CommunityMemberArgs(e)
|
||||||
self.delegate.onAcceptRequestToJoinLoading(args.communityId, args.pubKey)
|
self.delegate.onAcceptRequestToJoinLoading(args.communityId, args.pubKey)
|
||||||
|
@ -412,10 +416,6 @@ proc init*(self: Controller) =
|
||||||
let args = CommunityMemberStatusUpdatedArgs(e)
|
let args = CommunityMemberStatusUpdatedArgs(e)
|
||||||
self.delegate.onMembershipStateUpdated(args.communityId, args.memberPubkey, args.state)
|
self.delegate.onMembershipStateUpdated(args.communityId, args.memberPubkey, args.state)
|
||||||
|
|
||||||
self.events.on(SIGNAL_COMMUNITY_MEMBERS_CHANGED) do(e: Args):
|
|
||||||
let args = CommunityMembersArgs(e)
|
|
||||||
self.communityTokensService.fetchCommunityTokenOwners(args.communityId)
|
|
||||||
|
|
||||||
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED) do(e: Args):
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED) do(e: Args):
|
||||||
let args = SharedKeycarModuleFlowTerminatedArgs(e)
|
let args = SharedKeycarModuleFlowTerminatedArgs(e)
|
||||||
if args.uniqueIdentifier == UNIQUE_MAIN_MODULE_KEYCARD_SYNC_IDENTIFIER:
|
if args.uniqueIdentifier == UNIQUE_MAIN_MODULE_KEYCARD_SYNC_IDENTIFIER:
|
||||||
|
@ -597,3 +597,9 @@ proc asyncGetRevealedAccountsForAllMembers*(self: Controller, communityId: strin
|
||||||
|
|
||||||
proc asyncReevaluateCommunityMembersPermissions*(self: Controller, communityId: string) =
|
proc asyncReevaluateCommunityMembersPermissions*(self: Controller, communityId: string) =
|
||||||
self.communityService.asyncReevaluateCommunityMembersPermissions(communityId)
|
self.communityService.asyncReevaluateCommunityMembersPermissions(communityId)
|
||||||
|
|
||||||
|
proc startTokenHoldersManagement*(self: Controller, chainId: int, contractAddress: string) =
|
||||||
|
self.communityTokensService.startTokenHoldersManagement(chainId, contractAddress)
|
||||||
|
|
||||||
|
proc stopTokenHoldersManagement*(self: Controller) =
|
||||||
|
self.communityTokensService.stopTokenHoldersManagement()
|
||||||
|
|
|
@ -337,6 +337,9 @@ method onOwnerTokensDeploymentStarted*(self: AccessInterface, ownerToken: Commun
|
||||||
method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.base.} =
|
method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method errorLoadingTokenHolders*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, error: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, deployState: DeployState) {.base.} =
|
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, deployState: DeployState) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
@ -421,6 +424,12 @@ method openSectionChatAndMessage*(self: AccessInterface, sectionId: string, chat
|
||||||
method updateRequestToJoinState*(self: AccessInterface, sectionId: string, requestToJoinState: RequestToJoinState) {.base.} =
|
method updateRequestToJoinState*(self: AccessInterface, sectionId: string, requestToJoinState: RequestToJoinState) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method startTokenHoldersManagement*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method stopTokenHoldersManagement*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
# This way (using concepts) is used only for the modules managed by AppController
|
# This way (using concepts) is used only for the modules managed by AppController
|
||||||
type
|
type
|
||||||
DelegateInterface* = concept c
|
DelegateInterface* = concept c
|
||||||
|
|
|
@ -1213,6 +1213,20 @@ method onCommunityTokenRemoved*[T](self: Module[T], communityId: string, chainId
|
||||||
if item.id != "":
|
if item.id != "":
|
||||||
item.removeCommunityToken(chainId, address)
|
item.removeCommunityToken(chainId, address)
|
||||||
|
|
||||||
|
method startTokenHoldersManagement*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string) =
|
||||||
|
self.controller.startTokenHoldersManagement(chainId, contractAddress)
|
||||||
|
let item = self.view.model().getItemById(communityId)
|
||||||
|
if item.id != "" and not item.communityTokens.hasTokenHolders(chainId, contractAddress):
|
||||||
|
item.setCommunityTokenHoldersLoading(chainId, contractAddress, value = true)
|
||||||
|
|
||||||
|
method stopTokenHoldersManagement*[T](self: Module[T]) =
|
||||||
|
self.controller.stopTokenHoldersManagement()
|
||||||
|
|
||||||
|
method errorLoadingTokenHolders*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string, error: string) =
|
||||||
|
let item = self.view.model().getItemById(communityId)
|
||||||
|
if item.id != "":
|
||||||
|
item.setCommunityTokenHoldersLoading(chainId, contractAddress, value = false)
|
||||||
|
|
||||||
method onCommunityTokenOwnersFetched*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) =
|
method onCommunityTokenOwnersFetched*[T](self: Module[T], communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) =
|
||||||
let item = self.view.model().getItemById(communityId)
|
let item = self.view.model().getItemById(communityId)
|
||||||
if item.id != "":
|
if item.id != "":
|
||||||
|
|
|
@ -375,3 +375,9 @@ QtObject:
|
||||||
proc emitCommunityMemberStatusEphemeralNotification*(self:View, communityName: string, memberName: string,
|
proc emitCommunityMemberStatusEphemeralNotification*(self:View, communityName: string, memberName: string,
|
||||||
membershipState: int) =
|
membershipState: int) =
|
||||||
self.communityMemberStatusEphemeralNotification(communityName, memberName, membershipState)
|
self.communityMemberStatusEphemeralNotification(communityName, memberName, membershipState)
|
||||||
|
|
||||||
|
proc startTokenHoldersManagement*(self: View, communityId: string, chainId: int, contractAddress: string) {.slot.} =
|
||||||
|
self.delegate.startTokenHoldersManagement(communityId, chainId, contractAddress)
|
||||||
|
|
||||||
|
proc stopTokenHoldersManagement*(self: View) {.slot.} =
|
||||||
|
self.delegate.stopTokenHoldersManagement()
|
||||||
|
|
|
@ -373,6 +373,9 @@ proc updateRemoteDestructedAddresses*(self: SectionItem, chainId: int, contractA
|
||||||
proc setCommunityTokenOwners*(self: SectionItem, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.inline.} =
|
proc setCommunityTokenOwners*(self: SectionItem, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.inline.} =
|
||||||
self.communityTokensModel.setCommunityTokenOwners(chainId, contractAddress, owners)
|
self.communityTokensModel.setCommunityTokenOwners(chainId, contractAddress, owners)
|
||||||
|
|
||||||
|
proc setCommunityTokenHoldersLoading*(self: SectionItem, chainId: int, contractAddress: string, value: bool) {.inline.} =
|
||||||
|
self.communityTokensModel.setCommunityTokenHoldersLoading(chainId, contractAddress, value)
|
||||||
|
|
||||||
proc communityTokens*(self: SectionItem): community_tokens_model.TokenModel {.inline.} =
|
proc communityTokens*(self: SectionItem): community_tokens_model.TokenModel {.inline.} =
|
||||||
self.communityTokensModel
|
self.communityTokensModel
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ type
|
||||||
contractAddress*: string
|
contractAddress*: string
|
||||||
chainId*: int
|
chainId*: int
|
||||||
owners*: seq[CommunityCollectibleOwner]
|
owners*: seq[CommunityCollectibleOwner]
|
||||||
|
error*: string
|
||||||
|
|
||||||
type
|
type
|
||||||
CommunityTokensDetailsArgs* = ref object of Args
|
CommunityTokensDetailsArgs* = ref object of Args
|
||||||
|
@ -259,6 +260,7 @@ const SIGNAL_COMPUTE_SELF_DESTRUCT_FEE* = "communityTokens-computeSelfDestructFe
|
||||||
const SIGNAL_COMPUTE_BURN_FEE* = "communityTokens-computeBurnFee"
|
const SIGNAL_COMPUTE_BURN_FEE* = "communityTokens-computeBurnFee"
|
||||||
const SIGNAL_COMPUTE_AIRDROP_FEE* = "communityTokens-computeAirdropFee"
|
const SIGNAL_COMPUTE_AIRDROP_FEE* = "communityTokens-computeAirdropFee"
|
||||||
const SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED* = "communityTokens-communityTokenOwnersFetched"
|
const SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED* = "communityTokens-communityTokenOwnersFetched"
|
||||||
|
const SIGNAL_COMMUNITY_TOKEN_OWNERS_LOADING_FAILED* = "communityTokens-communityTokenOwnersLoadingFailed"
|
||||||
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokens-communityTokenRemoteDestructStatus"
|
const SIGNAL_REMOTE_DESTRUCT_STATUS* = "communityTokens-communityTokenRemoteDestructStatus"
|
||||||
const SIGNAL_BURN_STATUS* = "communityTokens-communityTokenBurnStatus"
|
const SIGNAL_BURN_STATUS* = "communityTokens-communityTokenBurnStatus"
|
||||||
const SIGNAL_BURN_ACTION_RECEIVED* = "communityTokens-communityTokenBurnActionReceived"
|
const SIGNAL_BURN_ACTION_RECEIVED* = "communityTokens-communityTokenBurnActionReceived"
|
||||||
|
@ -1290,17 +1292,28 @@ QtObject:
|
||||||
|
|
||||||
proc onCommunityTokenOwnersFetched*(self:Service, response: string) {.slot.} =
|
proc onCommunityTokenOwnersFetched*(self:Service, response: string) {.slot.} =
|
||||||
let responseJson = response.parseJson()
|
let responseJson = response.parseJson()
|
||||||
if responseJson{"error"}.kind != JNull and responseJson{"error"}.getStr != "":
|
|
||||||
let errorMessage = responseJson["error"].getStr
|
|
||||||
error "Can't fetch community token owners", chainId=responseJson{"chainId"}, contractAddress=responseJson{"contractAddress"}, errorMsg=errorMessage
|
|
||||||
return
|
|
||||||
let chainId = responseJson{"chainId"}.getInt
|
let chainId = responseJson{"chainId"}.getInt
|
||||||
let contractAddress = responseJson{"contractAddress"}.getStr
|
let contractAddress = responseJson{"contractAddress"}.getStr
|
||||||
let communityId = responseJson{"communityId"}.getStr
|
let communityId = responseJson{"communityId"}.getStr
|
||||||
|
|
||||||
|
try:
|
||||||
|
if responseJson{"error"}.kind != JNull and responseJson{"error"}.getStr != "":
|
||||||
|
raise newException(ValueError, responseJson["error"].getStr)
|
||||||
|
|
||||||
let communityTokenOwners = toCommunityCollectibleOwners(responseJson{"result"})
|
let communityTokenOwners = toCommunityCollectibleOwners(responseJson{"result"})
|
||||||
self.tokenOwnersCache[(chainId, contractAddress)] = communityTokenOwners
|
self.tokenOwnersCache[(chainId, contractAddress)] = communityTokenOwners
|
||||||
let data = CommunityTokenOwnersArgs(chainId: chainId, contractAddress: contractAddress, communityId: communityId, owners: communityTokenOwners)
|
let data = CommunityTokenOwnersArgs(chainId: chainId, contractAddress: contractAddress, communityId: communityId, owners: communityTokenOwners)
|
||||||
self.events.emit(SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED, data)
|
self.events.emit(SIGNAL_COMMUNITY_TOKEN_OWNERS_FETCHED, data)
|
||||||
|
except Exception as e:
|
||||||
|
error "Can't fetch community token owners", chainId=responseJson{"chainId"}, contractAddress=responseJson{"contractAddress"}, errorMsg=e.msg
|
||||||
|
|
||||||
|
let data = CommunityTokenOwnersArgs(
|
||||||
|
chainId: chainId,
|
||||||
|
contractAddress: contractAddress,
|
||||||
|
communityId: communityId,
|
||||||
|
error: e.msg,
|
||||||
|
)
|
||||||
|
self.events.emit(SIGNAL_COMMUNITY_TOKEN_OWNERS_LOADING_FAILED, data)
|
||||||
|
|
||||||
# restart token holders timer
|
# restart token holders timer
|
||||||
self.restartTokenHoldersTimer(chainId, contractAddress)
|
self.restartTokenHoldersTimer(chainId, contractAddress)
|
||||||
|
@ -1313,14 +1326,6 @@ QtObject:
|
||||||
let community = self.communityService.getCommunityById(communityId)
|
let community = self.communityService.getCommunityById(communityId)
|
||||||
return community.isPrivilegedUser()
|
return community.isPrivilegedUser()
|
||||||
|
|
||||||
# used when community members changed
|
|
||||||
proc fetchCommunityTokenOwners*(self: Service, communityId: string) =
|
|
||||||
if not self.iAmCommunityPrivilegedUser(communityId):
|
|
||||||
return
|
|
||||||
let tokens = self.getCommunityTokens(communityId)
|
|
||||||
for token in tokens:
|
|
||||||
self.fetchCommunityOwners(token)
|
|
||||||
|
|
||||||
proc getOwnerToken*(self: Service, communityId: string): CommunityTokenDto =
|
proc getOwnerToken*(self: Service, communityId: string): CommunityTokenDto =
|
||||||
let communityTokens = self.getCommunityTokens(communityId)
|
let communityTokens = self.getCommunityTokens(communityId)
|
||||||
for token in communityTokens:
|
for token in communityTokens:
|
||||||
|
|
|
@ -41,6 +41,7 @@ SplitView {
|
||||||
chainName: networksGroup.checkedButton.text
|
chainName: networksGroup.checkedButton.text
|
||||||
chainIcon: networksGroup.checkedButton.chainIcon
|
chainIcon: networksGroup.checkedButton.chainIcon
|
||||||
accountName: "helloworld"
|
accountName: "helloworld"
|
||||||
|
tokenHoldersLoading: loadingTokenHolders.checked
|
||||||
|
|
||||||
// collectible-specific properties
|
// collectible-specific properties
|
||||||
remotelyDestructState: remotelyDestructStateBox.checked
|
remotelyDestructState: remotelyDestructStateBox.checked
|
||||||
|
@ -141,6 +142,16 @@ SplitView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroupBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: loadingTokenHolders
|
||||||
|
text: "Loading Token Holders"
|
||||||
|
checked: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GroupBox {
|
GroupBox {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
|
|
@ -51,4 +51,7 @@ QtObject {
|
||||||
|
|
||||||
// Asset-specific properties:
|
// Asset-specific properties:
|
||||||
property int decimals: 2
|
property int decimals: 2
|
||||||
|
|
||||||
|
// Loading indicators
|
||||||
|
property bool tokenHoldersLoading: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1005,6 +1005,7 @@ StackView {
|
||||||
token.accountAddress: model.accountAddress
|
token.accountAddress: model.accountAddress
|
||||||
token.multiplierIndex: model.multiplierIndex
|
token.multiplierIndex: model.multiplierIndex
|
||||||
token.tokenAddress: model.tokenAddress
|
token.tokenAddress: model.tokenAddress
|
||||||
|
token.tokenHoldersLoading: model.tokenHoldersLoading
|
||||||
}
|
}
|
||||||
|
|
||||||
onCountChanged: {
|
onCountChanged: {
|
||||||
|
|
|
@ -375,7 +375,7 @@ StatusSectionLayout {
|
||||||
|
|
||||||
onRegisterBurnTokenFeesSubscriber: d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
|
onRegisterBurnTokenFeesSubscriber: d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
|
||||||
|
|
||||||
onStartTokenHoldersManagement: communityTokensStore.startTokenHoldersManagement(chainId, address)
|
onStartTokenHoldersManagement: communityTokensStore.startTokenHoldersManagement(root.community.id, chainId, address)
|
||||||
|
|
||||||
onStopTokenHoldersManagement: communityTokensStore.stopTokenHoldersManagement()
|
onStopTokenHoldersManagement: communityTokensStore.stopTokenHoldersManagement()
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ StatusScrollView {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
readonly property int iconSize: 20
|
readonly property int iconSize: 20
|
||||||
|
property bool loadingTokenHolders: false
|
||||||
|
|
||||||
readonly property var renamedTokenOwnersModel: RolesRenamingModel {
|
readonly property var renamedTokenOwnersModel: RolesRenamingModel {
|
||||||
sourceModel: root.tokenOwnersModel
|
sourceModel: root.tokenOwnersModel
|
||||||
|
@ -172,7 +173,7 @@ StatusScrollView {
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
font.pixelSize: Style.current.primaryTextFontSize
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: qsTr("Review token details before minting it as they can’t be edited later")
|
text: qsTr("Review token details before minting it as they can't be edited later")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +229,15 @@ StatusScrollView {
|
||||||
id: tokenHolderLoader
|
id: tokenHolderLoader
|
||||||
|
|
||||||
visible: !root.preview && root.deploymentCompleted
|
visible: !root.preview && root.deploymentCompleted
|
||||||
sourceComponent: isOwnerTokenItem ? tokenHolderContact : sortableTokenHolderPanel
|
sourceComponent: isOwnerTokenItem ? tokenHolderContact : (token.tokenHoldersLoading ? tokenHoldersLoadingComponent : sortableTokenHolderPanel)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: tokenHoldersLoadingComponent
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
text: qsTr("Loading token holders...")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
|
@ -7,6 +7,7 @@ QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var communityTokensModuleInst: communityTokensModule ?? null
|
property var communityTokensModuleInst: communityTokensModule ?? null
|
||||||
|
property var mainModuleInst: mainModule ?? null
|
||||||
|
|
||||||
// Network selection properties:
|
// Network selection properties:
|
||||||
property var flatNetworks: networksModule.flatNetworks
|
property var flatNetworks: networksModule.flatNetworks
|
||||||
|
@ -231,11 +232,11 @@ QtObject {
|
||||||
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
|
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
|
||||||
}
|
}
|
||||||
|
|
||||||
function startTokenHoldersManagement(chainId, contractAddress) {
|
function startTokenHoldersManagement(communityId, chainId, contractAddress) {
|
||||||
communityTokensModuleInst.startTokenHoldersManagement(chainId, contractAddress)
|
mainModuleInst.startTokenHoldersManagement(communityId, chainId, contractAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopTokenHoldersManagement() {
|
function stopTokenHoldersManagement() {
|
||||||
communityTokensModuleInst.stopTokenHoldersManagement()
|
mainModuleInst.stopTokenHoldersManagement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue