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:
Khushboo Mehta 2022-03-10 18:01:17 +01:00 committed by Iuri Matias
parent aef8d0c4ab
commit 6e0471c943
30 changed files with 767 additions and 674 deletions

View File

@ -26,17 +26,17 @@ method init*(self: Controller) =
method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] = method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
return self.walletAccountService.getWalletAccounts() return self.walletAccountService.getWalletAccounts()
method generateNewAccount*(self: Controller, password: string, accountName: string, color: string): string = method generateNewAccount*(self: Controller, password: string, accountName: string, color: string, emoji: string): string =
return self.walletAccountService.generateNewAccount(password, accountName, color) return self.walletAccountService.generateNewAccount(password, accountName, color, emoji)
method addAccountsFromPrivateKey*(self: Controller, privateKey: string, password: string, accountName: string, color: string): string = method addAccountsFromPrivateKey*(self: Controller, privateKey: string, password: string, accountName: string, color: string, emoji: string): string =
return self.walletAccountService.addAccountsFromPrivateKey(privateKey, password, accountName, color) return self.walletAccountService.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
method addAccountsFromSeed*(self: Controller, seedPhrase: string, password: string, accountName: string, color: string): string = method addAccountsFromSeed*(self: Controller, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string =
return self.walletAccountService.addAccountsFromSeed(seedPhrase, password, accountName, color) return self.walletAccountService.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
method addWatchOnlyAccount*(self: Controller, address: string, accountName: string, color: string): string = method addWatchOnlyAccount*(self: Controller, address: string, accountName: string, color: string, emoji: string): string =
return self.walletAccountService.addWatchOnlyAccount(address, accountName, color) return self.walletAccountService.addWatchOnlyAccount(address, accountName, color, emoji)
method deleteAccount*(self: Controller, address: string) = method deleteAccount*(self: Controller, address: string) =
self.walletAccountService.deleteAccount(address) self.walletAccountService.deleteAccount(address)

View File

@ -13,16 +13,16 @@ method init*(self: AccessInterface) {.base.} =
method getWalletAccounts*(self: AccessInterface): seq[wallet_account_service.WalletAccountDto] {.base.} = method getWalletAccounts*(self: AccessInterface): seq[wallet_account_service.WalletAccountDto] {.base.} =
raise newException(ValueError, "No implementation available") 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") 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") 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") 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") raise newException(ValueError, "No implementation available")
method deleteAccount*(self: AccessInterface, address: string) {.base.} = method deleteAccount*(self: AccessInterface, address: string) {.base.} =

View File

@ -11,16 +11,16 @@ method load*(self: AccessInterface) {.base.} =
method isLoaded*(self: AccessInterface): bool {.base.} = method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available") 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") 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") 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") 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") raise newException(ValueError, "No implementation available")
method deleteAccount*(self: AccessInterface, address: string) {.base.} = method deleteAccount*(self: AccessInterface, address: string) {.base.} =

View File

@ -13,6 +13,7 @@ type
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: float64
assets: account_tokens.Model assets: account_tokens.Model
emoji: string
proc initItem*( proc initItem*(
name: string, name: string,
@ -24,7 +25,8 @@ proc initItem*(
isWallet: bool, isWallet: bool,
isChat: bool, isChat: bool,
currencyBalance: float64, currencyBalance: float64,
assets: account_tokens.Model assets: account_tokens.Model,
emoji: string
): Item = ): Item =
result.name = name result.name = name
result.address = address result.address = address
@ -36,6 +38,7 @@ proc initItem*(
result.isChat = isChat result.isChat = isChat
result.currencyBalance = currencyBalance result.currencyBalance = currencyBalance
result.assets = assets result.assets = assets
result.emoji = emoji
proc `$`*(self: Item): string = proc `$`*(self: Item): string =
result = fmt"""WalletAccountItem( result = fmt"""WalletAccountItem(
@ -49,6 +52,7 @@ proc `$`*(self: Item): string =
isChat: {self.isChat}, isChat: {self.isChat},
currencyBalance: {self.currencyBalance}, currencyBalance: {self.currencyBalance},
assets.len: {self.assets.getCount()}, assets.len: {self.assets.getCount()},
emoji: {self.emoji}
]""" ]"""
proc getName*(self: Item): string = proc getName*(self: Item): string =
@ -60,6 +64,9 @@ proc getAddress*(self: Item): string =
proc getPath*(self: Item): string = proc getPath*(self: Item): string =
return self.path return self.path
proc getEmoji*(self: Item): string =
return self.emoji
proc getColor*(self: Item): string = proc getColor*(self: Item): string =
return self.color return self.color

View File

@ -13,7 +13,8 @@ type
IsWallet, IsWallet,
IsChat, IsChat,
CurrencyBalance, CurrencyBalance,
Assets Assets,
Emoji
QtObject: QtObject:
type type
@ -58,7 +59,8 @@ QtObject:
ModelRole.IsWallet.int:"isWallet", ModelRole.IsWallet.int:"isWallet",
ModelRole.IsChat.int:"isChat", ModelRole.IsChat.int:"isChat",
ModelRole.Assets.int:"assets", ModelRole.Assets.int:"assets",
ModelRole.CurrencyBalance.int:"currencyBalance" ModelRole.CurrencyBalance.int:"currencyBalance",
ModelRole.Emoji.int: "emoji"
}.toTable }.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant = method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -92,6 +94,8 @@ QtObject:
result = newQVariant(item.getCurrencyBalance()) result = newQVariant(item.getCurrencyBalance())
of ModelRole.Assets: of ModelRole.Assets:
result = newQVariant(item.getAssets()) result = newQVariant(item.getAssets())
of ModelRole.Emoji:
result = newQVariant(item.getEmoji())
proc setItems*(self: Model, items: seq[Item]) = proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel() self.beginResetModel()

View File

