feat(savedaddresses): display various cards if an address user is trying to save is known
Closes: #13280
This commit is contained in:
parent
aaa9937124
commit
bbaafa8954
|
@ -251,7 +251,8 @@ method getCommunitySectionModule*(self: AccessInterface, communityId: string): Q
|
||||||
method getAppSearchModule*(self: AccessInterface): QVariant {.base.} =
|
method getAppSearchModule*(self: AccessInterface): QVariant {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getContactDetailsAsJson*(self: AccessInterface, publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool): string {.base.} =
|
method getContactDetailsAsJson*(self: AccessInterface, publicKey: string, getVerificationRequest: bool = false,
|
||||||
|
getOnlineStatus: bool = false, includeDetails: bool = false): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getOwnerTokenAsJson*(self: AccessInterface, communityId: string): string {.base.} =
|
method getOwnerTokenAsJson*(self: AccessInterface, communityId: string): string {.base.} =
|
||||||
|
|
|
@ -1099,40 +1099,55 @@ method onCommunityMuted*[T](
|
||||||
method getVerificationRequestFrom*[T](self: Module[T], publicKey: string): VerificationRequest =
|
method getVerificationRequestFrom*[T](self: Module[T], publicKey: string): VerificationRequest =
|
||||||
self.controller.getVerificationRequestFrom(publicKey)
|
self.controller.getVerificationRequestFrom(publicKey)
|
||||||
|
|
||||||
method getContactDetailsAsJson*[T](self: Module[T], publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool): string =
|
method getContactDetailsAsJson*[T](self: Module[T], publicKey: string, getVerificationRequest: bool = false,
|
||||||
let contact = self.controller.getContact(publicKey)
|
getOnlineStatus: bool = false, includeDetails: bool = false): string =
|
||||||
|
var contactDetails: ContactDetails
|
||||||
|
## If includeDetails is true, additional details are calculated, like color hash and that results in higher CPU usage,
|
||||||
|
## that's why by default it is false and we should set it to true only when we really need it.
|
||||||
|
if includeDetails:
|
||||||
|
contactDetails = self.controller.getContactDetails(publicKey)
|
||||||
|
else:
|
||||||
|
contactDetails.dto = self.controller.getContact(publicKey)
|
||||||
|
|
||||||
var requestStatus = 0
|
var requestStatus = 0
|
||||||
if getVerificationRequest:
|
if getVerificationRequest:
|
||||||
requestStatus = self.getVerificationRequestFrom(publicKey).status.int
|
requestStatus = self.getVerificationRequestFrom(publicKey).status.int
|
||||||
var onlineStatus = OnlineStatus.Inactive
|
var onlineStatus = OnlineStatus.Inactive
|
||||||
if getOnlineStatus:
|
if getOnlineStatus:
|
||||||
onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(publicKey).statusType)
|
onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(publicKey).statusType)
|
||||||
|
|
||||||
let jsonObj = %* {
|
let jsonObj = %* {
|
||||||
"displayName": contact.displayName,
|
# contact details props
|
||||||
"displayIcon": contact.image.thumbnail,
|
"defaultDisplayName": contactDetails.defaultDisplayName,
|
||||||
"publicKey": contact.id,
|
"optionalName": contactDetails.optionalName,
|
||||||
"name": contact.name,
|
"icon": contactDetails.icon,
|
||||||
"ensVerified": contact.ensVerified,
|
"isCurrentUser": contactDetails.isCurrentUser,
|
||||||
"alias": contact.alias,
|
"colorId": contactDetails.colorId,
|
||||||
"lastUpdated": contact.lastUpdated,
|
"colorHash": contactDetails.colorHash,
|
||||||
"lastUpdatedLocally": contact.lastUpdatedLocally,
|
# contact dto props
|
||||||
"localNickname": contact.localNickname,
|
"displayName": contactDetails.dto.displayName,
|
||||||
"thumbnailImage": contact.image.thumbnail,
|
"publicKey": contactDetails.dto.id,
|
||||||
"largeImage": contact.image.large,
|
"name": contactDetails.dto.name,
|
||||||
"isContact": contact.isContact,
|
"ensVerified": contactDetails.dto.ensVerified,
|
||||||
"isBlocked": contact.blocked,
|
"alias": contactDetails.dto.alias,
|
||||||
"requestReceived": contact.hasAddedUs,
|
"lastUpdated": contactDetails.dto.lastUpdated,
|
||||||
"isAdded": contact.isContactRequestSent,
|
"lastUpdatedLocally": contactDetails.dto.lastUpdatedLocally,
|
||||||
"isSyncing": contact.isSyncing,
|
"localNickname": contactDetails.dto.localNickname,
|
||||||
"removed": contact.removed,
|
"thumbnailImage": contactDetails.dto.image.thumbnail,
|
||||||
"trustStatus": contact.trustStatus.int,
|
"largeImage": contactDetails.dto.image.large,
|
||||||
|
"isContact": contactDetails.dto.isContact,
|
||||||
|
"isBlocked": contactDetails.dto.isBlocked,
|
||||||
|
"isContactRequestReceived": contactDetails.dto.isContactRequestReceived,
|
||||||
|
"isContactRequestSent": contactDetails.dto.isContactRequestSent,
|
||||||
|
"isSyncing": contactDetails.dto.isSyncing,
|
||||||
|
"removed": contactDetails.dto.removed,
|
||||||
|
"trustStatus": contactDetails.dto.trustStatus.int,
|
||||||
# TODO rename verificationStatus to outgoingVerificationStatus
|
# TODO rename verificationStatus to outgoingVerificationStatus
|
||||||
"contactRequestState": contact.contactRequestState.int,
|
"contactRequestState": contactDetails.dto.contactRequestState.int,
|
||||||
"verificationStatus": contact.verificationStatus.int,
|
"verificationStatus": contactDetails.dto.verificationStatus.int,
|
||||||
"incomingVerificationStatus": requestStatus,
|
"incomingVerificationStatus": requestStatus,
|
||||||
"hasAddedUs": contact.hasAddedUs,
|
"socialLinks": $contactDetails.dto.socialLinks.toJsonNode(),
|
||||||
"socialLinks": $contact.socialLinks.toJsonNode(),
|
"bio": contactDetails.dto.bio,
|
||||||
"bio": contact.bio,
|
|
||||||
"onlineStatus": onlineStatus.int
|
"onlineStatus": onlineStatus.int
|
||||||
}
|
}
|
||||||
return $jsonObj
|
return $jsonObj
|
||||||
|
|
|
@ -64,6 +64,10 @@ proc init*(self: Controller) =
|
||||||
let args = ProfileShowcaseForContactArgs(e)
|
let args = ProfileShowcaseForContactArgs(e)
|
||||||
self.delegate.updateProfileShowcase(args.profileShowcase)
|
self.delegate.updateProfileShowcase(args.profileShowcase)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_PROFILE_SHOWCASE_ACCOUNTS_BY_ADDRESS_FETCHED) do(e: Args):
|
||||||
|
let args = ProfileShowcaseForContactArgs(e)
|
||||||
|
self.delegate.onProfileShowcaseAccountsByAddressFetched(args.profileShowcase.accounts)
|
||||||
|
|
||||||
self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e: Args):
|
self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e: Args):
|
||||||
let args = CommunitiesArgs(e)
|
let args = CommunitiesArgs(e)
|
||||||
self.delegate.onCommunitiesUpdated(args.communities)
|
self.delegate.onCommunitiesUpdated(args.communities)
|
||||||
|
@ -117,5 +121,8 @@ proc requestProfileShowcasePreferences*(self: Controller) =
|
||||||
proc requestProfileShowcaseForContact*(self: Controller, contactId: string) =
|
proc requestProfileShowcaseForContact*(self: Controller, contactId: string) =
|
||||||
self.profileService.requestProfileShowcaseForContact(contactId)
|
self.profileService.requestProfileShowcaseForContact(contactId)
|
||||||
|
|
||||||
|
proc fetchProfileShowcaseAccountsByAddress*(self: Controller, address: string) =
|
||||||
|
self.profileService.fetchProfileShowcaseAccountsByAddress(address)
|
||||||
|
|
||||||
proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard) =
|
proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard) =
|
||||||
self.communityService.requestCommunityInfo(communityId, shard)
|
self.communityService.requestCommunityInfo(communityId, shard)
|
||||||
|
|
|
@ -66,6 +66,12 @@ method requestProfileShowcasePreferences*(self: AccessInterface) {.base.} =
|
||||||
method requestProfileShowcase*(self: AccessInterface, publicKey: string) {.base.} =
|
method requestProfileShowcase*(self: AccessInterface, publicKey: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method fetchProfileShowcaseAccountsByAddress*(self: AccessInterface, address: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method onProfileShowcaseAccountsByAddressFetched*(self: AccessInterface, accounts: seq[ProfileShowcaseAccount]) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method updateProfileShowcase*(self: AccessInterface, profileShowcase: ProfileShowcaseDto) {.base.} =
|
method updateProfileShowcase*(self: AccessInterface, profileShowcase: ProfileShowcaseDto) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, chronicles, sequtils, sugar
|
import NimQml, chronicles, sequtils, sugar, json
|
||||||
|
|
||||||
import ./io_interface, ./view, ./controller
|
import ./io_interface, ./view, ./controller
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
|
@ -174,6 +174,13 @@ method requestProfileShowcase*(self: Module, publicKey: string) =
|
||||||
|
|
||||||
self.controller.requestProfileShowcaseForContact(publicKey)
|
self.controller.requestProfileShowcaseForContact(publicKey)
|
||||||
|
|
||||||
|
method fetchProfileShowcaseAccountsByAddress*(self: Module, address: string) =
|
||||||
|
self.controller.fetchProfileShowcaseAccountsByAddress(address)
|
||||||
|
|
||||||
|
method onProfileShowcaseAccountsByAddressFetched*(self: Module, accounts: seq[ProfileShowcaseAccount]) =
|
||||||
|
let jsonObj = % accounts
|
||||||
|
self.view.emitProfileShowcaseAccountsByAddressFetchedSignal($jsonObj)
|
||||||
|
|
||||||
method updateProfileShowcase(self: Module, profileShowcase: ProfileShowcaseDto) =
|
method updateProfileShowcase(self: Module, profileShowcase: ProfileShowcaseDto) =
|
||||||
if self.presentedPublicKey != profileShowcase.contactId:
|
if self.presentedPublicKey != profileShowcase.contactId:
|
||||||
return
|
return
|
||||||
|
|
|
@ -238,3 +238,10 @@ QtObject:
|
||||||
|
|
||||||
proc updateProfileShowcaseAssets*(self: View, assets: seq[ProfileShowcaseAssetItem]) =
|
proc updateProfileShowcaseAssets*(self: View, assets: seq[ProfileShowcaseAssetItem]) =
|
||||||
self.profileShowcaseAssetsModel.reset(assets.sorted((a, b) => cmp(a.order, b.order), SortOrder.Ascending))
|
self.profileShowcaseAssetsModel.reset(assets.sorted((a, b) => cmp(a.order, b.order), SortOrder.Ascending))
|
||||||
|
|
||||||
|
proc fetchProfileShowcaseAccountsByAddress*(self: View, address: string) {.slot.} =
|
||||||
|
self.delegate.fetchProfileShowcaseAccountsByAddress(address)
|
||||||
|
|
||||||
|
proc profileShowcaseAccountsByAddressFetched*(self: View, accounts: string) {.signal.}
|
||||||
|
proc emitProfileShowcaseAccountsByAddressFetchedSignal*(self: View, accounts: string) =
|
||||||
|
self.profileShowcaseAccountsByAddressFetched(accounts)
|
|
@ -233,8 +233,9 @@ QtObject:
|
||||||
QtProperty[QVariant] appSearchModule:
|
QtProperty[QVariant] appSearchModule:
|
||||||
read = getAppSearchModule
|
read = getAppSearchModule
|
||||||
|
|
||||||
proc getContactDetailsAsJson(self: View, publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool): string {.slot.} =
|
proc getContactDetailsAsJson(self: View, publicKey: string, getVerificationRequest: bool, getOnlineStatus: bool,
|
||||||
return self.delegate.getContactDetailsAsJson(publicKey, getVerificationRequest, getOnlineStatus)
|
includeDetails: bool): string {.slot.} =
|
||||||
|
return self.delegate.getContactDetailsAsJson(publicKey, getVerificationRequest, getOnlineStatus, includeDetails)
|
||||||
|
|
||||||
proc getOwnerTokenAsJson(self: View, communityId: string): string {.slot.} =
|
proc getOwnerTokenAsJson(self: View, communityId: string): string {.slot.} =
|
||||||
return self.delegate.getOwnerTokenAsJson(communityId)
|
return self.delegate.getOwnerTokenAsJson(communityId)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import json
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
## Abstract class for any input/interaction with this module.
|
## Abstract class for any input/interaction with this module.
|
||||||
|
@ -23,6 +25,9 @@ method filterChanged*(self: AccessInterface, addresses: seq[string], chainIds: s
|
||||||
method updateAccount*(self: AccessInterface, address: string, accountName: string, colorId: string, emoji: string) {.base.} =
|
method updateAccount*(self: AccessInterface, address: string, accountName: string, colorId: string, emoji: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getWalletAccountAsJson*(self: AccessInterface, address: string): JsonNode {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
# View Delegate Interface
|
# View Delegate Interface
|
||||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||||
# inheritance, which is not well supported in Nim.
|
# inheritance, which is not well supported in Nim.
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import NimQml, sequtils, sugar
|
import NimQml, json, sequtils, sugar
|
||||||
|
|
||||||
import ./io_interface, ./view, ./controller
|
import ./io_interface, ./view, ./controller
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import ../../../../global/global_singleton
|
import app/global/global_singleton
|
||||||
import ../../../../core/eventemitter
|
import app/core/eventemitter
|
||||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import ../../../../../app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
import ../../../../../app_service/service/currency/service as currency_service
|
import app_service/service/currency/service as currency_service
|
||||||
import ../../../shared/wallet_utils
|
import app/modules/shared/wallet_utils
|
||||||
|
|
||||||
export io_interface
|
export io_interface
|
||||||
|
|
||||||
|
@ -84,3 +84,9 @@ method updateWalletAccountTestPreferredChains*(self: Module, address, preferredC
|
||||||
|
|
||||||
method updateWatchAccountHiddenFromTotalBalance*(self: Module, address: string, hideFromTotalBalance: bool) =
|
method updateWatchAccountHiddenFromTotalBalance*(self: Module, address: string, hideFromTotalBalance: bool) =
|
||||||
self.controller.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
self.controller.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
||||||
|
|
||||||
|
method getWalletAccountAsJson*(self: Module, address: string): JsonNode =
|
||||||
|
let walletAccountDto = self.controller.getWalletAccount(address)
|
||||||
|
if walletAccountDto.isNil:
|
||||||
|
return newJNull()
|
||||||
|
return % walletAccountDto
|
|
@ -1,6 +1,6 @@
|
||||||
import NimQml, sequtils, strutils
|
import NimQml, json, sequtils, strutils
|
||||||
|
|
||||||
import ../../../../../app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
|
|
||||||
import ./model
|
import ./model
|
||||||
import ./item
|
import ./item
|
||||||
|
@ -66,3 +66,6 @@ QtObject:
|
||||||
|
|
||||||
proc updateWatchAccountHiddenFromTotalBalance*(self: View, address: string, hideFromTotalBalance: bool) {.slot.} =
|
proc updateWatchAccountHiddenFromTotalBalance*(self: View, address: string, hideFromTotalBalance: bool) {.slot.} =
|
||||||
self.delegate.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
self.delegate.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
||||||
|
|
||||||
|
proc getWalletAccountAsJson*(self: View, address: string): string {.slot.} =
|
||||||
|
return $self.delegate.getWalletAccountAsJson(address)
|
|
@ -36,3 +36,22 @@ const asyncGetProfileShowcaseForContactTask: Task = proc(argEncoded: string) {.g
|
||||||
"publicKey": arg.pubkey,
|
"publicKey": arg.pubkey,
|
||||||
"error": e.msg,
|
"error": e.msg,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type
|
||||||
|
FetchProfileShowcaseAccountsTaskArg = ref object of QObjectTaskArg
|
||||||
|
address: string
|
||||||
|
|
||||||
|
const fetchProfileShowcaseAccountsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[FetchProfileShowcaseAccountsTaskArg](argEncoded)
|
||||||
|
var response = %* {
|
||||||
|
"response": "",
|
||||||
|
"error": "",
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
let rpcResponse = status_accounts.getProfileShowcaseAccountsByAddress(arg.address)
|
||||||
|
if not rpcResponse.error.isNil:
|
||||||
|
raise newException(CatchableError, rpcResponse.error.message)
|
||||||
|
response["response"] = rpcResponse.result
|
||||||
|
except Exception as e:
|
||||||
|
response["error"] = %* e.msg
|
||||||
|
arg.finish(response)
|
|
@ -7,6 +7,7 @@ type ProfileShowcaseCommunity* = ref object of RootObj
|
||||||
order*: int
|
order*: int
|
||||||
|
|
||||||
type ProfileShowcaseAccount* = ref object of RootObj
|
type ProfileShowcaseAccount* = ref object of RootObj
|
||||||
|
contactId*: string
|
||||||
address*: string
|
address*: string
|
||||||
name*: string
|
name*: string
|
||||||
colorId*: string
|
colorId*: string
|
||||||
|
@ -45,6 +46,7 @@ proc toProfileShowcaseCommunity*(jsonObj: JsonNode): ProfileShowcaseCommunity =
|
||||||
|
|
||||||
proc toProfileShowcaseAccount*(jsonObj: JsonNode): ProfileShowcaseAccount =
|
proc toProfileShowcaseAccount*(jsonObj: JsonNode): ProfileShowcaseAccount =
|
||||||
result = ProfileShowcaseAccount()
|
result = ProfileShowcaseAccount()
|
||||||
|
discard jsonObj.getProp("contactId", result.contactId)
|
||||||
discard jsonObj.getProp("address", result.address)
|
discard jsonObj.getProp("address", result.address)
|
||||||
discard jsonObj.getProp("name", result.name)
|
discard jsonObj.getProp("name", result.name)
|
||||||
discard jsonObj.getProp("colorId", result.colorId)
|
discard jsonObj.getProp("colorId", result.colorId)
|
||||||
|
@ -86,3 +88,12 @@ proc toProfileShowcaseDto*(jsonObj: JsonNode): ProfileShowcaseDto =
|
||||||
result.verifiedTokens.add(jsonMsg.toProfileShowcaseVerifiedToken())
|
result.verifiedTokens.add(jsonMsg.toProfileShowcaseVerifiedToken())
|
||||||
for jsonMsg in jsonObj["unverifiedTokens"]:
|
for jsonMsg in jsonObj["unverifiedTokens"]:
|
||||||
result.unverifiedTokens.add(jsonMsg.toProfileShowcaseUnverifiedToken())
|
result.unverifiedTokens.add(jsonMsg.toProfileShowcaseUnverifiedToken())
|
||||||
|
|
||||||
|
proc `%`*(x: ProfileShowcaseAccount): JsonNode =
|
||||||
|
result = newJobject()
|
||||||
|
result["contactId"] = % x.contactId
|
||||||
|
result["address"] = % x.address
|
||||||
|
result["name"] = % x.name
|
||||||
|
result["colorId"] = % x.colorId
|
||||||
|
result["emoji"] = % x.emoji
|
||||||
|
result["order"] = % x.order
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, json, chronicles, tables
|
import NimQml, json, chronicles, tables, sequtils
|
||||||
|
|
||||||
import ../settings/service as settings_service
|
import ../settings/service as settings_service
|
||||||
import ../../../app/global/global_singleton
|
import ../../../app/global/global_singleton
|
||||||
|
@ -28,6 +28,7 @@ type
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
const SIGNAL_PROFILE_SHOWCASE_PREFERENCES_UPDATED* = "profileShowcasePreferencesUpdated"
|
const SIGNAL_PROFILE_SHOWCASE_PREFERENCES_UPDATED* = "profileShowcasePreferencesUpdated"
|
||||||
const SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED* = "profileShowcaseForContactUpdated"
|
const SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED* = "profileShowcaseForContactUpdated"
|
||||||
|
const SIGNAL_PROFILE_SHOWCASE_ACCOUNTS_BY_ADDRESS_FETCHED* = "profileShowcaseAccountsByAddressFetched"
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type Service* = ref object of QObject
|
type Service* = ref object of QObject
|
||||||
|
@ -128,6 +129,33 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error requesting profile showcase for a contact", msg = e.msg
|
error "Error requesting profile showcase for a contact", msg = e.msg
|
||||||
|
|
||||||
|
proc fetchProfileShowcaseAccountsByAddress*(self: Service, address: string) =
|
||||||
|
let arg = FetchProfileShowcaseAccountsTaskArg(
|
||||||
|
address: address,
|
||||||
|
tptr: cast[ByteAddress](fetchProfileShowcaseAccountsTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: "onProfileShowcaseAccountsByAddressFetched",
|
||||||
|
)
|
||||||
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
proc onProfileShowcaseAccountsByAddressFetched*(self: Service, rpcResponse: string) {.slot.} =
|
||||||
|
var data = ProfileShowcaseForContactArgs(
|
||||||
|
profileShowcase: ProfileShowcaseDto(
|
||||||
|
accounts: @[],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
let rpcResponseObj = rpcResponse.parseJson
|
||||||
|
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
|
||||||
|
raise newException(CatchableError, rpcResponseObj{"error"}.getStr)
|
||||||
|
if rpcResponseObj{"response"}.kind != JArray:
|
||||||
|
raise newException(CatchableError, "invalid response")
|
||||||
|
|
||||||
|
data.profileShowcase.accounts = map(rpcResponseObj{"response"}.getElems(), proc(x: JsonNode): ProfileShowcaseAccount = toProfileShowcaseAccount(x))
|
||||||
|
except Exception as e:
|
||||||
|
error "onProfileShowcaseAccountsByAddressFetched", msg = e.msg
|
||||||
|
self.events.emit(SIGNAL_PROFILE_SHOWCASE_ACCOUNTS_BY_ADDRESS_FETCHED, data)
|
||||||
|
|
||||||
proc requestProfileShowcasePreferences*(self: Service) =
|
proc requestProfileShowcasePreferences*(self: Service) =
|
||||||
let arg = QObjectTaskArg(
|
let arg = QObjectTaskArg(
|
||||||
tptr: cast[ByteAddress](asyncGetProfileShowcasePreferencesTask),
|
tptr: cast[ByteAddress](asyncGetProfileShowcasePreferencesTask),
|
||||||
|
|
|
@ -90,6 +90,7 @@ proc `%`*(x: WalletAccountDto): JsonNode =
|
||||||
result["path"] = % x.path
|
result["path"] = % x.path
|
||||||
result["colorId"] = % x.colorId
|
result["colorId"] = % x.colorId
|
||||||
result["publicKey"] = % x.publicKey
|
result["publicKey"] = % x.publicKey
|
||||||
|
result["walletType"] = % x.walletType
|
||||||
result["isWallet"] = % x.isWallet
|
result["isWallet"] = % x.isWallet
|
||||||
result["isChat"] = % x.isChat
|
result["isChat"] = % x.isChat
|
||||||
result["emoji"] = % x.emoji
|
result["emoji"] = % x.emoji
|
||||||
|
|
|
@ -478,6 +478,10 @@ proc getProfileShowcaseForContact*(contactId: string): RpcResponse[JsonNode] {.r
|
||||||
let payload = %* [contactId]
|
let payload = %* [contactId]
|
||||||
result = callPrivateRPC("getProfileShowcaseForContact".prefix, payload)
|
result = callPrivateRPC("getProfileShowcaseForContact".prefix, payload)
|
||||||
|
|
||||||
|
proc getProfileShowcaseAccountsByAddress*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
let payload = %* [address]
|
||||||
|
result = callPrivateRPC("getProfileShowcaseAccountsByAddress".prefix, payload)
|
||||||
|
|
||||||
proc getProfileShowcasePreferences*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc getProfileShowcasePreferences*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
result = callPrivateRPC("getProfileShowcasePreferences".prefix, %*[])
|
result = callPrivateRPC("getProfileShowcasePreferences".prefix, %*[])
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ Item {
|
||||||
property var viewAndPostHoldingsModel
|
property var viewAndPostHoldingsModel
|
||||||
|
|
||||||
readonly property var contactDetails: rootStore ? rootStore.oneToOneChatContact : null
|
readonly property var contactDetails: rootStore ? rootStore.oneToOneChatContact : null
|
||||||
readonly property bool isUserAdded: !!root.contactDetails && root.contactDetails.isAdded
|
readonly property bool isUserAdded: !!root.contactDetails && root.contactDetails.isContactRequestSent
|
||||||
property bool amISectionAdmin: false
|
property bool amISectionAdmin: false
|
||||||
|
|
||||||
signal openStickerPackPopup(string stickerPackId)
|
signal openStickerPackPopup(string stickerPackId)
|
||||||
|
|
|
@ -112,7 +112,7 @@ ItemDelegate {
|
||||||
isUntrustworthy: root.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
isUntrustworthy: root.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
||||||
isAdmin: root.contactDetails.memberRole === Constants.memberRole.owner
|
isAdmin: root.contactDetails.memberRole === Constants.memberRole.owner
|
||||||
status: root.contactDetails.onlineStatus
|
status: root.contactDetails.onlineStatus
|
||||||
asset.name: root.contactDetails.displayIcon
|
asset.name: root.contactDetails.thumbnailImage
|
||||||
asset.isImage: (asset.name !== "")
|
asset.isImage: (asset.name !== "")
|
||||||
asset.isLetterIdenticon: (asset.name === "")
|
asset.isLetterIdenticon: (asset.name === "")
|
||||||
asset.color: Utils.colorForPubkey(root.contactId)
|
asset.color: Utils.colorForPubkey(root.contactId)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import QtQuick.Layouts 1.14
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
|
import shared.stores 1.0 as SharedStores
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
@ -62,7 +63,7 @@ StatusModal {
|
||||||
colorSelection.selectedColorIndex = ind
|
colorSelection.selectedColorIndex = ind
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!!d.ens)
|
if (d.addressInputIsENS)
|
||||||
addressInput.setPlainText(d.ens)
|
addressInput.setPlainText(d.ens)
|
||||||
else
|
else
|
||||||
addressInput.setPlainText("%1%2"
|
addressInput.setPlainText("%1%2"
|
||||||
|
@ -72,6 +73,12 @@ StatusModal {
|
||||||
nameInput.input.edit.forceActiveFocus(Qt.MouseFocusReason)
|
nameInput.input.edit.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CardType {
|
||||||
|
Contact,
|
||||||
|
WalletAccount,
|
||||||
|
SavedAddress
|
||||||
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
@ -90,27 +97,78 @@ StatusModal {
|
||||||
property string storedChainShortNames: ""
|
property string storedChainShortNames: ""
|
||||||
|
|
||||||
property bool chainShortNamesDirty: false
|
property bool chainShortNamesDirty: false
|
||||||
readonly property bool valid: addressInput.valid && nameInput.valid
|
property bool addressInputValid: d.editMode ||
|
||||||
|
addressInput.input.dirty &&
|
||||||
|
d.addressInputIsAddress &&
|
||||||
|
!d.minAddressLengthRequestError &&
|
||||||
|
!d.addressAlreadyAddedToWalletError &&
|
||||||
|
!d.addressAlreadyAddedToSavedAddressesError
|
||||||
|
readonly property bool valid: d.addressInputValid && nameInput.valid
|
||||||
readonly property bool dirty: nameInput.input.dirty && (!d.editMode || d.storedName !== d.name)
|
readonly property bool dirty: nameInput.input.dirty && (!d.editMode || d.storedName !== d.name)
|
||||||
|| chainShortNamesDirty && (!d.editMode || d.storedChainShortNames !== d.chainShortNames)
|
|| chainShortNamesDirty && (!d.editMode || d.storedChainShortNames !== d.chainShortNames)
|
||||||
|| d.colorId.toUpperCase() !== d.storedColorId.toUpperCase()
|
|| d.colorId.toUpperCase() !== d.storedColorId.toUpperCase()
|
||||||
|
|
||||||
|
|
||||||
readonly property var chainPrefixRegexPattern: /[^:]+\:?|:/g
|
readonly property var chainPrefixRegexPattern: /[^:]+\:?|:/g
|
||||||
readonly property bool addressInputIsENS: !!d.ens
|
readonly property bool addressInputIsENS: !!d.ens &&
|
||||||
|
Utils.isValidEns(d.ens)
|
||||||
|
readonly property bool addressInputIsAddress: !!d.address &&
|
||||||
|
d.address != Constants.zeroAddress &&
|
||||||
|
(Utils.isAddress(d.address) || Utils.isValidAddressWithChainPrefix(d.address))
|
||||||
|
|
||||||
|
property ListModel cardsModel: ListModel {}
|
||||||
|
|
||||||
|
// possible errors/warnings
|
||||||
|
readonly property int minAddressLen: 1
|
||||||
|
property bool minAddressLengthRequestError: false
|
||||||
|
property bool addressAlreadyAddedToWalletError: false
|
||||||
|
property bool addressAlreadyAddedToSavedAddressesError: false
|
||||||
|
property bool checkingContactsAddressInProgress: false
|
||||||
|
property int contactsWithSameAddress: 0
|
||||||
|
|
||||||
property bool addressAlreadyAddedToWallet: false
|
|
||||||
function checkIfAddressIsAlreadyAdddedToWallet(address) {
|
function checkIfAddressIsAlreadyAdddedToWallet(address) {
|
||||||
let name = RootStore.getNameForWalletAddress(address)
|
let account = RootStore.getWalletAccount(address)
|
||||||
d.addressAlreadyAddedToWallet = !!name
|
d.cardsModel.clear()
|
||||||
|
d.addressAlreadyAddedToWalletError = !!account.name
|
||||||
|
if (!d.addressAlreadyAddedToWalletError) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.cardsModel.append({
|
||||||
|
type: AddEditSavedAddressPopup.CardType.WalletAccount,
|
||||||
|
address: account.mixedcaseAddress,
|
||||||
|
title: account.name,
|
||||||
|
icon: "",
|
||||||
|
emoji: account.emoji,
|
||||||
|
color: Utils.getColorForId(account.colorId).toString().toUpperCase()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool addressAlreadyAddedToSavedAddresses: false
|
|
||||||
function checkIfAddressIsAlreadyAdddedToSavedAddresses(address) {
|
function checkIfAddressIsAlreadyAdddedToSavedAddresses(address) {
|
||||||
let details = RootStore.getSavedAddress(address)
|
let savedAddress = RootStore.getSavedAddress(address)
|
||||||
d.addressAlreadyAddedToSavedAddresses = !!details.address
|
d.cardsModel.clear()
|
||||||
|
d.addressAlreadyAddedToSavedAddressesError = !!savedAddress.address
|
||||||
|
if (!d.addressAlreadyAddedToSavedAddressesError) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.cardsModel.append({
|
||||||
|
type: AddEditSavedAddressPopup.CardType.SavedAddress,
|
||||||
|
address: savedAddress.ens || savedAddress.address,
|
||||||
|
title: savedAddress.name,
|
||||||
|
icon: "",
|
||||||
|
emoji: "",
|
||||||
|
color: Utils.getColorForId(savedAddress.colorId).toString().toUpperCase()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool resolvingEnsNameInProgress: false
|
||||||
|
readonly property string uuid: Utils.uuid()
|
||||||
|
readonly property var validateEnsAsync: Backpressure.debounce(root, 500, function (value) {
|
||||||
|
var name = value.startsWith("@") ? value.substring(1) : value
|
||||||
|
mainModule.resolveENS(name, d.uuid)
|
||||||
|
});
|
||||||
|
|
||||||
|
property var profileModuleInst: SharedStores.RootStore.profileSectionModuleInst.profileModule
|
||||||
|
|
||||||
/// Ensures that the \c root.address and \c root.chainShortNames are not reset when the initial text is set
|
/// Ensures that the \c root.address and \c root.chainShortNames are not reset when the initial text is set
|
||||||
property bool initialized: false
|
property bool initialized: false
|
||||||
|
|
||||||
|
@ -118,11 +176,81 @@ StatusModal {
|
||||||
return prefixStr.match(d.chainPrefixRegexPattern)
|
return prefixStr.match(d.chainPrefixRegexPattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetAddressValues() {
|
function resetAddressValues(fullReset) {
|
||||||
d.ens = ""
|
if (fullReset) {
|
||||||
d.address = Constants.zeroAddress
|
d.ens = ""
|
||||||
d.chainShortNames = ""
|
d.address = Constants.zeroAddress
|
||||||
allNetworksModelCopy.setEnabledNetworks([])
|
d.chainShortNames = ""
|
||||||
|
allNetworksModelCopy.setEnabledNetworks([])
|
||||||
|
}
|
||||||
|
|
||||||
|
d.cardsModel.clear()
|
||||||
|
d.resolvingEnsNameInProgress = false
|
||||||
|
d.checkingContactsAddressInProgress = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForAddressInputOwningErrorsWarnings() {
|
||||||
|
d.addressAlreadyAddedToWalletError = false
|
||||||
|
d.addressAlreadyAddedToSavedAddressesError = false
|
||||||
|
|
||||||
|
if (d.addressInputIsAddress) {
|
||||||
|
d.checkIfAddressIsAlreadyAdddedToWallet(d.address)
|
||||||
|
if (d.addressAlreadyAddedToWalletError) {
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("You cannot add your own account as a saved address")
|
||||||
|
addressInput.errorMessageCmp.visible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.checkIfAddressIsAlreadyAdddedToSavedAddresses(d.address)
|
||||||
|
if (d.addressAlreadyAddedToSavedAddressesError) {
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("This address is already saved")
|
||||||
|
addressInput.errorMessageCmp.visible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.checkingContactsAddressInProgress = true
|
||||||
|
d.contactsWithSameAddress = 0
|
||||||
|
d.profileModuleInst.fetchProfileShowcaseAccountsByAddress(d.address)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("Not registered ens address")
|
||||||
|
addressInput.errorMessageCmp.visible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkForAddressInputErrorsWarnings() {
|
||||||
|
addressInput.errorMessageCmp.visible = false
|
||||||
|
addressInput.errorMessageCmp.color = Theme.palette.dangerColor1
|
||||||
|
addressInput.errorMessageCmp.text = ""
|
||||||
|
|
||||||
|
d.minAddressLengthRequestError = false
|
||||||
|
|
||||||
|
if (d.editMode || !addressInput.input.dirty) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.addressInputIsENS || d.addressInputIsAddress) {
|
||||||
|
let value = d.ens || d.address
|
||||||
|
if (value.trim().length < d.minAddressLen) {
|
||||||
|
d.minAddressLengthRequestError = true
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("Please enter an ethereum address")
|
||||||
|
addressInput.errorMessageCmp.visible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.addressInputIsENS) {
|
||||||
|
d.resolvingEnsNameInProgress = true
|
||||||
|
d.validateEnsAsync(d.ens)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d.addressInputIsAddress) {
|
||||||
|
d.checkForAddressInputOwningErrorsWarnings()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("Ethereum address invalid")
|
||||||
|
addressInput.errorMessageCmp.visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function submit(event) {
|
function submit(event) {
|
||||||
|
@ -134,13 +262,56 @@ StatusModal {
|
||||||
RootStore.createOrUpdateSavedAddress(d.name, d.address, d.ens, d.colorId, d.chainShortNames)
|
RootStore.createOrUpdateSavedAddress(d.name, d.address, d.ens, d.colorId, d.chainShortNames)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property bool resolvingEnsName: false
|
Connections {
|
||||||
readonly property string uuid: Utils.uuid()
|
target: mainModule
|
||||||
readonly property var validateEnsAsync: Backpressure.debounce(root, 500, function (value) {
|
function onResolvedENS(resolvedPubKey: string, resolvedAddress: string, uuid: string) {
|
||||||
var name = value.startsWith("@") ? value.substring(1) : value
|
if (uuid !== d.uuid) {
|
||||||
mainModule.resolveENS(name, d.uuid)
|
return
|
||||||
});
|
}
|
||||||
|
|
||||||
|
d.resolvingEnsNameInProgress = false
|
||||||
|
d.address = resolvedAddress
|
||||||
|
d.checkForAddressInputOwningErrorsWarnings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: d.profileModuleInst
|
||||||
|
function onProfileShowcaseAccountsByAddressFetched(accounts: string) {
|
||||||
|
d.cardsModel.clear()
|
||||||
|
d.checkingContactsAddressInProgress = false
|
||||||
|
try {
|
||||||
|
let accountsJson = JSON.parse(accounts)
|
||||||
|
d.contactsWithSameAddress = accountsJson.length
|
||||||
|
addressInput.errorMessageCmp.visible = d.contactsWithSameAddress > 0
|
||||||
|
addressInput.errorMessageCmp.color = Theme.palette.warningColor1
|
||||||
|
addressInput.errorMessageCmp.text = ""
|
||||||
|
if (d.contactsWithSameAddress === 1)
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("This address belongs to a contact")
|
||||||
|
if (d.contactsWithSameAddress > 1)
|
||||||
|
addressInput.errorMessageCmp.text = qsTr("This address belongs to the following contacts")
|
||||||
|
|
||||||
|
for (let i = 0; i < accountsJson.length; ++i) {
|
||||||
|
let contact = Utils.getContactDetailsAsJson(accountsJson[i].contactId, true, true, true)
|
||||||
|
d.cardsModel.append({
|
||||||
|
type: AddEditSavedAddressPopup.CardType.Contact,
|
||||||
|
address: accountsJson[i].address,
|
||||||
|
title: ProfileUtils.displayName(contact.localNickname, contact.name, contact.displayName, contact.alias),
|
||||||
|
icon: contact.icon,
|
||||||
|
emoji: "",
|
||||||
|
color: Utils.colorForColorId(contact.colorId),
|
||||||
|
onlineStatus: contact.onlineStatus,
|
||||||
|
colorHash: contact.colorHash
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.warn("error parsing fetched accounts for contact: ", e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusScrollView {
|
StatusScrollView {
|
||||||
|
@ -219,96 +390,21 @@ StatusModal {
|
||||||
maximumHeight: 66
|
maximumHeight: 66
|
||||||
input.implicitHeight: Math.min(Math.max(input.edit.contentHeight + topPadding + bottomPadding, minimumHeight), maximumHeight) // setting height instead does not work
|
input.implicitHeight: Math.min(Math.max(input.edit.contentHeight + topPadding + bottomPadding, minimumHeight), maximumHeight) // setting height instead does not work
|
||||||
enabled: !(d.editMode || d.addAddress)
|
enabled: !(d.editMode || d.addAddress)
|
||||||
validators: [
|
|
||||||
StatusMinLengthValidator {
|
|
||||||
minLength: 1
|
|
||||||
errorMessage: qsTr("Please enter an ethereum address")
|
|
||||||
},
|
|
||||||
StatusValidator {
|
|
||||||
errorMessage: d.addressAlreadyAddedToWallet? qsTr("This address is already added to Wallet") :
|
|
||||||
d.addressAlreadyAddedToSavedAddresses? qsTr("This address is already saved") : qsTr("Ethereum address invalid")
|
|
||||||
validate: function (value) {
|
|
||||||
if (value !== Constants.zeroAddress) {
|
|
||||||
if (Utils.isValidEns(value)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (Utils.isValidAddressWithChainPrefix(value)) {
|
|
||||||
if (d.editMode) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
const prefixAndAddress = Utils.splitToChainPrefixAndAddress(value)
|
|
||||||
d.checkIfAddressIsAlreadyAdddedToWallet(prefixAndAddress.address)
|
|
||||||
if (d.addressAlreadyAddedToWallet) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
d.checkIfAddressIsAlreadyAdddedToSavedAddresses(prefixAndAddress.address)
|
|
||||||
return !d.addressAlreadyAddedToSavedAddresses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
asyncValidators: [
|
|
||||||
StatusAsyncValidator {
|
|
||||||
id: resolvingEnsName
|
|
||||||
name: "resolving-ens-name"
|
|
||||||
errorMessage: d.addressAlreadyAddedToWallet? qsTr("This address is already added to Wallet") :
|
|
||||||
d.addressAlreadyAddedToSavedAddresses? qsTr("This address is already saved") : qsTr("Ethereum address invalid")
|
|
||||||
asyncOperation: (value) => {
|
|
||||||
if (!Utils.isValidEns(value)) {
|
|
||||||
resolvingEnsName.asyncComplete("not-ens")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.resolvingEnsName = true
|
|
||||||
d.validateEnsAsync(value)
|
|
||||||
}
|
|
||||||
validate: (value) => {
|
|
||||||
if (d.editMode || value === "not-ens") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (!!value) {
|
|
||||||
d.checkIfAddressIsAlreadyAdddedToWallet(prefixAndAddress.address)
|
|
||||||
if (d.addressAlreadyAddedToWallet) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
d.checkIfAddressIsAlreadyAdddedToSavedAddresses(value)
|
|
||||||
return !d.addressAlreadyAddedToSavedAddresses
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: mainModule
|
|
||||||
function onResolvedENS(resolvedPubKey: string, resolvedAddress: string, uuid: string) {
|
|
||||||
if (uuid !== d.uuid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.resolvingEnsName = false
|
|
||||||
d.address = resolvedAddress
|
|
||||||
resolvingEnsName.asyncComplete(resolvedAddress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
input.edit.textFormat: TextEdit.RichText
|
input.edit.textFormat: TextEdit.RichText
|
||||||
input.asset.name: addressInput.valid && !d.editMode ? "checkbox" : ""
|
input.asset.name: d.addressInputValid && !d.editMode ? "checkbox" : ""
|
||||||
input.asset.color: enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
input.asset.color: enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||||
input.rightPadding: 16
|
input.rightPadding: 16
|
||||||
input.leftIcon: false
|
input.leftIcon: false
|
||||||
|
|
||||||
multiline: true
|
multiline: true
|
||||||
|
|
||||||
property string plainText: input.edit.getText(0, text.length)
|
property string plainText: input.edit.getText(0, text.length).trim()
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (skipTextUpdate || !d.initialized)
|
if (skipTextUpdate || !d.initialized)
|
||||||
return
|
return
|
||||||
|
|
||||||
d.addressAlreadyAddedToSavedAddresses = false
|
plainText = input.edit.getText(0, text.length).trim()
|
||||||
plainText = input.edit.getText(0, text.length)
|
|
||||||
|
|
||||||
if (input.edit.previousText != plainText) {
|
if (input.edit.previousText != plainText) {
|
||||||
let newText = plainText
|
let newText = plainText
|
||||||
|
@ -322,30 +418,29 @@ StatusModal {
|
||||||
setRichText(newText)
|
setRichText(newText)
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
if (plainText.length == 0) {
|
d.resetAddressValues(plainText.length == 0)
|
||||||
d.resetAddressValues()
|
|
||||||
return
|
if (plainText.length > 0) {
|
||||||
|
// Update root values
|
||||||
|
if (Utils.isLikelyEnsName(plainText)) {
|
||||||
|
d.ens = plainText
|
||||||
|
d.address = Constants.zeroAddress
|
||||||
|
d.chainShortNames = ""
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d.ens = ""
|
||||||
|
d.address = prefixAndAddress.address
|
||||||
|
d.chainShortNames = prefixAndAddress.prefix
|
||||||
|
|
||||||
|
let prefixArrWithColumn = d.getPrefixArrayWithColumns(prefixAndAddress.prefix)
|
||||||
|
if (!prefixArrWithColumn)
|
||||||
|
prefixArrWithColumn = []
|
||||||
|
|
||||||
|
allNetworksModelCopy.setEnabledNetworks(prefixArrWithColumn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update root values
|
d.checkForAddressInputErrorsWarnings()
|
||||||
if (Utils.isLikelyEnsName(plainText)) {
|
|
||||||
d.resolvingEnsName = true
|
|
||||||
d.ens = plainText
|
|
||||||
d.address = Constants.zeroAddress
|
|
||||||
d.chainShortNames = ""
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
d.resolvingEnsName = false
|
|
||||||
d.ens = ""
|
|
||||||
d.address = prefixAndAddress.address
|
|
||||||
d.chainShortNames = prefixAndAddress.prefix
|
|
||||||
|
|
||||||
let prefixArrWithColumn = d.getPrefixArrayWithColumns(prefixAndAddress.prefix)
|
|
||||||
if (!prefixArrWithColumn)
|
|
||||||
prefixArrWithColumn = []
|
|
||||||
|
|
||||||
allNetworksModelCopy.setEnabledNetworks(prefixArrWithColumn)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,6 +498,51 @@ StatusModal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: scrollView.availableWidth
|
||||||
|
visible: d.cardsModel.count > 0
|
||||||
|
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: d.cardsModel
|
||||||
|
|
||||||
|
StatusListItem {
|
||||||
|
width: d.componentWidth
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
title: model.title
|
||||||
|
subTitle: model.address
|
||||||
|
statusListItemSubTitle.font.pixelSize: 12
|
||||||
|
sensor.hoverEnabled: false
|
||||||
|
statusListItemIcon.badge.visible: model.type === AddEditSavedAddressPopup.CardType.Contact
|
||||||
|
statusListItemIcon.badge.color: model.type === AddEditSavedAddressPopup.CardType.Contact && model.onlineStatus === 1?
|
||||||
|
Theme.palette.successColor1
|
||||||
|
: Theme.palette.baseColor1
|
||||||
|
statusListItemIcon.hoverEnabled: false
|
||||||
|
ringSettings.ringSpecModel: model.type === AddEditSavedAddressPopup.CardType.Contact? model.colorHash : ""
|
||||||
|
|
||||||
|
asset {
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
name: model.icon
|
||||||
|
isImage: model.icon !== ""
|
||||||
|
emoji: model.emoji
|
||||||
|
color: model.color
|
||||||
|
isLetterIdenticon: !model.icon
|
||||||
|
useAcronymForLetterIdenticon: model.type === AddEditSavedAddressPopup.CardType.SavedAddress
|
||||||
|
charactersLen: {
|
||||||
|
if (model.type === AddEditSavedAddressPopup.CardType.SavedAddress && model.title.split(" ").length == 1) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StatusColorSelectorGrid {
|
StatusColorSelectorGrid {
|
||||||
id: colorSelection
|
id: colorSelection
|
||||||
objectName: "addSavedAddressColor"
|
objectName: "addSavedAddressColor"
|
||||||
|
@ -426,7 +566,7 @@ StatusModal {
|
||||||
implicitWidth: d.componentWidth
|
implicitWidth: d.componentWidth
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
enabled: addressInput.valid && !d.addressInputIsENS
|
enabled: d.addressInputValid && !d.addressInputIsENS
|
||||||
defaultItemText: "Add networks"
|
defaultItemText: "Add networks"
|
||||||
defaultItemImageSource: "add"
|
defaultItemImageSource: "add"
|
||||||
rightButtonVisible: true
|
rightButtonVisible: true
|
||||||
|
@ -515,8 +655,8 @@ StatusModal {
|
||||||
rightButtons: [
|
rightButtons: [
|
||||||
StatusButton {
|
StatusButton {
|
||||||
text: d.editMode? qsTr("Save") : qsTr("Add address")
|
text: d.editMode? qsTr("Save") : qsTr("Add address")
|
||||||
enabled: d.valid && d.dirty && !d.resolvingEnsName
|
enabled: d.valid && d.dirty
|
||||||
loading: d.resolvingEnsName
|
loading: d.resolvingEnsNameInProgress || d.checkingContactsAddressInProgress
|
||||||
onClicked: {
|
onClicked: {
|
||||||
d.submit()
|
d.submit()
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,44 @@ QtObject {
|
||||||
return walletSectionAccounts.getNameByAddress(address)
|
return walletSectionAccounts.getNameByAddress(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getWalletAccount(address) {
|
||||||
|
const defaultValue = {
|
||||||
|
name: "",
|
||||||
|
address: "",
|
||||||
|
mixedcaseAddress: "",
|
||||||
|
keyUid: "",
|
||||||
|
path: "",
|
||||||
|
colorId: Constants.walletAccountColors.primary,
|
||||||
|
publicKey: "",
|
||||||
|
walletType: "",
|
||||||
|
isWallet: false,
|
||||||
|
isChat: false,
|
||||||
|
emoji: "",
|
||||||
|
ens: "",
|
||||||
|
assetsLoading: false,
|
||||||
|
removed: "",
|
||||||
|
operable: "",
|
||||||
|
createdAt: -1,
|
||||||
|
position: -1,
|
||||||
|
prodPreferredChainIds: "",
|
||||||
|
testPreferredChainIds: "",
|
||||||
|
hideFromTotalBalance: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonObj = walletSectionAccounts.getWalletAccountAsJson(address)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (jsonObj === "null" || jsonObj === undefined) {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
return JSON.parse(jsonObj)
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.warn("error parsing wallet account for address: ", address, " error: ", e.message)
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getSavedAddress(address) {
|
function getSavedAddress(address) {
|
||||||
const defaultValue = {
|
const defaultValue = {
|
||||||
name: "",
|
name: "",
|
||||||
|
|
|
@ -20,7 +20,7 @@ ActivityNotificationMessage {
|
||||||
contactDetails: notification ? Utils.getContactDetailsAsJson(notification.author, false) : null
|
contactDetails: notification ? Utils.getContactDetailsAsJson(notification.author, false) : null
|
||||||
|
|
||||||
messageDetails.messageText: qsTr("Wants to join")
|
messageDetails.messageText: qsTr("Wants to join")
|
||||||
messageDetails.sender.profileImage.name: contactDetails ? contactDetails.displayIcon : ""
|
messageDetails.sender.profileImage.name: contactDetails ? contactDetails.thumbnailImage : ""
|
||||||
messageDetails.sender.profileImage.assetSettings.isImage: true
|
messageDetails.sender.profileImage.assetSettings.isImage: true
|
||||||
messageDetails.sender.profileImage.pubkey: notification ? notification.author : ""
|
messageDetails.sender.profileImage.pubkey: notification ? notification.author : ""
|
||||||
messageDetails.sender.profileImage.colorId: Utils.colorIdForPubkey(notification ? notification.author : "")
|
messageDetails.sender.profileImage.colorId: Utils.colorIdForPubkey(notification ? notification.author : "")
|
||||||
|
|
|
@ -46,7 +46,7 @@ ActivityNotificationMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctaComponent: StatusFlatButton {
|
ctaComponent: StatusFlatButton {
|
||||||
enabled: root.contactDetails && !root.contactDetails.added && !root.contactDetails.hasAddedUs
|
enabled: root.contactDetails && !root.contactDetails.added && !root.contactDetails.isContactRequestReceived
|
||||||
size: StatusBaseButton.Size.Small
|
size: StatusBaseButton.Size.Small
|
||||||
text: qsTr("Send Contact Request")
|
text: qsTr("Send Contact Request")
|
||||||
onClicked: Global.openContactRequestPopup(root.contactId, null)
|
onClicked: Global.openContactRequestPopup(root.contactId, null)
|
||||||
|
|
|
@ -35,7 +35,7 @@ ActivityNotificationBase {
|
||||||
sender.profileImage {
|
sender.profileImage {
|
||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
name: contactDetails ? contactDetails.displayIcon : ""
|
name: contactDetails ? contactDetails.thumbnailImage : ""
|
||||||
pubkey: contactId
|
pubkey: contactId
|
||||||
colorId: Utils.colorIdForPubkey(contactId)
|
colorId: Utils.colorIdForPubkey(contactId)
|
||||||
colorHash: Utils.getColorHashAsJson(contactId, sender.isEnsVerified)
|
colorHash: Utils.getColorHashAsJson(contactId, sender.isEnsVerified)
|
||||||
|
|
|
@ -104,7 +104,7 @@ Item {
|
||||||
asset.height: 32
|
asset.height: 32
|
||||||
asset.isImage: true
|
asset.isImage: true
|
||||||
asset.name: (!!selectedContact && !!selectedContact.displayIcon) ? selectedContact.displayIcon : ""
|
asset.name: (!!selectedContact && !!selectedContact.displayIcon) ? selectedContact.displayIcon : ""
|
||||||
active: !!selectedContact && !!selectedContact.displayIcon
|
active: !!selectedContact && !!selectedContact.thumbnailImage
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
id: selectedTextField
|
id: selectedTextField
|
||||||
|
@ -142,7 +142,7 @@ Item {
|
||||||
|
|
||||||
StatusSmartIdenticon {
|
StatusSmartIdenticon {
|
||||||
asset.isImage: true
|
asset.isImage: true
|
||||||
asset.name: currentContact.displayIcon
|
asset.name: currentContact.thumbnailImage
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
@ -52,13 +52,13 @@ Item {
|
||||||
color: d.isContact ? Utils.colorForPubkey(root.contactPubKey) : d.walletAddressColor
|
color: d.isContact ? Utils.colorForPubkey(root.contactPubKey) : d.walletAddressColor
|
||||||
name: {
|
name: {
|
||||||
if (d.isContact) {
|
if (d.isContact) {
|
||||||
return isImage ? d.contactData.displayIcon : nameText.text
|
return isImage ? d.contactData.thumbnailImage : nameText.text
|
||||||
} else if (d.isWallet && !d.walletAddressEmoji) {
|
} else if (d.isWallet && !d.walletAddressEmoji) {
|
||||||
return "filled-account"
|
return "filled-account"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
isImage: d.isContact && statusAssetSettings.isImgSrc(d.contactData.displayIcon)
|
isImage: d.isContact && statusAssetSettings.isImgSrc(d.contactData.thumbnailImage)
|
||||||
emoji: d.isWallet && !!d.walletAddressEmoji ? d.walletAddressEmoji : ""
|
emoji: d.isWallet && !!d.walletAddressEmoji ? d.walletAddressEmoji : ""
|
||||||
isLetterIdenticon: d.isContact && !isImage
|
isLetterIdenticon: d.isContact && !isImage
|
||||||
charactersLen: 2
|
charactersLen: 2
|
||||||
|
|
|
@ -43,7 +43,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUserAdded() {
|
function isUserAdded() {
|
||||||
return root.pubKey != "" ? Utils.getContactDetailsAsJson(root.pubKey).isAdded : false
|
return root.pubKey != "" ? Utils.getContactDetailsAsJson(root.pubKey).isContactRequestSent : false
|
||||||
}
|
}
|
||||||
|
|
||||||
onPubKeyChanged: {
|
onPubKeyChanged: {
|
||||||
|
|
|
@ -406,10 +406,15 @@ QtObject {
|
||||||
|
|
||||||
/* Validation section end */
|
/* Validation section end */
|
||||||
|
|
||||||
function getContactDetailsAsJson(publicKey, getVerificationRequest=true, getOnlineStatus=false) {
|
function getContactDetailsAsJson(publicKey, getVerificationRequest=true, getOnlineStatus=false, includeDetails=false) {
|
||||||
const defaultValue = {
|
const defaultValue = {
|
||||||
|
defaultDisplayName: "",
|
||||||
|
optionalName: "",
|
||||||
|
icon: "",
|
||||||
|
isCurrentUser: "",
|
||||||
|
colorId: "",
|
||||||
|
colorHash: "",
|
||||||
displayName: "",
|
displayName: "",
|
||||||
displayIcon: "",
|
|
||||||
publicKey: publicKey,
|
publicKey: publicKey,
|
||||||
name: "",
|
name: "",
|
||||||
ensVerified: false,
|
ensVerified: false,
|
||||||
|
@ -420,21 +425,24 @@ QtObject {
|
||||||
thumbnailImage: "",
|
thumbnailImage: "",
|
||||||
largeImage: "",
|
largeImage: "",
|
||||||
isContact: false,
|
isContact: false,
|
||||||
isAdded: false,
|
|
||||||
isBlocked: false,
|
isBlocked: false,
|
||||||
requestReceived: false,
|
isContactRequestReceived: false,
|
||||||
|
isContactRequestSent: false,
|
||||||
isSyncing: false,
|
isSyncing: false,
|
||||||
removed: false,
|
removed: false,
|
||||||
trustStatus: Constants.trustStatus.unknown,
|
trustStatus: Constants.trustStatus.unknown,
|
||||||
|
contactRequestState: Constants.ContactRequestState.None,
|
||||||
verificationStatus: Constants.verificationStatus.unverified,
|
verificationStatus: Constants.verificationStatus.unverified,
|
||||||
incomingVerificationStatus: Constants.verificationStatus.unverified,
|
incomingVerificationStatus: Constants.verificationStatus.unverified,
|
||||||
|
socialLinks: [],
|
||||||
|
bio: "",
|
||||||
onlineStatus: Constants.onlineStatus.inactive
|
onlineStatus: Constants.onlineStatus.inactive
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mainModuleInst || !publicKey)
|
if (!mainModuleInst || !publicKey)
|
||||||
return defaultValue
|
return defaultValue
|
||||||
|
|
||||||
const jsonObj = mainModuleInst.getContactDetailsAsJson(publicKey, getVerificationRequest, getOnlineStatus)
|
const jsonObj = mainModuleInst.getContactDetailsAsJson(publicKey, getVerificationRequest, getOnlineStatus, includeDetails)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return JSON.parse(jsonObj)
|
return JSON.parse(jsonObj)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7c9977b780675ab0fa00fb14b10321e4d078b2c4
|
Subproject commit 6403a7413bd1c560d1beada7b4af1698ddc570d8
|
Loading…
Reference in New Issue