Skip to content

Commit

Permalink
refactor ProfileContextMenu to make it a functional component
Browse files Browse the repository at this point in the history
refactor ProfileContextMenu to make it a functional component

This refactor ProfileContextMenu to make it a functional component by:

refactored out direct calls to backend, and passing backend data structures and moved this logic to the callers, also refactored common calls between the callers
common types of context menus have been extracted to their sub components which removes a lot of logic too and makes the behaviour very clear
user verification workflow (which was already disabled) has been removed

refactor: use signals and call singletons on the parent instead

remove unused code for now from profile context menu

refactor profile context menu into two components; add property to storybook

extract blocked profile context menu and self profile context menu

use profileType instead of individual bools

refactor to pass trustStatus as an argument

make contact type a parameter

remove unnecessary method from RegularProfileContextMenu

add ensVerified property to ProfileContextMenu components

add onlineStatus property to ProfileContextMenu components

move ProfileContextMenu storybook controls to the right sidebar

move contactDetails logic up from the view

add local nickname property to ProfileContextMenu components

fix issue with missing signal; fix logs in storybook

use constant for profileType instead of string

refactor common code into a single method

refactor getProfileContext

remove references to contactDetails which are not longer needed

remove unnecessary comments

fix bridged constant

refactor into a single ProfileContextMenu component

refactor into a single ProfileContextMenu component

refactor into a single ProfileContextMenu component

simplify imports

remove unused store field

move methods from utils to contacts store

remove onClosed signal

remove unused param
  • Loading branch information
iurimatias committed Sep 17, 2024
1 parent 0c6a602 commit 93f17b2
Show file tree
Hide file tree
Showing 8 changed files with 435 additions and 249 deletions.
195 changes: 181 additions & 14 deletions storybook/pages/MessageContextMenuPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Models 1.0

import utils 1.0
import shared.views.chat 1.0
import shared.status 1.0

SplitView {

Expand Down Expand Up @@ -85,6 +86,46 @@ SplitView {
ProfileContextMenu {
anchors.centerIn: parent
hideDisabledItems: false
profileType: profileTypeSelector.currentValue
trustStatus: trustStatusSelector.currentValue
contactType: contactTypeSelector.currentValue
ensVerified: ensVerifiedCheckBox.checked
onlineStatus: onlineStatusSelector.currentValue
hasLocalNickname: hasLocalNicknameCheckBox.checked

onOpenProfileClicked: (publicKey) => {
logs.logEvent("Open profile clicked for:", publicKey)
}
onCreateOneToOneChat: (communityId, chatId, ensName) => {
logs.logEvent("Create one-to-one chat:", communityId, chatId, ensName)
}
onReviewContactRequest: (publicKey) => {
logs.logEvent("Review contact request:", publicKey)
}
onSendContactRequest: (publicKey) => {
logs.logEvent("Send contact request:", publicKey)
}
onEditNickname: (publicKey) => {
logs.logEvent("Edit nickname:", publicKey)
}
onRemoveNickname: (publicKey, displayName) => {
logs.logEvent("Remove nickname:", publicKey, displayName)
}
onUnblockContact: (publicKey) => {
logs.logEvent("Unblock contact:", publicKey)
}
onMarkAsUntrusted: (publicKey) => {
logs.logEvent("Mark as untrusted:", publicKey)
}
onRemoveTrustStatus: (publicKey) => {
logs.logEvent("Remove trust status:", publicKey)
}
onRemoveContact: (publicKey) => {
logs.logEvent("Remove contact:", publicKey)
}
onBlockContact: (publicKey) => {
logs.logEvent("Block contact:", publicKey)
}
onClosed: {
destroy()
}
Expand All @@ -96,36 +137,162 @@ SplitView {
ProfileContextMenu {
anchors.centerIn: parent
hideDisabledItems: true
profileType: profileTypeSelector.currentValue
trustStatus: trustStatusSelector.currentValue
contactType: contactTypeSelector.currentValue
ensVerified: ensVerifiedCheckBox.checked
onlineStatus: onlineStatusSelector.currentValue
hasLocalNickname: hasLocalNicknameCheckBox.checked

onOpenProfileClicked: (publicKey) => {
logs.logEvent("Open profile clicked for:", publicKey)
}
onCreateOneToOneChat: (communityId, chatId, ensName) => {
logs.logEvent("Create one-to-one chat:", communityId, chatId, ensName)
}
onReviewContactRequest: (publicKey) => {
logs.logEvent("Review contact request:", publicKey)
}
onSendContactRequest: (publicKey) => {
logs.logEvent("Send contact request:", publicKey)
}
onEditNickname: (publicKey) => {
logs.logEvent("Edit nickname:", publicKey)
}
onRemoveNickname: (publicKey, displayName) => {
logs.logEvent("Remove nickname:", publicKey, displayName)
}
onUnblockContact: (publicKey) => {
logs.logEvent("Unblock contact:", publicKey)
}
onMarkAsUntrusted: (publicKey) => {
logs.logEvent("Mark as untrusted:", publicKey)
}
onRemoveTrustStatus: (publicKey) => {
logs.logEvent("Remove trust status:", publicKey)
}
onRemoveContact: (publicKey) => {
logs.logEvent("Remove contact:", publicKey)
}
onBlockContact: (publicKey) => {
logs.logEvent("Block contact:", publicKey)
}

onClosed: {
destroy()
}
}
}
}

LogsAndControlsPanel {
id: logsAndControlsPanel
}

SplitView.minimumHeight: 100
SplitView.preferredHeight: 150
LogsAndControlsPanel {
id: logsAndControlsPanel

logsView.logText: logs.logText
}
}
SplitView.minimumWidth: 150
SplitView.preferredWidth: 250

Pane {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 300
logsView.logText: logs.logText

ScrollView {
anchors.fill: parent
controls: ColumnLayout {
spacing: 16

ComboBox {
id: profileTypeSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Regular", value: Constants.profileType.regular },
{ text: "Self", value: Constants.profileType.self },
{ text: "Blocked", value: Constants.profileType.blocked },
{ text: "Bridged", value: Constants.profileType.bridged }
]
currentIndex: 0
}

ColumnLayout {
spacing: 16
ComboBox {
id: trustStatusSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Unknown", value: Constants.trustStatus.unknown },
{ text: "Trusted", value: Constants.trustStatus.trusted },
{ text: "Untrusted", value: Constants.trustStatus.untrustworthy }
]
currentIndex: 0
}

ComboBox {
id: contactTypeSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Non Contact", value: Constants.contactType.nonContact },
{ text: "Contact", value: Constants.contactType.contact },
{ text: "Contact Request Received", value: Constants.contactType.contactRequestReceived },
{ text: "Contact Request Sent", value: Constants.contactType.contactRequestSent }
]
currentIndex: 0
}

CheckBox {
id: ensVerifiedCheckBox
text: "ENS Verified"
checked: false
}

Label {
Layout.fillWidth: true
text: "ENS Verified: " + (ensVerifiedCheckBox.checked ? "Yes" : "No")
}

Label {
Layout.fillWidth: true
text: "Profile type: " + profileTypeSelector.currentText
}

Label {
Layout.fillWidth: true
text: "Trust status: " + trustStatusSelector.currentText
}

Label {
Layout.fillWidth: true
text: "Contact type: " + contactTypeSelector.currentText
}

ComboBox {
id: onlineStatusSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Unknown", value: Constants.onlineStatus.unknown },
{ text: "Inactive", value: Constants.onlineStatus.inactive },
{ text: "Online", value: Constants.onlineStatus.online }
]
currentIndex: 2 // Default to online
}

Label {
Layout.fillWidth: true
text: "Online status: " + onlineStatusSelector.currentText
}

CheckBox {
id: hasLocalNicknameCheckBox
text: "Has Local Nickname"
checked: false
}

Label {
Layout.fillWidth: true
text: "Has Local Nickname: " + (hasLocalNicknameCheckBox.checked ? "Yes" : "No")
}

}
}

}

