perf(contacts): make initial contacts fetching async (#16560)
* perf(contacts): make initial contacts fetching async Fixes #16509 * fix: don't fetch contact if we don't have it in cache Fixes #16509 * feat: add a visible loading indicator when the chats are not ready yet
This commit is contained in:
parent
36f2bb79a9
commit
27ececad63
|
@ -2,6 +2,8 @@ const CHAT_SECTION_NAME* = "Messages"
|
|||
const CHAT_SECTION_ICON* = "chat"
|
||||
|
||||
const LOADING_SECTION_ID* = "loadingSection"
|
||||
const LOADING_SECTION_NAME* = "Chat section loading..."
|
||||
const LOADING_SECTION_ICON* = "loading"
|
||||
|
||||
const COMMUNITIESPORTAL_SECTION_ID* = "communitiesPortal"
|
||||
const COMMUNITIESPORTAL_SECTION_NAME* = "Communities Portal"
|
||||
|
|
|
@ -208,9 +208,6 @@ proc getMessageById*(self: Controller, messageId: string): GetMessageResult =
|
|||
proc isUsersListAvailable*(self: Controller): bool =
|
||||
return self.isUsersListAvailable
|
||||
|
||||
proc getMyMutualContacts*(self: Controller): seq[ContactsDto] =
|
||||
return self.contactService.getContactsByGroup(ContactsGroup.MyMutualContacts)
|
||||
|
||||
proc muteChat*(self: Controller, interval: int) =
|
||||
self.chatService.muteChat(self.chatId, interval)
|
||||
|
||||
|
|
|
@ -89,9 +89,6 @@ method unpinMessage*(self: AccessInterface, messageId: string) {.base.} =
|
|||
method getMyChatId*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isMyContact*(self: AccessInterface, contactId: string): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method muteChat*(self: AccessInterface, interval: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, chronicles, sequtils, sugar
|
||||
import NimQml, chronicles, sequtils
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view, controller
|
||||
|
@ -273,9 +273,6 @@ method onPinMessage*(self: Module, messageId: string, actionInitiatedBy: string)
|
|||
method getMyChatId*(self: Module): string =
|
||||
self.controller.getMyChatId()
|
||||
|
||||
method isMyContact*(self: Module, contactId: string): bool =
|
||||
self.controller.getMyMutualContacts().filter(x => x.id == contactId).len > 0
|
||||
|
||||
method muteChat*(self: Module, interval: int) =
|
||||
self.controller.muteChat(interval)
|
||||
|
||||
|
|
|
@ -66,9 +66,6 @@ QtObject:
|
|||
proc getMyChatId*(self: View): string {.slot.} =
|
||||
return self.delegate.getMyChatId()
|
||||
|
||||
proc isMyContact*(self: View, contactId: string): bool {.slot.} =
|
||||
return self.delegate.isMyContact(contactId)
|
||||
|
||||
proc muteChat*(self: View, interval: int) {.slot.} =
|
||||
self.delegate.muteChat(interval)
|
||||
|
||||
|
|
|
@ -263,12 +263,6 @@ method createGroupChat*(self: AccessInterface, groupName: string, pubKeys: seq[s
|
|||
method joinGroupChatFromInvitation*(self: AccessInterface, groupName: string, chatId: string, adminPK: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method initListOfMyContacts*(self: AccessInterface, pubKeys: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method clearListOfMyContacts*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method acceptRequestToJoinCommunity*(self: AccessInterface, requestId: string, communityId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -413,18 +413,6 @@ proc convertPubKeysToJson(self: Module, pubKeys: string): seq[string] =
|
|||
proc showPermissionUpdateNotification(self: Module, community: CommunityDto, tokenPermission: CommunityTokenPermissionDto): bool =
|
||||
return tokenPermission.state == TokenPermissionState.Approved and (community.isControlNode or not tokenPermission.isPrivate) and community.isMember
|
||||
|
||||
method initListOfMyContacts*(self: Module, pubKeys: string) =
|
||||
var myContacts: seq[UserItem]
|
||||
let contacts = self.controller.getContacts(ContactsGroup.MyMutualContacts)
|
||||
for c in contacts:
|
||||
let item = self.createItemFromPublicKey(c.id)
|
||||
myContacts.add(item)
|
||||
|
||||
self.view.listOfMyContacts().addItems(myContacts)
|
||||
|
||||
method clearListOfMyContacts*(self: Module) =
|
||||
self.view.listOfMyContacts().clear()
|
||||
|
||||
method load*(self: Module) =
|
||||
self.controller.init()
|
||||
self.view.load()
|
||||
|
@ -452,7 +440,7 @@ method onChatsLoaded*(
|
|||
if self.membersListModule != nil:
|
||||
self.membersListModule.load()
|
||||
|
||||
if(not self.controller.isCommunity()):
|
||||
if not self.controller.isCommunity():
|
||||
# we do this only in case of chat section (not in case of communities)
|
||||
self.initContactRequestsModel()
|
||||
else:
|
||||
|
|
|
@ -18,8 +18,6 @@ QtObject:
|
|||
tmpChatId: string # shouldn't be used anywhere except in prepareChatContentModuleForChatId/getChatContentModule procs
|
||||
contactRequestsModel: user_model.Model
|
||||
contactRequestsModelVariant: QVariant
|
||||
listOfMyContacts: user_model.Model
|
||||
listOfMyContactsVariant: QVariant
|
||||
editCategoryChannelsModel: chats_model.Model
|
||||
editCategoryChannelsVariant: QVariant
|
||||
loadingHistoryMessagesInProgress: bool
|
||||
|
@ -47,8 +45,6 @@ QtObject:
|
|||
self.activeItemVariant.delete
|
||||
self.contactRequestsModel.delete
|
||||
self.contactRequestsModelVariant.delete
|
||||
self.listOfMyContacts.delete
|
||||
self.listOfMyContactsVariant.delete
|
||||
self.editCategoryChannelsModel.delete
|
||||
self.editCategoryChannelsVariant.delete
|
||||
self.tokenPermissionsModel.delete
|
||||
|
@ -70,8 +66,6 @@ QtObject:
|
|||
result.activeItemVariant = newQVariant(result.activeItem)
|
||||
result.contactRequestsModel = user_model.newModel()
|
||||
result.contactRequestsModelVariant = newQVariant(result.contactRequestsModel)
|
||||
result.listOfMyContacts = user_model.newModel()
|
||||
result.listOfMyContactsVariant = newQVariant(result.listOfMyContacts)
|
||||
result.loadingHistoryMessagesInProgress = false
|
||||
result.tokenPermissionsModel = newTokenPermissionsModel()
|
||||
result.tokenPermissionsVariant = newQVariant(result.tokenPermissionsModel)
|
||||
|
@ -132,25 +126,6 @@ QtObject:
|
|||
QtProperty[QVariant] contactRequestsModel:
|
||||
read = getContactRequestsModel
|
||||
|
||||
proc listOfMyContactsChanged*(self: View) {.signal.}
|
||||
|
||||
proc populateMyContacts*(self: View, pubKeys: string) {.slot.} =
|
||||
self.delegate.initListOfMyContacts(pubKeys)
|
||||
self.listOfMyContactsChanged()
|
||||
|
||||
proc clearMyContacts*(self: View) {.slot.} =
|
||||
self.delegate.clearListOfMyContacts()
|
||||
self.listOfMyContactsChanged()
|
||||
|
||||
proc listOfMyContacts*(self: View): user_model.Model =
|
||||
return self.listOfMyContacts
|
||||
|
||||
proc getListOfMyContacts(self: View): QVariant {.slot.} =
|
||||
return self.listOfMyContactsVariant
|
||||
QtProperty[QVariant] listOfMyContacts:
|
||||
read = getListOfMyContacts
|
||||
notify = listOfMyContactsChanged
|
||||
|
||||
proc activeItemChanged*(self:View) {.signal.}
|
||||
|
||||
proc getActiveItem(self: View): QVariant {.slot.} =
|
||||
|
|
|
@ -143,6 +143,23 @@ proc init*(self: Controller) =
|
|||
self.networksService,
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_CONTACTS_LOADED) do(e:Args):
|
||||
self.delegate.onContactsLoaded(
|
||||
self.events,
|
||||
self.settingsService,
|
||||
self.nodeConfigurationService,
|
||||
self.contactsService,
|
||||
self.chatService,
|
||||
self.communityService,
|
||||
self.messageService,
|
||||
self.mailserversService,
|
||||
self.walletAccountService,
|
||||
self.tokenService,
|
||||
self.communityTokensService,
|
||||
self.sharedUrlsService,
|
||||
self.networksService,
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_CHATS_LOADING_FAILED) do(e:Args):
|
||||
self.delegate.onChatsLoadingFailed()
|
||||
|
||||
|
@ -533,9 +550,6 @@ proc setCurrentUserStatus*(self: Controller, status: StatusType) =
|
|||
proc getContact*(self: Controller, id: string): ContactsDto =
|
||||
return self.contactsService.getContactById(id)
|
||||
|
||||
proc getContacts*(self: Controller, group: ContactsGroup): seq[ContactsDto] =
|
||||
return self.contactsService.getContactsByGroup(group)
|
||||
|
||||
proc getContactNameAndImage*(self: Controller, contactId: string):
|
||||
tuple[name: string, image: string, largeImage: string] =
|
||||
return self.contactsService.getContactNameAndImage(contactId)
|
||||
|
|
|
@ -117,6 +117,24 @@ method onCommunityDataLoaded*(
|
|||
){.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onContactsLoaded*(
|
||||
self: AccessInterface,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
contactsService: contacts_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
communityService: community_service.Service,
|
||||
messageService: message_service.Service,
|
||||
mailserversService: mailservers_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
communityTokensService: community_tokens_service.Service,
|
||||
sharedUrlsService: urls_service.Service,
|
||||
networkService: network_service.Service,
|
||||
){.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onChatsLoadingFailed*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ type
|
|||
moduleLoaded: bool
|
||||
chatsLoaded: bool
|
||||
communityDataLoaded: bool
|
||||
contactsLoaded: bool
|
||||
pendingSpectateRequest: SpectateRequest
|
||||
statusDeepLinkToActivate: string
|
||||
|
||||
|
@ -195,6 +196,7 @@ proc newModule*[T](
|
|||
result.moduleLoaded = false
|
||||
result.chatsLoaded = false
|
||||
result.communityDataLoaded = false
|
||||
result.contactsLoaded = false
|
||||
|
||||
result.events = events
|
||||
result.urlsManager = urlsManager
|
||||
|
@ -502,6 +504,22 @@ method load*[T](
|
|||
if (activeSectionId == ""):
|
||||
activeSectionId = singletonInstance.userProfile.getPubKey()
|
||||
|
||||
let loadingItem = initItem(
|
||||
LOADING_SECTION_ID,
|
||||
SectionType.LoadingSection,
|
||||
conf.LOADING_SECTION_NAME,
|
||||
memberRole = MemberRole.Owner,
|
||||
description = "",
|
||||
image = "",
|
||||
icon = conf.LOADING_SECTION_ICON,
|
||||
color = "",
|
||||
hasNotification = false,
|
||||
notificationsCount = 0,
|
||||
active = false,
|
||||
enabled = true,
|
||||
)
|
||||
self.view.model().addItem(loadingItem)
|
||||
|
||||
# Communities Portal Section
|
||||
let communitiesPortalSectionItem = initItem(
|
||||
conf.COMMUNITIESPORTAL_SECTION_ID,
|
||||
|
@ -518,7 +536,7 @@ method load*[T](
|
|||
enabled = true,
|
||||
)
|
||||
self.view.model().addItem(communitiesPortalSectionItem)
|
||||
if(activeSectionId == communitiesPortalSectionItem.id):
|
||||
if activeSectionId == communitiesPortalSectionItem.id:
|
||||
activeSection = communitiesPortalSectionItem
|
||||
|
||||
# Wallet Section
|
||||
|
@ -539,7 +557,7 @@ method load*[T](
|
|||
enabled = WALLET_ENABLED,
|
||||
)
|
||||
self.view.model().addItem(walletSectionItem)
|
||||
if(activeSectionId == walletSectionItem.id):
|
||||
if activeSectionId == walletSectionItem.id:
|
||||
activeSection = walletSectionItem
|
||||
|
||||
# Node Management Section
|
||||
|
@ -560,7 +578,7 @@ method load*[T](
|
|||
enabled = singletonInstance.localAccountSensitiveSettings.getNodeManagementEnabled(),
|
||||
)
|
||||
self.view.model().addItem(nodeManagementSectionItem)
|
||||
if(activeSectionId == nodeManagementSectionItem.id):
|
||||
if activeSectionId == nodeManagementSectionItem.id:
|
||||
activeSection = nodeManagementSectionItem
|
||||
|
||||
# Profile Section
|
||||
|
@ -581,7 +599,7 @@ method load*[T](
|
|||
enabled = true,
|
||||
)
|
||||
self.view.model().addItem(profileSettingsSectionItem)
|
||||
if(activeSectionId == profileSettingsSectionItem.id):
|
||||
if activeSectionId == profileSettingsSectionItem.id:
|
||||
activeSection = profileSettingsSectionItem
|
||||
|
||||
self.profileSectionModule.load()
|
||||
|
@ -600,25 +618,13 @@ method load*[T](
|
|||
# If section is empty or profile then open the loading section until chats are loaded
|
||||
if activeSection.isEmpty() or activeSection.sectionType == SectionType.ProfileSettings:
|
||||
# Set bogus Item as active until the chat is loaded
|
||||
let loadingItem = initItem(
|
||||
LOADING_SECTION_ID,
|
||||
SectionType.LoadingSection,
|
||||
name = "",
|
||||
memberRole = MemberRole.Owner,
|
||||
description = "",
|
||||
image = "",
|
||||
icon = "",
|
||||
color = "",
|
||||
hasNotification = false,
|
||||
notificationsCount = 0,
|
||||
active = false,
|
||||
enabled = true,
|
||||
)
|
||||
self.view.model().addItem(loadingItem)
|
||||
self.setActiveSection(loadingItem, skipSavingInSettings = true)
|
||||
else:
|
||||
self.setActiveSection(activeSection)
|
||||
|
||||
proc isEverythingLoaded[T](self: Module[T]): bool =
|
||||
return self.communityDataLoaded and self.chatsLoaded and self.contactsLoaded
|
||||
|
||||
method onChatsLoaded*[T](
|
||||
self: Module[T],
|
||||
events: EventEmitter,
|
||||
|
@ -636,11 +642,9 @@ method onChatsLoaded*[T](
|
|||
networkService: network_service.Service,
|
||||
) =
|
||||
self.chatsLoaded = true
|
||||
if not self.communityDataLoaded:
|
||||
if not self.isEverythingLoaded:
|
||||
return
|
||||
|
||||
let myPubKey = singletonInstance.userProfile.getPubKey()
|
||||
|
||||
var activeSection: SectionItem
|
||||
var activeSectionId = singletonInstance.localAccountSensitiveSettings.getActiveSection()
|
||||
if activeSectionId == "" or activeSectionId == conf.SETTINGS_SECTION_ID:
|
||||
|
@ -752,7 +756,43 @@ method onCommunityDataLoaded*[T](
|
|||
networkService: network_service.Service,
|
||||
) =
|
||||
self.communityDataLoaded = true
|
||||
if not self.chatsLoaded:
|
||||
if not self.isEverythingLoaded:
|
||||
return
|
||||
|
||||
self.onChatsLoaded(
|
||||
events,
|
||||
settingsService,
|
||||
nodeConfigurationService,
|
||||
contactsService,
|
||||
chatService,
|
||||
communityService,
|
||||
messageService,
|
||||
mailserversService,
|
||||
walletAccountService,
|
||||
tokenService,
|
||||
communityTokensService,
|
||||
sharedUrlsService,
|
||||
networkService,
|
||||
)
|
||||
|
||||
method onContactsLoaded*[T](
|
||||
self: Module[T],
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
contactsService: contacts_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
communityService: community_service.Service,
|
||||
messageService: message_service.Service,
|
||||
mailserversService: mailservers_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
communityTokensService: community_tokens_service.Service,
|
||||
sharedUrlsService: urls_service.Service,
|
||||
networkService: network_service.Service,
|
||||
) =
|
||||
self.contactsLoaded = true
|
||||
if not self.isEverythingLoaded:
|
||||
return
|
||||
|
||||
self.onChatsLoaded(
|
||||
|
|
|
@ -30,6 +30,9 @@ proc delete*(self: Controller) =
|
|||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_CONTACTS_LOADED) do(e:Args):
|
||||
self.delegate.onContactsLoaded()
|
||||
|
||||
self.events.on(SIGNAL_CONTACT_ADDED) do(e: Args):
|
||||
var args = ContactArgs(e)
|
||||
self.delegate.contactAdded(args.contactId)
|
||||
|
|
|
@ -27,6 +27,9 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
|||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onContactsLoaded*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method switchToOrCreateOneToOneChat*(self: AccessInterface, publicKey: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -118,6 +118,10 @@ method isLoaded*(self: Module): bool =
|
|||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.contactsModuleDidLoad()
|
||||
|
||||
method onContactsLoaded*(self: Module) =
|
||||
self.buildModel(self.view.contactsModel(), ContactsGroup.AllKnownContacts)
|
||||
self.buildModel(self.view.myMutualContactsModel(), ContactsGroup.MyMutualContacts)
|
||||
self.buildModel(self.view.blockedContactsModel(), ContactsGroup.BlockedContacts)
|
||||
|
@ -127,9 +131,6 @@ method viewDidLoad*(self: Module) =
|
|||
# self.buildModel(self.view.receivedButRejectedContactRequestsModel(), ContactsGroup.IncomingRejectedContactRequests)
|
||||
# self.buildModel(self.view.sentButRejectedContactRequestsModel(), ContactsGroup.IncomingRejectedContactRequests)
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.contactsModuleDidLoad()
|
||||
|
||||
method getModuleAsVariant*(self: Module): QVariant =
|
||||
return self.viewVariant
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@ import ../../../app_service/service/community_tokens/community_collectible_owner
|
|||
|
||||
type
|
||||
SectionType* {.pure.} = enum
|
||||
LoadingSection = -1
|
||||
Chat = 0
|
||||
Community,
|
||||
Wallet,
|
||||
ProfileSettings,
|
||||
NodeManagement,
|
||||
CommunitiesPortal
|
||||
CommunitiesPortal,
|
||||
LoadingSection,
|
||||
|
||||
type
|
||||
SectionItem* = object
|
||||
|
|
|
@ -53,9 +53,22 @@ proc lookupContactTask(argEncoded: string) {.gcsafe, nimcall.} =
|
|||
error "error lookupContactTask: ", message = e.msg
|
||||
arg.finish(output)
|
||||
|
||||
#################################################
|
||||
# Async request contact info
|
||||
#################################################
|
||||
type
|
||||
AsyncFetchContactsTaskArg = ref object of QObjectTaskArg
|
||||
pubkey: string
|
||||
|
||||
proc asyncFetchContactsTask(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncFetchContactsTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_contacts.getContacts()
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
"error": "",
|
||||
})
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
})
|
||||
|
||||
type
|
||||
AsyncRequestContactInfoTaskArg = ref object of QObjectTaskArg
|
||||
|
|
|
@ -68,6 +68,7 @@ type
|
|||
|
||||
# Signals which may be emitted by this service:
|
||||
const SIGNAL_ENS_RESOLVED* = "ensResolved"
|
||||
const SIGNAL_CONTACTS_LOADED* = "contactsLoaded"
|
||||
const SIGNAL_CONTACT_ADDED* = "contactAdded"
|
||||
const SIGNAL_CONTACT_BLOCKED* = "contactBlocked"
|
||||
const SIGNAL_CONTACT_UNBLOCKED* = "contactUnblocked"
|
||||
|
@ -142,18 +143,22 @@ QtObject:
|
|||
self.contactsStatus[contact.dto.id] = StatusUpdateDto(publicKey: contact.dto.id, statusType: StatusType.Unknown)
|
||||
|
||||
proc fetchContacts*(self: Service) =
|
||||
let arg = AsyncFetchContactsTaskArg(
|
||||
tptr: asyncFetchContactsTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "fetchContactsDone",
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc fetchContactsDone*(self: Service, response: string) {.slot.} =
|
||||
try:
|
||||
let response = status_contacts.getContacts()
|
||||
|
||||
let contacts = map(response.result.getElems(), proc(x: JsonNode): ContactsDto = x.toContactsDto())
|
||||
|
||||
for contact in contacts:
|
||||
self.addContact(self.constructContactDetails(contact))
|
||||
|
||||
let rpcResponseObj = response.parseJson
|
||||
for elem in rpcResponseObj["response"]["result"].getElems():
|
||||
let contactDto = elem.toContactsDto()
|
||||
self.addContact(self.constructContactDetails(contactDto))
|
||||
self.events.emit(SIGNAL_CONTACTS_LOADED, Args())
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error fetching contacts: ", errDesription
|
||||
return
|
||||
error "error fetching contacts", msg = e.msg
|
||||
|
||||
proc updateAndEmitStatuses(self: Service, statusUpdates: seq[StatusUpdateDto]) =
|
||||
for s in statusUpdates:
|
||||
|
@ -271,37 +276,12 @@ QtObject:
|
|||
|
||||
return contacts
|
||||
|
||||
proc fetchContact(self: Service, id: string): ContactDetails =
|
||||
try:
|
||||
let response = status_contacts.getContactByID(id)
|
||||
|
||||
let contactDto = response.result.toContactsDto()
|
||||
if contactDto.id.len == 0:
|
||||
return
|
||||
|
||||
result = self.constructContactDetails(contactDto)
|
||||
self.addContact(result)
|
||||
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
||||
|
||||
proc generateAlias*(self: Service, publicKey: string): string =
|
||||
if(publicKey.len == 0):
|
||||
error "cannot generate an alias from the empty public key"
|
||||
return
|
||||
return status_accounts.generateAlias(publicKey).result.getStr
|
||||
|
||||
proc getTrustStatus*(self: Service, publicKey: string): TrustStatus =
|
||||
try:
|
||||
let t = status_contacts.getTrustStatus(publicKey).result.getInt
|
||||
return t.toTrustStatus()
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return TrustStatus.Unknown
|
||||
|
||||
proc getContactNameAndImageInternal(self: Service, contactDto: ContactsDto):
|
||||
tuple[name: string, optionalName: string, image: string, largeImage: string] =
|
||||
## This proc should be used accross the app in order to have for the same contact
|
||||
|
@ -334,7 +314,7 @@ QtObject:
|
|||
if len(pubkey) == 0:
|
||||
return
|
||||
|
||||
if(pubkey == singletonInstance.userProfile.getPubKey()):
|
||||
if pubkey == singletonInstance.userProfile.getPubKey():
|
||||
# If we try to get the contact details of ourselves, just return our own info
|
||||
return self.constructContactDetails(
|
||||
ContactsDto(
|
||||
|
@ -355,36 +335,32 @@ QtObject:
|
|||
|
||||
## Returns contact details based on passed id (public key)
|
||||
## If we don't have stored contact localy or in the db then we create it based on public key.
|
||||
if(self.contacts.hasKey(pubkey)):
|
||||
if self.contacts.hasKey(pubkey):
|
||||
return self.contacts[pubkey]
|
||||
|
||||
result = self.fetchContact(pubkey)
|
||||
if result.dto.id.len == 0:
|
||||
if(not pubkey.startsWith("0x")):
|
||||
debug "id is not in a hex format"
|
||||
return
|
||||
if not pubkey.startsWith("0x"):
|
||||
debug "id is not in a hex format"
|
||||
return
|
||||
|
||||
var num64: int64
|
||||
let parsedChars = parseHex(pubkey, num64)
|
||||
if(parsedChars != PK_LENGTH_0X_INCLUDED):
|
||||
debug "id doesn't have expected length"
|
||||
return
|
||||
var num64: int64
|
||||
let parsedChars = parseHex(pubkey, num64)
|
||||
if parsedChars != PK_LENGTH_0X_INCLUDED:
|
||||
debug "id doesn't have expected length"
|
||||
return
|
||||
|
||||
let alias = self.generateAlias(pubkey)
|
||||
let trustStatus = self.getTrustStatus(pubkey)
|
||||
let contact = self.constructContactDetails(
|
||||
ContactsDto(
|
||||
id: pubkey,
|
||||
alias: alias,
|
||||
ensVerified: result.dto.ensVerified,
|
||||
added: result.dto.added,
|
||||
blocked: result.dto.blocked,
|
||||
hasAddedUs: result.dto.hasAddedUs,
|
||||
trustStatus: trustStatus
|
||||
)
|
||||
let contact = self.constructContactDetails(
|
||||
ContactsDto(
|
||||
id: pubkey,
|
||||
alias: self.generateAlias(pubkey),
|
||||
ensVerified: false,
|
||||
added: false,
|
||||
blocked: false,
|
||||
hasAddedUs: false,
|
||||
trustStatus: TrustStatus.Unknown,
|
||||
)
|
||||
self.addContact(contact)
|
||||
return contact
|
||||
)
|
||||
self.addContact(contact)
|
||||
return contact
|
||||
|
||||
proc getContactById*(self: Service, id: string): ContactsDto =
|
||||
return self.getContactDetails(id).dto
|
||||
|
@ -562,13 +538,16 @@ QtObject:
|
|||
checkAndEmitACNotificationsFromResponse(self.events, response.result{"activityCenterNotifications"})
|
||||
|
||||
proc ensResolved*(self: Service, jsonObj: string) {.slot.} =
|
||||
let jsonObj = jsonObj.parseJson()
|
||||
let data = ResolvedContactArgs(
|
||||
pubkey: jsonObj["id"].getStr,
|
||||
address: jsonObj["address"].getStr,
|
||||
uuid: jsonObj["uuid"].getStr,
|
||||
reason: jsonObj["reason"].getStr)
|
||||
self.events.emit(SIGNAL_ENS_RESOLVED, data)
|
||||
try:
|
||||
let jsonObj = jsonObj.parseJson()
|
||||
let data = ResolvedContactArgs(
|
||||
pubkey: jsonObj["id"].getStr,
|
||||
address: jsonObj["address"].getStr,
|
||||
uuid: jsonObj["uuid"].getStr,
|
||||
reason: jsonObj["reason"].getStr)
|
||||
self.events.emit(SIGNAL_ENS_RESOLVED, data)
|
||||
except Exception as e:
|
||||
error "error resolving ENS ", msg=e.msg
|
||||
|
||||
proc resolveENS*(self: Service, value: string, uuid: string = "", reason = "") =
|
||||
if(self.closingApp):
|
||||
|
@ -635,26 +614,29 @@ QtObject:
|
|||
error "error in removeTrustStatus request", msg = e.msg
|
||||
|
||||
proc asyncContactInfoLoaded*(self: Service, pubkeyAndRpcResponse: string) {.slot.} =
|
||||
let rpcResponseObj = pubkeyAndRpcResponse.parseJson
|
||||
let publicKey = rpcResponseObj{"publicKey"}.getStr
|
||||
let requestError = rpcResponseObj{"error"}
|
||||
var error : string
|
||||
try:
|
||||
let rpcResponseObj = pubkeyAndRpcResponse.parseJson
|
||||
let publicKey = rpcResponseObj{"publicKey"}.getStr
|
||||
let requestError = rpcResponseObj{"error"}
|
||||
var error : string
|
||||
|
||||
if requestError.kind != JNull:
|
||||
error = requestError.getStr
|
||||
else:
|
||||
let responseError = rpcResponseObj{"response"}{"error"}
|
||||
if responseError.kind != JNull:
|
||||
error = Json.decode($responseError, RpcError).message
|
||||
if requestError.kind != JNull:
|
||||
error = requestError.getStr
|
||||
else:
|
||||
let responseError = rpcResponseObj{"response"}{"error"}
|
||||
if responseError.kind != JNull:
|
||||
error = Json.decode($responseError, RpcError).message
|
||||
|
||||
if len(error) != 0:
|
||||
error "error requesting contact info", msg = error, publicKey
|
||||
self.events.emit(SIGNAL_CONTACT_INFO_REQUEST_FINISHED, ContactInfoRequestArgs(publicKey: publicKey, ok: false))
|
||||
return
|
||||
if len(error) != 0:
|
||||
error "error requesting contact info", msg = error, publicKey
|
||||
self.events.emit(SIGNAL_CONTACT_INFO_REQUEST_FINISHED, ContactInfoRequestArgs(publicKey: publicKey, ok: false))
|
||||
return
|
||||
|
||||
let contact = rpcResponseObj{"response"}{"result"}.toContactsDto()
|
||||
self.saveContact(contact)
|
||||
self.events.emit(SIGNAL_CONTACT_INFO_REQUEST_FINISHED, ContactInfoRequestArgs(publicKey: publicKey, ok: true))
|
||||
let contact = rpcResponseObj{"response"}{"result"}.toContactsDto()
|
||||
self.saveContact(contact)
|
||||
self.events.emit(SIGNAL_CONTACT_INFO_REQUEST_FINISHED, ContactInfoRequestArgs(publicKey: publicKey, ok: true))
|
||||
except Exception as e:
|
||||
error "error in contact info loaded", msg = e.msg
|
||||
|
||||
proc requestContactInfo*(self: Service, pubkey: string) =
|
||||
try:
|
||||
|
|
|
@ -8,10 +8,6 @@ proc getContacts*(): RpcResponse[JsonNode] =
|
|||
let payload = %* []
|
||||
result = callPrivateRPC("contacts".prefix, payload)
|
||||
|
||||
proc getContactById*(id: string): RpcResponse[JsonNode] =
|
||||
let payload = %* [id]
|
||||
result = callPrivateRPC("getContactByID".prefix, payload)
|
||||
|
||||
proc blockContact*(id: string): RpcResponse[JsonNode] =
|
||||
result = callPrivateRPC("blockContactDesktop".prefix, %* [id])
|
||||
|
||||
|
@ -83,10 +79,6 @@ proc removeTrustStatus*(pubkey: string): RpcResponse[JsonNode] =
|
|||
let payload = %* [pubkey]
|
||||
result = callPrivateRPC("removeTrustStatus".prefix, payload)
|
||||
|
||||
proc getTrustStatus*(pubkey: string): RpcResponse[JsonNode] =
|
||||
let payload = %* [pubkey]
|
||||
result = callPrivateRPC("getTrustStatus".prefix, payload)
|
||||
|
||||
proc retractContactRequest*(pubkey: string): RpcResponse[JsonNode] =
|
||||
let payload = %*[{
|
||||
"id": pubkey
|
||||
|
|
|
@ -25,7 +25,8 @@ TabButton {
|
|||
StatusSmartIdenticon {
|
||||
id: identicon
|
||||
anchors.centerIn: parent
|
||||
asset.isImage: (statusIconTabButton.icon.source.toString() !== "")
|
||||
loading: statusIconTabButton.icon.name === "loading"
|
||||
asset.isImage: loading || statusIconTabButton.icon.source.toString() !== ""
|
||||
asset.name: asset.isImage ?
|
||||
statusIconTabButton.icon.source : statusIconTabButton.icon.name
|
||||
asset.width: asset.isImage ? 28 : statusIconTabButton.icon.width
|
||||
|
|
|
@ -815,7 +815,7 @@ Item {
|
|||
RangeFilter {
|
||||
roleName: "sectionType"
|
||||
minimumValue: Constants.appSection.wallet
|
||||
maximumValue: Constants.appSection.communitiesPortal
|
||||
maximumValue: Constants.appSection.loadingSection
|
||||
},
|
||||
ValueFilter {
|
||||
roleName: "enabled"
|
||||
|
|
|
@ -326,6 +326,7 @@ QtObject {
|
|||
readonly property int profile: 3
|
||||
readonly property int node: 4
|
||||
readonly property int communitiesPortal: 5
|
||||
readonly property int loadingSection: 6
|
||||
}
|
||||
|
||||
readonly property QtObject appViewStackIndex: QtObject {
|
||||
|
|
|
@ -417,6 +417,8 @@ QtObject {
|
|||
return qsTr("Node Management")
|
||||
case Constants.appSection.communitiesPortal:
|
||||
return qsTr("Discover Communities")
|
||||
case Constants.appSection.loadingSection:
|
||||
return qsTr("Chat section loading...")
|
||||
default:
|
||||
return fallback
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue