feat: add contact requests and handling of them
This commit is contained in:
parent
03addd4ea9
commit
436cb42eae
|
@ -74,7 +74,7 @@ QtObject:
|
||||||
proc pendingRequestsToJoinForCommunity*(self: CommunitiesView, communityId: string): seq[CommunityMembershipRequest] =
|
proc pendingRequestsToJoinForCommunity*(self: CommunitiesView, communityId: string): seq[CommunityMembershipRequest] =
|
||||||
result = self.status.chat.pendingRequestsToJoinForCommunity(communityId)
|
result = self.status.chat.pendingRequestsToJoinForCommunity(communityId)
|
||||||
|
|
||||||
proc membershipRequestPushed*(self: CommunitiesView, communityName: string, pubKey: string) {.signal.}
|
proc membershipRequestPushed*(self: CommunitiesView, communityId: string, communityName: string, pubKey: string) {.signal.}
|
||||||
|
|
||||||
proc addMembershipRequests*(self: CommunitiesView, membershipRequests: seq[CommunityMembershipRequest]) =
|
proc addMembershipRequests*(self: CommunitiesView, membershipRequests: seq[CommunityMembershipRequest]) =
|
||||||
var communityId: string
|
var communityId: string
|
||||||
|
@ -87,7 +87,7 @@ QtObject:
|
||||||
let alreadyPresentRequestIdx = community.membershipRequests.findIndexById(request.id)
|
let alreadyPresentRequestIdx = community.membershipRequests.findIndexById(request.id)
|
||||||
if (alreadyPresentRequestIdx == -1):
|
if (alreadyPresentRequestIdx == -1):
|
||||||
community.membershipRequests.add(request)
|
community.membershipRequests.add(request)
|
||||||
self.membershipRequestPushed(community.name, request.publicKey)
|
self.membershipRequestPushed(community.id, community.name, request.publicKey)
|
||||||
else:
|
else:
|
||||||
community.membershipRequests[alreadyPresentRequestIdx] = request
|
community.membershipRequests[alreadyPresentRequestIdx] = request
|
||||||
self.joinedCommunityList.replaceCommunity(community)
|
self.joinedCommunityList.replaceCommunity(community)
|
||||||
|
@ -171,7 +171,7 @@ QtObject:
|
||||||
error "Error joining the community", msg = e.msg
|
error "Error joining the community", msg = e.msg
|
||||||
result = fmt"Error joining the community: {e.msg}"
|
result = fmt"Error joining the community: {e.msg}"
|
||||||
|
|
||||||
proc membershipRequestChanged*(self: CommunitiesView, communityName: string, accepted: bool) {.signal.}
|
proc membershipRequestChanged*(self: CommunitiesView, communityId: string, communityName: string, accepted: bool) {.signal.}
|
||||||
|
|
||||||
proc communityAdded*(self: CommunitiesView, communityId: string) {.signal.}
|
proc communityAdded*(self: CommunitiesView, communityId: string) {.signal.}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ QtObject:
|
||||||
var i = 0
|
var i = 0
|
||||||
for communityRequest in self.myCommunityRequests:
|
for communityRequest in self.myCommunityRequests:
|
||||||
if (communityRequest.communityId == community.id):
|
if (communityRequest.communityId == community.id):
|
||||||
self.membershipRequestChanged(community.name, true)
|
self.membershipRequestChanged(community.id, community.name, true)
|
||||||
self.myCommunityRequests.delete(i, i)
|
self.myCommunityRequests.delete(i, i)
|
||||||
break
|
break
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
|
@ -49,6 +49,8 @@ QtObject:
|
||||||
proc activeChanged*(self: CommunityItemView) {.signal.}
|
proc activeChanged*(self: CommunityItemView) {.signal.}
|
||||||
|
|
||||||
proc setActive*(self: CommunityItemView, value: bool) {.slot.} =
|
proc setActive*(self: CommunityItemView, value: bool) {.slot.} =
|
||||||
|
if (self.active == value):
|
||||||
|
return
|
||||||
self.active = value
|
self.active = value
|
||||||
self.status.events.emit("communityActiveChanged", CommunityActiveChangedArgs(active: value))
|
self.status.events.emit("communityActiveChanged", CommunityActiveChangedArgs(active: value))
|
||||||
self.activeChanged()
|
self.activeChanged()
|
||||||
|
|
|
@ -120,6 +120,7 @@ proc init*(self: ProfileController, account: Account) =
|
||||||
# TODO: view should react to model changes
|
# TODO: view should react to model changes
|
||||||
self.status.chat.updateContacts(msgData.contacts)
|
self.status.chat.updateContacts(msgData.contacts)
|
||||||
self.view.contacts.updateContactList(msgData.contacts)
|
self.view.contacts.updateContactList(msgData.contacts)
|
||||||
|
self.view.contacts.notifyOnNewContactRequests(msgData.contacts)
|
||||||
if msgData.installations.len > 0:
|
if msgData.installations.len > 0:
|
||||||
self.view.devices.addDevices(msgData.installations)
|
self.view.devices.addDevices(msgData.installations)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ type
|
||||||
LocalNickname = UserRole + 9
|
LocalNickname = UserRole + 9
|
||||||
ThumbnailImage = UserRole + 10
|
ThumbnailImage = UserRole + 10
|
||||||
LargeImage = UserRole + 11
|
LargeImage = UserRole + 11
|
||||||
|
RequestReceived = UserRole + 12
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type ContactList* = ref object of QAbstractListModel
|
type ContactList* = ref object of QAbstractListModel
|
||||||
|
@ -38,6 +39,15 @@ QtObject:
|
||||||
method rowCount(self: ContactList, index: QModelIndex = nil): int =
|
method rowCount(self: ContactList, index: QModelIndex = nil): int =
|
||||||
return self.contacts.len
|
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.} =
|
proc userName*(self: ContactList, pubKey: string, defaultValue: string = ""): string {.slot.} =
|
||||||
for contact in self.contacts:
|
for contact in self.contacts:
|
||||||
if(contact.id != pubKey): continue
|
if(contact.id != pubKey): continue
|
||||||
|
@ -66,6 +76,7 @@ QtObject:
|
||||||
of "localNickname": result = $contact.localNickname
|
of "localNickname": result = $contact.localNickname
|
||||||
of "thumbnailImage": result = $contact.identityImage.thumbnail
|
of "thumbnailImage": result = $contact.identityImage.thumbnail
|
||||||
of "largeImage": result = $contact.identityImage.large
|
of "largeImage": result = $contact.identityImage.large
|
||||||
|
of "requestReceived": result = $contact.requestReceived()
|
||||||
|
|
||||||
method data(self: ContactList, index: QModelIndex, role: int): QVariant =
|
method data(self: ContactList, index: QModelIndex, role: int): QVariant =
|
||||||
if not index.isValid:
|
if not index.isValid:
|
||||||
|
@ -85,6 +96,7 @@ QtObject:
|
||||||
of ContactRoles.LocalNickname: result = newQVariant(contact.localNickname)
|
of ContactRoles.LocalNickname: result = newQVariant(contact.localNickname)
|
||||||
of ContactRoles.ThumbnailImage: result = newQVariant(contact.identityImage.thumbnail)
|
of ContactRoles.ThumbnailImage: result = newQVariant(contact.identityImage.thumbnail)
|
||||||
of ContactRoles.LargeImage: result = newQVariant(contact.identityImage.large)
|
of ContactRoles.LargeImage: result = newQVariant(contact.identityImage.large)
|
||||||
|
of ContactRoles.RequestReceived: result = newQVariant(contact.requestReceived())
|
||||||
|
|
||||||
method roleNames(self: ContactList): Table[int, string] =
|
method roleNames(self: ContactList): Table[int, string] =
|
||||||
{
|
{
|
||||||
|
@ -98,13 +110,15 @@ QtObject:
|
||||||
ContactRoles.LocalNickname.int:"localNickname",
|
ContactRoles.LocalNickname.int:"localNickname",
|
||||||
ContactRoles.EnsVerified.int:"ensVerified",
|
ContactRoles.EnsVerified.int:"ensVerified",
|
||||||
ContactRoles.ThumbnailImage.int:"thumbnailImage",
|
ContactRoles.ThumbnailImage.int:"thumbnailImage",
|
||||||
ContactRoles.LargeImage.int:"largeImage"
|
ContactRoles.LargeImage.int:"largeImage",
|
||||||
|
ContactRoles.RequestReceived.int:"requestReceived"
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
proc addContactToList*(self: ContactList, contact: Profile) =
|
proc addContactToList*(self: ContactList, contact: Profile) =
|
||||||
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()
|
||||||
|
|
||||||
proc hasAddedContacts(self: ContactList): bool {.slot.} =
|
proc hasAddedContacts(self: ContactList): bool {.slot.} =
|
||||||
for c in self.contacts:
|
for c in self.contacts:
|
||||||
|
@ -134,3 +148,4 @@ QtObject:
|
||||||
self.beginResetModel()
|
self.beginResetModel()
|
||||||
self.contacts = contactList
|
self.contacts = contactList
|
||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
|
self.countChanged()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, chronicles, sequtils, sugar, strutils
|
import NimQml, chronicles, sequtils, sugar, strutils, json
|
||||||
import ../../../status/libstatus/utils as status_utils
|
import ../../../status/libstatus/utils as status_utils
|
||||||
import ../../../status/status
|
import ../../../status/status
|
||||||
import ../../../status/chat/chat
|
import ../../../status/chat/chat
|
||||||
|
@ -34,6 +34,7 @@ QtObject:
|
||||||
type ContactsView* = ref object of QObject
|
type ContactsView* = ref object of QObject
|
||||||
status: Status
|
status: Status
|
||||||
contactList*: ContactList
|
contactList*: ContactList
|
||||||
|
contactRequests*: ContactList
|
||||||
addedContacts*: ContactList
|
addedContacts*: ContactList
|
||||||
blockedContacts*: ContactList
|
blockedContacts*: ContactList
|
||||||
contactToAdd*: Profile
|
contactToAdd*: Profile
|
||||||
|
@ -44,6 +45,7 @@ QtObject:
|
||||||
proc delete*(self: ContactsView) =
|
proc delete*(self: ContactsView) =
|
||||||
self.contactList.delete
|
self.contactList.delete
|
||||||
self.addedContacts.delete
|
self.addedContacts.delete
|
||||||
|
self.contactRequests.delete
|
||||||
self.blockedContacts.delete
|
self.blockedContacts.delete
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
|
@ -51,6 +53,7 @@ QtObject:
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.status = status
|
result.status = status
|
||||||
result.contactList = newContactList()
|
result.contactList = newContactList()
|
||||||
|
result.contactRequests = newContactList()
|
||||||
result.addedContacts = newContactList()
|
result.addedContacts = newContactList()
|
||||||
result.blockedContacts = newContactList()
|
result.blockedContacts = newContactList()
|
||||||
result.contactToAdd = Profile(
|
result.contactToAdd = Profile(
|
||||||
|
@ -63,10 +66,12 @@ QtObject:
|
||||||
proc updateContactList*(self: ContactsView, contacts: seq[Profile]) =
|
proc updateContactList*(self: ContactsView, contacts: seq[Profile]) =
|
||||||
for contact in contacts:
|
for contact in contacts:
|
||||||
self.contactList.updateContact(contact)
|
self.contactList.updateContact(contact)
|
||||||
if contact.systemTags.contains(":contact/added"):
|
if contact.systemTags.contains(contactAdded):
|
||||||
self.addedContacts.updateContact(contact)
|
self.addedContacts.updateContact(contact)
|
||||||
if contact.systemTags.contains(":contact/blocked"):
|
if contact.systemTags.contains(contactBlocked):
|
||||||
self.blockedContacts.updateContact(contact)
|
self.blockedContacts.updateContact(contact)
|
||||||
|
if contact.systemTags.contains(contactRequest) and not contact.systemTags.contains(contactAdded) and not contact.systemTags.contains(contactBlocked):
|
||||||
|
self.contactRequests.updateContact(contact)
|
||||||
|
|
||||||
proc contactListChanged*(self: ContactsView) {.signal.}
|
proc contactListChanged*(self: ContactsView) {.signal.}
|
||||||
|
|
||||||
|
@ -75,10 +80,18 @@ QtObject:
|
||||||
|
|
||||||
proc setContactList*(self: ContactsView, contactList: seq[Profile]) =
|
proc setContactList*(self: ContactsView, contactList: seq[Profile]) =
|
||||||
self.contactList.setNewData(contactList)
|
self.contactList.setNewData(contactList)
|
||||||
self.addedContacts.setNewData(contactList.filter(c => c.systemTags.contains(":contact/added")))
|
self.addedContacts.setNewData(contactList.filter(c => c.systemTags.contains(contactAdded)))
|
||||||
self.blockedContacts.setNewData(contactList.filter(c => c.systemTags.contains(":contact/blocked")))
|
self.blockedContacts.setNewData(contactList.filter(c => c.systemTags.contains(contactBlocked)))
|
||||||
|
self.contactRequests.setNewData(contactList.filter(c => c.systemTags.contains(contactRequest) and not c.systemTags.contains(contactAdded) and not c.systemTags.contains(contactBlocked)))
|
||||||
self.contactListChanged()
|
self.contactListChanged()
|
||||||
|
|
||||||
|
proc contactRequestAdded*(self: ContactsView, name: string, address: string) {.signal.}
|
||||||
|
|
||||||
|
proc notifyOnNewContactRequests*(self: ContactsView, contacts: seq[Profile]) =
|
||||||
|
for contact in contacts:
|
||||||
|
if contact.systemTags.contains(contactRequest) and not contact.systemTags.contains(contactAdded) and not contact.systemTags.contains(contactBlocked):
|
||||||
|
self.contactRequestAdded(status_ens.userNameOrAlias(contact), contact.address)
|
||||||
|
|
||||||
QtProperty[QVariant] list:
|
QtProperty[QVariant] list:
|
||||||
read = getContactList
|
read = getContactList
|
||||||
write = setContactList
|
write = setContactList
|
||||||
|
@ -104,6 +117,13 @@ QtObject:
|
||||||
return true
|
return true
|
||||||
return false
|
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 contactToAddChanged*(self: ContactsView) {.signal.}
|
||||||
|
|
||||||
proc getContactToAddUsername(self: ContactsView): QVariant {.slot.} =
|
proc getContactToAddUsername(self: ContactsView): QVariant {.slot.} =
|
||||||
|
@ -129,6 +149,10 @@ QtObject:
|
||||||
if id == "": return false
|
if id == "": return false
|
||||||
self.status.contacts.isAdded(id)
|
self.status.contacts.isAdded(id)
|
||||||
|
|
||||||
|
proc contactRequestReceived*(self: ContactsView, id: string): bool {.slot.} =
|
||||||
|
if id == "": return false
|
||||||
|
self.status.contacts.contactRequestReceived(id)
|
||||||
|
|
||||||
proc lookupContact*(self: ContactsView, value: string) {.slot.} =
|
proc lookupContact*(self: ContactsView, value: string) {.slot.} =
|
||||||
if value == "":
|
if value == "":
|
||||||
return
|
return
|
||||||
|
@ -164,6 +188,19 @@ QtObject:
|
||||||
self.status.chat.join(status_utils.getTimelineChatId(publicKey), ChatType.Profile, "", publicKey)
|
self.status.chat.join(status_utils.getTimelineChatId(publicKey), ChatType.Profile, "", publicKey)
|
||||||
self.contactChanged(publicKey, true)
|
self.contactChanged(publicKey, true)
|
||||||
|
|
||||||
|
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:
|
||||||
|
discard self.addContact(pubkey.getStr)
|
||||||
|
|
||||||
proc changeContactNickname*(self: ContactsView, publicKey: string, nickname: string) {.slot.} =
|
proc changeContactNickname*(self: ContactsView, publicKey: string, nickname: string) {.slot.} =
|
||||||
var nicknameToSet = nickname
|
var nicknameToSet = nickname
|
||||||
if (nicknameToSet == ""):
|
if (nicknameToSet == ""):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import json, sequtils, sugar
|
import json, sequtils, sugar, chronicles
|
||||||
import libstatus/contacts as status_contacts
|
import libstatus/contacts as status_contacts
|
||||||
import libstatus/accounts as status_accounts
|
import libstatus/accounts as status_accounts
|
||||||
import libstatus/chat as status_chat
|
import libstatus/chat as status_chat
|
||||||
|
@ -33,13 +33,17 @@ proc getContactByID*(self: ContactModel, id: string): Profile =
|
||||||
|
|
||||||
proc blockContact*(self: ContactModel, id: string): string =
|
proc blockContact*(self: ContactModel, id: string): string =
|
||||||
var contact = self.getContactByID(id)
|
var contact = self.getContactByID(id)
|
||||||
contact.systemTags.add(":contact/blocked")
|
contact.systemTags.add(contactBlocked)
|
||||||
|
let index = contact.systemTags.find(contactAdded)
|
||||||
|
if (index > -1):
|
||||||
|
contact.systemTags.delete(index)
|
||||||
discard status_contacts.blockContact(contact)
|
discard status_contacts.blockContact(contact)
|
||||||
self.events.emit("contactBlocked", Args())
|
self.events.emit("contactBlocked", Args())
|
||||||
|
|
||||||
|
|
||||||
proc unblockContact*(self: ContactModel, id: string): string =
|
proc unblockContact*(self: ContactModel, id: string): string =
|
||||||
var contact = self.getContactByID(id)
|
var contact = self.getContactByID(id)
|
||||||
contact.systemTags.delete(contact.systemTags.find(":contact/blocked"))
|
contact.systemTags.delete(contact.systemTags.find(contactBlocked))
|
||||||
discard status_contacts.saveContact(contact.id, contact.ensVerified, contact.ensName, contact.alias, contact.identicon, contact.identityImage.thumbnail, contact.systemTags, contact.localNickname)
|
discard status_contacts.saveContact(contact.id, contact.ensVerified, contact.ensName, contact.alias, contact.identicon, contact.identityImage.thumbnail, contact.systemTags, contact.localNickname)
|
||||||
self.events.emit("contactUnblocked", Args())
|
self.events.emit("contactUnblocked", Args())
|
||||||
|
|
||||||
|
@ -47,7 +51,7 @@ proc getAllContacts*(): seq[Profile] =
|
||||||
result = map(status_contacts.getContacts().getElems(), proc(x: JsonNode): Profile = x.toProfileModel())
|
result = map(status_contacts.getContacts().getElems(), proc(x: JsonNode): Profile = x.toProfileModel())
|
||||||
|
|
||||||
proc getAddedContacts*(): seq[Profile] =
|
proc getAddedContacts*(): seq[Profile] =
|
||||||
result = getAllContacts().filter(c => c.systemTags.contains(":contact/added"))
|
result = getAllContacts().filter(c => c.systemTags.contains(contactAdded))
|
||||||
|
|
||||||
proc getContacts*(self: ContactModel): seq[Profile] =
|
proc getContacts*(self: ContactModel): seq[Profile] =
|
||||||
result = getAllContacts()
|
result = getAllContacts()
|
||||||
|
@ -89,10 +93,16 @@ proc setNickName*(self: ContactModel, id: string, localNickname: string): string
|
||||||
|
|
||||||
proc addContact*(self: ContactModel, id: string): string =
|
proc addContact*(self: ContactModel, id: string): string =
|
||||||
var contact = self.getOrCreateContact(id)
|
var contact = self.getOrCreateContact(id)
|
||||||
let updating = contact.systemTags.contains(":contact/added")
|
|
||||||
|
let updating = contact.systemTags.contains(contactAdded)
|
||||||
if not updating:
|
if not updating:
|
||||||
contact.systemTags.add(":contact/added")
|
contact.systemTags.add(contactAdded)
|
||||||
discard status_chat.createProfileChat(contact.id)
|
discard status_chat.createProfileChat(contact.id)
|
||||||
|
else:
|
||||||
|
let index = contact.systemTags.find(contactBlocked)
|
||||||
|
if (index > -1):
|
||||||
|
contact.systemTags.delete(index)
|
||||||
|
|
||||||
var thumbnail = ""
|
var thumbnail = ""
|
||||||
if contact.identityImage != nil:
|
if contact.identityImage != nil:
|
||||||
thumbnail = contact.identityImage.thumbnail
|
thumbnail = contact.identityImage.thumbnail
|
||||||
|
@ -117,7 +127,7 @@ proc addContact*(self: ContactModel, id: string): string =
|
||||||
|
|
||||||
proc removeContact*(self: ContactModel, id: string) =
|
proc removeContact*(self: ContactModel, id: string) =
|
||||||
let contact = self.getContactByID(id)
|
let contact = self.getContactByID(id)
|
||||||
contact.systemTags.delete(contact.systemTags.find(":contact/added"))
|
contact.systemTags.delete(contact.systemTags.find(contactAdded))
|
||||||
|
|
||||||
var thumbnail = ""
|
var thumbnail = ""
|
||||||
if contact.identityImage != nil:
|
if contact.identityImage != nil:
|
||||||
|
@ -129,4 +139,20 @@ proc removeContact*(self: ContactModel, id: string) =
|
||||||
proc isAdded*(self: ContactModel, id: string): bool =
|
proc isAdded*(self: ContactModel, id: string): bool =
|
||||||
var contact = self.getContactByID(id)
|
var contact = self.getContactByID(id)
|
||||||
if contact.isNil: return false
|
if contact.isNil: return false
|
||||||
contact.systemTags.contains(":contact/added")
|
contact.systemTags.contains(contactAdded)
|
||||||
|
|
||||||
|
proc contactRequestReceived*(self: ContactModel, id: string): bool =
|
||||||
|
var contact = self.getContactByID(id)
|
||||||
|
if contact.isNil: return false
|
||||||
|
contact.systemTags.contains(contactRequest)
|
||||||
|
|
||||||
|
proc rejectContactRequest*(self: ContactModel, id: string) =
|
||||||
|
let contact = self.getContactByID(id)
|
||||||
|
contact.systemTags.delete(contact.systemTags.find(contactRequest))
|
||||||
|
|
||||||
|
var thumbnail = ""
|
||||||
|
if contact.identityImage != nil:
|
||||||
|
thumbnail = contact.identityImage.thumbnail
|
||||||
|
|
||||||
|
discard status_contacts.saveContact(contact.id, contact.ensVerified, contact.ensName, contact.alias, contact.identicon, thumbnail, contact.systemTags, contact.localNickname)
|
||||||
|
self.events.emit("contactRemoved", Args())
|
||||||
|
|
|
@ -8,11 +8,19 @@ type Profile* = ref object
|
||||||
appearance*: int
|
appearance*: int
|
||||||
systemTags*: seq[string]
|
systemTags*: seq[string]
|
||||||
|
|
||||||
|
|
||||||
|
const contactAdded* = ":contact/added"
|
||||||
|
const contactBlocked* = ":contact/blocked"
|
||||||
|
const contactRequest* = ":contact/request-received"
|
||||||
|
|
||||||
proc isContact*(self: Profile): bool =
|
proc isContact*(self: Profile): bool =
|
||||||
result = self.systemTags.contains(":contact/added") and not self.systemTags.contains(":contact/blocked")
|
result = self.systemTags.contains(contactAdded) and not self.systemTags.contains(":contact/blocked")
|
||||||
|
|
||||||
proc isBlocked*(self: Profile): bool =
|
proc isBlocked*(self: Profile): bool =
|
||||||
result = self.systemTags.contains(":contact/blocked")
|
result = self.systemTags.contains(contactBlocked)
|
||||||
|
|
||||||
|
proc requestReceived*(self: Profile): bool =
|
||||||
|
result = self.systemTags.contains(contactRequest)
|
||||||
|
|
||||||
proc toProfileModel*(account: Account): Profile =
|
proc toProfileModel*(account: Account): Profile =
|
||||||
result = Profile(
|
result = Profile(
|
||||||
|
|
|
@ -29,13 +29,17 @@ StackLayout {
|
||||||
property var doNotShowAddToContactBannerToThose: ([])
|
property var doNotShowAddToContactBannerToThose: ([])
|
||||||
|
|
||||||
property var onActivated: function () {
|
property var onActivated: function () {
|
||||||
chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
inputArea.chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
property string activeChatId: chatsModel.activeChannel.id
|
property string activeChatId: chatsModel.activeChannel.id
|
||||||
property bool isBlocked: profileModel.contacts.isContactBlocked(activeChatId)
|
property bool isBlocked: profileModel.contacts.isContactBlocked(activeChatId)
|
||||||
|
property bool isContact: profileModel.contacts.isAdded(activeChatId)
|
||||||
|
|
||||||
property alias input: chatInput
|
property alias input: inputArea.chatInput
|
||||||
|
|
||||||
|
property string currentNotificationChatId
|
||||||
|
property string currentNotificationCommunityId
|
||||||
|
|
||||||
property string hoveredMessage
|
property string hoveredMessage
|
||||||
property string activeMessage
|
property string activeMessage
|
||||||
|
@ -57,7 +61,7 @@ StackLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
inputArea.chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
@ -95,12 +99,12 @@ StackLayout {
|
||||||
identicon: chatsModel.messageList.getMessageData(i, "identicon"),
|
identicon: chatsModel.messageList.getMessageData(i, "identicon"),
|
||||||
localNickname: chatsModel.messageList.getMessageData(i, "localName")
|
localNickname: chatsModel.messageList.getMessageData(i, "localName")
|
||||||
})
|
})
|
||||||
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
inputArea.chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
||||||
idMap[contactAddr] = true;
|
idMap[contactAddr] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateSuggestions() {
|
function populateSuggestions() {
|
||||||
chatInput.suggestionsList.clear()
|
inputArea.chatInput.suggestionsList.clear()
|
||||||
const len = chatsModel.suggestionList.rowCount()
|
const len = chatsModel.suggestionList.rowCount()
|
||||||
|
|
||||||
idMap = {}
|
idMap = {}
|
||||||
|
@ -116,7 +120,7 @@ StackLayout {
|
||||||
localNickname: chatsModel.suggestionList.rowData(i, "localNickname")
|
localNickname: chatsModel.suggestionList.rowData(i, "localNickname")
|
||||||
})
|
})
|
||||||
|
|
||||||
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
inputArea.chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
||||||
idMap[contactAddr] = true;
|
idMap[contactAddr] = true;
|
||||||
}
|
}
|
||||||
const len2 = chatsModel.messageList.rowCount();
|
const len2 = chatsModel.messageList.rowCount();
|
||||||
|
@ -135,7 +139,7 @@ StackLayout {
|
||||||
let message = chatsModel.messageList.getMessageData(replyMessageIndex, "message")
|
let message = chatsModel.messageList.getMessageData(replyMessageIndex, "message")
|
||||||
let identicon = chatsModel.messageList.getMessageData(replyMessageIndex, "identicon")
|
let identicon = chatsModel.messageList.getMessageData(replyMessageIndex, "identicon")
|
||||||
|
|
||||||
chatInput.showReplyArea(userName, message, identicon)
|
inputArea.chatInput.showReplyArea(userName, message, identicon)
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestAddressForTransaction(address, amount, tokenAddress, tokenDecimals = 18) {
|
function requestAddressForTransaction(address, amount, tokenAddress, tokenDecimals = 18) {
|
||||||
|
@ -165,6 +169,25 @@ StackLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickOnNotification() {
|
||||||
|
applicationWindow.show()
|
||||||
|
applicationWindow.raise()
|
||||||
|
applicationWindow.requestActivate()
|
||||||
|
appMain.changeAppSection(Constants.chat)
|
||||||
|
if (currentNotificationChatId) {
|
||||||
|
chatsModel.setActiveChannel(currentNotificationChatId)
|
||||||
|
} else if (currentNotificationCommunityId) {
|
||||||
|
chatsModel.communities.setActiveCommunity(currentNotificationCommunityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: systemTray
|
||||||
|
onMessageClicked: function () {
|
||||||
|
clickOnNotification()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: timer
|
id: timer
|
||||||
}
|
}
|
||||||
|
@ -222,54 +245,9 @@ StackLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
AddToContactBanner {
|
||||||
visible: chatsModel.activeChannel.chatType === Constants.chatTypeOneToOne &&
|
|
||||||
!profileModel.contacts.isAdded(activeChatId) &&
|
|
||||||
!doNotShowAddToContactBannerToThose.includes(activeChatId)
|
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 36
|
|
||||||
|
|
||||||
SVGImage {
|
|
||||||
source: "../../img/plusSign.svg"
|
|
||||||
anchors.right: addToContactsTxt.left
|
|
||||||
anchors.rightMargin: Style.current.smallPadding
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
layer.enabled: true
|
|
||||||
layer.effect: ColorOverlay { color: addToContactsTxt.color }
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: addToContactsTxt
|
|
||||||
text: qsTr("Add to contacts")
|
|
||||||
color: Style.current.primary
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Separator {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: profileModel.contacts.addContact(activeChatId)
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusIconButton {
|
|
||||||
id: closeBtn
|
|
||||||
icon.name: "close"
|
|
||||||
onClicked: {
|
|
||||||
const newArray = Object.assign([], doNotShowAddToContactBannerToThose)
|
|
||||||
newArray.push(activeChatId)
|
|
||||||
doNotShowAddToContactBannerToThose = newArray
|
|
||||||
}
|
|
||||||
width: 20
|
|
||||||
height: 20
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Style.current.halfPadding
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
|
@ -306,8 +284,8 @@ StackLayout {
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel
|
||||||
onActiveChannelChanged: {
|
onActiveChannelChanged: {
|
||||||
chatInput.suggestions.hide();
|
inputArea.chatInput.suggestions.hide();
|
||||||
chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
inputArea.chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
populateSuggestions();
|
populateSuggestions();
|
||||||
}
|
}
|
||||||
onMessagePushed: {
|
onMessagePushed: {
|
||||||
|
@ -322,97 +300,17 @@ StackLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
ChatRequestMessage {
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: Style.current.bigPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
InputArea {
|
||||||
id: inputArea
|
id: inputArea
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: parent.width
|
Layout.preferredWidth: parent.width
|
||||||
height: chatInput.height
|
|
||||||
Layout.preferredHeight: height
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: chatsModel
|
|
||||||
onLoadingMessagesChanged:
|
|
||||||
if(value){
|
|
||||||
loadingMessagesIndicator.active = true
|
|
||||||
} else {
|
|
||||||
timer.setTimeout(function(){
|
|
||||||
loadingMessagesIndicator.active = false;
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loadingMessagesIndicator
|
|
||||||
active: chatsModel.loadingMessages
|
|
||||||
sourceComponent: loadingIndicator
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: chatInput.top
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
anchors.bottomMargin: Style.current.padding
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: loadingIndicator
|
|
||||||
LoadingAnimation {}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusChatInput {
|
|
||||||
id: chatInput
|
|
||||||
visible: {
|
|
||||||
const community = chatsModel.communities.activeCommunity
|
|
||||||
if (chatsModel.activeChannel.chatType === Constants.chatTypePrivateGroupChat) {
|
|
||||||
return chatsModel.activeChannel.isMember
|
|
||||||
}
|
|
||||||
return !community.active ||
|
|
||||||
community.access === Constants.communityChatPublicAccess ||
|
|
||||||
community.admin ||
|
|
||||||
chatsModel.activeChannel.canPost
|
|
||||||
}
|
|
||||||
enabled: !isBlocked
|
|
||||||
chatInputPlaceholder: isBlocked ?
|
|
||||||
//% "This user has been blocked."
|
|
||||||
qsTrId("this-user-has-been-blocked-") :
|
|
||||||
//% "Type a message."
|
|
||||||
qsTrId("type-a-message-")
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
recentStickers: chatsModel.stickers.recent
|
|
||||||
stickerPackList: chatsModel.stickers.stickerPacks
|
|
||||||
chatType: chatsModel.activeChannel.chatType
|
|
||||||
onSendTransactionCommandButtonClicked: {
|
|
||||||
if (chatsModel.activeChannel.ensVerified) {
|
|
||||||
txModalLoader.sourceComponent = cmpSendTransactionWithEns
|
|
||||||
} else {
|
|
||||||
txModalLoader.sourceComponent = cmpSendTransactionNoEns
|
|
||||||
}
|
|
||||||
txModalLoader.item.open()
|
|
||||||
}
|
|
||||||
onReceiveTransactionCommandButtonClicked: {
|
|
||||||
txModalLoader.sourceComponent = cmpReceiveTransaction
|
|
||||||
txModalLoader.item.open()
|
|
||||||
}
|
|
||||||
onStickerSelected: {
|
|
||||||
chatsModel.stickers.send(hashId, packId)
|
|
||||||
}
|
|
||||||
onSendMessage: {
|
|
||||||
if (chatInput.fileUrls.length > 0){
|
|
||||||
chatsModel.sendImages(JSON.stringify(fileUrls));
|
|
||||||
}
|
|
||||||
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
|
||||||
if (msg.length > 0){
|
|
||||||
msg = chatInput.interpretMessage(msg)
|
|
||||||
chatsModel.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
|
||||||
if(event) event.accepted = true
|
|
||||||
sendMessageSound.stop();
|
|
||||||
Qt.callLater(sendMessageSound.play);
|
|
||||||
|
|
||||||
chatInput.textInput.clear();
|
|
||||||
chatInput.textInput.textFormat = TextEdit.PlainText;
|
|
||||||
chatInput.textInput.textFormat = TextEdit.RichText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtGraphicalEffects 1.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: chatsModel.activeChannel.chatType === Constants.chatTypeOneToOne &&
|
||||||
|
!isContact &&
|
||||||
|
!doNotShowAddToContactBannerToThose.includes(activeChatId)
|
||||||
|
height: 36
|
||||||
|
|
||||||
|
SVGImage {
|
||||||
|
source: "../../../../img/plusSign.svg"
|
||||||
|
anchors.right: addToContactsTxt.left
|
||||||
|
anchors.rightMargin: Style.current.smallPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: ColorOverlay { color: addToContactsTxt.color }
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: addToContactsTxt
|
||||||
|
text: qsTr("Add to contacts")
|
||||||
|
color: Style.current.primary
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Separator {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: profileModel.contacts.addContact(activeChatId)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: closeBtn
|
||||||
|
icon.name: "close"
|
||||||
|
onClicked: {
|
||||||
|
const newArray = Object.assign([], doNotShowAddToContactBannerToThose)
|
||||||
|
newArray.push(activeChatId)
|
||||||
|
doNotShowAddToContactBannerToThose = newArray
|
||||||
|
}
|
||||||
|
width: 20
|
||||||
|
height: 20
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: chatsModel.activeChannel.chatType === Constants.chatTypeOneToOne && !isContact
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: waveImg
|
||||||
|
source: "../../../../img/wave.png"
|
||||||
|
width: 80
|
||||||
|
height: 80
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: contactText1
|
||||||
|
text: qsTr("You need to be mutual contacts with this person for them to receive your messages")
|
||||||
|
anchors.top: waveImg.bottom
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
anchors.topMargin: Style.current.padding
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width / 1.3
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: contactText2
|
||||||
|
text: qsTr("Just click this button to add them as contact. They will receive a notification all once they accept you as contact as well, you'll be able to chat")
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
anchors.top: contactText1.bottom
|
||||||
|
anchors.topMargin: 2
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width / 1.3
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Add to contacts")
|
||||||
|
anchors.top: contactText2.bottom
|
||||||
|
anchors.topMargin: Style.current.smallPadding
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
onClicked: profileModel.contacts.addContact(activeChatId)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
import "../../components"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property alias chatInput: chatInput
|
||||||
|
|
||||||
|
id: inputArea
|
||||||
|
height: chatInput.height
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatsModel
|
||||||
|
onLoadingMessagesChanged:
|
||||||
|
if(value){
|
||||||
|
loadingMessagesIndicator.active = true
|
||||||
|
} else {
|
||||||
|
timer.setTimeout(function(){
|
||||||
|
loadingMessagesIndicator.active = false;
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loadingMessagesIndicator
|
||||||
|
active: chatsModel.loadingMessages
|
||||||
|
sourceComponent: loadingIndicator
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: chatInput.top
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
anchors.bottomMargin: Style.current.padding
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: loadingIndicator
|
||||||
|
LoadingAnimation {}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusChatInput {
|
||||||
|
id: chatInput
|
||||||
|
visible: {
|
||||||
|
const community = chatsModel.communities.activeCommunity
|
||||||
|
if (chatsModel.activeChannel.chatType === Constants.chatTypePrivateGroupChat) {
|
||||||
|
return chatsModel.activeChannel.isMember
|
||||||
|
}
|
||||||
|
return !community.active ||
|
||||||
|
community.access === Constants.communityChatPublicAccess ||
|
||||||
|
community.admin ||
|
||||||
|
chatsModel.activeChannel.canPost
|
||||||
|
}
|
||||||
|
enabled: !isBlocked
|
||||||
|
chatInputPlaceholder: isBlocked ?
|
||||||
|
//% "This user has been blocked."
|
||||||
|
qsTrId("this-user-has-been-blocked-") :
|
||||||
|
//% "Type a message."
|
||||||
|
qsTrId("type-a-message-")
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
recentStickers: chatsModel.stickers.recent
|
||||||
|
stickerPackList: chatsModel.stickers.stickerPacks
|
||||||
|
chatType: chatsModel.activeChannel.chatType
|
||||||
|
onSendTransactionCommandButtonClicked: {
|
||||||
|
if (chatsModel.activeChannel.ensVerified) {
|
||||||
|
txModalLoader.sourceComponent = cmpSendTransactionWithEns
|
||||||
|
} else {
|
||||||
|
txModalLoader.sourceComponent = cmpSendTransactionNoEns
|
||||||
|
}
|
||||||
|
txModalLoader.item.open()
|
||||||
|
}
|
||||||
|
onReceiveTransactionCommandButtonClicked: {
|
||||||
|
txModalLoader.sourceComponent = cmpReceiveTransaction
|
||||||
|
txModalLoader.item.open()
|
||||||
|
}
|
||||||
|
onStickerSelected: {
|
||||||
|
chatsModel.stickers.send(hashId, packId)
|
||||||
|
}
|
||||||
|
onSendMessage: {
|
||||||
|
if (chatInput.fileUrls.length > 0){
|
||||||
|
chatsModel.sendImages(JSON.stringify(fileUrls));
|
||||||
|
}
|
||||||
|
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
||||||
|
if (msg.length > 0){
|
||||||
|
msg = chatInput.interpretMessage(msg)
|
||||||
|
chatsModel.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
||||||
|
if(event) event.accepted = true
|
||||||
|
sendMessageSound.stop();
|
||||||
|
Qt.callLater(sendMessageSound.play);
|
||||||
|
|
||||||
|
chatInput.textInput.clear();
|
||||||
|
chatInput.textInput.textFormat = TextEdit.PlainText;
|
||||||
|
chatInput.textInput.textFormat = TextEdit.RichText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import QtQml.Models 2.13
|
||||||
import QtGraphicalEffects 1.13
|
import QtGraphicalEffects 1.13
|
||||||
import QtQuick.Dialogs 1.3
|
import QtQuick.Dialogs 1.3
|
||||||
import "../../../../shared"
|
import "../../../../shared"
|
||||||
|
import "../../../../shared/status"
|
||||||
import "../../../../imports"
|
import "../../../../imports"
|
||||||
import "../components"
|
import "../components"
|
||||||
import "./samples/"
|
import "./samples/"
|
||||||
|
@ -31,8 +32,6 @@ ScrollView {
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
property string currentNotificationChatId
|
|
||||||
|
|
||||||
id: chatLogView
|
id: chatLogView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.bottomMargin: Style.current.bigPadding
|
anchors.bottomMargin: Style.current.bigPadding
|
||||||
|
@ -47,23 +46,33 @@ ScrollView {
|
||||||
verticalLayoutDirection: ListView.BottomToTop
|
verticalLayoutDirection: ListView.BottomToTop
|
||||||
|
|
||||||
// This header and Connections is to create an invisible padding so that the chat identifier is at the top
|
// This header and Connections is to create an invisible padding so that the chat identifier is at the top
|
||||||
// The Connections is necessary, because doing the check inside teh ehader created a binding loop (the contentHeight includes the header height
|
// The Connections is necessary, because doing the check inside the header created a binding loop (the contentHeight includes the header height
|
||||||
// If the content height is smaller than the full height, we "show" the padding so that the chat identifier is at the top, otherwise we disable the Connections
|
// If the content height is smaller than the full height, we "show" the padding so that the chat identifier is at the top, otherwise we disable the Connections
|
||||||
header: Item {
|
header: Item {
|
||||||
height: 0
|
height: 0
|
||||||
width: chatLogView.width
|
width: chatLogView.width
|
||||||
}
|
}
|
||||||
|
function checkHeaderHeight() {
|
||||||
|
if (!chatLogView.headerItem) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatLogView.contentItem.height - chatLogView.headerItem.height < chatLogView.height) {
|
||||||
|
chatLogView.headerItem.height = chatLogView.height - (chatLogView.contentItem.height - chatLogView.headerItem.height) - 36
|
||||||
|
} else {
|
||||||
|
chatLogView.headerItem.height = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
id: contentHeightConnection
|
id: contentHeightConnection
|
||||||
enabled: true
|
enabled: true
|
||||||
target: chatLogView
|
target: chatLogView
|
||||||
onContentHeightChanged: {
|
onContentHeightChanged: {
|
||||||
if (chatLogView.contentItem.height - chatLogView.headerItem.height < chatLogView.height) {
|
chatLogView.checkHeaderHeight()
|
||||||
chatLogView.headerItem.height = chatLogView.height - (chatLogView.contentItem.height - chatLogView.headerItem.height) - 36
|
}
|
||||||
} else {
|
onHeightChanged: {
|
||||||
chatLogView.headerItem.height = 0
|
chatLogView.checkHeaderHeight()
|
||||||
contentHeightConnection.enabled = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,14 +157,6 @@ ScrollView {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickOnNotification(chatId) {
|
|
||||||
applicationWindow.show()
|
|
||||||
applicationWindow.raise()
|
|
||||||
applicationWindow.requestActivate()
|
|
||||||
chatsModel.setActiveChannel(chatId)
|
|
||||||
appMain.changeAppSection(Constants.chat)
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel
|
||||||
onMessagesLoaded: {
|
onMessagesLoaded: {
|
||||||
|
@ -191,7 +192,8 @@ ScrollView {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
chatLogView.currentNotificationChatId = chatId
|
chatColumnLayout.currentNotificationChatId = chatId
|
||||||
|
chatColumnLayout.currentNotificationCommunityId = null
|
||||||
|
|
||||||
let name;
|
let name;
|
||||||
if (appSettings.notificationMessagePreviewSetting === Constants.notificationPreviewAnonymous) {
|
if (appSettings.notificationMessagePreviewSetting === Constants.notificationPreviewAnonymous) {
|
||||||
|
@ -223,7 +225,7 @@ ScrollView {
|
||||||
SystemTrayIcon.NoIcon,
|
SystemTrayIcon.NoIcon,
|
||||||
Constants.notificationPopupTTL)
|
Constants.notificationPopupTTL)
|
||||||
} else {
|
} else {
|
||||||
notificationWindow.notifyUser(chatId, name, message, chatType, identicon, chatLogView.clickOnNotification)
|
notificationWindow.notifyUser(chatId, name, message, chatType, identicon, chatColumnLayout.clickOnNotification)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +234,9 @@ ScrollView {
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel.communities
|
target: chatsModel.communities
|
||||||
|
|
||||||
onMembershipRequestChanged: function (communityName, accepted) {
|
onMembershipRequestChanged: function (communityId, communityName, accepted) {
|
||||||
|
chatColumnLayout.currentNotificationChatId = null
|
||||||
|
chatColumnLayout.currentNotificationCommunityId = communityId
|
||||||
systemTray.showMessage("Status",
|
systemTray.showMessage("Status",
|
||||||
accepted ? qsTr("You have been accepted into the ‘%1’ community").arg(communityName) :
|
accepted ? qsTr("You have been accepted into the ‘%1’ community").arg(communityName) :
|
||||||
qsTr("Your request to join the ‘%1’ community was declined").arg(communityName),
|
qsTr("Your request to join the ‘%1’ community was declined").arg(communityName),
|
||||||
|
@ -240,7 +244,9 @@ ScrollView {
|
||||||
Constants.notificationPopupTTL)
|
Constants.notificationPopupTTL)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMembershipRequestPushed: function (communityName, pubKey) {
|
onMembershipRequestPushed: function (communityId, communityName, pubKey) {
|
||||||
|
chatColumnLayout.currentNotificationChatId = null
|
||||||
|
chatColumnLayout.currentNotificationCommunityId = communityId
|
||||||
systemTray.showMessage(qsTr("New membership request"),
|
systemTray.showMessage(qsTr("New membership request"),
|
||||||
qsTr("%1 asks to join ‘%2’").arg(Utils.getDisplayName(pubKey)).arg(communityName),
|
qsTr("%1 asks to join ‘%2’").arg(Utils.getDisplayName(pubKey)).arg(communityName),
|
||||||
SystemTrayIcon.NoIcon,
|
SystemTrayIcon.NoIcon,
|
||||||
|
@ -248,13 +254,6 @@ ScrollView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: systemTray
|
|
||||||
onMessageClicked: {
|
|
||||||
chatLogView.clickOnNotification(chatLogView.currentNotificationChatId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
||||||
if(loadingMessages) return;
|
if(loadingMessages) return;
|
||||||
loadingMessages = true;
|
loadingMessages = true;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
import Qt.labs.platform 1.1
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import QtQuick.Layouts 1.13
|
import QtQuick.Layouts 1.13
|
||||||
|
|
||||||
import "../../../imports"
|
import "../../../imports"
|
||||||
import "../../../shared"
|
import "../../../shared"
|
||||||
|
import "../../../shared/status"
|
||||||
import "./components"
|
import "./components"
|
||||||
import "./ContactsColumn"
|
import "./ContactsColumn"
|
||||||
import "./CommunityComponents"
|
import "./CommunityComponents"
|
||||||
|
@ -90,6 +92,15 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: contactRequestsPopup
|
||||||
|
ContactRequestsPopup {
|
||||||
|
onClosed: {
|
||||||
|
destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: searchBox
|
id: searchBox
|
||||||
anchors.top: title.bottom
|
anchors.top: title.bottom
|
||||||
|
@ -108,9 +119,37 @@ Rectangle {
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: profileModel.contacts
|
||||||
|
onContactRequestAdded: {
|
||||||
|
systemTray.showMessage(qsTr("New contact request"),
|
||||||
|
qsTr("%1 requests to become contacts").arg(Utils.removeStatusEns(name)),
|
||||||
|
SystemTrayIcon.NoIcon,
|
||||||
|
Constants.notificationPopupTTL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusSettingsLineButton {
|
||||||
|
property int nbRequests: profileModel.contacts.contactRequests.count
|
||||||
|
|
||||||
|
id: contactRequest
|
||||||
|
anchors.top: searchBox.bottom
|
||||||
|
anchors.topMargin: visible ? Style.current.padding : 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.halfPadding
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
visible: nbRequests > 0
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
text: qsTr("Contact requests")
|
||||||
|
isBadge: true
|
||||||
|
badgeText: nbRequests.toString()
|
||||||
|
onClicked: openPopup(contactRequestsPopup)
|
||||||
|
}
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: chatGroupsContainer
|
id: chatGroupsContainer
|
||||||
anchors.top: searchBox.bottom
|
anchors.top: contactRequest.bottom
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import QtGraphicalEffects 1.13
|
||||||
|
import "../../../../imports"
|
||||||
|
import "../../../../shared"
|
||||||
|
import "../../../../shared/status"
|
||||||
|
import "../../Profile/Sections/Contacts"
|
||||||
|
|
||||||
|
ModalPopup {
|
||||||
|
id: popup
|
||||||
|
|
||||||
|
|
||||||
|
title: qsTr("Contact requests")
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: contactList
|
||||||
|
|
||||||
|
property Component profilePopupComponent: ProfilePopup {
|
||||||
|
id: profilePopup
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: -Style.current.halfPadding
|
||||||
|
anchors.rightMargin: -Style.current.halfPadding
|
||||||
|
|
||||||
|
model: profileModel.contacts.contactRequests
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: ContactRequest {
|
||||||
|
name: Utils.removeStatusEns(model.name)
|
||||||
|
address: model.address
|
||||||
|
localNickname: model.localNickname
|
||||||
|
identicon: model.thumbnailImage || model.identicon
|
||||||
|
profileClick: function (showFooter, userName, fromAuthor, identicon, textParam, nickName) {
|
||||||
|
var popup = profilePopupComponent.createObject(contactList);
|
||||||
|
popup.openPopup(showFooter, userName, fromAuthor, identicon, textParam, nickName);
|
||||||
|
}
|
||||||
|
onBlockContactActionTriggered: {
|
||||||
|
blockContactConfirmationDialog.contactName = name
|
||||||
|
blockContactConfirmationDialog.contactAddress = address
|
||||||
|
blockContactConfirmationDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: Item {
|
||||||
|
width: parent.width
|
||||||
|
height: children[0].height
|
||||||
|
|
||||||
|
BlockContactConfirmationDialog {
|
||||||
|
id: blockContactConfirmationDialog
|
||||||
|
onBlockButtonClicked: {
|
||||||
|
profileModel.contacts.blockContact(blockContactConfirmationDialog.contactAddress)
|
||||||
|
blockContactConfirmationDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmationDialog {
|
||||||
|
id: declineAllDialog
|
||||||
|
title: qsTr("Decline all contacts")
|
||||||
|
confirmationText: qsTr("Are you sure you want to decline all these contact requests")
|
||||||
|
onConfirmButtonClicked: {
|
||||||
|
const pubkeys = []
|
||||||
|
for (let i = 0; i < contactList.count; i++) {
|
||||||
|
pubkeys.push(contactList.itemAtIndex(i).address)
|
||||||
|
}
|
||||||
|
profileModel.contacts.rejectContactRequests(JSON.stringify(pubkeys))
|
||||||
|
declineAllDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmationDialog {
|
||||||
|
id: acceptAllDialog
|
||||||
|
title: qsTr("Accept all contacts")
|
||||||
|
confirmationText: qsTr("Are you sure you want to accept all these contact requests")
|
||||||
|
onConfirmButtonClicked: {
|
||||||
|
const pubkeys = []
|
||||||
|
for (let i = 0; i < contactList.count; i++) {
|
||||||
|
pubkeys.push(contactList.itemAtIndex(i).address)
|
||||||
|
}
|
||||||
|
profileModel.contacts.acceptContactRequests(JSON.stringify(pubkeys))
|
||||||
|
acceptAllDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusButton {
|
||||||
|
id: blockBtn
|
||||||
|
anchors.right: addToContactsButton.left
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
type: "warn"
|
||||||
|
text: qsTr("Decline all")
|
||||||
|
onClicked: declineAllDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusButton {
|
||||||
|
id: addToContactsButton
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: qsTr("Accept all")
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
onClicked: acceptAllDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ ListView {
|
||||||
// TODO: Make ConfirmationDialog a dynamic component on a future refactor
|
// TODO: Make ConfirmationDialog a dynamic component on a future refactor
|
||||||
ConfirmationDialog {
|
ConfirmationDialog {
|
||||||
id: removeContactConfirmationDialog
|
id: removeContactConfirmationDialog
|
||||||
title: qsTrId("remove-contact")
|
title: qsTr("Remove contact")
|
||||||
//% "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: {
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Layouts 1.13
|
||||||
|
import "../../../../../imports"
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../shared/status"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property string name
|
||||||
|
property string address
|
||||||
|
property string identicon
|
||||||
|
property string localNickname
|
||||||
|
property var profileClick: function() {}
|
||||||
|
signal blockContactActionTriggered(name: string, address: string)
|
||||||
|
property bool isHovered: false
|
||||||
|
id: container
|
||||||
|
|
||||||
|
height: visible ? 64 : 0
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: parent.left
|
||||||
|
border.width: 0
|
||||||
|
radius: Style.current.radius
|
||||||
|
color: isHovered ? Style.current.backgroundHover : Style.current.transparent
|
||||||
|
|
||||||
|
StatusImageIdenticon {
|
||||||
|
id: accountImage
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: identicon
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: usernameText
|
||||||
|
text: name
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: 17
|
||||||
|
anchors.top: accountImage.top
|
||||||
|
anchors.topMargin: Style.current.smallPadding
|
||||||
|
anchors.left: accountImage.right
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.right: declineBtn.left
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
contactContextMenu.popup()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: container.isHovered = hovered
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: declineBtn
|
||||||
|
icon.name: "close"
|
||||||
|
onClicked: profileModel.contacts.rejectContactRequest(container.address)
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
padding: 6
|
||||||
|
iconColor: Style.current.danger
|
||||||
|
hoveredIconColor: Style.current.danger
|
||||||
|
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.danger, 0.1)
|
||||||
|
anchors.right: acceptBtn.left
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusIconButton {
|
||||||
|
id: acceptBtn
|
||||||
|
icon.name: "check-circle"
|
||||||
|
onClicked: profileModel.contacts.addContact(container.address)
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
padding: 6
|
||||||
|
iconColor: Style.current.success
|
||||||
|
hoveredIconColor: Style.current.success
|
||||||
|
highlightedBackgroundColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
||||||
|
anchors.right: menuButton.left
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusContextMenuButton {
|
||||||
|
property int iconSize: 14
|
||||||
|
id: menuButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
contactContextMenu.popup()
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenu {
|
||||||
|
id: contactContextMenu
|
||||||
|
hasArrow: false
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../../img/profileActive.svg"
|
||||||
|
icon.width: menuButton.iconSize
|
||||||
|
icon.height: menuButton.iconSize
|
||||||
|
//% "View Profile"
|
||||||
|
text: qsTrId("view-profile")
|
||||||
|
onTriggered: profileClick(true, name, address, identicon, "", localNickname)
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
Separator {}
|
||||||
|
Action {
|
||||||
|
icon.source: "../../../../img/block-icon.svg"
|
||||||
|
icon.width: menuButton.iconSize
|
||||||
|
icon.height: menuButton.iconSize
|
||||||
|
icon.color: Style.current.danger
|
||||||
|
text: qsTr("Decline and block")
|
||||||
|
onTriggered: container.blockContactActionTriggered(name, address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
|
@ -96,10 +96,13 @@ DISTFILES += \
|
||||||
app/AppLayouts/Browser/FavoritesBar.qml \
|
app/AppLayouts/Browser/FavoritesBar.qml \
|
||||||
app/AppLayouts/Browser/FavoritesList.qml \
|
app/AppLayouts/Browser/FavoritesList.qml \
|
||||||
app/AppLayouts/Browser/components/BookmarkButton.qml \
|
app/AppLayouts/Browser/components/BookmarkButton.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/AddToContactBanner.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandsPopup.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatRequestMessage.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/InputArea.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/RequestModal.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/RequestModal.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml \
|
app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/CompactMessage.qml \
|
app/AppLayouts/Chat/ChatColumn/CompactMessage.qml \
|
||||||
|
@ -156,6 +159,7 @@ DISTFILES += \
|
||||||
app/AppLayouts/Chat/components/CommunitiesPopup.qml \
|
app/AppLayouts/Chat/components/CommunitiesPopup.qml \
|
||||||
app/AppLayouts/Chat/components/CommunityDetailPopup.qml \
|
app/AppLayouts/Chat/components/CommunityDetailPopup.qml \
|
||||||
app/AppLayouts/Chat/components/ContactList.qml \
|
app/AppLayouts/Chat/components/ContactList.qml \
|
||||||
|
app/AppLayouts/Chat/components/ContactRequestsPopup.qml \
|
||||||
app/AppLayouts/Chat/components/CreateCommunityPopup.qml \
|
app/AppLayouts/Chat/components/CreateCommunityPopup.qml \
|
||||||
app/AppLayouts/Chat/components/EmojiCategoryButton.qml \
|
app/AppLayouts/Chat/components/EmojiCategoryButton.qml \
|
||||||
app/AppLayouts/Chat/components/EmojiPopup.qml \
|
app/AppLayouts/Chat/components/EmojiPopup.qml \
|
||||||
|
@ -175,6 +179,7 @@ DISTFILES += \
|
||||||
app/AppLayouts/Profile/LeftTab/components/MenuButton.qml \
|
app/AppLayouts/Profile/LeftTab/components/MenuButton.qml \
|
||||||
app/AppLayouts/Chat/data/EmojiReactions.qml \
|
app/AppLayouts/Chat/data/EmojiReactions.qml \
|
||||||
app/AppLayouts/Profile/Sections/AppearanceContainer.qml \
|
app/AppLayouts/Profile/Sections/AppearanceContainer.qml \
|
||||||
|
app/AppLayouts/Profile/Sections/Contacts/ContactRequest.qml \
|
||||||
app/AppLayouts/Profile/Sections/NetworksModal.qml \
|
app/AppLayouts/Profile/Sections/NetworksModal.qml \
|
||||||
app/AppLayouts/Profile/Sections/BackupSeedModal.qml \
|
app/AppLayouts/Profile/Sections/BackupSeedModal.qml \
|
||||||
app/AppLayouts/Profile/Sections/BrowserContainer.qml \
|
app/AppLayouts/Profile/Sections/BrowserContainer.qml \
|
||||||
|
|
|
@ -119,19 +119,22 @@ Item {
|
||||||
text: {
|
text: {
|
||||||
switch(root.realChatType){
|
switch(root.realChatType){
|
||||||
//% "Public chat"
|
//% "Public chat"
|
||||||
case Constants.chatTypePublic: return qsTrId("public-chat")
|
case Constants.chatTypePublic: return qsTrId("public-chat")
|
||||||
case Constants.chatTypeOneToOne: return (profileModel.contacts.isAdded(root.chatId) ?
|
case Constants.chatTypeOneToOne: return (profileModel.contacts.isAdded(root.chatId) ?
|
||||||
//% "Contact"
|
profileModel.contacts.contactRequestReceived(root.chatId) ?
|
||||||
qsTrId("chat-is-a-contact") :
|
//% "Contact"
|
||||||
//% "Not a contact"
|
qsTrId("chat-is-a-contact") :
|
||||||
qsTrId("chat-is-not-a-contact"))
|
qsTr("Contact request pending") :
|
||||||
case Constants.chatTypePrivateGroupChat:
|
|
||||||
let cnt = chatsModel.activeChannel.members.rowCount();
|
//% "Not a contact"
|
||||||
//% "%1 members"
|
qsTrId("chat-is-not-a-contact"))
|
||||||
if(cnt > 1) return qsTrId("%1-members").arg(cnt);
|
case Constants.chatTypePrivateGroupChat:
|
||||||
//% "1 member"
|
let cnt = chatsModel.activeChannel.members.rowCount();
|
||||||
return qsTrId("1-member");
|
//% "%1 members"
|
||||||
default: return "...";
|
if(cnt > 1) return qsTrId("%1-members").arg(cnt);
|
||||||
|
//% "1 member"
|
||||||
|
return qsTrId("1-member");
|
||||||
|
default: return "...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
|
|
Loading…
Reference in New Issue