// category: Views
44 changes: 38 additions & 6 deletions ui/app/AppLayouts/Chat/panels/UserListPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ Item {
ringSettings.ringSpecModel: model.colorHash
onClicked: {
if (mouse.button === Qt.RightButton) {
const { profileType, trustStatus, contactType, ensVerified, onlineStatus, hasLocalNickname } = root.store.contactsStore.getProfileContext(model.pubKey, userProfile.pubKey)

Global.openMenu(profileContextMenuComponent, this, {
myPublicKey: root.store.myPublicKey(),
profileType, trustStatus, contactType, ensVerified, onlineStatus, hasLocalNickname,
selectedUserPublicKey: model.pubKey,
selectedUserDisplayName: nickName || userName,
selectedUserIcon: model.icon,
Expand Down Expand Up @@ -168,17 +170,47 @@ Item {
id: profileContextMenuComponent

ProfileContextMenu {
store: root.store
margins: 8
onOpenProfileClicked: {
onOpenProfileClicked: (publicKey) => {
Global.openProfilePopup(publicKey, null)
}
onCreateOneToOneChat: {
onCreateOneToOneChat: (communityId, chatId, ensName) => {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.store.chatCommunitySectionModule.createOneToOneChat(communityId, chatId, ensName)
}
onClosed: {
destroy()
onReviewContactRequest: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.openReviewContactRequestPopup(publicKey, contactDetails, null)
}
onSendContactRequest: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.openContactRequestPopup(publicKey, contactDetails, null)
}
onEditNickname: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.openNicknamePopupRequested(publicKey, contactDetails, null)
}
onRemoveNickname: (publicKey, displayName) => {
root.store.contactsStore.changeContactNickname(publicKey, "", displayName, true)
}
onUnblockContact: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.unblockContactRequested(publicKey, contactDetails)
}
onMarkAsUntrusted: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.markAsUntrustedRequested(publicKey, contactDetails)
}
onRemoveTrustStatus: (publicKey) => {
root.store.contactsStore.removeTrustStatus(publicKey)
}
onRemoveContact: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.removeContactRequested(publicKey, contactDetails)
}
onBlockContact: (publicKey) => {
const contactDetails = publicKey === "" ? {} : Utils.getContactDetailsAsJson(publicKey, true, true)
Global.blockContactRequested(publicKey, contactDetails)
}
}
}
Expand Down
17 changes: 8 additions & 9 deletions ui/app/AppLayouts/Communities/panels/MembersTabPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,15 @@ Item {

onClicked: {
if(mouse.button === Qt.RightButton) {
const { profileType, trustStatus, contactType, ensVerified, onlineStatus, hasLocalNickname } = root.rootStore.contactsStore.getProfileContext(model.pubKey, Global.userProfile.pubKey)

Global.openMenu(memberContextMenuComponent, this, {
selectedUserPublicKey: model.pubKey,
selectedUserDisplayName: memberItem.title,
selectedUserIcon: icon.name,
})
profileType, trustStatus, contactType, ensVerified, onlineStatus, hasLocalNickname,
myPublicKey: Global.userProfile.pubKey,
selectedUserPublicKey: model.pubKey,
selectedUserDisplayName: memberItem.title,
selectedUserIcon: icon.name,
})
} else {
Global.openProfilePopup(model.pubKey)
}
Expand All @@ -321,8 +325,6 @@ Item {

ProfileContextMenu {
id: memberContextMenuView
store: root.rootStore
myPublicKey: Global.userProfile.pubKey

onOpenProfileClicked: {
Global.openProfilePopup(publicKey, null)
Expand All @@ -331,9 +333,6 @@ Item {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.rootStore.chatCommunitySectionModule.createOneToOneChat(communityId, chatId, ensName)
}
onClosed: {
destroy()
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions ui/app/AppLayouts/Profile/stores/ContactsStore.qml
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,42 @@ QtObject {
function getLinkToProfile(publicKey) {
return root.contactsModule.shareUserUrlWithData(publicKey)
}

function getProfileContext(publicKey, myPublicKey, isBridgedAccount = false) {
const contactDetails = Utils.getContactDetailsAsJson(publicKey, true, true);
const isBlocked = contactDetails ? contactDetails.isBlocked : false;

const profileType = getProfileType(publicKey, myPublicKey, isBridgedAccount, isBlocked);
const contactType = getContactType(contactDetails ? contactDetails.contactRequestState : Constants.ContactRequestState.None, contactDetails ? contactDetails.isContact : false);
const trustStatus = contactDetails ? contactDetails.trustStatus : Constants.trustStatus.unknown;
const ensVerified = contactDetails ? contactDetails.ensVerified : false;
const onlineStatus = contactDetails ? contactDetails.onlineStatus : Constants.onlineStatus.unknown;
const hasLocalNickname = contactDetails ? !!contactDetails.localNickname : false;

return { profileType, trustStatus, contactType, ensVerified, onlineStatus, hasLocalNickname };
}

function getProfileType(publicKey, myPublicKey, isBridgedAccount, isBlocked) {
if (publicKey === myPublicKey) {
return Constants.profileType.self;
}
if (isBridgedAccount) {
return Constants.profileType.bridged;
}
if (isBlocked) {
return Constants.profileType.blocked;
}
return Constants.profileType.regular;
}

function getContactType(contactRequestState, isContact) {
switch (contactRequestState) {
case Constants.ContactRequestState.Received:
return Constants.contactType.contactRequestReceived;
case Constants.ContactRequestState.Sent:
return Constants.contactType.contactRequestSent;
default:
return isContact ? Constants.contactType.contact : Constants.contactType.nonContact;
}
}
}
Loading

0 comments on commit 93f17b2

Please sign in to comment.