2024-10-15 19:26:12 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
import StatusQ.Controls.Validators 0.1
|
|
|
|
|
|
|
|
import utils 1.0
|
2024-08-01 00:35:19 +00:00
|
|
|
import StatusQ 0.1
|
|
|
|
import SortFilterProxyModel 0.2
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
import "../stores"
|
|
|
|
import "../panels"
|
2023-08-04 12:41:57 +00:00
|
|
|
import "../../common"
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
Item {
|
|
|
|
id: root
|
|
|
|
|
|
|
|
property AddAccountStore store
|
|
|
|
|
2024-08-05 08:18:17 +00:00
|
|
|
signal watchOnlyAccountsLimitReached()
|
|
|
|
signal keypairLimitReached()
|
|
|
|
|
2023-03-22 15:48:44 +00:00
|
|
|
implicitHeight: layout.implicitHeight
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
2023-05-22 15:55:47 +00:00
|
|
|
if (root.store.addAccountModule.selectedColorId === "") {
|
2023-03-22 15:48:44 +00:00
|
|
|
colorSelection.selectedColorIndex = Math.floor(Math.random() * colorSelection.model.length)
|
|
|
|
}
|
|
|
|
else {
|
2023-12-29 13:10:55 +00:00
|
|
|
let ind = Utils.getColorIndexForId(root.store.addAccountModule.selectedColorId)
|
2023-03-22 15:48:44 +00:00
|
|
|
colorSelection.selectedColorIndex = ind
|
|
|
|
}
|
|
|
|
|
|
|
|
if (root.store.addAccountModule.selectedEmoji === "") {
|
2024-08-15 17:36:32 +00:00
|
|
|
// TODO: Reuse status-go RandomWalletEmoji
|
2023-03-22 15:48:44 +00:00
|
|
|
root.store.addAccountModule.selectedEmoji = StatusQUtils.Emoji.getRandomEmoji(StatusQUtils.Emoji.size.verySmall)
|
|
|
|
}
|
|
|
|
|
|
|
|
accountName.text = root.store.addAccountModule.accountName
|
2024-03-19 20:02:16 +00:00
|
|
|
if (root.store.addAccountModule.selectedEmoji !== "") {
|
2023-12-08 13:52:15 +00:00
|
|
|
accountName.input.asset.emoji = root.store.addAccountModule.selectedEmoji;
|
|
|
|
} else {
|
|
|
|
accountName.input.asset.isLetterIdenticon = true;
|
|
|
|
}
|
2024-03-19 20:02:16 +00:00
|
|
|
|
2023-03-22 15:48:44 +00:00
|
|
|
accountName.input.edit.forceActiveFocus()
|
2023-04-13 11:31:04 +00:00
|
|
|
accountName.validate(true)
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: d
|
2023-12-08 13:52:15 +00:00
|
|
|
readonly property bool isEdit: root.store.editMode
|
2023-03-22 15:48:44 +00:00
|
|
|
|
2024-08-01 00:35:19 +00:00
|
|
|
readonly property SortFilterProxyModel originModelWithoutWatchOnlyAcc: SortFilterProxyModel {
|
|
|
|
id: originModelWithoutWatchOnlyAcc
|
|
|
|
objectName: "originModelWithoutWatchOnlyAcc"
|
|
|
|
sourceModel: root.store.originModel
|
|
|
|
|
|
|
|
readonly property string addWatchOnlyAccKeyUid: Constants.appTranslatableConstants.addAccountLabelOptionAddWatchOnlyAcc
|
|
|
|
filters: [
|
|
|
|
FastExpressionFilter {
|
2024-08-05 09:24:48 +00:00
|
|
|
enabled: production
|
2024-08-01 00:35:19 +00:00
|
|
|
expression: model.keyPair.keyUid !== originModelWithoutWatchOnlyAcc.addWatchOnlyAccKeyUid
|
|
|
|
expectedRoles: ["keyPair"]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2023-03-28 13:47:54 +00:00
|
|
|
function openEmojiPopup(showLeft) {
|
|
|
|
if (!root.store.emojiPopup) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
let inputCoords = accountName.mapToItem(appMain, 0, 0)
|
|
|
|
root.store.emojiPopup.open()
|
|
|
|
root.store.emojiPopup.emojiSize = StatusQUtils.Emoji.size.verySmall
|
|
|
|
root.store.emojiPopup.x = inputCoords.x
|
|
|
|
if (!showLeft) {
|
|
|
|
root.store.emojiPopup.x += accountName.width - root.store.emojiPopup.width
|
|
|
|
}
|
2024-10-15 19:26:12 +00:00
|
|
|
root.store.emojiPopup.y = inputCoords.y + accountName.height + Theme.halfPadding
|
2023-03-28 13:47:54 +00:00
|
|
|
}
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
target: root.store.emojiPopup
|
|
|
|
|
|
|
|
function onEmojiSelected (emojiText, atCursor) {
|
2023-10-12 16:20:55 +00:00
|
|
|
let emoji = StatusQUtils.Emoji.deparse(emojiText)
|
|
|
|
root.store.addAccountModule.selectedEmoji = emoji
|
2023-12-08 13:52:15 +00:00
|
|
|
accountName.input.asset.isLetterIdenticon = false
|
|
|
|
accountName.input.asset.emoji = emojiText
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: spacer
|
|
|
|
Rectangle {
|
|
|
|
color: Theme.palette.baseColor4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
id: layout
|
|
|
|
width: parent.width
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
Loader {
|
2024-10-15 19:26:12 +00:00
|
|
|
Layout.preferredHeight: Theme.padding
|
2023-03-22 15:48:44 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
sourceComponent: spacer
|
|
|
|
}
|
|
|
|
|
|
|
|
Column {
|
|
|
|
Layout.fillWidth: true
|
2024-10-15 19:26:12 +00:00
|
|
|
spacing: Theme.padding
|
|
|
|
topPadding: Theme.padding
|
|
|
|
bottomPadding: Theme.padding
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
StatusInput {
|
|
|
|
id: accountName
|
2023-04-13 10:27:56 +00:00
|
|
|
objectName: "AddAccountPopup-AccountName"
|
2023-03-22 15:48:44 +00:00
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
2024-03-04 08:57:40 +00:00
|
|
|
placeholderText: qsTr("Account name")
|
2023-03-22 15:48:44 +00:00
|
|
|
label: qsTr("Name")
|
2023-04-13 11:31:04 +00:00
|
|
|
charLimit: 20
|
2023-03-22 15:48:44 +00:00
|
|
|
text: root.store.addAccountModule.accountName
|
|
|
|
input.isIconSelectable: true
|
2024-10-15 19:26:12 +00:00
|
|
|
input.leftPadding: Theme.padding
|
2023-05-22 15:55:47 +00:00
|
|
|
input.asset.color: Utils.getColorForId(root.store.addAccountModule.selectedColorId)
|
2023-03-22 15:48:44 +00:00
|
|
|
onIconClicked: {
|
2023-03-28 13:47:54 +00:00
|
|
|
d.openEmojiPopup(true)
|
|
|
|
}
|
|
|
|
input.rightComponent: StatusFlatRoundButton {
|
2023-04-13 10:27:56 +00:00
|
|
|
objectName: "AddAccountPopup-AccountEmoji"
|
2023-03-28 13:47:54 +00:00
|
|
|
width: 30
|
|
|
|
height: 30
|
|
|
|
radius: 30
|
|
|
|
icon.name: "emojis"
|
|
|
|
icon.width: 24
|
|
|
|
icon.height: 24
|
|
|
|
onClicked: {
|
|
|
|
d.openEmojiPopup(false)
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-13 11:31:04 +00:00
|
|
|
validators: [
|
|
|
|
StatusMinLengthValidator {
|
2024-02-05 10:04:20 +00:00
|
|
|
errorMessage: qsTr("Account name must be at least %n character(s)", "", Constants.addAccountPopup.keyPairAccountNameMinLength)
|
|
|
|
minLength: Constants.addAccountPopup.keyPairAccountNameMinLength
|
2023-04-13 11:31:04 +00:00
|
|
|
},
|
|
|
|
StatusRegularExpressionValidator {
|
2023-06-12 09:08:37 +00:00
|
|
|
regularExpression: Constants.regularExpressions.alphanumericalWithSpace
|
|
|
|
errorMessage: Constants.errorMessages.alphanumericalWithSpaceRegExp
|
2023-04-13 11:31:04 +00:00
|
|
|
}
|
|
|
|
]
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
onTextChanged: {
|
|
|
|
root.store.addAccountModule.accountName = text
|
2023-12-08 13:52:15 +00:00
|
|
|
if (input.asset.emoji === "") {
|
|
|
|
input.letterIconName = text;
|
|
|
|
}
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onKeyPressed: {
|
2023-08-04 12:41:57 +00:00
|
|
|
root.store.submitPopup(event)
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
2023-04-13 11:31:04 +00:00
|
|
|
|
|
|
|
onValidChanged: {
|
|
|
|
root.store.accountNameIsValid = accountName.valid
|
|
|
|
}
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusColorSelectorGrid {
|
|
|
|
id: colorSelection
|
2023-04-13 10:27:56 +00:00
|
|
|
objectName: "AddAccountPopup-AccountColor"
|
2023-03-22 15:48:44 +00:00
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
2023-05-22 15:55:47 +00:00
|
|
|
model: Theme.palette.customisationColorsArray
|
2023-03-22 15:48:44 +00:00
|
|
|
title.color: Theme.palette.directColor1
|
|
|
|
title.font.pixelSize: Constants.addAccountPopup.labelFontSize1
|
|
|
|
title.text: qsTr("Colour")
|
|
|
|
selectedColorIndex: -1
|
|
|
|
|
|
|
|
onSelectedColorChanged: {
|
2023-05-22 15:55:47 +00:00
|
|
|
root.store.addAccountModule.selectedColorId = Utils.getIdForColor(selectedColor)
|
2023-03-22 15:48:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectOrigin {
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
|
|
|
userProfilePublicKey: root.store.userProfilePublicKey
|
2024-08-01 00:35:19 +00:00
|
|
|
originModel: root.store.editMode? [] : d.originModelWithoutWatchOnlyAcc
|
2023-03-22 15:48:44 +00:00
|
|
|
selectedOrigin: root.store.selectedOrigin
|
2023-03-30 13:00:55 +00:00
|
|
|
caretVisible: !root.store.editMode
|
|
|
|
enabled: !root.store.editMode
|
2023-03-22 15:48:44 +00:00
|
|
|
|
|
|
|
onOriginSelected: {
|
2024-08-05 08:18:17 +00:00
|
|
|
if (keyUid === Constants.appTranslatableConstants.addAccountLabelOptionAddWatchOnlyAcc) {
|
|
|
|
if (root.store.remainingWatchOnlyAccountCapacity() === 0) {
|
|
|
|
root.watchOnlyAccountsLimitReached()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2023-03-22 15:48:44 +00:00
|
|
|
if (keyUid === Constants.appTranslatableConstants.addAccountLabelOptionAddNewMasterKey) {
|
2024-08-05 08:18:17 +00:00
|
|
|
if (root.store.remainingKeypairCapacity() === 0) {
|
|
|
|
root.keypairLimitReached()
|
|
|
|
return
|
|
|
|
}
|
2023-03-22 15:48:44 +00:00
|
|
|
root.store.currentState.doSecondaryAction()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
root.store.changeSelectedOrigin(keyUid)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WatchOnlyAddressSection {
|
2024-10-15 19:26:12 +00:00
|
|
|
width: parent.width - 2 * Theme.padding
|
2023-03-22 15:48:44 +00:00
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
2024-10-15 19:26:12 +00:00
|
|
|
spacing: Theme.padding
|
2023-03-30 13:00:55 +00:00
|
|
|
visible: !root.store.editMode &&
|
|
|
|
root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.unknown &&
|
2023-03-22 15:48:44 +00:00
|
|
|
root.store.selectedOrigin.keyUid === Constants.appTranslatableConstants.addAccountLabelOptionAddWatchOnlyAcc
|
|
|
|
|
|
|
|
store: root.store
|
|
|
|
|
|
|
|
onVisibleChanged: {
|
|
|
|
reset()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Loader {
|
2024-10-15 19:26:12 +00:00
|
|
|
Layout.preferredHeight: Theme.padding
|
2023-03-22 15:48:44 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
sourceComponent: spacer
|
|
|
|
}
|
|
|
|
|
|
|
|
DerivationPathSection {
|
|
|
|
id: derivationPathSection
|
|
|
|
Layout.fillWidth: true
|
|
|
|
visible: root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.profile ||
|
|
|
|
root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.seedImport
|
|
|
|
store: root.store
|
|
|
|
}
|
|
|
|
|
2023-03-24 14:03:47 +00:00
|
|
|
AddressWithAddressDetails {
|
|
|
|
id: addressWithDetails
|
|
|
|
Layout.fillWidth: true
|
2024-10-15 19:26:12 +00:00
|
|
|
Layout.margins: Theme.padding
|
|
|
|
spacing: Theme.halfPadding
|
2023-03-30 13:00:55 +00:00
|
|
|
visible: root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.privateKeyImport ||
|
|
|
|
root.store.editMode &&
|
|
|
|
root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.unknown &&
|
|
|
|
root.store.selectedOrigin.keyUid === Constants.appTranslatableConstants.addAccountLabelOptionAddWatchOnlyAcc
|
|
|
|
|
|
|
|
addressText: root.store.editMode? qsTr("Account") : qsTr("Public address of private key")
|
|
|
|
addressDetailsItem: root.store.selectedOrigin.pairType === Constants.addAccountPopup.keyPairType.privateKeyImport?
|
|
|
|
root.store.privateKeyAccAddress
|
|
|
|
: root.store.watchOnlyAccAddress
|
|
|
|
displayDetails: !root.store.editMode
|
|
|
|
displayCopyButton: root.store.editMode
|
|
|
|
addressColor: root.store.editMode? Theme.palette.baseColor1 : Theme.palette.directColor1
|
2023-03-24 14:03:47 +00:00
|
|
|
}
|
|
|
|
|
2023-03-22 15:48:44 +00:00
|
|
|
Loader {
|
2024-10-15 19:26:12 +00:00
|
|
|
Layout.preferredHeight: Theme.padding
|
2023-03-22 15:48:44 +00:00
|
|
|
Layout.fillWidth: true
|
2023-03-24 14:03:47 +00:00
|
|
|
visible: derivationPathSection.visible || addressWithDetails.visible
|
2023-03-22 15:48:44 +00:00
|
|
|
sourceComponent: spacer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|