feat(savedaddresses): display various cards if an address user is trying to save is known

Closes: #13280
This commit is contained in:
Sale Djenic 2024-01-26 16:28:49 +01:00 committed by saledjenic
parent aaa9937124
commit bbaafa8954
27 changed files with 488 additions and 181 deletions

View File

@ -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.} =

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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, %*[])

View File

@ -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)

View File

@ -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)

View File

@ -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()
} }

View File

@ -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: "",

View File

@ -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 : "")

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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: {

View File

@ -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)

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 7c9977b780675ab0fa00fb14b10321e4d078b2c4 Subproject commit 6403a7413bd1c560d1beada7b4af1698ddc570d8