2023-02-28 15:00:10 +00:00
import QtQuick 2.15
import QtQuick . Controls 2.15
import QtQuick . Layouts 1.15
import QtGraphicalEffects 1.15
2022-09-27 21:26:26 +00:00
import StatusQ . Core 0.1
import StatusQ . Core . Theme 0.1
import StatusQ . Controls 0.1
import StatusQ . Components 0.1
import StatusQ . Popups 0.1
import StatusQ . Popups . Dialog 0.1
2023-02-28 15:00:10 +00:00
import StatusQ . Core . Utils 0.1 as StatusQUtils
2022-09-27 21:26:26 +00:00
import utils 1.0
import shared . controls 1.0
import shared . panels 1.0
import shared . popups 1.0
import shared . controls . chat 1.0
import shared . controls . chat . menuItems 1.0
2023-02-28 15:00:10 +00:00
import shared . views . profile 1.0
import SortFilterProxyModel 0.2
import AppLayouts . Wallet . stores 1.0 as WalletNS
2022-09-27 21:26:26 +00:00
Pane {
id: root
2023-02-28 15:00:10 +00:00
property bool readOnly // inside settings/profile/preview
2022-09-27 21:26:26 +00:00
property string publicKey: contactsStore . myPublicKey
property var profileStore
property var contactsStore
2023-02-28 15:00:10 +00:00
property var walletStore: WalletNS . RootStore
property var communitiesModel
2022-09-27 21:26:26 +00:00
2022-11-08 18:30:50 +00:00
property QtObject dirtyValues: null
property bool dirty: false
2022-09-27 21:26:26 +00:00
signal closeRequested ( )
padding: 0
topPadding: 40
background: StatusDialogBackground {
id: background
}
QtObject {
id: d
property var contactDetails: Utils . getContactDetailsAsJson ( root . publicKey )
function reload ( ) {
contactDetails = Utils . getContactDetailsAsJson ( root . publicKey )
}
readonly property bool isCurrentUser: root . profileStore . pubkey === root . publicKey
readonly property string userDisplayName: contactDetails . displayName
readonly property string userNickName: contactDetails . localNickname
2022-11-08 11:37:25 +00:00
readonly property string prettyEnsName: contactDetails . name
2022-12-05 09:56:44 +00:00
readonly property string aliasName: contactDetails . alias
readonly property string mainDisplayName: ProfileUtils . displayName ( userNickName , prettyEnsName , userDisplayName , aliasName )
readonly property string optionalDisplayName: ProfileUtils . displayName ( "" , prettyEnsName , userDisplayName , aliasName )
2022-09-27 21:26:26 +00:00
readonly property bool isContact: contactDetails . isContact
readonly property bool isBlocked: contactDetails . isBlocked
2023-04-18 15:08:24 +00:00
readonly property int contactRequestState: contactDetails . contactRequestState
2022-09-27 21:26:26 +00:00
readonly property int outgoingVerificationStatus: contactDetails . verificationStatus
readonly property int incomingVerificationStatus: contactDetails . incomingVerificationStatus
readonly property bool isVerificationRequestSent:
outgoingVerificationStatus !== Constants . verificationStatus . unverified &&
outgoingVerificationStatus !== Constants . verificationStatus . verified &&
outgoingVerificationStatus !== Constants . verificationStatus . trusted
2023-02-17 10:25:48 +00:00
readonly property bool isVerificationRequestReceived: incomingVerificationStatus === Constants . verificationStatus . verifying ||
incomingVerificationStatus === Constants . verificationStatus . verified
2022-09-27 21:26:26 +00:00
readonly property bool isTrusted: outgoingVerificationStatus === Constants . verificationStatus . trusted ||
incomingVerificationStatus === Constants . verificationStatus . trusted
readonly property bool isVerified: outgoingVerificationStatus === Constants . verificationStatus . verified
readonly property string linkToProfile: {
let user = ""
if ( d . isCurrentUser )
2022-12-13 09:37:27 +00:00
user = root . profileStore . preferredName
2022-09-27 21:26:26 +00:00
else
user = contactDetails . name
if ( ! user )
2022-10-21 09:00:51 +00:00
user = Utils . getCompressedPk ( root . publicKey )
2022-09-27 21:26:26 +00:00
return Constants . userLinkPrefix + user
}
readonly property var conns: Connections {
2023-02-28 14:54:10 +00:00
target: root . contactsStore . myContactsModel ? ? null
2022-12-09 12:33:20 +00:00
function onItemChanged ( pubKey ) {
if ( pubKey === root . publicKey )
d . reload ( )
2022-09-27 21:26:26 +00:00
}
2022-12-09 12:33:20 +00:00
}
// FIXME: use myContactsModel for identity verification
readonly property var conns2: Connections {
2023-02-28 14:54:10 +00:00
target: root . contactsStore . receivedContactRequestsModel ? ? null
2022-12-09 12:33:20 +00:00
function onItemChanged ( pubKey ) {
if ( pubKey === root . publicKey )
d . reload ( )
2022-09-27 21:26:26 +00:00
}
}
2022-11-16 09:54:45 +00:00
2023-02-07 14:21:32 +00:00
readonly property var conns3: Connections {
2023-02-28 14:54:10 +00:00
target: root . contactsStore . sentContactRequestsModel ? ? null
2023-02-07 14:21:32 +00:00
function onItemChanged ( pubKey ) {
if ( pubKey === root . publicKey )
d . reload ( )
}
}
2023-04-19 16:28:23 +00:00
readonly property var conns4: Connections {
target: Global
function onContactRenamed ( pubKey ) {
if ( pubKey === root . publicKey )
d . reload ( )
}
}
2022-11-16 09:54:45 +00:00
readonly property var timer: Timer {
id: timer
}
2022-09-27 21:26:26 +00:00
}
function reload ( ) {
d . reload ( )
}
Component {
id: btnEditProfileComponent
StatusButton {
2022-12-16 18:24:51 +00:00
objectName: "editProfileButton"
2022-09-27 21:26:26 +00:00
size: StatusButton . Size . Small
text: qsTr ( "Edit Profile" )
enabled: ! root . readOnly
onClicked: {
Global . changeAppSectionBySectionType ( Constants . appSection . profile )
root . closeRequested ( )
}
}
}
Component {
id: btnSendMessageComponent
StatusButton {
size: StatusButton . Size . Small
text: qsTr ( "Send Message" )
onClicked: {
root . contactsStore . joinPrivateChat ( root . publicKey )
root . closeRequested ( )
}
}
}
Component {
id: btnAcceptContactRequestComponent
ColumnLayout {
spacing: Style . current . halfPadding
StatusBaseText {
color: Theme . palette . baseColor1
font.pixelSize: 13
text: qsTr ( "Respond to contact request" )
}
AcceptRejectOptionsButtonsPanel {
menuButton.visible: false
onAcceptClicked: {
2023-04-03 16:27:56 +00:00
root . contactsStore . acceptContactRequest ( root . publicKey , "" )
2022-09-27 21:26:26 +00:00
d . reload ( )
}
onDeclineClicked: {
root . contactsStore . dismissContactRequest ( root . publicKey )
d . reload ( )
}
}
}
}
Component {
id: btnSendContactRequestComponent
StatusButton {
2022-12-26 21:53:47 +00:00
objectName: "profileDialog_sendContactRequestButton"
2022-09-27 21:26:26 +00:00
size: StatusButton . Size . Small
text: qsTr ( "Send Contact Request" )
onClicked: {
2023-02-07 14:21:32 +00:00
Global . openContactRequestPopup ( root . publicKey , null )
2022-09-27 21:26:26 +00:00
}
}
}
Component {
id: btnBlockUserComponent
StatusButton {
size: StatusButton . Size . Small
type: StatusBaseButton . Type . Danger
text: qsTr ( "Block User" )
2022-12-05 09:56:44 +00:00
onClicked: Global . blockContactRequested ( root . publicKey , d . mainDisplayName )
2022-09-27 21:26:26 +00:00
}
}
Component {
id: btnUnblockUserComponent
StatusButton {
size: StatusButton . Size . Small
text: qsTr ( "Unblock User" )
2022-12-05 09:56:44 +00:00
onClicked: Global . unblockContactRequested ( root . publicKey , d . mainDisplayName )
2022-09-27 21:26:26 +00:00
}
}
Component {
id: txtPendingContactRequestComponent
StatusBaseText {
font.pixelSize: 13
font.weight: Font . Medium
color: Theme . palette . baseColor1
verticalAlignment: Text . AlignVCenter
text: qsTr ( "Contact Request Pending..." )
}
}
Component {
id: txtRejectedContactRequestComponent
StatusBaseText {
font.pixelSize: 13
font.weight: Font . Medium
color: Theme . palette . baseColor1
verticalAlignment: Text . AlignVCenter
text: qsTr ( "Contact Request Rejected" )
}
}
Component {
id: btnRespondToIdRequestComponent
StatusButton {
size: StatusButton . Size . Small
text: qsTr ( "Respond to ID Request" )
onClicked: {
2022-10-21 13:37:39 +00:00
Global . openIncomingIDRequestPopup ( root . publicKey ,
popup = > popup . closed . connect ( d . reload ) )
2022-09-27 21:26:26 +00:00
}
}
}
ConfirmationDialog {
id: removeContactConfirmationDialog
2023-05-05 12:38:26 +00:00
header.title: qsTr ( "Remove '%1' as a contact" ) . arg ( d . mainDisplayName )
confirmationText: qsTr ( "This will mean that you and '%1' will no longer be able to send direct messages to each other. You will need to send them a new Contact Request in order to message again. All previous direct messages between you and '%1' will be retained in read-only mode." ) . arg ( d . mainDisplayName )
showCancelButton: true
cancelBtnType: ""
2022-09-27 21:26:26 +00:00
onConfirmButtonClicked: {
root . contactsStore . removeContact ( root . publicKey )
close ( )
d . reload ( )
}
2023-05-05 12:38:26 +00:00
onCancelButtonClicked: {
removeContactConfirmationDialog . close ( ) ;
}
2022-09-27 21:26:26 +00:00
}
ConfirmationDialog {
id: removeVerificationConfirmationDialog
header.title: qsTr ( "Remove contact verification" )
confirmationText: qsTr ( "This will remove the contact's verified status. Please confirm." )
onConfirmButtonClicked: {
root . contactsStore . removeTrustStatus ( root . publicKey )
close ( )
d . reload ( )
}
}
ColumnLayout {
id: column
spacing: 20
anchors {
fill: parent
leftMargin: Style . current . bigPadding
rightMargin: Style . current . bigPadding
}
RowLayout {
Layout.fillWidth: true
spacing: Style . current . halfPadding
UserImage {
Layout.alignment: Qt . AlignTop
objectName: "ProfileDialog_userImage"
2022-11-08 18:30:50 +00:00
name: root . dirty ? root . dirtyValues . displayName
2022-12-05 09:56:44 +00:00
: d . mainDisplayName
2022-09-27 21:26:26 +00:00
pubkey: root . publicKey
2022-11-08 18:30:50 +00:00
image: root . dirty ? root . dirtyValues . profileLargeImage
: d . contactDetails . largeImage
2022-09-27 21:26:26 +00:00
interactive: false
imageWidth: 80
imageHeight: imageWidth
2022-12-01 10:24:25 +00:00
ensVerified: d . contactDetails . ensVerified
2022-09-27 21:26:26 +00:00
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 4
Layout.alignment: Qt . AlignTop
spacing: 4
Item {
id: contactRow
Layout.fillWidth: true
Layout.preferredHeight: childrenRect . height
StatusBaseText {
id: contactName
anchors.left: parent . left
width: Math . min ( implicitWidth , contactRow . width - verificationIcons . width - verificationIcons . anchors . leftMargin )
objectName: "ProfileDialog_displayName"
font.bold: true
font.pixelSize: 22
elide: Text . ElideRight
2022-11-08 18:30:50 +00:00
text: root . dirty ? root . dirtyValues . displayName
2022-12-05 09:56:44 +00:00
: d . mainDisplayName
2022-09-27 21:26:26 +00:00
}
StatusContactVerificationIcons {
id: verificationIcons
anchors.left: contactName . right
anchors.leftMargin: Style . current . halfPadding
anchors.verticalCenter: contactName . verticalCenter
objectName: "ProfileDialog_userVerificationIcons"
visible: ! d . isCurrentUser
isContact: d . isContact
trustIndicator: d . contactDetails . trustStatus
tiny: false
}
}
StatusBaseText {
id: contactSecondaryName
font.pixelSize: 12
color: Theme . palette . baseColor1
2022-12-05 09:56:44 +00:00
text: "(%1)" . arg ( d . optionalDisplayName )
visible: ! ! d . userNickName
2022-09-27 21:26:26 +00:00
}
EmojiHash {
objectName: "ProfileDialog_userEmojiHash"
publicKey: root . publicKey
}
}
Loader {
Layout.alignment: Qt . AlignTop
Layout.preferredHeight: menuButton . visible ? menuButton.height : - 1
sourceComponent: {
// current user
if ( d . isCurrentUser )
return btnEditProfileComponent
2023-04-18 11:43:28 +00:00
// blocked contact
if ( d . isBlocked )
return btnUnblockUserComponent
2023-04-18 15:08:24 +00:00
// block user
if ( d . contactDetails . trustStatus === Constants . trustStatus . untrustworthy )
return btnBlockUserComponent
2023-03-15 14:26:10 +00:00
2023-04-18 15:08:24 +00:00
// depend on contactRequestState
switch ( d . contactRequestState ) {
case Constants.ContactRequestState.Sent:
2022-09-27 21:26:26 +00:00
return txtPendingContactRequestComponent
2023-04-18 15:08:24 +00:00
case Constants.ContactRequestState.Received:
2023-04-17 15:37:43 +00:00
return btnAcceptContactRequestComponent
2023-04-18 15:08:24 +00:00
case Constants.ContactRequestState.Mutual: {
if ( d . incomingVerificationStatus === Constants . verificationStatus . declined ) {
return btnBlockUserComponent
} else if ( ! d . isTrusted && d . isVerificationRequestReceived ) {
return btnRespondToIdRequestComponent
}
return btnSendMessageComponent
2023-03-15 14:26:10 +00:00
}
2023-04-18 15:08:24 +00:00
case Constants.ContactRequestState.None:
case Constants.ContactRequestState.Dismissed:
2022-09-27 21:26:26 +00:00
return btnSendContactRequestComponent
2023-04-18 15:08:24 +00:00
default:
console . warn ( "!!! UNHANDLED CONTACT ACTION BUTTON; PUBKEY" , root . publicKey )
return null
}
2022-09-27 21:26:26 +00:00
}
}
StatusFlatButton {
id: menuButton
Layout.alignment: Qt . AlignTop
Layout.preferredWidth: height
visible: ! d . isCurrentUser
size: StatusBaseButton . Size . Small
horizontalPadding: 6
verticalPadding: 6
icon.name: "more"
icon.color: Theme . palette . directColor1
highlighted: moreMenu . opened
onClicked: moreMenu . popup ( - moreMenu . width + width , height + 4 )
2022-12-01 16:58:37 +00:00
StatusMenu {
2022-09-27 21:26:26 +00:00
id: moreMenu
width: 230
SendContactRequestMenuItem {
2023-04-26 09:12:45 +00:00
enabled: ! d . isContact && ! d . isBlocked && d . contactRequestState !== Constants . ContactRequestState . Sent &&
2022-09-27 21:26:26 +00:00
d . contactDetails . trustStatus === Constants . trustStatus . untrustworthy // we have an action button otherwise
onTriggered: {
moreMenu . close ( )
2023-02-07 14:21:32 +00:00
Global . openContactRequestPopup ( root . publicKey , null )
2022-09-27 21:26:26 +00:00
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Verify Identity" )
icon.name: "checkmark-circle"
enabled: d . isContact && ! d . isBlocked &&
d . outgoingVerificationStatus === Constants . verificationStatus . unverified &&
! d . isVerificationRequestReceived
onTriggered: {
moreMenu . close ( )
2022-10-21 13:37:39 +00:00
Global . openSendIDRequestPopup ( root . publicKey ,
popup = > popup . accepted . connect ( d . reload ) )
2022-09-27 21:26:26 +00:00
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "ID Request Pending..." )
icon.name: "checkmark-circle"
enabled: d . isContact && ! d . isBlocked && ! d . isTrusted && d . isVerificationRequestSent
onTriggered: {
moreMenu . close ( )
2022-10-21 13:37:39 +00:00
Global . openOutgoingIDRequestPopup ( root . publicKey ,
popup = > popup . closed . connect ( d . reload ) )
2022-09-27 21:26:26 +00:00
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Rename" )
icon.name: "edit_pencil"
onTriggered: {
moreMenu . close ( )
Global . openNicknamePopupRequested ( root . publicKey , d . userNickName ,
2022-12-05 09:56:44 +00:00
"%1 (%2)" . arg ( d . optionalDisplayName ) . arg ( Utils . getElidedCompressedPk ( root . publicKey ) ) )
2022-09-27 21:26:26 +00:00
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Copy Link to Profile" )
icon.name: "copy"
onTriggered: {
moreMenu . close ( )
root . profileStore . copyToClipboard ( d . linkToProfile )
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Unblock User" )
icon.name: "remove-circle"
enabled: d . isBlocked
onTriggered: {
moreMenu . close ( )
2022-12-05 09:56:44 +00:00
Global . unblockContactRequested ( root . publicKey , d . mainDisplayName )
2022-09-27 21:26:26 +00:00
}
}
StatusMenuSeparator { }
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Mark as Untrustworthy" )
icon.name: "warning"
2022-12-01 16:58:37 +00:00
type: StatusAction . Type . Danger
2022-09-27 21:26:26 +00:00
enabled: d . contactDetails . trustStatus === Constants . trustStatus . unknown
onTriggered: {
moreMenu . close ( )
if ( d . isContact && ! d . isTrusted && d . isVerificationRequestReceived )
root . contactsStore . verifiedUntrustworthy ( root . publicKey )
else
root . contactsStore . markUntrustworthy ( root . publicKey )
d . reload ( )
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Remove Untrustworthy Mark" )
icon.name: "warning"
enabled: d . contactDetails . trustStatus === Constants . trustStatus . untrustworthy
onTriggered: {
moreMenu . close ( )
root . contactsStore . removeTrustStatus ( root . publicKey )
d . reload ( )
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Remove Identity Verification" )
icon.name: "warning"
2022-12-01 16:58:37 +00:00
type: StatusAction . Type . Danger
2022-09-27 21:26:26 +00:00
enabled: d . isContact && d . isTrusted
onTriggered: {
moreMenu . close ( )
removeVerificationConfirmationDialog . open ( )
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Remove Contact" )
icon.name: "remove-contact"
2022-12-01 16:58:37 +00:00
type: StatusAction . Type . Danger
2023-04-18 15:08:24 +00:00
enabled: d . isContact && ! d . isBlocked && d . contactRequestState !== Constants . ContactRequestState . Sent
2022-09-27 21:26:26 +00:00
onTriggered: {
moreMenu . close ( )
removeContactConfirmationDialog . open ( )
}
}
2022-12-01 16:58:37 +00:00
StatusAction {
2022-09-27 21:26:26 +00:00
text: qsTr ( "Block User" )
icon.name: "cancel"
2022-12-01 16:58:37 +00:00
type: StatusAction . Type . Danger
2022-09-27 21:26:26 +00:00
enabled: ! d . isBlocked
onTriggered: {
moreMenu . close ( )
2022-12-05 09:56:44 +00:00
Global . blockContactRequested ( root . publicKey , d . mainDisplayName )
2022-09-27 21:26:26 +00:00
}
}
}
}
}
StatusDialogDivider {
Layout.fillWidth: true
Layout.leftMargin: - column . anchors . leftMargin
Layout.rightMargin: - column . anchors . rightMargin
Layout.topMargin: - column . spacing
Layout.bottomMargin: - column . spacing
opacity: scrollView . atYBeginning ? 0 : 1
Behavior on opacity { OpacityAnimator { } }
}
StatusScrollView {
id: scrollView
2023-02-28 15:00:10 +00:00
implicitWidth: contentWidth + leftPadding + rightPadding
implicitHeight: contentHeight + topPadding + bottomPadding
2022-09-27 21:26:26 +00:00
Layout.fillWidth: true
2023-02-28 15:00:10 +00:00
Layout.fillHeight: true
2022-09-27 21:26:26 +00:00
Layout.leftMargin: - column . anchors . leftMargin
Layout.rightMargin: - column . anchors . rightMargin
Layout.topMargin: - column . spacing
padding: 0
ColumnLayout {
width: scrollView . width
spacing: 20
ProfileBioSocialsPanel {
Layout.fillWidth: true
Layout.leftMargin: column . anchors . leftMargin + Style . current . halfPadding
Layout.rightMargin: column . anchors . rightMargin + Style . current . halfPadding
2023-02-28 15:00:10 +00:00
bio: root . dirty ? root.dirtyValues.bio : d . contactDetails . bio
2023-03-08 01:56:41 +00:00
userSocialLinksJson: root . readOnly ? root . profileStore . temporarySocialLinksJson
: d . contactDetails . socialLinks
2022-09-27 21:26:26 +00:00
}
GridLayout {
Layout.fillWidth: true
Layout.leftMargin: column . anchors . leftMargin
Layout.rightMargin: column . anchors . rightMargin
flow: GridLayout . TopToBottom
rowSpacing: Style . current . halfPadding
columnSpacing: Style . current . bigPadding
visible: d . isCurrentUser
enabled: visible
columns: 2
rows: 4
StatusBaseText {
Layout.fillWidth: true
text: qsTr ( "Link to Profile" )
font.pixelSize: 13
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 56
2023-03-08 01:56:41 +00:00
leftPadding: Style . current . padding
2022-09-27 21:26:26 +00:00
rightPadding: Style . current . halfPadding
topPadding: 0
bottomPadding: 0
placeholder.rightPadding: Style . current . halfPadding
placeholderText: d . linkToProfile
placeholderTextColor: Theme . palette . directColor1
edit.readOnly: true
rightComponent: StatusButton {
2022-11-16 09:54:45 +00:00
id: copyLinkBtn
2022-09-27 21:26:26 +00:00
anchors.verticalCenter: parent . verticalCenter
borderColor: Theme . palette . primaryColor1
size: StatusBaseButton . Size . Tiny
text: qsTr ( "Copy" )
onClicked: {
text = qsTr ( "Copied" )
root . profileStore . copyToClipboard ( d . linkToProfile )
2022-11-16 09:54:45 +00:00
d . timer . setTimeout ( function ( ) {
copyLinkBtn . text = qsTr ( "Copy" )
} , 2000 ) ;
2022-09-27 21:26:26 +00:00
}
}
}
StatusBaseText {
Layout.fillWidth: true
Layout.topMargin: Style . current . smallPadding
text: qsTr ( "Emoji Hash" )
font.pixelSize: 13
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 56
2023-03-08 01:56:41 +00:00
leftPadding: Style . current . padding
2022-09-27 21:26:26 +00:00
rightPadding: Style . current . halfPadding
topPadding: 0
bottomPadding: 0
edit.readOnly: true
leftComponent: EmojiHash {
publicKey: root . publicKey
oneRow: ! root . readOnly
}
rightComponent: StatusButton {
2022-11-16 09:54:45 +00:00
id: copyHashBtn
2022-09-27 21:26:26 +00:00
anchors.verticalCenter: parent . verticalCenter
borderColor: Theme . palette . primaryColor1
size: StatusBaseButton . Size . Tiny
text: qsTr ( "Copy" )
onClicked: {
root . profileStore . copyToClipboard ( Utils . getEmojiHashAsJson ( root . publicKey ) . join ( "" ) . toString ( ) )
text = qsTr ( "Copied" )
2022-11-16 09:54:45 +00:00
d . timer . setTimeout ( function ( ) {
copyHashBtn . text = qsTr ( "Copy" )
} , 2000 ) ;
2022-09-27 21:26:26 +00:00
}
}
}
Rectangle {
Layout.rowSpan: 4
Layout.fillHeight: true
Layout.preferredWidth: height
Layout.alignment: Qt . AlignCenter
color: "transparent"
border.width: 1
border.color: Theme . palette . baseColor2
radius: Style . current . halfPadding
Image {
anchors.centerIn: parent
asynchronous: true
fillMode: Image . PreserveAspectFit
width: 170
height: width
mipmap: true
smooth: false
2023-02-28 15:00:10 +00:00
source: root . profileStore . getQrCodeSource ( Utils . getCompressedPk ( root . profileStore . pubkey ) )
2022-09-27 21:26:26 +00:00
}
}
}
StatusTabBar {
2023-02-28 15:00:10 +00:00
id: showcaseTabBar
2022-09-27 21:26:26 +00:00
Layout.fillWidth: true
Layout.leftMargin: column . anchors . leftMargin
Layout.rightMargin: column . anchors . rightMargin
bottomPadding: - 4
StatusTabButton {
2023-04-19 16:48:57 +00:00
leftPadding: 0
2022-09-27 21:26:26 +00:00
width: implicitWidth
2023-02-28 15:00:10 +00:00
text: qsTr ( "Communities" )
2022-09-27 21:26:26 +00:00
}
StatusTabButton {
width: implicitWidth
2023-02-28 15:00:10 +00:00
text: qsTr ( "Accounts" )
2022-09-27 21:26:26 +00:00
}
StatusTabButton {
width: implicitWidth
2023-02-28 15:00:10 +00:00
text: qsTr ( "Collectibles" )
2022-09-27 21:26:26 +00:00
}
StatusTabButton {
width: implicitWidth
2023-02-28 15:00:10 +00:00
text: qsTr ( "Assets" )
2022-09-27 21:26:26 +00:00
}
}
2023-02-28 15:00:10 +00:00
// Profile Showcase
ProfileShowcaseView {
2022-09-27 21:26:26 +00:00
Layout.fillWidth: true
Layout.topMargin: - column . spacing
Layout.preferredHeight: 300
2023-02-28 15:00:10 +00:00
currentTabIndex: showcaseTabBar . currentIndex
isCurrentUser: d . isCurrentUser
mainDisplayName: d . mainDisplayName
readOnly: root . readOnly
profileStore: root . profileStore
walletStore: root . walletStore
communitiesModel: root . communitiesModel
2022-09-27 21:26:26 +00:00
2023-02-28 15:00:10 +00:00
onCloseRequested: root . closeRequested ( )
2022-09-27 21:26:26 +00:00
}
}
}
}
layer.enabled: ! root . readOnly // profile preview has its own layer.effect
layer.effect: OpacityMask {
maskSource: Rectangle {
anchors.centerIn: parent
width: column . width
height: column . height
radius: background . radius
}
}
}