@ -62,7 +62,8 @@ method refreshWalletAccounts*(self: Module) =
w.isWallet, w.isWallet,
w.isChat, w.isChat,
w.getCurrencyBalance(), w.getCurrencyBalance(),
assets assets,
w.emoji
)) ))
self.view.setItems(items) self.view.setItems(items)
@ -100,17 +101,17 @@ method viewDidLoad*(self: Module) =
self.moduleLoaded = true self.moduleLoaded = true
self.delegate.accountsModuleDidLoad() self.delegate.accountsModuleDidLoad()
method generateNewAccount*(self: Module, password: string, accountName: string, color: string): string = method generateNewAccount*(self: Module, password: string, accountName: string, color: string, emoji: string): string =
return self.controller.generateNewAccount(password, accountName, color) return self.controller.generateNewAccount(password, accountName, color, emoji)
method addAccountsFromPrivateKey*(self: Module, privateKey: string, password: string, accountName: string, color: string): string = method addAccountsFromPrivateKey*(self: Module, privateKey: string, password: string, accountName: string, color: string, emoji: string): string =
return self.controller.addAccountsFromPrivateKey(privateKey, password, accountName, color) return self.controller.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
method addAccountsFromSeed*(self: Module, seedPhrase: string, password: string, accountName: string, color: string): string = method addAccountsFromSeed*(self: Module, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string =
return self.controller.addAccountsFromSeed(seedPhrase, password, accountName, color) return self.controller.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
method addWatchOnlyAccount*(self: Module, address: string, accountName: string, color: string): string = method addWatchOnlyAccount*(self: Module, address: string, accountName: string, color: string, emoji: string): string =
return self.controller.addWatchOnlyAccount(address, accountName, color) return self.controller.addWatchOnlyAccount(address, accountName, color, emoji)
method deleteAccount*(self: Module, address: string) = method deleteAccount*(self: Module, address: string) =
self.controller.deleteAccount(address) self.controller.deleteAccount(address)

View File

@ -103,17 +103,17 @@ QtObject:
self.imported.setItems(imported) self.imported.setItems(imported)
self.generated.setItems(generated) self.generated.setItems(generated)
proc generateNewAccount*(self: View, password: string, accountName: string, color: string): string {.slot.} = proc generateNewAccount*(self: View, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
return self.delegate.generateNewAccount(password, accountName, color) return self.delegate.generateNewAccount(password, accountName, color, emoji)
proc addAccountsFromPrivateKey*(self: View, privateKey: string, password: string, accountName: string, color: string): string {.slot.} = proc addAccountsFromPrivateKey*(self: View, privateKey: string, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
return self.delegate.addAccountsFromPrivateKey(privateKey, password, accountName, color) return self.delegate.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
proc addAccountsFromSeed*(self: View, seedPhrase: string, password: string, accountName: string, color: string): string {.slot.} = proc addAccountsFromSeed*(self: View, seedPhrase: string, password: string, accountName: string, color: string, emoji: string): string {.slot.} =
return self.delegate.addAccountsFromSeed(seedPhrase, password, accountName, color) return self.delegate.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
proc addWatchOnlyAccount*(self: View, address: string, accountName: string, color: string): string {.slot.} = proc addWatchOnlyAccount*(self: View, address: string, accountName: string, color: string, emoji: string): string {.slot.} =
return self.delegate.addWatchOnlyAccount(address, accountName, color) return self.delegate.addWatchOnlyAccount(address, accountName, color, emoji)
proc deleteAccount*(self: View, address: string) {.slot.} = proc deleteAccount*(self: View, address: string) {.slot.} =
self.delegate.deleteAccount(address) self.delegate.deleteAccount(address)

View File

@ -26,5 +26,5 @@ method init*(self: Controller) =
method getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto = method getWalletAccount*(self: Controller, accountIndex: int): wallet_account_service.WalletAccountDto =
return self.walletAccountService.getWalletAccount(accountIndex) return self.walletAccountService.getWalletAccount(accountIndex)
method update*(self: Controller, address: string, accountName: string, color: string) = method update*(self: Controller, address: string, accountName: string, color: string, emoji: string) =
self.walletAccountService.updateWalletAccount(address, accountName, color) self.walletAccountService.updateWalletAccount(address, accountName, color, emoji)

View File

@ -13,7 +13,7 @@ method init*(self: AccessInterface) {.base.} =
method getWalletAccount*(self: AccessInterface, accountIndex: int): wallet_account_service.WalletAccountDto {.base.} = method getWalletAccount*(self: AccessInterface, accountIndex: int): wallet_account_service.WalletAccountDto {.base.} =
raise newException(ValueError, "No implementation available") 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") raise newException(ValueError, "No implementation available")
type type

View File

@ -14,7 +14,7 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} = method switchAccount*(self: AccessInterface, accountIndex: int) {.base.} =
raise newException(ValueError, "No implementation available") 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") raise newException(ValueError, "No implementation available")
# View Delegate Interface # View Delegate Interface

View File

@ -65,5 +65,5 @@ method switchAccount*(self: Module, accountIndex: int) =
let walletAccount = self.controller.getWalletAccount(accountIndex) let walletAccount = self.controller.getWalletAccount(accountIndex)
self.view.setData(walletAccount) self.view.setData(walletAccount)
method update*(self: Module, address: string, accountName: string, color: string) = method update*(self: Module, address: string, accountName: string, color: string, emoji: string) =
self.controller.update(address, accountName, color) self.controller.update(address, accountName, color, emoji)

View File

@ -18,6 +18,7 @@ QtObject:
isChat: bool isChat: bool
currencyBalance: float64 currencyBalance: float64
assets: account_tokens.Model assets: account_tokens.Model
emoji: string
proc setup(self: View) = proc setup(self: View) =
self.QObject.setup self.QObject.setup
@ -114,8 +115,17 @@ QtObject:
read = getAssets read = getAssets
notify = assetsChanged notify = assetsChanged
proc update(self: View, address: string, accountName: string, color: string) {.slot.} = proc getEmoji(self: View): QVariant {.slot.} =
self.delegate.update(address, accountName, color) 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) = proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
self.name = dto.name self.name = dto.name
@ -134,6 +144,8 @@ proc setData*(self: View, dto: wallet_account_service.WalletAccountDto) =
self.isChatChanged() self.isChatChanged()
self.currencyBalance = dto.getCurrencyBalance() self.currencyBalance = dto.getCurrencyBalance()
self.currencyBalanceChanged() self.currencyBalanceChanged()
self.emoji = dto.emoji
self.emojiChanged()
let assets = account_tokens.newModel() let assets = account_tokens.newModel()

View File

@ -25,6 +25,7 @@ type
isWallet*: bool isWallet*: bool
isChat*: bool isChat*: bool
tokens*: seq[WalletTokenDto] tokens*: seq[WalletTokenDto]
emoji*: string
proc newDto*( proc newDto*(
name: string, name: string,
@ -34,7 +35,8 @@ proc newDto*(
publicKey: string, publicKey: string,
walletType: string, walletType: string,
isWallet: bool, isWallet: bool,
isChat: bool isChat: bool,
emoji: string
): WalletAccountDto = ): WalletAccountDto =
return WalletAccountDto( return WalletAccountDto(
name: name, name: name,
@ -44,7 +46,8 @@ proc newDto*(
publicKey: publicKey, publicKey: publicKey,
walletType: walletType, walletType: walletType,
isWallet: isWallet, isWallet: isWallet,
isChat: isChat isChat: isChat,
emoji: emoji
) )
proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto = proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
@ -57,6 +60,7 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto =
discard jsonObj.getProp("chat", result.isChat) discard jsonObj.getProp("chat", result.isChat)
discard jsonObj.getProp("public-key", result.publicKey) discard jsonObj.getProp("public-key", result.publicKey)
discard jsonObj.getProp("type", result.walletType) discard jsonObj.getProp("type", result.walletType)
discard jsonObj.getProp("emoji", result.emoji)
proc getCurrencyBalance*(self: WalletAccountDto): float64 = proc getCurrencyBalance*(self: WalletAccountDto): float64 =
return self.tokens.map(t => t.currencyBalance).foldl(a + b, 0.0) return self.tokens.map(t => t.currencyBalance).foldl(a + b, 0.0)

View File

@ -244,49 +244,53 @@ method addNewAccountToLocalStore(self: Service) =
self.accounts[newAccount.address] = newAccount self.accounts[newAccount.address] = newAccount
self.events.emit(SIGNAL_WALLET_ACCOUNT_SAVED, AccountSaved(account: 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: try:
discard status_go_wallet.generateAccount( discard status_go_wallet.generateAccount(
password, password,
accountName, accountName,
color) color,
emoji)
except Exception as e: except Exception as e:
return fmt"Error generating new account: {e.msg}" return fmt"Error generating new account: {e.msg}"
self.addNewAccountToLocalStore() 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: try:
discard status_go_wallet.addAccountWithPrivateKey( discard status_go_wallet.addAccountWithPrivateKey(
privateKey, privateKey,
password, password,
accountName, accountName,
color, color,
emoji
) )
except Exception as e: except Exception as e:
return fmt"Error adding account with private key: {e.msg}" return fmt"Error adding account with private key: {e.msg}"
self.addNewAccountToLocalStore() 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: try:
discard status_go_wallet.addAccountWithMnemonic( discard status_go_wallet.addAccountWithMnemonic(
mnemonic, mnemonic,
password, password,
accountName, accountName,
color, color,
emoji
) )
except Exception as e: except Exception as e:
return fmt"Error adding account with mnemonic: {e.msg}" return fmt"Error adding account with mnemonic: {e.msg}"
self.addNewAccountToLocalStore() 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: try:
discard status_go_wallet.addAccountWatch( discard status_go_wallet.addAccountWatch(
address, address,
accountName, accountName,
color, color,
emoji
) )
except Exception as e: except Exception as e:
return fmt"Error adding account with mnemonic: {e.msg}" return fmt"Error adding account with mnemonic: {e.msg}"
@ -316,16 +320,18 @@ method toggleNetworkEnabled*(self: Service, chainId: int) =
self.refreshBalances() self.refreshBalances()
self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled()) 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] let account = self.accounts[address]
status_go_accounts.updateAccount( status_go_accounts.updateAccount(
accountName, accountName,
account.address, account.address,
account.publicKey, account.publicKey,
account.walletType, account.walletType,
color color,
emoji
) )
account.name = accountName account.name = accountName
account.color = color account.color = color
account.emoji = emoji
self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, WalletAccountUpdated(account: account)) self.events.emit(SIGNAL_WALLET_ACCOUNT_UPDATED, WalletAccountUpdated(account: account))

View File

@ -24,16 +24,16 @@ method getWalletAccount*(self: ServiceInterface, accountIndex: int): WalletAccou
method getCurrencyBalance*(self: ServiceInterface): float64 {.base.} = method getCurrencyBalance*(self: ServiceInterface): float64 {.base.} =
raise newException(ValueError, "No implementation available") 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") 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") 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") 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") raise newException(ValueError, "No implementation available")
method deleteAccount*(self: ServiceInterface, address: string) {.base.} = 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.} = method updateCurrency*(self: ServiceInterface, newCurrency: string) {.base.} =
raise newException(ValueError, "No implementation available") 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") raise newException(ValueError, "No implementation available")
method toggleTokenVisible*(self: ServiceInterface, chainId: int, symbol: string) {.base.} = 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") raise newException(ValueError, "No implementation available")
method getIndex*(self: ServiceInterface, address: string): int {.base.} = method getIndex*(self: ServiceInterface, address: string): int {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -23,9 +23,10 @@ proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
proc deleteAccount*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc deleteAccount*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_deleteAccount", %* [address]) 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", %* [ discard core.callPrivateRPC("accounts_saveAccounts", %* [
[{ [{
"emoji": emoji,
"color": color, "color": color,
"name": name, "name": name,
"address": address, "address": address,

View File

@ -11,18 +11,18 @@ proc getPendingTransactions*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [] let payload = %* []
result = core.callPrivateRPC("wallet_getPendingTransactions", payload) result = core.callPrivateRPC("wallet_getPendingTransactions", payload)
proc generateAccount*(password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc generateAccount*(password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [hashPassword(password), name, color] let payload = %* [hashPassword(password), name, color, emoji]
return core.callPrivateRPC("accounts_generateAccount", payload) return core.callPrivateRPC("accounts_generateAccount", payload)
proc addAccountWithMnemonic*(mnemonic, password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc addAccountWithMnemonic*(mnemonic, password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [mnemonic, hashPassword(password), name, color] let payload = %* [mnemonic, hashPassword(password), name, color, emoji]
return core.callPrivateRPC("accounts_addAccountWithMnemonic", payload) return core.callPrivateRPC("accounts_addAccountWithMnemonic", payload)
proc addAccountWithPrivateKey*(privateKey, password, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc addAccountWithPrivateKey*(privateKey, password, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [privateKey, hashPassword(password), name, color] let payload = %* [privateKey, hashPassword(password), name, color, emoji]
return core.callPrivateRPC("accounts_addAccountWithPrivateKey", payload) return core.callPrivateRPC("accounts_addAccountWithPrivateKey", payload)
proc addAccountWatch*(address, name, color: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc addAccountWatch*(address, name, color, emoji: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address, name, color] let payload = %* [address, name, color, emoji]
return core.callPrivateRPC("accounts_addAccountWatch", payload) return core.callPrivateRPC("accounts_addAccountWatch", payload)

@ -1 +1 @@
Subproject commit 381150a7b55d53b3cb59d9ee2c4f50985488c708 Subproject commit 428b165198e53caa5a55ef605f241cc4b6f7e02d

View File

@ -18,6 +18,7 @@ Item {
property bool hideSignPhraseModal: false property bool hideSignPhraseModal: false
property var store property var store
property var contactsStore property var contactsStore
property var emojiPopup: null
function showSigningPhrasePopup(){ function showSigningPhrasePopup(){
if(!hideSignPhraseModal && !RootStore.hideSignPhraseModal){ if(!hideSignPhraseModal && !RootStore.hideSignPhraseModal){
@ -52,6 +53,7 @@ Item {
RightTabView { RightTabView {
changeSelectedAccount: leftTab.changeSelectedAccount changeSelectedAccount: leftTab.changeSelectedAccount
store: walletView.store store: walletView.store
emojiPopup: walletView.emojiPopup
} }
} }
@ -94,6 +96,7 @@ Item {
else else
rightPanelStackView.replace(walletContainer) rightPanelStackView.replace(walletContainer)
} }
emojiPopup: walletView.emojiPopup
} }
rightPanel: StackView { rightPanel: StackView {

View File

@ -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)
}
}
}

View File

@ -21,6 +21,7 @@ Item {
property var changeSelectedAccount property var changeSelectedAccount
property var store property var store
property var walletStore property var walletStore
property var emojiPopup
height: walletAddress.y + walletAddress.height height: walletAddress.y + walletAddress.height
anchors.right: parent.right anchors.right: parent.right
@ -109,8 +110,10 @@ Item {
Component { Component {
id: accountSettingsModalComponent id: accountSettingsModalComponent
AccountSettingsModal { AccountSettingsModal {
anchors.centerIn: parent
onClosed: destroy() onClosed: destroy()
changeSelectedAccount: walletHeader.changeSelectedAccount changeSelectedAccount: walletHeader.changeSelectedAccount
emojiPopup: walletHeader.emojiPopup
} }
} }

View File

@ -6,126 +6,151 @@ import QtQuick.Dialogs 1.3
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Controls.Validators 0.1
import utils 1.0 import utils 1.0
import shared.panels 1.0
import shared.popups 1.0 import shared.popups 1.0
import shared.panels 1.0
import shared.controls 1.0 import shared.controls 1.0
import "../stores" import "../stores"
// TODO: replace with StatusModal StatusModal {
ModalPopup {
id: popup id: popup
property var currentAccount: RootStore.currentAccount property var currentAccount: RootStore.currentAccount
property var changeSelectedAccount property var changeSelectedAccount
property var emojiPopup
// TODO add icon when we have that feature
//% "Status account settings" //% "Status account settings"
title: qsTrId("status-account-settings") header.title: qsTrId("status-account-settings")
height: 675 height: 675
property int marginBetweenInputs: 35 property int marginBetweenInputs: 30
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 === ""
}
onOpened: { onOpened: {
accountNameInput.forceActiveFocus(Qt.MouseFocusReason) accountNameInput.forceActiveFocus(Qt.MouseFocusReason)
} }
Input { Connections {
id: accountNameInput enabled: popup.opened
//% "Enter an account name..." target: emojiPopup
placeholderText: qsTrId("enter-an-account-name...") onEmojiSelected: function (emojiText, atCursor) {
//% "Account name" popup.contentItem.accountNameInput.input.icon.emoji = emojiText
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
} }
anchors.top: accountColorInput.bottom
anchors.topMargin: marginBetweenInputs
} }
TextWithLabel {
id: addressText contentItem: Column {
//% "Wallet address" property alias accountNameInput: accountNameInput
label: qsTrId("wallet-address")
text: currentAccount.address width: popup.width
fontFamily: Style.current.fontHexRegular.name spacing: marginBetweenInputs
anchors.top: typeText.bottom topPadding: Style.current.padding
anchors.topMargin: marginBetweenInputs
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 { rightButtons: [
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
StatusButton { StatusButton {
visible: currentAccount.walletType === Constants.watchWalletType visible: currentAccount.walletType === Constants.watchWalletType
anchors.top: parent.top
anchors.right: saveBtn.left
anchors.rightMargin: Style.current.padding
//% "Delete account" //% "Delete account"
text: qsTrId("delete-account") text: qsTrId("delete-account")
type: StatusBaseButton.Type.Danger type: StatusBaseButton.Type.Danger
@ -157,12 +182,9 @@ ModalPopup {
onClicked : { onClicked : {
confirmationDialog.open() confirmationDialog.open()
} }
} },
StatusButton { StatusButton {
id: saveBtn id: saveBtn
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
//% "Save changes" //% "Save changes"
text: qsTrId("save-changes") text: qsTrId("save-changes")
@ -175,12 +197,12 @@ ModalPopup {
standardButtons: StandardButton.Ok standardButtons: StandardButton.Ok
} }
onClicked : { onClicked : {
if (!validate()) { if (!accountNameInput.valid) {
return 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) { if (error) {
Global.playErrorSound(); Global.playErrorSound();
@ -191,5 +213,5 @@ ModalPopup {
popup.close(); popup.close();
} }
} }
} ]
} }

View File

@ -7,25 +7,23 @@ import utils 1.0
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 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.panels 1.0
import shared.popups 1.0
import shared.controls 1.0 import shared.controls 1.0
import "../stores" import "../stores"
// TODO: replace with StatusModal StatusModal {
ModalPopup {
id: popup id: popup
//% "Add account from private key"
title: qsTrId("add-private-key-account")
height: 600
property int marginBetweenInputs: 38 property int marginBetweenInputs: 38
property string passwordValidationError: "" property string passwordValidationError: ""
property string privateKeyValidationError: "" property string privateKeyValidationError: ""
property string accountNameValidationError: ""
property bool loading: false property bool loading: false
property var emojiPopup: null
signal afterAddAccount() signal afterAddAccount()
@ -40,13 +38,6 @@ ModalPopup {
passwordValidationError = "" 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 === "") { if (accountPKeyInput.text === "") {
//% "You need to enter a private key" //% "You need to enter a private key"
privateKeyValidationError = qsTrId("you-need-to-enter-a-private-key") privateKeyValidationError = qsTrId("you-need-to-enter-a-private-key")
@ -57,119 +48,159 @@ ModalPopup {
privateKeyValidationError = "" privateKeyValidationError = ""
} }
return passwordValidationError === "" && privateKeyValidationError === "" && accountNameValidationError === "" return passwordValidationError === "" && privateKeyValidationError === "" && accountNameInput.valid
} }
//% "Add account from private key"
header.title: qsTrId("add-private-key-account")
onOpened: { onOpened: {
passwordInput.text = "" passwordInput.text = ""
accountPKeyInput.text = "" accountPKeyInput.text = ""
accountNameInput.reset()
accountNameInput.text = "" accountNameInput.text = ""
accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
passwordValidationError = "" passwordValidationError = ""
privateKeyValidationError = "" privateKeyValidationError = ""
accountNameValidationError = "" accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
accountColorInput.selectedColor = Style.current.accountColors[Math.floor(Math.random() * Style.current.accountColors.length)]
passwordInput.forceActiveFocus(Qt.MouseFocusReason) passwordInput.forceActiveFocus(Qt.MouseFocusReason)
} }
Input { Connections {
id: passwordInput enabled: popup.opened
//% "Enter your password" target: emojiPopup
placeholderText: qsTrId("enter-your-password…") onEmojiSelected: function (emojiText, atCursor) {
//% "Password" popup.contentItem.accountNameInput.input.icon.emoji = emojiText
label: qsTrId("password") }
textField.echoMode: TextInput.Password
validationError: popup.passwordValidationError
} }
StyledTextArea { contentItem: Column {
id: accountPKeyInput property alias accountNameInput: accountNameInput
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
}
Input { width: popup.width
id: accountNameInput spacing: 8
anchors.top: accountPKeyInput.bottom topPadding: 20
anchors.topMargin: marginBetweenInputs
//% "Enter an account name..."
placeholderText: qsTrId("enter-an-account-name...")
//% "Account name"
label: qsTrId("account-name")
validationError: popup.accountNameValidationError
}
StatusWalletColorSelect { Column {
id: accountColorInput width: parent.width
anchors.top: accountNameInput.bottom spacing: Style.current.xlPadding
anchors.topMargin: marginBetweenInputs // To-Do Password hidden option not supported in StatusQ StatusBaseInput
anchors.left: parent.left Input {
anchors.right: parent.right id: passwordInput
model: Theme.palette.accountColors anchors.leftMargin: Style.current.padding
} anchors.rightMargin: Style.current.padding
width: parent.width
footer: StatusButton { //% "Enter your password"
anchors.top: parent.top placeholderText: qsTrId("enter-your-password…")
anchors.right: parent.right //% "Password"
text: loading ? label: qsTrId("password")
//% "Loading..." textField.echoMode: TextInput.Password
qsTrId("loading") : validationError: popup.passwordValidationError
//% "Add account" inputLabel.font.pixelSize: 15
qsTrId("add-account") 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 !== "" validationError: popup.privateKeyValidationError
//% "Private key"
MessageDialog { label: qsTrId("private-key")
id: accountError textField.wrapMode: Text.WordWrap
title: "Adding the account failed" textField.horizontalAlignment: TextEdit.AlignHCenter
icon: StandardIcon.Critical textField.verticalAlignment: TextEdit.AlignVCenter
standardButtons: StandardButton.Ok 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 : { StatusInput {
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads id: accountNameInput
loading = true //% "Enter an account name..."
if (!validate()) { input.placeholderText: qsTrId("enter-an-account-name...")
return loading = false //% "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: [
const errMessage = RootStore.addAccountsFromPrivateKey(accountPKeyInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor) StatusMinLengthValidator {
//% "You need to enter an account name"
loading = false errorMessage: qsTrId("you-need-to-enter-an-account-name")
if (errMessage) { minLength: 1
Global.playErrorSound();
if (Utils.isInvalidPasswordMessage(errMessage)) {
//% "Wrong password"
popup.passwordValidationError = qsTrId("wrong-password")
} else {
accountError.text = errMessage
accountError.open()
} }
return ]
} }
popup.afterAddAccount()
popup.close(); StatusColorSelectorGrid {
id: accountColorInput
anchors.horizontalCenter: parent.horizontalCenter
//% "color"
titleText: qsTr("color").toUpperCase()
}
Item {
width: parent.width
height: 8
} }
} }
}
/*##^## rightButtons: [
Designer { StatusButton {
D{i:0;formeditorColor:"#ffffff";height:500;width:400} 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();
}
}
]
} }
##^##*/

View File

@ -7,22 +7,21 @@ import utils 1.0
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 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 shared.controls 1.0
import "../stores" import "../stores"
// TODO: replace with StatusModal StatusModal {
ModalPopup {
id: popup id: popup
height: 615
property int marginBetweenInputs: 38
property string passwordValidationError: "" property string passwordValidationError: ""
property string seedValidationError: "" property string seedValidationError: ""
property string accountNameValidationError: ""
property bool loading: false property bool loading: false
property var emojiPopup: null
signal afterAddAccount() signal afterAddAccount()
@ -43,13 +42,6 @@ ModalPopup {
passwordValidationError = "" 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 === "") { if (seedPhraseTextArea.textArea.text === "") {
//% "You need to enter a seed phrase" //% "You need to enter a seed phrase"
seedValidationError = qsTrId("you-need-to-enter-a-seed-phrase") seedValidationError = qsTrId("you-need-to-enter-a-seed-phrase")
@ -60,102 +52,144 @@ ModalPopup {
seedValidationError = "" seedValidationError = ""
} }
return passwordValidationError === "" && seedValidationError === "" && accountNameValidationError === "" return passwordValidationError === "" && seedValidationError === "" && accountNameInput.valid
}
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)
} }
//% "Add account with a seed phrase" //% "Add account with a seed phrase"
title: qsTrId("add-seed-account") header.title: qsTrId("add-seed-account")
Input { onOpened: {
id: passwordInput seedPhraseTextArea.textArea.text = ""
//% "Enter your password" passwordInput.text = ""
placeholderText: qsTrId("enter-your-password…") accountNameInput.text = ""
//% "Password" accountNameInput.reset()
label: qsTrId("password") accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
textField.echoMode: TextInput.Password passwordValidationError = ""
validationError: popup.passwordValidationError seedValidationError = ""
accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
} }
SeedPhraseTextArea { Connections {
id: seedPhraseTextArea enabled: popup.opened
anchors.top: passwordInput.bottom target: emojiPopup
anchors.topMargin: marginBetweenInputs onEmojiSelected: function (emojiText, atCursor) {
width: parent.width popup.contentItem.accountNameInput.input.icon.emoji = emojiText
}
} }
Input { contentItem: Column {
id: accountNameInput property alias accountNameInput: 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
}
StatusWalletColorSelect { width: popup.width
id: accountColorInput spacing: 8
anchors.top: accountNameInput.bottom topPadding: 20
anchors.topMargin: marginBetweenInputs
anchors.left: parent.left
anchors.right: parent.right
model: Theme.palette.accountColors
}
footer: StatusButton { Column {
anchors.top: parent.top width: parent.width
anchors.right: parent.right spacing: Style.current.xlPadding
text: loading ? // To-Do Password hidden option not supported in StatusQ StatusBaseInput
//% "Loading..." Input {
qsTrId("loading") : id: passwordInput
//% "Add account" anchors.leftMargin: Style.current.padding
qsTrId("add-account") anchors.rightMargin: Style.current.padding
width: parent.width
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== "" && seedPhraseTextArea.correctWordCount //% "Enter your password"
placeholderText: qsTrId("enter-your-password…")
MessageDialog { //% "Password"
id: accountError label: qsTrId("password")
title: "Adding the account failed" textField.echoMode: TextInput.Password
icon: StandardIcon.Critical validationError: popup.passwordValidationError
standardButtons: StandardButton.Ok 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 : { StatusInput {
// TODO the loading doesn't work because the function freezes the view. Might need to use threads id: accountNameInput
loading = true //% "Enter an account name..."
if (!validate() || !seedPhraseTextArea.validateSeed()) { input.placeholderText: qsTrId("enter-an-account-name...")
Global.playErrorSound(); //% "Account name"
return loading = false 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: [
const errMessage = RootStore.addAccountsFromSeed(seedPhraseTextArea.textArea.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor) StatusMinLengthValidator {
loading = false //% "You need to enter an account name"
if (errMessage) { errorMessage: qsTrId("you-need-to-enter-an-account-name")
Global.playErrorSound(); minLength: 1
if (Utils.isInvalidPasswordMessage(errMessage)) {
//% "Wrong password"
popup.passwordValidationError = qsTrId("wrong-password")
} else {
accountError.text = errMessage
accountError.open()
} }
return ]
} }
popup.afterAddAccount()
popup.reset() StatusColorSelectorGrid {
popup.close(); 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();
}
}
]
} }

View File

@ -6,121 +6,140 @@ import utils 1.0
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
import StatusQ.Controls 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 shared.controls 1.0
import "../stores" import "../stores"
// TODO: replace with StatusModal StatusModal {
ModalPopup {
id: popup 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 bool loading: false
property var emojiPopup: null
signal afterAddAccount() signal afterAddAccount()
function validate() { //% "Add a watch-only account"
if (addressInput.text === "") { header.title: qsTrId("add-watch-account")
//% "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 === ""
}
onOpened: { onOpened: {
addressError = ""; addressInput.text = ""
accountNameValidationError = ""; addressInput.reset()
addressInput.text = ""; accountNameInput.text = ""
accountNameInput.text = ""; accountNameInput.reset()
accountColorInput.selectedColor = Style.current.accountColors[Math.floor(Math.random() * Style.current.accountColors.length)] accountNameInput.input.icon.emoji = StatusQUtils.Emoji.getRandomEmoji()
accountColorInput.selectedColorIndex = Math.floor(Math.random() * accountColorInput.model.length)
addressInput.forceActiveFocus(Qt.MouseFocusReason) addressInput.forceActiveFocus(Qt.MouseFocusReason)
} }
Input { Connections {
id: addressInput enabled: popup.opened
// TODO add QR code reader for the address target: emojiPopup
//% "Enter address..." onEmojiSelected: function (emojiText, atCursor) {
placeholderText: qsTrId("enter-address...") popup.contentItem.accountNameInput.input.icon.emoji = emojiText
//% "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();
} }
} }
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();
}
}
]
} }

View File

@ -6,26 +6,28 @@ import utils 1.0
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Controls 0.1 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 shared.controls 1.0
import "../stores" import "../stores"
// TODO: replace with StatusModal StatusModal {
ModalPopup {
id: popup id: popup
//% "Generate an account"
title: qsTrId("generate-a-new-account")
property int marginBetweenInputs: 38 property int marginBetweenInputs: 38
property string passwordValidationError: "" property string passwordValidationError: ""
property string accountNameValidationError: ""
property bool loading: false property bool loading: false
property var emojiPopup: null
signal afterAddAccount() signal afterAddAccount()
//% "Generate an account"
header.title: qsTrId("generate-a-new-account")
function validate() { function validate() {
if (passwordInput.text === "") { if (passwordInput.text === "") {
//% "You need to enter a password" //% "You need to enter a password"
@ -36,98 +38,131 @@ ModalPopup {
} else { } else {
passwordValidationError = "" passwordValidationError = ""
} }
return passwordValidationError === "" && accountNameInput.valid
if (accountNameInput.text === "") {
//% "You need to enter an account name"
accountNameValidationError = qsTrId("you-need-to-enter-an-account-name")
} else {
accountNameValidationError = ""
} }
return passwordValidationError === "" && accountNameValidationError === ""
}
onOpened: { onOpened: {
passwordValidationError = ""; passwordValidationError = "";
accountNameValidationError = "";
passwordInput.text = ""; passwordInput.text = "";
accountNameInput.reset()
accountNameInput.text = ""; 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) passwordInput.forceActiveFocus(Qt.MouseFocusReason)
} }
Input { Connections {
id: passwordInput enabled: popup.opened
//% "Enter your password" target: emojiPopup
placeholderText: qsTrId("enter-your-password…") onEmojiSelected: function (emojiText, atCursor) {
//% "Password" popup.contentItem.accountNameInput.input.icon.emoji = emojiText
label: qsTrId("password") }
textField.echoMode: TextInput.Password
validationError: popup.passwordValidationError
} }
Input { contentItem: Column {
id: accountNameInput property alias accountNameInput: accountNameInput
anchors.top: passwordInput.bottom width: popup.width
anchors.topMargin: marginBetweenInputs spacing: 8
//% "Enter an account name..." topPadding: 20
placeholderText: qsTrId("enter-an-account-name...")
//% "Account name"
label: qsTrId("account-name")
validationError: popup.accountNameValidationError
}
StatusWalletColorSelect { // To-Do Password hidden option not supported in StatusQ StatusBaseInput
id: accountColorInput Item {
selectedColor: Theme.palette.accountColors[0] width: parent.width
anchors.top: accountNameInput.bottom height: passwordInput.height
anchors.topMargin: marginBetweenInputs Input {
width: parent.width id: passwordInput
model: Theme.palette.accountColors anchors.fill: parent
} anchors.leftMargin: Style.current.padding
anchors.rightMargin: Style.current.padding
footer: StatusButton { //% "Enter your password"
anchors.top: parent.top placeholderText: qsTrId("enter-your-password…")
anchors.right: parent.right //% "Password"
text: loading ? label: qsTrId("password")
//% "Loading..." textField.echoMode: TextInput.Password
qsTrId("loading") : validationError: popup.passwordValidationError
//% "Add account" inputLabel.font.pixelSize: 15
qsTrId("add-account") inputLabel.font.weight: Font.Normal
}
enabled: !loading && passwordInput.text !== "" && accountNameInput.text !== ""
MessageDialog {
id: accountError
title: "Adding the account failed"
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
} }
onClicked : { StatusInput {
// TODO the loaidng doesn't work because the function freezes th eview. Might need to use threads id: accountNameInput
loading = true //% "Enter an account name..."
if (!validate()) { input.placeholderText: qsTrId("enter-an-account-name...")
Global.playErrorSound(); //% "Account name"
return loading = false 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
} }
validators: [
const errMessage = RootStore.generateNewAccount(passwordInput.text, accountNameInput.text, accountColorInput.selectedColor) StatusMinLengthValidator {
console.log(errMessage) //% "You need to enter an account name"
loading = false errorMessage: qsTrId("you-need-to-enter-an-account-name")
if (errMessage) { minLength: 1
Global.playErrorSound();
if (Utils.isInvalidPasswordMessage(errMessage)) {
//% "Wrong password"
popup.passwordValidationError = qsTrId("wrong-password")
} else {
accountError.text = errMessage;
accountError.open();
} }
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();
}
}
]
} }

View File

@ -105,28 +105,28 @@ QtObject {
walletSection.switchAccount(newIndex) walletSection.switchAccount(newIndex)
} }
function generateNewAccount(password, accountName, color) { function generateNewAccount(password, accountName, color, emoji) {
return walletSectionAccounts.generateNewAccount(password, accountName, color) return walletSectionAccounts.generateNewAccount(password, accountName, color, emoji)
} }
function addAccountsFromPrivateKey(privateKey, password, accountName, color) { function addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji) {
return walletSectionAccounts.addAccountsFromPrivateKey(privateKey, password, accountName, color) return walletSectionAccounts.addAccountsFromPrivateKey(privateKey, password, accountName, color, emoji)
} }
function addAccountsFromSeed(seedPhrase, password, accountName, color) { function addAccountsFromSeed(seedPhrase, password, accountName, color, emoji) {
return walletSectionAccounts.addAccountsFromSeed(seedPhrase, password, accountName, color) return walletSectionAccounts.addAccountsFromSeed(seedPhrase, password, accountName, color, emoji)
} }
function addWatchOnlyAccount(address, accountName, color) { function addWatchOnlyAccount(address, accountName,color, emoji) {
return walletSectionAccounts.addWatchOnlyAccount(address, accountName, color) return walletSectionAccounts.addWatchOnlyAccount(address, accountName, color, emoji)
} }
function deleteAccount(address) { function deleteAccount(address) {
return walletSectionAccounts.deleteAccount(address) return walletSectionAccounts.deleteAccount(address)
} }
function updateCurrentAccount(address, accountName, color) { function updateCurrentAccount(address, accountName, color, emoji) {
return walletSectionCurrent.update(address, accountName, color) return walletSectionCurrent.update(address, accountName, color, emoji)
} }
function updateCurrency(newCurrency) { function updateCurrency(newCurrency) {

View File

@ -9,6 +9,7 @@ import shared.panels 1.0
import shared.controls 1.0 import shared.controls 1.0
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import "../controls" import "../controls"
import "../popups" import "../popups"
@ -20,6 +21,7 @@ Rectangle {
property int selectedAccountIndex: 0 property int selectedAccountIndex: 0
property var changeSelectedAccount: function(){} property var changeSelectedAccount: function(){}
property var showSavedAddresses: function(showSavedAddresses){} property var showSavedAddresses: function(showSavedAddresses){}
property var emojiPopup: null
function onAfterAddAccount () { function onAfterAddAccount () {
walletInfoContainer.changeSelectedAccount(RootStore.accounts.rowCount() - 1) walletInfoContainer.changeSelectedAccount(RootStore.accounts.rowCount() - 1)
@ -111,22 +113,30 @@ Rectangle {
GenerateAccountModal { GenerateAccountModal {
id: generateAccountModal id: generateAccountModal
anchors.centerIn: parent
onAfterAddAccount: walletInfoContainer.onAfterAddAccount() onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
emojiPopup: walletInfoContainer.emojiPopup
} }
AddAccountWithSeedModal { AddAccountWithSeedModal {
id: addAccountWithSeedModal id: addAccountWithSeedModal
anchors.centerIn: parent
onAfterAddAccount: walletInfoContainer.onAfterAddAccount() onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
emojiPopup: walletInfoContainer.emojiPopup
} }
AddAccountWithPrivateKeyModal { AddAccountWithPrivateKeyModal {
id: addAccountWithPrivateKeydModal id: addAccountWithPrivateKeydModal
anchors.centerIn: parent
onAfterAddAccount: walletInfoContainer.onAfterAddAccount() onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
emojiPopup: walletInfoContainer.emojiPopup
} }
AddWatchOnlyAccountModal { AddWatchOnlyAccountModal {
id: addWatchOnlyAccountModal id: addWatchOnlyAccountModal
anchors.centerIn: parent
onAfterAddAccount: walletInfoContainer.onAfterAddAccount() onAfterAddAccount: walletInfoContainer.onAfterAddAccount()
emojiPopup: walletInfoContainer.emojiPopup
} }
ScrollView { ScrollView {
@ -134,8 +144,8 @@ Rectangle {
anchors.bottomMargin: btnSavedAddresses.height + Style.current.padding anchors.bottomMargin: btnSavedAddresses.height + Style.current.padding
anchors.top: walletValueTextContainer.bottom anchors.top: walletValueTextContainer.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
anchors.right: parent.right anchors.horizontalCenter: parent.horizontalCenter
anchors.left: parent.left width: 272
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: listView.contentHeight > listView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff ScrollBar.vertical.policy: listView.contentHeight > listView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
clip: true clip: true
@ -150,10 +160,17 @@ Rectangle {
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
clip: true clip: true
delegate: WalletDelegate { delegate: StatusListItem {
currency: RootStore.currentCurrency width: parent.width
locale: RootStore.locale highlighted: index === selectedAccountIndex
selectedAccountIndex: walletInfoContainer.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: { onClicked: {
changeSelectedAccount(index) changeSelectedAccount(index)
showSavedAddresses(false) showSavedAddresses(false)

View File

@ -19,6 +19,7 @@ Item {
property var changeSelectedAccount property var changeSelectedAccount
property alias currentTabIndex: walletTabBar.currentIndex property alias currentTabIndex: walletTabBar.currentIndex
property var store property var store
property var emojiPopup
WalletHeader { WalletHeader {
id: walletHeader id: walletHeader
@ -28,6 +29,7 @@ Item {
changeSelectedAccount: walletContainer.changeSelectedAccount changeSelectedAccount: walletContainer.changeSelectedAccount
store: walletContainer.store store: walletContainer.store
walletStore: RootStore walletStore: RootStore
emojiPopup: walletContainer.emojiPopup
} }
RowLayout { RowLayout {

View File

@ -497,6 +497,7 @@ Item {
Layout.fillHeight: true Layout.fillHeight: true
store: appMain.rootStore store: appMain.rootStore
contactsStore: appMain.rootStore.profileSectionStore.contactsStore contactsStore: appMain.rootStore.profileSectionStore.contactsStore
emojiPopup: statusEmojiPopup
} }
Component { Component {