mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-25 13:06:08 +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] =
|
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)
|
||||||
|
@ -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.} =
|
||||||
|
@ -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.} =
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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))
|
||||||
|
@ -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.} =
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
@ -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 {
|
||||||
|
@ -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 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
|
||||||
@ -176,11 +198,11 @@ ModalPopup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
##^##*/
|
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user