feat(desktop/contacts) Improvements in contacts

Contacts updates currently in base_bc

Closes #4100
This commit is contained in:
Alexandra Betouni 2021-11-15 10:15:21 -05:00 committed by Alexandra Betouni
parent 4cfc1de6a8
commit b4b28d2f98
46 changed files with 446 additions and 705 deletions

View File

@ -1,9 +1,12 @@
import ./controller_interface import ./controller_interface
import io_interface import io_interface
#import ../../../../core/signals/types
import ../../../../../app_service/service/contacts/service as contacts_service import ../../../../../app_service/service/contacts/service as contacts_service
import ../../../../../app_service/service/contacts/dto/contacts import ../../../../../app_service/service/contacts/dto/contacts
import ../../../../../app_service/service/accounts/service as accounts_service import ../../../../../app_service/service/accounts/service as accounts_service
import status/signals
# import ./item as item # import ./item as item
import eventemitter import eventemitter
@ -16,9 +19,6 @@ type
contactsService: contacts_service.Service contactsService: contacts_service.Service
accountsService: accounts_service.ServiceInterface accountsService: accounts_service.ServiceInterface
# forward declaration:
method getContacts*[T](self: Controller[T]): seq[ContactsDto]
proc newController*[T](delegate: io_interface.AccessInterface, proc newController*[T](delegate: io_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
contactsService: contacts_service.Service, contactsService: contacts_service.Service,
@ -33,56 +33,78 @@ method delete*[T](self: Controller[T]) =
discard discard
method init*[T](self: Controller[T]) = method init*[T](self: Controller[T]) =
self.events.on("contactAdded") do(e: Args): # TODO change this event when chat is refactored
self.contactsService.fetchContacts() # The goal would be to send the event with COntactsDto instead of Profile
let contacts = self.getContacts() self.events.on(SignalType.Message.event) do(e: Args):
self.delegate.setContactList(contacts) let msgData = MessageSignal(e);
if msgData.contacts.len > 0:
var contacts: seq[ContactsDto] = @[]
for contact in msgData.contacts:
contacts.add(ContactsDto(
id: contact.id,
name: contact.username,
ensVerified: contact.ensVerified,
alias: contact.alias,
identicon: contact.identicon,
localNickname: contact.localNickname,
# image: contact.identityImage,
added: contact.added,
blocked: contact.blocked,
hasAddedUs: contact.hasAddedUs
))
self.events.on("contactBlocked") do(e: Args): self.delegate.updateContactList(contacts)
self.contactsService.fetchContacts()
let contacts = self.getContacts()
self.delegate.setContactList(contacts)
self.events.on("contactUnblocked") do(e: Args):
self.contactsService.fetchContacts()
let contacts = self.getContacts()
self.delegate.setContactList(contacts)
self.events.on("contactRemoved") do(e: Args):
self.contactsService.fetchContacts()
let contacts = self.getContacts()
self.delegate.setContactList(contacts)
self.events.on(SIGNAL_CONTACT_LOOKED_UP) do(e: Args): self.events.on(SIGNAL_CONTACT_LOOKED_UP) do(e: Args):
let args = LookupResolvedArgs(e) var args = ContactArgs(e)
self.delegate.contactLookedUp(args.id) self.delegate.contactLookedUp(args.contactId)
self.events.on(SIGNAL_CONTACT_ADDED) do(e: Args):
var args = ContactAddedArgs(e)
self.delegate.contactAdded(args.contact)
self.events.on(SIGNAL_CONTACT_BLOCKED) do(e: Args):
var args = ContactArgs(e)
self.delegate.contactBlocked(args.contactId)
self.events.on(SIGNAL_CONTACT_UNBLOCKED) do(e: Args):
var args = ContactArgs(e)
self.delegate.contactUnblocked(args.contactId)
self.events.on(SIGNAL_CONTACT_REMOVED) do(e: Args):
var args = ContactArgs(e)
self.delegate.contactRemoved(args.contactId)
self.events.on(SIGNAL_CONTACT_NICKNAME_CHANGED) do(e: Args):
var args = ContactNicknameUpdatedArgs(e)
self.delegate.contactNicknameChanged(args.contactId, args.nickname)
method getContacts*[T](self: Controller[T]): seq[ContactsDto] = method getContacts*[T](self: Controller[T]): seq[ContactsDto] =
return self.contactsService.getContacts() return self.contactsService.getContacts()
method getContact*[T](self: Controller[T], id: string): ContactsDto = method getContact*[T](self: Controller[T], id: string): ContactsDto =
return self.contactsService.getContact(id) return self.contactsService.getContactById(id)
method generateAlias*[T](self: Controller[T], publicKey: string): string = method generateAlias*[T](self: Controller[T], publicKey: string): string =
return self.accountsService.generateAlias(publicKey) return self.accountsService.generateAlias(publicKey)
method addContact*[T](self: Controller[T], publicKey: string): void = method addContact*[T](self: Controller[T], publicKey: string) =
self.contactsService.addContact(publicKey) self.contactsService.addContact(publicKey)
method rejectContactRequest*[T](self: Controller[T], publicKey: string): void = method rejectContactRequest*[T](self: Controller[T], publicKey: string) =
self.contactsService.rejectContactRequest(publicKey) self.contactsService.rejectContactRequest(publicKey)
method unblockContact*[T](self: Controller[T], publicKey: string): void = method unblockContact*[T](self: Controller[T], publicKey: string) =
self.contactsService.unblockContact(publicKey) self.contactsService.unblockContact(publicKey)
method blockContact*[T](self: Controller[T], publicKey: string): void = method blockContact*[T](self: Controller[T], publicKey: string) =
self.contactsService.blockContact(publicKey) self.contactsService.blockContact(publicKey)
method removeContact*[T](self: Controller[T], publicKey: string): void = method removeContact*[T](self: Controller[T], publicKey: string) =
self.contactsService.removeContact(publicKey) self.contactsService.removeContact(publicKey)
method changeContactNickname*[T](self: Controller[T], accountKeyUID: string, publicKey: string, nicknameToSet: string): void = method changeContactNickname*[T](self: Controller[T], publicKey: string, nickname: string) =
self.contactsService.changeContactNickname(accountKeyUID, publicKey, nicknameToSet) self.contactsService.changeContactNickname(publicKey, nickname)
method lookupContact*[T](self: Controller[T], value: string): void = method lookupContact*[T](self: Controller[T], value: string) =
self.contactsService.lookupContact(value) self.contactsService.lookupContact(value)

View File

@ -13,6 +13,9 @@ method load*(self: AccessInterface) {.base.} =
method setContactList*(self: AccessInterface, contacts: seq[ContactsDto]) {.base.} = method setContactList*(self: AccessInterface, contacts: seq[ContactsDto]) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method updateContactList*(self: AccessInterface, contacts: seq[ContactsDto]) {.base.} =
raise newException(ValueError, "No implementation available")
method isLoaded*(self: AccessInterface): bool {.base.} = method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
@ -22,28 +25,43 @@ method getContact*(self: AccessInterface, id: string): ContactsDto {.base.} =
method generateAlias*(self: AccessInterface, publicKey: string): string {.base.} = method generateAlias*(self: AccessInterface, publicKey: string): string {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method addContact*(self: AccessInterface, publicKey: string): void {.base.} = method addContact*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method rejectContactRequest*(self: AccessInterface, publicKey: string): void {.base.} = method contactAdded*(self: AccessInterface, contact: ContactsDto) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method unblockContact*(self: AccessInterface, publicKey: string): void {.base.} = method contactBlocked*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method blockContact*(self: AccessInterface, publicKey: string): void {.base.} = method contactUnblocked*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method removeContact*(self: AccessInterface, publicKey: string): void {.base.} = method contactRemoved*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method changeContactNickname*(self: AccessInterface, accountKeyUID: string, publicKey: string, nicknameToSet: string): void {.base.} = method contactNicknameChanged*(self: AccessInterface, publicKey: string, nickname: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method lookupContact*(self: AccessInterface, value: string): void {.base.} = method rejectContactRequest*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method contactLookedUp*(self: AccessInterface, id: string): void {.base.} = method unblockContact*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method blockContact*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method removeContact*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method changeContactNickname*(self: AccessInterface, publicKey: string, nickname: string) {.base.} =
raise newException(ValueError, "No implementation available")
method lookupContact*(self: AccessInterface, value: string) {.base.} =
raise newException(ValueError, "No implementation available")
method contactLookedUp*(self: AccessInterface, id: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
type type

View File

@ -36,6 +36,37 @@ QtObject:
proc contactListChanged*(self: Model) {.signal.} proc contactListChanged*(self: Model) {.signal.}
proc contactRequestAdded*(self: Model, name: string, address: string) {.signal.} proc contactRequestAdded*(self: Model, name: string, address: string) {.signal.}
proc contactAdded*(self: Model, contact: ContactsDto) =
self.contactList.updateContact(contact)
self.addedContacts.addContactToList(contact)
self.blockedContacts.removeContactFromList(contact.id)
self.contactRequests.removeContactFromList(contact.id)
self.contactListChanged()
proc contactBlocked*(self: Model, contact: ContactsDto) =
self.contactList.updateContact(contact)
self.addedContacts.removeContactFromList(contact.id)
self.blockedContacts.addContactToList(contact)
self.contactRequests.removeContactFromList(contact.id)
self.contactListChanged()
proc contactUnblocked*(self: Model, contact: ContactsDto) =
self.contactList.updateContact(contact)
self.blockedContacts.removeContactFromList(contact.id)
self.contactListChanged()
proc contactRemoved*(self: Model, contact: ContactsDto) =
self.contactList.updateContact(contact)
self.addedContacts.removeContactFromList(contact.id)
self.contactRequests.removeContactFromList(contact.id)
self.contactListChanged()
proc changeNicknameForContactWithId*(self: Model, id: string, nickname: string) =
self.contactList.changeNicknameForContactWithId(id, nickname)
self.addedContacts.changeNicknameForContactWithId(id, nickname)
self.blockedContacts.changeNicknameForContactWithId(id, nickname)
self.contactRequests.changeNicknameForContactWithId(id, nickname)
proc updateContactList*(self: Model, contacts: seq[ContactsDto]) = proc updateContactList*(self: Model, contacts: seq[ContactsDto]) =
for contact in contacts: for contact in contacts:
var requestAlreadyAdded = false var requestAlreadyAdded = false
@ -115,5 +146,3 @@ proc contactRequestReceived*(self: Model, pubkey: string): bool {.slot.} =
if contact.id == pubkey: if contact.id == pubkey:
return true return true
return false return false

View File

@ -73,8 +73,7 @@ QtObject:
of "isBlocked": result = $contact.isBlocked() of "isBlocked": result = $contact.isBlocked()
of "alias": result = contact.alias of "alias": result = contact.alias
of "ensVerified": result = $contact.ensVerified of "ensVerified": result = $contact.ensVerified
# TODO check if localNickname exists in the contact ContactsDto of "localNickname": result = $contact.localNickname
of "localNickname": result = ""#$contact.localNickname
of "thumbnailImage": result = $contact.image.thumbnail of "thumbnailImage": result = $contact.image.thumbnail
of "largeImage": result = $contact.image.large of "largeImage": result = $contact.image.large
of "requestReceived": result = $contact.requestReceived() of "requestReceived": result = $contact.requestReceived()
@ -94,7 +93,7 @@ QtObject:
of ContactRoles.IsBlocked: result = newQVariant(contact.isBlocked()) of ContactRoles.IsBlocked: result = newQVariant(contact.isBlocked())
of ContactRoles.Alias: result = newQVariant(contact.alias) of ContactRoles.Alias: result = newQVariant(contact.alias)
of ContactRoles.EnsVerified: result = newQVariant(contact.ensVerified) of ContactRoles.EnsVerified: result = newQVariant(contact.ensVerified)
of ContactRoles.LocalNickname: result = newQVariant("")#newQVariant(contact.localNickname) of ContactRoles.LocalNickname: result = newQVariant(contact.localNickname)
of ContactRoles.ThumbnailImage: result = newQVariant(contact.image.thumbnail) of ContactRoles.ThumbnailImage: result = newQVariant(contact.image.thumbnail)
of ContactRoles.LargeImage: result = newQVariant(contact.image.large) of ContactRoles.LargeImage: result = newQVariant(contact.image.large)
of ContactRoles.RequestReceived: result = newQVariant(contact.requestReceived()) of ContactRoles.RequestReceived: result = newQVariant(contact.requestReceived())
@ -116,23 +115,38 @@ QtObject:
}.toTable }.toTable
proc addContactToList*(self: ContactList, contact: ContactsDto) = proc addContactToList*(self: ContactList, contact: ContactsDto) =
let index = self.getContactIndexByPubkey(contact.id)
if index > -1:
return
self.beginInsertRows(newQModelIndex(), self.contacts.len, self.contacts.len) self.beginInsertRows(newQModelIndex(), self.contacts.len, self.contacts.len)
self.contacts.add(contact) self.contacts.add(contact)
self.endInsertRows() self.endInsertRows()
self.countChanged() self.countChanged()
proc removeContactFromList*(self: ContactList, pubkey: string) =
let index = self.getContactIndexByPubkey(pubkey)
if index == -1:
return
self.beginRemoveRows(newQModelIndex(), index, index)
self.contacts.delete(index)
self.endRemoveRows()
self.countChanged()
proc hasAddedContacts(self: ContactList): bool {.slot.} = proc hasAddedContacts(self: ContactList): bool {.slot.} =
for c in self.contacts: for c in self.contacts:
if(c.isContact()): return true if(c.isContact()): return true
return false return false
# There are much better ways of notifying qml about this change than sending this signal.
# It also may has an impact to the app performances since it's handled on multiple places on the qml side.
# Would be good to get rid of it durign refactor phase.
proc contactChanged*(self: ContactList, pubkey: string) {.signal.} proc contactChanged*(self: ContactList, pubkey: string) {.signal.}
proc updateContact*(self: ContactList, contact: ContactsDto) = proc updateContact*(self: ContactList, contact: ContactsDto) =
var found = false var found = false
let topLeft = self.createIndex(0, 0, nil) let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.contacts.len, 0, nil) let bottomRight = self.createIndex(self.contacts.len, 0, nil)
for c in self.contacts: for c in self.contacts.mitems:
if(c.id != contact.id): continue if(c.id != contact.id): continue
found = true found = true
c.ensVerified = contact.ensVerified c.ensVerified = contact.ensVerified
@ -151,3 +165,16 @@ QtObject:
self.contacts = contactList self.contacts = contactList
self.endResetModel() self.endResetModel()
self.countChanged() self.countChanged()
proc changeNicknameForContactWithId*(self: ContactList, id: string, nickname: string) =
for i in 0 ..< self.contacts.len:
if(self.contacts[i].id != id):
continue
let index = self.createIndex(i, 0, nil)
self.contacts[i].localNickname = nickname
self.dataChanged(index, index, @[ContactRoles.LocalNickname.int])
# Wrote about it where this signal is defined, it's emitted from here just because of the qml part.
self.contactChanged(self.contacts[i].id)
return

View File

@ -1,7 +1,9 @@
import NimQml, Tables import NimQml, Tables
import ./io_interface, ./view, ./controller #import ./io_interface, ./view, ./controller
import io_interface, view, controller, model
import ../../../../core/global_singleton import ../../../../core/global_singleton
#import ../../../../global/global_singleton
import ../../../../../app_service/service/contacts/service as contacts_service import ../../../../../app_service/service/contacts/service as contacts_service
import ../../../../../app_service/service/contacts/dto/contacts import ../../../../../app_service/service/contacts/dto/contacts
@ -37,7 +39,10 @@ method delete*[T](self: Module[T]) =
self.view.delete self.view.delete
method setContactList*[T](self: Module[T], contacts: seq[ContactsDto]) = method setContactList*[T](self: Module[T], contacts: seq[ContactsDto]) =
self.view.setContactList(contacts) self.view.model().setContactList(contacts)
method updateContactList*[T](self: Module[T], contacts: seq[ContactsDto]) =
self.view.model().updateContactList(contacts)
method load*[T](self: Module[T]) = method load*[T](self: Module[T]) =
self.controller.init() self.controller.init()
@ -54,26 +59,47 @@ method getContact*[T](self: Module[T], id: string): ContactsDto =
method generateAlias*[T](self: Module[T], publicKey: string): string = method generateAlias*[T](self: Module[T], publicKey: string): string =
self.controller.generateAlias(publicKey) self.controller.generateAlias(publicKey)
method addContact*[T](self: Module[T], publicKey: string): void = method addContact*[T](self: Module[T], publicKey: string) =
self.controller.addContact(publicKey) self.controller.addContact(publicKey)
method rejectContactRequest*[T](self: Module[T], publicKey: string): void = method contactAdded*[T](self: Module[T], contact: ContactsDto) =
self.view.model().contactAdded(contact)
method contactBlocked*[T](self: Module[T], publicKey: string) =
# once we refactore a model, we should pass only pk from here (like we have for nickname change)
let contact = self.controller.getContact(publicKey)
self.view.model().contactBlocked(contact)
method contactUnblocked*[T](self: Module[T], publicKey: string) =
# once we refactore a model, we should pass only pk from here (like we have for nickname change)
let contact = self.controller.getContact(publicKey)
self.view.model().contactUnblocked(contact)
method contactRemoved*[T](self: Module[T], publicKey: string) =
# once we refactore a model, we should pass only pk from here (like we have for nickname change)
let contact = self.controller.getContact(publicKey)
self.view.model().contactRemoved(contact)
method contactNicknameChanged*[T](self: Module[T], publicKey: string, nickname: string) =
self.view.model().changeNicknameForContactWithId(publicKey, nickname)
method rejectContactRequest*[T](self: Module[T], publicKey: string) =
self.controller.rejectContactRequest(publicKey) self.controller.rejectContactRequest(publicKey)
method unblockContact*[T](self: Module[T], publicKey: string): void = method unblockContact*[T](self: Module[T], publicKey: string) =
self.controller.unblockContact(publicKey) self.controller.unblockContact(publicKey)
method blockContact*[T](self: Module[T], publicKey: string): void = method blockContact*[T](self: Module[T], publicKey: string) =
self.controller.blockContact(publicKey) self.controller.blockContact(publicKey)
method removeContact*[T](self: Module[T], publicKey: string): void = method removeContact*[T](self: Module[T], publicKey: string) =
self.controller.removeContact(publicKey) self.controller.removeContact(publicKey)
method changeContactNickname*[T](self: Module[T], accountKeyUID: string, publicKey: string, nicknameToSet: string): void = method changeContactNickname*[T](self: Module[T], accountKeyUID: string, publicKey: string, nicknameToSet: string): void =
self.controller.changeContactNickname(accountKeyUID, publicKey, nicknameToSet) self.controller.changeContactNickname(accountKeyUID, publicKey, nicknameToSet)
method lookupContact*[T](self: Module[T], value: string): void = method lookupContact*[T](self: Module[T], value: string) =
self.controller.lookupContact(value) self.controller.lookupContact(value)
method contactLookedUp*[T](self: Module[T], id: string): void = method contactLookedUp*[T](self: Module[T], id: string) =
self.view.contactLookedUp(id) self.view.contactLookedUp(id)

View File

@ -19,7 +19,6 @@ QtObject:
model: Model model: Model
modelVariant: QVariant modelVariant: QVariant
contactToAdd*: ContactsDto contactToAdd*: ContactsDto
accountKeyUID*: string
proc delete*(self: View) = proc delete*(self: View) =
self.model.delete self.model.delete
@ -34,8 +33,8 @@ QtObject:
result.modelVariant = newQVariant(result.model) result.modelVariant = newQVariant(result.model)
result.contactToAdd = ContactsDto() result.contactToAdd = ContactsDto()
proc setContactList*(self: View, contacts: seq[ContactsDto]) = proc model*(self: View): Model =
self.model.setContactList(contacts) return self.model
proc modelChanged*(self: View) {.signal.} proc modelChanged*(self: View) {.signal.}
@ -79,7 +78,7 @@ QtObject:
let contact = self.delegate.getContact(id) let contact = self.delegate.getContact(id)
if contact != nil and contact.id != "": if contact.id != "":
self.contactToAdd = contact self.contactToAdd = contact
else: else:
self.contactToAdd = ContactsDto( self.contactToAdd = ContactsDto(
@ -98,8 +97,6 @@ QtObject:
proc addContact*(self: View, publicKey: string) {.slot.} = proc addContact*(self: View, publicKey: string) {.slot.} =
self.delegate.addContact(publicKey) self.delegate.addContact(publicKey)
# TODO add back joining of timeline
# self.status.chat.join(status_utils.getTimelineChatId(publicKey), ChatType.Profile, "", publicKey)
proc rejectContactRequest*(self: View, publicKey: string) {.slot.} = proc rejectContactRequest*(self: View, publicKey: string) {.slot.} =
self.delegate.rejectContactRequest(publicKey) self.delegate.rejectContactRequest(publicKey)
@ -115,10 +112,7 @@ QtObject:
self.addContact(pubkey.getStr) self.addContact(pubkey.getStr)
proc changeContactNickname*(self: View, publicKey: string, nickname: string) {.slot.} = proc changeContactNickname*(self: View, publicKey: string, nickname: string) {.slot.} =
var nicknameToSet = nickname self.delegate.changeContactNickname(publicKey, nickname)
if (nicknameToSet == ""):
nicknameToSet = DELETE_CONTACT
self.delegate.changeContactNickname(publicKey, nicknameToSet, self.accountKeyUID)
proc unblockContact*(self: View, publicKey: string) {.slot.} = proc unblockContact*(self: View, publicKey: string) {.slot.} =
self.delegate.unblockContact(publicKey) self.delegate.unblockContact(publicKey)
@ -131,7 +125,3 @@ QtObject:
proc removeContact*(self: View, publicKey: string) {.slot.} = proc removeContact*(self: View, publicKey: string) {.slot.} =
self.delegate.removeContact(publicKey) self.delegate.removeContact(publicKey)
# TODO add back leaving timeline
# let channelId = status_utils.getTimelineChatId(publicKey)
# if self.status.chat.hasChannel(channelId):
# self.status.chat.leave(channelId)

View File

@ -11,7 +11,7 @@ import ../../app_service/[main]
import ../../app_service/tasks/marathon/mailserver/events import ../../app_service/tasks/marathon/mailserver/events
import eventemitter import eventemitter
import view import view
import views/[ens_manager, devices, network, mailservers, contacts, muted_chats] import views/[ens_manager, devices, network, mailservers, muted_chats]
import ../chat/views/channels_list import ../chat/views/channels_list
import chronicles import chronicles
@ -71,9 +71,6 @@ proc init*(self: ProfileController, account: Account) =
let mailserver = MailServer(name: mailserver["name"].getStr(), endpoint: mailserver["address"].getStr()) let mailserver = MailServer(name: mailserver["name"].getStr(), endpoint: mailserver["address"].getStr())
self.view.mailservers.add(mailserver) self.view.mailservers.add(mailserver)
let contacts = self.status.contacts.getContacts()
self.view.contacts.setContactList(contacts)
self.status.events.on("channelLoaded") do(e: Args): self.status.events.on("channelLoaded") do(e: Args):
var channel = ChannelArgs(e) var channel = ChannelArgs(e)
if channel.chat.muted: if channel.chat.muted:
@ -98,24 +95,6 @@ proc init*(self: ProfileController, account: Account) =
var evArgs = ChatUpdateArgs(e) var evArgs = ChatUpdateArgs(e)
self.view.mutedChats.updateChats(evArgs.chats) self.view.mutedChats.updateChats(evArgs.chats)
self.status.events.on("contactAdded") do(e: Args):
let contacts = self.status.contacts.getContacts()
self.view.contacts.setContactList(contacts)
self.view.contactsChanged()
self.status.events.on("contactBlocked") do(e: Args):
let contacts = self.status.contacts.getContacts()
self.view.contacts.setContactList(contacts)
self.status.events.on("contactUnblocked") do(e: Args):
let contacts = self.status.contacts.getContacts()
self.view.contacts.setContactList(contacts)
self.status.events.on("contactRemoved") do(e: Args):
let contacts = self.status.contacts.getContacts()
self.view.contacts.setContactList(contacts)
self.view.contactsChanged()
self.status.events.on("mailserver:changed") do(e: Args): self.status.events.on("mailserver:changed") do(e: Args):
let mailserverArg = MailserverArgs(e) let mailserverArg = MailserverArgs(e)
self.view.mailservers.activeMailserverChanged(mailserverArg.peer) self.view.mailservers.activeMailserverChanged(mailserverArg.peer)
@ -138,10 +117,6 @@ proc init*(self: ProfileController, account: Account) =
self.status.events.on(SignalType.Message.event) do(e: Args): self.status.events.on(SignalType.Message.event) do(e: Args):
let msgData = MessageSignal(e); let msgData = MessageSignal(e);
if msgData.contacts.len > 0:
# TODO: view should react to model changes
let contacts = self.status.contacts.getContacts(false)
self.view.contacts.updateContactList(contacts)
if msgData.installations.len > 0: if msgData.installations.len > 0:
self.view.devices.addDevices(msgData.installations) self.view.devices.addDevices(msgData.installations)

View File

@ -1,5 +1,5 @@
import NimQml, sequtils, strutils, sugar, os, json, chronicles import NimQml, sequtils, strutils, sugar, os, json, chronicles
import views/[mailservers_list, ens_manager, contacts, devices, mailservers, mnemonic, network, fleets, profile_info, device_list, profile_picture, muted_chats] import views/[mailservers_list, ens_manager, devices, mailservers, mnemonic, network, fleets, profile_info, device_list, profile_picture, muted_chats]
import chronicles import chronicles
import qrcode/qrcode import qrcode/qrcode
@ -7,7 +7,6 @@ import qrcode/qrcode
import status/statusgo_backend/eth as eth import status/statusgo_backend/eth as eth
import status/statusgo_backend/accounts as status_accounts import status/statusgo_backend/accounts as status_accounts
import status/profile as status_profile import status/profile as status_profile
import status/contacts as status_contacts
import status/status import status/status
import status/ens as status_ens import status/ens as status_ens
import status/chat/chat import status/chat/chat
@ -28,7 +27,6 @@ QtObject:
profile*: ProfileInfoView profile*: ProfileInfoView
profilePicture*: ProfilePictureView profilePicture*: ProfilePictureView
mutedChats*: MutedChatsView mutedChats*: MutedChatsView
contacts*: ContactsView
devices*: DevicesView devices*: DevicesView
mailservers*: MailserversView mailservers*: MailserversView
mnemonic*: MnemonicView mnemonic*: MnemonicView
@ -43,7 +41,6 @@ QtObject:
self.QObject.setup self.QObject.setup
proc delete*(self: ProfileView) = proc delete*(self: ProfileView) =
if not self.contacts.isNil: self.contacts.delete
if not self.devices.isNil: self.devices.delete if not self.devices.isNil: self.devices.delete
if not self.ens.isNil: self.ens.delete if not self.ens.isNil: self.ens.delete
if not self.profilePicture.isNil: self.profilePicture.delete if not self.profilePicture.isNil: self.profilePicture.delete
@ -62,7 +59,6 @@ QtObject:
result.profile = newProfileInfoView() result.profile = newProfileInfoView()
result.profilePicture = newProfilePictureView(status, result.profile) result.profilePicture = newProfilePictureView(status, result.profile)
result.mutedChats = newMutedChatsView(status) result.mutedChats = newMutedChatsView(status)
result.contacts = newContactsView(status, appService)
result.devices = newDevicesView(status) result.devices = newDevicesView(status)
result.network = newNetworkView(status) result.network = newNetworkView(status)
result.mnemonic = newMnemonicView(status) result.mnemonic = newMnemonicView(status)
@ -83,7 +79,6 @@ QtObject:
proc setNewProfile*(self: ProfileView, profile: Profile) = proc setNewProfile*(self: ProfileView, profile: Profile) =
self.profile.setProfile(profile) self.profile.setProfile(profile)
self.contacts.accountKeyUID = profile.address
self.profileChanged() self.profileChanged()
QtProperty[QVariant] profile: QtProperty[QVariant] profile:
@ -142,13 +137,6 @@ QtObject:
proc contactsChanged*(self: ProfileView) {.signal.} proc contactsChanged*(self: ProfileView) {.signal.}
proc getContacts*(self: ProfileView): QVariant {.slot.} =
newQVariant(self.contacts)
QtProperty[QVariant] contacts:
read = getContacts
notify = contactsChanged
proc getDevices*(self: ProfileView): QVariant {.slot.} = proc getDevices*(self: ProfileView): QVariant {.slot.} =
newQVariant(self.devices) newQVariant(self.devices)

View File

@ -1,154 +0,0 @@
import NimQml, chronicles
import Tables
import status/types/profile
from status/ens import nil
type
ContactRoles {.pure.} = enum
PubKey = UserRole + 1
Name = UserRole + 2,
Address = UserRole + 3
Identicon = UserRole + 4
IsContact = UserRole + 5
IsBlocked = UserRole + 6
Alias = UserRole + 7
EnsVerified = UserRole + 8
LocalNickname = UserRole + 9
ThumbnailImage = UserRole + 10
LargeImage = UserRole + 11
RequestReceived = UserRole + 12
QtObject:
type ContactList* = ref object of QAbstractListModel
contacts*: seq[Profile]
proc setup(self: ContactList) = self.QAbstractListModel.setup
proc delete(self: ContactList) =
self.contacts = @[]
self.QAbstractListModel.delete
proc newContactList*(): ContactList =
new(result, delete)
# TODO: (rramos) contacts should be a table[string, Profile] instead, with the key being the public key
# This is to optimize determining if a contact is part of the contact list or not
# (including those that do not have a system tag)
result.contacts = @[]
result.setup
method rowCount(self: ContactList, index: QModelIndex = nil): int =
return self.contacts.len
proc countChanged*(self: ContactList) {.signal.}
proc count*(self: ContactList): int {.slot.} =
self.contacts.len
QtProperty[int] count:
read = count
notify = countChanged
proc userName*(self: ContactList, pubKey: string, defaultValue: string = ""): string {.slot.} =
for contact in self.contacts:
if(contact.id != pubKey): continue
return ens.userNameOrAlias(contact)
return defaultValue
proc getContactIndexByPubkey(self: ContactList, pubkey: string): int {.slot.} =
var i = 0
for contact in self.contacts:
if (contact.id == pubkey):
return i
i = i + 1
return -1
proc rowData(self: ContactList, index: int, column: string): string {.slot.} =
let contact = self.contacts[index]
case column:
of "name": result = ens.userNameOrAlias(contact)
of "address": result = contact.address
of "identicon": result = contact.identicon
of "pubKey": result = contact.id
of "isContact": result = $contact.isContact()
of "isBlocked": result = $contact.isBlocked()
of "alias": result = contact.alias
of "ensVerified": result = $contact.ensVerified
of "localNickname": result = $contact.localNickname
of "thumbnailImage": result = $contact.identityImage.thumbnail
of "largeImage": result = $contact.identityImage.large
of "requestReceived": result = $contact.requestReceived()
method data(self: ContactList, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.contacts.len:
return
let contact = self.contacts[index.row]
case role.ContactRoles:
of ContactRoles.Name: result = newQVariant(ens.userNameOrAlias(contact))
of ContactRoles.Address: result = newQVariant(contact.address)
of ContactRoles.Identicon: result = newQVariant(contact.identicon)
of ContactRoles.PubKey: result = newQVariant(contact.id)
of ContactRoles.IsContact: result = newQVariant(contact.isContact())
of ContactRoles.IsBlocked: result = newQVariant(contact.isBlocked())
of ContactRoles.Alias: result = newQVariant(contact.alias)
of ContactRoles.EnsVerified: result = newQVariant(contact.ensVerified)
of ContactRoles.LocalNickname: result = newQVariant(contact.localNickname)
of ContactRoles.ThumbnailImage: result = newQVariant(contact.identityImage.thumbnail)
of ContactRoles.LargeImage: result = newQVariant(contact.identityImage.large)
of ContactRoles.RequestReceived: result = newQVariant(contact.requestReceived())
method roleNames(self: ContactList): Table[int, string] =
{
ContactRoles.Name.int:"name",
ContactRoles.Address.int:"address",
ContactRoles.Identicon.int:"identicon",
ContactRoles.PubKey.int:"pubKey",
ContactRoles.IsContact.int:"isContact",
ContactRoles.IsBlocked.int:"isBlocked",
ContactRoles.Alias.int:"alias",
ContactRoles.LocalNickname.int:"localNickname",
ContactRoles.EnsVerified.int:"ensVerified",
ContactRoles.ThumbnailImage.int:"thumbnailImage",
ContactRoles.LargeImage.int:"largeImage",
ContactRoles.RequestReceived.int:"requestReceived"
}.toTable
proc addContactToList*(self: ContactList, contact: Profile) =
self.beginInsertRows(newQModelIndex(), self.contacts.len, self.contacts.len)
self.contacts.add(contact)
self.endInsertRows()
self.countChanged()
proc hasAddedContacts(self: ContactList): bool {.slot.} =
for c in self.contacts:
if(c.isContact()): return true
return false
proc contactChanged*(self: ContactList, pubkey: string) {.signal.}
proc updateContact*(self: ContactList, contact: Profile) =
var found = false
let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.contacts.len, 0, nil)
for c in self.contacts:
if(c.id != contact.id): continue
found = true
c.ensName = contact.ensName
c.ensVerified = contact.ensVerified
c.identityImage = contact.identityImage
c.added = contact.added
c.blocked = contact.blocked
if not found:
self.addContactToList(contact)
else:
self.dataChanged(topLeft, bottomRight, @[ContactRoles.Name.int])
self.contactChanged(contact.id)
proc setNewData*(self: ContactList, contactList: seq[Profile]) =
self.beginResetModel()
self.contacts = contactList
self.endResetModel()
self.countChanged()

View File

@ -1,241 +0,0 @@
import NimQml, chronicles, sequtils, sugar, strutils, json
import status/utils as status_utils
import status/status
import status/chat/chat
import status/types/profile
import status/ens as status_ens
import contact_list
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
logScope:
topics = "contacts-view"
type
LookupContactTaskArg = ref object of QObjectTaskArg
value: string
const lookupContactTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[LookupContactTaskArg](argEncoded)
var id = arg.value
if not id.startsWith("0x"):
id = status_ens.pubkey(id)
arg.finish(id)
proc lookupContact[T](self: T, slot: string, value: string) =
let arg = LookupContactTaskArg(
tptr: cast[ByteAddress](lookupContactTask),
vptr: cast[ByteAddress](self.vptr),
slot: slot,
value: value
)
self.appService.threadpool.start(arg)
QtObject:
type ContactsView* = ref object of QObject
status: Status
appService: AppService
contactList*: ContactList
contactRequests*: ContactList
addedContacts*: ContactList
blockedContacts*: ContactList
contactToAdd*: Profile
accountKeyUID*: string
proc setup(self: ContactsView) =
self.QObject.setup
proc delete*(self: ContactsView) =
self.contactList.delete
self.addedContacts.delete
self.contactRequests.delete
self.blockedContacts.delete
self.QObject.delete
proc newContactsView*(status: Status, appService: AppService): ContactsView =
new(result, delete)
result.status = status
result.appService = appService
result.contactList = newContactList()
result.contactRequests = newContactList()
result.addedContacts = newContactList()
result.blockedContacts = newContactList()
result.contactToAdd = Profile(
username: "",
alias: "",
ensName: ""
)
result.setup
proc contactListChanged*(self: ContactsView) {.signal.}
proc contactRequestAdded*(self: ContactsView, name: string, address: string) {.signal.}
proc updateContactList*(self: ContactsView, contacts: seq[Profile]) =
for contact in contacts:
var requestAlreadyAdded = false
for existingContact in self.contactList.contacts:
if existingContact.address == contact.address and existingContact.requestReceived():
requestAlreadyAdded = true
break
self.contactList.updateContact(contact)
if contact.added:
self.addedContacts.updateContact(contact)
if contact.isBlocked():
self.blockedContacts.updateContact(contact)
if contact.requestReceived() and not contact.added and not contact.blocked:
self.contactRequests.updateContact(contact)
if not requestAlreadyAdded and contact.requestReceived():
self.contactRequestAdded(status_ens.userNameOrAlias(contact), contact.address)
self.contactListChanged()
proc getContactList(self: ContactsView): QVariant {.slot.} =
return newQVariant(self.contactList)
proc setContactList*(self: ContactsView, contactList: seq[Profile]) =
self.contactList.setNewData(contactList)
self.addedContacts.setNewData(contactList.filter(c => c.added))
self.blockedContacts.setNewData(contactList.filter(c => c.blocked))
self.contactRequests.setNewData(contactList.filter(c => c.hasAddedUs and not c.added and not c.blocked))
self.contactListChanged()
QtProperty[QVariant] list:
read = getContactList
write = setContactList
notify = contactListChanged
proc getAddedContacts(self: ContactsView): QVariant {.slot.} =
return newQVariant(self.addedContacts)
QtProperty[QVariant] addedContacts:
read = getAddedContacts
notify = contactListChanged
proc getBlockedContacts(self: ContactsView): QVariant {.slot.} =
return newQVariant(self.blockedContacts)
QtProperty[QVariant] blockedContacts:
read = getBlockedContacts
notify = contactListChanged
proc isContactBlocked*(self: ContactsView, pubkey: string): bool {.slot.} =
for contact in self.blockedContacts.contacts:
if contact.id == pubkey:
return true
return false
proc getContactRequests(self: ContactsView): QVariant {.slot.} =
return newQVariant(self.contactRequests)
QtProperty[QVariant] contactRequests:
read = getContactRequests
notify = contactListChanged
proc contactToAddChanged*(self: ContactsView) {.signal.}
proc getContactToAddUsername(self: ContactsView): QVariant {.slot.} =
var username = self.contactToAdd.alias;
if self.contactToAdd.ensVerified and self.contactToAdd.ensName != "":
username = self.contactToAdd.ensName
return newQVariant(username)
QtProperty[QVariant] contactToAddUsername:
read = getContactToAddUsername
notify = contactToAddChanged
proc getContactToAddPubKey(self: ContactsView): QVariant {.slot.} =
return newQVariant(self.contactToAdd.address)
QtProperty[QVariant] contactToAddPubKey:
read = getContactToAddPubKey
notify = contactToAddChanged
proc isAdded*(self: ContactsView, pubkey: string): bool {.slot.} =
for contact in self.addedContacts.contacts:
if contact.id == pubkey:
return true
return false
proc contactRequestReceived*(self: ContactsView, pubkey: string): bool {.slot.} =
for contact in self.contactRequests.contacts:
if contact.id == pubkey:
return true
return false
proc lookupContact*(self: ContactsView, value: string) {.slot.} =
if value == "":
return
self.lookupContact("ensResolved", value)
proc ensWasResolved*(self: ContactsView, resolvedPubKey: string) {.signal.}
proc ensResolved(self: ContactsView, id: string) {.slot.} =
self.ensWasResolved(id)
if id == "":
self.contactToAddChanged()
return
let contact = self.status.contacts.getContactByID(id)
if contact != nil:
self.contactToAdd = contact
else:
self.contactToAdd = Profile(
address: id,
username: "",
alias: generateAlias(id),
ensName: "",
ensVerified: false
)
self.contactToAddChanged()
proc addContact*(self: ContactsView, publicKey: string) {.slot.} =
self.status.contacts.addContact(publicKey, self.accountKeyUID)
self.status.chat.join(status_utils.getTimelineChatId(publicKey), ChatType.Profile, "", publicKey)
proc rejectContactRequest*(self: ContactsView, publicKey: string) {.slot.} =
self.status.contacts.rejectContactRequest(publicKey)
proc rejectContactRequests*(self: ContactsView, publicKeysJSON: string) {.slot.} =
let publicKeys = publicKeysJSON.parseJson
for pubkey in publicKeys:
self.rejectContactRequest(pubkey.getStr)
proc acceptContactRequests*(self: ContactsView, publicKeysJSON: string) {.slot.} =
let publicKeys = publicKeysJSON.parseJson
for pubkey in publicKeys:
self.addContact(pubkey.getStr)
proc changeContactNickname*(self: ContactsView, publicKey: string, nickname: string) {.slot.} =
var nicknameToSet = nickname
if (nicknameToSet == ""):
nicknameToSet = DELETE_CONTACT
self.status.contacts.setNickName(publicKey, nicknameToSet, self.accountKeyUID)
proc unblockContact*(self: ContactsView, publicKey: string) {.slot.} =
self.contactListChanged()
self.status.contacts.unblockContact(publicKey)
proc contactBlocked*(self: ContactsView, publicKey: string) {.signal.}
proc blockContact*(self: ContactsView, publicKey: string) {.slot.} =
self.contactListChanged()
self.contactBlocked(publicKey)
self.status.contacts.blockContact(publicKey)
proc removeContact*(self: ContactsView, publicKey: string) {.slot.} =
self.status.contacts.removeContact(publicKey)
let channelId = status_utils.getTimelineChatId(publicKey)
if self.status.chat.hasChannel(channelId):
self.status.chat.leave(channelId)

View File

@ -20,3 +20,7 @@ proc first*(jArray: JsonNode, fieldName, id: string): JsonNode =
for child in jArray.getElems: for child in jArray.getElems:
if child{fieldName}.getStr.toLower == id.toLower: if child{fieldName}.getStr.toLower == id.toLower:
return child return child
proc prettyEnsName*(ensName: string): string =
if ensName.endsWith(".eth"):
return "@" & ensName.split(".")[0]

View File

@ -3,21 +3,21 @@
import json, strformat, strutils import json, strformat, strutils
include ../../../common/json_utils include ../../../common/json_utils
include ../../../common/utils
const domain* = ".stateofus.eth"
type type
Images* = ref object Images* = object
thumbnail*: string thumbnail*: string
large*: string large*: string
type ContactsDto* = ref object type ContactsDto* = object
id*: string id*: string
name*: string name*: string
ensVerified*: bool ensVerified*: bool
alias*: string alias*: string
identicon*: string identicon*: string
lastUpdated*: int64 lastUpdated*: int64
localNickname*: string
image*: Images image*: Images
added*: bool added*: bool
blocked*: bool blocked*: bool
@ -39,6 +39,7 @@ proc `$`*(self: ContactsDto): string =
alias: {self.alias}, alias: {self.alias},
identicon: {self.identicon}, identicon: {self.identicon},
lastUpdated: {self.lastUpdated}, lastUpdated: {self.lastUpdated},
localNickname: {self.localNickname},
image:[ image:[
{$self.image} {$self.image}
], ],
@ -68,6 +69,7 @@ proc toContactsDto*(jsonObj: JsonNode): ContactsDto =
discard jsonObj.getProp("alias", result.alias) discard jsonObj.getProp("alias", result.alias)
discard jsonObj.getProp("identicon", result.identicon) discard jsonObj.getProp("identicon", result.identicon)
discard jsonObj.getProp("lastUpdated", result.lastUpdated) discard jsonObj.getProp("lastUpdated", result.lastUpdated)
discard jsonObj.getProp("localNickname", result.localNickname)
var imageObj: JsonNode var imageObj: JsonNode
if(jsonObj.getProp("images", imageObj)): if(jsonObj.getProp("images", imageObj)):
@ -79,20 +81,11 @@ proc toContactsDto*(jsonObj: JsonNode): ContactsDto =
discard jsonObj.getProp("IsSyncing", result.isSyncing) discard jsonObj.getProp("IsSyncing", result.isSyncing)
discard jsonObj.getProp("Removed", result.removed) discard jsonObj.getProp("Removed", result.removed)
proc userName*(ensName: string, removeSuffix: bool = false): string = proc userNameOrAlias*(contact: ContactsDto): string =
if ensName != "" and ensName.endsWith(domain): if(contact.localNickname.len > 0):
if removeSuffix: result = contact.localNickname
result = ensName.split(".")[0] elif(contact.name.len > 0 and contact.ensVerified):
else: result = prettyEnsName(contact.name)
result = ensName
else:
if ensName.endsWith(".eth") and removeSuffix:
return ensName.split(".")[0]
result = ensName
proc userNameOrAlias*(contact: ContactsDto, removeSuffix: bool = false): string =
if(contact.name != "" and contact.ensVerified):
result = "@" & userName(contact.name, removeSuffix)
else: else:
result = contact.alias result = contact.alias

View File

@ -3,14 +3,13 @@ import NimQml, Tables, json, sequtils, strformat, chronicles, strutils
import eventemitter import eventemitter
import ../../tasks/[qt, threadpool] import ../../tasks/[qt, threadpool]
import service_interface, ./dto/contacts import ./dto/contacts as contacts_dto
import status/statusgo_backend_new/contacts as status_contacts import status/statusgo_backend_new/contacts as status_contacts
import status/statusgo_backend_new/accounts as status_accounts import status/statusgo_backend_new/accounts as status_accounts
import status/statusgo_backend_new/chat as status_chat import status/statusgo_backend_new/chat as status_chat
import status/statusgo_backend_new/utils as status_utils import status/statusgo_backend_new/utils as status_utils
import status/contacts as old_status_contacts
export service_interface export contacts_dto
include async_tasks include async_tasks
@ -18,11 +17,23 @@ logScope:
topics = "contacts-service" topics = "contacts-service"
type type
LookupResolvedArgs* = ref object of Args ContactArgs* = ref object of Args
id*: string contactId*: string
ContactNicknameUpdatedArgs* = ref object of ContactArgs
nickname*: string
ContactAddedArgs* = ref object of Args
contact*: ContactsDto
# Signals which may be emitted by this service: # Signals which may be emitted by this service:
const SIGNAL_CONTACT_LOOKED_UP* = "SIGNAL_CONTACT_LOOKED_UP" const SIGNAL_CONTACT_LOOKED_UP* = "SIGNAL_CONTACT_LOOKED_UP"
# Remove new when old code is removed
const SIGNAL_CONTACT_ADDED* = "new-contactAdded"
const SIGNAL_CONTACT_BLOCKED* = "new-contactBlocked"
const SIGNAL_CONTACT_UNBLOCKED* = "new-contactUnblocked"
const SIGNAL_CONTACT_REMOVED* = "new-contactRemoved"
const SIGNAL_CONTACT_NICKNAME_CHANGED* = "new-contactNicknameChanged"
QtObject: QtObject:
type Service* = ref object of QObject type Service* = ref object of QObject
@ -60,103 +71,103 @@ QtObject:
proc getContacts*(self: Service): seq[ContactsDto] = proc getContacts*(self: Service): seq[ContactsDto] =
return toSeq(self.contacts.values) return toSeq(self.contacts.values)
proc getContact*(self: Service, id: string): ContactsDto = proc fetchContact(self: Service, id: string): ContactsDto =
return status_contacts.getContactByID(id).result.toContactsDto() try:
let response = status_contacts.getContactByID(id)
proc getOrCreateContact*(self: Service, id: string): ContactsDto = result = response.result.toContactsDto()
result = self.getContact(id) self.contacts[result.id] = result
if result == nil or result.id == "":
let alias = $status_accounts.generateAlias(id) except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return
proc generateAlias*(self: Service, publicKey: string): string =
return status_accounts.generateAlias(publicKey).result.getStr
proc generateIdenticon*(self: Service, publicKey: string): string =
return status_accounts.generateIdenticon(publicKey).result.getStr
proc getContactById*(self: Service, id: string): ContactsDto =
## 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(id)):
return self.contacts[id]
result = self.fetchContact(id)
if result.id.len == 0:
let alias = self.generateAlias(id)
let identicon = self.generateIdenticon(id)
result = ContactsDto( result = ContactsDto(
id: id, id: id,
# username: alias, identicon: identicon,
# localNickname: "",
identicon: $status_accounts.generateIdenticon(id),
alias: alias, alias: alias,
# ensName: "",
ensVerified: false, ensVerified: false,
# appearance: 0,
added: false, added: false,
blocked: false, blocked: false,
hasAddedUs: false hasAddedUs: false
) )
proc saveContact(self: Service, contact: ContactsDto) = proc saveContact(self: Service, contact: ContactsDto) =
var thumbnail = "" # we must keep local contacts updated
var largeImage = "" self.contacts[contact.id] = contact
# if contact.identityImage != nil:
# thumbnail = contact.identityImage.thumbnail
# largeImage = contact.identityImage.large
# status_contacts.saveContact(contact.id, contact.ensVerified, contact.ensName, contact.alias, contact.identicon, thumbnail, largeImage, contact.added, contact.blocked, contact.hasAddedUs, contact.localNickname)
status_contacts.saveContact(contact.id, contact.ensVerified, "", contact.alias, contact.identicon, thumbnail, largeImage, contact.added, contact.blocked, contact.hasAddedUs, "")
proc addContact*(self: Service, publicKey: string) = proc addContact*(self: Service, publicKey: string) =
var contact = self.getOrCreateContact(publicKey) var contact = self.getContactById(publicKey)
let updating = contact.added if not contact.added:
if not updating:
contact.added = true contact.added = true
# discard status_chat.createProfileChat(contact.id)
else: else:
contact.blocked = false contact.blocked = false
self.saveContact(contact) self.saveContact(contact)
status_contacts.addContact(contact.id, contact.name)
self.events.emit("contactAdded", Args()) self.events.emit(SIGNAL_CONTACT_ADDED, ContactAddedArgs(contact: contact))
# sendContactUpdate(contact.id, accountKeyUID)
if updating:
let profile = ContactsDto(
id: contact.id,
# username: contact.alias,
identicon: contact.identicon,
alias: contact.alias,
# ensName: contact.ensName,
ensVerified: contact.ensVerified,
# appearance: 0,
added: contact.added,
blocked: contact.blocked,
hasAddedUs: contact.hasAddedUs,
# localNickname: contact.localNickname
)
# TODO fix this to use ContactsDto
# self.events.emit("contactUpdate", ContactUpdateArgs(contacts: @[profile]))
proc rejectContactRequest*(self: Service, publicKey: string) = proc rejectContactRequest*(self: Service, publicKey: string) =
status_contacts.rejectContactRequest(publicKey) var contact = self.getContactById(publicKey)
self.events.emit("contactRemoved", Args()) contact.hasAddedUs = false
proc changeContactNickname*(self: Service, accountKeyUID: string, publicKey: string, nicknameToSet: string) = self.saveContact(contact)
status_contacts.setContactLocalNickname(publicKey, nicknameToSet) status_contacts.rejectContactRequest(contact.id)
self.events.emit("contactAdded", Args()) self.events.emit(SIGNAL_CONTACT_REMOVED, ContactArgs(contactId: contact.id))
proc changeContactNickname*(self: Service, publicKey: string, nickname: string) =
var contact = self.getContactById(publicKey)
contact.localNickname = nickname
self.saveContact(contact)
status_contacts.setContactLocalNickname(contact.id, contact.localNickname)
let data = ContactNicknameUpdatedArgs(contactId: contact.id, nickname: nickname)
self.events.emit(SIGNAL_CONTACT_NICKNAME_CHANGED, data)
proc unblockContact*(self: Service, publicKey: string) = proc unblockContact*(self: Service, publicKey: string) =
status_contacts.unblockContact(publicKey) var contact = self.getContactById(publicKey)
self.events.emit("contactUnblocked", old_status_contacts.ContactIdArgs(id: publicKey)) contact.blocked = false
self.saveContact(contact)
status_contacts.unblockContact(contact.id)
self.events.emit(SIGNAL_CONTACT_UNBLOCKED, ContactArgs(contactId: contact.id))
proc blockContact*(self: Service, publicKey: string) = proc blockContact*(self: Service, publicKey: string) =
status_contacts.blockContact(publicKey) var contact = self.getContactById(publicKey)
self.events.emit("contactBlocked", old_status_contacts.ContactIdArgs(id: publicKey)) contact.blocked = true
self.saveContact(contact)
status_contacts.blockContact(contact.id)
self.events.emit(SIGNAL_CONTACT_BLOCKED, ContactArgs(contactId: contact.id))
proc removeContact*(self: Service, publicKey: string) = proc removeContact*(self: Service, publicKey: string) =
status_contacts.removeContact(publicKey) var contact = self.getContactById(publicKey)
self.events.emit("contactRemoved", Args()) contact.added = false
# let channelId = status_utils.getTimelineChatId(publicKey) contact.hasAddedUs = false
# if status_chat.hasChannel(channelId):
# status_chat.leave(channelId) self.saveContact(contact)
status_contacts.removeContact(contact.id)
self.events.emit(SIGNAL_CONTACT_REMOVED, ContactArgs(contactId: contact.id))
proc ensResolved*(self: Service, id: string) {.slot.} = proc ensResolved*(self: Service, id: string) {.slot.} =
# var contact = self.getContact(id) let data = ContactArgs(contactId: id)
# if contact == nil or contact.id == "":
# contact = ContactsDto(
# id: id,
# alias: $status_accounts.generateAlias(id),
# ensVerified: false
# )
let data = LookupResolvedArgs(id: id)
self.events.emit(SIGNAL_CONTACT_LOOKED_UP, data) self.events.emit(SIGNAL_CONTACT_LOOKED_UP, data)
proc lookupContact*(self: Service, value: string) = proc lookupContact*(self: Service, value: string) =

View File

@ -26,9 +26,7 @@ StatusAppThreePanelLayout {
handle: SplitViewHandle { implicitWidth: 5 } handle: SplitViewHandle { implicitWidth: 5 }
property var messageStore property var messageStore
property RootStore rootStore: RootStore {
messageStore: root.messageStore
}
property alias chatColumn: chatColumn property alias chatColumn: chatColumn
property bool stickersLoaded: false property bool stickersLoaded: false
signal profileButtonClicked() signal profileButtonClicked()
@ -44,6 +42,10 @@ StatusAppThreePanelLayout {
root.rootStore.chatsModelInst.channelView.restorePreviousActiveChannel(); root.rootStore.chatsModelInst.channelView.restorePreviousActiveChannel();
chatColumn.onActivated(); chatColumn.onActivated();
} }
// Not Refactored
property RootStore rootStore: RootStore {
messageStore: root.messageStore
}
StatusSearchLocationMenu { StatusSearchLocationMenu {
id: searchPopupMenu id: searchPopupMenu
@ -181,11 +183,11 @@ StatusAppThreePanelLayout {
currentTime: chatColumn.currentTime currentTime: chatColumn.currentTime
messageContextMenu: quickActionMessageOptionsMenu messageContextMenu: quickActionMessageOptionsMenu
profilePubKey: userProfile.pubKey profilePubKey: userProfile.pubKey
contactsList: root.rootStore.profileModelInst.contacts.list
community: root.rootStore.chatsModelInst.communities.activeCommunity community: root.rootStore.chatsModelInst.communities.activeCommunity
currentUserName: Utils.removeStatusEns(root.rootStore.profileModelInst.ens.preferredUsername currentUserName: Utils.removeStatusEns(root.rootStore.profileModelInst.ens.preferredUsername
|| root.rootStore.profileModelInst.profile.username) || root.rootStore.profileModelInst.profile.username)
currentUserOnline: root.store.userProfileInst.userStatus currentUserOnline: root.store.userProfileInst.userStatus
contactsList: root.rootStore.allContacts
} }
} }
@ -196,7 +198,7 @@ StatusAppThreePanelLayout {
userList: chatColumn.userList userList: chatColumn.userList
messageContextMenu: quickActionMessageOptionsMenu messageContextMenu: quickActionMessageOptionsMenu
profilePubKey: userProfile.pubKey profilePubKey: userProfile.pubKey
contactsList: root.rootStore.profileModelInst.contacts.list contactsList: root.rootStore.allContacts
isOnline: root.rootStore.chatsModelInst.isOnline isOnline: root.rootStore.chatsModelInst.isOnline
} }
} }
@ -204,6 +206,7 @@ StatusAppThreePanelLayout {
Component { Component {
id: contactsColumnComponent id: contactsColumnComponent
ContactsColumnView { ContactsColumnView {
// Not Refactored
store: root.rootStore store: root.rootStore
onOpenProfileClicked: { onOpenProfileClicked: {
root.profileButtonClicked(); root.profileButtonClicked();
@ -222,6 +225,7 @@ StatusAppThreePanelLayout {
Component { Component {
id: groupInfoPopupComponent id: groupInfoPopupComponent
GroupInfoPopup { GroupInfoPopup {
// Not Refactored
store: root.rootStore store: root.rootStore
pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
} }
@ -243,8 +247,9 @@ StatusAppThreePanelLayout {
//% "Are you sure you want to remove this contact?" //% "Are you sure you want to remove this contact?"
confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-") confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-")
onConfirmButtonClicked: { onConfirmButtonClicked: {
if (root.rootStore.profileModelInst.contacts.isAdded(chatColumn.contactToRemove)) { if (root.rootStore.contactsModuleInst.model.isAdded(chatColumn.contactToRemove)) {
root.rootStore.profileModelInst.contacts.removeContact(chatColumn.contactToRemove) root.rootStore.contactsModuleInst.model.removeContact(chatColumn.contactToRemove)
} }
removeContactConfirmationDialog.parentPopup.close(); removeContactConfirmationDialog.parentPopup.close();
removeContactConfirmationDialog.close(); removeContactConfirmationDialog.close();
@ -253,8 +258,9 @@ StatusAppThreePanelLayout {
MessageContextMenuView { MessageContextMenuView {
id: quickActionMessageOptionsMenu id: quickActionMessageOptionsMenu
// Not Refactored
store: root.rootStore store: root.rootStore
reactionModel: root.rootStore.emojiReactionsModel // reactionModel: root.rootStore.emojiReactionsModel
} }
} }

View File

@ -162,7 +162,8 @@ Item {
Connections { Connections {
enabled: realChatType === Constants.chatTypeOneToOne enabled: realChatType === Constants.chatTypeOneToOne
target: profileModel.contacts.list // TODO use a store once it is available
target: contactsModule.model.list
onContactChanged: { onContactChanged: {
if (pubkey === wrapper.chatId) { if (pubkey === wrapper.chatId) {
wrapper.profileImage = appMain.getProfileImage(wrapper.chatId) wrapper.profileImage = appMain.getProfileImage(wrapper.chatId)

View File

@ -12,6 +12,7 @@ Item {
width: parent.width width: parent.width
height: childrenRect.height height: childrenRect.height
property bool isContact
signal addContactClicked() signal addContactClicked()
Image { Image {

View File

@ -24,6 +24,7 @@ Item {
property string headerImageSource: "" property string headerImageSource: ""
property alias members: memberList.model property alias members: memberList.model
property var community property var community
property var store
signal inviteButtonClicked() signal inviteButtonClicked()
@ -223,6 +224,7 @@ Item {
Component { Component {
id: profilePopup id: profilePopup
ProfilePopup { ProfilePopup {
store: root.store
onClosed: { onClosed: {
destroy() destroy()
} }

View File

@ -103,13 +103,14 @@ Popup {
property Component profilePopupComponent: ProfilePopup { property Component profilePopupComponent: ProfilePopup {
id: profilePopup id: profilePopup
store: activityCenter.store
onClosed: destroy() onClosed: destroy()
} }
// TODO remove this once it is handled by the activity center // TODO remove this once it is handled by the activity center
// Repeater { // Repeater {
// id: contactList // id: contactList
// model: activityCenter.store.profileModelInst.contacts.contactRequests // model: activityCenter.store.contactRequests
// delegate: ContactRequest { // delegate: ContactRequest {
// visible: !hideReadNotifications && // visible: !hideReadNotifications &&

View File

@ -89,7 +89,7 @@ StatusModal {
RecipientSelector { RecipientSelector {
id: selectRecipient id: selectRecipient
accounts: root.store.walletModelInst.accountsView.accounts accounts: root.store.walletModelInst.accountsView.accounts
contacts: root.store.profileModelInst.contacts.addedContacts contacts: root.store.addedContacts
label: root.isRequested ? label: root.isRequested ?
//% "From" //% "From"
qsTrId("from") : qsTrId("from") :

View File

@ -25,6 +25,7 @@ ModalPopup {
property Component profilePopupComponent: ProfilePopup { property Component profilePopupComponent: ProfilePopup {
id: profilePopup id: profilePopup
store: popup.store
onClosed: destroy() onClosed: destroy()
} }
@ -32,7 +33,7 @@ ModalPopup {
anchors.leftMargin: -Style.current.halfPadding anchors.leftMargin: -Style.current.halfPadding
anchors.rightMargin: -Style.current.halfPadding anchors.rightMargin: -Style.current.halfPadding
model: popup.store.profileModelInst.contacts.contactRequests model: popup.store.contactRequests
clip: true clip: true
delegate: ContactRequestPanel { delegate: ContactRequestPanel {
@ -51,10 +52,10 @@ ModalPopup {
} }
onAcceptClicked: { onAcceptClicked: {
popup.store.chatsModelInst.channelView.joinPrivateChat(model.address, "") popup.store.chatsModelInst.channelView.joinPrivateChat(model.address, "")
popup.store.profileModelInst.contacts.addContact(model.address) popup.store.contactsModuleInst.addContact(model.address)
} }
onDeclineClicked: { onDeclineClicked: {
popup.store.profileModelInst.contacts.rejectContactRequest(model.address) popup.store.contactsModuleInst.rejectContactRequest(model.address)
} }
} }
} }
@ -66,7 +67,7 @@ ModalPopup {
BlockContactConfirmationDialog { BlockContactConfirmationDialog {
id: blockContactConfirmationDialog id: blockContactConfirmationDialog
onBlockButtonClicked: { onBlockButtonClicked: {
popup.store.profileModelInst.contacts.blockContact(blockContactConfirmationDialog.contactAddress) popup.store.contactsModuleInst.blockContact(blockContactConfirmationDialog.contactAddress)
blockContactConfirmationDialog.close() blockContactConfirmationDialog.close()
} }
} }
@ -78,12 +79,12 @@ ModalPopup {
//% "Are you sure you want to decline all these contact requests" //% "Are you sure you want to decline all these contact requests"
confirmationText: qsTrId("are-you-sure-you-want-to-decline-all-these-contact-requests") confirmationText: qsTrId("are-you-sure-you-want-to-decline-all-these-contact-requests")
onConfirmButtonClicked: { onConfirmButtonClicked: {
const requests = popup.store.profileModelInst.contacts.contactRequests const requests = popup.store.contactRequests
const pubkeys = [] const pubkeys = []
for (let i = 0; i < requests.count; i++) { for (let i = 0; i < requests.count; i++) {
pubkeys.push(requests.rowData(i, "address")) pubkeys.push(requests.rowData(i, "address"))
} }
popup.store.profileModelInst.contacts.rejectContactRequests(JSON.stringify(pubkeys)) popup.store.contactsModuleInst.rejectContactRequests(JSON.stringify(pubkeys))
declineAllDialog.close() declineAllDialog.close()
} }
} }
@ -95,12 +96,12 @@ ModalPopup {
//% "Are you sure you want to accept all these contact requests" //% "Are you sure you want to accept all these contact requests"
confirmationText: qsTrId("are-you-sure-you-want-to-accept-all-these-contact-requests") confirmationText: qsTrId("are-you-sure-you-want-to-accept-all-these-contact-requests")
onConfirmButtonClicked: { onConfirmButtonClicked: {
const requests = popup.store.profileModelInst.contacts.contactRequests const requests = popup.store.contactRequests
const pubkeys = [] const pubkeys = []
for (let i = 0; i < requests.count; i++) { for (let i = 0; i < requests.count; i++) {
pubkeys.push(requests.rowData(i, "address")) pubkeys.push(requests.rowData(i, "address"))
} }
popup.store.profileModelInst.contacts.acceptContactRequests(JSON.stringify(pubkeys)) popup.store.contactsModuleInst.acceptContactRequests(JSON.stringify(pubkeys))
acceptAllDialog.close() acceptAllDialog.close()
} }
} }

View File

@ -45,7 +45,7 @@ ModalPopup {
thumbnailImage: userProfile.thumbnailImage, thumbnailImage: userProfile.thumbnailImage,
isUser: true isUser: true
}); });
noContactsRect.visible = !popup.store.profileModelInst.contacts.list.hasAddedContacts(); noContactsRect.visible = !popup.store.allContacts.hasAddedContacts();
contactList.visible = !noContactsRect.visible; contactList.visible = !noContactsRect.visible;
if (!contactList.visible) { if (!contactList.visible) {
memberCount = 0; memberCount = 0;

View File

@ -28,7 +28,7 @@ ModalPopup {
contactFieldAndList.pubKey = "" contactFieldAndList.pubKey = ""
contactFieldAndList.ensUsername = "" contactFieldAndList.ensUsername = ""
contactFieldAndList.chatKey.forceActiveFocus(Qt.MouseFocusReason) contactFieldAndList.chatKey.forceActiveFocus(Qt.MouseFocusReason)
contactFieldAndList.existingContacts.visible = popup.store.profileModelInst.contacts.list.hasAddedContacts() contactFieldAndList.existingContacts.visible = popup.store.allContacts.hasAddedContacts()
contactFieldAndList.noContactsRect.visible = !contactFieldAndList.existingContacts.visible contactFieldAndList.noContactsRect.visible = !contactFieldAndList.existingContacts.visible
} }

View File

@ -52,7 +52,7 @@ StatusModal {
identicon = identiconParam || "" identicon = identiconParam || ""
text = textParam || "" text = textParam || ""
isEnsVerified = chatsModel.ensView.isEnsVerified(this.fromAuthor) isEnsVerified = chatsModel.ensView.isEnsVerified(this.fromAuthor)
isBlocked = profileModel.contacts.isContactBlocked(this.fromAuthor); isBlocked = popup.store.contactsModuleInst.model.isContactBlocked(this.fromAuthor);
alias = chatsModel.alias(this.fromAuthor) || "" alias = chatsModel.alias(this.fromAuthor) || ""
isCurrentUser = userProfile.pubKey === this.fromAuthor isCurrentUser = userProfile.pubKey === this.fromAuthor
showFooter = _showFooter; showFooter = _showFooter;
@ -208,7 +208,7 @@ StatusModal {
UnblockContactConfirmationDialog { UnblockContactConfirmationDialog {
id: unblockContactConfirmationDialog id: unblockContactConfirmationDialog
onUnblockButtonClicked: { onUnblockButtonClicked: {
profileModel.contacts.unblockContact(fromAuthor) popup.store.contactsModuleInst.unblockContact(fromAuthor)
unblockContactConfirmationDialog.close(); unblockContactConfirmationDialog.close();
popup.close() popup.close()
popup.contactUnblocked(fromAuthor) popup.contactUnblocked(fromAuthor)
@ -218,7 +218,7 @@ StatusModal {
BlockContactConfirmationDialog { BlockContactConfirmationDialog {
id: blockContactConfirmationDialog id: blockContactConfirmationDialog
onBlockButtonClicked: { onBlockButtonClicked: {
profileModel.contacts.blockContact(fromAuthor) popup.store.contactsModuleInst.blockContact(fromAuthor)
blockContactConfirmationDialog.close(); blockContactConfirmationDialog.close();
popup.close() popup.close()
@ -231,8 +231,8 @@ StatusModal {
header.title: qsTr("Remove contact") header.title: qsTr("Remove contact")
confirmationText: qsTr("Are you sure you want to remove this contact?") confirmationText: qsTr("Are you sure you want to remove this contact?")
onConfirmButtonClicked: { onConfirmButtonClicked: {
if (profileModel.contacts.isAdded(fromAuthor)) { if (popup.store.contactsModuleInst.model.isAdded(fromAuthor)) {
profileModel.contacts.removeContact(fromAuthor); popup.store.contactsModuleInst.removeContact(fromAuthor);
} }
removeContactConfirmationDialog.close(); removeContactConfirmationDialog.close();
popup.close(); popup.close();
@ -247,7 +247,7 @@ StatusModal {
popup.userName = newUsername; popup.userName = newUsername;
} }
popup.nickname = newNickname; popup.nickname = newNickname;
profileModel.contacts.changeContactNickname(fromAuthor, newNickname); popup.store.contactsModuleInst.changeContactNickname(fromAuthor, newNickname);
popup.close() popup.close()
if (!!chatsModel.communities.activeCommunity) { if (!!chatsModel.communities.activeCommunity) {
chatsModel.communities.activeCommunity.triggerMembersUpdate(); chatsModel.communities.activeCommunity.triggerMembersUpdate();
@ -276,7 +276,7 @@ StatusModal {
}, },
StatusFlatButton { StatusFlatButton {
property bool isAdded: profileModel.contacts.isAdded(fromAuthor) property bool isAdded: popup.store.contactsModuleInst.model.isAdded(fromAuthor)
visible: !isBlocked && isAdded visible: !isBlocked && isAdded
type: StatusBaseButton.Type.Danger type: StatusBaseButton.Type.Danger
text: qsTr('Remove Contact') text: qsTr('Remove Contact')
@ -287,7 +287,7 @@ StatusModal {
}, },
StatusButton { StatusButton {
property bool isAdded: profileModel.contacts.isAdded(fromAuthor) property bool isAdded: popup.store.contactsModuleInst.model.isAdded(fromAuthor)
text: qsTr("Add to contacts") text: qsTr("Add to contacts")
visible: !isBlocked && !isAdded visible: !isBlocked && !isAdded
onClicked: { onClicked: {

View File

@ -127,7 +127,7 @@ StatusModal {
id: selectRecipient id: selectRecipient
visible: false visible: false
accounts: root.store.walletModelInst.accountsView.accounts accounts: root.store.walletModelInst.accountsView.accounts
contacts: root.store.profileModelInst.contacts.addedContacts contacts: root.store.addedContacts
selectedRecipient: root.selectedRecipient selectedRecipient: root.selectedRecipient
readOnly: true readOnly: true
} }

View File

@ -106,6 +106,8 @@ StatusModal {
Component { Component {
id: membersList id: membersList
CommunityProfilePopupMembersListPanel { CommunityProfilePopupMembersListPanel {
// TODO assign the store on open
store: root.store
width: stack.width width: stack.width
//% "Members" //% "Members"
headerTitle: qsTrId("members-label") headerTitle: qsTrId("members-label")
@ -127,7 +129,7 @@ StatusModal {
contactListSearch.pubKey: "" contactListSearch.pubKey: ""
contactListSearch.pubKeys: [] contactListSearch.pubKeys: []
contactListSearch.ensUsername: "" contactListSearch.ensUsername: ""
contactListSearch.existingContacts.visible: root.store.profileModelInst.contacts.list.hasAddedContacts() contactListSearch.existingContacts.visible: root.store.allContacts.hasAddedContacts()
contactListSearch.noContactsRect.visible: !contactListSearch.existingContacts.visible contactListSearch.noContactsRect.visible: !contactListSearch.existingContacts.visible
} }
} }

View File

@ -59,9 +59,9 @@ StatusModal {
delegate: StatusListItem { delegate: StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
property int contactIndex: popup.store.profileModelInst.contacts.list.getContactIndexByPubkey(model.publicKey) property int contactIndex: popup.store.allContacts.getContactIndexByPubkey(model.publicKey)
property string nickname: appMain.getUserNickname(model.publicKey) property string nickname: appMain.getUserNickname(model.publicKey)
property string profileImage: contactIndex === -1 ? "" : popup.store.profileModelInst.contacts.list.rowData(contactIndex, 'thumbnailImage') property string profileImage: contactIndex === -1 ? "" : popup.store.allContacts.rowData(contactIndex, 'thumbnailImage')
property string displayName: Utils.getDisplayName(publicKey, contactIndex) property string displayName: Utils.getDisplayName(publicKey, contactIndex)
image.isIdenticon: !profileImage && model.identicon image.isIdenticon: !profileImage && model.identicon

View File

@ -13,12 +13,11 @@ QtObject {
property var walletModelInst: walletModel property var walletModelInst: walletModel
property var profileModelInst: profileModel property var profileModelInst: profileModel
property var profileModuleInst: profileModule property var profileModuleInst: profileModule
property var userProfileInst: userProfile property var userProfileInst: userProfile
property bool isDebugEnabled: profileSectionModule.isDebugEnabled property bool isDebugEnabled: profileSectionModule.isDebugEnabled
property var activeCommunity: chatsModelInst.communities.activeCommunity
property var accounts: walletSectionAccounts.model property var accounts: walletSectionAccounts.model
property var currentAccount: walletSectionCurrent property var currentAccount: walletSectionCurrent
property var currentCurrency: walletSection.currentCurrency property var currentCurrency: walletSection.currentCurrency
@ -38,6 +37,13 @@ QtObject {
}) })
} }
} }
property var contactsModuleInst: contactsModule
property var activeCommunity: chatsModelInst.communities.activeCommunity
property var contactRequests: contactsModuleInst.model.contactRequests
property var addedContacts: contactsModuleInst.model.addedContacts
property var allContacts: contactsModuleInst.model.list
function copyToClipboard(text) { function copyToClipboard(text) {
chatsModelInst.copyToClipboard(text); chatsModelInst.copyToClipboard(text);
@ -169,4 +175,12 @@ QtObject {
function generateIdenticon(pk) { function generateIdenticon(pk) {
return utilsModelInst.generateIdenticon(pk); return utilsModelInst.generateIdenticon(pk);
} }
function addContact(pubKey) {
contactsModuleInst.addContact(pubKey);
}
function isContactAdded(address) {
return contactsModuleInst.model.isAdded(address);
}
} }

View File

@ -166,7 +166,7 @@ Item {
BlockContactConfirmationDialog { BlockContactConfirmationDialog {
id: blockContactConfirmationDialog id: blockContactConfirmationDialog
onBlockButtonClicked: { onBlockButtonClicked: {
root.store.profileModelInst.contacts.blockContact(blockContactConfirmationDialog.contactAddress) root.store.profileModuleInst.blockContact(blockContactConfirmationDialog.contactAddress)
root.store.chatsModelInst.activityNotificationList.dismissActivityCenterNotification(model.id) root.store.chatsModelInst.activityNotificationList.dismissActivityCenterNotification(model.id)
blockContactConfirmationDialog.close() blockContactConfirmationDialog.close()
} }

View File

@ -73,7 +73,7 @@ Item {
const setActiveChannel = root.store.chatsModelInst.channelView.setActiveChannel const setActiveChannel = root.store.chatsModelInst.channelView.setActiveChannel
const chatId = model.message.chatId const chatId = model.message.chatId
const messageId = model.message.messageId const messageId = model.message.messageId
root.store.profileModelInst.contacts.addContact(model.author) root.store.profileModuleInst.addContact(model.author)
root.store.chatsModelInst.activityNotificationList.acceptActivityCenterNotification(model.id) root.store.chatsModelInst.activityNotificationList.acceptActivityCenterNotification(model.id)
setActiveChannel(chatId) setActiveChannel(chatId)
positionAtMessage(messageId) positionAtMessage(messageId)
@ -90,7 +90,7 @@ Item {
BlockContactConfirmationDialog { BlockContactConfirmationDialog {
id: blockContactConfirmationDialog id: blockContactConfirmationDialog
onBlockButtonClicked: { onBlockButtonClicked: {
root.store.profileModelInst.contacts.blockContact(blockContactConfirmationDialog.contactAddress) root.store.profileModuleInst.blockContact(blockContactConfirmationDialog.contactAddress)
root.store.chatsModelInst.activityNotificationList.dismissActivityCenterNotification(model.id) root.store.chatsModelInst.activityNotificationList.dismissActivityCenterNotification(model.id)
blockContactConfirmationDialog.close() blockContactConfirmationDialog.close()
} }
@ -261,7 +261,7 @@ Item {
Connections { Connections {
enabled: badge.realChatType === Constants.chatTypeOneToOne enabled: badge.realChatType === Constants.chatTypeOneToOne
target: root.store.profileModelInst.contacts.list target: root.store.allContacts
onContactChanged: { onContactChanged: {
if (pubkey === badge.chatId) { if (pubkey === badge.chatId) {
badge.profileImage = appMain.getProfileImage(badge.chatId) badge.profileImage = appMain.getProfileImage(badge.chatId)

View File

@ -33,9 +33,9 @@ Item {
property bool isConnected: false property bool isConnected: false
property string contactToRemove: "" property string contactToRemove: ""
property string activeChatId: root.rootStore.chatsModelInst.channelView.activeChannel.id property string activeChatId: root.rootStore.chatsModelInst.channelView.activeChannel.id
property bool isBlocked: root.rootStore.profileModelInst.contacts.isContactBlocked(activeChatId) property bool isBlocked: root.rootStore.contactsModuleInst.model.isContactBlocked(activeChatId)
property bool isContact: root.rootStore.profileModelInst.contacts.isAdded(activeChatId) property bool isContact: root.rootStore.isContactAdded(activeChatId)
property bool contactRequestReceived: root.rootStore.profileModelInst.contacts.contactRequestReceived(activeChatId) // property bool contactRequestReceived: root.rootStore.contactsModuleInst.model.contactRequestReceived(activeChatId)
property string currentNotificationChatId property string currentNotificationChatId
property string currentNotificationCommunityId property string currentNotificationCommunityId
property var currentTime: 0 property var currentTime: 0
@ -150,7 +150,7 @@ Item {
chatInfoButton.subTitle: { chatInfoButton.subTitle: {
switch (root.rootStore.chatsModelInst.channelView.activeChannel.chatType) { switch (root.rootStore.chatsModelInst.channelView.activeChannel.chatType) {
case Constants.chatTypeOneToOne: case Constants.chatTypeOneToOne:
return (root.rootStore.profileModelInst.contacts.isAdded(topBar.chatId) ? return (root.isContact ?
//% "Contact" //% "Contact"
qsTrId("chat-is-a-contact") : qsTrId("chat-is-a-contact") :
//% "Not a contact" //% "Not a contact"
@ -408,7 +408,7 @@ Item {
Connections { Connections {
target: root.rootStore.chatsModelInst.channelView target: root.rootStore.chatsModelInst.channelView
onActiveChannelChanged: { onActiveChannelChanged: {
isBlocked = root.rootStore.profileModelInst.contacts.isContactBlocked(activeChatId); isBlocked = root.rootStore.contactsModuleInst.model.isContactBlocked(activeChatId);
chatInput.suggestions.hide(); chatInput.suggestions.hide();
if(stackLayoutChatMessages.currentIndex >= 0 && stackLayoutChatMessages.currentIndex < stackLayoutChatMessages.children.length) if(stackLayoutChatMessages.currentIndex >= 0 && stackLayoutChatMessages.currentIndex < stackLayoutChatMessages.children.length)
stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason) stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
@ -422,8 +422,12 @@ Item {
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.fillWidth: true Layout.fillWidth: true
Layout.bottomMargin: Style.current.bigPadding Layout.bottomMargin: Style.current.bigPadding
visible: root.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatTypeOneToOne && (!isContact /*|| !contactRequestReceived*/) isContact: root.isContact
onAddContactClicked: root.rootStore.profileModelInst.contacts.addContact(activeChatId) visible: root.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatTypeOneToOne
&& (!root.isContact /*|| !contactRequestReceived*/)
onAddContactClicked: {
root.rootStore.addContact(activeChatId);
}
} }
} }
@ -536,9 +540,10 @@ Item {
} }
Connections { Connections {
target: root.rootStore.profileModelInst.contacts target: root.rootStore.contactsModuleInst.model
onContactListChanged: { onContactListChanged: {
isBlocked = root.rootStore.profileModelInst.contacts.isContactBlocked(activeChatId); root.isBlocked = root.rootStore.contactsModuleInst.model.isContactBlocked(activeChatId);
root.isContact = root.rootStore.contactsModuleInst.model.isAdded(activeChatId);
} }
} }

View File

@ -185,7 +185,7 @@ Item {
StatusContactRequestsIndicatorListItem { StatusContactRequestsIndicatorListItem {
id: contactRequests id: contactRequests
property int nbRequests: root.store.profileModelInst.contacts.contactRequests.count property int nbRequests: root.store.contactRequests.count
anchors.top: searchInputWrapper.bottom anchors.top: searchInputWrapper.bottom
anchors.topMargin: visible ? Style.current.padding : 0 anchors.topMargin: visible ? Style.current.padding : 0
@ -233,13 +233,13 @@ Item {
} }
Connections { Connections {
target: root.store.profileModelInst.contacts.list target: root.store.allContacts
onContactChanged: { onContactChanged: {
for (var i = 0; i < channelList.chatListItems.count; i++) { for (var i = 0; i < channelList.chatListItems.count; i++) {
if (!!channelList.statusChatListItems) { if (!!channelList.statusChatListItems) {
let chatItem = !!channelList.statusChatListItems.model ? let chatItem = !!channelList.statusChatListItems.model.items ?
channelList.statusChatListItems.model.itemAt(i) : null channelList.statusChatListItems.model.items.get(i) : null
if (chatItem.chatId === pubkey) { if (chatItem && chatItem.chatId === pubkey) {
let profileImage = appMain.getProfileImage(pubkey) let profileImage = appMain.getProfileImage(pubkey)
if (!!profileImage) { if (!!profileImage) {
chatItem.image.isIdenticon = false chatItem.image.isIdenticon = false

View File

@ -61,7 +61,8 @@ ListView {
BlockContactConfirmationDialog { BlockContactConfirmationDialog {
id: blockContactConfirmationDialog id: blockContactConfirmationDialog
onBlockButtonClicked: { onBlockButtonClicked: {
profileModel.contacts.blockContact(blockContactConfirmationDialog.contactAddress) // TODO use a store once it is available
contactsModule.blockContact(blockContactConfirmationDialog.contactAddress)
blockContactConfirmationDialog.close() blockContactConfirmationDialog.close()
} }
} }
@ -74,8 +75,9 @@ ListView {
//% "Are you sure you want to remove this contact?" //% "Are you sure you want to remove this contact?"
confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-") confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-")
onConfirmButtonClicked: { onConfirmButtonClicked: {
if (profileModel.contacts.isAdded(removeContactConfirmationDialog.value)) { // TODO use a store once it is available
profileModel.contacts.removeContact(removeContactConfirmationDialog.value); if (contactsModule.model.isAdded(removeContactConfirmationDialog.value)) {
contactsModule.removeContact(removeContactConfirmationDialog.value);
} }
removeContactConfirmationDialog.close() removeContactConfirmationDialog.close()
} }

View File

@ -11,6 +11,7 @@ import "."
ListView { ListView {
id: contactList id: contactList
property var contacts property var contacts
property var store
property string searchStr: "" property string searchStr: ""
property string searchString: "" property string searchString: ""
property string lowerCaseSearchString: searchString.toLowerCase() property string lowerCaseSearchString: searchString.toLowerCase()
@ -40,7 +41,7 @@ ListView {
isContact: model.isContact isContact: model.isContact
isBlocked: model.isBlocked isBlocked: model.isBlocked
profileClick: function (showFooter, userName, fromAuthor, identicon, textParam, nickName) { profileClick: function (showFooter, userName, fromAuthor, identicon, textParam, nickName) {
var popup = profilePopupComponent.createObject(contactList); var popup = profilePopupComponent.createObject(contactList, {store: contactList.store});
popup.openPopup(showFooter, userName, fromAuthor, identicon, textParam, nickName); popup.openPopup(showFooter, userName, fromAuthor, identicon, textParam, nickName);
} }
onClicked: contactList.contactClicked(model) onClicked: contactList.contactClicked(model)

View File

@ -83,7 +83,7 @@ Item {
anchors.top: addNewContact.bottom anchors.top: addNewContact.bottom
anchors.topMargin: Style.current.bigPadding anchors.topMargin: Style.current.bigPadding
width: parent.width width: parent.width
visible: root.store.blockedContacts.rowCount() > 0 visible: root.store.blockedContacts.count > 0
height: 64 height: 64
StatusRoundButton { StatusRoundButton {
@ -108,7 +108,7 @@ Item {
StyledText { StyledText {
id: numberOfBlockedContacts id: numberOfBlockedContacts
text: root.store.blockedContacts.rowCount() text: root.store.blockedContacts.count
color: Style.current.darkGrey color: Style.current.darkGrey
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Style.current.padding anchors.rightMargin: Style.current.padding
@ -131,6 +131,7 @@ Item {
title: qsTrId("blocked-contacts") title: qsTrId("blocked-contacts")
ContactsListPanel { ContactsListPanel {
store: root.store
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
contacts: root.store.blockedContacts contacts: root.store.blockedContacts
@ -246,6 +247,7 @@ Item {
ContactsListPanel { ContactsListPanel {
id: contactListView id: contactListView
store: root.store
anchors.top: blockedContactsButton.visible ? blockedContactsButton.bottom : addNewContact.bottom anchors.top: blockedContactsButton.visible ? blockedContactsButton.bottom : addNewContact.bottom
anchors.topMargin: Style.current.bigPadding anchors.topMargin: Style.current.bigPadding
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -281,7 +283,7 @@ Item {
NoFriendsRectangle { NoFriendsRectangle {
id: element id: element
visible: root.store.addedContacts.rowCount() === 0 visible: root.store.addedContacts.count === 0
//% "You dont have any contacts yet" //% "You dont have any contacts yet"
text: qsTrId("you-don-t-have-any-contacts-yet") text: qsTrId("you-don-t-have-any-contacts-yet")
width: parent.width width: parent.width

View File

@ -57,6 +57,7 @@ ScrollView {
property Component profilePopupComponent: ProfilePopup { property Component profilePopupComponent: ProfilePopup {
id: profilePopup id: profilePopup
store: root.store
onClosed: { onClosed: {
if(profilePopup.parentPopup){ if(profilePopup.parentPopup){
profilePopup.parentPopup.close(); profilePopup.parentPopup.close();

View File

@ -16,6 +16,10 @@ QtObject {
property var assets: walletSectionAccountTokens.model property var assets: walletSectionAccountTokens.model
property MessageStore messageStore: MessageStore { } property MessageStore messageStore: MessageStore { }
property var contactsModuleInst: contactsModule
property var addedContacts: contactsModuleInst.model.addedContacts
function setCommunityMuted(communityId, checked) { function setCommunityMuted(communityId, checked) {
chatsModelInst.communities.setCommunityMuted(communityId, checked); chatsModelInst.communities.setCommunityMuted(communityId, checked);
} }

View File

@ -51,19 +51,19 @@ Item {
return userProfile.thumbnailImage return userProfile.thumbnailImage
} }
const index = profileModel.contacts.list.getContactIndexByPubkey(pubkey) const index = appMain.rootStore.contactsModuleInst.model.list.getContactIndexByPubkey(pubkey)
if (index === -1) { if (index === -1) {
return return
} }
if (localAccountSensitiveSettings.onlyShowContactsProfilePics) { if (localAccountSensitiveSettings.onlyShowContactsProfilePics) {
const isContact = profileModel.contacts.list.rowData(index, "isContact") const isContact = appMain.rootStore.contactsModuleInst.model.list.rowData(index, "isContact")
if (isContact === "false") { if (isContact === "false") {
return return
} }
} }
return profileModel.contacts.list.rowData(index, useLargeImage ? "largeImage" : "thumbnailImage") return appMain.rootStore.contactsModuleInst.model.list.rowData(index, useLargeImage ? "largeImage" : "thumbnailImage")
} }
function openPopup(popupComponent, params = {}) { function openPopup(popupComponent, params = {}) {
@ -73,23 +73,23 @@ Item {
} }
function getContactListObject(dataModel) { function getContactListObject(dataModel) {
const nbContacts = profileModel.contacts.list.rowCount() const nbContacts = appMain.rootStore.contactsModuleInst.model.list.rowCount()
const contacts = [] const contacts = []
let contact let contact
for (let i = 0; i < nbContacts; i++) { for (let i = 0; i < nbContacts; i++) {
if (profileModel.contacts.list.rowData(i, "isBlocked") === "true") { if (appMain.rootStore.contactsModuleInst.model.list.rowData(i, "isBlocked") === "true") {
continue continue
} }
contact = { contact = {
name: profileModel.contacts.list.rowData(i, "name"), name: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "name"),
localNickname: profileModel.contacts.list.rowData(i, "localNickname"), localNickname: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "localNickname"),
pubKey: profileModel.contacts.list.rowData(i, "pubKey"), pubKey: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "pubKey"),
address: profileModel.contacts.list.rowData(i, "address"), address: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "address"),
identicon: profileModel.contacts.list.rowData(i, "identicon"), identicon: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "identicon"),
thumbnailImage: profileModel.contacts.list.rowData(i, "thumbnailImage"), thumbnailImage: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "thumbnailImage"),
isUser: false, isUser: false,
isContact: profileModel.contacts.list.rowData(i, "isContact") !== "false" isContact: appMain.rootStore.contactsModuleInst.model.list.rowData(i, "isContact") !== "false"
} }
contacts.push(contact) contacts.push(contact)
@ -102,7 +102,7 @@ Item {
function getUserNickname(pubKey) { function getUserNickname(pubKey) {
// Get contact nickname // Get contact nickname
const contactList = profileModel.contacts.list const contactList = appMain.rootStore.contactsModuleInst.model.list
const contactCount = contactList.rowCount() const contactCount = contactList.rowCount()
for (let i = 0; i < contactCount; i++) { for (let i = 0; i < contactCount; i++) {
if (contactList.rowData(i, 'pubKey') === pubKey) { if (contactList.rowData(i, 'pubKey') === pubKey) {
@ -136,6 +136,7 @@ Item {
property Component profilePopupComponent: ProfilePopup { property Component profilePopupComponent: ProfilePopup {
id: profilePopup id: profilePopup
store: rootStore
onClosed: { onClosed: {
if(profilePopup.parentPopup){ if(profilePopup.parentPopup){
profilePopup.parentPopup.close(); profilePopup.parentPopup.close();
@ -527,13 +528,22 @@ Item {
} }
Connections { Connections {
target: profileModel.contacts target: profileModel
ignoreUnknownSignals: true
enabled: removeMnemonicAfterLogin
onInitialized: {
mnemonicModule.remove()
}
}
Connections {
target: appMain.rootStore.contactsModuleInst.model
onContactRequestAdded: { onContactRequestAdded: {
if (!localAccountSensitiveSettings.notifyOnNewRequests) { if (!localAccountSensitiveSettings.notifyOnNewRequests) {
return return
} }
const isContact = profileModel.contacts.isAdded(address) const isContact = appMain.rootStore.contactsModuleInst.model.isAdded(address)
// Note: // Note:
// Whole this Connection object should be moved to the nim side. // Whole this Connection object should be moved to the nim side.
@ -575,7 +585,7 @@ Item {
id: inviteFriendsToCommunityPopup id: inviteFriendsToCommunityPopup
InviteFriendsToCommunityPopup { InviteFriendsToCommunityPopup {
anchors.centerIn: parent anchors.centerIn: parent
hasAddedContacts: appMain.rootStore.profileModelInst.contacts.list.hasAddedContacts() hasAddedContacts: appMain.rootStore.allContacts.hasAddedContacts()
onClosed: { onClosed: {
destroy() destroy()
} }

View File

@ -73,7 +73,7 @@ Item {
if (Utils.isChatKey(chatKey.text)) { if (Utils.isChatKey(chatKey.text)) {
pubKey = chatKey.text; pubKey = chatKey.text;
if (!profileModel.contacts.isAdded(pubKey)) { if (!contactsModule.model.isAdded(pubKey)) {
searchResults.username = utilsModel.generateAlias(pubKey); searchResults.username = utilsModel.generateAlias(pubKey);
searchResults.userAlias = Utils.compactAddress(pubKey, 4); searchResults.userAlias = Utils.compactAddress(pubKey, 4);
searchResults.pubKey = pubKey searchResults.pubKey = pubKey
@ -115,7 +115,7 @@ Item {
searchResults.showProfileNotFoundMessage = false searchResults.showProfileNotFoundMessage = false
} }
searchResults.loading = false; searchResults.loading = false;
noContactsRect.visible = pubKey === "" && ensUsername.text === "" && !profileModel.contacts.list.hasAddedContacts() && !profileNotFoundMessage.visible noContactsRect.visible = pubKey === "" && ensUsername.text === "" && !contactsModule.model.list.hasAddedContacts() && !profileNotFoundMessage.visible
} }
} }
@ -184,7 +184,7 @@ Item {
} }
root.pubKeys = pubKeysCopy root.pubKeys = pubKeysCopy
userClicked(true, contact.pubKey, profileModel.contacts.addedContacts.userName(contact.pubKey, contact.name), contact.address) userClicked(true, contact.pubKey, contactsModule.model.addedContacts.userName(contact.pubKey, contact.name), contact.address)
} }
expanded: !searchResults.loading && pubKey === "" && !searchResults.showProfileNotFoundMessage expanded: !searchResults.loading && pubKey === "" && !searchResults.showProfileNotFoundMessage
} }
@ -204,7 +204,7 @@ Item {
} }
userClicked(false, pubKey, chatKey.text, searchResults.address) userClicked(false, pubKey, chatKey.text, searchResults.address)
} }
onAddToContactsButtonClicked: profileModel.contacts.addContact(pubKey) onAddToContactsButtonClicked: contactsModule.addContact(pubKey)
} }
NoFriendsRectangle { NoFriendsRectangle {

View File

@ -107,7 +107,7 @@ ModalPopup {
RecipientSelector { RecipientSelector {
id: selectRecipient id: selectRecipient
accounts: root.store.accounts accounts: root.store.accounts
contacts: profileModel.contacts.addedContacts contacts: popup.store.addedContacts
//% "Recipient" //% "Recipient"
label: qsTrId("recipient") label: qsTrId("recipient")
anchors.top: separator.bottom anchors.top: separator.bottom

View File

@ -1150,7 +1150,7 @@ Rectangle {
text: qsTr("Unblock") text: qsTr("Unblock")
type: StatusQ.StatusBaseButton.Type.Danger type: StatusQ.StatusBaseButton.Type.Danger
onClicked: function (event) { onClicked: function (event) {
profileModel.contacts.unblockContact(chatsModel.channelView.activeChannel.id) contactsModule.unblockContact(chatsModel.channelView.activeChannel.id)
} }
} }
} }

View File

@ -103,8 +103,8 @@ ModalPopup {
RecipientSelector { RecipientSelector {
id: selectRecipient id: selectRecipient
visible: false visible: false
accounts: walletSectionAccounts.model accounts: walletModel.accountsView.accounts
contacts: profileModel.contacts.addedContacts contacts: contactsModule.model.addedContacts
selectedRecipient: { "address": utilsModel.ensRegisterAddress, "type": RecipientSelector.Type.Address } selectedRecipient: { "address": utilsModel.ensRegisterAddress, "type": RecipientSelector.Type.Address }
readOnly: true readOnly: true
onSelectedRecipientChanged: if (isValid) { gasSelector.estimateGas() } onSelectedRecipientChanged: if (isValid) { gasSelector.estimateGas() }

View File

@ -108,8 +108,8 @@ ModalPopup {
RecipientSelector { RecipientSelector {
id: selectRecipient id: selectRecipient
visible: false visible: false
accounts: walletSectionAccounts.model accounts: walletModel.accountsView.accounts
contacts: profileModel.contacts.addedContacts contacts: contactsModule.model.addedContacts
selectedRecipient: { "address": contractAddress, "type": RecipientSelector.Type.Address } selectedRecipient: { "address": contractAddress, "type": RecipientSelector.Type.Address }
readOnly: true readOnly: true
onSelectedRecipientChanged: if (isValid) { gasSelector.estimateGas() } onSelectedRecipientChanged: if (isValid) { gasSelector.estimateGas() }

View File

@ -36,7 +36,7 @@ Item {
spacing: 0 spacing: 0
clip: true clip: true
id: contactListView id: contactListView
model: profileModel.contacts.list model: contactsModule.model.list
delegate: Contact { delegate: Contact {
showCheckbox: root.showCheckbox showCheckbox: root.showCheckbox
isChecked: root.pubKeys.indexOf(model.pubKey) > -1 isChecked: root.pubKeys.indexOf(model.pubKey) > -1

View File

@ -198,7 +198,7 @@ Column {
Connections { Connections {
enabled: (!placeholderMessage && !!root.rootStore) enabled: (!placeholderMessage && !!root.rootStore)
target: !!root.rootStore ? root.rootStore.profileModelInst.contacts.list : null target: !!root.rootStore ? root.rootStore.allContacts : null
onContactChanged: { onContactChanged: {
if (pubkey === fromAuthor) { if (pubkey === fromAuthor) {
const img = appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) const img = appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage)

View File

@ -146,20 +146,20 @@ QtObject {
function getDisplayName(publicKey, contactIndex) { function getDisplayName(publicKey, contactIndex) {
if (contactIndex === undefined) { if (contactIndex === undefined) {
contactIndex = profileModel.contacts.list.getContactIndexByPubkey(publicKey) contactIndex = contactsModule.model.list.getContactIndexByPubkey(publicKey)
} }
if (contactIndex === -1) { if (contactIndex === -1) {
return utilsModel.generateAlias(publicKey) return utilsModel.generateAlias(publicKey)
} }
const ensVerified = profileModel.contacts.list.rowData(contactIndex, 'ensVerified') const ensVerified = contactsModule.model.list.rowData(contactIndex, 'ensVerified')
if (!ensVerified) { if (!ensVerified) {
const nickname = profileModel.contacts.list.rowData(contactIndex, 'localNickname') const nickname = contactsModule.model.list.rowData(contactIndex, 'localNickname')
if (nickname) { if (nickname) {
return nickname return nickname
} }
} }
return profileModel.contacts.list.rowData(contactIndex, 'name') return contactsModule.model.list.rowData(contactIndex, 'name')
} }
function isMnemonic(value) { function isMnemonic(value) {

2
vendor/status-lib vendored

@ -1 +1 @@
Subproject commit 158e83e78aea2cd5f1d33cc3b65b17c622bd686c Subproject commit 6d0e5ccf6232003231e7a83f52ffaaa85469e7bd