mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 20:39:51 +00:00
Added auto saving of wallet address to wallet info. Added users wallet addresses into address book.
This commit is contained in:
parent
26a30a62f0
commit
bef18de7a6
16 changed files with 234 additions and 121 deletions
|
@ -89,7 +89,6 @@ class BitcoinWalletService extends WalletService<
|
||||||
walletInfo: credentials.walletInfo);
|
walletInfo: credentials.walletInfo);
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
await wallet.generateNewAddresses(32);
|
|
||||||
|
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
19
lib/di.dart
19
lib/di.dart
|
@ -330,7 +330,8 @@ Future setup(
|
||||||
(ContactRecord contact, _) =>
|
(ContactRecord contact, _) =>
|
||||||
ContactViewModel(contactSource, contact: contact));
|
ContactViewModel(contactSource, contact: contact));
|
||||||
|
|
||||||
getIt.registerFactory(() => ContactListViewModel(contactSource));
|
getIt.registerFactory(
|
||||||
|
() => ContactListViewModel(contactSource, walletInfoSource));
|
||||||
|
|
||||||
getIt.registerFactoryParam<ContactListPage, bool, void>(
|
getIt.registerFactoryParam<ContactListPage, bool, void>(
|
||||||
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
|
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
|
||||||
|
@ -419,17 +420,17 @@ Future setup(
|
||||||
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
|
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
|
||||||
WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
|
WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
|
||||||
|
|
||||||
getIt.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>
|
getIt
|
||||||
((TransactionInfo transactionInfo, _) => TransactionDetailsViewModel(
|
.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
|
||||||
transactionInfo: transactionInfo,
|
(TransactionInfo transactionInfo, _) => TransactionDetailsViewModel(
|
||||||
transactionDescriptionBox: transactionDescriptionBox,
|
transactionInfo: transactionInfo,
|
||||||
settingsStore: getIt.get<SettingsStore>()
|
transactionDescriptionBox: transactionDescriptionBox,
|
||||||
));
|
settingsStore: getIt.get<SettingsStore>()));
|
||||||
|
|
||||||
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
|
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
|
||||||
(TransactionInfo transactionInfo, _) => TransactionDetailsPage(
|
(TransactionInfo transactionInfo, _) => TransactionDetailsPage(
|
||||||
transactionDetailsViewModel: getIt
|
transactionDetailsViewModel:
|
||||||
.get<TransactionDetailsViewModel>(param1: transactionInfo)));
|
getIt.get<TransactionDetailsViewModel>(param1: transactionInfo)));
|
||||||
|
|
||||||
getIt.registerFactoryParam<NewWalletTypePage,
|
getIt.registerFactoryParam<NewWalletTypePage,
|
||||||
void Function(BuildContext, WalletType), bool>(
|
void Function(BuildContext, WalletType), bool>(
|
||||||
|
|
9
lib/entities/contact_base.dart
Normal file
9
lib/entities/contact_base.dart
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
|
|
||||||
|
abstract class ContactBase {
|
||||||
|
String name;
|
||||||
|
|
||||||
|
String address;
|
||||||
|
|
||||||
|
CryptoCurrency type;
|
||||||
|
}
|
|
@ -3,21 +3,27 @@ import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/entities/contact.dart';
|
import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/entities/record.dart';
|
import 'package:cake_wallet/entities/record.dart';
|
||||||
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
|
|
||||||
part 'contact_record.g.dart';
|
part 'contact_record.g.dart';
|
||||||
|
|
||||||
class ContactRecord = ContactRecordBase with _$ContactRecord;
|
class ContactRecord = ContactRecordBase with _$ContactRecord;
|
||||||
|
|
||||||
abstract class ContactRecordBase extends Record<Contact> with Store {
|
abstract class ContactRecordBase extends Record<Contact>
|
||||||
|
with Store
|
||||||
|
implements ContactBase {
|
||||||
ContactRecordBase(Box<Contact> source, Contact original)
|
ContactRecordBase(Box<Contact> source, Contact original)
|
||||||
: super(source, original);
|
: super(source, original);
|
||||||
|
|
||||||
|
@override
|
||||||
@observable
|
@observable
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
|
@override
|
||||||
@observable
|
@observable
|
||||||
String address;
|
String address;
|
||||||
|
|
||||||
|
@override
|
||||||
@observable
|
@observable
|
||||||
CryptoCurrency type;
|
CryptoCurrency type;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show File, Platform;
|
||||||
|
import 'package:cake_wallet/core/key_service.dart';
|
||||||
|
import 'package:cake_wallet/di.dart';
|
||||||
|
import 'package:cake_wallet/entities/pathForWallet.dart';
|
||||||
|
import 'package:cake_wallet/monero/monero_wallet_service.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -73,6 +77,9 @@ Future defaultSettingsMigration(
|
||||||
sharedPreferences: sharedPreferences, nodes: nodes);
|
sharedPreferences: sharedPreferences, nodes: nodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
await addAddressesForMoneroWallets(walletInfoSource);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -189,3 +196,27 @@ Future<void> addBitcoinElectrumServerList({@required Box<Node> nodes}) async {
|
||||||
final serverList = await loadElectrumServerList();
|
final serverList = await loadElectrumServerList();
|
||||||
await nodes.addAll(serverList);
|
await nodes.addAll(serverList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> addAddressesForMoneroWallets(
|
||||||
|
Box<WalletInfo> walletInfoSource) async {
|
||||||
|
final moneroWalletsInfo =
|
||||||
|
walletInfoSource.values.where((info) => info.type == WalletType.monero);
|
||||||
|
moneroWalletsInfo.forEach((info) async {
|
||||||
|
try {
|
||||||
|
final walletPath =
|
||||||
|
await pathForWallet(name: info.name, type: WalletType.monero);
|
||||||
|
final addressFilePath = '$walletPath.address.txt';
|
||||||
|
final addressFile = File(addressFilePath);
|
||||||
|
|
||||||
|
if (!addressFile.existsSync()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final addressText = await addressFile.readAsString();
|
||||||
|
info.address = addressText;
|
||||||
|
await info.save();
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
15
lib/entities/wallet_contact.dart
Normal file
15
lib/entities/wallet_contact.dart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
|
|
||||||
|
class WalletContact implements ContactBase {
|
||||||
|
WalletContact(this.address, this.name, this.type);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String address;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
CryptoCurrency type;
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ part 'wallet_info.g.dart';
|
||||||
@HiveType(typeId: 4)
|
@HiveType(typeId: 4)
|
||||||
class WalletInfo extends HiveObject {
|
class WalletInfo extends HiveObject {
|
||||||
WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
|
WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
|
||||||
this.timestamp, this.dirPath, this.path);
|
this.timestamp, this.dirPath, this.path, this.address);
|
||||||
|
|
||||||
factory WalletInfo.external(
|
factory WalletInfo.external(
|
||||||
{@required String id,
|
{@required String id,
|
||||||
|
@ -17,9 +17,10 @@ class WalletInfo extends HiveObject {
|
||||||
@required int restoreHeight,
|
@required int restoreHeight,
|
||||||
@required DateTime date,
|
@required DateTime date,
|
||||||
@required String dirPath,
|
@required String dirPath,
|
||||||
@required String path}) {
|
@required String path,
|
||||||
|
@required String address}) {
|
||||||
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
||||||
date.millisecondsSinceEpoch ?? 0, dirPath, path);
|
date.millisecondsSinceEpoch ?? 0, dirPath, path, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const boxName = 'WalletInfo';
|
static const boxName = 'WalletInfo';
|
||||||
|
@ -48,5 +49,8 @@ class WalletInfo extends HiveObject {
|
||||||
@HiveField(7)
|
@HiveField(7)
|
||||||
String path;
|
String path;
|
||||||
|
|
||||||
|
@HiveField(8)
|
||||||
|
String address;
|
||||||
|
|
||||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
part 'wallet_type.g.dart';
|
part 'wallet_type.g.dart';
|
||||||
|
@ -59,3 +60,14 @@ String walletTypeToDisplayName(WalletType type) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
|
||||||
|
switch (type) {
|
||||||
|
case WalletType.monero:
|
||||||
|
return CryptoCurrency.xmr;
|
||||||
|
case WalletType.bitcoin:
|
||||||
|
return CryptoCurrency.btc;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ void main() async {
|
||||||
templates: templates,
|
templates: templates,
|
||||||
exchangeTemplates: exchangeTemplates,
|
exchangeTemplates: exchangeTemplates,
|
||||||
transactionDescriptions: transactionDescriptions,
|
transactionDescriptions: transactionDescriptions,
|
||||||
initialMigrationVersion: 4);
|
initialMigrationVersion: 5);
|
||||||
runApp(App());
|
runApp(App());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
runApp(MaterialApp(
|
runApp(MaterialApp(
|
||||||
|
|
|
@ -10,14 +10,14 @@ ReactionDisposer _onAuthenticationStateChange;
|
||||||
dynamic loginError;
|
dynamic loginError;
|
||||||
|
|
||||||
void startAuthenticationStateChange(AuthenticationStore authenticationStore,
|
void startAuthenticationStateChange(AuthenticationStore authenticationStore,
|
||||||
@required GlobalKey<NavigatorState> navigatorKey) {
|
GlobalKey<NavigatorState> navigatorKey) {
|
||||||
_onAuthenticationStateChange ??= autorun((_) async {
|
_onAuthenticationStateChange ??= autorun((_) async {
|
||||||
final state = authenticationStore.state;
|
final state = authenticationStore.state;
|
||||||
|
|
||||||
if (state == AuthenticationState.installed) {
|
if (state == AuthenticationState.installed) {
|
||||||
try {
|
try {
|
||||||
await loadCurrentWallet();
|
await loadCurrentWallet();
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
loginError = e;
|
loginError = e;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -30,6 +30,14 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
||||||
await getIt.get<SharedPreferences>().setInt(
|
await getIt.get<SharedPreferences>().setInt(
|
||||||
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
||||||
await wallet.connectToNode(node: node);
|
await wallet.connectToNode(node: node);
|
||||||
|
|
||||||
|
if (wallet.walletInfo.address?.isEmpty ?? true) {
|
||||||
|
wallet.walletInfo.address = wallet.address;
|
||||||
|
|
||||||
|
if (wallet.walletInfo.isInBox) {
|
||||||
|
await wallet.walletInfo.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
|
@ -39,8 +47,9 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
||||||
reaction((_) => appStore.wallet, (WalletBase wallet) async {
|
reaction((_) => appStore.wallet, (WalletBase wallet) async {
|
||||||
try {
|
try {
|
||||||
fiatConversionStore.prices[wallet.currency] = 0;
|
fiatConversionStore.prices[wallet.currency] = 0;
|
||||||
fiatConversionStore.prices[wallet.currency] = await FiatConversionService.fetchPrice(
|
fiatConversionStore.prices[wallet.currency] =
|
||||||
wallet.currency, settingsStore.fiatCurrency);
|
await FiatConversionService.fetchPrice(
|
||||||
|
wallet.currency, settingsStore.fiatCurrency);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
import 'package:cake_wallet/utils/show_bar.dart';
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -61,107 +62,113 @@ class ContactListPage extends BasePage {
|
||||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
||||||
child: Observer(
|
child: Observer(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return contactListViewModel.contacts.isNotEmpty
|
return SectionStandardList(
|
||||||
? SectionStandardList(
|
context: context,
|
||||||
sectionCount: 1,
|
sectionCount: 2,
|
||||||
context: context,
|
sectionTitleBuilder: (_, int sectionIndex) {
|
||||||
itemCounter: (int sectionIndex) =>
|
var title = 'Contacts';
|
||||||
contactListViewModel.contacts.length,
|
|
||||||
itemBuilder: (_, sectionIndex, index) {
|
|
||||||
final contact = contactListViewModel.contacts[index];
|
|
||||||
final image = _getCurrencyImage(contact.type);
|
|
||||||
final content = GestureDetector(
|
|
||||||
onTap: () async {
|
|
||||||
if (!isEditable) {
|
|
||||||
Navigator.of(context).pop(contact);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final isCopied = await showNameAndAddressDialog(
|
if (sectionIndex == 0) {
|
||||||
context, contact.name, contact.address);
|
title = 'My wallets';
|
||||||
|
}
|
||||||
|
|
||||||
if (isCopied != null && isCopied) {
|
return Container(
|
||||||
await Clipboard.setData(
|
padding: EdgeInsets.only(left: 24, bottom: 20),
|
||||||
ClipboardData(text: contact.address));
|
child: Text(title, style: TextStyle(fontSize: 36)));
|
||||||
await showBar<void>(
|
},
|
||||||
context, S.of(context).copied_to_clipboard);
|
itemCounter: (int sectionIndex) => sectionIndex == 0
|
||||||
}
|
? contactListViewModel.walletContacts.length
|
||||||
},
|
: contactListViewModel.contacts.length,
|
||||||
child: Container(
|
itemBuilder: (_, sectionIndex, index) {
|
||||||
color: Colors.transparent,
|
if (sectionIndex == 0) {
|
||||||
padding: const EdgeInsets.only(
|
final walletInfo = contactListViewModel.walletContacts[index];
|
||||||
left: 24, top: 16, bottom: 16, right: 24),
|
return generateRaw(context, walletInfo);
|
||||||
child: Row(
|
}
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
image ?? Offstage(),
|
|
||||||
Padding(
|
|
||||||
padding: image != null
|
|
||||||
? EdgeInsets.only(left: 12)
|
|
||||||
: EdgeInsets.only(left: 0),
|
|
||||||
child: Text(
|
|
||||||
contact.name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.primaryTextTheme
|
|
||||||
.title
|
|
||||||
.color),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return !isEditable
|
final contact = contactListViewModel.contacts[index];
|
||||||
? content
|
final content = generateRaw(context, contact);
|
||||||
: Slidable(
|
|
||||||
key: Key('${contact.key}'),
|
|
||||||
actionPane: SlidableDrawerActionPane(),
|
|
||||||
child: content,
|
|
||||||
secondaryActions: <Widget>[
|
|
||||||
IconSlideAction(
|
|
||||||
caption: S.of(context).edit,
|
|
||||||
color: Colors.blue,
|
|
||||||
icon: Icons.edit,
|
|
||||||
onTap: () async =>
|
|
||||||
await Navigator.of(context).pushNamed(
|
|
||||||
Routes.addressBookAddContact,
|
|
||||||
arguments: contact),
|
|
||||||
),
|
|
||||||
IconSlideAction(
|
|
||||||
caption: S.of(context).delete,
|
|
||||||
color: Colors.red,
|
|
||||||
icon: CupertinoIcons.delete,
|
|
||||||
onTap: () async {
|
|
||||||
final isDelete =
|
|
||||||
await showAlertDialog(context) ??
|
|
||||||
false;
|
|
||||||
|
|
||||||
if (isDelete) {
|
return !isEditable
|
||||||
await contactListViewModel
|
? content
|
||||||
.delete(contact);
|
: Slidable(
|
||||||
}
|
key: Key('${contact.key}'),
|
||||||
},
|
actionPane: SlidableDrawerActionPane(),
|
||||||
),
|
child: content,
|
||||||
]);
|
secondaryActions: <Widget>[
|
||||||
},
|
IconSlideAction(
|
||||||
)
|
caption: S.of(context).edit,
|
||||||
: Center(
|
color: Colors.blue,
|
||||||
child: Text(
|
icon: Icons.edit,
|
||||||
S.of(context).placeholder_contacts,
|
onTap: () async => await Navigator.of(context)
|
||||||
textAlign: TextAlign.center,
|
.pushNamed(Routes.addressBookAddContact,
|
||||||
style: TextStyle(color: Colors.grey, fontSize: 14),
|
arguments: contact),
|
||||||
),
|
),
|
||||||
);
|
IconSlideAction(
|
||||||
|
caption: S.of(context).delete,
|
||||||
|
color: Colors.red,
|
||||||
|
icon: CupertinoIcons.delete,
|
||||||
|
onTap: () async {
|
||||||
|
final isDelete =
|
||||||
|
await showAlertDialog(context) ?? false;
|
||||||
|
|
||||||
|
if (isDelete) {
|
||||||
|
await contactListViewModel.delete(contact);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget generateRaw(BuildContext context, ContactBase contact) {
|
||||||
|
final image = _getCurrencyImage(contact.type);
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
if (!isEditable) {
|
||||||
|
Navigator.of(context).pop(contact);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final isCopied = await showNameAndAddressDialog(
|
||||||
|
context, contact.name, contact.address);
|
||||||
|
|
||||||
|
if (isCopied != null && isCopied) {
|
||||||
|
await Clipboard.setData(ClipboardData(text: contact.address));
|
||||||
|
await showBar<void>(context, S.of(context).copied_to_clipboard);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
image ?? Offstage(),
|
||||||
|
Padding(
|
||||||
|
padding: image != null
|
||||||
|
? EdgeInsets.only(left: 12)
|
||||||
|
: EdgeInsets.only(left: 0),
|
||||||
|
child: Text(
|
||||||
|
contact.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: Theme.of(context).primaryTextTheme.title.color),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Image _getCurrencyImage(CryptoCurrency currency) {
|
Image _getCurrencyImage(CryptoCurrency currency) {
|
||||||
Image image;
|
Image image;
|
||||||
switch (currency) {
|
switch (currency) {
|
||||||
|
|
|
@ -2,8 +2,8 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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';
|
||||||
import 'package:cake_wallet/entities/contact_record.dart';
|
|
||||||
import 'package:cake_wallet/entities/qr_scanner.dart';
|
import 'package:cake_wallet/entities/qr_scanner.dart';
|
||||||
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
|
|
||||||
enum AddressTextFieldOption { paste, qrCode, addressBook }
|
enum AddressTextFieldOption { paste, qrCode, addressBook }
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class AddressTextField extends StatelessWidget {
|
||||||
final Color iconColor;
|
final Color iconColor;
|
||||||
final TextStyle textStyle;
|
final TextStyle textStyle;
|
||||||
final TextStyle hintStyle;
|
final TextStyle hintStyle;
|
||||||
FocusNode focusNode;
|
final FocusNode focusNode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -212,7 +212,7 @@ class AddressTextField extends StatelessWidget {
|
||||||
final contact = await Navigator.of(context, rootNavigator: true)
|
final contact = await Navigator.of(context, rootNavigator: true)
|
||||||
.pushNamed(Routes.pickerAddressBook);
|
.pushNamed(Routes.pickerAddressBook);
|
||||||
|
|
||||||
if (contact is ContactRecord && contact.address != null) {
|
if (contact is ContactBase && contact.address != null) {
|
||||||
controller.text = contact.address;
|
controller.text = contact.address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,16 +113,19 @@ class SectionStandardList extends StatelessWidget {
|
||||||
{@required this.itemCounter,
|
{@required this.itemCounter,
|
||||||
@required this.itemBuilder,
|
@required this.itemBuilder,
|
||||||
@required this.sectionCount,
|
@required this.sectionCount,
|
||||||
|
this.sectionTitleBuilder,
|
||||||
this.hasTopSeparator = false,
|
this.hasTopSeparator = false,
|
||||||
BuildContext context})
|
BuildContext context})
|
||||||
: totalRows = transform(hasTopSeparator, context, sectionCount,
|
: totalRows = transform(hasTopSeparator, context, sectionCount,
|
||||||
itemCounter, itemBuilder);
|
itemCounter, itemBuilder, sectionTitleBuilder);
|
||||||
|
|
||||||
final int sectionCount;
|
final int sectionCount;
|
||||||
final bool hasTopSeparator;
|
final bool hasTopSeparator;
|
||||||
final int Function(int sectionIndex) itemCounter;
|
final int Function(int sectionIndex) itemCounter;
|
||||||
final Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
final Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
||||||
itemBuilder;
|
itemBuilder;
|
||||||
|
final Widget Function(BuildContext context, int sectionIndex)
|
||||||
|
sectionTitleBuilder;
|
||||||
final List<Widget> totalRows;
|
final List<Widget> totalRows;
|
||||||
|
|
||||||
static List<Widget> transform(
|
static List<Widget> transform(
|
||||||
|
@ -131,14 +134,20 @@ class SectionStandardList extends StatelessWidget {
|
||||||
int sectionCount,
|
int sectionCount,
|
||||||
int Function(int sectionIndex) itemCounter,
|
int Function(int sectionIndex) itemCounter,
|
||||||
Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
||||||
itemBuilder) {
|
itemBuilder,
|
||||||
|
Widget Function(BuildContext context, int sectionIndex)
|
||||||
|
sectionTitleBuilder) {
|
||||||
final items = <Widget>[];
|
final items = <Widget>[];
|
||||||
|
|
||||||
for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
|
for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
|
||||||
if ((sectionIndex == 0)&&(hasTopSeparator)) {
|
if ((sectionIndex == 0) && (hasTopSeparator)) {
|
||||||
items.add(StandardListSeparator(padding: EdgeInsets.only(left: 24)));
|
items.add(StandardListSeparator(padding: EdgeInsets.only(left: 24)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sectionTitleBuilder != null) {
|
||||||
|
items.add(sectionTitleBuilder(context, sectionIndex));
|
||||||
|
}
|
||||||
|
|
||||||
final itemCount = itemCounter(sectionIndex);
|
final itemCount = itemCounter(sectionIndex);
|
||||||
|
|
||||||
for (var itemIndex = 0; itemIndex < itemCount; itemIndex++) {
|
for (var itemIndex = 0; itemIndex < itemCount; itemIndex++) {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:cake_wallet/entities/wallet_contact.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_info.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.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/entities/contact_record.dart';
|
import 'package:cake_wallet/entities/contact_record.dart';
|
||||||
|
@ -11,15 +14,22 @@ class ContactListViewModel = ContactListViewModelBase
|
||||||
with _$ContactListViewModel;
|
with _$ContactListViewModel;
|
||||||
|
|
||||||
abstract class ContactListViewModelBase with Store {
|
abstract class ContactListViewModelBase with Store {
|
||||||
ContactListViewModelBase(this.contactSource)
|
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
|
||||||
: contacts = ObservableList<ContactRecord>() {
|
: contacts = ObservableList<ContactRecord>(),
|
||||||
|
walletContacts = walletInfoSource.values
|
||||||
|
.where((info) => info.address?.isNotEmpty ?? false)
|
||||||
|
.map((info) => WalletContact(
|
||||||
|
info.address, info.name, walletTypeToCryptoCurrency(info.type)))
|
||||||
|
.toList() {
|
||||||
_subscription = contactSource.bindToListWithTransform(
|
_subscription = contactSource.bindToListWithTransform(
|
||||||
contacts, (Contact contact) => ContactRecord(contactSource, contact),
|
contacts, (Contact contact) => ContactRecord(contactSource, contact),
|
||||||
initialFire: true);
|
initialFire: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Box<Contact> contactSource;
|
final Box<Contact> contactSource;
|
||||||
|
final Box<WalletInfo> walletInfoSource;
|
||||||
final ObservableList<ContactRecord> contacts;
|
final ObservableList<ContactRecord> contacts;
|
||||||
|
final List<WalletContact> walletContacts;
|
||||||
StreamSubscription<BoxEvent> _subscription;
|
StreamSubscription<BoxEvent> _subscription;
|
||||||
|
|
||||||
Future<void> delete(ContactRecord contact) async => contact.original.delete();
|
Future<void> delete(ContactRecord contact) async => contact.original.delete();
|
||||||
|
|
|
@ -50,6 +50,7 @@ abstract class WalletCreationVMBase with Store {
|
||||||
dirPath: dirPath);
|
dirPath: dirPath);
|
||||||
credentials.walletInfo = walletInfo;
|
credentials.walletInfo = walletInfo;
|
||||||
final wallet = await process(credentials);
|
final wallet = await process(credentials);
|
||||||
|
walletInfo.address = wallet.address;
|
||||||
await _walletInfoSource.add(walletInfo);
|
await _walletInfoSource.add(walletInfo);
|
||||||
_appStore.changeCurrentWallet(wallet);
|
_appStore.changeCurrentWallet(wallet);
|
||||||
_appStore.authenticationStore.allowed();
|
_appStore.authenticationStore.allowed();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue