mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-11-16 17:27:37 +00:00
Cw 426 replace trash and swipe with edit icons (#974)
* feat: Replace trash and swipe with edit icons on node list item - replaces yellow Test button with red Delete node button with confirmation on the edit node page * feat: make node indicator icons bigger (figma comment) * feat: Replace trash and swipe with edit icons on wallet list page and create wallet_edit_page.dart * fix: make delete buttons red * fix: make wallet name wrap when it is too long * refactor: improve logic & fix observer not refreshing * fix: add string * feat: remove the confirmation pop-up for switching between wallets - which was another item on the jira issue * fix: remove slideable widgets from node list * feat: add edit button to currently selected node & disable deleting if selected * fix: rename wallet also renames to new wallet files * feat: make sure edits can't overlap existing names * fix: improve rename flow, fix electrum transactions refresh & add delete old logic * fix: also fix rename for monero & haven * refactor: fix identations * refactor: dont declare the current wallet twice * refactor: missing newWalletInfo.id * fix: dont unnecessarily load the current wallet * fix: remove unnecessary reaction * feat: make save button disabled until the text is changed * feat: make walletEditViewModel and make state useful for pending actions * fix: add back reaction for desktop flow * - Remove un-necessary code - Format Edit page --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
bb6dea0292
commit
d4969633b0
48 changed files with 670 additions and 249 deletions
|
@ -52,9 +52,32 @@ class BitcoinWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> remove(String wallet) async =>
|
Future<void> remove(String wallet) async {
|
||||||
File(await pathForWalletDir(name: wallet, type: WalletType.bitcoin))
|
File(await pathForWalletDir(name: wallet, type: getType()))
|
||||||
.delete(recursive: true);
|
.delete(recursive: true);
|
||||||
|
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||||
|
(info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||||
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rename(String currentName, String password, String newName) async {
|
||||||
|
final currentWalletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||||
|
(info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||||
|
final currentWallet = await BitcoinWalletBase.open(
|
||||||
|
password: password,
|
||||||
|
name: currentName,
|
||||||
|
walletInfo: currentWalletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||||
|
|
||||||
|
await currentWallet.renameWalletFiles(newName);
|
||||||
|
|
||||||
|
final newWalletInfo = currentWalletInfo;
|
||||||
|
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||||
|
newWalletInfo.name = newName;
|
||||||
|
|
||||||
|
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<BitcoinWallet> restoreFromKeys(
|
Future<BitcoinWallet> restoreFromKeys(
|
||||||
|
|
|
@ -9,7 +9,7 @@ import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||||
|
|
||||||
part 'electrum_transaction_history.g.dart';
|
part 'electrum_transaction_history.g.dart';
|
||||||
|
|
||||||
const _transactionsHistoryFileName = 'transactions.json';
|
const transactionsHistoryFileName = 'transactions.json';
|
||||||
|
|
||||||
class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
|
class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
|
||||||
with _$ElectrumTransactionHistory;
|
with _$ElectrumTransactionHistory;
|
||||||
|
@ -42,7 +42,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
try {
|
try {
|
||||||
final dirPath =
|
final dirPath =
|
||||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
final path = '$dirPath/$transactionsHistoryFileName';
|
||||||
final data =
|
final data =
|
||||||
json.encode({'height': _height, 'transactions': transactions});
|
json.encode({'height': _height, 'transactions': transactions});
|
||||||
await writeData(path: path, password: _password, data: data);
|
await writeData(path: path, password: _password, data: data);
|
||||||
|
@ -59,7 +59,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
Future<Map<String, dynamic>> _read() async {
|
Future<Map<String, dynamic>> _read() async {
|
||||||
final dirPath =
|
final dirPath =
|
||||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
final path = '$dirPath/$transactionsHistoryFileName';
|
||||||
final content = await read(path: path, password: _password);
|
final content = await read(path: path, password: _password);
|
||||||
return json.decode(content) as Map<String, dynamic>;
|
return json.decode(content) as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -430,6 +431,28 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
await transactionHistory.save();
|
await transactionHistory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> renameWalletFiles(String newWalletName) async {
|
||||||
|
final currentWalletPath = await pathForWallet(name: walletInfo.name, type: type);
|
||||||
|
final currentWalletFile = File(currentWalletPath);
|
||||||
|
|
||||||
|
final currentDirPath =
|
||||||
|
await pathForWalletDir(name: walletInfo.name, type: type);
|
||||||
|
final currentTransactionsFile = File('$currentDirPath/$transactionsHistoryFileName');
|
||||||
|
|
||||||
|
// Copies current wallet files into new wallet name's dir and files
|
||||||
|
if (currentWalletFile.existsSync()) {
|
||||||
|
final newWalletPath = await pathForWallet(name: newWalletName, type: type);
|
||||||
|
await currentWalletFile.copy(newWalletPath);
|
||||||
|
}
|
||||||
|
if (currentTransactionsFile.existsSync()) {
|
||||||
|
final newDirPath = await pathForWalletDir(name: newWalletName, type: type);
|
||||||
|
await currentTransactionsFile.copy('$newDirPath/$transactionsHistoryFileName');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete old name's dir and files
|
||||||
|
await Directory(currentDirPath).delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> changePassword(String password) async {
|
Future<void> changePassword(String password) async {
|
||||||
_password = password;
|
_password = password;
|
||||||
|
|
|
@ -53,9 +53,32 @@ class LitecoinWalletService extends WalletService<
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> remove(String wallet) async =>
|
Future<void> remove(String wallet) async {
|
||||||
File(await pathForWalletDir(name: wallet, type: getType()))
|
File(await pathForWalletDir(name: wallet, type: getType()))
|
||||||
.delete(recursive: true);
|
.delete(recursive: true);
|
||||||
|
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||||
|
(info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||||
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rename(String currentName, String password, String newName) async {
|
||||||
|
final currentWalletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||||
|
(info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||||
|
final currentWallet = await LitecoinWalletBase.open(
|
||||||
|
password: password,
|
||||||
|
name: currentName,
|
||||||
|
walletInfo: currentWalletInfo,
|
||||||
|
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||||
|
|
||||||
|
await currentWallet.renameWalletFiles(newName);
|
||||||
|
|
||||||
|
final newWalletInfo = currentWalletInfo;
|
||||||
|
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||||
|
newWalletInfo.name = newName;
|
||||||
|
|
||||||
|
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<LitecoinWallet> restoreFromKeys(
|
Future<LitecoinWallet> restoreFromKeys(
|
||||||
|
|
|
@ -17,4 +17,6 @@ abstract class WalletService<N extends WalletCredentials,
|
||||||
Future<bool> isWalletExit(String name);
|
Future<bool> isWalletExit(String name);
|
||||||
|
|
||||||
Future<void> remove(String wallet);
|
Future<void> remove(String wallet);
|
||||||
|
|
||||||
|
Future<void> rename(String name, String password, String newName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
|
@ -251,6 +253,29 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
||||||
await haven_wallet.store();
|
await haven_wallet.store();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> renameWalletFiles(String newWalletName) async {
|
||||||
|
final currentWalletPath = await pathForWallet(name: name, type: type);
|
||||||
|
final currentCacheFile = File(currentWalletPath);
|
||||||
|
final currentKeysFile = File('$currentWalletPath.keys');
|
||||||
|
final currentAddressListFile = File('$currentWalletPath.address.txt');
|
||||||
|
|
||||||
|
final newWalletPath = await pathForWallet(name: newWalletName, type: type);
|
||||||
|
|
||||||
|
// Copies current wallet files into new wallet name's dir and files
|
||||||
|
if (currentCacheFile.existsSync()) {
|
||||||
|
await currentCacheFile.copy(newWalletPath);
|
||||||
|
}
|
||||||
|
if (currentKeysFile.existsSync()) {
|
||||||
|
await currentKeysFile.copy('$newWalletPath.keys');
|
||||||
|
}
|
||||||
|
if (currentAddressListFile.existsSync()) {
|
||||||
|
await currentAddressListFile.copy('$newWalletPath.address.txt');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete old name's dir and files
|
||||||
|
await Directory(currentWalletPath).delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> changePassword(String password) async {
|
Future<void> changePassword(String password) async {
|
||||||
haven_wallet.setPasswordSync(password);
|
haven_wallet.setPasswordSync(password);
|
||||||
|
|
|
@ -149,6 +149,26 @@ class HavenWalletService extends WalletService<
|
||||||
if (isExist) {
|
if (isExist) {
|
||||||
await file.delete(recursive: true);
|
await file.delete(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final walletInfo = walletInfoSource.values
|
||||||
|
.firstWhere((info) => info.id == WalletBase.idFor(wallet, getType()));
|
||||||
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rename(
|
||||||
|
String currentName, String password, String newName) async {
|
||||||
|
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||||
|
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||||
|
final currentWallet = HavenWallet(walletInfo: currentWalletInfo);
|
||||||
|
|
||||||
|
await currentWallet.renameWalletFiles(newName);
|
||||||
|
|
||||||
|
final newWalletInfo = currentWalletInfo;
|
||||||
|
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||||
|
newWalletInfo.name = newName;
|
||||||
|
|
||||||
|
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/transaction_priority.dart';
|
import 'package:cw_core/transaction_priority.dart';
|
||||||
import 'package:cw_core/monero_amount_format.dart';
|
import 'package:cw_core/monero_amount_format.dart';
|
||||||
import 'package:cw_monero/monero_transaction_creation_exception.dart';
|
import 'package:cw_monero/monero_transaction_creation_exception.dart';
|
||||||
|
@ -6,7 +8,6 @@ import 'package:cw_monero/monero_transaction_info.dart';
|
||||||
import 'package:cw_monero/monero_wallet_addresses.dart';
|
import 'package:cw_monero/monero_wallet_addresses.dart';
|
||||||
import 'package:cw_core/monero_wallet_utils.dart';
|
import 'package:cw_core/monero_wallet_utils.dart';
|
||||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_monero/api/transaction_history.dart'
|
import 'package:cw_monero/api/transaction_history.dart'
|
||||||
as monero_transaction_history;
|
as monero_transaction_history;
|
||||||
|
@ -267,6 +268,29 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
await monero_wallet.store();
|
await monero_wallet.store();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> renameWalletFiles(String newWalletName) async {
|
||||||
|
final currentWalletPath = await pathForWallet(name: name, type: type);
|
||||||
|
final currentCacheFile = File(currentWalletPath);
|
||||||
|
final currentKeysFile = File('$currentWalletPath.keys');
|
||||||
|
final currentAddressListFile = File('$currentWalletPath.address.txt');
|
||||||
|
|
||||||
|
final newWalletPath = await pathForWallet(name: newWalletName, type: type);
|
||||||
|
|
||||||
|
// Copies current wallet files into new wallet name's dir and files
|
||||||
|
if (currentCacheFile.existsSync()) {
|
||||||
|
await currentCacheFile.copy(newWalletPath);
|
||||||
|
}
|
||||||
|
if (currentKeysFile.existsSync()) {
|
||||||
|
await currentKeysFile.copy('$newWalletPath.keys');
|
||||||
|
}
|
||||||
|
if (currentAddressListFile.existsSync()) {
|
||||||
|
await currentAddressListFile.copy('$newWalletPath.address.txt');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete old name's dir and files
|
||||||
|
await Directory(currentWalletPath).delete(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> changePassword(String password) async {
|
Future<void> changePassword(String password) async {
|
||||||
monero_wallet.setPasswordSync(password);
|
monero_wallet.setPasswordSync(password);
|
||||||
|
|
|
@ -146,6 +146,26 @@ class MoneroWalletService extends WalletService<
|
||||||
if (isExist) {
|
if (isExist) {
|
||||||
await file.delete(recursive: true);
|
await file.delete(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final walletInfo = walletInfoSource.values
|
||||||
|
.firstWhere((info) => info.id == WalletBase.idFor(wallet, getType()));
|
||||||
|
await walletInfoSource.delete(walletInfo.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> rename(
|
||||||
|
String currentName, String password, String newName) async {
|
||||||
|
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||||
|
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||||
|
final currentWallet = MoneroWallet(walletInfo: currentWalletInfo);
|
||||||
|
|
||||||
|
await currentWallet.renameWalletFiles(newName);
|
||||||
|
|
||||||
|
final newWalletInfo = currentWalletInfo;
|
||||||
|
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||||
|
newWalletInfo.name = newName;
|
||||||
|
|
||||||
|
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -21,4 +21,11 @@ class KeyService {
|
||||||
|
|
||||||
await _secureStorage.write(key: key, value: encodedPassword);
|
await _secureStorage.write(key: key, value: encodedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteWalletPassword({required String walletName}) async {
|
||||||
|
final key = generateStoreKeyFor(
|
||||||
|
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
||||||
|
|
||||||
|
await _secureStorage.delete(key: key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,43 +7,58 @@ import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class WalletLoadingService {
|
class WalletLoadingService {
|
||||||
WalletLoadingService(
|
WalletLoadingService(
|
||||||
this.sharedPreferences,
|
this.sharedPreferences, this.keyService, this.walletServiceFactory);
|
||||||
this.keyService,
|
|
||||||
this.walletServiceFactory);
|
|
||||||
|
|
||||||
final SharedPreferences sharedPreferences;
|
|
||||||
final KeyService keyService;
|
|
||||||
final WalletService Function(WalletType type) walletServiceFactory;
|
|
||||||
|
|
||||||
Future<WalletBase> load(WalletType type, String name) async {
|
final SharedPreferences sharedPreferences;
|
||||||
final walletService = walletServiceFactory.call(type);
|
final KeyService keyService;
|
||||||
final password = await keyService.getWalletPassword(walletName: name);
|
final WalletService Function(WalletType type) walletServiceFactory;
|
||||||
final wallet = await walletService.openWallet(name, password);
|
|
||||||
|
|
||||||
if (type == WalletType.monero) {
|
Future<void> renameWallet(
|
||||||
await updateMoneroWalletPassword(wallet);
|
WalletType type, String name, String newName) async {
|
||||||
}
|
final walletService = walletServiceFactory.call(type);
|
||||||
|
final password = await keyService.getWalletPassword(walletName: name);
|
||||||
|
|
||||||
return wallet;
|
// Save the current wallet's password to the new wallet name's key
|
||||||
}
|
await keyService.saveWalletPassword(
|
||||||
|
walletName: newName, password: password);
|
||||||
|
// Delete previous wallet name from keyService to keep only new wallet's name
|
||||||
|
// otherwise keeps duplicate (old and new names)
|
||||||
|
await keyService.deleteWalletPassword(walletName: name);
|
||||||
|
|
||||||
Future<void> updateMoneroWalletPassword(WalletBase wallet) async {
|
await walletService.rename(name, password, newName);
|
||||||
final key = PreferencesKey.moneroWalletUpdateV1Key(wallet.name);
|
}
|
||||||
var isPasswordUpdated = sharedPreferences.getBool(key) ?? false;
|
|
||||||
|
|
||||||
if (isPasswordUpdated) {
|
Future<WalletBase> load(WalletType type, String name) async {
|
||||||
return;
|
final walletService = walletServiceFactory.call(type);
|
||||||
}
|
final password = await keyService.getWalletPassword(walletName: name);
|
||||||
|
final wallet = await walletService.openWallet(name, password);
|
||||||
|
|
||||||
final password = generateWalletPassword();
|
if (type == WalletType.monero) {
|
||||||
// Save new generated password with backup key for case where
|
await updateMoneroWalletPassword(wallet);
|
||||||
// wallet will change password, but it will fail to update in secure storage
|
}
|
||||||
final bakWalletName = '#__${wallet.name}_bak__#';
|
|
||||||
await keyService.saveWalletPassword(walletName: bakWalletName, password: password);
|
return wallet;
|
||||||
await wallet.changePassword(password);
|
}
|
||||||
await keyService.saveWalletPassword(walletName: wallet.name, password: password);
|
|
||||||
isPasswordUpdated = true;
|
Future<void> updateMoneroWalletPassword(WalletBase wallet) async {
|
||||||
await sharedPreferences.setBool(key, isPasswordUpdated);
|
final key = PreferencesKey.moneroWalletUpdateV1Key(wallet.name);
|
||||||
}
|
var isPasswordUpdated = sharedPreferences.getBool(key) ?? false;
|
||||||
|
|
||||||
|
if (isPasswordUpdated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final password = generateWalletPassword();
|
||||||
|
// Save new generated password with backup key for case where
|
||||||
|
// wallet will change password, but it will fail to update in secure storage
|
||||||
|
final bakWalletName = '#__${wallet.name}_bak__#';
|
||||||
|
await keyService.saveWalletPassword(
|
||||||
|
walletName: bakWalletName, password: password);
|
||||||
|
await wallet.changePassword(password);
|
||||||
|
await keyService.saveWalletPassword(
|
||||||
|
walletName: wallet.name, password: password);
|
||||||
|
isPasswordUpdated = true;
|
||||||
|
await sharedPreferences.setBool(key, isPasswordUpdated);
|
||||||
|
}
|
||||||
}
|
}
|
18
lib/di.dart
18
lib/di.dart
|
@ -31,6 +31,7 @@ import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
|
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
|
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
|
||||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
|
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
|
||||||
import 'package:cake_wallet/themes/theme_list.dart';
|
import 'package:cake_wallet/themes/theme_list.dart';
|
||||||
import 'package:cake_wallet/utils/device_info.dart';
|
import 'package:cake_wallet/utils/device_info.dart';
|
||||||
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
||||||
|
@ -67,6 +68,8 @@ import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart
|
||||||
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
|
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
|
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:cake_wallet/core/backup_service.dart';
|
import 'package:cake_wallet/core/backup_service.dart';
|
||||||
import 'package:cw_core/wallet_service.dart';
|
import 'package:cw_core/wallet_service.dart';
|
||||||
|
@ -566,6 +569,21 @@ Future setup({
|
||||||
authService: getIt.get<AuthService>(),
|
authService: getIt.get<AuthService>(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<WalletEditViewModel, WalletListViewModel, void>(
|
||||||
|
(WalletListViewModel walletListViewModel, _) => WalletEditViewModel(
|
||||||
|
walletListViewModel, getIt.get<WalletLoadingService>()));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<WalletEditPage, List<dynamic>, void>((args, _) {
|
||||||
|
final walletListViewModel = args.first as WalletListViewModel;
|
||||||
|
final editingWallet = args.last as WalletListItem;
|
||||||
|
return WalletEditPage(
|
||||||
|
walletEditViewModel: getIt.get<WalletEditViewModel>(param1: walletListViewModel),
|
||||||
|
authService: getIt.get<AuthService>(),
|
||||||
|
walletNewVM: getIt.get<WalletNewVM>(param1: editingWallet.type),
|
||||||
|
editingWallet: editingWallet);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
getIt.registerFactory(() {
|
getIt.registerFactory(() {
|
||||||
final wallet = getIt.get<AppStore>().wallet!;
|
final wallet = getIt.get<AppStore>().wallet!;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -63,6 +64,7 @@ import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/receive/receive_page.dart';
|
import 'package:cake_wallet/src/screens/receive/receive_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
|
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
|
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
|
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
|
import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/restore_options_page.dart';
|
import 'package:cake_wallet/src/screens/restore/restore_options_page.dart';
|
||||||
|
@ -260,6 +262,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
|
fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
|
||||||
|
|
||||||
|
case Routes.walletEdit:
|
||||||
|
return MaterialPageRoute<void>(
|
||||||
|
fullscreenDialog: true,
|
||||||
|
builder: (_) => getIt.get<WalletEditPage>(
|
||||||
|
param1: settings.arguments as List<dynamic>));
|
||||||
|
|
||||||
case Routes.auth:
|
case Routes.auth:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
|
|
|
@ -11,6 +11,7 @@ class Routes {
|
||||||
static const transactionDetails = '/transaction_info';
|
static const transactionDetails = '/transaction_info';
|
||||||
static const receive = '/receive';
|
static const receive = '/receive';
|
||||||
static const newSubaddress = '/new_subaddress';
|
static const newSubaddress = '/new_subaddress';
|
||||||
|
static const walletEdit = '/walletEdit';
|
||||||
static const disclaimer = '/disclaimer';
|
static const disclaimer = '/disclaimer';
|
||||||
static const readDisclaimer = '/read_disclaimer';
|
static const readDisclaimer = '/read_disclaimer';
|
||||||
static const seedLanguage = '/seed_language';
|
static const seedLanguage = '/seed_language';
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
|
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -122,17 +124,35 @@ class NodeCreateOrEditPage extends BasePage {
|
||||||
padding: EdgeInsets.only(right: 8.0),
|
padding: EdgeInsets.only(right: 8.0),
|
||||||
child: LoadingPrimaryButton(
|
child: LoadingPrimaryButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
|
final confirmed = await showPopUp<bool>(
|
||||||
return;
|
context: context,
|
||||||
}
|
builder: (BuildContext context) {
|
||||||
|
return AlertWithTwoActions(
|
||||||
|
alertTitle:
|
||||||
|
S.of(context).remove_node,
|
||||||
|
alertContent: S
|
||||||
|
.of(context)
|
||||||
|
.remove_node_message,
|
||||||
|
rightButtonText:
|
||||||
|
S.of(context).remove,
|
||||||
|
leftButtonText:
|
||||||
|
S.of(context).cancel,
|
||||||
|
actionRightButton: () =>
|
||||||
|
Navigator.pop(context, true),
|
||||||
|
actionLeftButton: () =>
|
||||||
|
Navigator.pop(context, false));
|
||||||
|
}) ??
|
||||||
|
false;
|
||||||
|
|
||||||
await nodeCreateOrEditViewModel.connect();
|
if (confirmed) {
|
||||||
|
await editingNode!.delete();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
isLoading: nodeCreateOrEditViewModel
|
text: S.of(context).delete,
|
||||||
.connectionState is IsExecutingState,
|
isDisabled: !nodeCreateOrEditViewModel.isReady ||
|
||||||
text: S.of(context).node_test,
|
(isSelected ?? false),
|
||||||
isDisabled: !nodeCreateOrEditViewModel.isReady,
|
color: Palette.red,
|
||||||
color: Colors.orange,
|
|
||||||
textColor: Colors.white),
|
textColor: Colors.white),
|
||||||
)),
|
)),
|
||||||
Flexible(
|
Flexible(
|
||||||
|
|
|
@ -9,8 +9,8 @@ class NodeIndicator extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
width: 8.0,
|
width: 12.0,
|
||||||
height: 8.0,
|
height: 12.0,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle, color: isLive ? Palette.green : Palette.red),
|
shape: BoxShape.circle, color: isLive ? Palette.green : Palette.red),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.dart';
|
import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.dart';
|
||||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||||
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class NodeListRow extends StandardListRow {
|
class NodeListRow extends StandardListRow {
|
||||||
NodeListRow(
|
NodeListRow(
|
||||||
{required String title,
|
{required String title,
|
||||||
|
required this.node,
|
||||||
required void Function(BuildContext context) onTap,
|
required void Function(BuildContext context) onTap,
|
||||||
required bool isSelected,
|
required bool isSelected})
|
||||||
required this.isAlive})
|
|
||||||
: super(title: title, onTap: onTap, isSelected: isSelected);
|
: super(title: title, onTap: onTap, isSelected: isSelected);
|
||||||
|
|
||||||
final Future<bool> isAlive;
|
final Node node;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildTrailing(BuildContext context) {
|
Widget buildLeading(BuildContext context) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: isAlive,
|
future: node.requestNode(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
switch (snapshot.connectionState) {
|
switch (snapshot.connectionState) {
|
||||||
case ConnectionState.done:
|
case ConnectionState.done:
|
||||||
|
@ -25,6 +27,24 @@ class NodeListRow extends StandardListRow {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildTrailing(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => Navigator.of(context).pushNamed(Routes.newNode,
|
||||||
|
arguments: {'editingNode': node, 'isSelected': isSelected}),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineMedium!
|
||||||
|
.decorationColor!),
|
||||||
|
child: Icon(Icons.edit,
|
||||||
|
size: 14,
|
||||||
|
color: Theme.of(context).textTheme.headlineMedium!.color!)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NodeHeaderListRow extends StandardListRow {
|
class NodeHeaderListRow extends StandardListRow {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart';
|
||||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
||||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
|
||||||
|
|
||||||
class ConnectionSyncPage extends BasePage {
|
class ConnectionSyncPage extends BasePage {
|
||||||
ConnectionSyncPage(this.nodeListViewModel, this.dashboardViewModel);
|
ConnectionSyncPage(this.nodeListViewModel, this.dashboardViewModel);
|
||||||
|
@ -64,49 +63,37 @@ class ConnectionSyncPage extends BasePage {
|
||||||
itemBuilder: (_, sectionIndex, index) {
|
itemBuilder: (_, sectionIndex, index) {
|
||||||
final node = nodeListViewModel.nodes[index];
|
final node = nodeListViewModel.nodes[index];
|
||||||
final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
|
final isSelected = node.keyIndex == nodeListViewModel.currentNode.keyIndex;
|
||||||
final nodeListRow = Semantics(
|
final nodeListRow = NodeListRow(
|
||||||
label: 'Slidable',
|
title: node.uriRaw,
|
||||||
selected: isSelected,
|
node: node,
|
||||||
enabled: !isSelected,
|
isSelected: isSelected,
|
||||||
child: NodeListRow(
|
onTap: (_) async {
|
||||||
title: node.uriRaw,
|
if (isSelected) {
|
||||||
isSelected: isSelected,
|
return;
|
||||||
isAlive: node.requestNode(),
|
}
|
||||||
onTap: (_) async {
|
|
||||||
if (isSelected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await showPopUp<void>(
|
await showPopUp<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertWithTwoActions(
|
return AlertWithTwoActions(
|
||||||
alertTitle:
|
alertTitle:
|
||||||
S.of(context).change_current_node_title,
|
S.of(context).change_current_node_title,
|
||||||
alertContent: nodeListViewModel
|
alertContent: nodeListViewModel
|
||||||
.getAlertContent(node.uriRaw),
|
.getAlertContent(node.uriRaw),
|
||||||
leftButtonText: S.of(context).cancel,
|
leftButtonText: S.of(context).cancel,
|
||||||
rightButtonText: S.of(context).change,
|
rightButtonText: S.of(context).change,
|
||||||
actionLeftButton: () =>
|
actionLeftButton: () =>
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
actionRightButton: () async {
|
actionRightButton: () async {
|
||||||
await nodeListViewModel.setAsCurrent(node);
|
await nodeListViewModel.setAsCurrent(node);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final dismissibleRow = Slidable(
|
return nodeListRow;
|
||||||
key: Key('${node.keyIndex}'),
|
|
||||||
startActionPane: _actionPane(context, node, isSelected),
|
|
||||||
endActionPane: _actionPane(context, node, isSelected),
|
|
||||||
child: nodeListRow,
|
|
||||||
);
|
|
||||||
|
|
||||||
return dismissibleRow;
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -134,44 +121,4 @@ class ConnectionSyncPage extends BasePage {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPane _actionPane(BuildContext context, Node node, bool isSelected) => ActionPane(
|
|
||||||
motion: const ScrollMotion(),
|
|
||||||
extentRatio: isSelected ? 0.3 : 0.6,
|
|
||||||
children: [
|
|
||||||
if (!isSelected)
|
|
||||||
SlidableAction(
|
|
||||||
onPressed: (context) async {
|
|
||||||
final confirmed = await showPopUp<bool>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertWithTwoActions(
|
|
||||||
alertTitle: S.of(context).remove_node,
|
|
||||||
alertContent: S.of(context).remove_node_message,
|
|
||||||
rightButtonText: S.of(context).remove,
|
|
||||||
leftButtonText: S.of(context).cancel,
|
|
||||||
actionRightButton: () => Navigator.pop(context, true),
|
|
||||||
actionLeftButton: () => Navigator.pop(context, false));
|
|
||||||
}) ??
|
|
||||||
false;
|
|
||||||
|
|
||||||
if (confirmed) {
|
|
||||||
await nodeListViewModel.delete(node);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
icon: CupertinoIcons.delete,
|
|
||||||
label: S.of(context).delete,
|
|
||||||
),
|
|
||||||
SlidableAction(
|
|
||||||
onPressed: (_) => Navigator.of(context).pushNamed(Routes.newNode,
|
|
||||||
arguments: {'editingNode': node, 'isSelected': isSelected}),
|
|
||||||
backgroundColor: Colors.blue,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
icon: Icons.edit,
|
|
||||||
label: S.of(context).edit,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
175
lib/src/screens/wallet/wallet_edit_page.dart
Normal file
175
lib/src/screens/wallet/wallet_edit_page.dart
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
import 'package:another_flushbar/flushbar.dart';
|
||||||
|
import 'package:cake_wallet/core/auth_service.dart';
|
||||||
|
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
|
|
||||||
|
class WalletEditPage extends BasePage {
|
||||||
|
WalletEditPage(
|
||||||
|
{required this.walletEditViewModel,
|
||||||
|
required this.editingWallet,
|
||||||
|
required this.walletNewVM,
|
||||||
|
required this.authService})
|
||||||
|
: _formKey = GlobalKey<FormState>(),
|
||||||
|
_labelController = TextEditingController(),
|
||||||
|
super() {
|
||||||
|
_labelController.text = editingWallet.name;
|
||||||
|
_labelController.addListener(() => walletEditViewModel.newName = _labelController.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
final GlobalKey<FormState> _formKey;
|
||||||
|
final TextEditingController _labelController;
|
||||||
|
|
||||||
|
final WalletEditViewModel walletEditViewModel;
|
||||||
|
final WalletNewVM walletNewVM;
|
||||||
|
final WalletListItem editingWallet;
|
||||||
|
final AuthService authService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get title => S.current.wallet_list_edit_wallet;
|
||||||
|
|
||||||
|
Flushbar<void>? _progressBar;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget body(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(24.0),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: BaseTextFormField(
|
||||||
|
controller: _labelController,
|
||||||
|
hintText: S.of(context).wallet_list_wallet_name,
|
||||||
|
validator: WalletNameValidator()))),
|
||||||
|
Observer(
|
||||||
|
builder: (_) {
|
||||||
|
final isLoading = walletEditViewModel.state is WalletEditRenamePending ||
|
||||||
|
walletEditViewModel.state is WalletEditDeletePending;
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(right: 8.0),
|
||||||
|
child: LoadingPrimaryButton(
|
||||||
|
isDisabled: isLoading,
|
||||||
|
onPressed: () => _removeWallet(context),
|
||||||
|
text: S.of(context).delete,
|
||||||
|
color: Palette.red,
|
||||||
|
textColor: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(left: 8.0),
|
||||||
|
child: LoadingPrimaryButton(
|
||||||
|
onPressed: () async {
|
||||||
|
if (_formKey.currentState?.validate() ?? false) {
|
||||||
|
if (walletNewVM.nameExists(walletEditViewModel.newName)) {
|
||||||
|
showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) {
|
||||||
|
return AlertWithOneAction(
|
||||||
|
alertTitle: '',
|
||||||
|
alertContent: S.of(context).wallet_name_exists,
|
||||||
|
buttonText: S.of(context).ok,
|
||||||
|
buttonAction: () => Navigator.of(context).pop(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await walletEditViewModel.changeName(editingWallet);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
walletEditViewModel.resetState();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: S.of(context).save,
|
||||||
|
color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
|
||||||
|
textColor: Colors.white,
|
||||||
|
isDisabled: walletEditViewModel.newName.isEmpty || isLoading,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _removeWallet(BuildContext context) async {
|
||||||
|
authService.authenticateAction(context, onAuthSuccess: (isAuthenticatedSuccessfully) async {
|
||||||
|
if (!isAuthenticatedSuccessfully) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSuccessfulAuth(context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSuccessfulAuth(BuildContext context) async {
|
||||||
|
bool confirmed = false;
|
||||||
|
|
||||||
|
await showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext dialogContext) {
|
||||||
|
return AlertWithTwoActions(
|
||||||
|
alertTitle: S.of(context).delete_wallet,
|
||||||
|
alertContent: S.of(context).delete_wallet_confirm_message(editingWallet.name),
|
||||||
|
leftButtonText: S.of(context).cancel,
|
||||||
|
rightButtonText: S.of(context).delete,
|
||||||
|
actionLeftButton: () => Navigator.of(dialogContext).pop(),
|
||||||
|
actionRightButton: () {
|
||||||
|
confirmed = true;
|
||||||
|
Navigator.of(dialogContext).pop();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (confirmed) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
try {
|
||||||
|
changeProcessText(context, S.of(context).wallet_list_removing_wallet(editingWallet.name));
|
||||||
|
await walletEditViewModel.remove(editingWallet);
|
||||||
|
hideProgressText();
|
||||||
|
} catch (e) {
|
||||||
|
changeProcessText(
|
||||||
|
context,
|
||||||
|
S.of(context).wallet_list_failed_to_remove(editingWallet.name, e.toString()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeProcessText(BuildContext context, String text) {
|
||||||
|
_progressBar = createBar<void>(text, duration: null)..show(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> hideProgressText() async {
|
||||||
|
await Future.delayed(Duration(milliseconds: 50), () {
|
||||||
|
_progressBar?.dismiss();
|
||||||
|
_progressBar = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
import 'package:another_flushbar/flushbar.dart';
|
import 'package:another_flushbar/flushbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
@ -15,7 +14,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
|
||||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||||
|
|
||||||
class WalletListPage extends BasePage {
|
class WalletListPage extends BasePage {
|
||||||
|
@ -77,31 +75,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
? Theme.of(context).accentTextTheme!.titleSmall!.decorationColor!
|
? Theme.of(context).accentTextTheme!.titleSmall!.decorationColor!
|
||||||
: Theme.of(context).colorScheme.background;
|
: Theme.of(context).colorScheme.background;
|
||||||
final row = GestureDetector(
|
final row = GestureDetector(
|
||||||
onTap: () async {
|
onTap: () => wallet.isCurrent ? null : _loadWallet(wallet),
|
||||||
if (wallet.isCurrent || !wallet.isEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final confirmed = await showPopUp<bool>(
|
|
||||||
context: context,
|
|
||||||
builder: (dialogContext) {
|
|
||||||
return AlertWithTwoActions(
|
|
||||||
alertTitle: S.of(context).change_wallet_alert_title,
|
|
||||||
alertContent:
|
|
||||||
S.of(context).change_wallet_alert_content(wallet.name),
|
|
||||||
leftButtonText: S.of(context).cancel,
|
|
||||||
rightButtonText: S.of(context).change,
|
|
||||||
actionLeftButton: () =>
|
|
||||||
Navigator.of(dialogContext).pop(false),
|
|
||||||
actionRightButton: () =>
|
|
||||||
Navigator.of(dialogContext).pop(true));
|
|
||||||
}) ??
|
|
||||||
false;
|
|
||||||
|
|
||||||
if (confirmed) {
|
|
||||||
await _loadWallet(wallet);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: tileHeight,
|
height: tileHeight,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
|
@ -129,16 +103,21 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
? _imageFor(type: wallet.type)
|
? _imageFor(type: wallet.type)
|
||||||
: nonWalletTypeIcon,
|
: nonWalletTypeIcon,
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
Text(
|
Flexible(
|
||||||
wallet.name,
|
child: Text(
|
||||||
style: TextStyle(
|
wallet.name,
|
||||||
|
maxLines: null,
|
||||||
|
softWrap: true,
|
||||||
|
style: TextStyle(
|
||||||
fontSize: 22,
|
fontSize: 22,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.titleLarge!
|
.titleLarge!
|
||||||
.color!),
|
.color!,
|
||||||
)
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -149,12 +128,38 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
|
|
||||||
return wallet.isCurrent
|
return wallet.isCurrent
|
||||||
? row
|
? row
|
||||||
: Slidable(
|
: Row(children: [
|
||||||
key: Key('${wallet.key}'),
|
Expanded(child: row),
|
||||||
startActionPane: _actionPane(wallet),
|
GestureDetector(
|
||||||
endActionPane: _actionPane(wallet),
|
onTap: () => Navigator.of(context).pushNamed(
|
||||||
child: row,
|
Routes.walletEdit,
|
||||||
);
|
arguments: [widget.walletListViewModel, wallet]),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(right: 20),
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
height: 40,
|
||||||
|
width: 44,
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineMedium!
|
||||||
|
.decorationColor!),
|
||||||
|
child: Icon(
|
||||||
|
Icons.edit,
|
||||||
|
size: 14,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineMedium!
|
||||||
|
.color!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -226,47 +231,6 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _removeWallet(WalletListItem wallet) async {
|
|
||||||
widget.authService.authenticateAction(context,
|
|
||||||
onAuthSuccess: (isAuthenticatedSuccessfully) async {
|
|
||||||
if (!isAuthenticatedSuccessfully) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_onSuccessfulAuth(wallet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onSuccessfulAuth(WalletListItem wallet) async {
|
|
||||||
bool confirmed = false;
|
|
||||||
await showPopUp<void>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertWithTwoActions(
|
|
||||||
alertTitle: S.of(context).delete_wallet,
|
|
||||||
alertContent: S.of(context).delete_wallet_confirm_message(wallet.name),
|
|
||||||
leftButtonText: S.of(context).cancel,
|
|
||||||
rightButtonText: S.of(context).delete,
|
|
||||||
actionLeftButton: () => Navigator.of(context).pop(),
|
|
||||||
actionRightButton: () {
|
|
||||||
confirmed = true;
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (confirmed) {
|
|
||||||
try {
|
|
||||||
changeProcessText(S.of(context).wallet_list_removing_wallet(wallet.name));
|
|
||||||
await widget.walletListViewModel.remove(wallet);
|
|
||||||
hideProgressText();
|
|
||||||
} catch (e) {
|
|
||||||
changeProcessText(
|
|
||||||
S.of(context).wallet_list_failed_to_remove(wallet.name, e.toString()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeProcessText(String text) {
|
void changeProcessText(String text) {
|
||||||
_progressBar = createBar<void>(text, duration: null)..show(context);
|
_progressBar = createBar<void>(text, duration: null)..show(context);
|
||||||
}
|
}
|
||||||
|
@ -277,18 +241,4 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
_progressBar = null;
|
_progressBar = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPane _actionPane(WalletListItem wallet) => ActionPane(
|
|
||||||
motion: const ScrollMotion(),
|
|
||||||
extentRatio: 0.3,
|
|
||||||
children: [
|
|
||||||
SlidableAction(
|
|
||||||
onPressed: (_) => _removeWallet(wallet),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
icon: CupertinoIcons.delete,
|
|
||||||
label: S.of(context).delete,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,7 +231,7 @@ class SectionStandardList extends StatelessWidget {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
return StandardListSeparator(padding: EdgeInsets.only(left: 24));
|
return StandardListSeparator(padding: dividerPadding);
|
||||||
},
|
},
|
||||||
itemCount: totalRows.length,
|
itemCount: totalRows.length,
|
||||||
itemBuilder: (_, index) => totalRows[index]);
|
itemBuilder: (_, index) => totalRows[index]);
|
||||||
|
|
55
lib/view_model/wallet_list/wallet_edit_view_model.dart
Normal file
55
lib/view_model/wallet_list/wallet_edit_view_model.dart
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/di.dart';
|
||||||
|
import 'package:cw_core/wallet_service.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
|
|
||||||
|
part 'wallet_edit_view_model.g.dart';
|
||||||
|
|
||||||
|
class WalletEditViewModel = WalletEditViewModelBase with _$WalletEditViewModel;
|
||||||
|
|
||||||
|
abstract class WalletEditViewModelState {}
|
||||||
|
|
||||||
|
class WalletEditViewModelInitialState extends WalletEditViewModelState {}
|
||||||
|
|
||||||
|
class WalletEditRenamePending extends WalletEditViewModelState {}
|
||||||
|
|
||||||
|
class WalletEditDeletePending extends WalletEditViewModelState {}
|
||||||
|
|
||||||
|
abstract class WalletEditViewModelBase with Store {
|
||||||
|
WalletEditViewModelBase(this._walletListViewModel, this._walletLoadingService)
|
||||||
|
: state = WalletEditViewModelInitialState(),
|
||||||
|
newName = '';
|
||||||
|
|
||||||
|
@observable
|
||||||
|
WalletEditViewModelState state;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String newName;
|
||||||
|
|
||||||
|
final WalletListViewModel _walletListViewModel;
|
||||||
|
final WalletLoadingService _walletLoadingService;
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> changeName(WalletListItem walletItem) async {
|
||||||
|
state = WalletEditRenamePending();
|
||||||
|
await _walletLoadingService.renameWallet(
|
||||||
|
walletItem.type, walletItem.name, newName);
|
||||||
|
_walletListViewModel.updateList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> remove(WalletListItem wallet) async {
|
||||||
|
state = WalletEditDeletePending();
|
||||||
|
final walletService = getIt.get<WalletService>(param1: wallet.type);
|
||||||
|
await walletService.remove(wallet.name);
|
||||||
|
resetState();
|
||||||
|
_walletListViewModel.updateList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void resetState() {
|
||||||
|
state = WalletEditViewModelInitialState();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
import 'package:cake_wallet/core/auth_service.dart';
|
import 'package:cake_wallet/core/auth_service.dart';
|
||||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
import 'package:cw_core/wallet_service.dart';
|
|
||||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -21,8 +20,8 @@ abstract class WalletListViewModelBase with Store {
|
||||||
this._walletLoadingService,
|
this._walletLoadingService,
|
||||||
this._authService,
|
this._authService,
|
||||||
) : wallets = ObservableList<WalletListItem>() {
|
) : wallets = ObservableList<WalletListItem>() {
|
||||||
_updateList();
|
updateList();
|
||||||
reaction((_) => _appStore.wallet, (_) => _updateList());
|
reaction((_) => _appStore.wallet, (_) => updateList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
|
@ -37,20 +36,14 @@ abstract class WalletListViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> loadWallet(WalletListItem walletItem) async {
|
Future<void> loadWallet(WalletListItem walletItem) async {
|
||||||
final wallet = await _walletLoadingService.load(walletItem.type, walletItem.name);
|
final wallet =
|
||||||
|
await _walletLoadingService.load(walletItem.type, walletItem.name);
|
||||||
|
|
||||||
_appStore.changeCurrentWallet(wallet);
|
_appStore.changeCurrentWallet(wallet);
|
||||||
_updateList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> remove(WalletListItem wallet) async {
|
void updateList() {
|
||||||
final walletService = getIt.get<WalletService>(param1: wallet.type);
|
|
||||||
await walletService.remove(wallet.name);
|
|
||||||
await _walletInfoSource.delete(wallet.key);
|
|
||||||
_updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateList() {
|
|
||||||
wallets.clear();
|
wallets.clear();
|
||||||
wallets.addAll(
|
wallets.addAll(
|
||||||
_walletInfoSource.values.map(
|
_walletInfoSource.values.map(
|
||||||
|
@ -58,7 +51,8 @@ abstract class WalletListViewModelBase with Store {
|
||||||
name: info.name,
|
name: info.name,
|
||||||
type: info.type,
|
type: info.type,
|
||||||
key: info.key,
|
key: info.key,
|
||||||
isCurrent: info.name == _appStore.wallet!.name && info.type == _appStore.wallet!.type,
|
isCurrent: info.name == _appStore.wallet!.name &&
|
||||||
|
info.type == _appStore.wallet!.type,
|
||||||
isEnabled: availableWalletTypes.contains(info.type),
|
isEnabled: availableWalletTypes.contains(info.type),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "عناوين المستلم",
|
"transaction_details_recipient_address": "عناوين المستلم",
|
||||||
"wallet_list_title": "محفظة Monero",
|
"wallet_list_title": "محفظة Monero",
|
||||||
"wallet_list_create_new_wallet": "إنشاء محفظة جديدة",
|
"wallet_list_create_new_wallet": "إنشاء محفظة جديدة",
|
||||||
|
"wallet_list_edit_wallet" : "تحرير المحفظة",
|
||||||
|
"wallet_list_wallet_name" : "اسم المحفظة",
|
||||||
"wallet_list_restore_wallet": "استعادة المحفظة",
|
"wallet_list_restore_wallet": "استعادة المحفظة",
|
||||||
"wallet_list_load_wallet": "تحميل المحفظة",
|
"wallet_list_load_wallet": "تحميل المحفظة",
|
||||||
"wallet_list_loading_wallet": "جار تحميل محفظة ${wallet_name}",
|
"wallet_list_loading_wallet": "جار تحميل محفظة ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Адрес на получател",
|
"transaction_details_recipient_address": "Адрес на получател",
|
||||||
"wallet_list_title": "Monero портфейл",
|
"wallet_list_title": "Monero портфейл",
|
||||||
"wallet_list_create_new_wallet": "Създаване на нов портфейл",
|
"wallet_list_create_new_wallet": "Създаване на нов портфейл",
|
||||||
|
"wallet_list_edit_wallet" : "Редактиране на портфейла",
|
||||||
|
"wallet_list_wallet_name" : "Име на портфейла",
|
||||||
"wallet_list_restore_wallet": "Възстановяване на портфейл",
|
"wallet_list_restore_wallet": "Възстановяване на портфейл",
|
||||||
"wallet_list_load_wallet": "Зареждане на портфейл",
|
"wallet_list_load_wallet": "Зареждане на портфейл",
|
||||||
"wallet_list_loading_wallet": "Зареждане на портфейл ${wallet_name}",
|
"wallet_list_loading_wallet": "Зареждане на портфейл ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adresa příjemce",
|
"transaction_details_recipient_address": "Adresa příjemce",
|
||||||
"wallet_list_title": "Monero Wallet",
|
"wallet_list_title": "Monero Wallet",
|
||||||
"wallet_list_create_new_wallet": "Vytvořit novou peněženku",
|
"wallet_list_create_new_wallet": "Vytvořit novou peněženku",
|
||||||
|
"wallet_list_edit_wallet" : "Upravit peněženku",
|
||||||
|
"wallet_list_wallet_name" : "Název peněženky",
|
||||||
"wallet_list_restore_wallet": "Obnovit peněženku",
|
"wallet_list_restore_wallet": "Obnovit peněženku",
|
||||||
"wallet_list_load_wallet": "Načíst peněženku",
|
"wallet_list_load_wallet": "Načíst peněženku",
|
||||||
"wallet_list_loading_wallet": "Načítám ${wallet_name} peněženku",
|
"wallet_list_loading_wallet": "Načítám ${wallet_name} peněženku",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Empfängeradressen",
|
"transaction_details_recipient_address": "Empfängeradressen",
|
||||||
"wallet_list_title": "Monero-Wallet",
|
"wallet_list_title": "Monero-Wallet",
|
||||||
"wallet_list_create_new_wallet": "Neue Wallet erstellen",
|
"wallet_list_create_new_wallet": "Neue Wallet erstellen",
|
||||||
|
"wallet_list_edit_wallet" : "Wallet bearbeiten",
|
||||||
|
"wallet_list_wallet_name" : "Wallet namen",
|
||||||
"wallet_list_restore_wallet": "Wallet wiederherstellen",
|
"wallet_list_restore_wallet": "Wallet wiederherstellen",
|
||||||
"wallet_list_load_wallet": "Wallet laden",
|
"wallet_list_load_wallet": "Wallet laden",
|
||||||
"wallet_list_loading_wallet": "Wallet ${wallet_name} wird geladen",
|
"wallet_list_loading_wallet": "Wallet ${wallet_name} wird geladen",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Recipient addresses",
|
"transaction_details_recipient_address": "Recipient addresses",
|
||||||
"wallet_list_title": "Monero Wallet",
|
"wallet_list_title": "Monero Wallet",
|
||||||
"wallet_list_create_new_wallet": "Create New Wallet",
|
"wallet_list_create_new_wallet": "Create New Wallet",
|
||||||
|
"wallet_list_edit_wallet" : "Edit wallet",
|
||||||
|
"wallet_list_wallet_name" : "Wallet name",
|
||||||
"wallet_list_restore_wallet": "Restore Wallet",
|
"wallet_list_restore_wallet": "Restore Wallet",
|
||||||
"wallet_list_load_wallet": "Load wallet",
|
"wallet_list_load_wallet": "Load wallet",
|
||||||
"wallet_list_loading_wallet": "Loading ${wallet_name} wallet",
|
"wallet_list_loading_wallet": "Loading ${wallet_name} wallet",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Direcciones de destinatarios",
|
"transaction_details_recipient_address": "Direcciones de destinatarios",
|
||||||
"wallet_list_title": "Monedero Monero",
|
"wallet_list_title": "Monedero Monero",
|
||||||
"wallet_list_create_new_wallet": "Crear nueva billetera",
|
"wallet_list_create_new_wallet": "Crear nueva billetera",
|
||||||
|
"wallet_list_edit_wallet" : "Editar billetera",
|
||||||
|
"wallet_list_wallet_name" : "Nombre de la billetera",
|
||||||
"wallet_list_restore_wallet": "Restaurar billetera",
|
"wallet_list_restore_wallet": "Restaurar billetera",
|
||||||
"wallet_list_load_wallet": "Billetera de carga",
|
"wallet_list_load_wallet": "Billetera de carga",
|
||||||
"wallet_list_loading_wallet": "Billetera ${wallet_name} de carga",
|
"wallet_list_loading_wallet": "Billetera ${wallet_name} de carga",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adresse du bénéficiaire",
|
"transaction_details_recipient_address": "Adresse du bénéficiaire",
|
||||||
"wallet_list_title": "Portefeuille (Wallet) Monero",
|
"wallet_list_title": "Portefeuille (Wallet) Monero",
|
||||||
"wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)",
|
"wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)",
|
||||||
|
"wallet_list_edit_wallet" : "Modifier le portefeuille",
|
||||||
|
"wallet_list_wallet_name" : "Nom du portefeuille",
|
||||||
"wallet_list_restore_wallet": "Restaurer un Portefeuille (Wallet)",
|
"wallet_list_restore_wallet": "Restaurer un Portefeuille (Wallet)",
|
||||||
"wallet_list_load_wallet": "Charger un Portefeuille (Wallet)",
|
"wallet_list_load_wallet": "Charger un Portefeuille (Wallet)",
|
||||||
"wallet_list_loading_wallet": "Chargement du portefeuille (wallet) ${wallet_name}",
|
"wallet_list_loading_wallet": "Chargement du portefeuille (wallet) ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adireshin masu amfani",
|
"transaction_details_recipient_address": "Adireshin masu amfani",
|
||||||
"wallet_list_title": "Monero walat",
|
"wallet_list_title": "Monero walat",
|
||||||
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
|
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
|
||||||
|
"wallet_list_edit_wallet" : "Gyara walat",
|
||||||
|
"wallet_list_wallet_name" : "Sunan walat",
|
||||||
"wallet_list_restore_wallet": "Maida Wallet",
|
"wallet_list_restore_wallet": "Maida Wallet",
|
||||||
"wallet_list_load_wallet": "Ana loda wallet na Monero",
|
"wallet_list_load_wallet": "Ana loda wallet na Monero",
|
||||||
"wallet_list_loading_wallet": "Ana loda ${wallet_name} walat",
|
"wallet_list_loading_wallet": "Ana loda ${wallet_name} walat",
|
||||||
|
@ -617,3 +619,4 @@
|
||||||
"share": "Raba",
|
"share": "Raba",
|
||||||
"slidable": "Mai iya zamewa"
|
"slidable": "Mai iya zamewa"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "प्राप्तकर्ता के पते",
|
"transaction_details_recipient_address": "प्राप्तकर्ता के पते",
|
||||||
"wallet_list_title": "Monero बटुआ",
|
"wallet_list_title": "Monero बटुआ",
|
||||||
"wallet_list_create_new_wallet": "नया बटुआ बनाएँ",
|
"wallet_list_create_new_wallet": "नया बटुआ बनाएँ",
|
||||||
|
"wallet_list_edit_wallet" : "बटुआ संपादित करें",
|
||||||
|
"wallet_list_wallet_name" : "बटुआ नाम",
|
||||||
"wallet_list_restore_wallet": "वॉलेट को पुनर्स्थापित करें",
|
"wallet_list_restore_wallet": "वॉलेट को पुनर्स्थापित करें",
|
||||||
"wallet_list_load_wallet": "वॉलेट लोड करें",
|
"wallet_list_load_wallet": "वॉलेट लोड करें",
|
||||||
"wallet_list_loading_wallet": "लोड हो रहा है ${wallet_name} बटुआ",
|
"wallet_list_loading_wallet": "लोड हो रहा है ${wallet_name} बटुआ",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adrese primatelja",
|
"transaction_details_recipient_address": "Adrese primatelja",
|
||||||
"wallet_list_title": "Monero novčanik",
|
"wallet_list_title": "Monero novčanik",
|
||||||
"wallet_list_create_new_wallet": "Izradi novi novčanik",
|
"wallet_list_create_new_wallet": "Izradi novi novčanik",
|
||||||
|
"wallet_list_edit_wallet" : "Uredi novčanik",
|
||||||
|
"wallet_list_wallet_name" : "Naziv novčanika",
|
||||||
"wallet_list_restore_wallet": "Oporavi novčanik",
|
"wallet_list_restore_wallet": "Oporavi novčanik",
|
||||||
"wallet_list_load_wallet": "Učitaj novčanik",
|
"wallet_list_load_wallet": "Učitaj novčanik",
|
||||||
"wallet_list_loading_wallet": "Učitavanje novčanika ${wallet_name}",
|
"wallet_list_loading_wallet": "Učitavanje novčanika ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Alamat Penerima",
|
"transaction_details_recipient_address": "Alamat Penerima",
|
||||||
"wallet_list_title": "Dompet Monero",
|
"wallet_list_title": "Dompet Monero",
|
||||||
"wallet_list_create_new_wallet": "Buat Dompet Baru",
|
"wallet_list_create_new_wallet": "Buat Dompet Baru",
|
||||||
|
"wallet_list_edit_wallet" : "Edit dompet",
|
||||||
|
"wallet_list_wallet_name" : "Nama dompet",
|
||||||
"wallet_list_restore_wallet": "Pulihkan Dompet",
|
"wallet_list_restore_wallet": "Pulihkan Dompet",
|
||||||
"wallet_list_load_wallet": "Muat dompet",
|
"wallet_list_load_wallet": "Muat dompet",
|
||||||
"wallet_list_loading_wallet": "Memuat ${wallet_name} dompet",
|
"wallet_list_loading_wallet": "Memuat ${wallet_name} dompet",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Indirizzi dei destinatari",
|
"transaction_details_recipient_address": "Indirizzi dei destinatari",
|
||||||
"wallet_list_title": "Portafoglio Monero",
|
"wallet_list_title": "Portafoglio Monero",
|
||||||
"wallet_list_create_new_wallet": "Crea Nuovo Portafoglio",
|
"wallet_list_create_new_wallet": "Crea Nuovo Portafoglio",
|
||||||
|
"wallet_list_edit_wallet" : "Modifica portafoglio",
|
||||||
|
"wallet_list_wallet_name" : "Nome del portafoglio",
|
||||||
"wallet_list_restore_wallet": "Recupera Portafoglio",
|
"wallet_list_restore_wallet": "Recupera Portafoglio",
|
||||||
"wallet_list_load_wallet": "Caricamento Portafoglio",
|
"wallet_list_load_wallet": "Caricamento Portafoglio",
|
||||||
"wallet_list_loading_wallet": "Caricamento portafoglio ${wallet_name}",
|
"wallet_list_loading_wallet": "Caricamento portafoglio ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "受信者のアドレス",
|
"transaction_details_recipient_address": "受信者のアドレス",
|
||||||
"wallet_list_title": "Monero 財布",
|
"wallet_list_title": "Monero 財布",
|
||||||
"wallet_list_create_new_wallet": "新しいウォレットを作成",
|
"wallet_list_create_new_wallet": "新しいウォレットを作成",
|
||||||
|
"wallet_list_edit_wallet" : "ウォレットを編集する",
|
||||||
|
"wallet_list_wallet_name" : "ウォレット名",
|
||||||
"wallet_list_restore_wallet": "ウォレットを復元",
|
"wallet_list_restore_wallet": "ウォレットを復元",
|
||||||
"wallet_list_load_wallet": "ウォレットをロード",
|
"wallet_list_load_wallet": "ウォレットをロード",
|
||||||
"wallet_list_loading_wallet": "読み込み中 ${wallet_name} 財布",
|
"wallet_list_loading_wallet": "読み込み中 ${wallet_name} 財布",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "받는 사람 주소",
|
"transaction_details_recipient_address": "받는 사람 주소",
|
||||||
"wallet_list_title": "모네로 월렛",
|
"wallet_list_title": "모네로 월렛",
|
||||||
"wallet_list_create_new_wallet": "새 월렛 만들기",
|
"wallet_list_create_new_wallet": "새 월렛 만들기",
|
||||||
|
"wallet_list_edit_wallet" : "지갑 수정",
|
||||||
|
"wallet_list_wallet_name" : "지갑 이름",
|
||||||
"wallet_list_restore_wallet": "월렛 복원",
|
"wallet_list_restore_wallet": "월렛 복원",
|
||||||
"wallet_list_load_wallet": "지갑로드",
|
"wallet_list_load_wallet": "지갑로드",
|
||||||
"wallet_list_loading_wallet": "로딩 ${wallet_name} 지갑",
|
"wallet_list_loading_wallet": "로딩 ${wallet_name} 지갑",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "လက်ခံသူလိပ်စာများ",
|
"transaction_details_recipient_address": "လက်ခံသူလိပ်စာများ",
|
||||||
"wallet_list_title": "Monero ပိုက်ဆံအိတ်",
|
"wallet_list_title": "Monero ပိုက်ဆံအိတ်",
|
||||||
"wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။",
|
"wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။",
|
||||||
|
"wallet_list_edit_wallet" : "ပိုက်ဆံအိတ်ကို တည်းဖြတ်ပါ။",
|
||||||
|
"wallet_list_wallet_name" : "ပိုက်ဆံအိတ်နာမည်",
|
||||||
"wallet_list_restore_wallet": "ပိုက်ဆံအိတ်ကို ပြန်ယူပါ။",
|
"wallet_list_restore_wallet": "ပိုက်ဆံအိတ်ကို ပြန်ယူပါ။",
|
||||||
"wallet_list_load_wallet": "ပိုက်ဆံအိတ်ကို တင်ပါ။",
|
"wallet_list_load_wallet": "ပိုက်ဆံအိတ်ကို တင်ပါ။",
|
||||||
"wallet_list_loading_wallet": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖွင့်နေသည်။",
|
"wallet_list_loading_wallet": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖွင့်နေသည်။",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adressen van ontvangers",
|
"transaction_details_recipient_address": "Adressen van ontvangers",
|
||||||
"wallet_list_title": "Monero portemonnee",
|
"wallet_list_title": "Monero portemonnee",
|
||||||
"wallet_list_create_new_wallet": "Maak een nieuwe portemonnee",
|
"wallet_list_create_new_wallet": "Maak een nieuwe portemonnee",
|
||||||
|
"wallet_list_edit_wallet" : "Portemonnee bewerken",
|
||||||
|
"wallet_list_wallet_name" : "Portemonnee naam",
|
||||||
"wallet_list_restore_wallet": "Portemonnee herstellen",
|
"wallet_list_restore_wallet": "Portemonnee herstellen",
|
||||||
"wallet_list_load_wallet": "Portemonnee laden",
|
"wallet_list_load_wallet": "Portemonnee laden",
|
||||||
"wallet_list_loading_wallet": "Bezig met laden ${wallet_name} portemonnee",
|
"wallet_list_loading_wallet": "Bezig met laden ${wallet_name} portemonnee",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Adres odbiorcy",
|
"transaction_details_recipient_address": "Adres odbiorcy",
|
||||||
"wallet_list_title": "Portfel Monero",
|
"wallet_list_title": "Portfel Monero",
|
||||||
"wallet_list_create_new_wallet": "Utwórz nowy portfel",
|
"wallet_list_create_new_wallet": "Utwórz nowy portfel",
|
||||||
|
"wallet_list_edit_wallet" : "Edytuj portfel",
|
||||||
|
"wallet_list_wallet_name" : "Nazwa portfela",
|
||||||
"wallet_list_restore_wallet": "Przywróć portfel",
|
"wallet_list_restore_wallet": "Przywróć portfel",
|
||||||
"wallet_list_load_wallet": "Załaduj portfel",
|
"wallet_list_load_wallet": "Załaduj portfel",
|
||||||
"wallet_list_loading_wallet": "Ładuję ${wallet_name} portfel",
|
"wallet_list_loading_wallet": "Ładuję ${wallet_name} portfel",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Endereços de destinatários",
|
"transaction_details_recipient_address": "Endereços de destinatários",
|
||||||
"wallet_list_title": "Carteira Monero",
|
"wallet_list_title": "Carteira Monero",
|
||||||
"wallet_list_create_new_wallet": "Criar nova carteira",
|
"wallet_list_create_new_wallet": "Criar nova carteira",
|
||||||
|
"wallet_list_edit_wallet" : "Editar carteira",
|
||||||
|
"wallet_list_wallet_name" : "Nome da carteira",
|
||||||
"wallet_list_restore_wallet": "Restaurar carteira",
|
"wallet_list_restore_wallet": "Restaurar carteira",
|
||||||
"wallet_list_load_wallet": "Abrir carteira",
|
"wallet_list_load_wallet": "Abrir carteira",
|
||||||
"wallet_list_loading_wallet": "Abrindo a carteira ${wallet_name}",
|
"wallet_list_loading_wallet": "Abrindo a carteira ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Адреса получателей",
|
"transaction_details_recipient_address": "Адреса получателей",
|
||||||
"wallet_list_title": "Monero Кошелёк",
|
"wallet_list_title": "Monero Кошелёк",
|
||||||
"wallet_list_create_new_wallet": "Создать новый кошелёк",
|
"wallet_list_create_new_wallet": "Создать новый кошелёк",
|
||||||
|
"wallet_list_edit_wallet" : "Изменить кошелек",
|
||||||
|
"wallet_list_wallet_name" : "Имя кошелька",
|
||||||
"wallet_list_restore_wallet": "Восстановить кошелёк",
|
"wallet_list_restore_wallet": "Восстановить кошелёк",
|
||||||
"wallet_list_load_wallet": "Загрузка кошелька",
|
"wallet_list_load_wallet": "Загрузка кошелька",
|
||||||
"wallet_list_loading_wallet": "Загрузка ${wallet_name} кошелька",
|
"wallet_list_loading_wallet": "Загрузка ${wallet_name} кошелька",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "ที่อยู่ผู้รับ",
|
"transaction_details_recipient_address": "ที่อยู่ผู้รับ",
|
||||||
"wallet_list_title": "กระเป๋า Monero",
|
"wallet_list_title": "กระเป๋า Monero",
|
||||||
"wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่",
|
"wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่",
|
||||||
|
"wallet_list_edit_wallet" : "แก้ไขกระเป๋าสตางค์",
|
||||||
|
"wallet_list_wallet_name" : "ชื่อกระเป๋าสตางค์",
|
||||||
"wallet_list_restore_wallet": "กู้กระเป๋า",
|
"wallet_list_restore_wallet": "กู้กระเป๋า",
|
||||||
"wallet_list_load_wallet": "โหลดกระเป๋า",
|
"wallet_list_load_wallet": "โหลดกระเป๋า",
|
||||||
"wallet_list_loading_wallet": "กำลังโหลดกระเป๋า ${wallet_name}",
|
"wallet_list_loading_wallet": "กำลังโหลดกระเป๋า ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Alıcı adres",
|
"transaction_details_recipient_address": "Alıcı adres",
|
||||||
"wallet_list_title": "Monero Cüzdanı",
|
"wallet_list_title": "Monero Cüzdanı",
|
||||||
"wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur",
|
"wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur",
|
||||||
|
"wallet_list_edit_wallet" : "Cüzdanı düzenle",
|
||||||
|
"wallet_list_wallet_name" : "Cüzdan adı",
|
||||||
"wallet_list_restore_wallet": "Cüzdanı Geri Yükle",
|
"wallet_list_restore_wallet": "Cüzdanı Geri Yükle",
|
||||||
"wallet_list_load_wallet": "Cüzdanı yükle",
|
"wallet_list_load_wallet": "Cüzdanı yükle",
|
||||||
"wallet_list_loading_wallet": "${wallet_name} cüzdanı yükleniyor",
|
"wallet_list_loading_wallet": "${wallet_name} cüzdanı yükleniyor",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Адреси одержувачів",
|
"transaction_details_recipient_address": "Адреси одержувачів",
|
||||||
"wallet_list_title": "Monero Гаманець",
|
"wallet_list_title": "Monero Гаманець",
|
||||||
"wallet_list_create_new_wallet": "Створити новий гаманець",
|
"wallet_list_create_new_wallet": "Створити новий гаманець",
|
||||||
|
"wallet_list_edit_wallet" : "Редагувати гаманець",
|
||||||
|
"wallet_list_wallet_name" : "Назва гаманця",
|
||||||
"wallet_list_restore_wallet": "Відновити гаманець",
|
"wallet_list_restore_wallet": "Відновити гаманець",
|
||||||
"wallet_list_load_wallet": "Завантаження гаманця",
|
"wallet_list_load_wallet": "Завантаження гаманця",
|
||||||
"wallet_list_loading_wallet": "Завантаження ${wallet_name} гаманця",
|
"wallet_list_loading_wallet": "Завантаження ${wallet_name} гаманця",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "وصول کنندگان کے پتے",
|
"transaction_details_recipient_address": "وصول کنندگان کے پتے",
|
||||||
"wallet_list_title": "Monero والیٹ",
|
"wallet_list_title": "Monero والیٹ",
|
||||||
"wallet_list_create_new_wallet": "نیا والیٹ بنائیں",
|
"wallet_list_create_new_wallet": "نیا والیٹ بنائیں",
|
||||||
|
"wallet_list_edit_wallet" : "بٹوے میں ترمیم کریں۔",
|
||||||
|
"wallet_list_wallet_name" : "بٹوے کا نام",
|
||||||
"wallet_list_restore_wallet": "والیٹ کو بحال کریں۔",
|
"wallet_list_restore_wallet": "والیٹ کو بحال کریں۔",
|
||||||
"wallet_list_load_wallet": "پرس لوڈ کریں۔",
|
"wallet_list_load_wallet": "پرس لوڈ کریں۔",
|
||||||
"wallet_list_loading_wallet": "${wallet_name} والیٹ لوڈ ہو رہا ہے۔",
|
"wallet_list_loading_wallet": "${wallet_name} والیٹ لوڈ ہو رہا ہے۔",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "Àwọn àdírẹ́sì olùgbà",
|
"transaction_details_recipient_address": "Àwọn àdírẹ́sì olùgbà",
|
||||||
"wallet_list_title": "Àpamọ́wọ́ Monero",
|
"wallet_list_title": "Àpamọ́wọ́ Monero",
|
||||||
"wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun",
|
"wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun",
|
||||||
|
"wallet_list_edit_wallet" : "Ṣatunkọ apamọwọ",
|
||||||
|
"wallet_list_wallet_name" : "Orukọ apamọwọ",
|
||||||
"wallet_list_restore_wallet": "Restore àpamọ́wọ́",
|
"wallet_list_restore_wallet": "Restore àpamọ́wọ́",
|
||||||
"wallet_list_load_wallet": "Load àpamọ́wọ́",
|
"wallet_list_load_wallet": "Load àpamọ́wọ́",
|
||||||
"wallet_list_loading_wallet": "Ń ṣí àpamọ́wọ́ ${wallet_name}",
|
"wallet_list_loading_wallet": "Ń ṣí àpamọ́wọ́ ${wallet_name}",
|
||||||
|
|
|
@ -250,6 +250,8 @@
|
||||||
"transaction_details_recipient_address": "收件人地址",
|
"transaction_details_recipient_address": "收件人地址",
|
||||||
"wallet_list_title": "Monero 钱包",
|
"wallet_list_title": "Monero 钱包",
|
||||||
"wallet_list_create_new_wallet": "创建新钱包",
|
"wallet_list_create_new_wallet": "创建新钱包",
|
||||||
|
"wallet_list_edit_wallet" : "编辑钱包",
|
||||||
|
"wallet_list_wallet_name" : "钱包名称",
|
||||||
"wallet_list_restore_wallet": "恢复钱包",
|
"wallet_list_restore_wallet": "恢复钱包",
|
||||||
"wallet_list_load_wallet": "加载钱包",
|
"wallet_list_load_wallet": "加载钱包",
|
||||||
"wallet_list_loading_wallet": "载入中 ${wallet_name} 钱包",
|
"wallet_list_loading_wallet": "载入中 ${wallet_name} 钱包",
|
||||||
|
|
Loading…
Reference in a new issue