mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-25 04:55:59 +00:00
bash: py: command not found
feat(@desktop/wallet): Add emoji to Wallet accounts. Support added to: 1. Wallet list 2. Adding a new account 3. Editing an account fixes #4926
This commit is contained in:
parent
aef8d0c4ab
commit
6e0471c943
@ -26,17 +26,17 @@ method init*(self: Controller) =
|
||||
method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||
return self.walletAccountService.getWalletAccounts()
|
||||
|
||||
method generateNewAccount*(self: Controller, password: string, accountName: string, color: string): string =
|
||||
return self.walletAccountService.generateNewAccount(password, accountName, color)
|
||||
method generateNewAccount*(self: Controller, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.walletAccountService.generateNewAccount(password, accountName, color, emoji)
|
||||
|
||||
method addAccountsFromPrivateKey*(self: Controller, privateKey: string, password: string, accountName: string, color: string): string =
|
||||
return self.walletAccountService.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
method addAccountsFromPrivateKey*(self: Controller, privateKey: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.walletAccountService.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
|
||||
|
||||
method addAccountsFromSeed*(self: Controller, seedPhrase: string, password: string, accountName: string, color: string): string =
|
||||
return self.walletAccountService.addAccountsFromSeed(seedPhrase, password, accountName, color)
|
||||
method addAccountsFromSeed*(self: Controller, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.walletAccountService.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
|
||||
|
||||
method addWatchOnlyAccount*(self: Controller, address: string, accountName: string, color: string): string =
|
||||
return self.walletAccountService.addWatchOnlyAccount(address, accountName, color)
|
||||
method addWatchOnlyAccount*(self: Controller, address: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.walletAccountService.addWatchOnlyAccount(address, accountName, color, emoji)
|
||||
|
||||
method deleteAccount*(self: Controller, address: string) =
|
||||
self.walletAccountService.deleteAccount(address)
|
||||
|
@ -13,16 +13,16 @@ method init*(self: AccessInterface) {.base.} =
|
||||
method getWalletAccounts*(self: AccessInterface): seq[wallet_account_service.WalletAccountDto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method generateNewAccount*(self: AccessInterface, password: string, accountName: string, color: string): string {.base.} =
|
||||
method generateNewAccount*(self: AccessInterface, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromPrivateKey*(self: AccessInterface, privateKey: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromPrivateKey*(self: AccessInterface, privateKey: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromSeed*(self: AccessInterface, seedPhrase: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromSeed*(self: AccessInterface, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addWatchOnlyAccount*(self: AccessInterface, address: string, accountName: string, color: string): string {.base.} =
|
||||
method addWatchOnlyAccount*(self: AccessInterface, address: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteAccount*(self: AccessInterface, address: string) {.base.} =
|
||||
|
@ -11,16 +11,16 @@ method load*(self: AccessInterface) {.base.} =
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method generateNewAccount*(self: AccessInterface, password: string, accountName: string, color: string): string {.base.} =
|
||||
method generateNewAccount*(self: AccessInterface, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromPrivateKey*(self: AccessInterface, privateKey: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromPrivateKey*(self: AccessInterface, privateKey: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromSeed*(self: AccessInterface, seedPhrase: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromSeed*(self: AccessInterface, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addWatchOnlyAccount*(self: AccessInterface, address: string, accountName: string, color: string): string {.base.} =
|
||||
method addWatchOnlyAccount*(self: AccessInterface, address: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteAccount*(self: AccessInterface, address: string) {.base.} =
|
||||
|
@ -13,6 +13,7 @@ type
|
||||
isChat: bool
|
||||
currencyBalance: float64
|
||||
assets: account_tokens.Model
|
||||
emoji: string
|
||||
|
||||
proc initItem*(
|
||||
name: string,
|
||||
@ -24,7 +25,8 @@ proc initItem*(
|
||||
isWallet: bool,
|
||||
isChat: bool,
|
||||
currencyBalance: float64,
|
||||
assets: account_tokens.Model
|
||||
assets: account_tokens.Model,
|
||||
emoji: string
|
||||
): Item =
|
||||
result.name = name
|
||||
result.address = address
|
||||
@ -36,6 +38,7 @@ proc initItem*(
|
||||
result.isChat = isChat
|
||||
result.currencyBalance = currencyBalance
|
||||
result.assets = assets
|
||||
result.emoji = emoji
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""WalletAccountItem(
|
||||
@ -49,6 +52,7 @@ proc `$`*(self: Item): string =
|
||||
isChat: {self.isChat},
|
||||
currencyBalance: {self.currencyBalance},
|
||||
assets.len: {self.assets.getCount()},
|
||||
emoji: {self.emoji}
|
||||
]"""
|
||||
|
||||
proc getName*(self: Item): string =
|
||||
@ -60,6 +64,9 @@ proc getAddress*(self: Item): string =
|
||||
proc getPath*(self: Item): string =
|
||||
return self.path
|
||||
|
||||
proc getEmoji*(self: Item): string =
|
||||
return self.emoji
|
||||
|
||||
proc getColor*(self: Item): string =
|
||||
return self.color
|
||||
|
||||
|
@ -13,7 +13,8 @@ type
|
||||
IsWallet,
|
||||
IsChat,
|
||||
CurrencyBalance,
|
||||
Assets
|
||||
Assets,
|
||||
Emoji
|
||||
|
||||
QtObject:
|
||||
type
|
||||
@ -58,7 +59,8 @@ QtObject:
|
||||
ModelRole.IsWallet.int:"isWallet",
|
||||
ModelRole.IsChat.int:"isChat",
|
||||
ModelRole.Assets.int:"assets",
|
||||
ModelRole.CurrencyBalance.int:"currencyBalance"
|
||||
ModelRole.CurrencyBalance.int:"currencyBalance",
|
||||
ModelRole.Emoji.int: "emoji"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
@ -92,6 +94,8 @@ QtObject:
|
||||
result = newQVariant(item.getCurrencyBalance())
|
||||
of ModelRole.Assets:
|
||||
result = newQVariant(item.getAssets())
|
||||
of ModelRole.Emoji:
|
||||
result = newQVariant(item.getEmoji())
|
||||
|
||||
proc setItems*(self: Model, items: seq[Item]) =
|
||||
self.beginResetModel()
|
||||
|
@ -62,7 +62,8 @@ method refreshWalletAccounts*(self: Module) =
|
||||
w.isWallet,
|
||||
w.isChat,
|
||||
w.getCurrencyBalance(),
|
||||
assets
|
||||
assets,
|
||||
w.emoji
|
||||
))
|
||||
|
||||
self.view.setItems(items)
|
||||
@ -100,17 +101,17 @@ method viewDidLoad*(self: Module) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.accountsModuleDidLoad()
|
||||
|
||||
method generateNewAccount*(self: Module, password: string, accountName: string, color: string): string =
|
||||
return self.controller.generateNewAccount(password, accountName, color)
|
||||
method generateNewAccount*(self: Module, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.controller.generateNewAccount(password, accountName, color, emoji)
|
||||
|
||||
method addAccountsFromPrivateKey*(self: Module, privateKey: string, password: string, accountName: string, color: string): string =
|
||||
return self.controller.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
method addAccountsFromPrivateKey*(self: Module, privateKey: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.controller.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
|
||||
|
||||
method addAccountsFromSeed*(self: Module, seedPhrase: string, password: string, accountName: string, color: string): string =
|
||||
return self.controller.addAccountsFromSeed(seedPhrase, password, accountName, color)
|
||||
method addAccountsFromSeed*(self: Module, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.controller.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
|
||||
|
||||
method addWatchOnlyAccount*(self: Module, address: string, accountName: string, color: string): string =
|
||||
return self.controller.addWatchOnlyAccount(address, accountName, color)
|
||||
method addWatchOnlyAccount*(self: Module, address: string, accountName: string, color: string, emoji: string): string =
|
||||
return self.controller.addWatchOnlyAccount(address, accountName, color, emoji)
|
||||
|
||||
method deleteAccount*(self: Module, address: string) =
|
||||
self.controller.deleteAccount(address)
|
||||
|
@ -103,17 +103,17 @@ QtObject:
|
||||
self.imported.setItems(imported)
|
||||
self.generated.setItems(generated)
|
||||
|
||||
proc generateNewAccount*(self: View, password: string, accountName: string, color: string): string {.slot.} =
|
||||
return self.delegate.generateNewAccount(password, accountName, color)
|
||||
proc generateNewAccount*(self: View, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
|
||||
return self.delegate.generateNewAccount(password, accountName, color, emoji)
|
||||
|
||||
proc addAccountsFromPrivateKey*(self: View, privateKey: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
return self.delegate.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
proc addAccountsFromPrivateKey*(self: View, privateKey: string, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
|
||||
return self.delegate.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
|
||||
|
||||
proc addAccountsFromSeed*(self: View, seedPhrase: string, password: string, accountName: string, color: string): string {.slot.} =
|
||||
return self.delegate.addAccountsFromSeed(seedPhrase, password, accountName, color)
|
||||
proc addAccountsFromSeed*(self: View, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
|
||||
return self.delegate.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
|
||||
|
||||
proc addWatchOnlyAccount*(self: View, address: string, accountName: string, color: string): string {.slot.} =
|
||||
return self.delegate.addWatchOnlyAccount(address, accountName, color)
|
||||
proc addWatchOnlyAccount*(self: View, address: string, accountName: string, color: string, emoji: string): string {.slot.} =
|
||||
return self.delegate.addWatchOnlyAccount(address, accountName, color, emoji)
|
||||
|
||||
proc deleteAccount*(self: View, address: string) {.slot.} =
|
||||
self.delegate.deleteAccount(address)
|
||||
|
@ -26,5 +26,5 @@ method init*(self: Controller) =
|
||||
method getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto =
|
||||
return self.walletAccountService.getWalletAccount(accountIndex)
|
||||
|
||||
method update*(self: Controller, address: string, accountName: string, color: string) =
|
||||
self.walletAccountService.updateWalletAccount(address, accountName, color)
|
||||
method update*(self: Controller, address: string, accountName: string, color: string, emoji: string) =
|
||||
self.walletAccountService.updateWalletAccount(address, accountName, color, emoji)
|
||||
|
@ -13,7 +13,7 @@ method init*(self: AccessInterface) {.base.} =
|
||||
method getWalletAccount*(self: AccessInterface, accountIndex: int): wallet_account_service.WalletAccountDto {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method update*(self: AccessInterface, address: string, accountName: string, color: string) {.base.} =
|
||||
method update*(self: AccessInterface, address: string, accountName: string, color: string, emoji: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
|
@ -14,7 +14,7 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method update*(self: AccessInterface, address: string, accountName: string, color: string) {.base.} =
|
||||
method update*(self: AccessInterface, address: string, accountName: string, color: string, emoji: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
|
@ -65,5 +65,5 @@ method switchAccount*(self: Module, accountIndex: int) =
|
||||
let walletAccount = self.controller.getWalletAccount(accountIndex)
|
||||
self.view.setData(walletAccount)
|
||||
|
||||
method update*(self: Module, address: string, accountName: string, color: string) =
|
||||
self.controller.update(address, accountName, color)
|
||||
method update*(self: Module, address: string, accountName: string, color: string, emoji: string) =
|
||||
self.controller.update(address, accountName, color, emoji)
|
||||
|
@ -18,6 +18,7 @@ QtObject:
|
||||
isChat: bool
|
||||
currencyBalance: float64
|
||||
assets: account_tokens.Model
|
||||
emoji: string
|
||||
|
||||
proc setup(self: View) =
|
||||
self.QObject.setup
|
||||
@ -114,8 +115,17 @@ QtObject:
|
||||
read = getAssets
|
||||
notify = assetsChanged
|
||||
|
||||
proc update(self: View, address: string, accountName: string, color: string) {.slot.} =
|
||||
self.delegate.update(address, accountName, color)
|
||||
proc getEmoji(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.emoji)
|
||||
|
||||
proc emojiChanged(self: View) {.signal.}
|
||||
|
||||
QtProperty[QVariant] emoji:
|
||||
read = getEmoji
|
||||
notify = emojiChanged
|
||||
|
||||
proc update(self: View, address: string, accountName: string, color: string, emoji: string) {.slot.} =
|
||||
self.delegate.update(address, accountName, color, emoji)
|
||||
|
||||
proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
|
||||
self.name = dto.name
|
||||
@ -134,6 +144,8 @@ proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
|
||||
self.isChatChanged()
|
||||
self.currencyBalance = dto.getCurrencyBalance()
|
||||
self.currencyBalanceChanged()
|
||||
self.emoji = dto.emoji
|
||||
self.emojiChanged()
|
||||
|
||||
let assets = account_tokens.newModel()
|
||||
|
||||
|
@ -25,6 +25,7 @@ type
|
||||
isWallet*: bool
|
||||
isChat*: bool
|
||||
tokens*: seq[WalletTokenDto]
|
||||
emoji*: string
|
||||
|
||||
proc newDto*(
|
||||
name: string,
|
||||
@ -34,7 +35,8 @@ proc newDto*(
|
||||
publicKey: string,
|
||||
walletType: string,
|
||||
isWallet: bool,
|
||||
isChat: bool
|
||||
isChat: bool,
|
||||
emoji: string
|
||||
): WalletAccountDto =
|
||||
return WalletAccountDto(
|
||||
name: name,
|
||||
@ -44,7 +46,8 @@ proc newDto*(
|
||||
publicKey: publicKey,
|
||||
walletType: walletType,
|
||||
isWallet: isWallet,
|
||||
isChat: isChat
|
||||
isChat: isChat,
|
||||
emoji: emoji
|
||||
)
|
||||
|
||||
proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
|
||||
@ -57,6 +60,7 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
|
||||
discard jsonObj.getProp("chat", result.isChat)
|
||||
discard jsonObj.getProp("public-key", result.publicKey)
|
||||
discard jsonObj.getProp("type", result.walletType)
|
||||
discard jsonObj.getProp("emoji", result.emoji)
|
||||
|
||||
proc getCurrencyBalance*(self: WalletAccountDto): float64 =
|
||||
return self.tokens.map(t => t.currencyBalance).foldl(a + b, 0.0)
|
||||
|
@ -244,49 +244,53 @@ method addNewAccountToLocalStore(self: Service) =
|
||||
self.accounts[newAccount.address] = newAccount
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountSaved(account: newAccount))
|
||||
|
||||
method generateNewAccount*(self: Service, password: string, accountName: string, color: string): string =
|
||||
method generateNewAccount*(self: Service, password: string, accountName: string, color: string, emoji: string): string =
|
||||
try:
|
||||
discard status_go_wallet.generateAccount(
|
||||
password,
|
||||
accountName,
|
||||
color)
|
||||
color,
|
||||
emoji)
|
||||
except Exception as e:
|
||||
return fmt"Error generating new account: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
|
||||
method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: string, accountName: string, color: string): string =
|
||||
method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
try:
|
||||
discard status_go_wallet.addAccountWithPrivateKey(
|
||||
privateKey,
|
||||
password,
|
||||
accountName,
|
||||
color,
|
||||
emoji
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with private key: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
|
||||
method addAccountsFromSeed*(self: Service, mnemonic: string, password: string, accountName: string, color: string): string =
|
||||
method addAccountsFromSeed*(self: Service, mnemonic: string, password: string, accountName: string, color: string, emoji: string): string =
|
||||
try:
|
||||
discard status_go_wallet.addAccountWithMnemonic(
|
||||
mnemonic,
|
||||
password,
|
||||
accountName,
|
||||
color,
|
||||
emoji
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with mnemonic: {e.msg}"
|
||||
|
||||
self.addNewAccountToLocalStore()
|
||||
|
||||
method addWatchOnlyAccount*(self: Service, address: string, accountName: string, color: string): string =
|
||||
method addWatchOnlyAccount*(self: Service, address: string, accountName: string, color: string, emoji: string): string =
|
||||
try:
|
||||
discard status_go_wallet.addAccountWatch(
|
||||
address,
|
||||
accountName,
|
||||
color,
|
||||
emoji
|
||||
)
|
||||
except Exception as e:
|
||||
return fmt"Error adding account with mnemonic: {e.msg}"
|
||||
@ -316,16 +320,18 @@ method toggleNetworkEnabled*(self: Service, chainId: int) =
|
||||
self.refreshBalances()
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled())
|
||||
|
||||
method updateWalletAccount*(self: Service, address: string, accountName: string, color: string) =
|
||||
method updateWalletAccount*(self: Service, address: string, accountName: string, color: string, emoji: string) =
|
||||
let account = self.accounts[address]
|
||||
status_go_accounts.updateAccount(
|
||||
accountName,
|
||||
account.address,
|
||||
account.publicKey,
|
||||
account.walletType,
|
||||
color
|
||||
color,
|
||||
emoji
|
||||
)
|
||||
account.name = accountName
|
||||
account.color = color
|
||||
account.emoji = emoji
|
||||
|
||||
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, WalletAccountUpdated(account: account))
|
||||
|
@ -24,16 +24,16 @@ method getWalletAccount*(self: ServiceInterface, accountIndex: int): WalletAccou
|
||||
method getCurrencyBalance*(self: ServiceInterface): float64 {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method generateNewAccount*(self: ServiceInterface, password: string, accountName: string, color: string): string {.base.} =
|
||||
method generateNewAccount*(self: ServiceInterface, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromPrivateKey*(self: ServiceInterface, privateKey: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromPrivateKey*(self: ServiceInterface, privateKey: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addAccountsFromSeed*(self: ServiceInterface, seedPhrase: string, password: string, accountName: string, color: string): string {.base.} =
|
||||
method addAccountsFromSeed*(self: ServiceInterface, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method addWatchOnlyAccount*(self: ServiceInterface, address: string, accountName: string, color: string): string {.base.} =
|
||||
method addWatchOnlyAccount*(self: ServiceInterface, address: string, accountName: string, color: string, emoji: string): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method deleteAccount*(self: ServiceInterface, address: string) {.base.} =
|
||||
@ -42,7 +42,7 @@ method deleteAccount*(self: ServiceInterface, address: string) {.base.} =
|
||||
method updateCurrency*(self: ServiceInterface, newCurrency: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method updateWalletAccount*(self: ServiceInterface, address: string, accountName: string, color: string) {.base.} =
|
||||
method updateWalletAccount*(self: ServiceInterface, address: string, accountName: string, color: string, emoji: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method toggleTokenVisible*(self: ServiceInterface, chainId: int, symbol: string) {.base.} =
|
||||
@ -52,4 +52,4 @@ method getPrice*(self: ServiceInterface, crypto: string, fiat: string): float64
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getIndex*(self: ServiceInterface, address: string): int {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
@ -23,9 +23,10 @@ proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
proc deleteAccount*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return core.callPrivateRPC("accounts_deleteAccount", %* [address])
|
||||
|
||||
proc updateAccount*(name, address, publicKey, walletType, color: string) {.raises: [Exception].} =
|
||||
proc updateAccount*(name, address, publicKey, walletType, color, emoji: string) {.raises: [Exception].} =
|
||||
discard core.callPrivateRPC("accounts_saveAccounts", %* [
|
||||
[{
|
||||
"emoji": emoji,
|
||||
"color": color,
|
||||
"name": name,
|
||||
"address": address,
|
||||
|
@ -11,18 +11,18 @@ proc getPendingTransactions*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* []
|
||||
result = core.callPrivateRPC("wallet_getPendingTransactions", payload)
|
||||
|
||||
proc generateAccount*(password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [hashPassword(password), name, color]
|
||||
proc generateAccount*(password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [hashPassword(password), name, color, emoji]
|
||||
return core.callPrivateRPC("accounts_generateAccount", payload)
|
||||
|
||||
proc addAccountWithMnemonic*(mnemonic, password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [mnemonic, hashPassword(password), name, color]
|
||||
proc addAccountWithMnemonic*(mnemonic, password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [mnemonic, hashPassword(password), name, color, emoji]
|
||||
return core.callPrivateRPC("accounts_addAccountWithMnemonic", payload)
|
||||
|
||||
proc addAccountWithPrivateKey*(privateKey, password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [privateKey, hashPassword(password), name, color]
|
||||
proc addAccountWithPrivateKey*(privateKey, password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [privateKey, hashPassword(password), name, color, emoji]
|
||||
return core.callPrivateRPC("accounts_addAccountWithPrivateKey", payload)
|
||||
|
||||
proc addAccountWatch*(address, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [address, name, color]
|
||||
proc addAccountWatch*(address, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %* [address, name, color, emoji]
|
||||
return core.callPrivateRPC("accounts_addAccountWatch", payload)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 381150a7b55d53b3cb59d9ee2c4f50985488c708
|
||||
Subproject commit 428b165198e53caa5a55ef605f241cc4b6f7e02d
|
@ -18,6 +18,7 @@ Item {
|
||||
property bool hideSignPhraseModal: false
|
||||
property var store
|
||||
property var contactsStore
|
||||
property var emojiPopup: null
|
||||
|
||||
function showSigningPhrasePopup(){
|
||||
if(!hideSignPhraseModal && !RootStore.hideSignPhraseModal){
|
||||
@ -52,6 +53,7 @@ Item {
|
||||
RightTabView {
|
||||
changeSelectedAccount: leftTab.changeSelectedAccount
|
||||
store: walletView.store
|
||||
emojiPopup: walletView.emojiPopup
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,6 +96,7 @@ Item {
|
||||
else
|
||||
rightPanelStackView.replace(walletContainer)
|
||||
}
|
||||
emojiPopup: walletView.emojiPopup
|
||||
}
|
||||
|
||||
rightPanel: StackView {
|
||||
|
@ -1,109 +0,0 @@
|
||||
import QtQuick 2.13
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
|
||||
Rectangle {
|
||||
id: walletDelegate
|
||||
|
||||
property string locale: ""
|
||||
property string currency: ""
|
||||
property int selectedAccountIndex
|
||||
property bool selected: index === selectedAccountIndex
|
||||
property bool hovered
|
||||
|
||||
signal clicked(int index)
|
||||
|
||||
height: 64
|
||||
color: {
|
||||
if (selected) {
|
||||
return Style.current.menuBackgroundActive
|
||||
}
|
||||
if (hovered) {
|
||||
return Style.current.backgroundHoverLight
|
||||
}
|
||||
return Style.current.transparent
|
||||
}
|
||||
radius: Style.current.radius
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
|
||||
SVGImage {
|
||||
id: walletIcon
|
||||
width: 12
|
||||
height: 12
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
source: Style.svg("walletIcon")
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: walletIcon
|
||||
source: walletIcon
|
||||
color: {
|
||||
Utils.getCurrentThemeAccountColor(model.color) || Style.current.accountColors[0]
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
id: walletName
|
||||
text: name
|
||||
elide: Text.ElideRight
|
||||
anchors.right: walletBalance.left
|
||||
anchors.rightMargin: Style.current.smallPadding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
anchors.left: walletIcon.right
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
color: Style.current.textColor
|
||||
}
|
||||
StyledText {
|
||||
id: walletAddress
|
||||
font.family: Style.current.fontHexRegular.name
|
||||
text: address
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: parent.width/2
|
||||
elide: Text.ElideMiddle
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.smallPadding
|
||||
anchors.left: walletIcon.left
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
color: Style.current.secondaryText
|
||||
opacity: selected ? 0.7 : 1
|
||||
}
|
||||
StyledText {
|
||||
id: walletBalance
|
||||
text: {
|
||||
Utils.toLocaleString(currencyBalance.toFixed(2), locale, {"currency": true}) + " " + walletDelegate.currency.toUpperCase()
|
||||
}
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
color: Style.current.textColor
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onEntered: {
|
||||
walletDelegate.hovered = true
|
||||
}
|
||||
onExited: {
|
||||
walletDelegate.hovered = false
|
||||
}
|
||||
onClicked: {
|
||||
walletDelegate.clicked(index)
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ Item {
|
||||
property var changeSelectedAccount
|
||||
property var store
|
||||
property var walletStore
|
||||
property var emojiPopup
|
||||
|
||||
height: walletAddress.y + walletAddress.height
|
||||
anchors.right: parent.right
|
||||
@ -109,8 +110,10 @@ Item {
|
||||
Component {
|
||||
id: accountSettingsModalComponent
|
||||
AccountSettingsModal {
|
||||
anchors.centerIn: parent
|
||||
onClosed: destroy()
|
||||
changeSelectedAccount: walletHeader.changeSelectedAccount
|
||||
emojiPopup: walletHeader.emojiPopup
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,126 +6,151 @@ import QtQuick.Dialogs 1.3
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
StatusModal {
|
||||
id: popup
|
||||
|
||||
property var currentAccount: RootStore.currentAccount
|
||||
property var changeSelectedAccount
|
||||
property var emojiPopup
|
||||
|
||||
// TODO add icon when we have that feature
|
||||
//% "Status account settings"
|
||||
title: qsTrId("status-account-settings")
|
||||
header.title: qsTrId("status-account-settings")
|
||||
height: 675
|
||||
|
||||
property int marginBetweenInputs: 35
|
||||
property string accountNameValidationError: ""
|
||||
|
||||
function validate() {
|
||||
if (accountNameInput.text === "") {
|
||||
//% "You need to enter an account name"
|
||||
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
|
||||
} else {
|
||||
accountNameValidationError = ""
|
||||
}
|
||||
|
||||
return accountNameValidationError === ""
|
||||
}
|
||||
property int marginBetweenInputs: 30
|
||||
|
||||
onOpened: {
|
||||
accountNameInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
Input {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
text: currentAccount.name
|
||||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
StatusWalletColorSelect {
|
||||
id: accountColorInput
|
||||
selectedColor: currentAccount.iconColor.toUpperCase()
|
||||
model: Theme.palette.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: typeText
|
||||
//% "Type"
|
||||
label: qsTrId("type")
|
||||
text: {
|
||||
var result = ""
|
||||
switch (currentAccount.walletType) {
|
||||
//% "Watch-only"
|
||||
case Constants.watchWalletType: result = qsTrId("watch-only"); break;
|
||||
case Constants.keyWalletType:
|
||||
//% "Off Status tree"
|
||||
case Constants.seedWalletType: result = qsTrId("off-status-tree"); break;
|
||||
//% "On Status tree"
|
||||
default: result = qsTrId("on-status-tree")
|
||||
}
|
||||
return result
|
||||
Connections {
|
||||
enabled: popup.opened
|
||||
target: emojiPopup
|
||||
onEmojiSelected: function (emojiText, atCursor) {
|
||||
popup.contentItem.accountNameInput.input.icon.emoji = emojiText
|
||||
}
|
||||
anchors.top: accountColorInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: addressText
|
||||
//% "Wallet address"
|
||||
label: qsTrId("wallet-address")
|
||||
text: currentAccount.address
|
||||
fontFamily: Style.current.fontHexRegular.name
|
||||
anchors.top: typeText.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
|
||||
contentItem: Column {
|
||||
property alias accountNameInput: accountNameInput
|
||||
|
||||
width: popup.width
|
||||
spacing: marginBetweenInputs
|
||||
topPadding: Style.current.padding
|
||||
|
||||
StatusInput {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
input.placeholderText: qsTrId("enter-an-account-name...")
|
||||
input.text: currentAccount.name
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
input.isIconSelectable: true
|
||||
input.icon.emoji: currentAccount.emoji
|
||||
input.icon.color: currentAccount.color
|
||||
input.icon.name: !currentAccount.emoji ? "filled-account": ""
|
||||
onIconClicked: {
|
||||
popup.emojiPopup.open()
|
||||
popup.emojiPopup.x = Global.applicationWindow.width/2 - popup.emojiPopup.width/2 + popup.width/2
|
||||
popup.emojiPopup.y = Global.applicationWindow.height/2 - popup.emojiPopup.height/2
|
||||
}
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an account name"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-account-name")
|
||||
minLength: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
StatusColorSelectorGrid {
|
||||
id: accountColorInput
|
||||
anchors.top: selectedColor.bottom
|
||||
anchors.topMargin: 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//% "color"
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
selectedColor: currentAccount.color
|
||||
selectedColorIndex: {
|
||||
for (let i = 0; i < model.length; i++) {
|
||||
if(model[i] === currentAccount.color)
|
||||
return i
|
||||
}
|
||||
}
|
||||
onSelectedColorChanged: {
|
||||
if(selectedColor !== currentAccount.color) {
|
||||
accountNameInput.input.icon.color = selectedColor
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
leftPadding: Style.current.padding
|
||||
spacing: Style.current.padding
|
||||
|
||||
TextWithLabel {
|
||||
id: typeText
|
||||
//% "Type"
|
||||
label: qsTrId("type")
|
||||
text: {
|
||||
var result = ""
|
||||
switch (currentAccount.walletType) {
|
||||
//% "Watch-only"
|
||||
case Constants.watchWalletType: result = qsTrId("watch-only"); break;
|
||||
case Constants.keyWalletType:
|
||||
//% "Off Status tree"
|
||||
case Constants.seedWalletType: result = qsTrId("off-status-tree"); break;
|
||||
//% "On Status tree"
|
||||
default: result = qsTrId("on-status-tree")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: addressText
|
||||
//% "Wallet address"
|
||||
label: qsTrId("wallet-address")
|
||||
text: currentAccount.address
|
||||
fontFamily: Style.current.fontHexRegular.name
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: pathText
|
||||
visible: currentAccount.walletType !== Constants.watchWalletType && currentAccount.walletType !== Constants.keyWalletType
|
||||
//% "Derivation path"
|
||||
label: qsTrId("derivation-path")
|
||||
text: currentAccount.path
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: storageText
|
||||
visible: currentAccount.walletType !== Constants.watchWalletType
|
||||
//% "Storage"
|
||||
label: qsTrId("storage")
|
||||
//% "This device"
|
||||
text: qsTrId("this-device")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: pathText
|
||||
visible: currentAccount.walletType !== Constants.watchWalletType && currentAccount.walletType !== Constants.keyWalletType
|
||||
//% "Derivation path"
|
||||
label: qsTrId("derivation-path")
|
||||
text: currentAccount.path
|
||||
anchors.top: addressText.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
id: storageText
|
||||
visible: currentAccount.walletType !== Constants.watchWalletType
|
||||
//% "Storage"
|
||||
label: qsTrId("storage")
|
||||
//% "This device"
|
||||
text: qsTrId("this-device")
|
||||
anchors.top: pathText.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
width: parent.width
|
||||
height: saveBtn.height
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
visible: currentAccount.walletType === Constants.watchWalletType
|
||||
anchors.top: parent.top
|
||||
anchors.right: saveBtn.left
|
||||
anchors.rightMargin: Style.current.padding
|
||||
//% "Delete account"
|
||||
text: qsTrId("delete-account")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
@ -157,12 +182,9 @@ ModalPopup {
|
||||
onClicked : {
|
||||
confirmationDialog.open()
|
||||
}
|
||||
}
|
||||
},
|
||||
StatusButton {
|
||||
id: saveBtn
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
//% "Save changes"
|
||||
text: qsTrId("save-changes")
|
||||
|
||||
@ -175,12 +197,12 @@ ModalPopup {
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
if (!validate()) {
|
||||
return
|
||||
}
|
||||
onClicked : {
|
||||
if (!accountNameInput.valid) {
|
||||
return
|
||||
}
|
||||
|
||||
const error = RootStore.updateCurrentAccount(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor);
|
||||
const error = RootStore.updateCurrentAccount(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.icon.emoji);
|
||||
|
||||
if (error) {
|
||||
Global.playErrorSound();
|
||||
@ -191,5 +213,5 @@ ModalPopup {
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -7,25 +7,23 @@ import utils 1.0
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
StatusModal {
|
||||
id: popup
|
||||
//% "Add account from private key"
|
||||
title: qsTrId("add-private-key-account")
|
||||
height: 600
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string passwordValidationError: ""
|
||||
property string privateKeyValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
property var emojiPopup: null
|
||||
|
||||
signal afterAddAccount()
|
||||
|
||||
@ -40,13 +38,6 @@ ModalPopup {
|
||||
passwordValidationError = ""
|
||||
}
|
||||
|
||||
if (accountNameInput.text === "") {
|
||||
//% "You need to enter an account name"
|
||||
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
|
||||
} else {
|
||||
accountNameValidationError = ""
|
||||
}
|
||||
|
||||
if (accountPKeyInput.text === "") {
|
||||
//% "You need to enter a private key"
|
||||
privateKeyValidationError = qsTrId("you-need-to-enter-a-private-key")
|
||||
@ -57,119 +48,159 @@ ModalPopup {
|
||||
privateKeyValidationError = ""
|
||||
}
|
||||
|
||||
return passwordValidationError === "" && privateKeyValidationError === "" && accountNameValidationError === ""
|
||||
return passwordValidationError === "" && privateKeyValidationError === "" && accountNameInput.valid
|
||||
}
|
||||
|
||||
//% "Add account from private key"
|
||||
header.title: qsTrId("add-private-key-account")
|
||||
|
||||
onOpened: {
|
||||
passwordInput.text = ""
|
||||
accountPKeyInput.text = ""
|
||||
accountNameInput.reset()
|
||||
accountNameInput.text = ""
|
||||
accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
|
||||
passwordValidationError = ""
|
||||
privateKeyValidationError = ""
|
||||
accountNameValidationError = ""
|
||||
accountColorInput.selectedColor = Style.current.accountColors[Math.floor(Math.random() * Style.current.accountColors.length)]
|
||||
accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
|
||||
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
Input {
|
||||
id: passwordInput
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
Connections {
|
||||
enabled: popup.opened
|
||||
target: emojiPopup
|
||||
onEmojiSelected: function (emojiText, atCursor) {
|
||||
popup.contentItem.accountNameInput.input.icon.emoji = emojiText
|
||||
}
|
||||
}
|
||||
|
||||
StyledTextArea {
|
||||
id: accountPKeyInput
|
||||
customHeight: 88
|
||||
anchors.top: passwordInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
validationError: popup.privateKeyValidationError
|
||||
//% "Private key"
|
||||
label: qsTrId("private-key")
|
||||
textField.wrapMode: Text.WordWrap
|
||||
textField.horizontalAlignment: TextEdit.AlignHCenter
|
||||
textField.verticalAlignment: TextEdit.AlignVCenter
|
||||
textField.font.weight: Font.DemiBold
|
||||
//% "Paste the contents of your private key"
|
||||
placeholderText: qsTrId("paste-the-contents-of-your-private-key")
|
||||
textField.placeholderTextColor: Style.current.secondaryText
|
||||
textField.selectByKeyboard: true
|
||||
textField.selectionColor: Style.current.secondaryBackground
|
||||
textField.selectedTextColor: Style.current.secondaryText
|
||||
}
|
||||
contentItem: Column {
|
||||
property alias accountNameInput: accountNameInput
|
||||
|
||||
Input {
|
||||
id: accountNameInput
|
||||
anchors.top: accountPKeyInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
//% "Enter an account name..."
|
||||
placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
width: popup.width
|
||||
spacing: 8
|
||||
topPadding: 20
|
||||
|
||||
StatusWalletColorSelect {
|
||||
id: accountColorInput
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
model: Theme.palette.accountColors
|
||||
}
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Style.current.xlPadding
|
||||
// To-Do Password hidden option not supported in StatusQ StatusBaseInput
|
||||
Input {
|
||||
id: passwordInput
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
width: parent.width
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
inputLabel.font.pixelSize: 15
|
||||
inputLabel.font.weight: Font.Normal
|
||||
}
|
||||
// To-Do use StatusInput
|
||||
StyledTextArea {
|
||||
id: accountPKeyInput
|
||||
customHeight: 88
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && accountPKeyInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
validationError: popup.privateKeyValidationError
|
||||
//% "Private key"
|
||||
label: qsTrId("private-key")
|
||||
textField.wrapMode: Text.WordWrap
|
||||
textField.horizontalAlignment: TextEdit.AlignHCenter
|
||||
textField.verticalAlignment: TextEdit.AlignVCenter
|
||||
textField.font.weight: Font.DemiBold
|
||||
//% "Paste the contents of your private key"
|
||||
placeholderText: qsTrId("paste-the-contents-of-your-private-key")
|
||||
textField.placeholderTextColor: Style.current.secondaryText
|
||||
textField.selectByKeyboard: true
|
||||
textField.selectionColor: Style.current.secondaryBackground
|
||||
textField.selectedTextColor: Style.current.secondaryText
|
||||
}
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!validate()) {
|
||||
return loading = false
|
||||
StatusInput {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
input.placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
input.isIconSelectable: true
|
||||
input.icon.color: accountColorInput.selectedColor ? accountColorInput.selectedColor : Theme.palette.directColor1
|
||||
onIconClicked: {
|
||||
popup.emojiPopup.open()
|
||||
popup.emojiPopup.x = Global.applicationWindow.width/2 - popup.emojiPopup.width/2 + popup.width/2
|
||||
popup.emojiPopup.y = Global.applicationWindow.height/2 - popup.emojiPopup.height/2
|
||||
}
|
||||
|
||||
const errMessage = RootStore.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage
|
||||
accountError.open()
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an account name"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-account-name")
|
||||
minLength: 1
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.close();
|
||||
]
|
||||
}
|
||||
|
||||
StatusColorSelectorGrid {
|
||||
id: accountColorInput
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//% "color"
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;formeditorColor:"#ffffff";height:500;width:400}
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && accountPKeyInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!validate()) {
|
||||
return loading = false
|
||||
}
|
||||
|
||||
const errMessage = RootStore.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.icon.emoji)
|
||||
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage
|
||||
accountError.open()
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
##^##*/
|
||||
|
@ -7,22 +7,21 @@ import utils 1.0
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
StatusModal {
|
||||
id: popup
|
||||
height: 615
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string passwordValidationError: ""
|
||||
property string seedValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
property var emojiPopup: null
|
||||
|
||||
signal afterAddAccount()
|
||||
|
||||
@ -43,13 +42,6 @@ ModalPopup {
|
||||
passwordValidationError = ""
|
||||
}
|
||||
|
||||
if (accountNameInput.text === "") {
|
||||
//% "You need to enter an account name"
|
||||
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
|
||||
} else {
|
||||
accountNameValidationError = ""
|
||||
}
|
||||
|
||||
if (seedPhraseTextArea.textArea.text === "") {
|
||||
//% "You need to enter a seed phrase"
|
||||
seedValidationError = qsTrId("you-need-to-enter-a-seed-phrase")
|
||||
@ -60,102 +52,144 @@ ModalPopup {
|
||||
seedValidationError = ""
|
||||
}
|
||||
|
||||
return passwordValidationError === "" && seedValidationError === "" && accountNameValidationError === ""
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
seedPhraseTextArea.textArea.text = "";
|
||||
passwordInput.text = "";
|
||||
accountNameInput.text = "";
|
||||
passwordValidationError = "";
|
||||
seedValidationError = "";
|
||||
accountNameValidationError = "";
|
||||
accountColorInput.selectedColor = Theme.palette.accountColors[Math.floor(Math.random() * Theme.palette.accountColors.length)]
|
||||
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
return passwordValidationError === "" && seedValidationError === "" && accountNameInput.valid
|
||||
}
|
||||
|
||||
//% "Add account with a seed phrase"
|
||||
title: qsTrId("add-seed-account")
|
||||
header.title: qsTrId("add-seed-account")
|
||||
|
||||
Input {
|
||||
id: passwordInput
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
onOpened: {
|
||||
seedPhraseTextArea.textArea.text = ""
|
||||
passwordInput.text = ""
|
||||
accountNameInput.text = ""
|
||||
accountNameInput.reset()
|
||||
accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
|
||||
passwordValidationError = ""
|
||||
seedValidationError = ""
|
||||
accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
|
||||
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
SeedPhraseTextArea {
|
||||
id: seedPhraseTextArea
|
||||
anchors.top: passwordInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
width: parent.width
|
||||
Connections {
|
||||
enabled: popup.opened
|
||||
target: emojiPopup
|
||||
onEmojiSelected: function (emojiText, atCursor) {
|
||||
popup.contentItem.accountNameInput.input.icon.emoji = emojiText
|
||||
}
|
||||
}
|
||||
|
||||
Input {
|
||||
id: accountNameInput
|
||||
anchors.top: seedPhraseTextArea.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
//% "Enter an account name..."
|
||||
placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
contentItem: Column {
|
||||
property alias accountNameInput: accountNameInput
|
||||
|
||||
StatusWalletColorSelect {
|
||||
id: accountColorInput
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
model: Theme.palette.accountColors
|
||||
}
|
||||
width: popup.width
|
||||
spacing: 8
|
||||
topPadding: 20
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Style.current.xlPadding
|
||||
// To-Do Password hidden option not supported in StatusQ StatusBaseInput
|
||||
Input {
|
||||
id: passwordInput
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
width: parent.width
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && seedPhraseTextArea.correctWordCount
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
inputLabel.font.pixelSize: 15
|
||||
inputLabel.font.weight: Font.Normal
|
||||
}
|
||||
// To-Do use StatusInput
|
||||
SeedPhraseTextArea {
|
||||
id: seedPhraseTextArea
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
width: parent.width - 2*Style.current.padding
|
||||
}
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loading doesn't work because the function freezes the view. Might need to use threads
|
||||
loading = true
|
||||
if (!validate() || !seedPhraseTextArea.validateSeed()) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
StatusInput {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
input.placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
input.isIconSelectable: true
|
||||
input.icon.color: accountColorInput.selectedColor ? accountColorInput.selectedColor : Theme.palette.directColor1
|
||||
onIconClicked: {
|
||||
popup.emojiPopup.open()
|
||||
popup.emojiPopup.x = Global.applicationWindow.width/2 - popup.emojiPopup.width/2 + popup.width/2
|
||||
popup.emojiPopup.y = Global.applicationWindow.height/2 - popup.emojiPopup.height/2
|
||||
}
|
||||
|
||||
const errMessage = RootStore.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage
|
||||
accountError.open()
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an account name"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-account-name")
|
||||
minLength: 1
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.reset()
|
||||
popup.close();
|
||||
]
|
||||
}
|
||||
|
||||
StatusColorSelectorGrid {
|
||||
id: accountColorInput
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//% "color"
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 8
|
||||
}
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && seedPhraseTextArea.correctWordCount
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loading doesn't work because the function freezes the view. Might need to use threads
|
||||
loading = true
|
||||
if (!validate() || !seedPhraseTextArea.validateSeed()) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
}
|
||||
|
||||
const errMessage = RootStore.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.icon.emoji)
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage
|
||||
accountError.open()
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.reset()
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -6,121 +6,140 @@ import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
StatusModal {
|
||||
id: popup
|
||||
//% "Add a watch-only account"
|
||||
title: qsTrId("add-watch-account")
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string addressError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
property var emojiPopup: null
|
||||
|
||||
signal afterAddAccount()
|
||||
|
||||
function validate() {
|
||||
if (addressInput.text === "") {
|
||||
//% "You need to enter an address"
|
||||
addressError = qsTrId("you-need-to-enter-an-address")
|
||||
} else if (!Utils.isAddress(addressInput.text)) {
|
||||
//% "This needs to be a valid address (starting with 0x)"
|
||||
addressError = qsTrId("this-needs-to-be-a-valid-address-(starting-with-0x)")
|
||||
} else {
|
||||
addressError = ""
|
||||
}
|
||||
|
||||
if (accountNameInput.text === "") {
|
||||
//% "You need to enter an account name"
|
||||
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
|
||||
} else {
|
||||
accountNameValidationError = ""
|
||||
}
|
||||
|
||||
return addressError === "" && accountNameValidationError === ""
|
||||
}
|
||||
//% "Add a watch-only account"
|
||||
header.title: qsTrId("add-watch-account")
|
||||
|
||||
onOpened: {
|
||||
addressError = "";
|
||||
accountNameValidationError = "";
|
||||
addressInput.text = "";
|
||||
accountNameInput.text = "";
|
||||
accountColorInput.selectedColor = Style.current.accountColors[Math.floor(Math.random() * Style.current.accountColors.length)]
|
||||
addressInput.text = ""
|
||||
addressInput.reset()
|
||||
accountNameInput.text = ""
|
||||
accountNameInput.reset()
|
||||
accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
|
||||
accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
|
||||
addressInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
Input {
|
||||
id: addressInput
|
||||
// TODO add QR code reader for the address
|
||||
//% "Enter address..."
|
||||
placeholderText: qsTrId("enter-address...")
|
||||
//% "Account address"
|
||||
label: qsTrId("wallet-key-title")
|
||||
validationError: popup.addressError
|
||||
}
|
||||
|
||||
Input {
|
||||
id: accountNameInput
|
||||
anchors.top: addressInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
//% "Enter an account name..."
|
||||
placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
StatusWalletColorSelect {
|
||||
id: accountColorInput
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
model: Theme.palette.accountColors
|
||||
}
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && addressInput.text !== "" && accountNameInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!validate()) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
}
|
||||
|
||||
const error = RootStore.addWatchOnlyAccount(addressInput.text, accountNameInput.text, accountColorInput.selectedColor);
|
||||
loading = false
|
||||
if (error) {
|
||||
Global.playErrorSound();
|
||||
accountError.text = error
|
||||
return accountError.open()
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.close();
|
||||
Connections {
|
||||
enabled: popup.opened
|
||||
target: emojiPopup
|
||||
onEmojiSelected: function (emojiText, atCursor) {
|
||||
popup.contentItem.accountNameInput.input.icon.emoji = emojiText
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Column {
|
||||
property alias accountNameInput: accountNameInput
|
||||
|
||||
width: popup.width
|
||||
spacing: 8
|
||||
topPadding: 20
|
||||
|
||||
StatusInput {
|
||||
id: addressInput
|
||||
// TODO add QR code reader for the address
|
||||
//% "Enter address..."
|
||||
input.placeholderText: qsTrId("enter-address...")
|
||||
//% "Account address"
|
||||
label: qsTrId("wallet-key-title")
|
||||
validators: [
|
||||
StatusAddressValidator {
|
||||
//% "This needs to be a valid address (starting with 0x)"
|
||||
errorMessage: qsTrId("this-needs-to-be-a-valid-address-(starting-with-0x)")
|
||||
},
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an address"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-address")
|
||||
minLength: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
StatusInput {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
input.placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
input.isIconSelectable: true
|
||||
input.icon.color: accountColorInput.selectedColor ? accountColorInput.selectedColor : Theme.palette.directColor1
|
||||
onIconClicked: {
|
||||
popup.emojiPopup.open()
|
||||
popup.emojiPopup.x = Global.applicationWindow.width/2 - popup.emojiPopup.width/2 + popup.width/2
|
||||
popup.emojiPopup.y = Global.applicationWindow.height/2 - popup.emojiPopup.height/2
|
||||
}
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an account name"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-account-name")
|
||||
minLength: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
StatusColorSelectorGrid {
|
||||
id: accountColorInput
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//% "color"
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 8
|
||||
}
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && addressInput.text !== "" && accountNameInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!addressInput.valid || !accountNameInput.valid) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
}
|
||||
const error = RootStore.addWatchOnlyAccount(addressInput.text, accountNameInput.text, accountColorInput.selectedColor, accountNameInput.input.icon.emoji);
|
||||
loading = false
|
||||
if (error) {
|
||||
Global.playErrorSound();
|
||||
accountError.text = error
|
||||
return accountError.open()
|
||||
}
|
||||
popup.afterAddAccount()
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -6,26 +6,28 @@ import utils 1.0
|
||||
|
||||
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 StatusQ.Popups 0.1
|
||||
|
||||
import shared.popups 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
// TODO: replace with StatusModal
|
||||
ModalPopup {
|
||||
StatusModal {
|
||||
id: popup
|
||||
//% "Generate an account"
|
||||
title: qsTrId("generate-a-new-account")
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string passwordValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
property var emojiPopup: null
|
||||
|
||||
signal afterAddAccount()
|
||||
|
||||
//% "Generate an account"
|
||||
header.title: qsTrId("generate-a-new-account")
|
||||
|
||||
function validate() {
|
||||
if (passwordInput.text === "") {
|
||||
//% "You need to enter a password"
|
||||
@ -36,98 +38,131 @@ ModalPopup {
|
||||
} else {
|
||||
passwordValidationError = ""
|
||||
}
|
||||
|
||||
if (accountNameInput.text === "") {
|
||||
//% "You need to enter an account name"
|
||||
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
|
||||
} else {
|
||||
accountNameValidationError = ""
|
||||
return passwordValidationError === "" && accountNameInput.valid
|
||||
}
|
||||
|
||||
return passwordValidationError === "" && accountNameValidationError === ""
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
passwordValidationError = "";
|
||||
accountNameValidationError = "";
|
||||
passwordInput.text = "";
|
||||
accountNameInput.reset()
|
||||
accountNameInput.text = "";
|
||||
accountColorInput.selectedColor = Style.current.accountColors[Math.floor(Math.random() * Style.current.accountColors.length)]
|
||||
accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
|
||||
colorSelectionGrid.selectedColorIndex = Math.floor(Math.random() * colorSelectionGrid.model.length)
|
||||
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
}
|
||||
|
||||
Input {
|
||||
id: passwordInput
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
Connections {
|
||||
enabled: popup.opened
|
||||
target: emojiPopup
|
||||
onEmojiSelected: function (emojiText, atCursor) {
|
||||
popup.contentItem.accountNameInput.input.icon.emoji = emojiText
|
||||
}
|
||||
}
|
||||
|
||||
Input {
|
||||
id: accountNameInput
|
||||
anchors.top: passwordInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
//% "Enter an account name..."
|
||||
placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
contentItem: Column {
|
||||
property alias accountNameInput: accountNameInput
|
||||
width: popup.width
|
||||
spacing: 8
|
||||
topPadding: 20
|
||||
|
||||
StatusWalletColorSelect {
|
||||
id: accountColorInput
|
||||
selectedColor: Theme.palette.accountColors[0]
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
width: parent.width
|
||||
model: Theme.palette.accountColors
|
||||
}
|
||||
// To-Do Password hidden option not supported in StatusQ StatusBaseInput
|
||||
Item {
|
||||
width: parent.width
|
||||
height: passwordInput.height
|
||||
Input {
|
||||
id: passwordInput
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.rightMargin: Style.current.padding
|
||||
|
||||
footer: StatusButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
//% "Enter your password…"
|
||||
placeholderText: qsTrId("enter-your-password…")
|
||||
//% "Password"
|
||||
label: qsTrId("password")
|
||||
textField.echoMode: TextInput.Password
|
||||
validationError: popup.passwordValidationError
|
||||
inputLabel.font.pixelSize: 15
|
||||
inputLabel.font.weight: Font.Normal
|
||||
}
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!validate()) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
StatusInput {
|
||||
id: accountNameInput
|
||||
//% "Enter an account name..."
|
||||
input.placeholderText: qsTrId("enter-an-account-name...")
|
||||
//% "Account name"
|
||||
label: qsTrId("account-name")
|
||||
input.isIconSelectable: true
|
||||
input.icon.color: colorSelectionGrid.selectedColor ? colorSelectionGrid.selectedColor : Theme.palette.directColor1
|
||||
onIconClicked: {
|
||||
popup.emojiPopup.open()
|
||||
popup.emojiPopup.x = Global.applicationWindow.width/2 - popup.emojiPopup.width/2 + popup.width/2
|
||||
popup.emojiPopup.y = Global.applicationWindow.height/2 - popup.emojiPopup.height/2
|
||||
}
|
||||
|
||||
const errMessage = RootStore.generateNewAccount(passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
console.log(errMessage)
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage;
|
||||
accountError.open();
|
||||
validators: [
|
||||
StatusMinLengthValidator {
|
||||
//% "You need to enter an account name"
|
||||
errorMessage: qsTrId("you-need-to-enter-an-account-name")
|
||||
minLength: 1
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount();
|
||||
popup.close();
|
||||
]
|
||||
}
|
||||
|
||||
StatusColorSelectorGrid {
|
||||
id: colorSelectionGrid
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
//% "color"
|
||||
titleText: qsTr("color").toUpperCase()
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 8
|
||||
}
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
StatusButton {
|
||||
text: loading ?
|
||||
//% "Loading..."
|
||||
qsTrId("loading") :
|
||||
//% "Add account"
|
||||
qsTrId("add-account")
|
||||
|
||||
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== ""
|
||||
|
||||
MessageDialog {
|
||||
id: accountError
|
||||
title: "Adding the account failed"
|
||||
icon: StandardIcon.Critical
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
onClicked : {
|
||||
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads
|
||||
loading = true
|
||||
if (!validate()) {
|
||||
Global.playErrorSound();
|
||||
return loading = false
|
||||
}
|
||||
|
||||
const errMessage = RootStore.generateNewAccount(passwordInput.text, accountNameInput.text, colorSelectionGrid.selectedColor, accountNameInput.input.icon.emoji)
|
||||
console.log(errMessage)
|
||||
loading = false
|
||||
if (errMessage) {
|
||||
Global.playErrorSound();
|
||||
if (Utils.isInvalidPasswordMessage(errMessage)) {
|
||||
//% "Wrong password"
|
||||
popup.passwordValidationError = qsTrId("wrong-password")
|
||||
} else {
|
||||
accountError.text = errMessage;
|
||||
accountError.open();
|
||||
}
|
||||
return
|
||||
}
|
||||
popup.afterAddAccount();
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -105,28 +105,28 @@ QtObject {
|
||||
walletSection.switchAccount(newIndex)
|
||||
}
|
||||
|
||||
function generateNewAccount(password, accountName, color) {
|
||||
return walletSectionAccounts.generateNewAccount(password, accountName, color)
|
||||
function generateNewAccount(password, accountName, color, emoji) {
|
||||
return walletSectionAccounts.generateNewAccount(password, accountName, color, emoji)
|
||||
}
|
||||
|
||||
function addAccountsFromPrivateKey(privateKey, password, accountName, color) {
|
||||
return walletSectionAccounts.addAccountsFromPrivateKey(privateKey, password, accountName, color)
|
||||
function addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji) {
|
||||
return walletSectionAccounts.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
|
||||
}
|
||||
|
||||
function addAccountsFromSeed(seedPhrase, password, accountName, color) {
|
||||
return walletSectionAccounts.addAccountsFromSeed(seedPhrase, password, accountName, color)
|
||||
function addAccountsFromSeed(seedPhrase, password, accountName, color, emoji) {
|
||||
return walletSectionAccounts.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
|
||||
}
|
||||
|
||||
function addWatchOnlyAccount(address, accountName, color) {
|
||||
return walletSectionAccounts.addWatchOnlyAccount(address, accountName, color)
|
||||
function addWatchOnlyAccount(address, accountName,color, emoji) {
|
||||
return walletSectionAccounts.addWatchOnlyAccount(address, accountName, color, emoji)
|
||||
}
|
||||
|
||||
function deleteAccount(address) {
|
||||
return walletSectionAccounts.deleteAccount(address)
|
||||
}
|
||||
|
||||
function updateCurrentAccount(address, accountName, color) {
|
||||
return walletSectionCurrent.update(address, accountName, color)
|
||||
function updateCurrentAccount(address, accountName, color, emoji) {
|
||||
return walletSectionCurrent.update(address, accountName, color, emoji)
|
||||
}
|
||||
|
||||
function updateCurrency(newCurrency) {
|
||||
|
@ -9,6 +9,7 @@ import shared.panels 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import "../controls"
|
||||
import "../popups"
|
||||
@ -20,6 +21,7 @@ Rectangle {
|
||||
property int selectedAccountIndex: 0
|
||||
property var changeSelectedAccount: function(){}
|
||||
property var showSavedAddresses: function(showSavedAddresses){}
|
||||
property var emojiPopup: null
|
||||
|
||||
function onAfterAddAccount () {
|
||||
walletInfoContainer.changeSelectedAccount(RootStore.accounts.rowCount() - 1)
|
||||
@ -111,22 +113,30 @@ Rectangle {
|
||||
|
||||
GenerateAccountModal {
|
||||
id: generateAccountModal
|
||||
anchors.centerIn: parent
|
||||
onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
|
||||
emojiPopup: walletInfoContainer.emojiPopup
|
||||
}
|
||||
|
||||
AddAccountWithSeedModal {
|
||||
id: addAccountWithSeedModal
|
||||
anchors.centerIn: parent
|
||||
onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
|
||||
emojiPopup: walletInfoContainer.emojiPopup
|
||||
}
|
||||
|
||||
AddAccountWithPrivateKeyModal {
|
||||
id: addAccountWithPrivateKeydModal
|
||||
anchors.centerIn: parent
|
||||
onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
|
||||
emojiPopup: walletInfoContainer.emojiPopup
|
||||
}
|
||||
|
||||
AddWatchOnlyAccountModal {
|
||||
id: addWatchOnlyAccountModal
|
||||
anchors.centerIn: parent
|
||||
onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
|
||||
emojiPopup: walletInfoContainer.emojiPopup
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
@ -134,8 +144,8 @@ Rectangle {
|
||||
anchors.bottomMargin: btnSavedAddresses.height + Style.current.padding
|
||||
anchors.top: walletValueTextContainer.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 272
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: listView.contentHeight > listView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||
clip: true
|
||||
@ -150,10 +160,17 @@ Rectangle {
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
|
||||
delegate: WalletDelegate {
|
||||
currency: RootStore.currentCurrency
|
||||
locale: RootStore.locale
|
||||
selectedAccountIndex: walletInfoContainer.selectedAccountIndex
|
||||
delegate: StatusListItem {
|
||||
width: parent.width
|
||||
highlighted: index === selectedAccountIndex
|
||||
title: model.name
|
||||
subTitle: Utils.toLocaleString(model.currencyBalance.toFixed(2), RootStore.locale, {"model.currency": true}) + " " + RootStore.currentCurrency.toUpperCase()
|
||||
icon.emoji: !!model.emoji ? model.emoji: ""
|
||||
icon.color: model.color
|
||||
icon.name: !model.emoji ? "filled-account": ""
|
||||
icon.letterSize: 14
|
||||
icon.isLetterIdenticon: !!model.emoji ? true : false
|
||||
icon.background.color: Theme.palette.indirectColor1
|
||||
onClicked: {
|
||||
changeSelectedAccount(index)
|
||||
showSavedAddresses(false)
|
||||
|
@ -19,6 +19,7 @@ Item {
|
||||
property var changeSelectedAccount
|
||||
property alias currentTabIndex: walletTabBar.currentIndex
|
||||
property var store
|
||||
property var emojiPopup
|
||||
|
||||
WalletHeader {
|
||||
id: walletHeader
|
||||
@ -28,6 +29,7 @@ Item {
|
||||
changeSelectedAccount: walletContainer.changeSelectedAccount
|
||||
store: walletContainer.store
|
||||
walletStore: RootStore
|
||||
emojiPopup: walletContainer.emojiPopup
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
@ -497,6 +497,7 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
store: appMain.rootStore
|
||||
contactsStore: appMain.rootStore.profileSectionStore.contactsStore
|
||||
emojiPopup: statusEmojiPopup
|
||||
}
|
||||
|
||||
Component {
|
||||
|
Loading…
x
Reference in New Issue
Block a user