fix(@desktop/communities): Lazy loading token holders
Token holders are not fetched when application starts. They are fetched only when token details screen is opened. Fix #14974
This commit is contained in:
parent
146a6e8501
commit
a7b9a62745
|
@ -178,3 +178,9 @@ 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,3 +119,9 @@ 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")
|
|
@ -385,3 +385,9 @@ 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,3 +145,9 @@ 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()
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, Tables, chronicles, json, stint, strutils, sugar, sequtils, stew/shims/strformat
|
import NimQml, Tables, chronicles, json, stint, strutils, sugar, sequtils, stew/shims/strformat, times
|
||||||
import ../../../app/global/global_singleton
|
import ../../../app/global/global_singleton
|
||||||
import ../../../app/core/eventemitter
|
import ../../../app/core/eventemitter
|
||||||
import ../../../app/core/tasks/[qt, threadpool]
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
|
@ -287,9 +287,6 @@ QtObject:
|
||||||
communityService: community_service.Service
|
communityService: community_service.Service
|
||||||
currencyService: currency_service.Service
|
currencyService: currency_service.Service
|
||||||
|
|
||||||
tokenOwnersTimer: QTimer
|
|
||||||
tokenOwners1SecTimer: QTimer # used to update 1 sec after changes in owners
|
|
||||||
tempTokenOwnersToFetch: CommunityTokenDto # used by 1sec timer
|
|
||||||
tokenOwnersCache: Table[ContractTuple, seq[CommunityCollectibleOwner]]
|
tokenOwnersCache: Table[ContractTuple, seq[CommunityCollectibleOwner]]
|
||||||
|
|
||||||
tempFeeTable: Table[int, SuggestedFeesDto] # fees per chain, filled during gas computation, used during operation (deployment, mint, burn)
|
tempFeeTable: Table[int, SuggestedFeesDto] # fees per chain, filled during gas computation, used during operation (deployment, mint, burn)
|
||||||
|
@ -298,19 +295,26 @@ QtObject:
|
||||||
|
|
||||||
communityTokensCache: seq[CommunityTokenDto]
|
communityTokensCache: seq[CommunityTokenDto]
|
||||||
|
|
||||||
communityDataLoaded: bool
|
# keep times when token holders list for contracts were updated
|
||||||
allCommunityTokensLoaded: bool
|
tokenHoldersLastUpdateMap: Table[ContractTuple, int64]
|
||||||
|
# timer which fetches token holders
|
||||||
|
tokenHoldersTimer: QTimer
|
||||||
|
# token for which token holders are fetched
|
||||||
|
tokenHoldersToken: CommunityTokenDto
|
||||||
|
# flag to indicate that token holders management started
|
||||||
|
tokenHoldersManagementStarted: bool
|
||||||
|
|
||||||
# Forward declaration
|
# Forward declaration
|
||||||
proc getAllCommunityTokensAsync*(self: Service)
|
proc getAllCommunityTokensAsync*(self: Service)
|
||||||
proc fetchAllTokenOwners(self: Service)
|
|
||||||
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CommunityCollectibleOwner]
|
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CommunityCollectibleOwner]
|
||||||
proc getCommunityToken*(self: Service, chainId: int, address: string): CommunityTokenDto
|
proc getCommunityToken*(self: Service, chainId: int, address: string): CommunityTokenDto
|
||||||
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto
|
proc findContractByUniqueId*(self: Service, contractUniqueKey: string): CommunityTokenDto
|
||||||
|
proc restartTokenHoldersTimer(self: Service, chainId: int, contractAddress: string)
|
||||||
|
proc refreshTokenHolders(self: Service, token: CommunityTokenDto)
|
||||||
|
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
delete(self.tokenOwnersTimer)
|
delete(self.tokenHoldersTimer)
|
||||||
delete(self.tokenOwners1SecTimer)
|
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
proc newService*(
|
proc newService*(
|
||||||
|
@ -335,13 +339,10 @@ QtObject:
|
||||||
result.acService = acService
|
result.acService = acService
|
||||||
result.communityService = communityService
|
result.communityService = communityService
|
||||||
result.currencyService = currencyService
|
result.currencyService = currencyService
|
||||||
result.tokenOwnersTimer = newQTimer()
|
|
||||||
result.tokenOwnersTimer.setInterval(5*60*1000)
|
result.tokenHoldersTimer = newQTimer()
|
||||||
signalConnect(result.tokenOwnersTimer, "timeout()", result, "onRefreshTransferableTokenOwners()", 2)
|
result.tokenHoldersTimer.setSingleShot(true)
|
||||||
result.tokenOwners1SecTimer = newQTimer()
|
signalConnect(result.tokenHoldersTimer, "timeout()", result, "onTokenHoldersTimeout()", 2)
|
||||||
result.tokenOwners1SecTimer.setInterval(1000)
|
|
||||||
result.tokenOwners1SecTimer.setSingleShot(true)
|
|
||||||
signalConnect(result.tokenOwners1SecTimer, "timeout()", result, "onFetchTempTokenOwners()", 2)
|
|
||||||
|
|
||||||
# cache functions
|
# cache functions
|
||||||
proc updateCommunityTokenCache(self: Service, chainId: int, address: string, tokenToUpdate: CommunityTokenDto) =
|
proc updateCommunityTokenCache(self: Service, chainId: int, address: string, tokenToUpdate: CommunityTokenDto) =
|
||||||
|
@ -507,8 +508,7 @@ QtObject:
|
||||||
|
|
||||||
# update owners list if airdrop was successfull
|
# update owners list if airdrop was successfull
|
||||||
if signalArgs.success:
|
if signalArgs.success:
|
||||||
self.tempTokenOwnersToFetch = signalArgs.communityToken
|
self.refreshTokenHolders(signalArgs.communityToken)
|
||||||
self.tokenOwners1SecTimer.start()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error processing airdrop pending transaction event", msg=e.msg
|
error "Error processing airdrop pending transaction event", msg=e.msg
|
||||||
|
|
||||||
|
@ -520,8 +520,7 @@ QtObject:
|
||||||
|
|
||||||
# update owners list if remote destruct was successfull
|
# update owners list if remote destruct was successfull
|
||||||
if signalArgs.success:
|
if signalArgs.success:
|
||||||
self.tempTokenOwnersToFetch = signalArgs.communityToken
|
self.refreshTokenHolders(signalArgs.communityToken)
|
||||||
self.tokenOwners1SecTimer.start()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error processing collectible self destruct pending transaction event", msg=e.msg
|
error "Error processing collectible self destruct pending transaction event", msg=e.msg
|
||||||
|
|
||||||
|
@ -574,24 +573,16 @@ QtObject:
|
||||||
proc processCommunityTokenAction(self: Service, signalArgs: CommunityTokenActionSignal) =
|
proc processCommunityTokenAction(self: Service, signalArgs: CommunityTokenActionSignal) =
|
||||||
case signalArgs.actionType
|
case signalArgs.actionType
|
||||||
of CommunityTokenActionType.Airdrop:
|
of CommunityTokenActionType.Airdrop:
|
||||||
self.tempTokenOwnersToFetch = signalArgs.communityToken
|
self.refreshTokenHolders(signalArgs.communityToken)
|
||||||
self.tokenOwners1SecTimer.start()
|
|
||||||
of CommunityTokenActionType.Burn:
|
of CommunityTokenActionType.Burn:
|
||||||
self.updateCommunityTokenCache(signalArgs.communityToken.chainId, signalArgs.communityToken.address, signalArgs.communityToken)
|
self.updateCommunityTokenCache(signalArgs.communityToken.chainId, signalArgs.communityToken.address, signalArgs.communityToken)
|
||||||
let data = RemoteDestructArgs(communityToken: signalArgs.communityToken)
|
let data = RemoteDestructArgs(communityToken: signalArgs.communityToken)
|
||||||
self.events.emit(SIGNAL_BURN_ACTION_RECEIVED, data)
|
self.events.emit(SIGNAL_BURN_ACTION_RECEIVED, data)
|
||||||
of CommunityTokenActionType.RemoteDestruct:
|
of CommunityTokenActionType.RemoteDestruct:
|
||||||
self.tempTokenOwnersToFetch = signalArgs.communityToken
|
self.refreshTokenHolders(signalArgs.communityToken)
|
||||||
self.tokenOwners1SecTimer.start()
|
|
||||||
else:
|
else:
|
||||||
warn "Unknown token action", actionType=signalArgs.actionType
|
warn "Unknown token action", actionType=signalArgs.actionType
|
||||||
|
|
||||||
proc tryFetchOwners(self: Service) =
|
|
||||||
# both communities and tokens should be loaded
|
|
||||||
if self.allCommunityTokensLoaded and self.communityDataLoaded:
|
|
||||||
self.fetchAllTokenOwners()
|
|
||||||
self.tokenOwnersTimer.start()
|
|
||||||
|
|
||||||
proc init*(self: Service) =
|
proc init*(self: Service) =
|
||||||
self.getAllCommunityTokensAsync()
|
self.getAllCommunityTokensAsync()
|
||||||
|
|
||||||
|
@ -602,10 +593,6 @@ QtObject:
|
||||||
elif data.eventType == tokens_backend.eventCommunityTokenReceived:
|
elif data.eventType == tokens_backend.eventCommunityTokenReceived:
|
||||||
self.processReceivedCommunityTokenWalletEvent(data.message, data.accounts)
|
self.processReceivedCommunityTokenWalletEvent(data.message, data.accounts)
|
||||||
|
|
||||||
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
|
|
||||||
self.communityDataLoaded = true
|
|
||||||
self.tryFetchOwners()
|
|
||||||
|
|
||||||
self.events.on(SignalType.CommunityTokenAction.event) do(e:Args):
|
self.events.on(SignalType.CommunityTokenAction.event) do(e:Args):
|
||||||
let receivedData = CommunityTokenActionSignal(e)
|
let receivedData = CommunityTokenActionSignal(e)
|
||||||
self.processCommunityTokenAction(receivedData)
|
self.processCommunityTokenAction(receivedData)
|
||||||
|
@ -753,8 +740,6 @@ QtObject:
|
||||||
self.communityTokensCache = map(responseJson["response"]["result"].getElems(),
|
self.communityTokensCache = map(responseJson["response"]["result"].getElems(),
|
||||||
proc(x: JsonNode): CommunityTokenDto = x.toCommunityTokenDto())
|
proc(x: JsonNode): CommunityTokenDto = x.toCommunityTokenDto())
|
||||||
|
|
||||||
self.allCommunityTokensLoaded = true
|
|
||||||
self.tryFetchOwners()
|
|
||||||
except RpcException as e:
|
except RpcException as e:
|
||||||
error "Error getting all community tokens async", message = e.msg
|
error "Error getting all community tokens async", message = e.msg
|
||||||
|
|
||||||
|
@ -1315,6 +1300,9 @@ QtObject:
|
||||||
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)
|
||||||
|
|
||||||
|
# restart token holders timer
|
||||||
|
self.restartTokenHoldersTimer(chainId, contractAddress)
|
||||||
|
|
||||||
# get owners from cache
|
# get owners from cache
|
||||||
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CommunityCollectibleOwner] =
|
proc getCommunityTokenOwners*(self: Service, communityId: string, chainId: int, contractAddress: string): seq[CommunityCollectibleOwner] =
|
||||||
return self.tokenOwnersCache.getOrDefault((chainId: chainId, address: contractAddress))
|
return self.tokenOwnersCache.getOrDefault((chainId: chainId, address: contractAddress))
|
||||||
|
@ -1323,25 +1311,6 @@ QtObject:
|
||||||
let community = self.communityService.getCommunityById(communityId)
|
let community = self.communityService.getCommunityById(communityId)
|
||||||
return community.isPrivilegedUser()
|
return community.isPrivilegedUser()
|
||||||
|
|
||||||
# update in 5 minute intervals, only transferable tokens
|
|
||||||
proc onRefreshTransferableTokenOwners*(self:Service) {.slot.} =
|
|
||||||
let allTokens = self.getAllCommunityTokens()
|
|
||||||
for token in allTokens:
|
|
||||||
if token.transferable and self.iAmCommunityPrivilegedUser(token.communityId):
|
|
||||||
self.fetchCommunityOwners(token)
|
|
||||||
|
|
||||||
# used after airdrop or remote destruct
|
|
||||||
proc onFetchTempTokenOwners*(self: Service) {.slot.} =
|
|
||||||
self.fetchCommunityOwners(self.tempTokenOwnersToFetch)
|
|
||||||
|
|
||||||
# used in init
|
|
||||||
proc fetchAllTokenOwners(self: Service) =
|
|
||||||
let allTokens = self.getAllCommunityTokens()
|
|
||||||
for token in allTokens:
|
|
||||||
if not self.iAmCommunityPrivilegedUser(token.communityId):
|
|
||||||
continue
|
|
||||||
self.fetchCommunityOwners(token)
|
|
||||||
|
|
||||||
# used when community members changed
|
# used when community members changed
|
||||||
proc fetchCommunityTokenOwners*(self: Service, communityId: string) =
|
proc fetchCommunityTokenOwners*(self: Service, communityId: string) =
|
||||||
if not self.iAmCommunityPrivilegedUser(communityId):
|
if not self.iAmCommunityPrivilegedUser(communityId):
|
||||||
|
@ -1409,3 +1378,59 @@ QtObject:
|
||||||
discard tokens_backend.reTrackOwnerTokenDeploymentTransaction(chainId, contractAddress)
|
discard tokens_backend.reTrackOwnerTokenDeploymentTransaction(chainId, contractAddress)
|
||||||
except Exception:
|
except Exception:
|
||||||
error "can't retrack token transaction", message = getCurrentExceptionMsg()
|
error "can't retrack token transaction", message = getCurrentExceptionMsg()
|
||||||
|
|
||||||
|
# ran also when holders are fetched
|
||||||
|
proc restartTokenHoldersTimer(self: Service, chainId: int, contractAddress: string) =
|
||||||
|
if not self.tokenHoldersManagementStarted:
|
||||||
|
return
|
||||||
|
self.tokenHoldersTimer.stop()
|
||||||
|
|
||||||
|
let tokenTupleKey = (chainId: chainId, address: contractAddress)
|
||||||
|
var nextTimerShotInSeconds = int64(0)
|
||||||
|
if self.tokenHoldersLastUpdateMap.hasKey(tokenTupleKey):
|
||||||
|
let lastUpdateTime = self.tokenHoldersLastUpdateMap[tokenTupleKey]
|
||||||
|
const intervalInSecs = int64(5*60)
|
||||||
|
let nowInSeconds = now().toTime().toUnix()
|
||||||
|
nextTimerShotInSeconds = intervalInSecs - (nowInSeconds - lastUpdateTime)
|
||||||
|
if nextTimerShotInSeconds < 0:
|
||||||
|
nextTimerShotInSeconds = 0
|
||||||
|
|
||||||
|
self.tokenHoldersTimer.setInterval(int(nextTimerShotInSeconds * 1000))
|
||||||
|
self.tokenHoldersTimer.start()
|
||||||
|
|
||||||
|
# executed when Token page with holders is opened
|
||||||
|
proc startTokenHoldersManagement*(self: Service, chainId: int, contractAddress: string) =
|
||||||
|
let communityToken = self.getCommunityToken(chainId, contractAddress)
|
||||||
|
if not self.iAmCommunityPrivilegedUser(communityToken.communityId):
|
||||||
|
warn "can't get token holders - not privileged user"
|
||||||
|
return
|
||||||
|
|
||||||
|
self.tokenHoldersToken = communityToken
|
||||||
|
self.tokenHoldersManagementStarted = true
|
||||||
|
self.restartTokenHoldersTimer(chainId, contractAddress)
|
||||||
|
|
||||||
|
# executed when Token page with holders is closed
|
||||||
|
proc stopTokenHoldersManagement*(self: Service) =
|
||||||
|
self.tokenHoldersManagementStarted = false
|
||||||
|
self.tokenHoldersTimer.stop()
|
||||||
|
|
||||||
|
proc onTokenHoldersTimeout(self: Service) {.slot.} =
|
||||||
|
# update last fetch time
|
||||||
|
let tokenTupleKey = (chainId: self.tokenHoldersToken.chainId, address: self.tokenHoldersToken.address)
|
||||||
|
let nowInSeconds = now().toTime().toUnix()
|
||||||
|
self.tokenHoldersLastUpdateMap[tokenTupleKey] = nowInSeconds
|
||||||
|
# run async calls to fetch holders
|
||||||
|
self.fetchCommunityOwners(self.tokenHoldersToken)
|
||||||
|
|
||||||
|
# executed when there was some change and holders needs to be fetched again
|
||||||
|
proc refreshTokenHolders(self: Service, token: CommunityTokenDto) =
|
||||||
|
let tokenTupleKey = (chainId: token.chainId, address: token.address)
|
||||||
|
self.tokenHoldersLastUpdateMap.del(tokenTupleKey)
|
||||||
|
if not self.tokenHoldersManagementStarted:
|
||||||
|
# not need to get holders now
|
||||||
|
return
|
||||||
|
let holdersTokenTuple = (chainId: self.tokenHoldersToken.chainId, address: self.tokenHoldersToken.address)
|
||||||
|
if (tokenTupleKey != holdersTokenTuple):
|
||||||
|
# different token is opened now
|
||||||
|
return
|
||||||
|
self.restartTokenHoldersTimer(token.chainId, token.address)
|
|
@ -79,6 +79,9 @@ StackView {
|
||||||
signal registerSelfDestructFeesSubscriber(var feeSubscriber)
|
signal registerSelfDestructFeesSubscriber(var feeSubscriber)
|
||||||
signal registerBurnTokenFeesSubscriber(var feeSubscriber)
|
signal registerBurnTokenFeesSubscriber(var feeSubscriber)
|
||||||
|
|
||||||
|
signal startTokenHoldersManagement(int chainId, string address)
|
||||||
|
signal stopTokenHoldersManagement()
|
||||||
|
|
||||||
function navigateBack() {
|
function navigateBack() {
|
||||||
pop(StackView.Immediate)
|
pop(StackView.Immediate)
|
||||||
}
|
}
|
||||||
|
@ -541,6 +544,9 @@ StackView {
|
||||||
tokenOwnersModel: tokenViewPage.tokenOwnersModel
|
tokenOwnersModel: tokenViewPage.tokenOwnersModel
|
||||||
isOwnerTokenItem: tokenViewPage.isOwnerTokenItem
|
isOwnerTokenItem: tokenViewPage.isOwnerTokenItem
|
||||||
|
|
||||||
|
onStartTokenHoldersManagement: root.startTokenHoldersManagement(chainId, address)
|
||||||
|
onStopTokenHoldersManagement: root.stopTokenHoldersManagement()
|
||||||
|
|
||||||
onGeneralAirdropRequested: {
|
onGeneralAirdropRequested: {
|
||||||
root.airdropToken(view.airdropKey,
|
root.airdropToken(view.airdropKey,
|
||||||
"1" + "0".repeat(view.token.multiplierIndex),
|
"1" + "0".repeat(view.token.multiplierIndex),
|
||||||
|
|
|
@ -368,6 +368,10 @@ StatusSectionLayout {
|
||||||
|
|
||||||
onRegisterBurnTokenFeesSubscriber: d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
|
onRegisterBurnTokenFeesSubscriber: d.feesBroker.registerBurnFeesSubscriber(feeSubscriber)
|
||||||
|
|
||||||
|
onStartTokenHoldersManagement: communityTokensStore.startTokenHoldersManagement(chainId, address)
|
||||||
|
|
||||||
|
onStopTokenHoldersManagement: communityTokensStore.stopTokenHoldersManagement()
|
||||||
|
|
||||||
onMintCollectible:
|
onMintCollectible:
|
||||||
communityTokensStore.deployCollectible(
|
communityTokensStore.deployCollectible(
|
||||||
root.community.id, collectibleItem)
|
root.community.id, collectibleItem)
|
||||||
|
|
|
@ -78,6 +78,20 @@ StatusScrollView {
|
||||||
signal kickRequested(string name, string contactId, string address)
|
signal kickRequested(string name, string contactId, string address)
|
||||||
signal banRequested(string name, string contactId, string address)
|
signal banRequested(string name, string contactId, string address)
|
||||||
|
|
||||||
|
signal startTokenHoldersManagement(int chainId, string address)
|
||||||
|
signal stopTokenHoldersManagement()
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
root.startTokenHoldersManagement(root.chainId, root.token.tokenAddress)
|
||||||
|
} else {
|
||||||
|
root.stopTokenHoldersManagement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: root.startTokenHoldersManagement(root.chainId, root.token.tokenAddress)
|
||||||
|
Component.onDestruction: root.stopTokenHoldersManagement()
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
|
|
@ -220,4 +220,12 @@ QtObject {
|
||||||
function asyncGetOwnerTokenDetails(communityId) {
|
function asyncGetOwnerTokenDetails(communityId) {
|
||||||
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
|
communityTokensModuleInst.asyncGetOwnerTokenDetails(communityId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startTokenHoldersManagement(chainId, contractAddress) {
|
||||||
|
communityTokensModuleInst.startTokenHoldersManagement(chainId, contractAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopTokenHoldersManagement() {
|
||||||
|
communityTokensModuleInst.stopTokenHoldersManagement()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue