feat(airdrop): get revealed accounts using new API instead of desc
Fixes #11817 Instead of getting revealed accounts from the community description (it's no longer available), uses the new `getRevealedAccountsForAllMembers` API. Uses it async so that we do not slow the start process. The model is updated correctly when we finish loading them.
This commit is contained in:
parent
9e89bd4f1a
commit
24d26cc038
|
@ -133,7 +133,6 @@ proc addChatMember(self: Module, member: ChatMember) =
|
||||||
memberRole = member.role,
|
memberRole = member.role,
|
||||||
joined = member.joined,
|
joined = member.joined,
|
||||||
isUntrustworthy = contactDetails.dto.trustStatus == TrustStatus.Untrustworthy,
|
isUntrustworthy = contactDetails.dto.trustStatus == TrustStatus.Untrustworthy,
|
||||||
airdropAddress = member.airdropAccount.address,
|
|
||||||
))
|
))
|
||||||
|
|
||||||
method onChatMembersAdded*(self: Module, ids: seq[string]) =
|
method onChatMembersAdded*(self: Module, ids: seq[string]) =
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import chronicles, stint
|
import chronicles, stint, tables
|
||||||
import ../../global/app_sections_config as conf
|
import ../../global/app_sections_config as conf
|
||||||
import ../../global/global_singleton
|
import ../../global/global_singleton
|
||||||
import ../../global/app_signals
|
import ../../global/app_signals
|
||||||
|
@ -248,6 +248,10 @@ proc init*(self: Controller) =
|
||||||
let args = CommunityArgs(e)
|
let args = CommunityArgs(e)
|
||||||
self.delegate.communityEdited(args.community)
|
self.delegate.communityEdited(args.community)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_COMMUNITY_MEMBERS_REVEALED_ACCOUNTS_LOADED) do(e:Args):
|
||||||
|
let args = CommunityMembersRevealedAccountsArgs(e)
|
||||||
|
self.delegate.communityMembersRevealedAccountsLoaded(args.communityId, args.membersRevealedAccounts)
|
||||||
|
|
||||||
self.events.on(SIGNAL_COMMUNITY_PRIVATE_KEY_REMOVED) do(e:Args):
|
self.events.on(SIGNAL_COMMUNITY_PRIVATE_KEY_REMOVED) do(e:Args):
|
||||||
let args = CommunityArgs(e)
|
let args = CommunityArgs(e)
|
||||||
self.delegate.communityEdited(args.community)
|
self.delegate.communityEdited(args.community)
|
||||||
|
@ -524,3 +528,6 @@ proc getColorHash*(self: Controller, pubkey: string): ColorHashDto =
|
||||||
|
|
||||||
proc getColorId*(self: Controller, pubkey: string): int =
|
proc getColorId*(self: Controller, pubkey: string): int =
|
||||||
procs_from_visual_identity_service.colorIdOf(pubkey)
|
procs_from_visual_identity_service.colorIdOf(pubkey)
|
||||||
|
|
||||||
|
proc asyncGetRevealedAccountsForAllMembers*(self: Controller, communityId: string) =
|
||||||
|
self.communityService.asyncGetRevealedAccountsForAllMembers(communityId)
|
||||||
|
|
|
@ -330,6 +330,9 @@ method windowActivated*(self: AccessInterface) {.base.} =
|
||||||
method windowDeactivated*(self: AccessInterface) {.base.} =
|
method windowDeactivated*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method communityMembersRevealedAccountsLoaded*(self: AccessInterface, communityId: string, membersRevealedAccounts: MembersRevealedAccounts) {.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
|
||||||
|
|
|
@ -262,6 +262,11 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
||||||
communityTokensItems = communityTokens.map(proc(tokenDto: CommunityTokenDto): TokenItem =
|
communityTokensItems = communityTokens.map(proc(tokenDto: CommunityTokenDto): TokenItem =
|
||||||
result = self.createTokenItem(tokenDto)
|
result = self.createTokenItem(tokenDto)
|
||||||
)
|
)
|
||||||
|
# Get community members' revealed accounts
|
||||||
|
# We will update the model later when we finish loading the accounts
|
||||||
|
# TODO add TokenMaster here too when it's available
|
||||||
|
if communityDetails.memberRole == MemberRole.Owner:
|
||||||
|
self.controller.asyncGetRevealedAccountsForAllMembers(channelGroup.id)
|
||||||
|
|
||||||
let unviewedCount = channelGroup.unviewedMessagesCount
|
let unviewedCount = channelGroup.unviewedMessagesCount
|
||||||
let notificationsCount = channelGroup.unviewedMentionsCount
|
let notificationsCount = channelGroup.unviewedMentionsCount
|
||||||
|
@ -312,7 +317,6 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
||||||
isContact = contactDetails.dto.isContact,
|
isContact = contactDetails.dto.isContact,
|
||||||
isVerified = contactDetails.dto.isContactVerified(),
|
isVerified = contactDetails.dto.isContactVerified(),
|
||||||
memberRole = member.role,
|
memberRole = member.role,
|
||||||
airdropAddress = member.airdropAccount.address,
|
|
||||||
membershipRequestState = MembershipRequestState.Accepted
|
membershipRequestState = MembershipRequestState.Accepted
|
||||||
)),
|
)),
|
||||||
# pendingRequestsToJoin
|
# pendingRequestsToJoin
|
||||||
|
@ -1305,3 +1309,13 @@ method windowActivated*[T](self: Module[T]) =
|
||||||
method windowDeactivated*[T](self: Module[T]) =
|
method windowDeactivated*[T](self: Module[T]) =
|
||||||
self.controller.speedupArchivesImport()
|
self.controller.speedupArchivesImport()
|
||||||
|
|
||||||
|
method communityMembersRevealedAccountsLoaded*[T](self: Module[T], communityId: string, membersRevealedAccounts: MembersRevealedAccounts) =
|
||||||
|
var communityMembersAirdropAddress: Table[string, string]
|
||||||
|
for pubkey, revealedAccounts in membersRevealedAccounts.pairs:
|
||||||
|
for revealedAccount in revealedAccounts:
|
||||||
|
if revealedAccount.isAirdropAddress:
|
||||||
|
communityMembersAirdropAddress[pubkey] = revealedAccount.address
|
||||||
|
discard
|
||||||
|
|
||||||
|
self.view.model.setMembersAirdropAddress(communityId, communityMembersAirdropAddress)
|
||||||
|
|
||||||
|
|
|
@ -298,19 +298,33 @@ QtObject:
|
||||||
ModelRole.IsUntrustworthy.int,
|
ModelRole.IsUntrustworthy.int,
|
||||||
])
|
])
|
||||||
|
|
||||||
proc setOnlineStatus*(self: Model, pubKey: string,
|
proc setOnlineStatus*(self: Model, pubKey: string, onlineStatus: OnlineStatus) =
|
||||||
onlineStatus: OnlineStatus) =
|
let idx = self.findIndexForMember(pubKey)
|
||||||
let ind = self.findIndexForMember(pubKey)
|
if(idx == -1):
|
||||||
if(ind == -1):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if(self.items[ind].onlineStatus == onlineStatus):
|
if(self.items[idx].onlineStatus == onlineStatus):
|
||||||
return
|
return
|
||||||
|
|
||||||
var item = self.items[ind]
|
self.items[idx].onlineStatus = onlineStatus
|
||||||
item.onlineStatus = onlineStatus
|
let index = self.createIndex(idx, 0, nil)
|
||||||
self.removeItemWithIndex(ind)
|
self.dataChanged(index, index, @[
|
||||||
self.addItem(item)
|
ModelRole.OnlineStatus.int
|
||||||
|
])
|
||||||
|
|
||||||
|
proc setAirdropAddress*(self: Model, pubKey: string, airdropAddress: string) =
|
||||||
|
let idx = self.findIndexForMember(pubKey)
|
||||||
|
if(idx == -1):
|
||||||
|
return
|
||||||
|
|
||||||
|
if(self.items[idx].airdropAddress == airdropAddress):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.items[idx].airdropAddress = airdropAddress
|
||||||
|
let index = self.createIndex(idx, 0, nil)
|
||||||
|
self.dataChanged(index, index, @[
|
||||||
|
ModelRole.AirdropAddress.int
|
||||||
|
])
|
||||||
|
|
||||||
# TODO: rename me to removeItemByPubkey
|
# TODO: rename me to removeItemByPubkey
|
||||||
proc removeItemById*(self: Model, pubKey: string) =
|
proc removeItemById*(self: Model, pubKey: string) =
|
||||||
|
|
|
@ -446,3 +446,12 @@ QtObject:
|
||||||
"encrypted": item.encrypted,
|
"encrypted": item.encrypted,
|
||||||
}
|
}
|
||||||
return $jsonObj
|
return $jsonObj
|
||||||
|
|
||||||
|
proc setMembersAirdropAddress*(self: SectionModel, id: string, communityMembersAirdropAddress: Table[string, string]) =
|
||||||
|
let index = self.getItemIndex(id)
|
||||||
|
if (index == -1):
|
||||||
|
return
|
||||||
|
|
||||||
|
for pubkey, revealedAccounts in communityMembersAirdropAddress.pairs:
|
||||||
|
self.items[index].members.setAirdropAddress(pubkey, revealedAccounts)
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,10 @@ type
|
||||||
large*: string
|
large*: string
|
||||||
banner*: string
|
banner*: string
|
||||||
|
|
||||||
type RevealedAccount* = object
|
|
||||||
address*: string
|
|
||||||
chainIds*: seq[int]
|
|
||||||
isAirdropAddress*: bool
|
|
||||||
|
|
||||||
type ChatMember* = object
|
type ChatMember* = object
|
||||||
id*: string
|
id*: string
|
||||||
joined*: bool
|
joined*: bool
|
||||||
role*: MemberRole
|
role*: MemberRole
|
||||||
airdropAccount*: RevealedAccount
|
|
||||||
|
|
||||||
type CheckPermissionsResultDto* = object
|
type CheckPermissionsResultDto* = object
|
||||||
criteria*: seq[bool]
|
criteria*: seq[bool]
|
||||||
|
@ -243,22 +237,6 @@ proc toChannelMember*(jsonObj: JsonNode, memberId: string, joined: bool): ChatMe
|
||||||
for roleObj in rolesObj:
|
for roleObj in rolesObj:
|
||||||
roles.add(roleObj.getInt)
|
roles.add(roleObj.getInt)
|
||||||
|
|
||||||
var revealedAccountsObj: JsonNode
|
|
||||||
if jsonObj.getProp("revealed_accounts", revealedAccountsObj):
|
|
||||||
for revealedAccountObj in revealedAccountsObj:
|
|
||||||
if revealedAccountObj{"isAirdropAddress"}.getBool:
|
|
||||||
var chainIdsObj: JsonNode
|
|
||||||
var chainIds: seq[int] = @[]
|
|
||||||
if revealedAccountObj.getProp("chain_ids", chainIdsObj):
|
|
||||||
for chainIdObj in chainIdsObj:
|
|
||||||
chainIds.add(chainIdObj.getInt)
|
|
||||||
|
|
||||||
result.airdropAccount = RevealedAccount(
|
|
||||||
address: revealedAccountObj["address"].getStr,
|
|
||||||
chainIds: chainIds,
|
|
||||||
isAirdropAddress: true,
|
|
||||||
)
|
|
||||||
|
|
||||||
result.role = MemberRole.None
|
result.role = MemberRole.None
|
||||||
if roles.contains(MemberRole.Owner.int):
|
if roles.contains(MemberRole.Owner.int):
|
||||||
result.role = MemberRole.Owner
|
result.role = MemberRole.Owner
|
||||||
|
|
|
@ -185,3 +185,22 @@ const asyncImportCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcal
|
||||||
arg.finish(%* {
|
arg.finish(%* {
|
||||||
"error": e.msg,
|
"error": e.msg,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncGetRevealedAccountsForAllMembersArg = ref object of QObjectTaskArg
|
||||||
|
communityId: string
|
||||||
|
|
||||||
|
const asyncGetRevealedAccountsForAllMembersTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncGetRevealedAccountsForAllMembersArg](argEncoded)
|
||||||
|
try:
|
||||||
|
let response = status_go.getRevealedAccountsForAllMembers(arg.communityId)
|
||||||
|
arg.finish(%* {
|
||||||
|
"communityId": arg.communityId,
|
||||||
|
"response": response,
|
||||||
|
"error": "",
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
arg.finish(%* {
|
||||||
|
"communityId": arg.communityId,
|
||||||
|
"error": e.msg,
|
||||||
|
})
|
||||||
|
|
|
@ -106,6 +106,13 @@ type CommunityMetricsDto* = object
|
||||||
metricsType*: CommunityMetricsType
|
metricsType*: CommunityMetricsType
|
||||||
intervals*: seq[MetricsIntervalDto]
|
intervals*: seq[MetricsIntervalDto]
|
||||||
|
|
||||||
|
type RevealedAccount* = object
|
||||||
|
address*: string
|
||||||
|
chainIds*: seq[int]
|
||||||
|
isAirdropAddress*: bool
|
||||||
|
|
||||||
|
type MembersRevealedAccounts* = Table[string, seq[RevealedAccount]]
|
||||||
|
|
||||||
type CommunityDto* = object
|
type CommunityDto* = object
|
||||||
id*: string
|
id*: string
|
||||||
memberRole*: MemberRole
|
memberRole*: MemberRole
|
||||||
|
@ -524,3 +531,26 @@ proc parseDiscordChannels*(response: JsonNode): seq[DiscordChannelDto] =
|
||||||
if (response["discordChannels"].kind == JArray):
|
if (response["discordChannels"].kind == JArray):
|
||||||
for channel in response["discordChannels"].items():
|
for channel in response["discordChannels"].items():
|
||||||
result.add(channel.toDiscordChannelDto())
|
result.add(channel.toDiscordChannelDto())
|
||||||
|
|
||||||
|
proc toRevealedAccount*(revealedAccountObj: JsonNode): RevealedAccount =
|
||||||
|
var chainIdsObj: JsonNode
|
||||||
|
var chainIds: seq[int] = @[]
|
||||||
|
if revealedAccountObj.getProp("chain_ids", chainIdsObj):
|
||||||
|
for chainIdObj in chainIdsObj:
|
||||||
|
chainIds.add(chainIdObj.getInt)
|
||||||
|
|
||||||
|
result = RevealedAccount(
|
||||||
|
address: revealedAccountObj["address"].getStr,
|
||||||
|
chainIds: chainIds,
|
||||||
|
isAirdropAddress: revealedAccountObj{"isAirdropAddress"}.getBool,
|
||||||
|
)
|
||||||
|
|
||||||
|
proc toRevealedAccounts*(revealedAccountsObj: JsonNode): seq[RevealedAccount] =
|
||||||
|
result = @[]
|
||||||
|
for revealedAccountObj in revealedAccountsObj:
|
||||||
|
result.add(revealedAccountObj.toRevealedAccount())
|
||||||
|
|
||||||
|
proc toMembersRevealedAccounts*(membersRevealedAccountsObj: JsonNode): MembersRevealedAccounts =
|
||||||
|
result = initTable[string, seq[RevealedAccount]]()
|
||||||
|
for (pubkey, revealedAccountsObj) in membersRevealedAccountsObj.pairs:
|
||||||
|
result[pubkey] = revealedAccountsObj.toRevealedAccounts()
|
|
@ -125,6 +125,10 @@ type
|
||||||
communityId*: string
|
communityId*: string
|
||||||
metricsType*: CommunityMetricsType
|
metricsType*: CommunityMetricsType
|
||||||
|
|
||||||
|
CommunityMembersRevealedAccountsArgs* = ref object of Args
|
||||||
|
communityId*: string
|
||||||
|
membersRevealedAccounts*: MembersRevealedAccounts
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
|
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
|
||||||
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
|
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
|
||||||
|
@ -133,6 +137,7 @@ const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded"
|
||||||
const SIGNAL_COMMUNITY_MY_REQUEST_FAILED* = "communityMyRequestFailed"
|
const SIGNAL_COMMUNITY_MY_REQUEST_FAILED* = "communityMyRequestFailed"
|
||||||
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_SUCCEEDED* = "communityEditSharedAddressesSucceded"
|
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_SUCCEEDED* = "communityEditSharedAddressesSucceded"
|
||||||
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED* = "communityEditSharedAddressesFailed"
|
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED* = "communityEditSharedAddressesFailed"
|
||||||
|
const SIGNAL_COMMUNITY_MEMBERS_REVEALED_ACCOUNTS_LOADED* = "communityMembersRevealedAccountsLoaded"
|
||||||
const SIGNAL_COMMUNITY_LEFT* = "communityLeft"
|
const SIGNAL_COMMUNITY_LEFT* = "communityLeft"
|
||||||
const SIGNAL_COMMUNITY_CREATED* = "communityCreated"
|
const SIGNAL_COMMUNITY_CREATED* = "communityCreated"
|
||||||
const SIGNAL_COMMUNITY_ADDED* = "communityAdded"
|
const SIGNAL_COMMUNITY_ADDED* = "communityAdded"
|
||||||
|
@ -2011,3 +2016,32 @@ QtObject:
|
||||||
result = response.result.getStr
|
result = response.result.getStr
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "error while getting community public key", msg = e.msg
|
error "error while getting community public key", msg = e.msg
|
||||||
|
|
||||||
|
proc asyncGetRevealedAccountsForAllMembers*(self: Service, communityId: string) =
|
||||||
|
let arg = AsyncGetRevealedAccountsForAllMembersArg(
|
||||||
|
tptr: cast[ByteAddress](asyncGetRevealedAccountsForAllMembersTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onAsyncGetRevealedAccountsForAllMembersCompleted",
|
||||||
|
communityId: communityId,
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc onAsyncGetRevealedAccountsForAllMembersCompleted*(self: Service, response: string) {.slot.} =
|
||||||
|
try:
|
||||||
|
let rpcResponseObj = response.parseJson
|
||||||
|
|
||||||
|
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
|
||||||
|
raise newException(RpcException, rpcResponseObj["error"].getStr)
|
||||||
|
|
||||||
|
if rpcResponseObj["response"]{"error"}.kind != JNull:
|
||||||
|
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
|
||||||
|
raise newException(RpcException, error.message)
|
||||||
|
|
||||||
|
let revealedAccounts = rpcResponseObj["response"]["result"].toMembersRevealedAccounts
|
||||||
|
|
||||||
|
self.events.emit(SIGNAL_COMMUNITY_MEMBERS_REVEALED_ACCOUNTS_LOADED, CommunityMembersRevealedAccountsArgs(
|
||||||
|
communityId: rpcResponseObj["communityId"].getStr,
|
||||||
|
membersRevealedAccounts: revealedAccounts
|
||||||
|
))
|
||||||
|
except Exception as e:
|
||||||
|
error "error while getting the community members' revealed addressesses", msg = e.msg
|
||||||
|
|
|
@ -61,6 +61,17 @@ proc editSharedAddresses*(
|
||||||
"airdropAddress": airdropAddress,
|
"airdropAddress": airdropAddress,
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
proc getRevealedAccountsForMember*(
|
||||||
|
communityId: string,
|
||||||
|
memberPubkey: string,
|
||||||
|
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
result = callPrivateRPC("getRevealedAccounts".prefix, %*[communityId, memberPubkey])
|
||||||
|
|
||||||
|
proc getRevealedAccountsForAllMembers*(
|
||||||
|
communityId: string,
|
||||||
|
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
result = callPrivateRPC("getRevealedAccountsForAllMembers".prefix, %*[communityId])
|
||||||
|
|
||||||
proc checkPermissionsToJoinCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc checkPermissionsToJoinCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
result = callPrivateRPC("checkPermissionsToJoinCommunity".prefix, %*[{
|
result = callPrivateRPC("checkPermissionsToJoinCommunity".prefix, %*[{
|
||||||
"communityId": communityId
|
"communityId": communityId
|
||||||
|
|
|
@ -504,14 +504,7 @@ StatusSectionLayout {
|
||||||
|
|
||||||
assetsModel: assetsModelLoader.item
|
assetsModel: assetsModelLoader.item
|
||||||
collectiblesModel: collectiblesModelLoader.item
|
collectiblesModel: collectiblesModelLoader.item
|
||||||
membersModel: {
|
membersModel: community.members
|
||||||
const chatContentModule = root.rootStore.currentChatContentModule()
|
|
||||||
if (!chatContentModule || !chatContentModule.usersModule) {
|
|
||||||
// New communities have no chats, so no chatContentModule
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return chatContentModule.usersModule.model
|
|
||||||
}
|
|
||||||
|
|
||||||
accountsModel: SortFilterProxyModel {
|
accountsModel: SortFilterProxyModel {
|
||||||
sourceModel: root.rootStore.accounts
|
sourceModel: root.rootStore.accounts
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a63e417f9f6c779300f35b51998770742f5e363f
|
Subproject commit b4b0d26aa4c3f11ee66e3aeb404834cd8c5e48c8
|
Loading…
Reference in New Issue