fix(MyProfileView): New design
This commit is contained in:
parent
5c6b5f1f47
commit
c7d2157d20
|
@ -1,12 +1,12 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.popups 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
|
@ -20,6 +20,9 @@ Item {
|
|||
property bool editable: false
|
||||
|
||||
readonly property Item contentItem: contentLoader.item
|
||||
readonly property size settingsDirtyToastMessageImplicitSize:
|
||||
Qt.size(settingsDirtyToastMessage.implicitWidth,
|
||||
settingsDirtyToastMessage.implicitHeight + settingsDirtyToastMessage.anchors.bottomMargin)
|
||||
|
||||
signal previousPageClicked
|
||||
signal saveChangesClicked
|
||||
|
@ -31,9 +34,7 @@ Item {
|
|||
}
|
||||
|
||||
function notifyDirty() {
|
||||
cancelChangesButtonAnimation.running = true
|
||||
saveChangesButtonAnimation.running = true
|
||||
saveChangesButton.forceActiveFocus()
|
||||
settingsDirtyToastMessage.notifyDirty()
|
||||
}
|
||||
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
@ -81,69 +82,20 @@ Item {
|
|||
|
||||
sourceComponent: root.content
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
|
||||
implicitHeight: buttonsLayout.implicitHeight
|
||||
|
||||
color: Theme.palette.statusToastMessage.backgroundColor
|
||||
visible: root.editable
|
||||
|
||||
RowLayout {
|
||||
id: buttonsLayout
|
||||
|
||||
anchors.fill: parent
|
||||
enabled: root.dirty
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: cancelChangesButton
|
||||
|
||||
text: qsTr("Cancel changes")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
|
||||
border.color: textColor
|
||||
border.width: 0
|
||||
|
||||
onClicked: root.resetChangesClicked()
|
||||
|
||||
NumberAnimation on border.width {
|
||||
id: cancelChangesButtonAnimation
|
||||
from: 0
|
||||
to: 2
|
||||
loops: 2
|
||||
duration: 600
|
||||
|
||||
onFinished: cancelChangesButton.border.width = 0
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: saveChangesButton
|
||||
|
||||
text: qsTr("Save changes")
|
||||
|
||||
border.color: textColor
|
||||
border.width: 0
|
||||
|
||||
onClicked: root.saveChangesClicked()
|
||||
|
||||
NumberAnimation on border.width {
|
||||
id: saveChangesButtonAnimation
|
||||
from: 0
|
||||
to: 2
|
||||
loops: 2
|
||||
duration: 600
|
||||
|
||||
onFinished: saveChangesButton.border.width = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsDirtyToastMessage {
|
||||
id: settingsDirtyToastMessage
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottomMargin: 16
|
||||
}
|
||||
active: root.dirty
|
||||
flickable: root.contentItem
|
||||
saveChangesButtonEnabled: root.contentItem && root.contentItem.saveChangesButtonEnabled
|
||||
onResetChangesClicked: root.resetChangesClicked()
|
||||
onSaveChangesClicked: root.saveChangesClicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ Flickable {
|
|||
property alias bannerPath: bannerPicker.source
|
||||
property alias bannerCropRect: bannerPicker.cropRect
|
||||
|
||||
property size bottomReservedSpace: Qt.size(0, 0)
|
||||
property bool bottomReservedSpaceActive: false
|
||||
|
||||
readonly property bool saveChangesButtonEnabled: true
|
||||
|
||||
contentWidth: layout.width
|
||||
contentHeight: layout.height
|
||||
clip: true
|
||||
|
@ -149,7 +154,10 @@ Flickable {
|
|||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
// settingsDirtyToastMessage placeholder
|
||||
visible: root.bottomReservedSpaceActive
|
||||
implicitWidth: root.bottomReservedSpace.width
|
||||
implicitHeight: root.bottomReservedSpace.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,6 +184,9 @@ StackLayout {
|
|||
pinMessagesEnabled: root.pinMessagesEnabled
|
||||
}
|
||||
|
||||
bottomReservedSpace: editCommunityPage.settingsDirtyToastMessageImplicitSize
|
||||
bottomReservedSpaceActive: editCommunityPage.dirty
|
||||
|
||||
Component.onCompleted: {
|
||||
editCommunityPage.dirty =
|
||||
Qt.binding(() => {
|
||||
|
|
|
@ -41,6 +41,12 @@ StatusAppTwoPanelLayout {
|
|||
store: profileView.store
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: d.topMargin
|
||||
onMenuItemClicked: {
|
||||
if (profileContainer.currentItem.dirty) {
|
||||
event.accepted = true;
|
||||
profileContainer.currentItem.notifyDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rightPanel: Item {
|
||||
|
@ -65,6 +71,8 @@ StatusAppTwoPanelLayout {
|
|||
StackLayout {
|
||||
id: profileContainer
|
||||
|
||||
readonly property var currentItem: (currentIndex >= 0 && currentIndex < children.length) ? children[currentIndex] : null
|
||||
|
||||
anchors.top: banner.visible? banner.bottom : parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -86,7 +94,9 @@ StatusAppTwoPanelLayout {
|
|||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
|
||||
walletStore: profileView.store.walletStore
|
||||
profileStore: profileView.store.profileStore
|
||||
privacyStore: profileView.store.privacyStore
|
||||
sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.profile)
|
||||
contentWidth: d.contentWidth
|
||||
}
|
||||
|
@ -138,15 +148,6 @@ StatusAppTwoPanelLayout {
|
|||
contentWidth: d.contentWidth
|
||||
}
|
||||
|
||||
PrivacyView {
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
|
||||
privacyStore: profileView.store.privacyStore
|
||||
sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.privacyAndSecurity)
|
||||
contentWidth: d.contentWidth
|
||||
}
|
||||
|
||||
AppearanceView {
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
StatusListItem {
|
||||
property var community
|
||||
|
||||
title: community.name
|
||||
subTitle: community.amISectionAdmin ? qsTr("Admin") : qsTr("Member")
|
||||
|
||||
image {
|
||||
source: community.image
|
||||
}
|
||||
|
||||
icon {
|
||||
name: community.name
|
||||
letterSize: 14
|
||||
isLetterIdenticon: !community.image
|
||||
color: community.color
|
||||
}
|
||||
}
|
|
@ -4,9 +4,12 @@ import StatusQ.Core 0.1
|
|||
|
||||
|
||||
StatusListItem {
|
||||
signal goToAccountView()
|
||||
|
||||
id: root
|
||||
|
||||
property var account
|
||||
property bool showShevronIcon: true
|
||||
|
||||
signal goToAccountView()
|
||||
|
||||
title: account.name
|
||||
subTitle: account.address
|
||||
|
@ -17,15 +20,18 @@ StatusListItem {
|
|||
icon.isLetterIdenticon: !!account.emoji
|
||||
icon.background.color: Theme.palette.indirectColor1
|
||||
width: parent.width
|
||||
components: [
|
||||
StatusIcon {
|
||||
icon: "chevron-down"
|
||||
rotation: 270
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
|
||||
components: !showShevronIcon ? [] : [ shevronIcon ]
|
||||
|
||||
onClicked: {
|
||||
goToAccountView()
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
id: shevronIcon
|
||||
visible: root.showShevronIcon
|
||||
icon: "chevron-down"
|
||||
rotation: 270
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,28 @@ StatusModal {
|
|||
|
||||
function onChangePasswordResponse(success, errorMsg) {
|
||||
if (success) {
|
||||
if (Qt.platform.os === "osx") {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueStore;
|
||||
root.privacyStore.storeToKeyChain(d.passwordProcessing);
|
||||
}
|
||||
passwordChanged()
|
||||
submitBtn.enabled = false
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
view.reset()
|
||||
view.errorMsgText = errorMsg
|
||||
console.warn("TODO: Display error message when change password action failure! ")
|
||||
}
|
||||
submitBtn.loading = false
|
||||
d.passwordProcessing = "";
|
||||
submitBtn.enabled = false;
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
// We temporarly store the password during "changePassword" call
|
||||
// to store it to KeyChain after successfull change operation.
|
||||
property string passwordProcessing: ""
|
||||
|
||||
function submit() {
|
||||
submitBtn.loading = true
|
||||
// ChangePassword operation blocks the UI so loading = true; will never have any affect until changePassword/createPassword is done.
|
||||
|
@ -77,6 +86,7 @@ StatusModal {
|
|||
interval: 20
|
||||
onTriggered: {
|
||||
// Change current password call action to the backend
|
||||
d.passwordProcessing = view.newPswText
|
||||
root.privacyStore.changePassword(view.currentPswText, view.newPswText)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../../Onboarding/shared" as OnboardingComponents
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: popup
|
||||
|
||||
property var privacyStore
|
||||
|
||||
title: qsTr("Store pass to Keychain")
|
||||
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
|
||||
function updateListState() {
|
||||
if (localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueStore)
|
||||
storeBtn.checked = true
|
||||
else if (localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueNotNow ||
|
||||
localAccountSettings.storeToKeychainValue === "")
|
||||
notNowBtn.checked = true
|
||||
else if (localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueNever)
|
||||
neverBtn.checked = true
|
||||
}
|
||||
|
||||
function offerToStorePassword(password, runStoreToKeychainPopup) {
|
||||
if(Qt.platform.os == "osx")
|
||||
{
|
||||
if(runStoreToKeychainPopup)
|
||||
Global.openPopup(storeToKeychainConfirmationPopupComponent, { password: password })
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.leftMargin: Style.current.padding
|
||||
|
||||
spacing: 0
|
||||
|
||||
Connections {
|
||||
target: localAccountSettings
|
||||
onStoreToKeychainValueChanged: {
|
||||
updateListState()
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: openLinksWithGroup
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
id: storeBtn
|
||||
title: qsTr("Store")
|
||||
buttonGroup: openLinksWithGroup
|
||||
checked: localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueStore
|
||||
onCheckedChanged: {
|
||||
if (checked && localAccountSettings.storeToKeychainValue !== Constants.storeToKeychainValueStore) {
|
||||
// TODO: REFACTOR TO NEW PASWORD VIEW AND
|
||||
// DELETE StoreToKeychainSelectionModal.qml
|
||||
// AND CreatePasswordModal.qml IF NOT NEEDED
|
||||
var storePassPopup = Global.openPopup(storePasswordModal)
|
||||
if(storePassPopup)
|
||||
{
|
||||
storePassPopup.closed.connect(function(){
|
||||
updateListState()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
id: notNowBtn
|
||||
title: qsTr("Not now")
|
||||
buttonGroup: openLinksWithGroup
|
||||
checked: localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueNotNow ||
|
||||
localAccountSettings.storeToKeychainValue === ""
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueNotNow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonSelector {
|
||||
id: neverBtn
|
||||
title: qsTr("Never")
|
||||
buttonGroup: openLinksWithGroup
|
||||
checked: localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueNever
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueNever
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: storePasswordModal
|
||||
OnboardingComponents.CreatePasswordModal {
|
||||
privacyStore: popup.privacyStore
|
||||
storingPasswordModal: true
|
||||
height: 350
|
||||
|
||||
onOfferToStorePassword: {
|
||||
popup.offerToStorePassword(password, runStoreToKeychainPopup)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: storeToKeychainConfirmationPopupComponent
|
||||
ConfirmationDialog {
|
||||
id: storeToKeychainConfirmationPopup
|
||||
property string password: ""
|
||||
height: 200
|
||||
confirmationText: qsTr("Would you like to store password to the Keychain?")
|
||||
showRejectButton: true
|
||||
showCancelButton: true
|
||||
confirmButtonLabel: qsTr("Store")
|
||||
rejectButtonLabel: qsTr("Not now")
|
||||
cancelButtonLabel: qsTr("Never")
|
||||
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
|
||||
function finish()
|
||||
{
|
||||
password = ""
|
||||
storeToKeychainConfirmationPopup.close()
|
||||
}
|
||||
|
||||
onConfirmButtonClicked: {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueStore
|
||||
root.privacyStore.storeToKeyChain(password)
|
||||
finish()
|
||||
}
|
||||
|
||||
onRejectButtonClicked: {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueNotNow
|
||||
finish()
|
||||
}
|
||||
|
||||
onCancelButtonClicked: {
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueNever
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -100,9 +100,6 @@ QtObject {
|
|||
|
||||
property ListModel settingsMenuItems: ListModel {
|
||||
Component.onCompleted: {
|
||||
append({subsection: Constants.settingsSubsection.privacyAndSecurity,
|
||||
text: qsTr("Privacy and security"),
|
||||
icon: "security"})
|
||||
append({subsection: Constants.settingsSubsection.appearance,
|
||||
text: qsTr("Appearance"),
|
||||
icon: "appearance"})
|
||||
|
|
|
@ -20,6 +20,8 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
property var details: Utils.getContactDetailsAsJson(pubkey)
|
||||
|
||||
function uploadImage(source, aX, aY, bX, bY) {
|
||||
return root.profileModule.upload(source, aX, aY, bX, bY)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ QtObject {
|
|||
networksModule.toggleTestNetworksEnabled()
|
||||
}
|
||||
|
||||
property var accounts: walletSectionAccounts.model
|
||||
property var importedAccounts: walletSectionAccounts.imported
|
||||
property var generatedAccounts: walletSectionAccounts.generated
|
||||
property var watchOnlyAccounts: walletSectionAccounts.watchOnly
|
||||
|
|
|
@ -8,9 +8,12 @@ import shared.popups 1.0
|
|||
import "../panels"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var store
|
||||
|
||||
signal menuItemClicked(var event)
|
||||
|
||||
StatusNavigationPanelHeadline {
|
||||
id: title
|
||||
text: qsTr("Settings")
|
||||
|
@ -46,12 +49,20 @@ Item {
|
|||
onMenuItemClicked: {
|
||||
if (menu_item.subsection === Constants.settingsSubsection.backUpSeed) {
|
||||
Global.openBackUpSeedPopup();
|
||||
} else {
|
||||
if (menu_item.subsection === Constants.settingsSubsection.signout) {
|
||||
return confirmDialog.open();
|
||||
}
|
||||
Global.settingsSubsection = menu_item.subsection;
|
||||
return;
|
||||
}
|
||||
|
||||
let event = { accepted: false, item: menu_item.subsection };
|
||||
|
||||
root.menuItemClicked(event);
|
||||
|
||||
if (event.accepted)
|
||||
return;
|
||||
|
||||
if (menu_item.subsection === Constants.settingsSubsection.signout)
|
||||
return confirmDialog.open()
|
||||
|
||||
Global.settingsSubsection = menu_item.subsection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import shared.controls.chat 1.0
|
|||
|
||||
import "../popups"
|
||||
import "../stores"
|
||||
import "../controls"
|
||||
import "./profile"
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
@ -19,161 +21,69 @@ import StatusQ.Controls 0.1
|
|||
SettingsContentBase {
|
||||
id: root
|
||||
|
||||
property WalletStore walletStore
|
||||
property ProfileStore profileStore
|
||||
property PrivacyStore privacyStore
|
||||
|
||||
titleRowComponentLoader.sourceComponent: StatusButton {
|
||||
text: qsTr("Change Password")
|
||||
onClicked: changePasswordModal.open()
|
||||
}
|
||||
|
||||
dirty: settingsView.dirty
|
||||
saveChangesButtonEnabled: settingsView.valid
|
||||
|
||||
onResetChangesClicked: settingsView.reset()
|
||||
onSaveChangesClicked: settingsView.save()
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
spacing: Constants.settingsSection.itemSpacing
|
||||
width: root.contentWidth
|
||||
|
||||
RowLayout {
|
||||
StatusTabBar {
|
||||
id: editPreviwTabBar
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
StatusBaseText {
|
||||
id: profileName
|
||||
text: root.profileStore.name
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 20
|
||||
color: Theme.palette.directColor1
|
||||
StatusTabButton {
|
||||
width: implicitWidth
|
||||
text: qsTr("Edit")
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Edit"
|
||||
onClicked: Global.openPopup(displayNamePopupComponent)
|
||||
StatusTabButton {
|
||||
width: implicitWidth
|
||||
text: qsTr("Preview")
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
StackLayout {
|
||||
Layout.fillWidth: true
|
||||
currentIndex: editPreviwTabBar.currentIndex
|
||||
|
||||
MyProfileSettingsView {
|
||||
id: settingsView
|
||||
Layout.fillWidth: true
|
||||
profileStore: root.profileStore
|
||||
privacyStore: root.privacyStore
|
||||
walletStore: root.walletStore
|
||||
}
|
||||
|
||||
MyProfilePreview {
|
||||
id: profilePreview
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: qrCodeButton
|
||||
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
icon.name: "qr"
|
||||
type: StatusFlatRoundButton.Type.Quaternary
|
||||
onClicked: qrCodePopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ProfileHeader {
|
||||
id: profileImgNameContainer
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
displayName: profileStore.name
|
||||
pubkey: profileStore.pubkey
|
||||
icon: profileStore.icon
|
||||
|
||||
displayNameVisible: false
|
||||
pubkeyVisible: false
|
||||
compact: false
|
||||
|
||||
imageOverlay: Item {
|
||||
StatusFlatRoundButton {
|
||||
width: 24
|
||||
height: 24
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
rightMargin: -8
|
||||
}
|
||||
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
icon.name: "pencil"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.width: 12.5
|
||||
icon.height: 12.5
|
||||
|
||||
onClicked: Global.openChangeProfilePicPopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
title: qsTr("ENS username")
|
||||
subTitle: root.profileStore.ensName
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
visible: !!root.profileStore.ensName
|
||||
iconButton.onClicked: {
|
||||
root.profileStore.copyToClipboard(root.profileStore.ensName)
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
title: qsTr("Chat key")
|
||||
subTitle: Utils.getCompressedPk(root.profileStore.pubkey)
|
||||
subTitleComponent.elide: Text.ElideMiddle
|
||||
subTitleComponent.width: 320
|
||||
subTitleComponent.font.family: Theme.palette.monoFont.name
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
root.profileStore.copyToClipboard(subTitle)
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
title: qsTr("Share Profile URL")
|
||||
subTitle: `${Constants.userLinkPrefix}${root.profileStore.ensName !== "" ? root.profileStore.ensName : (root.profileStore.pubkey.substring(0, 5) + "..." + root.profileStore.pubkey.substring(root.profileStore.pubkey.length - 5))}`
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
root.profileStore.copyToClipboard(Constants.userLinkPrefix + (root.profileStore.ensName !== "" ? root.profileStore.ensName : root.profileStore.pubkey))
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: displayNamePopupComponent
|
||||
DisplayNamePopup {
|
||||
profileStore: root.profileStore
|
||||
anchors.centerIn: Overlay.overlay
|
||||
onClosed: { destroy() }
|
||||
}
|
||||
}
|
||||
|
||||
ModalPopup {
|
||||
id: qrCodePopup
|
||||
width: 420
|
||||
height: 420
|
||||
Image {
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: root.profileStore.getQrCodeSource(root.profileStore.pubkey)
|
||||
anchors.verticalCenterOffset: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: 312
|
||||
width: 312
|
||||
mipmap: true
|
||||
smooth: false
|
||||
}
|
||||
ChangePasswordModal {
|
||||
id: changePasswordModal
|
||||
privacyStore: root.privacyStore
|
||||
anchors.centerIn: parent
|
||||
onPasswordChanged: successPopup.open()
|
||||
}
|
||||
|
||||
ChangePasswordSuccessModal {
|
||||
id: successPopup
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1 as StatusQControls
|
||||
|
||||
import "../popups"
|
||||
import "../stores"
|
||||
|
||||
SettingsContentBase {
|
||||
id: root
|
||||
|
||||
property PrivacyStore privacyStore
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Constants.settingsSection.itemSpacing
|
||||
width: root.contentWidth
|
||||
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Change password")
|
||||
implicitHeight: 52
|
||||
components: [
|
||||
StatusIcon {
|
||||
icon: "chevron-down"
|
||||
rotation: 270
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
sensor.onClicked: changePasswordModal.open()
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Store pass to Keychain")
|
||||
implicitHeight: 52
|
||||
visible: Qt.platform.os == "osx" // For now, this is available only on MacOS
|
||||
label: {
|
||||
let value = localAccountSettings.storeToKeychainValue
|
||||
if(value == Constants.storeToKeychainValueStore)
|
||||
return qsTr("Store")
|
||||
|
||||
if(value == Constants.storeToKeychainValueNever)
|
||||
return qsTr("Never")
|
||||
|
||||
return qsTr("Not now")
|
||||
}
|
||||
components: [
|
||||
StatusIcon {
|
||||
icon: "chevron-down"
|
||||
rotation: 270
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
]
|
||||
sensor.onClicked: Global.openPopup(storeToKeychainSelectionModal)
|
||||
|
||||
Component {
|
||||
id: storeToKeychainSelectionModal
|
||||
StoreToKeychainSelectionModal {
|
||||
privacyStore: root.privacyStore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChangePasswordModal {
|
||||
id: changePasswordModal
|
||||
privacyStore: root.privacyStore
|
||||
anchors.centerIn: parent
|
||||
|
||||
onPasswordChanged: successPopup.open()
|
||||
}
|
||||
|
||||
ChangePasswordSuccessModal {
|
||||
id: successPopup
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ import QtQuick.Controls 2.3
|
|||
import QtQuick.Layouts 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared.popups 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
@ -20,8 +21,17 @@ Item {
|
|||
property list<Item> headerComponents
|
||||
default property Item content
|
||||
|
||||
property bool dirty: false
|
||||
property bool saveChangesButtonEnabled: false
|
||||
|
||||
signal backButtonClicked()
|
||||
signal baseAreaClicked()
|
||||
signal saveChangesClicked()
|
||||
signal resetChangesClicked()
|
||||
|
||||
function notifyDirty() {
|
||||
settingsDirtyToastMessage.notifyDirty();
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
@ -90,21 +100,57 @@ Item {
|
|||
}
|
||||
|
||||
ScrollView {
|
||||
anchors.top: titleRow.visible? titleRow.bottom : topHeader.bottom
|
||||
id: scrollView
|
||||
anchors.top: titleRow.visible ? titleRow.bottom : topHeader.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: Style.current.bigPadding
|
||||
contentWidth: Math.max(contentWrapper.implicitWidth, width)
|
||||
contentHeight: Math.max(contentWrapper.implicitHeight, height)+anchors.topMargin
|
||||
width: root.contentWidth
|
||||
clip: true
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: { root.baseAreaClicked() }
|
||||
|
||||
Flickable {
|
||||
id: contentFliackable
|
||||
contentWidth: Math.max(contentLayout.implicitWidth, scrollView.width)
|
||||
contentHeight: Math.max(contentLayout.implicitHeight, scrollView.height) + scrollView.anchors.topMargin
|
||||
|
||||
Column {
|
||||
id: contentWrapper
|
||||
id: contentLayout
|
||||
anchors.fill: parent.contentItem
|
||||
|
||||
MouseArea {
|
||||
onClicked: root.baseAreaClicked()
|
||||
width: contentWrapper.implicitWidth
|
||||
height: contentWrapper.implicitHeight
|
||||
|
||||
Column {
|
||||
id: contentWrapper
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
// This is a settingsDirtyToastMessage placeholder
|
||||
width: settingsDirtyToastMessage.implicitWidth
|
||||
height: settingsDirtyToastMessage.active ? settingsDirtyToastMessage.implicitHeight : 0
|
||||
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: 150
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDirtyToastMessage {
|
||||
id: settingsDirtyToastMessage
|
||||
anchors.bottom: scrollView.bottom
|
||||
anchors.horizontalCenter: scrollView.horizontalCenter
|
||||
active: root.dirty
|
||||
flickable: contentFliackable
|
||||
saveChangesButtonEnabled: root.saveChangesButtonEnabled
|
||||
onResetChangesClicked: root.resetChangesClicked()
|
||||
onSaveChangesClicked: root.saveChangesClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.14
|
||||
|
||||
import shared.views 1.0 as SharedViews
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Item {
|
||||
property alias profileStore: profilePreview.profileStore
|
||||
|
||||
implicitHeight: profilePreview.implicitHeight
|
||||
+ profilePreview.anchors.topMargin
|
||||
+ profilePreview.anchors.bottomMargin
|
||||
|
||||
implicitWidth: profilePreview.implicitWidth
|
||||
+ profilePreview.anchors.leftMargin
|
||||
+ profilePreview.anchors.rightMargin
|
||||
|
||||
SharedViews.ProfileView {
|
||||
id: profilePreview
|
||||
anchors.fill: parent
|
||||
anchors.margins: 24
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: shadow
|
||||
anchors.fill: profilePreview
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 4
|
||||
radius: 16
|
||||
samples: 12
|
||||
color: "#40000000"
|
||||
source: profilePreview
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls.chat 1.0
|
||||
|
||||
import "../../popups"
|
||||
import "../../stores"
|
||||
import "../../controls"
|
||||
import "../../../Onboarding/shared" as OnboardingComponents
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property PrivacyStore privacyStore
|
||||
property ProfileStore profileStore
|
||||
property WalletStore walletStore
|
||||
|
||||
readonly property bool dirty: displayNameInput.text != profileStore.displayName
|
||||
|| biometricsSwitch.checked != biometricsSwitch.currentStoredValue
|
||||
|
||||
readonly property bool valid: !!displayNameInput.text && displayNameInput.valid
|
||||
|
||||
function reset() {
|
||||
displayNameInput.text = Qt.binding(() => { return profileStore.displayName })
|
||||
biometricsSwitch.checked = Qt.binding(() => { return biometricsSwitch.currentStoredValue })
|
||||
}
|
||||
|
||||
function save() {
|
||||
profileStore.setDisplayName(displayNameInput.text)
|
||||
|
||||
if (biometricsSwitch.checked)
|
||||
Global.openPopup(storePasswordModal)
|
||||
else
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueNever;
|
||||
}
|
||||
|
||||
function offerToStorePassword(password, runStoreToKeyChainPopup)
|
||||
{
|
||||
if (Qt.platform.os !== "osx")
|
||||
return;
|
||||
|
||||
localAccountSettings.storeToKeychainValue = Constants.storeToKeychainValueStore;
|
||||
root.privacyStore.storeToKeyChain(password);
|
||||
}
|
||||
|
||||
ProfileHeader {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
displayName: profileStore.name
|
||||
pubkey: profileStore.pubkey
|
||||
icon: profileStore.icon
|
||||
imageSize: ProfileHeader.ImageSize.Big
|
||||
|
||||
displayNameVisible: false
|
||||
pubkeyVisible: false
|
||||
emojiHashVisible: false
|
||||
editImageButtonVisible: true
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: displayNameInput
|
||||
Layout.fillWidth: true
|
||||
label: qsTr("Display name")
|
||||
input.placeholderText: qsTr("Display Name")
|
||||
charLimit: 24
|
||||
input.text: root.profileStore.displayName
|
||||
validators: Constants.validators.displayName
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
Layout.fillWidth: true
|
||||
visible: Qt.platform.os == "osx"
|
||||
title: qsTr("Biometric login and transaction authentication")
|
||||
icon.name: "touch-id"
|
||||
components: [ StatusSwitch {
|
||||
id: biometricsSwitch
|
||||
readonly property bool currentStoredValue: localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueStore
|
||||
checked: currentStoredValue
|
||||
} ]
|
||||
sensor.onClicked: biometricsSwitch.toggle()
|
||||
}
|
||||
|
||||
StatusTabBar {
|
||||
id: showcaseTabBar
|
||||
Layout.fillWidth: true
|
||||
|
||||
function validateCurrentIndex() {
|
||||
|
||||
let processedButtons = 0;
|
||||
|
||||
while (!itemAt(currentIndex).enabled) {
|
||||
if (++processedButtons == count) {
|
||||
currentIndex = -1;
|
||||
break;
|
||||
}
|
||||
currentIndex = (currentIndex + 1) % count;
|
||||
}
|
||||
}
|
||||
|
||||
StatusTabButton {
|
||||
enabled: localAccountSensitiveSettings.communitiesEnabled
|
||||
width: enabled ? implicitWidth : 0
|
||||
text: qsTr("Communities")
|
||||
onEnabledChanged: showcaseTabBar.validateCurrentIndex()
|
||||
}
|
||||
|
||||
StatusTabButton {
|
||||
enabled: localAccountSensitiveSettings.isWalletEnabled
|
||||
width: enabled ? implicitWidth : 0
|
||||
text: qsTr("Accounts")
|
||||
onEnabledChanged: showcaseTabBar.validateCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
Layout.fillWidth: true
|
||||
currentIndex: showcaseTabBar.currentIndex
|
||||
|
||||
Column {
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusBaseText {
|
||||
visible: communitiesRepeater.count == 0
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
text: qsTr("You haven't joined any communities yet")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: communitiesRepeater
|
||||
model: communitiesModule.model
|
||||
|
||||
CommunityDelegate {
|
||||
width: parent.width
|
||||
visible: joined
|
||||
community: model
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
StatusBaseText {
|
||||
visible: accountsRepeater.count == 0
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.directColor1
|
||||
text: qsTr("You don't have any wallet accounts yet")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: accountsRepeater
|
||||
model: root.walletStore.accounts
|
||||
|
||||
WalletAccountDelegate {
|
||||
width: parent.width
|
||||
account: model
|
||||
showShevronIcon: false
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: storePasswordModal
|
||||
|
||||
OnboardingComponents.CreatePasswordModal {
|
||||
privacyStore: root.privacyStore
|
||||
storingPasswordModal: true
|
||||
onOfferToStorePassword: {
|
||||
root.offerToStorePassword(password, runStoreToKeychainPopup)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -98,7 +98,7 @@ Item {
|
|||
}
|
||||
onOpenChangeProfilePicPopup: {
|
||||
var popup = changeProfilePicComponent.createObject(appMain);
|
||||
popup.open();
|
||||
popup.chooseImageToCrop();
|
||||
}
|
||||
onOpenBackUpSeedPopup: {
|
||||
var popup = backupSeedModalComponent.createObject(appMain)
|
||||
|
@ -196,8 +196,16 @@ Item {
|
|||
}
|
||||
|
||||
property Component changeProfilePicComponent: Component {
|
||||
ChangeProfilePicModal {
|
||||
profileStore: appMain.rootStore.profileSectionStore.profileStore
|
||||
ImageCropWorkflow {
|
||||
title: qsTr("Profile Picture")
|
||||
acceptButtonText: qsTr("Make this my Profile Pic")
|
||||
onImageCropped: {
|
||||
appMain.rootStore.profileSectionStore.profileStore.uploadImage(image,
|
||||
cropRect.x.toFixed(),
|
||||
cropRect.y.toFixed(),
|
||||
(cropRect.x + cropRect.width).toFixed(),
|
||||
(cropRect.y + cropRect.height).toFixed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,27 +5,47 @@ import utils 1.0
|
|||
import shared.panels 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
enum ImageSize {
|
||||
Compact,
|
||||
Middle,
|
||||
Big
|
||||
}
|
||||
|
||||
property string displayName
|
||||
property string pubkey
|
||||
property string icon
|
||||
|
||||
property bool compact: true
|
||||
property int imageSize: ProfileHeader.ImageSize.Compact
|
||||
property bool displayNameVisible: true
|
||||
property bool pubkeyVisible: true
|
||||
|
||||
property alias imageOverlay: imageOverlay.sourceComponent
|
||||
property bool emojiHashVisible: true
|
||||
property bool editImageButtonVisible: false
|
||||
readonly property bool compact: root.imageSize == ProfileHeader.ImageSize.Compact
|
||||
|
||||
signal clicked()
|
||||
|
||||
height: visible ? contentContainer.height : 0
|
||||
implicitHeight: contentContainer.implicitHeight
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
function getSize(compact, normal, big) {
|
||||
switch(root.imageSize) {
|
||||
case ProfileHeader.ImageSize.Compact: return compact;
|
||||
case ProfileHeader.ImageSize.Middle: return normal;
|
||||
case ProfileHeader.ImageSize.Big: return big;
|
||||
return normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: contentContainer
|
||||
|
||||
|
@ -38,21 +58,36 @@ Item {
|
|||
rightMargin: Style.current.smallPadding
|
||||
}
|
||||
|
||||
UserImage {
|
||||
id: userImage
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: userImage.width
|
||||
implicitHeight: userImage.height
|
||||
|
||||
name: root.displayName
|
||||
pubkey: root.pubkey
|
||||
image: root.icon
|
||||
interactive: false
|
||||
imageWidth: root.compact ? 36 : 80
|
||||
imageHeight: imageWidth
|
||||
UserImage {
|
||||
id: userImage
|
||||
name: root.displayName
|
||||
pubkey: root.pubkey
|
||||
image: root.icon
|
||||
interactive: false
|
||||
imageWidth: d.getSize(36, 80, 160)
|
||||
imageHeight: imageWidth
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: imageOverlay
|
||||
anchors.fill: parent
|
||||
StatusRoundButton {
|
||||
visible: root.editImageButtonVisible
|
||||
anchors.bottom: userImage.bottom
|
||||
anchors.right: userImage.right
|
||||
anchors.rightMargin: Math.round(userImage.width / 10)
|
||||
|
||||
width: d.getSize(10, 24, 40)
|
||||
height: width
|
||||
|
||||
type: StatusRoundButton.Type.Secondary
|
||||
icon.name: "edit_pencil"
|
||||
icon.width: d.getSize(8, 12, 20)
|
||||
icon.height: d.getSize(8, 12, 20)
|
||||
|
||||
onClicked: Global.openChangeProfilePicPopup()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,9 +122,8 @@ Item {
|
|||
|
||||
EmojiHash {
|
||||
id: emojiHash
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
visible: root.emojiHashVisible
|
||||
publicKey: root.pubkey
|
||||
size: root.compact ? 16 : 20
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import utils 1.0
|
|||
import shared 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.stores 1.0
|
||||
import shared.views 1.0 as SharedViews
|
||||
import shared.controls.chat 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
@ -29,23 +30,18 @@ StatusModal {
|
|||
property string userNickname: ""
|
||||
property string userEnsName: ""
|
||||
property string userIcon: ""
|
||||
property string text: ""
|
||||
|
||||
property bool userIsEnsVerified: false
|
||||
property bool userIsBlocked: false
|
||||
property bool isCurrentUser: false
|
||||
property bool isAddedContact: false
|
||||
|
||||
signal blockButtonClicked(name: string, address: string)
|
||||
signal unblockButtonClicked(name: string, address: string)
|
||||
signal removeButtonClicked(address: string)
|
||||
|
||||
signal contactUnblocked(publicKey: string)
|
||||
signal contactBlocked(publicKey: string)
|
||||
|
||||
function openPopup(publicKey, state = "") {
|
||||
// All this should be improved more, but for now we leave it like this.
|
||||
let contactDetails = Utils.getContactDetailsAsJson(publicKey);
|
||||
const contactDetails = Utils.getContactDetailsAsJson(publicKey);
|
||||
userPublicKey = publicKey;
|
||||
userDisplayName = contactDetails.displayName;
|
||||
userName = contactDetails.alias;
|
||||
|
@ -55,9 +51,8 @@ StatusModal {
|
|||
userIsEnsVerified = contactDetails.ensVerified;
|
||||
userIsBlocked = contactDetails.isBlocked;
|
||||
isAddedContact = contactDetails.isContact;
|
||||
|
||||
text = ""; // this is most likely unneeded
|
||||
isCurrentUser = popup.profileStore.pubkey === publicKey;
|
||||
|
||||
showFooter = !isCurrentUser;
|
||||
popup.open();
|
||||
|
||||
|
@ -73,20 +68,21 @@ StatusModal {
|
|||
}
|
||||
|
||||
function blockUser() {
|
||||
contentItem.blockContactConfirmationDialog.contactName = userName;
|
||||
contentItem.blockContactConfirmationDialog.contactAddress = userPublicKey;
|
||||
contentItem.blockContactConfirmationDialog.open();
|
||||
profileView.blockContactConfirmationDialog.contactName = userName;
|
||||
profileView.blockContactConfirmationDialog.contactAddress = userPublicKey;
|
||||
profileView.blockContactConfirmationDialog.open();
|
||||
}
|
||||
|
||||
function unblockUser() {
|
||||
contentItem.unblockContactConfirmationDialog.contactName = userName;
|
||||
contentItem.unblockContactConfirmationDialog.contactAddress = userPublicKey;
|
||||
contentItem.unblockContactConfirmationDialog.open();
|
||||
profileView.unblockContactConfirmationDialog.contactName = userName;
|
||||
profileView.unblockContactConfirmationDialog.contactAddress = userPublicKey;
|
||||
profileView.unblockContactConfirmationDialog.open();
|
||||
}
|
||||
|
||||
header.title: userDisplayName + qsTr("'s Profile")
|
||||
header.subTitle: userIsEnsVerified ? userName : Utils.getElidedCompressedPk(userPublicKey)
|
||||
header.subTitleElide: Text.ElideMiddle
|
||||
padding: 8
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
@ -103,213 +99,47 @@ StatusModal {
|
|||
icon.width: 20
|
||||
icon.height: 20
|
||||
icon.name: "qr"
|
||||
onClicked: contentItem.qrCodePopup.open()
|
||||
onClicked: profileView.qrCodePopup.open()
|
||||
}
|
||||
|
||||
Component {
|
||||
id: contactTopComponent
|
||||
SharedViews.ProfileView {
|
||||
id: profileView
|
||||
anchors.fill: parent
|
||||
|
||||
ProfileHeader {
|
||||
displayName: popup.userDisplayName
|
||||
pubkey: popup.userPublicKey
|
||||
icon: popup.isCurrentUser ? popup.profileStore.icon : popup.userIcon
|
||||
profileStore: popup.profileStore
|
||||
contactsStore: popup.contactsStore
|
||||
|
||||
displayNameVisible: false
|
||||
pubkeyVisible: false
|
||||
compact: false
|
||||
userPublicKey: popup.userPublicKey
|
||||
userDisplayName: popup.userDisplayName
|
||||
userName: popup.userName
|
||||
userNickname: popup.userNickname
|
||||
userEnsName: popup.userEnsName
|
||||
userIcon: popup.userIcon
|
||||
userIsEnsVerified: popup.userIsEnsVerified
|
||||
userIsBlocked: popup.userIsBlocked
|
||||
isAddedContact: popup.isAddedContact
|
||||
isCurrentUser: popup.isCurrentUser
|
||||
|
||||
imageOverlay: Item {
|
||||
visible: popup.isCurrentUser
|
||||
|
||||
StatusFlatRoundButton {
|
||||
width: 24
|
||||
height: 24
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
rightMargin: -8
|
||||
}
|
||||
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
icon.name: "pencil"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.width: 12.5
|
||||
icon.height: 12.5
|
||||
|
||||
onClicked: Global.openChangeProfilePicPopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
id: modalContent
|
||||
|
||||
property alias qrCodePopup: qrCodePopup
|
||||
property alias unblockContactConfirmationDialog: unblockContactConfirmationDialog
|
||||
property alias blockContactConfirmationDialog: blockContactConfirmationDialog
|
||||
property alias removeContactConfirmationDialog: removeContactConfirmationDialog
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: d.contentMargins
|
||||
spacing: d.contentSpacing
|
||||
clip: true
|
||||
|
||||
Item {
|
||||
implicitHeight: d.contentSpacing
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Loader {
|
||||
sourceComponent: contactTopComponent
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBanner {
|
||||
visible: popup.userIsBlocked
|
||||
type: StatusBanner.Type.Danger
|
||||
statusText: qsTr("Blocked")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
title: userIsEnsVerified ?
|
||||
qsTr("ENS username") :
|
||||
qsTr("Username")
|
||||
subTitle: userIsEnsVerified ? userEnsName : userName
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
globalUtils.copyToClipboard(subTitle)
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
title: qsTr("Chat key")
|
||||
subTitle: Utils.getCompressedPk(userPublicKey)
|
||||
subTitleComponent.elide: Text.ElideMiddle
|
||||
subTitleComponent.width: 320
|
||||
subTitleComponent.font.family: Theme.palette.monoFont.name
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
globalUtils.copyToClipboard(subTitle)
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
title: qsTr("Share Profile URL")
|
||||
subTitle: {
|
||||
|
||||
let user = ""
|
||||
if (isCurrentUser) {
|
||||
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName :
|
||||
(popup.profileStore.pubkey.substring(0, 5) + "..." + popup.profileStore.pubkey.substring(popup.profileStore.pubkey.length - 5))
|
||||
} else if (userIsEnsVerified) {
|
||||
user = userEnsName
|
||||
}
|
||||
|
||||
if (user === ""){
|
||||
user = userPublicKey.substr(0, 4) + "..." + userPublicKey.substr(userPublicKey.length - 5)
|
||||
}
|
||||
return Constants.userLinkPrefix + user;
|
||||
}
|
||||
tooltip.text: qsTr("Copy to clipboard")
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
let user = ""
|
||||
if (isCurrentUser) {
|
||||
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName : popup.profileStore.pubkey
|
||||
} else {
|
||||
user = (userEnsName !== "" ? userEnsName : userPublicKey)
|
||||
}
|
||||
popup.profileStore.copyToClipboard(Constants.userLinkPrefix + user)
|
||||
tooltip.visible = !tooltip.visible
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
visible: !isCurrentUser
|
||||
title: qsTr("Chat settings")
|
||||
subTitle: qsTr("Nickname")
|
||||
value: userNickname ? userNickname : qsTr("None")
|
||||
sensor.enabled: true
|
||||
sensor.onClicked: {
|
||||
nicknamePopup.open()
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with StatusStackModal
|
||||
ModalPopup {
|
||||
id: qrCodePopup
|
||||
width: 320
|
||||
height: 320
|
||||
Image {
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: globalUtils.qrCode(userPublicKey)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 212
|
||||
width: 212
|
||||
mipmap: true
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
UnblockContactConfirmationDialog {
|
||||
id: unblockContactConfirmationDialog
|
||||
onUnblockButtonClicked: {
|
||||
popup.contactsStore.unblockContact(userPublicKey)
|
||||
unblockContactConfirmationDialog.close();
|
||||
onContactUnblocked: {
|
||||
popup.close()
|
||||
popup.contactUnblocked(userPublicKey)
|
||||
popup.contactUnblocked(publicKey)
|
||||
}
|
||||
}
|
||||
|
||||
BlockContactConfirmationDialog {
|
||||
id: blockContactConfirmationDialog
|
||||
onBlockButtonClicked: {
|
||||
popup.contactsStore.blockContact(userPublicKey)
|
||||
blockContactConfirmationDialog.close();
|
||||
onContactBlocked: {
|
||||
popup.close()
|
||||
|
||||
popup.contactBlocked(userPublicKey)
|
||||
popup.contactBlocked(publicKey)
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmationDialog {
|
||||
id: removeContactConfirmationDialog
|
||||
header.title: qsTr("Remove contact")
|
||||
confirmationText: qsTr("Are you sure you want to remove this contact?")
|
||||
onConfirmButtonClicked: {
|
||||
if (isAddedContact) {
|
||||
popup.contactsStore.removeContact(userPublicKey);
|
||||
}
|
||||
removeContactConfirmationDialog.close();
|
||||
popup.close();
|
||||
onContactAdded: {
|
||||
popup.close()
|
||||
popup.contactAdded(publicKey)
|
||||
}
|
||||
}
|
||||
|
||||
NicknamePopup {
|
||||
id: nicknamePopup
|
||||
nickname: popup.userNickname
|
||||
header.subTitle: popup.header.subTitle
|
||||
header.subTitleElide: popup.header.subTitleElide
|
||||
onEditDone: {
|
||||
if(popup.userNickname !== newNickname)
|
||||
{
|
||||
popup.userNickname = newNickname;
|
||||
popup.contactsStore.changeContactNickname(userPublicKey, newNickname);
|
||||
}
|
||||
onContactRemoved: {
|
||||
popup.close()
|
||||
}
|
||||
|
||||
onNicknameEdited: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +152,9 @@ StatusModal {
|
|||
height: popup.height
|
||||
visible: false
|
||||
header.title: qsTr("Send Contact Request to") + " " + userDisplayName
|
||||
topComponent: contactTopComponent
|
||||
userPublicKey: popup.userPublicKey
|
||||
userDisplayName: popup.userDisplayName
|
||||
userIcon: popup.userIcon
|
||||
onAccepted: popup.contactsStore.sendContactRequest(userPublicKey, message)
|
||||
onClosed: popup.close()
|
||||
}
|
||||
|
@ -341,8 +173,8 @@ StatusModal {
|
|||
type: StatusBaseButton.Type.Danger
|
||||
text: qsTr('Remove Contact')
|
||||
onClicked: {
|
||||
contentItem.removeContactConfirmationDialog.parentPopup = popup;
|
||||
contentItem.removeContactConfirmationDialog.open();
|
||||
profileView.removeContactConfirmationDialog.parentPopup = popup;
|
||||
profileView.removeContactConfirmationDialog.open();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import QtQuick.Controls 2.14
|
|||
import QtQuick.Layouts 1.14
|
||||
|
||||
import utils 1.0
|
||||
import shared.controls.chat 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
@ -13,9 +14,13 @@ import StatusQ.Popups 0.1
|
|||
StatusModal {
|
||||
id: root
|
||||
|
||||
property string userPublicKey: ""
|
||||
property string userDisplayName: ""
|
||||
property string userIcon: ""
|
||||
|
||||
signal accepted(string message)
|
||||
|
||||
property alias topComponent: topComponentLoader.sourceComponent
|
||||
padding: 16
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
@ -24,19 +29,24 @@ StatusModal {
|
|||
readonly property int minMsgLength: 1
|
||||
readonly property int msgHeight: 152
|
||||
readonly property int contentSpacing: 5
|
||||
readonly property int contentMargins: 16
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: d.contentMargins
|
||||
anchors.fill: parent
|
||||
spacing: d.contentSpacing
|
||||
|
||||
Loader {
|
||||
id: topComponentLoader
|
||||
ProfileHeader {
|
||||
Layout.fillWidth: true
|
||||
|
||||
displayName: root.userDisplayName
|
||||
pubkey: root.userPublicKey
|
||||
icon: root.userIcon
|
||||
|
||||
displayNameVisible: false
|
||||
pubkeyVisible: false
|
||||
imageSize: ProfileHeader.ImageSize.Middle
|
||||
editImageButtonVisible: false
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
|
@ -65,4 +75,4 @@ StatusModal {
|
|||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property bool active: false
|
||||
property bool saveChangesButtonEnabled: false
|
||||
|
||||
property Flickable flickable: null
|
||||
|
||||
signal saveChangesClicked
|
||||
signal resetChangesClicked
|
||||
|
||||
function notifyDirty() {
|
||||
toastAlertAnimation.running = true
|
||||
saveChangesButton.forceActiveFocus()
|
||||
}
|
||||
|
||||
implicitHeight: toastContent.implicitHeight + toastContent.anchors.topMargin + toastContent.anchors.bottomMargin
|
||||
implicitWidth: toastContent.implicitWidth + toastContent.anchors.leftMargin + toastContent.anchors.rightMargin
|
||||
|
||||
opacity: active ? 1 : 0
|
||||
color: Theme.palette.statusToastMessage.backgroundColor
|
||||
radius: 8
|
||||
border.color: Theme.palette.dangerColor2
|
||||
border.width: 2
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: 3
|
||||
radius: 8
|
||||
samples: 15
|
||||
fast: true
|
||||
cached: true
|
||||
color: Theme.palette.dangerColor2
|
||||
spread: 0.1
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active || !flickable)
|
||||
return;
|
||||
|
||||
const item = Global.applicationWindow.activeFocusItem;
|
||||
const h1 = this.height;
|
||||
const y1 = this.mapToGlobal(0, 0).y;
|
||||
const h2 = item.height;
|
||||
const y2 = item.mapToGlobal(0, 0).y;
|
||||
const margin = 20;
|
||||
const offset = h2 - (y1 - y2);
|
||||
|
||||
if (offset <= 0)
|
||||
return;
|
||||
|
||||
toastFlickAnimation.from = flickable.contentY;
|
||||
toastFlickAnimation.to = flickable.contentY + offset + margin;
|
||||
toastFlickAnimation.start()
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: toastFlickAnimation
|
||||
target: root.flickable
|
||||
property: "contentY"
|
||||
duration: 150
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
|
||||
NumberAnimation on border.width {
|
||||
id: toastAlertAnimation
|
||||
from: 0
|
||||
to: 4
|
||||
loops: 2
|
||||
duration: 600
|
||||
onFinished: root.border.width = 2
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
visible: root.active // This is required not to change cursorShape
|
||||
enabled: root.active
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: toastContent
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 16
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
padding: 8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: Theme.palette.directColor1
|
||||
text: qsTr("Changes detected")
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: qsTr("Cancel")
|
||||
enabled: root.active
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: root.resetChangesClicked()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: saveChangesButton
|
||||
enabled: root.active && root.saveChangesButtonEnabled
|
||||
text: qsTr("Save changes")
|
||||
onClicked: root.saveChangesClicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
ChatCommandsPopup 1.0 ChatCommandsPopup.qml
|
||||
BlockContactConfirmationDialog 1.0 BlockContactConfirmationDialog.qml
|
||||
SettingsDirtyToastMessage 1.0 SettingsDirtyToastMessage.qml
|
||||
ConfirmationDialog 1.0 ConfirmationDialog.qml
|
||||
CommunityIntroDialog 1.0 CommunityIntroDialog.qml
|
||||
DownloadModal 1.0 DownloadModal.qml
|
||||
DownloadPage 1.0 DownloadPage.qml
|
||||
ImageCropperModal 1.0 ImageCropperModal.qml
|
||||
InviteFriendsPopup 1.0 InviteFriendsPopup.qml
|
||||
NicknamePopup 1.0 NicknamePopup.qml
|
||||
ModalPopup 1.0 ModalPopup.qml
|
||||
PopupMenu 1.0 PopupMenu.qml
|
||||
SendModal 1.0 SendModal.qml
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.stores 1.0
|
||||
import shared.controls.chat 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property Popup parentPopup
|
||||
|
||||
property var profileStore
|
||||
property var contactsStore
|
||||
|
||||
property string userPublicKey: profileStore.pubkey
|
||||
property string userDisplayName: profileStore.displayName
|
||||
property string userName: profileStore.username
|
||||
property string userNickname: profileStore.details.localNickname
|
||||
property string userEnsName: profileStore.ensName
|
||||
property string userIcon: profileStore.profileLargeImage
|
||||
property string text: ""
|
||||
|
||||
property bool userIsEnsVerified: profileStore.details.ensVerified
|
||||
property bool userIsBlocked: profileStore.details.isBlocked
|
||||
property bool isCurrentUser: profileStore.pubkey === userPublicKey
|
||||
property bool isAddedContact: false
|
||||
|
||||
readonly property alias qrCodePopup: qrCodePopup
|
||||
readonly property alias unblockContactConfirmationDialog: unblockContactConfirmationDialog
|
||||
readonly property alias blockContactConfirmationDialog: blockContactConfirmationDialog
|
||||
readonly property alias removeContactConfirmationDialog: removeContactConfirmationDialog
|
||||
|
||||
signal contactUnblocked(publicKey: string)
|
||||
signal contactBlocked(publicKey: string)
|
||||
signal contactAdded(publicKey: string)
|
||||
signal contactRemoved(publicKey: string)
|
||||
signal nicknameEdited(publicKey: string)
|
||||
|
||||
implicitWidth: modalContent.implicitWidth
|
||||
implicitHeight: modalContent.implicitHeight
|
||||
|
||||
color: Theme.palette.statusAppLayout.backgroundColor
|
||||
radius: 8
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property string subTitle: root.userIsEnsVerified ? root.userName : Utils.getElidedCompressedPk(userPublicKey)
|
||||
readonly property int subTitleElide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: modalContent
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 16
|
||||
}
|
||||
|
||||
ProfileHeader {
|
||||
Layout.fillWidth: true
|
||||
|
||||
displayName: root.userDisplayName
|
||||
pubkey: root.userPublicKey
|
||||
icon: root.isCurrentUser ? root.profileStore.icon : root.userIcon
|
||||
|
||||
displayNameVisible: false
|
||||
pubkeyVisible: false
|
||||
imageSize: ProfileHeader.ImageSize.Middle
|
||||
editImageButtonVisible: root.isCurrentUser
|
||||
}
|
||||
|
||||
StatusBanner {
|
||||
Layout.fillWidth: true
|
||||
visible: root.userIsBlocked
|
||||
type: StatusBanner.Type.Danger
|
||||
statusText: qsTr("Blocked")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 16
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
title: root.userIsEnsVerified ? qsTr("ENS username") : qsTr("Username")
|
||||
subTitle: root.userIsEnsVerified ? root.userEnsName : root.userName
|
||||
tooltip.text: qsTr("Copied to clipboard")
|
||||
tooltip.timeout: 1000
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
globalUtils.copyToClipboard(subTitle)
|
||||
tooltip.open();
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Chat key")
|
||||
subTitle: Utils.getCompressedPk(root.userPublicKey)
|
||||
subTitleComponent.elide: Text.ElideMiddle
|
||||
subTitleComponent.width: 320
|
||||
subTitleComponent.font.family: Theme.palette.monoFont.name
|
||||
tooltip.text: qsTr("Copied to clipboard")
|
||||
tooltip.timeout: 1000
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
globalUtils.copyToClipboard(subTitle)
|
||||
tooltip.open();
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Share Profile URL")
|
||||
subTitle: {
|
||||
let user = ""
|
||||
if (isCurrentUser) {
|
||||
user = root.profileStore.ensName !== "" ? root.profileStore.ensName
|
||||
: (root.profileStore.pubkey.substring(0, 5) + "..." + root.profileStore.pubkey.substring(root.profileStore.pubkey.length - 5))
|
||||
} else if (userIsEnsVerified) {
|
||||
user = userEnsName
|
||||
}
|
||||
|
||||
if (user === ""){
|
||||
user = userPublicKey.substr(0, 4) + "..." + userPublicKey.substr(userPublicKey.length - 5)
|
||||
}
|
||||
return Constants.userLinkPrefix + user;
|
||||
}
|
||||
tooltip.text: qsTr("Copied to clipboard")
|
||||
tooltip.timeout: 1000
|
||||
icon.name: "copy"
|
||||
iconButton.onClicked: {
|
||||
let user = ""
|
||||
if (isCurrentUser) {
|
||||
user = root.profileStore.ensName !== "" ? root.profileStore.ensName : root.profileStore.pubkey
|
||||
} else {
|
||||
user = (userEnsName !== "" ? userEnsName : userPublicKey)
|
||||
}
|
||||
root.profileStore.copyToClipboard(Constants.userLinkPrefix + user)
|
||||
tooltip.open();
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescriptionListItem {
|
||||
Layout.fillWidth: true
|
||||
visible: !isCurrentUser
|
||||
title: qsTr("Chat settings")
|
||||
subTitle: qsTr("Nickname")
|
||||
value: userNickname ? userNickname : qsTr("None")
|
||||
sensor.enabled: true
|
||||
sensor.onClicked: {
|
||||
nicknamePopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
visible: !isCurrentUser
|
||||
implicitHeight: 16
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
id: qrCodePopup
|
||||
width: 320
|
||||
height: 320
|
||||
Image {
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: globalUtils.qrCode(userPublicKey)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 212
|
||||
width: 212
|
||||
mipmap: true
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
UnblockContactConfirmationDialog {
|
||||
id: unblockContactConfirmationDialog
|
||||
onUnblockButtonClicked: {
|
||||
root.contactsStore.unblockContact(userPublicKey)
|
||||
unblockContactConfirmationDialog.close();
|
||||
root.contactUnblocked(userPublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
BlockContactConfirmationDialog {
|
||||
id: blockContactConfirmationDialog
|
||||
onBlockButtonClicked: {
|
||||
root.contactsStore.blockContact(userPublicKey)
|
||||
blockContactConfirmationDialog.close();
|
||||
root.contactBlocked(userPublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmationDialog {
|
||||
id: removeContactConfirmationDialog
|
||||
header.title: qsTr("Remove contact")
|
||||
confirmationText: qsTr("Are you sure you want to remove this contact?")
|
||||
onConfirmButtonClicked: {
|
||||
if (isAddedContact) {
|
||||
root.contactsStore.removeContact(userPublicKey);
|
||||
}
|
||||
removeContactConfirmationDialog.close();
|
||||
root.contactRemoved(userPublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
NicknamePopup {
|
||||
id: nicknamePopup
|
||||
nickname: root.userNickname
|
||||
header.subTitle: d.subTitle
|
||||
header.subTitleElide: d.subTitleElide
|
||||
onEditDone: {
|
||||
if (root.userNickname !== newNickname)
|
||||
{
|
||||
root.userNickname = newNickname;
|
||||
root.contactsStore.changeContactNickname(userPublicKey, newNickname);
|
||||
}
|
||||
root.nicknameEdited(userPublicKey)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,5 +6,6 @@ TransactionPreview 1.0 TransactionPreview.qml
|
|||
TransactionSigner 1.0 TransactionSigner.qml
|
||||
TransactionStackView 1.0 TransactionStackView.qml
|
||||
PasswordView 1.0 PasswordView.qml
|
||||
ProfileView 1.0 ProfileView.qml
|
||||
AssetsView 1.0 AssetsView.qml
|
||||
HistoryView 1.0 HistoryView.qml
|
||||
|
|
|
@ -37,17 +37,16 @@ QtObject {
|
|||
property int ensUsernames: 2
|
||||
property int messaging: 3
|
||||
property int wallet: 4
|
||||
property int privacyAndSecurity: 5
|
||||
property int appearance: 6
|
||||
property int language: 7
|
||||
property int notifications: 8
|
||||
property int devicesSettings: 9
|
||||
property int browserSettings: 10
|
||||
property int advanced: 11
|
||||
property int about: 12
|
||||
property int communitiesSettings: 13
|
||||
property int signout: 14
|
||||
property int backUpSeed: 15
|
||||
property int appearance: 5
|
||||
property int language: 6
|
||||
property int notifications: 7
|
||||
property int devicesSettings: 8
|
||||
property int browserSettings: 9
|
||||
property int advanced: 10
|
||||
property int about: 11
|
||||
property int communitiesSettings: 12
|
||||
property int signout: 13
|
||||
property int backUpSeed: 14
|
||||
}
|
||||
|
||||
readonly property QtObject userStatus: QtObject{
|
||||
|
|
Loading…
Reference in New Issue