mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-23 03:58:49 +00:00
ContactView: indpendent lists per tab
This commit is contained in:
parent
3281e841db
commit
52c3d1bcc9
@ -1,23 +1,16 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
|
|
||||||
import Models 1.0
|
import Models 1.0
|
||||||
import Storybook 1.0
|
import Storybook 1.0
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import shared.stores 1.0 as SharedStores
|
import shared.stores 1.0 as SharedStores
|
||||||
import AppLayouts.Profile.views 1.0
|
import AppLayouts.Profile.views 1.0
|
||||||
import AppLayouts.Profile.stores 1.0
|
import AppLayouts.Profile.stores 1.0
|
||||||
import mainui.adaptors 1.0
|
import mainui.adaptors 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
|
||||||
|
|
||||||
ContactsView {
|
ContactsView {
|
||||||
sectionTitle: "Contacts"
|
sectionTitle: "Contacts"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@ -29,13 +22,20 @@ Item {
|
|||||||
function joinPrivateChat(pubKey) {}
|
function joinPrivateChat(pubKey) {}
|
||||||
function acceptContactRequest(pubKey, contactRequestId) {}
|
function acceptContactRequest(pubKey, contactRequestId) {}
|
||||||
function dismissContactRequest(pubKey, contactRequestId) {}
|
function dismissContactRequest(pubKey, contactRequestId) {}
|
||||||
|
|
||||||
|
function resolveENS(value) {}
|
||||||
|
|
||||||
|
signal resolvedENS(string resolvedPubKey, string resolvedAddress,
|
||||||
|
string uuid)
|
||||||
}
|
}
|
||||||
utilsStore: SharedStores.UtilsStore {
|
utilsStore: SharedStores.UtilsStore {
|
||||||
function getEmojiHash(publicKey) {
|
function getEmojiHash(publicKey) {
|
||||||
if (publicKey === "")
|
if (publicKey === "")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
return JSON.stringify(["👨🏻🍼", "🏃🏿♂️", "🌇", "🤶🏿", "🏮","🤷🏻♂️", "🤦🏻", "📣", "🤎", "👷🏽", "😺", "🥞", "🔃", "🧝🏽♂️"])
|
return JSON.stringify(
|
||||||
|
["👨🏻🍼", "🏃🏿♂️", "🌇", "🤶🏿", "🏮","🤷🏻♂️", "🤦🏻",
|
||||||
|
"📣", "🤎", "👷🏽", "😺", "🥞", "🔃", "🧝🏽♂️"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,20 +47,8 @@ Item {
|
|||||||
|
|
||||||
ContactsModelAdaptor {
|
ContactsModelAdaptor {
|
||||||
id: adaptor
|
id: adaptor
|
||||||
allContacts: SortFilterProxyModel {
|
|
||||||
sourceModel: UsersModel {}
|
|
||||||
proxyRoles: [
|
|
||||||
FastExpressionRole {
|
|
||||||
function displayNameProxy(localNickname, ensName, displayName, aliasName) {
|
|
||||||
return ProfileUtils.displayName(localNickname, ensName, displayName, aliasName)
|
|
||||||
}
|
|
||||||
|
|
||||||
name: "preferredDisplayName"
|
allContacts: UsersModel {}
|
||||||
expectedRoles: ["localNickname", "displayName", "ensName", "alias"]
|
|
||||||
expression: displayNameProxy(model.localNickname, model.ensName, model.displayName, model.alias)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ ListModel {
|
|||||||
alias: "",
|
alias: "",
|
||||||
localNickname: "",
|
localNickname: "",
|
||||||
ensName: "",
|
ensName: "",
|
||||||
|
preferredDisplayName: "Mike has a very long name that should elide " +
|
||||||
|
"eventually and result in a tooltip displayed instead",
|
||||||
icon: ModelsData.icons.cryptPunks,
|
icon: ModelsData.icons.cryptPunks,
|
||||||
colorId: 7,
|
colorId: 7,
|
||||||
isEnsVerified: false,
|
isEnsVerified: false,
|
||||||
@ -43,6 +45,7 @@ ListModel {
|
|||||||
alias: "",
|
alias: "",
|
||||||
localNickname: "",
|
localNickname: "",
|
||||||
ensName: "",
|
ensName: "",
|
||||||
|
preferredDisplayName: "Jane",
|
||||||
icon: "",
|
icon: "",
|
||||||
colorId: 9,
|
colorId: 9,
|
||||||
isEnsVerified: false,
|
isEnsVerified: false,
|
||||||
@ -67,6 +70,7 @@ ListModel {
|
|||||||
alias: "",
|
alias: "",
|
||||||
localNickname: "Johnny Johny",
|
localNickname: "Johnny Johny",
|
||||||
ensName: "",
|
ensName: "",
|
||||||
|
preferredDisplayName: "Johnny Johny",
|
||||||
icon: ModelsData.icons.dragonereum,
|
icon: ModelsData.icons.dragonereum,
|
||||||
colorId: 4,
|
colorId: 4,
|
||||||
isEnsVerified: false,
|
isEnsVerified: false,
|
||||||
@ -91,6 +95,7 @@ ListModel {
|
|||||||
alias: "meth",
|
alias: "meth",
|
||||||
localNickname: "",
|
localNickname: "",
|
||||||
ensName: "",
|
ensName: "",
|
||||||
|
preferredDisplayName: "Maria",
|
||||||
icon: "",
|
icon: "",
|
||||||
colorId: 5,
|
colorId: 5,
|
||||||
isEnsVerified: false,
|
isEnsVerified: false,
|
||||||
@ -112,6 +117,7 @@ ListModel {
|
|||||||
alias: "Richard The Lionheart",
|
alias: "Richard The Lionheart",
|
||||||
localNickname: "",
|
localNickname: "",
|
||||||
ensName: "richard-the-lionheart.eth",
|
ensName: "richard-the-lionheart.eth",
|
||||||
|
preferredDisplayName: "richard-the-lionheart.eth",
|
||||||
icon: "",
|
icon: "",
|
||||||
colorId: 3,
|
colorId: 3,
|
||||||
isEnsVerified: true,
|
isEnsVerified: true,
|
||||||
@ -132,6 +138,7 @@ ListModel {
|
|||||||
alias: "",
|
alias: "",
|
||||||
localNickname: "",
|
localNickname: "",
|
||||||
ensName: "8⃣6⃣.sth.eth",
|
ensName: "8⃣6⃣.sth.eth",
|
||||||
|
preferredDisplayName: "8⃣6⃣.sth.eth",
|
||||||
icon: "",
|
icon: "",
|
||||||
colorId: 7,
|
colorId: 7,
|
||||||
isEnsVerified: true,
|
isEnsVerified: true,
|
||||||
|
@ -58,18 +58,14 @@ Item {
|
|||||||
model: SortFilterProxyModel {
|
model: SortFilterProxyModel {
|
||||||
sourceModel: root.model
|
sourceModel: root.model
|
||||||
|
|
||||||
sorters: [
|
sorters: StringSorter {
|
||||||
StringSorter {
|
roleName: "preferredDisplayName"
|
||||||
roleName: "preferredDisplayName"
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
caseSensitivity: Qt.CaseInsensitive
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
filters: [
|
filters: UserSearchFilter {
|
||||||
UserSearchFilterContainer {
|
searchString: root.searchString
|
||||||
searchString: root.searchString
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
@ -2,70 +2,44 @@ import QtQuick 2.15
|
|||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
|
||||||
import shared 1.0
|
import shared.views 1.0
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
StatusListView {
|
StatusListView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property var contactsModel
|
property bool inviteButtonVisible
|
||||||
property int panelUsage: Constants.contactsPanelUsage.unknownPosition
|
|
||||||
property string searchString: ""
|
|
||||||
|
|
||||||
signal openContactContextMenu(string publicKey)
|
signal profilePopupRequested(string publicKey)
|
||||||
signal sendMessageActionTriggered(string publicKey)
|
signal contextMenuRequested(string publicKey)
|
||||||
signal contactRequestAccepted(string publicKey)
|
|
||||||
signal contactRequestRejected(string publicKey)
|
signal sendMessageRequested(string publicKey)
|
||||||
|
signal acceptContactRequested(string publicKey)
|
||||||
|
signal rejectContactRequested(string publicKey)
|
||||||
|
|
||||||
objectName: "ContactListPanel_ListView"
|
objectName: "ContactListPanel_ListView"
|
||||||
|
|
||||||
model: SortFilterProxyModel {
|
header: NoFriendsRectangle {
|
||||||
id: filteredModel
|
width: ListView.view.width
|
||||||
|
visible: ListView.view.count === 0
|
||||||
sourceModel: root.contactsModel
|
inviteButtonVisible: root.inviteButtonVisible
|
||||||
|
|
||||||
filters: [
|
|
||||||
UserSearchFilterContainer {
|
|
||||||
searchString: root.searchString
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
sorters: [
|
|
||||||
FilterSorter { // Trusted contacts first
|
|
||||||
enabled: root.panelUsage === Constants.contactsPanelUsage.mutualContacts
|
|
||||||
ValueFilter { roleName: "isVerified"; value: true }
|
|
||||||
},
|
|
||||||
FilterSorter { // Received CRs first
|
|
||||||
id: pendingFilter
|
|
||||||
readonly property int received: Constants.ContactRequestState.Received
|
|
||||||
enabled: root.panelUsage === Constants.contactsPanelUsage.pendingContacts
|
|
||||||
ValueFilter { roleName: "contactRequest"; value: pendingFilter.received }
|
|
||||||
},
|
|
||||||
StringSorter {
|
|
||||||
roleName: "preferredDisplayName"
|
|
||||||
caseSensitivity: Qt.CaseInsensitive
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: ContactPanel {
|
delegate: ContactPanel {
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
|
|
||||||
showSendMessageButton: model.isContact && !model.isBlocked
|
showSendMessageButton: model.isContact && !model.isBlocked
|
||||||
showRejectContactRequestButton: root.panelUsage === Constants.contactsPanelUsage.pendingContacts &&
|
showRejectContactRequestButton:
|
||||||
model.contactRequest === Constants.ContactRequestState.Received
|
model.contactRequest === Constants.ContactRequestState.Received
|
||||||
showAcceptContactRequestButton: showRejectContactRequestButton
|
showAcceptContactRequestButton: showRejectContactRequestButton
|
||||||
|
|
||||||
contactText: root.panelUsage === Constants.contactsPanelUsage.pendingContacts &&
|
contactText: model.contactRequest === Constants.ContactRequestState.Sent
|
||||||
model.contactRequest === Constants.ContactRequestState.Sent ? qsTr("Contact Request Sent")
|
? qsTr("Contact Request Sent") : ""
|
||||||
: ""
|
|
||||||
|
|
||||||
onClicked: Global.openProfilePopup(model.pubKey)
|
onClicked: root.profilePopupRequested(model.pubKey)
|
||||||
onContextMenuRequested: root.openContactContextMenu(model.pubKey)
|
onContextMenuRequested: root.contextMenuRequested(model.pubKey)
|
||||||
onSendMessageRequested: root.sendMessageActionTriggered(model.pubKey)
|
onSendMessageRequested: root.sendMessageRequested(model.pubKey)
|
||||||
onAcceptContactRequested: root.contactRequestAccepted(model.pubKey)
|
onAcceptContactRequested: root.acceptContactRequested(model.pubKey)
|
||||||
onRejectRequestRequested: root.contactRequestRejected(model.pubKey)
|
onRejectRequestRequested: root.rejectContactRequested(model.pubKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import AppLayouts.Profile.panels 1.0
|
||||||
|
import AppLayouts.Profile.popups 1.0
|
||||||
|
import AppLayouts.Profile.stores 1.0
|
||||||
|
|
||||||
|
import shared 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
import shared.panels 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import shared.stores 1.0 as SharedStores
|
import shared.stores 1.0 as SharedStores
|
||||||
import shared.views 1.0
|
import shared.views 1.0
|
||||||
import shared.views.chat 1.0
|
import shared.views.chat 1.0
|
||||||
|
|
||||||
import AppLayouts.Profile.stores 1.0
|
import utils 1.0
|
||||||
import AppLayouts.Profile.panels 1.0
|
|
||||||
import AppLayouts.Profile.popups 1.0
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
SettingsContentBase {
|
SettingsContentBase {
|
||||||
id: root
|
id: root
|
||||||
@ -37,6 +36,7 @@ SettingsContentBase {
|
|||||||
|
|
||||||
titleRowComponentLoader.sourceComponent: StatusButton {
|
titleRowComponentLoader.sourceComponent: StatusButton {
|
||||||
objectName: "ContactsView_ContactRequest_Button"
|
objectName: "ContactsView_ContactRequest_Button"
|
||||||
|
|
||||||
text: qsTr("Send contact request to chat key")
|
text: qsTr("Send contact request to chat key")
|
||||||
onClicked: sendContactRequestComponent.createObject(root).open()
|
onClicked: sendContactRequestComponent.createObject(root).open()
|
||||||
}
|
}
|
||||||
@ -70,128 +70,134 @@ SettingsContentBase {
|
|||||||
|
|
||||||
StatusTabBar {
|
StatusTabBar {
|
||||||
id: contactsTabBar
|
id: contactsTabBar
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
StatusTabButton {
|
StatusTabButton {
|
||||||
readonly property int panelUsage: Constants.contactsPanelUsage.mutualContacts
|
objectName: "ContactsView_Contacts_Button"
|
||||||
|
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
text: qsTr("Contacts")
|
text: qsTr("Contacts")
|
||||||
}
|
}
|
||||||
StatusTabButton {
|
StatusTabButton {
|
||||||
readonly property int panelUsage: Constants.contactsPanelUsage.pendingContacts
|
|
||||||
|
|
||||||
objectName: "ContactsView_PendingRequest_Button"
|
objectName: "ContactsView_PendingRequest_Button"
|
||||||
|
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
enabled: !!root.pendingContactsModel && !root.pendingContactsModel.ModelCount.empty
|
enabled: !root.pendingContactsModel.ModelCount.empty
|
||||||
text: qsTr("Pending Requests")
|
text: qsTr("Pending Requests")
|
||||||
badge.value: root.pendingReceivedContactsCount
|
badge.value: root.pendingReceivedContactsCount
|
||||||
}
|
}
|
||||||
StatusTabButton {
|
StatusTabButton {
|
||||||
readonly property int panelUsage: Constants.contactsPanelUsage.blockedContacts
|
|
||||||
|
|
||||||
objectName: "ContactsView_Blocked_Button"
|
objectName: "ContactsView_Blocked_Button"
|
||||||
|
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
enabled: !!root.blockedContactsModel && !root.blockedContactsModel.ModelCount.empty
|
enabled: !root.blockedContactsModel.ModelCount.empty
|
||||||
text: qsTr("Blocked")
|
text: qsTr("Blocked")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: searchBox
|
id: searchBox
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
placeholderText: qsTr("Search by name or chat key")
|
placeholderText: qsTr("Search by name or chat key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactsListPanel {
|
StackLayout {
|
||||||
id: contactsListPanel
|
|
||||||
width: root.contentWidth
|
width: root.contentWidth
|
||||||
height: root.availableHeight
|
height: root.availableHeight
|
||||||
|
|
||||||
panelUsage: contactsTabBar.currentItem.panelUsage
|
currentIndex: contactsTabBar.currentIndex
|
||||||
contactsModel: {
|
|
||||||
switch (panelUsage) {
|
ContactsList {
|
||||||
case Constants.contactsPanelUsage.pendingContacts:
|
inviteButtonVisible: searchBox.text === ""
|
||||||
return root.pendingContactsModel
|
|
||||||
case Constants.contactsPanelUsage.blockedContacts:
|
model: SortFilterProxyModel {
|
||||||
return root.blockedContactsModel
|
sourceModel: root.mutualContactsModel
|
||||||
case Constants.contactsPanelUsage.mutualContacts:
|
|
||||||
default:
|
filters: UserSearchFilter {
|
||||||
return root.mutualContactsModel
|
searchString: searchBox.text
|
||||||
|
}
|
||||||
|
|
||||||
|
sorters: [
|
||||||
|
RoleSorter {
|
||||||
|
roleName: "isVerified"
|
||||||
|
sortOrder: Qt.DescendingOrder
|
||||||
|
},
|
||||||
|
StringSorter {
|
||||||
|
roleName: "preferredDisplayName"
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
section.property: {
|
section.property: "isVerified"
|
||||||
switch (contactsListPanel.panelUsage) {
|
section.delegate: SectionComponent {
|
||||||
case Constants.contactsPanelUsage.pendingContacts:
|
text: section === "true" ? qsTr("Trusted Contacts")
|
||||||
return "contactRequest"
|
: qsTr("Contacts")
|
||||||
case Constants.contactsPanelUsage.mutualContacts:
|
|
||||||
return "isVerified"
|
|
||||||
case Constants.contactsPanelUsage.blockedContacts:
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section.labelPositioning: ViewSection.InlineLabels |
|
||||||
|
ViewSection.CurrentLabelAtStart
|
||||||
}
|
}
|
||||||
section.delegate: SectionComponent {
|
|
||||||
text: {
|
ContactsList {
|
||||||
switch (contactsListPanel.panelUsage) {
|
model: SortFilterProxyModel {
|
||||||
case Constants.contactsPanelUsage.pendingContacts:
|
sourceModel: root.pendingContactsModel
|
||||||
return section === `${Constants.ContactRequestState.Received}` ? qsTr("Received") : qsTr("Sent")
|
|
||||||
case Constants.contactsPanelUsage.mutualContacts:
|
filters: UserSearchFilter {
|
||||||
return section === "true" ? qsTr("Trusted Contacts") : qsTr("Contacts")
|
searchString: searchBox.text
|
||||||
case Constants.contactsPanelUsage.blockedContacts:
|
}
|
||||||
default:
|
|
||||||
return ""
|
sorters: [
|
||||||
|
FilterSorter { // Received CRs first
|
||||||
|
ValueFilter {
|
||||||
|
roleName: "contactRequest"
|
||||||
|
value: Constants.ContactRequestState.Received
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
StringSorter {
|
||||||
|
roleName: "preferredDisplayName"
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
section.property: "contactRequest"
|
||||||
|
section.delegate: SectionComponent {
|
||||||
|
text: section === `${Constants.ContactRequestState.Received}`
|
||||||
|
? qsTr("Received") : qsTr("Sent")
|
||||||
|
}
|
||||||
|
|
||||||
|
section.labelPositioning: ViewSection.InlineLabels |
|
||||||
|
ViewSection.CurrentLabelAtStart
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactsList {
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: root.blockedContactsModel
|
||||||
|
|
||||||
|
filters: UserSearchFilter {
|
||||||
|
searchString: searchBox.text
|
||||||
|
}
|
||||||
|
|
||||||
|
sorters: StringSorter {
|
||||||
|
roleName: "preferredDisplayName"
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
|
}
|
||||||
|
|
||||||
header: NoFriendsRectangle {
|
component ContactsList: ContactsListPanel {
|
||||||
width: ListView.view.width
|
onProfilePopupRequested: Global.openProfilePopup(publicKey)
|
||||||
visible: ListView.view.count === 0
|
onContextMenuRequested: root.openContextMenu(model, publicKey)
|
||||||
inviteButtonVisible: searchBox.text === ""
|
|
||||||
}
|
|
||||||
|
|
||||||
searchString: searchBox.text
|
onSendMessageRequested: root.contactsStore.joinPrivateChat(publicKey)
|
||||||
onOpenContactContextMenu: root.openContextMenu(contactsModel, publicKey)
|
onAcceptContactRequested: root.contactsStore.acceptContactRequest(publicKey, "")
|
||||||
onSendMessageActionTriggered: root.contactsStore.joinPrivateChat(publicKey)
|
onRejectContactRequested: root.contactsStore.dismissContactRequest(publicKey, "")
|
||||||
onContactRequestAccepted: root.contactsStore.acceptContactRequest(publicKey, "")
|
|
||||||
onContactRequestRejected: root.contactsStore.dismissContactRequest(publicKey, "")
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: sendContactRequestComponent
|
|
||||||
SendContactRequestModal {
|
|
||||||
contactsStore: root.contactsStore
|
|
||||||
onClosed: destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: contactContextMenuComponent
|
|
||||||
ProfileContextMenu {
|
|
||||||
id: contactContextMenu
|
|
||||||
|
|
||||||
property string pubKey
|
|
||||||
|
|
||||||
onOpenProfileClicked: Global.openProfilePopup(contactContextMenu.pubKey, null, null)
|
|
||||||
onReviewContactRequest: Global.openReviewContactRequestPopup(contactContextMenu.pubKey, null)
|
|
||||||
onSendContactRequest: Global.openContactRequestPopup(contactContextMenu.pubKey, null)
|
|
||||||
onEditNickname: Global.openNicknamePopupRequested(contactContextMenu.pubKey, null)
|
|
||||||
onUnblockContact: Global.unblockContactRequested(contactContextMenu.pubKey)
|
|
||||||
onMarkAsUntrusted: Global.markAsUntrustedRequested(contactContextMenu.pubKey)
|
|
||||||
onRemoveContact: Global.removeContactRequested(contactContextMenu.pubKey)
|
|
||||||
onBlockContact: Global.blockContactRequested(contactContextMenu.pubKey)
|
|
||||||
|
|
||||||
onCreateOneToOneChat: root.contactsStore.joinPrivateChat(contactContextMenu.pubKey)
|
|
||||||
onRemoveTrustStatus: root.contactsStore.removeTrustStatus(contactContextMenu.pubKey)
|
|
||||||
onRemoveNickname: root.contactsStore.changeContactNickname(contactContextMenu.pubKey, "",
|
|
||||||
contactContextMenu.displayName, true)
|
|
||||||
onMarkAsTrusted: Global.openMarkAsIDVerifiedPopup(contactContextMenu.pubKey, null)
|
|
||||||
onRemoveTrustedMark: Global.openRemoveIDVerificationDialog(contactContextMenu.pubKey, null)
|
|
||||||
onClosed: destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component SectionComponent: Rectangle {
|
component SectionComponent: Rectangle {
|
||||||
@ -215,4 +221,41 @@ SettingsContentBase {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: sendContactRequestComponent
|
||||||
|
|
||||||
|
SendContactRequestModal {
|
||||||
|
contactsStore: root.contactsStore
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: contactContextMenuComponent
|
||||||
|
|
||||||
|
ProfileContextMenu {
|
||||||
|
id: menu
|
||||||
|
|
||||||
|
property string pubKey
|
||||||
|
|
||||||
|
onOpenProfileClicked: Global.openProfilePopup(menu.pubKey, null, null)
|
||||||
|
onReviewContactRequest: Global.openReviewContactRequestPopup(menu.pubKey, null)
|
||||||
|
onSendContactRequest: Global.openContactRequestPopup(menu.pubKey, null)
|
||||||
|
onEditNickname: Global.openNicknamePopupRequested(menu.pubKey, null)
|
||||||
|
onUnblockContact: Global.unblockContactRequested(menu.pubKey)
|
||||||
|
onMarkAsUntrusted: Global.markAsUntrustedRequested(menu.pubKey)
|
||||||
|
onRemoveContact: Global.removeContactRequested(menu.pubKey)
|
||||||
|
onBlockContact: Global.blockContactRequested(menu.pubKey)
|
||||||
|
|
||||||
|
onCreateOneToOneChat: root.contactsStore.joinPrivateChat(menu.pubKey)
|
||||||
|
onRemoveTrustStatus: root.contactsStore.removeTrustStatus(menu.pubKey)
|
||||||
|
onRemoveNickname: root.contactsStore.changeContactNickname(menu.pubKey, "",
|
||||||
|
menu.displayName, true)
|
||||||
|
onMarkAsTrusted: Global.openMarkAsIDVerifiedPopup(menu.pubKey, null)
|
||||||
|
onRemoveTrustedMark: Global.openRemoveIDVerificationDialog(menu.pubKey, null)
|
||||||
|
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ FocusScope {
|
|||||||
property alias titleRowComponentLoader: loader
|
property alias titleRowComponentLoader: loader
|
||||||
property list<Item> headerComponents
|
property list<Item> headerComponents
|
||||||
property alias bottomHeaderComponents: secondHeaderRow.contentItem
|
property alias bottomHeaderComponents: secondHeaderRow.contentItem
|
||||||
default property alias content: contentWrapper.children
|
default property alias content: contentWrapper.data
|
||||||
property alias titleLayout: titleLayout
|
property alias titleLayout: titleLayout
|
||||||
|
|
||||||
property bool stickTitleRowComponentLoader: false
|
property bool stickTitleRowComponentLoader: false
|
||||||
|
28
ui/imports/shared/UserSearchFilter.qml
Normal file
28
ui/imports/shared/UserSearchFilter.qml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
AnyOf {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string searchString
|
||||||
|
|
||||||
|
enabled: root.searchString !== ""
|
||||||
|
|
||||||
|
// substring search for either nickname or the other primary/secondary display name
|
||||||
|
SearchFilter {
|
||||||
|
roleName: "localNickname"
|
||||||
|
searchPhrase: root.searchString
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchFilter {
|
||||||
|
roleName: "preferredDisplayName"
|
||||||
|
searchPhrase: root.searchString
|
||||||
|
}
|
||||||
|
|
||||||
|
// exact search for the full key
|
||||||
|
ValueFilter {
|
||||||
|
roleName: "compressedPubKey"
|
||||||
|
value: root.searchString
|
||||||
|
}
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
import StatusQ 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
AnyOf {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string searchString
|
|
||||||
|
|
||||||
function searchPredicate(ensName, displayName, aliasName) {
|
|
||||||
const lowerCaseSearchString = root.searchString.toLowerCase()
|
|
||||||
const secondaryName = ProfileUtils.displayName("", ensName, displayName, aliasName)
|
|
||||||
|
|
||||||
return secondaryName.toLowerCase().includes(lowerCaseSearchString)
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled: root.searchString !== ""
|
|
||||||
|
|
||||||
// substring search for either nickname or the other primary/secondary display name
|
|
||||||
SearchFilter {
|
|
||||||
roleName: "localNickname"
|
|
||||||
searchPhrase: root.searchString
|
|
||||||
}
|
|
||||||
FastExpressionFilter {
|
|
||||||
expression: {
|
|
||||||
root.searchString
|
|
||||||
return root.searchPredicate(model.ensName, model.displayName, model.alias)
|
|
||||||
}
|
|
||||||
expectedRoles: ["ensName", "displayName", "alias"]
|
|
||||||
}
|
|
||||||
// exact search for the full key
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "compressedPubKey"
|
|
||||||
value: root.searchString
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,4 +3,4 @@ module shared
|
|||||||
DelegateModelGeneralized 1.0 DelegateModelGeneralized.qml
|
DelegateModelGeneralized 1.0 DelegateModelGeneralized.qml
|
||||||
LoadingAnimation 1.0 LoadingAnimation.qml
|
LoadingAnimation 1.0 LoadingAnimation.qml
|
||||||
MacTrafficLights 1.0 MacTrafficLights.qml
|
MacTrafficLights 1.0 MacTrafficLights.qml
|
||||||
UserSearchFilterContainer 1.0 UserSearchFilterContainer.qml
|
UserSearchFilter 1.0 UserSearchFilter.qml
|
||||||
|
Loading…
x
Reference in New Issue
Block a user