diff --git a/assets/images/dai.png b/assets/images/dai.png new file mode 100644 index 000000000..698ffc48e Binary files /dev/null and b/assets/images/dai.png differ diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index 1ee9e72db..19810c636 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -22,6 +22,8 @@ class AddressValidator extends TextValidator { return '[0-9a-zA-Z]'; case CryptoCurrency.btc: return '[0-9a-zA-Z]'; + case CryptoCurrency.dai: + return '[0-9a-zA-Z]'; case CryptoCurrency.dash: return '[0-9a-zA-Z]'; case CryptoCurrency.eos: @@ -57,6 +59,8 @@ class AddressValidator extends TextValidator { return [42]; case CryptoCurrency.btc: return [34, 42]; + case CryptoCurrency.dai: + return [42]; case CryptoCurrency.dash: return [34]; case CryptoCurrency.eos: diff --git a/lib/core/contact_service.dart b/lib/core/contact_service.dart deleted file mode 100644 index c7027fa8f..000000000 --- a/lib/core/contact_service.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:hive/hive.dart'; -import 'package:cake_wallet/store/contact_list_store.dart'; -import 'package:cake_wallet/entities/contact.dart'; - -class ContactService { - ContactService(this.contactSource, this.contactListStore) { - _forceUpdateContactListStore(); - } - - final Box<Contact> contactSource; - final ContactListStore contactListStore; - - Future add(Contact contact) async { - await contactSource.add(contact); - // contactListStore.contacts.add(contact); - } - - Future update(Contact contact) async { - await contact.save(); - final index = contactListStore.contacts.indexOf(contact) ?? -1; - - if (index >= 0) { - _forceUpdateContactListStore(); - } else { - contactListStore.contacts.add(contact); - } - } - - Future delete(Contact contact) async { - await contact.delete(); - contactListStore.contacts.remove(contact); - } - - void _forceUpdateContactListStore() { - contactListStore.contacts.clear(); - contactListStore.contacts.addAll(contactSource.values); - } -} diff --git a/lib/di.dart b/lib/di.dart index 2010a6158..d133b6ed0 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -1,28 +1,28 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart'; -import 'package:cake_wallet/core/contact_service.dart'; import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/entities/biometric_auth.dart'; +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/monero/monero_wallet_service.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/exchange/trade.dart'; -// import 'package:cake_wallet/src/domain/services/wallet_service.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; +import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart'; import 'package:cake_wallet/src/screens/rescan/rescan_page.dart'; import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart'; import 'package:cake_wallet/src/screens/send/send_template_page.dart'; +import 'package:cake_wallet/src/screens/settings/change_language.dart'; import 'package:cake_wallet/src/screens/settings/settings.dart'; import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart'; import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart'; -import 'package:cake_wallet/store/contact_list_store.dart'; import 'package:cake_wallet/store/node_list_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/core/auth_service.dart'; @@ -37,10 +37,7 @@ import 'package:cake_wallet/src/screens/receive/receive_page.dart'; import 'package:cake_wallet/src/screens/send/send_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/store/theme_changer_store.dart'; import 'package:cake_wallet/store/wallet_list_store.dart'; -import 'package:cake_wallet/utils/mobx.dart'; -import 'package:cake_wallet/theme_changer.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; @@ -61,11 +58,9 @@ import 'package:cake_wallet/view_model/wallet_keys_view_model.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; import 'package:cake_wallet/view_model/wallet_seed_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:get_it/get_it.dart'; import 'package:hive/hive.dart'; -import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart'; @@ -103,17 +98,13 @@ Future setup( getIt.registerSingleton<FlutterSecureStorage>(FlutterSecureStorage()); getIt.registerSingleton(AuthenticationStore()); getIt.registerSingleton<WalletListStore>(WalletListStore()); - getIt.registerSingleton(ContactListStore()); getIt.registerSingleton(NodeListStoreBase.instance); getIt.registerSingleton<SettingsStore>(settingsStore); getIt.registerSingleton<AppStore>(AppStore( authenticationStore: getIt.get<AuthenticationStore>(), walletList: getIt.get<WalletListStore>(), settingsStore: getIt.get<SettingsStore>(), - contactListStore: getIt.get<ContactListStore>(), nodeListStore: getIt.get<NodeListStore>())); - getIt.registerSingleton<ContactService>( - ContactService(contactSource, getIt.get<AppStore>().contactListStore)); getIt.registerSingleton<TradesStore>(TradesStore( tradesSource: tradesSource, settingsStore: getIt.get<SettingsStore>())); getIt.registerSingleton<TradeFilterStore>(TradeFilterStore()); @@ -197,7 +188,8 @@ Future setup( getIt .registerFactoryParam<AuthPage, void Function(bool, AuthPageState), bool>( (onAuthFinished, closable) => AuthPage(getIt.get<AuthViewModel>(), - onAuthenticationFinished: onAuthFinished, closable: closable ?? false)); + onAuthenticationFinished: onAuthFinished, + closable: closable ?? false)); getIt.registerFactory<DashboardPage>(() => DashboardPage( walletViewModel: getIt.get<DashboardViewModel>(), @@ -282,27 +274,24 @@ Future setup( getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>())); - getIt.registerFactoryParam<ContactViewModel, Contact, void>( - (Contact contact, _) => ContactViewModel( - contactSource, getIt.get<AppStore>().wallet, - contact: contact)); + getIt.registerFactoryParam<ContactViewModel, ContactRecord, void>( + (ContactRecord contact, _) => + ContactViewModel(contactSource, contact: contact)); - getIt.registerFactory(() => ContactListViewModel( - getIt.get<AppStore>().contactListStore, - getIt.get<ContactService>(), - contactSource)); + getIt.registerFactory(() => ContactListViewModel(contactSource)); getIt.registerFactoryParam<ContactListPage, bool, void>( (bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(), isEditable: isEditable)); - getIt.registerFactoryParam<ContactPage, Contact, void>((Contact contact, _) => - ContactPage(getIt.get<ContactViewModel>(param1: contact))); + getIt.registerFactoryParam<ContactPage, ContactRecord, void>( + (ContactRecord contact, _) => + ContactPage(getIt.get<ContactViewModel>(param1: contact))); getIt.registerFactory(() { final appStore = getIt.get<AppStore>(); - return NodeListViewModel(appStore.nodeListStore, nodeSource, - appStore.wallet, appStore.settingsStore); + return NodeListViewModel( + nodeSource, appStore.wallet, appStore.settingsStore); }); getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>())); @@ -363,9 +352,8 @@ Future setup( getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet)); getIt.registerFactory(() => RescanPage(getIt.get<RescanViewModel>())); -} -void setupThemeChangerStore(ThemeChanger themeChanger) { - getIt.registerSingleton<ThemeChangerStore>( - ThemeChangerStore(themeChanger: themeChanger)); + getIt.registerFactory(() => FaqPage(getIt.get<SettingsStore>())); + + getIt.registerFactory(() => LanguageListPage(getIt.get<SettingsStore>())); } diff --git a/lib/entities/contact_record.dart b/lib/entities/contact_record.dart new file mode 100644 index 000000000..c4f55cc5a --- /dev/null +++ b/lib/entities/contact_record.dart @@ -0,0 +1,40 @@ +import 'package:hive/hive.dart'; +import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/entities/contact.dart'; +import 'package:cake_wallet/entities/crypto_currency.dart'; +import 'package:cake_wallet/entities/record.dart'; + +part 'contact_record.g.dart'; + +class ContactRecord = ContactRecordBase with _$ContactRecord; + +abstract class ContactRecordBase extends Record<Contact> with Store { + ContactRecordBase(Box<Contact> source, Contact original) + : super(source, original); + + @observable + String name; + + @observable + String address; + + @observable + CryptoCurrency type; + + @override + void toBind(Contact original) { + reaction((_) => name, (String name) => original.name = name); + reaction((_) => address, (String address) => original.address = address); + reaction( + (_) => type, + (CryptoCurrency currency) => + original.updateCryptoCurrency(currency: currency)); + } + + @override + void fromBind(Contact original) { + name = original.name; + address = original.address; + type = original.type; + } +} diff --git a/lib/entities/crypto_currency.dart b/lib/entities/crypto_currency.dart index 722fc2aef..b836393bd 100644 --- a/lib/entities/crypto_currency.dart +++ b/lib/entities/crypto_currency.dart @@ -14,6 +14,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> { CryptoCurrency.bch, CryptoCurrency.bnb, CryptoCurrency.btc, + CryptoCurrency.dai, CryptoCurrency.dash, CryptoCurrency.eos, CryptoCurrency.eth, @@ -29,15 +30,16 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> { static const bch = CryptoCurrency(title: 'BCH', raw: 2); static const bnb = CryptoCurrency(title: 'BNB', raw: 3); static const btc = CryptoCurrency(title: 'BTC', raw: 4); - static const dash = CryptoCurrency(title: 'DASH', raw: 5); - static const eos = CryptoCurrency(title: 'EOS', raw: 6); - static const eth = CryptoCurrency(title: 'ETH', raw: 7); - static const ltc = CryptoCurrency(title: 'LTC', raw: 8); - static const nano = CryptoCurrency(title: 'NANO', raw: 9); - static const trx = CryptoCurrency(title: 'TRX', raw: 10); - static const usdt = CryptoCurrency(title: 'USDT', raw: 11); - static const xlm = CryptoCurrency(title: 'XLM', raw: 12); - static const xrp = CryptoCurrency(title: 'XRP', raw: 13); + static const dai = CryptoCurrency(title: 'DAI', raw: 5); + static const dash = CryptoCurrency(title: 'DASH', raw: 6); + static const eos = CryptoCurrency(title: 'EOS', raw: 7); + static const eth = CryptoCurrency(title: 'ETH', raw: 8); + static const ltc = CryptoCurrency(title: 'LTC', raw: 9); + static const nano = CryptoCurrency(title: 'NANO', raw: 10); + static const trx = CryptoCurrency(title: 'TRX', raw: 11); + static const usdt = CryptoCurrency(title: 'USDT', raw: 12); + static const xlm = CryptoCurrency(title: 'XLM', raw: 13); + static const xrp = CryptoCurrency(title: 'XRP', raw: 14); static CryptoCurrency deserialize({int raw}) { switch (raw) { @@ -52,22 +54,24 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> { case 4: return CryptoCurrency.btc; case 5: - return CryptoCurrency.dash; + return CryptoCurrency.dai; case 6: - return CryptoCurrency.eos; + return CryptoCurrency.dash; case 7: - return CryptoCurrency.eth; + return CryptoCurrency.eos; case 8: - return CryptoCurrency.ltc; + return CryptoCurrency.eth; case 9: - return CryptoCurrency.nano; + return CryptoCurrency.ltc; case 10: - return CryptoCurrency.trx; + return CryptoCurrency.nano; case 11: - return CryptoCurrency.usdt; + return CryptoCurrency.trx; case 12: - return CryptoCurrency.xlm; + return CryptoCurrency.usdt; case 13: + return CryptoCurrency.xlm; + case 14: return CryptoCurrency.xrp; default: return null; @@ -86,6 +90,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> { return CryptoCurrency.bnb; case 'btc': return CryptoCurrency.btc; + case 'dai': + return CryptoCurrency.dai; case 'dash': return CryptoCurrency.dash; case 'eos': diff --git a/lib/entities/language.dart b/lib/entities/language.dart deleted file mode 100644 index 16e1d1a6a..000000000 --- a/lib/entities/language.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:devicelocale/devicelocale.dart'; -import 'package:intl/intl.dart'; - -const Map<String, String> languages = { - 'en': 'English', - 'de': 'Deutsch (German)', - 'es': 'Español (Spanish)', - 'hi': 'हिंदी (Hindi)', - 'ja': '日本 (Japanese)', - 'ko': '한국어 (Korean)', - 'nl': 'Nederlands (Dutch)', - 'pl': 'Polski (Polish)', - 'pt': 'Português (Portuguese)', - 'ru': 'Русский (Russian)', - 'uk': 'Українська (Ukrainian)', - 'zh': '中文 (Chinese)' -}; - -class Language with ChangeNotifier { - Language(this._currentLanguage); - - String _currentLanguage; - - String getCurrentLanguage() => _currentLanguage; - - void setCurrentLanguage(String language) { - _currentLanguage = language; - notifyListeners(); - } - - static Future<String> localeDetection() async { - var locale = await Devicelocale.currentLocale; - locale = Intl.shortLocale(locale); - - return languages.keys.contains(locale) ? locale : 'en'; - } -} \ No newline at end of file diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart new file mode 100644 index 000000000..4ea158353 --- /dev/null +++ b/lib/entities/language_service.dart @@ -0,0 +1,26 @@ +import 'package:devicelocale/devicelocale.dart'; +import 'package:intl/intl.dart'; + +class LanguageService { + static const Map<String, String> list = { + 'en': 'English', + 'de': 'Deutsch (German)', + 'es': 'Español (Spanish)', + 'hi': 'हिंदी (Hindi)', + 'ja': '日本 (Japanese)', + 'ko': '한국어 (Korean)', + 'nl': 'Nederlands (Dutch)', + 'pl': 'Polski (Polish)', + 'pt': 'Português (Portuguese)', + 'ru': 'Русский (Russian)', + 'uk': 'Українська (Ukrainian)', + 'zh': '中文 (Chinese)' + }; + + static Future<String> localeDetection() async { + var locale = await Devicelocale.currentLocale; + locale = Intl.shortLocale(locale); + + return list.keys.contains(locale) ? locale : 'en'; + } +} diff --git a/lib/entities/node.dart b/lib/entities/node.dart index 74643112a..d96834dcb 100644 --- a/lib/entities/node.dart +++ b/lib/entities/node.dart @@ -38,6 +38,9 @@ class Node extends HiveObject with Keyable { @HiveField(3) int typeRaw; + @override + dynamic get keyIndex => key; + WalletType get type => deserializeFromInt(typeRaw); set type(WalletType type) => typeRaw = serializeToInt(type); @@ -58,24 +61,28 @@ class Node extends HiveObject with Keyable { } Future<bool> requestMoneroNode() async { - Map<String, dynamic> resBody; + try { + Map<String, dynamic> resBody; - if (login != null && password != null) { - final digestRequest = DigestRequest(); - final response = await digestRequest.request( - uri: uri, login: login, password: password); - resBody = response.data as Map<String, dynamic>; - } else { - final url = Uri.http(uri, '/json_rpc'); - final headers = {'Content-type': 'application/json'}; - final body = - json.encode({'jsonrpc': '2.0', 'id': '0', 'method': 'get_info'}); - final response = - await http.post(url.toString(), headers: headers, body: body); - resBody = json.decode(response.body) as Map<String, dynamic>; + if (login != null && password != null) { + final digestRequest = DigestRequest(); + final response = await digestRequest.request( + uri: uri, login: login, password: password); + resBody = response.data as Map<String, dynamic>; + } else { + final url = Uri.http(uri, '/json_rpc'); + final headers = {'Content-type': 'application/json'}; + final body = + json.encode({'jsonrpc': '2.0', 'id': '0', 'method': 'get_info'}); + final response = + await http.post(url.toString(), headers: headers, body: body); + resBody = json.decode(response.body) as Map<String, dynamic>; + } + + return !(resBody['result']['offline'] as bool); + } catch (_) { + return false; } - - return !(resBody['result']['offline'] as bool); } Future<bool> requestBitcoinElectrumServer() async { diff --git a/lib/entities/record.dart b/lib/entities/record.dart new file mode 100644 index 000000000..1ca661684 --- /dev/null +++ b/lib/entities/record.dart @@ -0,0 +1,36 @@ +import 'dart:async'; + +import 'package:cake_wallet/utils/mobx.dart'; +import 'package:hive/hive.dart'; + +abstract class Record<T extends HiveObject> with Keyable { + Record(this._source, this.original) { + key = original.key; + _listener?.cancel(); + _listener = _source.watch(key: original.key).listen((event) { + if (!event.deleted) { + fromBind(event.value as T); + } + }); + + fromBind(original); + toBind(original); + } + + dynamic key; + + @override + dynamic get keyIndex => key; + + final T original; + + final Box<T> _source; + + StreamSubscription<BoxEvent> _listener; + + void fromBind(T original); + + void toBind(T original); + + Future<void> save() => original.save(); +} diff --git a/lib/exchange/morphtoken/morphtoken_exchange_provider.dart b/lib/exchange/morphtoken/morphtoken_exchange_provider.dart index 3d9ba9587..195f72ae5 100644 --- a/lib/exchange/morphtoken/morphtoken_exchange_provider.dart +++ b/lib/exchange/morphtoken/morphtoken_exchange_provider.dart @@ -1,6 +1,5 @@ import 'dart:convert'; import 'package:cake_wallet/core/amount_converter.dart'; -import 'package:cake_wallet/monero/monero_amount_format.dart'; import 'package:hive/hive.dart'; import 'package:cake_wallet/exchange/trade_not_found_exeption.dart'; import 'package:flutter/foundation.dart'; diff --git a/lib/main.dart b/lib/main.dart index 66cca43a5..4a49b646a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,66 +1,30 @@ -import 'package:cake_wallet/entities/fs_migration.dart'; -import 'package:cake_wallet/entities/transaction_description.dart'; -import 'package:cake_wallet/entities/transaction_description.dart'; -import 'package:cake_wallet/reactions/bootstrap.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/store/app_store.dart'; -import 'package:cake_wallet/store/authentication_store.dart'; -import 'package:cake_wallet/core/auth_service.dart'; -import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart'; -import 'package:cake_wallet/monero/monero_wallet_service.dart'; -import 'package:cake_wallet/core/wallet_creation_service.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/view_model/wallet_new_vm.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:get_it/get_it.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hive/hive.dart'; +import 'package:cake_wallet/di.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cw_monero/wallet.dart' as monero_wallet; import 'package:cake_wallet/router.dart'; -import 'theme_changer.dart'; -import 'themes.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/reactions/bootstrap.dart'; +import 'package:cake_wallet/store/app_store.dart'; +import 'package:cake_wallet/store/authentication_store.dart'; +import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/get_encryption_key.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/entities/wallet_info.dart'; -import 'package:cake_wallet/exchange/trade.dart'; - -// import 'package:cake_wallet/monero/transaction_description.dart'; -import 'package:cake_wallet/src/reactions/set_reactions.dart'; - -// import 'package:cake_wallet/src/stores/login/login_store.dart'; -// import 'package:cake_wallet/src/stores/balance/balance_store.dart'; -// import 'package:cake_wallet/src/stores/sync/sync_store.dart'; -// import 'package:cake_wallet/src/stores/wallet/wallet_store.dart'; -// import 'package:cake_wallet/src/stores/send_template/send_template_store.dart'; -// import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart'; -import 'package:cake_wallet/src/screens/root/root.dart'; - -//import 'package:cake_wallet/src/stores/authentication/authentication_store.dart'; -// import 'package:cake_wallet/src/stores/settings/settings_store.dart'; -// import 'package:cake_wallet/src/stores/price/price_store.dart'; -// import 'package:cake_wallet/src/domain/services/user_service.dart'; -// import 'package:cake_wallet/src/domain/services/wallet_list_service.dart'; -import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/default_settings_migration.dart'; -import 'package:cake_wallet/entities/fiat_currency.dart'; -import 'package:cake_wallet/entities/transaction_priority.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/entities/template.dart'; +import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/exchange/exchange_template.dart'; - -// import 'package:cake_wallet/src/domain/services/wallet_service.dart'; -// import 'package:cake_wallet/src/domain/services/fiat_convertation_service.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/entities/language.dart'; -// import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart'; - -bool isThemeChangerRegistered = false; +import 'package:cake_wallet/src/screens/root/root.dart'; final navigatorKey = GlobalKey<NavigatorState>(); @@ -94,41 +58,6 @@ void main() async { final templates = await Hive.openBox<Template>(Template.boxName); final exchangeTemplates = await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName); - - // final sharedPreferences = await SharedPreferences.getInstance(); - // final walletService = WalletService(); - // final fiatConvertationService = FiatConvertationService(); - // final walletListService = WalletListService( - // secureStorage: secureStorage, - // walletInfoSource: walletInfoSource, - // walletService: walletService, - // sharedPreferences: sharedPreferences); - // final userService = UserService( - // sharedPreferences: sharedPreferences, secureStorage: secureStorage); - // final settingsStore = await SettingsStoreBase.load( - // nodes: nodes, - // sharedPreferences: sharedPreferences, - // initialFiatCurrency: FiatCurrency.usd, - // initialTransactionPriority: TransactionPriority.slow, - // initialBalanceDisplayMode: BalanceDisplayMode.availableBalance); - // final priceStore = PriceStore(); - // final walletStore = - // WalletStore(walletService: walletService, settingsStore: settingsStore); - // final syncStore = SyncStore(walletService: walletService); - // final balanceStore = BalanceStore( - // walletService: walletService, - // settingsStore: settingsStore, - // priceStore: priceStore); - // final loginStore = LoginStore( - // sharedPreferences: sharedPreferences, walletsService: walletListService); - // final seedLanguageStore = SeedLanguageStore(); - // final sendTemplateStore = SendTemplateStore(templateSource: templates); - // final exchangeTemplateStore = - // ExchangeTemplateStore(templateSource: exchangeTemplates); - - // final walletCreationService = WalletCreationService(); - // final authService = AuthService(); - await initialSetup( sharedPreferences: await SharedPreferences.getInstance(), nodes: nodes, @@ -139,15 +68,7 @@ void main() async { templates: templates, exchangeTemplates: exchangeTemplates, initialMigrationVersion: 4); -// setReactions( -// settingsStore: settingsStore, -// priceStore: priceStore, -// syncStore: syncStore, -// walletStore: walletStore, -// walletService: walletService, -// // authenticationStore: authenticationStore, -// loginStore: loginStore); - runApp(CakeWalletApp()); + runApp(App()); } Future<void> initialSetup( @@ -178,63 +99,25 @@ Future<void> initialSetup( monero_wallet.onStartup(); } -class CakeWalletApp extends StatelessWidget { - CakeWalletApp() { +class App extends StatelessWidget { + App() { SystemChrome.setPreferredOrientations( [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); } - @override Widget build(BuildContext context) { - //final settingsStore = Provider.of<SettingsStore>(context); final settingsStore = getIt.get<AppStore>().settingsStore; - return ChangeNotifierProvider<ThemeChanger>( - create: (_) => ThemeChanger( - settingsStore.isDarkTheme ? Themes.darkTheme : Themes.lightTheme), - child: ChangeNotifierProvider<Language>( - create: (_) => Language(settingsStore.languageCode), - child: MaterialAppWithTheme())); - } -} - -class MaterialAppWithTheme extends StatelessWidget { - MaterialAppWithTheme(); - - @override - Widget build(BuildContext context) { - // final sharedPreferences = Provider.of<SharedPreferences>(context); - // final walletService = Provider.of<WalletService>(context); - // final walletListService = Provider.of<WalletListService>(context); - // final userService = Provider.of<UserService>(context); - // final settingsStore = Provider.of<SettingsStore>(context); - // final priceStore = Provider.of<PriceStore>(context); - // final walletStore = Provider.of<WalletStore>(context); - // final syncStore = Provider.of<SyncStore>(context); - // final balanceStore = Provider.of<BalanceStore>(context); - final theme = Provider.of<ThemeChanger>(context); - final currentLanguage = Provider.of<Language>(context); - // final contacts = Provider.of<Box<Contact>>(context); - // final nodes = Provider.of<Box<Node>>(context); - // final trades = Provider.of<Box<Trade>>(context); - // final transactionDescriptions = - // Provider.of<Box<TransactionDescription>>(context); - - if (!isThemeChangerRegistered) { - setupThemeChangerStore(theme); - isThemeChangerRegistered = true; + if (settingsStore.theme == null) { + settingsStore.isDarkTheme = false; } - /*final statusBarColor = - settingsStore.isDarkTheme ? Colors.black : Colors.white;*/ - final _settingsStore = getIt.get<AppStore>().settingsStore; - final statusBarColor = Colors.transparent; final statusBarBrightness = - _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; + settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; final statusBarIconBrightness = - _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; + settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; final authenticationStore = getIt.get<AuthenticationStore>(); final initialRoute = authenticationStore.state == AuthenticationState.denied ? Routes.welcome @@ -245,22 +128,24 @@ class MaterialAppWithTheme extends StatelessWidget { statusBarBrightness: statusBarBrightness, statusBarIconBrightness: statusBarIconBrightness)); - return Root( - authenticationStore: authenticationStore, - child: MaterialApp( - navigatorKey: navigatorKey, - debugShowCheckedModeBanner: false, - theme: theme.getTheme(), - localizationsDelegates: [ - S.delegate, - GlobalCupertinoLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - ], - supportedLocales: S.delegate.supportedLocales, - locale: Locale(currentLanguage.getCurrentLanguage()), - onGenerateRoute: (settings) => Router.generateRoute(settings), - initialRoute: initialRoute, - )); + return Observer(builder: (BuildContext context) { + return Root( + authenticationStore: authenticationStore, + child: MaterialApp( + navigatorKey: navigatorKey, + debugShowCheckedModeBanner: false, + theme: settingsStore.theme, + localizationsDelegates: [ + S.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + supportedLocales: S.delegate.supportedLocales, + locale: Locale(settingsStore.languageCode), + onGenerateRoute: (settings) => Router.generateRoute(settings), + initialRoute: initialRoute, + )); + }); } } diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 6f0ea6d79..4a053b788 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -191,7 +191,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store { @override Future<void> rescan({int height}) async { - // FIXME: Unimplemented + monero_wallet.rescanBlockchainAsync(); } void _setListeners() { diff --git a/lib/reactions/bootstrap.dart b/lib/reactions/bootstrap.dart index 2ffb5d376..fef73c46f 100644 --- a/lib/reactions/bootstrap.dart +++ b/lib/reactions/bootstrap.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:cake_wallet/reactions/on_current_node_change.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -31,4 +32,5 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async { startCurrentWalletChangeReaction( appStore, settingsStore, fiatConversionStore); startCurrentFiatChangeReaction(appStore, settingsStore); + startOnCurrentNodeChangeReaction(appStore); } diff --git a/lib/reactions/on_current_node_change.dart b/lib/reactions/on_current_node_change.dart new file mode 100644 index 000000000..c03bbac21 --- /dev/null +++ b/lib/reactions/on_current_node_change.dart @@ -0,0 +1,17 @@ +import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/entities/node.dart'; +import 'package:cake_wallet/store/app_store.dart'; + +ReactionDisposer _onCurrentNodeChangeReaction; + +void startOnCurrentNodeChangeReaction(AppStore appStore) { + _onCurrentNodeChangeReaction?.reaction?.dispose(); + _onCurrentNodeChangeReaction = + reaction((_) => appStore.settingsStore.currentNode, (Node node) async { + try { + await appStore.wallet.connectToNode(node: node); + } catch (e) { + print(e.toString()); + } + }); +} diff --git a/lib/router.dart b/lib/router.dart index 5ae418395..7407e9b11 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; @@ -67,7 +68,7 @@ class Router { .pushNamed(Routes.newWallet, arguments: type))); case Routes.newWallet: - final type = settings.arguments as WalletType; + final type = WalletType.monero; // settings.arguments as WalletType; final walletNewVM = getIt.get<WalletNewVM>(param1: type); return CupertinoPageRoute<void>( @@ -97,7 +98,7 @@ class Router { builder: (_) => RestoreOptionsPage(type: type)); case Routes.restoreWalletOptions: - final type = settings.arguments as WalletType; + final type = WalletType.monero; //settings.arguments as WalletType; return CupertinoPageRoute<void>( builder: (_) => RestoreWalletOptionsPage( @@ -251,8 +252,8 @@ class Router { case Routes.addressBookAddContact: return CupertinoPageRoute<void>( - builder: (_) => - getIt.get<ContactPage>(param1: settings.arguments as Contact)); + builder: (_) => getIt.get<ContactPage>( + param1: settings.arguments as ContactRecord)); case Routes.showKeys: return MaterialPageRoute<void>( @@ -296,10 +297,11 @@ class Router { return MaterialPageRoute<void>(builder: (_) => getIt.get<RescanPage>()); case Routes.faq: - return MaterialPageRoute<void>(builder: (_) => FaqPage()); + return MaterialPageRoute<void>(builder: (_) => getIt.get<FaqPage>()); case Routes.changeLanguage: - return MaterialPageRoute<void>(builder: (_) => ChangeLanguage()); + return MaterialPageRoute<void>( + builder: (_) => getIt.get<LanguageListPage>()); default: return MaterialPageRoute<void>( diff --git a/lib/src/reactions/set_reactions.dart b/lib/src/reactions/set_reactions.dart deleted file mode 100644 index 788f3bcb1..000000000 --- a/lib/src/reactions/set_reactions.dart +++ /dev/null @@ -1,98 +0,0 @@ -// import 'dart:async'; -// import 'package:flutter/foundation.dart'; -// import 'package:mobx/mobx.dart'; -// import 'package:cake_wallet/entities/node.dart'; -// import 'package:cake_wallet/entities/sync_status.dart'; -// import 'package:cake_wallet/src/domain/services/wallet_service.dart'; -// import 'package:cake_wallet/src/start_updating_price.dart'; -// import 'package:cake_wallet/src/stores/sync/sync_store.dart'; -// import 'package:cake_wallet/src/stores/wallet/wallet_store.dart'; -// import 'package:cake_wallet/src/stores/settings/settings_store.dart'; -// import 'package:cake_wallet/src/stores/price/price_store.dart'; -// import 'package:cake_wallet/src/stores/authentication/authentication_store.dart'; -// import 'package:cake_wallet/src/stores/login/login_store.dart'; -// -// Timer _reconnectionTimer; -// ReactionDisposer _connectToNodeDisposer; -// ReactionDisposer _onSyncStatusChangeDisposer; -// ReactionDisposer _onCurrentWalletChangeDisposer; -// -// void setReactions( -// {@required SettingsStore settingsStore, -// @required PriceStore priceStore, -// @required SyncStore syncStore, -// @required WalletStore walletStore, -// @required WalletService walletService, -// // @required AuthenticationStore authenticationStore, -// @required LoginStore loginStore}) { -// connectToNode(settingsStore: settingsStore, walletStore: walletStore); -// onSyncStatusChange( -// syncStore: syncStore, -// walletStore: walletStore, -// settingsStore: settingsStore); -// onCurrentWalletChange( -// walletStore: walletStore, -// settingsStore: settingsStore, -// priceStore: priceStore); -// autorun((_) async { -// // if (authenticationStore.state == AuthenticationState.allowed) { -// // await loginStore.loadCurrentWallet(); -// // authenticationStore.state = AuthenticationState.readyToLogin; -// // } -// }); -// } -// -// void connectToNode({SettingsStore settingsStore, WalletStore walletStore}) { -// _connectToNodeDisposer?.call(); -// -// _connectToNodeDisposer = reaction((_) => settingsStore.node, -// (Node node) async => await walletStore.connectToNode(node: node)); -// } -// -// void onCurrentWalletChange( -// {WalletStore walletStore, -// SettingsStore settingsStore, -// PriceStore priceStore}) { -// _onCurrentWalletChangeDisposer?.call(); -// -// reaction((_) => walletStore.name, (String _) { -// walletStore.connectToNode(node: settingsStore.node); -// startUpdatingPrice(settingsStore: settingsStore, priceStore: priceStore); -// }); -// } -// -// void onSyncStatusChange( -// {SyncStore syncStore, -// WalletStore walletStore, -// SettingsStore settingsStore}) { -// // _onSyncStatusChangeDisposer?.call(); -// -// // reaction((_) => syncStore.status, (SyncStatus status) async { -// // if (status is ConnectedSyncStatus) { -// // await walletStore.startSync(); -// // } -// -// // // Reconnect to the node if the app is not started sync after 30 seconds -// // if (status is StartingSyncStatus) { -// // startReconnectionObserver(syncStore: syncStore, walletStore: walletStore); -// // } -// // }); -// } -// -// void startReconnectionObserver({SyncStore syncStore, WalletStore walletStore}) { -// if (_reconnectionTimer != null) { -// _reconnectionTimer.cancel(); -// } -// -// _reconnectionTimer = Timer.periodic(Duration(minutes: 1), (_) async { -// try { -// final isConnected = await walletStore.isConnected(); -// -// if (!isConnected) { -// await walletStore.reconnect(); -// } -// } catch (e) { -// print(e); -// } -// }); -// } diff --git a/lib/src/screens/base_page.dart b/lib/src/screens/base_page.dart index bc6da2521..f8cfa5ae1 100644 --- a/lib/src/screens/base_page.dart +++ b/lib/src/screens/base_page.dart @@ -1,14 +1,22 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/nav_bar.dart'; -import 'package:provider/provider.dart'; -import 'package:cake_wallet/themes.dart'; -import 'package:cake_wallet/theme_changer.dart'; import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/src/widgets/nav_bar.dart'; enum AppBarStyle { regular, withShadow, transparent } abstract class BasePage extends StatelessWidget { + BasePage() + : _scaffoldKey = GlobalKey<ScaffoldState>(), + _closeButtonImage = Image.asset('assets/images/close_button.png'), + _closeButtonImageDarkTheme = + Image.asset('assets/images/close_button_dark_theme.png'); + final GlobalKey<ScaffoldState> _scaffoldKey; + final Image _closeButtonImage; + final Image _closeButtonImageDarkTheme; + String get title => null; bool get isModalBackButton => false; @@ -29,11 +37,7 @@ abstract class BasePage extends StatelessWidget { Widget Function(BuildContext, Widget) get rootWrapper => null; - final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); - - final _closeButtonImage = Image.asset('assets/images/close_button.png'); - final _closeButtonImageDarkTheme = - Image.asset('assets/images/close_button_dark_theme.png'); + bool get _isDarkTheme => getIt.get<SettingsStore>().isDarkTheme; void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer(); @@ -45,12 +49,9 @@ abstract class BasePage extends StatelessWidget { } final _backButton = Image.asset('assets/images/back_arrow.png', - color: titleColor ?? Theme.of(context).primaryTextTheme.title.color); - - final _themeChanger = Provider.of<ThemeChanger>(context); - final _closeButton = _themeChanger.getTheme() == Themes.darkTheme - ? _closeButtonImageDarkTheme - : _closeButtonImage; + color: titleColor ?? Theme.of(context).primaryTextTheme.title.color); + final _closeButton = + _isDarkTheme ? _closeButtonImageDarkTheme : _closeButtonImage; return SizedBox( height: 37, @@ -77,7 +78,7 @@ abstract class BasePage extends StatelessWidget { fontWeight: FontWeight.bold, fontFamily: 'Poppins', color: titleColor ?? - Theme.of(context).primaryTextTheme.title.color), + Theme.of(context).primaryTextTheme.title.color), ); } @@ -86,10 +87,8 @@ abstract class BasePage extends StatelessWidget { Widget floatingActionButton(BuildContext context) => null; ObstructingPreferredSizeWidget appBar(BuildContext context) { - final _themeChanger = Provider.of<ThemeChanger>(context); - final _isDarkTheme = _themeChanger.getTheme() == Themes.darkTheme; - final appBarColor = _isDarkTheme - ? backgroundDarkColor : backgroundLightColor; + final appBarColor = + _isDarkTheme ? backgroundDarkColor : backgroundLightColor; switch (appBarStyle) { case AppBarStyle.regular: @@ -131,9 +130,6 @@ abstract class BasePage extends StatelessWidget { @override Widget build(BuildContext context) { - final _themeChanger = Provider.of<ThemeChanger>(context); - final _isDarkTheme = _themeChanger.getTheme() == Themes.darkTheme; - final root = Scaffold( key: _scaffoldKey, backgroundColor: @@ -142,7 +138,7 @@ abstract class BasePage extends StatelessWidget { extendBodyBehindAppBar: extendBodyBehindAppBar, endDrawer: endDrawer, appBar: appBar(context), - body: body(context), //SafeArea(child: ), + body: body(context), floatingActionButton: floatingActionButton(context)); return rootWrapper?.call(context, root) ?? root; diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index dc1d14b72..5344c4736 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; @@ -172,8 +173,8 @@ class ContactListPage extends BasePage { ], dismissal: SlidableDismissal( child: SlidableDrawerDismissal(), - onDismissed: (actionType) async => - await contactListViewModel.delete(contact), + onDismissed: (actionType) async => null, + // await contactListViewModel.delete(contact), onWillDismiss: (actionType) async => showAlertDialog(context), ), @@ -211,6 +212,9 @@ class ContactListPage extends BasePage { case CryptoCurrency.btc: image = Image.asset('assets/images/bitcoin.png', height: 24, width: 24); break; + case CryptoCurrency.dai: + image = Image.asset('assets/images/dai.png', height: 24, width: 24); + break; case CryptoCurrency.dash: image = Image.asset('assets/images/dash.png', height: 24, width: 24); break; @@ -246,7 +250,7 @@ class ContactListPage extends BasePage { } Future<bool> showAlertDialog(BuildContext context) async { - return await showDialog( + return await showPopUp( context: context, builder: (BuildContext context) { return AlertWithTwoActions( @@ -261,7 +265,7 @@ class ContactListPage extends BasePage { Future<bool> showNameAndAddressDialog( BuildContext context, String name, String address) async { - return await showDialog( + return await showPopUp( context: context, builder: (BuildContext context) { return AlertWithTwoActions( diff --git a/lib/src/screens/contact/contact_page.dart b/lib/src/screens/contact/contact_page.dart index e73760ce1..a65a86e29 100644 --- a/lib/src/screens/contact/contact_page.dart +++ b/lib/src/screens/contact/contact_page.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -138,7 +139,7 @@ class ContactPage extends BasePage { } void _presentCurrencyPicker(BuildContext context) { - showDialog<void>( + showPopUp<void>( builder: (_) => CurrencyPicker( selectedAtIndex: contactViewModel.currencies.indexOf(contactViewModel.currency), @@ -150,7 +151,7 @@ class ContactPage extends BasePage { } void _onContactSavingFailure(BuildContext context, String error) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/dashboard/create_dashboard_page.dart b/lib/src/screens/dashboard/create_dashboard_page.dart deleted file mode 100644 index a14c2498a..000000000 --- a/lib/src/screens/dashboard/create_dashboard_page.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hive/hive.dart'; -import 'package:provider/provider.dart'; -import 'package:cake_wallet/exchange/trade.dart'; -// import 'package:cake_wallet/monero/transaction_description.dart'; -// import 'package:cake_wallet/src/domain/services/wallet_service.dart'; -// import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart'; -// import 'package:cake_wallet/src/stores/action_list/action_list_store.dart'; -// import 'package:cake_wallet/src/stores/action_list/trade_filter_store.dart'; -// import 'package:cake_wallet/src/stores/action_list/transaction_filter_store.dart'; -// import 'package:cake_wallet/src/stores/price/price_store.dart'; -// import 'package:cake_wallet/src/stores/settings/settings_store.dart'; -// import 'package:cake_wallet/src/stores/wallet/wallet_store.dart'; - -// FIXME: Remove me. - -// Widget createDashboardPage( -// {@required WalletService walletService, -// @required PriceStore priceStore, -// @required Box<TransactionDescription> transactionDescriptions, -// @required SettingsStore settingsStore, -// @required Box<Trade> trades, -// @required WalletStore walletStore}) => -// Provider( -// create: (_) => ActionListStore( -// walletService: walletService, -// settingsStore: settingsStore, -// priceStore: priceStore, -// tradesSource: trades, -// transactionFilterStore: TransactionFilterStore(), -// tradeFilterStore: TradeFilterStore(walletStore: walletStore), -// transactionDescriptions: transactionDescriptions), -// child: DashboardPage()); diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index 6458b5f2a..0d7347d24 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -105,20 +105,16 @@ class DashboardPage extends BasePage { Container( padding: EdgeInsets.only(left: 45, right: 45, bottom: 24), child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ ActionButton( - image: sendImage, - title: S.of(context).send, - route: Routes.send, - alignment: Alignment.centerLeft, - ), + image: sendImage, + title: S.of(context).send, + route: Routes.send), ActionButton( - image: exchangeImage, - title: S.of(context).exchange, - route: Routes.exchange, - alignment: Alignment.centerLeft, - ), + image: exchangeImage, + title: S.of(context).exchange, + route: Routes.exchange), ], ), ) diff --git a/lib/src/screens/dashboard/wallet_menu.dart b/lib/src/screens/dashboard/wallet_menu.dart index 1eb3864d0..d06068c89 100644 --- a/lib/src/screens/dashboard/wallet_menu.dart +++ b/lib/src/screens/dashboard/wallet_menu.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; import 'package:provider/provider.dart'; @@ -72,7 +73,7 @@ class WalletMenu { } Future<void> _presentReconnectAlert(BuildContext context) async { - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithTwoActions( diff --git a/lib/src/screens/dashboard/widgets/action_button.dart b/lib/src/screens/dashboard/widgets/action_button.dart index dc9a64bbf..9f9fbc418 100644 --- a/lib/src/screens/dashboard/widgets/action_button.dart +++ b/lib/src/screens/dashboard/widgets/action_button.dart @@ -36,6 +36,7 @@ class ActionButton extends StatelessWidget { child: image, ), ), + SizedBox(height: 15), Text( title, style: TextStyle(fontSize: 14, color: Colors.white), diff --git a/lib/src/screens/dashboard/widgets/balance_page.dart b/lib/src/screens/dashboard/widgets/balance_page.dart index 4cd3fe2a0..4410fc3ff 100644 --- a/lib/src/screens/dashboard/widgets/balance_page.dart +++ b/lib/src/screens/dashboard/widgets/balance_page.dart @@ -11,57 +11,42 @@ class BalancePage extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(24), - child: Center( - child: Container( - height: 160, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: <Widget>[ - Observer( - builder: (_) { - return Text( - dashboardViewModel.wallet.currency.toString(), - style: TextStyle( - fontSize: 40, - fontWeight: FontWeight.bold, - color: Theme.of(context).indicatorColor, - height: 1 - ), - ); - } - ), - Observer( - builder: (_) { - return Text( - dashboardViewModel.balanceViewModel.cryptoBalance, - style: TextStyle( - fontSize: 54, - fontWeight: FontWeight.bold, - color: Colors.white, - height: 1 - ), - ); - } - ), - Observer( - builder: (_) { - return Text( - dashboardViewModel.balanceViewModel.fiatBalance, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - color: Theme.of(context).indicatorColor, - height: 1 - ), - ); - } - ), - ], - ), - ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: <Widget>[ + Observer(builder: (_) { + return Text( + dashboardViewModel.balanceViewModel.currency.toString(), + style: TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + color: Theme.of(context).indicatorColor, + height: 1), + ); + }), + SizedBox(height: 10), + Observer(builder: (_) { + return Text(dashboardViewModel.balanceViewModel.cryptoBalance, + style: TextStyle( + fontSize: 54, + fontWeight: FontWeight.bold, + color: Colors.white, + height: 1), + textAlign: TextAlign.center); + }), + SizedBox(height: 10), + Observer(builder: (_) { + return Text(dashboardViewModel.balanceViewModel.fiatBalance, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + color: Theme.of(context).indicatorColor, + height: 1), + textAlign: TextAlign.center); + }), + ], ), ); } } - diff --git a/lib/src/screens/dashboard/widgets/header_row.dart b/lib/src/screens/dashboard/widgets/header_row.dart index a878ff11f..5b63f7a0e 100644 --- a/lib/src/screens/dashboard/widgets/header_row.dart +++ b/lib/src/screens/dashboard/widgets/header_row.dart @@ -1,4 +1,5 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; @@ -31,7 +32,7 @@ class HeaderRow extends StatelessWidget { ), GestureDetector( onTap: () { - showDialog<void>( + showPopUp<void>( context: context, builder: (context) => FilterWidget(dashboardViewModel: dashboardViewModel) ); diff --git a/lib/src/screens/dashboard/widgets/transaction_raw.dart b/lib/src/screens/dashboard/widgets/transaction_raw.dart index 13e3bd2be..14d07a9fc 100644 --- a/lib/src/screens/dashboard/widgets/transaction_raw.dart +++ b/lib/src/screens/dashboard/widgets/transaction_raw.dart @@ -3,13 +3,13 @@ import 'package:cake_wallet/entities/transaction_direction.dart'; import 'package:cake_wallet/generated/i18n.dart'; class TransactionRow extends StatelessWidget { - TransactionRow({ - this.direction, - this.formattedDate, - this.formattedAmount, - this.formattedFiatAmount, - this.isPending, - @required this.onTap}); + TransactionRow( + {this.direction, + this.formattedDate, + this.formattedAmount, + this.formattedFiatAmount, + this.isPending, + @required this.onTap}); final VoidCallback onTap; final TransactionDirection direction; @@ -23,75 +23,73 @@ class TransactionRow extends StatelessWidget { return InkWell( onTap: onTap, child: Container( - height: 52, + height: 62, color: Colors.transparent, padding: EdgeInsets.only(left: 24, right: 24), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ - Container( - height: 36, - width: 36, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).textTheme.overline.decorationColor - ), - child: Image.asset( - direction == TransactionDirection.incoming - ? 'assets/images/down_arrow.png' - : 'assets/images/up_arrow.png'), - ), Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 12), - child: Container( - height: 46, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: <Widget>[ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: <Widget>[ - Text( - (direction == TransactionDirection.incoming + child: Container( + height: 56, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: <Widget>[ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + Text( + (direction == TransactionDirection.incoming ? S.of(context).received : S.of(context).sent) + - (isPending ? S.of(context).pending : ''), + (isPending ? S.of(context).pending : ''), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white)), + Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(10)), + color: (direction == + TransactionDirection.incoming + ? Colors.green.withOpacity(0.8) + : Theme.of(context) + .accentTextTheme + .body2 + .decorationColor + .withOpacity(0.8))), + padding: EdgeInsets.only( + top: 3, bottom: 3, left: 10, right: 10), + child: Text(formattedAmount, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, - color: Colors.white - )), - Text(direction == TransactionDirection.incoming - ? formattedAmount - : '- ' + formattedAmount, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Colors.white - )) - ]), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: <Widget>[ - Text(formattedDate, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).textTheme - .overline.backgroundColor)), - Text(direction == TransactionDirection.incoming - ? formattedFiatAmount - : '- ' + formattedFiatAmount, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).textTheme - .overline.backgroundColor)) - ]), - ], - ), - ), - )) + color: Colors.white))) + ]), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + Text(formattedDate, + style: TextStyle( + fontSize: 14, + color: Theme.of(context) + .textTheme + .overline + .backgroundColor)), + Text(formattedFiatAmount, + style: TextStyle( + fontSize: 14, + color: Theme.of(context) + .textTheme + .overline + .backgroundColor)) + ]), + ], + ), + ), + ) ]), )); } diff --git a/lib/src/screens/disclaimer/disclaimer_page.dart b/lib/src/screens/disclaimer/disclaimer_page.dart index fde5677e7..b80a7a1fe 100644 --- a/lib/src/screens/disclaimer/disclaimer_page.dart +++ b/lib/src/screens/disclaimer/disclaimer_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; @@ -51,7 +52,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> { } Future<void> _showAlertDialog(BuildContext context) async { - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 23210deb8..fab5826f5 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/template_tile.dart'; import 'package:cake_wallet/src/widgets/trail_button.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -294,7 +295,7 @@ class ExchangePage extends BasePage { exchangeViewModel, template); }, onRemove: () { - showDialog<void>( + showPopUp<void>( context: context, builder: (dialogContext) { return AlertWithTwoActions( @@ -499,7 +500,7 @@ class ExchangePage extends BasePage { // reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) { // if (state is TradeIsCreatedFailure) { // WidgetsBinding.instance.addPostFrameCallback((_) { - // showDialog<void>( + // showPopUp<void>( // context: context, // builder: (BuildContext context) { // return AlertWithOneAction( diff --git a/lib/src/screens/exchange/widgets/currency_picker.dart b/lib/src/screens/exchange/widgets/currency_picker.dart index 21ba5ce31..668f99e77 100644 --- a/lib/src/screens/exchange/widgets/currency_picker.dart +++ b/lib/src/screens/exchange/widgets/currency_picker.dart @@ -62,13 +62,7 @@ class CurrencyPicker extends StatelessWidget { physics: const NeverScrollableScrollPhysics(), crossAxisSpacing: 1, mainAxisSpacing: 1, - children: List.generate(15, (index) { - - if (index == 14) { - return Container( - color: Theme.of(context).accentTextTheme.title.color, - ); - } + children: List.generate(items.length, (index) { final item = items[index]; final isItemSelected = index == selectedAtIndex; diff --git a/lib/src/screens/exchange/widgets/exchange_card.dart b/lib/src/screens/exchange/widgets/exchange_card.dart index 1836ec912..cd2fa6527 100644 --- a/lib/src/screens/exchange/widgets/exchange_card.dart +++ b/lib/src/screens/exchange/widgets/exchange_card.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -145,11 +146,11 @@ class ExchangeCardState extends State<ExchangeCard> { textAlign: TextAlign.left, keyboardType: TextInputType.numberWithOptions( signed: false, decimal: true), - inputFormatters: [ - LengthLimitingTextInputFormatter(15), - BlacklistingTextInputFormatter( - RegExp('[\\-|\\ |\\,]')) - ], + // inputFormatters: [ + // LengthLimitingTextInputFormatter(15), + // BlacklistingTextInputFormatter( + // RegExp('[\\-|\\ |\\,]')) + // ], hintText: '0.0000', borderColor: widget.borderColor, textStyle: TextStyle( @@ -303,7 +304,7 @@ class ExchangeCardState extends State<ExchangeCard> { } void _presentPicker(BuildContext context) { - showDialog<void>( + showPopUp<void>( builder: (_) => CurrencyPicker( selectedAtIndex: widget.currencies.indexOf(_selectedCurrency), items: widget.currencies, diff --git a/lib/src/screens/exchange/widgets/present_provider_picker.dart b/lib/src/screens/exchange/widgets/present_provider_picker.dart index b8154632e..f4cc7abf1 100644 --- a/lib/src/screens/exchange/widgets/present_provider_picker.dart +++ b/lib/src/screens/exchange/widgets/present_provider_picker.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/exchange_provider.dart'; @@ -72,7 +73,7 @@ class PresentProviderPicker extends StatelessWidget { } } - showDialog<void>( + showPopUp<void>( builder: (_) => Picker( items: items, images: images, diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart index 545492e09..945bb298d 100644 --- a/lib/src/screens/exchange_trade/exchange_trade_page.dart +++ b/lib/src/screens/exchange_trade/exchange_trade_page.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart'; import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; import 'package:cake_wallet/src/widgets/standart_list_row.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; import 'package:mobx/mobx.dart'; import 'package:provider/provider.dart'; @@ -37,7 +38,7 @@ void showInformation(ExchangeTradeViewModel exchangeTradeViewModel, BuildContext : S.current.exchange_result_description( trade.amount ?? fetchingLabel, trade.from.toString()); - showDialog<void>( + showPopUp<void>( context: context, builder: (_) => InformationPage(information: information) ); @@ -255,7 +256,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> { reaction((_) => sendStore.state, (SendingState state) { if (state is SendingFailed) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -270,7 +271,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> { if (state is TransactionCreatedSuccessfully) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithTwoActions( @@ -292,7 +293,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> { if (state is TransactionCommitted) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/faq/faq_item.dart b/lib/src/screens/faq/faq_item.dart new file mode 100644 index 000000000..5463b3f1c --- /dev/null +++ b/lib/src/screens/faq/faq_item.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:cake_wallet/palette.dart'; + +class FAQItem extends StatefulWidget { + FAQItem(this.title, this.text); + + final String title; + final String text; + + @override + State<StatefulWidget> createState() => FAQItemState(); +} + +class FAQItemState extends State<FAQItem> { + bool isActive; + + @override + void initState() { + isActive = false; + super.initState(); + } + + @override + Widget build(BuildContext context) { + final addIcon = + Icon(Icons.add, color: Theme.of(context).primaryTextTheme.title.color); + final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola); + final icon = isActive ? removeIcon : addIcon; + final color = isActive + ? Palette.blueCraiola + : Theme.of(context).primaryTextTheme.title.color; + + return ListTileTheme( + contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6), + child: ExpansionTile( + title: Text(widget.title, + style: TextStyle( + fontSize: 14, fontWeight: FontWeight.w500, color: color)), + trailing: icon, + onExpansionChanged: (value) => setState(() => isActive = value), + children: <Widget>[ + Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ + Expanded( + child: Container( + padding: EdgeInsets.only( + right: 24.0, + ), + child: Text( + widget.text, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).primaryTextTheme.title.color), + ), + )) + ]) + ], + ), + ); + } +} diff --git a/lib/src/screens/faq/faq_page.dart b/lib/src/screens/faq/faq_page.dart index b68c95732..467431e18 100644 --- a/lib/src/screens/faq/faq_page.dart +++ b/lib/src/screens/faq/faq_page.dart @@ -1,46 +1,30 @@ import 'dart:convert'; -import 'package:cake_wallet/palette.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:provider/provider.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/src/screens/faq/faq_item.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/widgets/standard_list.dart'; +import 'package:cake_wallet/store/settings_store.dart'; class FaqPage extends BasePage { + FaqPage(this.settingsStore); + + final SettingsStore settingsStore; + @override String get title => S.current.faq; - @override - Widget body(BuildContext context) => FaqForm(); -} - -class FaqForm extends StatefulWidget { - @override - FaqFormState createState() => FaqFormState(); -} - -class FaqFormState extends State<FaqForm> { - List<Icon> icons; - List<Color> colors; - bool isLoaded = false; + String get path => 'assets/faq/faq_' + settingsStore.languageCode + '.json'; @override - Widget build(BuildContext context) { - final addIcon = Icon(Icons.add, color: Theme.of(context).primaryTextTheme.title.color); - final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola); - + Widget body(BuildContext context) { return Container( padding: EdgeInsets.only(top: 12, left: 24), child: FutureBuilder( builder: (context, snapshot) { final faqItems = jsonDecode(snapshot.data.toString()) as List; - if (snapshot.hasData) { - setIconsAndColors(context, faqItems.length, addIcon); - } - return SingleChildScrollView( child: Column( children: <Widget>[ @@ -49,112 +33,20 @@ class FaqFormState extends State<FaqForm> { shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { - final itemTitle = faqItems[index]["question"].toString(); - final itemChild = faqItems[index]["answer"].toString(); + final title = faqItems[index]["question"].toString(); + final text = faqItems[index]["answer"].toString(); - return ListTileTheme( - contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6), - child: ExpansionTile( - title: Text( - itemTitle, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: colors[index] - ), - ), - trailing: icons[index], - onExpansionChanged: (value) { - setState(() { - if (value) { - icons[index] = removeIcon; - colors[index] = Palette.blueCraiola; - } else { - icons[index] = addIcon; - colors[index] = Theme.of(context).primaryTextTheme.title.color; - } - }); - }, - children: <Widget>[ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: <Widget>[ - Expanded( - child: Container( - padding: EdgeInsets.only( - right: 24.0, - ), - child: Text( - itemChild, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.normal, - color: Theme.of(context).primaryTextTheme.title.color - ), - ), - )) - ], - ) - ], - ), - ); + return FAQItem(title, text); }, - separatorBuilder: (_, __) => - StandardListSeparator(), - itemCount: faqItems == null ? 0 : faqItems.length, + separatorBuilder: (_, __) => StandardListSeparator(), + itemCount: faqItems?.length ?? 0, ) ], ), ); }, - future: rootBundle.loadString(getFaqPath(context)), + future: rootBundle.loadString(path), ), ); } - - void setIconsAndColors(BuildContext context, int index, Icon icon) { - if (isLoaded) { - return; - } - - icons = List.generate(index, (int i) => icon); - colors = List.generate(index, (int i) => Theme.of(context).primaryTextTheme.title.color); - - isLoaded = true; - } - - String getFaqPath(BuildContext context) { - // FIXME: FIXME - // final settingsStore = Provider.of<SettingsStore>(context); - // - // switch (settingsStore.languageCode) { - // case 'en': - // return 'assets/faq/faq_en.json'; - // case 'uk': - // return 'assets/faq/faq_uk.json'; - // case 'ru': - // return 'assets/faq/faq_ru.json'; - // case 'es': - // return 'assets/faq/faq_es.json'; - // case 'ja': - // return 'assets/faq/faq_ja.json'; - // case 'ko': - // return 'assets/faq/faq_ko.json'; - // case 'hi': - // return 'assets/faq/faq_hi.json'; - // case 'de': - // return 'assets/faq/faq_de.json'; - // case 'zh': - // return 'assets/faq/faq_zh.json'; - // case 'pt': - // return 'assets/faq/faq_pt.json'; - // case 'pl': - // return 'assets/faq/faq_pl.json'; - // case 'nl': - // return 'assets/faq/faq_nl.json'; - // default: - // return 'assets/faq/faq_en.json'; - // } - return ''; - } -} \ No newline at end of file +} diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart index c39758bd5..50238a67c 100644 --- a/lib/src/screens/monero_accounts/widgets/account_tile.dart +++ b/lib/src/screens/monero_accounts/widgets/account_tile.dart @@ -31,7 +31,7 @@ class AccountTile extends StatelessWidget { accountName, style: TextStyle( fontSize: 18, - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w600, fontFamily: 'Poppins', color: textColor, decoration: TextDecoration.none, diff --git a/lib/src/screens/new_wallet/new_wallet_page.dart b/lib/src/screens/new_wallet/new_wallet_page.dart index 9512a3753..9300b9c3a 100644 --- a/lib/src/screens/new_wallet/new_wallet_page.dart +++ b/lib/src/screens/new_wallet/new_wallet_page.dart @@ -1,6 +1,7 @@ import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter/material.dart'; @@ -60,7 +61,7 @@ class _WalletNameFormState extends State<WalletNameForm> { if (state is FailureState) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (_) { return AlertWithOneAction( diff --git a/lib/src/screens/nodes/nodes_list_page.dart b/lib/src/screens/nodes/nodes_list_page.dart index dd713d430..b0bc8c15f 100644 --- a/lib/src/screens/nodes/nodes_list_page.dart +++ b/lib/src/screens/nodes/nodes_list_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -29,7 +30,7 @@ class NodeListPage extends BasePage { minWidth: double.minPositive, child: FlatButton( onPressed: () async { - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithTwoActions( @@ -66,87 +67,86 @@ class NodeListPage extends BasePage { sectionCount: 2, context: context, itemBuilder: (_, sectionIndex, index) { - if (sectionIndex == 0) { - return NodeHeaderListRow( - title: S.of(context).add_new_node, - onTap: (_) async => - await Navigator.of(context).pushNamed(Routes.newNode)); - } + return Observer(builder: (_) { + if (sectionIndex == 0) { + return NodeHeaderListRow( + title: S.of(context).add_new_node, + onTap: (_) async => await Navigator.of(context) + .pushNamed(Routes.newNode)); + } - final node = nodeListViewModel.nodes[index]; - final nodeListRow = NodeListRow( - title: node.value.uri, - isSelected: node.isSelected, - isAlive: node.value.requestNode(), - onTap: (_) async { - if (node.isSelected) { - return; - } + final node = nodeListViewModel.nodes[index]; + final isSelected = node.keyIndex == + nodeListViewModel.settingsStore.currentNode.keyIndex; + final nodeListRow = NodeListRow( + title: node.uri, + isSelected: isSelected, + isAlive: node.requestNode(), + onTap: (_) async { + if (isSelected) { + return; + } - await showDialog<void>( - context: context, - builder: (BuildContext context) { - return AlertDialog( - content: Text( - S.of(context).change_current_node(node.value.uri), - textAlign: TextAlign.center, + await showPopUp<void>( + context: context, + builder: (BuildContext context) { + // FIXME: Add translation. + return AlertWithTwoActions( + alertTitle: 'Change current node', + alertContent: + S.of(context).change_current_node(node.uri), + leftButtonText: S.of(context).cancel, + rightButtonText: S.of(context).change, + actionLeftButton: () => + Navigator.of(context).pop(), + actionRightButton: () async { + await nodeListViewModel.setAsCurrent(node); + Navigator.of(context).pop(); + }); + }); + }); + + final dismissibleRow = Dismissible( + key: Key('${node.keyIndex}'), + confirmDismiss: (direction) async { + return await showPopUp( + 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)); + }); + }, + onDismissed: (direction) async => + nodeListViewModel.delete(node), + direction: DismissDirection.endToStart, + background: Container( + padding: EdgeInsets.only(right: 10.0), + alignment: AlignmentDirectional.centerEnd, + color: Palette.red, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: <Widget>[ + const Icon( + CupertinoIcons.delete, + color: Colors.white, ), - actions: <Widget>[ - FlatButton( - onPressed: () => Navigator.pop(context), - child: Text(S.of(context).cancel)), - FlatButton( - onPressed: () async { - Navigator.of(context).pop(); - await nodeListViewModel - .setAsCurrent(node.value); - }, - child: Text(S.of(context).change)), - ], - ); - }); - }); + Text( + S.of(context).delete, + style: TextStyle(color: Colors.white), + ) + ], + )), + child: nodeListRow); - final dismissibleRow = Dismissible( - key: Key('${node.keyIndex}'), - confirmDismiss: (direction) async { - return await showDialog( - 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)); - }); - }, - onDismissed: (direction) async => - nodeListViewModel.delete(node.value), - direction: DismissDirection.endToStart, - background: Container( - padding: EdgeInsets.only(right: 10.0), - alignment: AlignmentDirectional.centerEnd, - color: Palette.red, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: <Widget>[ - const Icon( - CupertinoIcons.delete, - color: Colors.white, - ), - Text( - S.of(context).delete, - style: TextStyle(color: Colors.white), - ) - ], - )), - child: nodeListRow); - - return node.isSelected ? nodeListRow : dismissibleRow; + return isSelected ? nodeListRow : dismissibleRow; + }); }, itemCounter: (int sectionIndex) { if (sectionIndex == 0) { diff --git a/lib/src/screens/pin_code/pin_code_widget.dart b/lib/src/screens/pin_code/pin_code_widget.dart index e4e17dae3..6cb0a9714 100644 --- a/lib/src/screens/pin_code/pin_code_widget.dart +++ b/lib/src/screens/pin_code/pin_code_widget.dart @@ -266,7 +266,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> { return; } - pin.substring(0, pin.length - 1); + setState(() => pin = pin.substring(0, pin.length - 1)); } String _changePinLengthText() { diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index fbae17324..b7b06fcdb 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -34,21 +35,19 @@ class ReceivePage extends BasePage { @override Widget Function(BuildContext, Widget) get rootWrapper => - (BuildContext context, Widget scaffold) => Container( + (BuildContext context, Widget scaffold) => Container( decoration: BoxDecoration( gradient: LinearGradient(colors: [ - Theme.of(context).accentColor, - Theme.of(context).scaffoldBackgroundColor, - Theme.of(context).primaryColor, - ], - begin: Alignment.topRight, - end: Alignment.bottomLeft)), + Theme.of(context).accentColor, + Theme.of(context).scaffoldBackgroundColor, + Theme.of(context).primaryColor, + ], begin: Alignment.topRight, end: Alignment.bottomLeft)), child: scaffold); @override Widget trailing(BuildContext context) { - final shareImage = Image.asset('assets/images/share.png', - color: Colors.white); + final shareImage = + Image.asset('assets/images/share.png', color: Colors.white); return SizedBox( height: 20.0, @@ -56,12 +55,12 @@ class ReceivePage extends BasePage { child: ButtonTheme( minWidth: double.minPositive, child: FlatButton( - highlightColor: Colors.transparent, - splashColor: Colors.transparent, - padding: EdgeInsets.all(0), - onPressed: () => Share.text(S.current.share_address, - addressListViewModel.address.address, 'text/plain'), - child: shareImage), + highlightColor: Colors.transparent, + splashColor: Colors.transparent, + padding: EdgeInsets.all(0), + onPressed: () => Share.text(S.current.share_address, + addressListViewModel.address.address, 'text/plain'), + child: shareImage), ), ); } @@ -80,10 +79,9 @@ class ReceivePage extends BasePage { ), Observer( builder: (_) => ListView.separated( - separatorBuilder: (context, _) => - Container( - height: 1, - color: Theme.of(context).dividerColor), + padding: EdgeInsets.all(0), + separatorBuilder: (context, _) => Container( + height: 1, color: Theme.of(context).dividerColor), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: addressListViewModel.items.length, @@ -93,9 +91,10 @@ class ReceivePage extends BasePage { if (item is WalletAccountListHeader) { cell = HeaderTile( - onTap: () async => await showDialog<void>( + onTap: () async => await showPopUp<void>( context: context, - builder: (_) => getIt.get<MoneroAccountListPage>()), + builder: (_) => + getIt.get<MoneroAccountListPage>()), title: addressListViewModel.accountLabel, icon: Icon( Icons.arrow_forward_ios, @@ -117,27 +116,31 @@ class ReceivePage extends BasePage { } if (item is WalletAddressListItem) { - cell = Observer( - builder: (_) { - final isCurrent = item.address == - addressListViewModel.address.address; - final backgroundColor = isCurrent - ? Theme.of(context).textTheme.display3.decorationColor - : Theme.of(context).textTheme.display2.decorationColor; - final textColor = isCurrent - ? Theme.of(context).textTheme.display3.color - : Theme.of(context).textTheme.display2.color; + cell = Observer(builder: (_) { + final isCurrent = item.address == + addressListViewModel.address.address; + final backgroundColor = isCurrent + ? Theme.of(context) + .textTheme + .display3 + .decorationColor + : Theme.of(context) + .textTheme + .display2 + .decorationColor; + final textColor = isCurrent + ? Theme.of(context).textTheme.display3.color + : Theme.of(context).textTheme.display2.color; - return AddressCell.fromItem(item, - isCurrent: isCurrent, - backgroundColor: backgroundColor, - textColor: textColor, - onTap: (_) => addressListViewModel.address = item, - onEdit: () => Navigator.of(context).pushNamed( - Routes.newSubaddress, - arguments: item)); - } - ); + return AddressCell.fromItem(item, + isCurrent: isCurrent, + backgroundColor: backgroundColor, + textColor: textColor, + onTap: (_) => addressListViewModel.address = item, + onEdit: () => Navigator.of(context).pushNamed( + Routes.newSubaddress, + arguments: item)); + }); } return index != 0 diff --git a/lib/src/screens/restore/restore_wallet_from_keys_page.dart b/lib/src/screens/restore/restore_wallet_from_keys_page.dart index f0e17ccf0..fa5efdff6 100644 --- a/lib/src/screens/restore/restore_wallet_from_keys_page.dart +++ b/lib/src/screens/restore/restore_wallet_from_keys_page.dart @@ -80,7 +80,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> { if (state is WalletRestorationFailure) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/restore/restore_wallet_from_seed_details.dart b/lib/src/screens/restore/restore_wallet_from_seed_details.dart index 5469a9f58..6a245884d 100644 --- a/lib/src/screens/restore/restore_wallet_from_seed_details.dart +++ b/lib/src/screens/restore/restore_wallet_from_seed_details.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -53,7 +54,7 @@ class _RestoreFromSeedDetailsFormState if (state is FailureState) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/seed/wallet_seed_page.dart b/lib/src/screens/seed/wallet_seed_page.dart index 6e6088bdd..92d3b8504 100644 --- a/lib/src/screens/seed/wallet_seed_page.dart +++ b/lib/src/screens/seed/wallet_seed_page.dart @@ -2,6 +2,7 @@ import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -27,12 +28,12 @@ class WalletSeedPage extends BasePage { @override void onClose(BuildContext context) async { if (isNewWalletCreated) { - final confirmed = await showDialog<bool>(context: context, builder: (BuildContext context) { + final confirmed = await showPopUp<bool>(context: context, builder: (BuildContext context) { // FIXME: add translations return AlertWithTwoActions( alertTitle: 'Attention', - alertContent: 'Have you written it down? The seed is the only way to recover your wallet.', - leftButtonText: 'Not yet', + alertContent: 'The seed is the only way to recover your wallet. Have you written it down?', + leftButtonText: 'Go back', rightButtonText: 'Yes, I have', actionLeftButton: () => Navigator.of(context).pop(false), actionRightButton: () => Navigator.of(context).pop(true)); diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 0beddd831..1bc42ccca 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,4 +1,5 @@ import 'dart:ui'; + // import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; @@ -6,6 +7,7 @@ import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/trail_button.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -19,6 +21,7 @@ import 'package:dotted_border/dotted_border.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/src/screens/send/widgets/confirm_sending_alert.dart'; + // import 'package:cake_wallet/src/screens/send/widgets/sending_alert.dart'; import 'package:cake_wallet/src/widgets/template_tile.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; @@ -69,8 +72,7 @@ class SendPage extends BasePage { decoration: BoxDecoration( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(24), - bottomRight: Radius.circular(24) - ), + bottomRight: Radius.circular(24)), gradient: LinearGradient(colors: [ Theme.of(context).primaryTextTheme.subhead.color, Theme.of(context).primaryTextTheme.subhead.decorationColor, @@ -105,10 +107,14 @@ class SendPage extends BasePage { AddressTextFieldOption.qrCode, AddressTextFieldOption.addressBook ], - buttonColor: - Theme.of(context).primaryTextTheme.display1.color, - borderColor: - Theme.of(context).primaryTextTheme.headline.color, + buttonColor: Theme.of(context) + .primaryTextTheme + .display1 + .color, + borderColor: Theme.of(context) + .primaryTextTheme + .headline + .color, textStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, @@ -122,83 +128,76 @@ class SendPage extends BasePage { .decorationColor), validator: sendViewModel.addressValidator, ), - Observer(builder: (_) { - return Padding( - padding: const EdgeInsets.only(top: 20), - child: BaseTextFormField( - controller: _cryptoAmountController, - keyboardType: TextInputType.numberWithOptions( - signed: false, decimal: true), - inputFormatters: [ - BlacklistingTextInputFormatter( - RegExp('[\\-|\\ |\\,]')) - ], - prefixIcon: Padding( - padding: EdgeInsets.only(top: 9), - child: - Text(sendViewModel.currency.title + ':', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Colors.white, - )), - ), - suffixIcon: Container( - height: 32, - width: 32, - margin: EdgeInsets.only( - left: 14, top: 4, bottom: 10), - decoration: BoxDecoration( - color: Theme.of(context) - .primaryTextTheme - .display1 - .color, - borderRadius: BorderRadius.all( - Radius.circular(6))), - child: InkWell( - onTap: () => - sendViewModel.setSendAll(), - child: Center( - child: Text(S.of(context).all, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Theme.of(context) - .primaryTextTheme - .display1 - .decorationColor)), - ), - ), - ), - hintText: '0.0000', - borderColor: Theme.of(context) - .primaryTextTheme - .headline - .color, - textStyle: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: Colors.white), - placeholderTextStyle: TextStyle( + Padding( + padding: const EdgeInsets.only(top: 20), + child: BaseTextFormField( + controller: _cryptoAmountController, + keyboardType: TextInputType.numberWithOptions( + signed: false, decimal: true), + prefixIcon: Padding( + padding: EdgeInsets.only(top: 9), + child: + Text(sendViewModel.currency.title + ':', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: Colors.white, + )), + ), + suffixIcon: Container( + height: 32, + width: 32, + margin: EdgeInsets.only( + left: 14, top: 4, bottom: 10), + decoration: BoxDecoration( color: Theme.of(context) .primaryTextTheme - .headline - .decorationColor, - fontWeight: FontWeight.w500, - fontSize: 14), - validator: sendViewModel.amountValidator)); - }), + .display1 + .color, + borderRadius: BorderRadius.all( + Radius.circular(6))), + child: InkWell( + onTap: () => sendViewModel.setSendAll(), + child: Center( + child: Text(S.of(context).all, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Theme.of(context) + .primaryTextTheme + .display1 + .decorationColor)), + ), + ), + ), + hintText: '0.0000', + borderColor: Theme.of(context) + .primaryTextTheme + .headline + .color, + textStyle: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white), + placeholderTextStyle: TextStyle( + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor, + fontWeight: FontWeight.w500, + fontSize: 14), + validator: sendViewModel.amountValidator)), Observer( builder: (_) => Padding( - padding: EdgeInsets.only(top: 10), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: <Widget>[ - Expanded( - child: Text( + padding: EdgeInsets.only(top: 10), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: <Widget>[ + Expanded( + child: Text( S.of(context).available_balance + ':', style: TextStyle( fontSize: 12, @@ -208,29 +207,25 @@ class SendPage extends BasePage { .headline .decorationColor), )), - Text( - sendViewModel.balance, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Theme.of(context) - .primaryTextTheme - .headline - .decorationColor), - ) - ], - ), - )), + Text( + sendViewModel.balance, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .headline + .decorationColor), + ) + ], + ), + )), Padding( padding: const EdgeInsets.only(top: 20), child: BaseTextFormField( controller: _fiatAmountController, keyboardType: TextInputType.numberWithOptions( signed: false, decimal: true), - inputFormatters: [ - BlacklistingTextInputFormatter( - RegExp('[\\-|\\ |\\,]')) - ], prefixIcon: Padding( padding: EdgeInsets.only(top: 9), child: Text(sendViewModel.fiat.title + ':', @@ -259,51 +254,51 @@ class SendPage extends BasePage { )), Observer( builder: (_) => GestureDetector( - onTap: () => - _setTransactionPriority(context), - child: Container( - padding: EdgeInsets.only(top: 24), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: <Widget>[ - Text(S.of(context).send_estimated_fee, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, - //color: Theme.of(context).primaryTextTheme.display2.color, - color: Colors.white)), - Container( - child: Row( - children: <Widget>[ - Text( - sendViewModel.estimatedFee - .toString() + - ' ' + - sendViewModel - .currency.title, - style: TextStyle( - fontSize: 12, - fontWeight: - FontWeight.w600, - //color: Theme.of(context).primaryTextTheme.display2.color, - color: Colors.white)), - Padding( - padding: - EdgeInsets.only(left: 5), - child: Icon( - Icons.arrow_forward_ios, - size: 12, - color: Colors.white, - ), - ) - ], - ), - ) - ], - ), - ), - )) + onTap: () => + _setTransactionPriority(context), + child: Container( + padding: EdgeInsets.only(top: 24), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: <Widget>[ + Text(S.of(context).send_estimated_fee, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + //color: Theme.of(context).primaryTextTheme.display2.color, + color: Colors.white)), + Container( + child: Row( + children: <Widget>[ + Text( + sendViewModel.estimatedFee + .toString() + + ' ' + + sendViewModel + .currency.title, + style: TextStyle( + fontSize: 12, + fontWeight: + FontWeight.w600, + //color: Theme.of(context).primaryTextTheme.display2.color, + color: Colors.white)), + Padding( + padding: + EdgeInsets.only(left: 5), + child: Icon( + Icons.arrow_forward_ios, + size: 12, + color: Colors.white, + ), + ) + ], + ), + ) + ], + ), + ), + )) ], ), ) @@ -357,7 +352,7 @@ class SendPage extends BasePage { alignment: Alignment.center, decoration: BoxDecoration( borderRadius: - BorderRadius.all(Radius.circular(20)), + BorderRadius.all(Radius.circular(20)), color: Colors.transparent, ), child: Text( @@ -397,7 +392,7 @@ class SendPage extends BasePage { // getOpenaliasRecord(context); // }, // onRemove: () { - // showDialog<void>( + // showPopUp<void>( // context: context, // builder: (dialogContext) { // return AlertWithTwoActions( @@ -426,13 +421,12 @@ class SendPage extends BasePage { ) ], ), - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), + bottomSectionPadding: + EdgeInsets.only(left: 24, right: 24, bottom: 24), bottomSection: Observer(builder: (_) { return LoadingPrimaryButton( onPressed: () { - if (_formKey.currentState.validate()) { - - } + if (_formKey.currentState.validate()) {} }, text: S.of(context).send, color: Theme.of(context).accentTextTheme.body2.color, @@ -440,10 +434,9 @@ class SendPage extends BasePage { isLoading: sendViewModel.state is IsExecutingState || sendViewModel.state is TransactionCommitting, isDisabled: - false // FIXME !(syncStore.status is SyncedSyncStatus), - ); - }) - ), + false // FIXME !(syncStore.status is SyncedSyncStatus), + ); + })), ); } @@ -492,7 +485,7 @@ class SendPage extends BasePage { reaction((_) => sendViewModel.state, (ExecutionState state) { if (state is FailureState) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -506,14 +499,14 @@ class SendPage extends BasePage { if (state is ExecutedSuccessfullyState) { WidgetsBinding.instance.addPostFrameCallback((_) { - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return ConfirmSendingAlert( alertTitle: S.of(context).confirm_sending, amount: S.of(context).send_amount, amountValue: - sendViewModel.pendingTransaction.amountFormatted, + sendViewModel.pendingTransaction.amountFormatted, fee: S.of(context).send_fee, feeValue: sendViewModel.pendingTransaction.feeFormatted, leftButtonText: S.of(context).ok, @@ -521,7 +514,7 @@ class SendPage extends BasePage { actionLeftButton: () { Navigator.of(context).pop(); sendViewModel.commitTransaction(); - showDialog<void>( + showPopUp<void>( context: context, builder: (BuildContext context) { return Observer(builder: (_) { @@ -564,7 +557,10 @@ class SendPage extends BasePage { onPressed: () => Navigator.of(context).pop(), text: S.of(context).send_got_it, - color: Theme.of(context).accentTextTheme.body2.color, + color: Theme.of(context) + .accentTextTheme + .body2 + .color, textColor: Colors.white)) ], ); @@ -635,7 +631,7 @@ class SendPage extends BasePage { // if (isOpenalias) { // _addressController.text = sendViewModel.recordAddress; - // await showDialog<void>( + // await showPopUp<void>( // context: context, // builder: (BuildContext context) { // return AlertWithOneAction( @@ -653,7 +649,7 @@ class SendPage extends BasePage { // final items = TransactionPriority.all; // final selectedItem = items.indexOf(sendViewModel.transactionPriority); // - // await showDialog<void>( + // await showPopUp<void>( // builder: (_) => Picker( // items: items, // selectedAtIndex: selectedItem, diff --git a/lib/src/screens/settings/change_language.dart b/lib/src/screens/settings/change_language.dart index 78e6f09fb..37801802a 100644 --- a/lib/src/screens/settings/change_language.dart +++ b/lib/src/screens/settings/change_language.dart @@ -1,67 +1,67 @@ import 'package:cake_wallet/src/screens/settings/widgets/language_row.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/entities/language.dart'; +import 'package:cake_wallet/entities/language_service.dart'; + // import 'package:cake_wallet/src/stores/settings/settings_store.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -// FIXME: FIXME +class LanguageListPage extends BasePage { + LanguageListPage(this.settingsStore); + + final SettingsStore settingsStore; -class ChangeLanguage extends BasePage { @override String get title => S.current.settings_change_language; @override Widget body(BuildContext context) { - // final settingsStore = Provider.of<SettingsStore>(context); - // final currentLanguage = Provider.of<Language>(context); - // - // return Container( - // padding: EdgeInsets.only(top: 10.0), - // child: SectionStandardList( - // sectionCount: 1, - // context: context, - // itemCounter: (int sectionIndex) => languages.values.length, - // itemBuilder: (_, sectionIndex, index) { - // final item = languages.values.elementAt(index); - // final code = languages.keys.elementAt(index); - // - // final isCurrent = settingsStore.languageCode == null - // ? false - // : code == settingsStore.languageCode; - // - // return LanguageRow( - // title: item, - // isSelected: isCurrent, - // handler: (context) async { - // if (!isCurrent) { - // await showDialog<void>( - // context: context, - // builder: (BuildContext context) { - // return AlertWithTwoActions( - // alertTitle: S.of(context).change_language, - // alertContent: S.of(context).change_language_to(item), - // rightButtonText: S.of(context).change, - // leftButtonText: S.of(context).cancel, - // actionRightButton: () { - // settingsStore.saveLanguageCode( - // languageCode: code); - // currentLanguage.setCurrentLanguage(code); - // Navigator.of(context).pop(); - // }, - // actionLeftButton: () => Navigator.of(context).pop() - // ); - // }); - // } - // }, - // ); - // }, - // ) - // ); + return Container( + padding: EdgeInsets.only(top: 10.0), + child: SectionStandardList( + sectionCount: 1, + context: context, + itemCounter: (int sectionIndex) => LanguageService.list.values.length, + itemBuilder: (_, sectionIndex, index) { + return Observer(builder: (BuildContext context) { + final item = LanguageService.list.values.elementAt(index); + final code = LanguageService.list.keys.elementAt(index); + final isCurrent = code == settingsStore.languageCode ?? false; + + return LanguageRow( + title: item, + isSelected: isCurrent, + handler: (context) async { + if (!isCurrent) { + await showPopUp<void>( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: S.of(context).change_language, + alertContent: + S.of(context).change_language_to(item), + rightButtonText: S.of(context).change, + leftButtonText: S.of(context).cancel, + actionRightButton: () { + settingsStore.languageCode = code; + Navigator.of(context).pop(); + }, + actionLeftButton: () => + Navigator.of(context).pop()); + }); + } + }, + ); + }); + }, + )); return null; } diff --git a/lib/src/screens/settings/widgets/settings_picker_cell.dart b/lib/src/screens/settings/widgets/settings_picker_cell.dart index a77e76efd..e2c949683 100644 --- a/lib/src/screens/settings/widgets/settings_picker_cell.dart +++ b/lib/src/screens/settings/widgets/settings_picker_cell.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; @@ -16,7 +17,7 @@ class SettingsPickerCell<ItemType> extends StandardListRow { onTap: (BuildContext context) async { final selectedAtIndex = items.indexOf(selectedItem); - await showDialog<void>( + await showPopUp<void>( context: context, builder: (_) => Picker( items: items, diff --git a/lib/src/screens/setup_pin_code/setup_pin_code.dart b/lib/src/screens/setup_pin_code/setup_pin_code.dart index dad0c0f2f..6cd54625d 100644 --- a/lib/src/screens/setup_pin_code/setup_pin_code.dart +++ b/lib/src/screens/setup_pin_code/setup_pin_code.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -26,7 +27,7 @@ class SetupPinCodePage extends BasePage { } if (!pinCodeViewModel.isPinCodeCorrect) { - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -43,7 +44,7 @@ class SetupPinCodePage extends BasePage { try { await pinCodeViewModel.setupPinCode(); - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( @@ -60,7 +61,7 @@ class SetupPinCodePage extends BasePage { }); } catch (e) { // FIXME: Add translation for alert content text. - await showDialog<void>( + await showPopUp<void>( context: context, builder: (BuildContext context) { return AlertWithOneAction( diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 0e743e1c9..0b845f3ed 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -1,8 +1,9 @@ +import 'package:cake_wallet/src/screens/wallet_list/widgets/wallet_menu_alert.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; @@ -10,7 +11,6 @@ import 'package:cake_wallet/src/widgets/primary_button.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/screens/wallet_list/wallet_menu.dart'; -import 'package:cake_wallet/src/screens/wallet_list/widgets/wallet_tile.dart'; class WalletListPage extends BasePage { WalletListPage({this.walletListViewModel}); @@ -65,95 +65,66 @@ class WalletListBodyState extends State<WalletListBody> { itemCount: widget.walletListViewModel.wallets.length, itemBuilder: (__, index) { final wallet = widget.walletListViewModel.wallets[index]; - final screenWidth = MediaQuery.of(context).size.width; final walletMenu = WalletMenu(context, widget.walletListViewModel); final items = walletMenu.generateItemsForWalletMenu(wallet.isCurrent); - final colors = walletMenu - .generateColorsForWalletMenu(wallet.isCurrent); - final images = walletMenu - .generateImagesForWalletMenu(wallet.isCurrent); + final currentColor = wallet.isCurrent + ? Theme.of(context).accentTextTheme.subtitle.decorationColor + : Theme.of(context).backgroundColor; - return Container( - height: tileHeight, - width: double.infinity, - child: CustomScrollView( - scrollDirection: Axis.horizontal, - controller: scrollController, - slivers: <Widget>[ - SliverPersistentHeader( - pinned: false, - floating: true, - delegate: WalletTile( - min: screenWidth - 170, - max: screenWidth, - image: _imageFor(type: wallet.type), - walletName: wallet.name, - walletAddress: '', //shortAddress, - isCurrent: wallet.isCurrent), - ), - SliverList( - delegate: - SliverChildBuilderDelegate((context, index) { - final item = items[index]; - final image = images[index]; - final firstColor = colors[index*2]; - final secondColor = colors[index*2 + 1]; - - final radius = index == 0 ? 10.0 : 0.0; - - return GestureDetector( - onTap: () { - scrollController.animateTo(0.0, - duration: Duration(milliseconds: 500), - curve: Curves.fastOutSlowIn); - walletMenu.action( - walletMenu.listItems.indexOf(item), - wallet, - wallet.isCurrent); - }, - child: Container( - height: tileHeight, - width: 80, - color: Theme.of(context).backgroundColor, + return GestureDetector( + onTap: () { + showPopUp<void>( + context: context, + builder: (dialogContext) { + return WalletMenuAlert( + wallet: wallet, + walletMenu: walletMenu, + items: items); + } + ); + }, + child: Container( + height: tileHeight, + width: double.infinity, + child: Row( + children: <Widget>[ + Container( + height: tileHeight, + width: 4, + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topRight: Radius.circular(4), + bottomRight: Radius.circular(4)), + color: currentColor + ), + ), + Expanded( child: Container( - padding: EdgeInsets.only(left: 5, right: 5), - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(radius), - bottomLeft: Radius.circular(radius)), - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - firstColor, - secondColor - ] + height: tileHeight, + padding: EdgeInsets.only(left: 20, right: 20), + color: Theme.of(context).backgroundColor, + alignment: Alignment.centerLeft, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: <Widget>[ + _imageFor(type: wallet.type), + SizedBox(width: 10), + Text( + wallet.name, + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.w600, + color: Theme.of(context).primaryTextTheme.title.color + ), ) - ), - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: <Widget>[ - image, - SizedBox(height: 2), - Text( - item, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 7, - fontWeight: FontWeight.w500, - color: Colors.white), - ) - ], - ), + ], ), ), - ), - ); - }, childCount: items.length)) - ], - ), + ), + ], + ), + ) ); }), ), diff --git a/lib/src/screens/wallet_list/wallet_menu.dart b/lib/src/screens/wallet_list/wallet_menu.dart index a508541bd..8673b192a 100644 --- a/lib/src/screens/wallet_list/wallet_menu.dart +++ b/lib/src/screens/wallet_list/wallet_menu.dart @@ -1,10 +1,10 @@ +import 'package:cake_wallet/src/screens/wallet_list/wallet_menu_item.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/view_model/wallet_list/wallet_list_view_model.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:provider/provider.dart'; import 'package:cake_wallet/generated/i18n.dart'; -// import 'package:cake_wallet/src/stores/wallet_list/wallet_list_store.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/palette.dart'; @@ -15,85 +15,46 @@ class WalletMenu { final WalletListViewModel walletListViewModel; final BuildContext context; - final List<String> listItems = [ - S.current.wallet_list_load_wallet, - S.current.show_seed, - S.current.remove, - S.current.rescan + final List<WalletMenuItem> menuItems = [ + WalletMenuItem( + title: S.current.wallet_list_load_wallet, + firstGradientColor: Palette.cornflower, + secondGradientColor: Palette.royalBlue, + image: Image.asset('assets/images/load.png', + height: 24, width: 24, color: Colors.white)), + WalletMenuItem( + title: S.current.show_seed, + firstGradientColor: Palette.moderateOrangeYellow, + secondGradientColor: Palette.moderateOrange, + image: Image.asset('assets/images/eye_action.png', + height: 24, width: 24, color: Colors.white)), + WalletMenuItem( + title: S.current.remove, + firstGradientColor: Palette.lightRed, + secondGradientColor: Palette.persianRed, + image: Image.asset('assets/images/trash.png', + height: 24, width: 24, color: Colors.white)), + WalletMenuItem( + title: S.current.rescan, + firstGradientColor: Palette.shineGreen, + secondGradientColor: Palette.moderateGreen, + image: Image.asset('assets/images/scanner.png', + height: 24, width: 24, color: Colors.white)) ]; - final List<Color> firstColors = [ - Palette.cornflower, - Palette.moderateOrangeYellow, - Palette.lightRed, - Palette.shineGreen - ]; + List<WalletMenuItem> generateItemsForWalletMenu(bool isCurrentWallet) { + final items = List<WalletMenuItem>(); - final List<Color> secondColors = [ - Palette.royalBlue, - Palette.moderateOrange, - Palette.persianRed, - Palette.moderateGreen - ]; - - final List<Image> listImages = [ - Image.asset('assets/images/load.png', - height: 24, width: 24, color: Colors.white), - Image.asset('assets/images/eye_action.png', - height: 24, width: 24, color: Colors.white), - Image.asset('assets/images/trash.png', - height: 24, width: 24, color: Colors.white), - Image.asset('assets/images/scanner.png', - height: 24, width: 24, color: Colors.white) - ]; - - List<String> generateItemsForWalletMenu(bool isCurrentWallet) { - final items = List<String>(); - - if (!isCurrentWallet) items.add(listItems[0]); - if (isCurrentWallet) items.add(listItems[1]); - if (!isCurrentWallet) items.add(listItems[2]); - if (isCurrentWallet) items.add(listItems[3]); + if (!isCurrentWallet) items.add(menuItems[0]); + if (isCurrentWallet) items.add(menuItems[1]); + if (!isCurrentWallet) items.add(menuItems[2]); + if (isCurrentWallet) items.add(menuItems[3]); return items; } - List<Color> generateColorsForWalletMenu(bool isCurrentWallet) { - final colors = <Color>[]; - - if (!isCurrentWallet) { - colors.add(firstColors[0]); - colors.add(secondColors[0]); - } - if (isCurrentWallet) { - colors.add(firstColors[1]); - colors.add(secondColors[1]); - } - if (!isCurrentWallet) { - colors.add(firstColors[2]); - colors.add(secondColors[2]); - } - if (isCurrentWallet) { - colors.add(firstColors[3]); - colors.add(secondColors[3]); - } - - return colors; - } - - List<Image> generateImagesForWalletMenu(bool isCurrentWallet) { - final images = <Image>[]; - - if (!isCurrentWallet) images.add(listImages[0]); - if (isCurrentWallet) images.add(listImages[1]); - if (!isCurrentWallet) images.add(listImages[2]); - if (isCurrentWallet) images.add(listImages[3]); - - return images; - } - Future<void> action( - int index, WalletListItem wallet, bool isCurrentWallet) async { + int index, WalletListItem wallet) async { switch (index) { case 0: await Navigator.of(context).pushNamed(Routes.auth, arguments: @@ -126,7 +87,7 @@ class WalletMenu { }); break; case 2: - final isComfirmed = await showDialog<bool>( + final isComfirmed = await showPopUp<bool>( context: context, builder: (BuildContext context) { return AlertWithTwoActions( diff --git a/lib/src/screens/wallet_list/wallet_menu_item.dart b/lib/src/screens/wallet_list/wallet_menu_item.dart new file mode 100644 index 000000000..55e7189c5 --- /dev/null +++ b/lib/src/screens/wallet_list/wallet_menu_item.dart @@ -0,0 +1,16 @@ +import 'dart:ui'; +import 'package:flutter/cupertino.dart'; + +class WalletMenuItem { + WalletMenuItem({ + @required this.title, + @required this.firstGradientColor, + @required this.secondGradientColor, + @required this.image + }); + + final String title; + final Color firstGradientColor; + final Color secondGradientColor; + final Image image; +} \ No newline at end of file diff --git a/lib/src/screens/wallet_list/widgets/wallet_menu_alert.dart b/lib/src/screens/wallet_list/widgets/wallet_menu_alert.dart new file mode 100644 index 000000000..e5f68597f --- /dev/null +++ b/lib/src/screens/wallet_list/widgets/wallet_menu_alert.dart @@ -0,0 +1,112 @@ +import 'dart:ui'; +import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/src/screens/wallet_list/wallet_menu.dart'; +import 'package:cake_wallet/src/screens/wallet_list/wallet_menu_item.dart'; +import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/src/widgets/alert_background.dart'; +import 'package:cake_wallet/src/widgets/alert_close_button.dart'; + +class WalletMenuAlert extends StatelessWidget { + WalletMenuAlert({ + @required this.wallet, + @required this.walletMenu, + @required this.items + }); + + final WalletListItem wallet; + final WalletMenu walletMenu; + final List<WalletMenuItem> items; + final closeButton = Image.asset('assets/images/close.png', + color: Palette.darkBlueCraiola, + ); + + @override + Widget build(BuildContext context) { + return AlertBackground( + child: Stack( + alignment: Alignment.center, + children: <Widget>[ + Padding( + padding: EdgeInsets.only( + left: 24, + right: 24, + ), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(14)), + child: Container( + color: Theme.of(context).textTheme.body2.decorationColor, + padding: EdgeInsets.only(left: 24), + child: ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: items.length, + separatorBuilder: (context, _) => Container( + height: 1, + color: Theme.of(context).accentTextTheme.subhead.backgroundColor, + ), + itemBuilder: (_, index) { + final item = items[index]; + + return GestureDetector( + onTap: () { + Navigator.of(context).pop(); + walletMenu.action( + walletMenu.menuItems.indexOf(item), + wallet); + }, + child: Container( + height: 60, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: <Widget>[ + Container( + height: 32, + width: 32, + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(4)), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + item.firstGradientColor, + item.secondGradientColor + ] + ) + ), + child: Center( + child: item.image, + ), + ), + SizedBox(width: 12), + Expanded( + child: Text( + item.title, + style: TextStyle( + color: Theme.of(context).primaryTextTheme.title.color, + fontSize: 18, + fontFamily: 'Poppins', + fontWeight: FontWeight.w500, + decoration: TextDecoration.none + ), + ) + ) + ], + ), + ), + ); + }, + ), + ), + ), + ), + AlertCloseButton(image: closeButton) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/screens/wallet_list/widgets/wallet_tile.dart b/lib/src/screens/wallet_list/widgets/wallet_tile.dart deleted file mode 100644 index 4e4165341..000000000 --- a/lib/src/screens/wallet_list/widgets/wallet_tile.dart +++ /dev/null @@ -1,151 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; - -class WalletTile extends SliverPersistentHeaderDelegate { - WalletTile({ - @required this.min, - @required this.max, - @required this.image, - @required this.walletName, - @required this.walletAddress, - @required this.isCurrent - }); - - final double min; - final double max; - final Image image; - final String walletName; - final String walletAddress; - final bool isCurrent; - final double tileHeight = 60; - - @override - Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { - var opacity = 1 - shrinkOffset / (max - min); - opacity = opacity >= 0 ? opacity : 0; - - var panelWidth = 10 * opacity; - panelWidth = panelWidth < 10 ? 0 : 10; - - final currentColor = isCurrent - ? Theme.of(context).accentTextTheme.subtitle.decorationColor - : Theme.of(context).backgroundColor; - - return Stack( - fit: StackFit.expand, - overflow: Overflow.visible, - children: <Widget>[ - Positioned( - top: 0, - right: max - 4, - child: Container( - height: tileHeight, - width: 4, - decoration: BoxDecoration( - borderRadius: BorderRadius.only(topRight: Radius.circular(4), bottomRight: Radius.circular(4)), - color: currentColor - ), - ), - ), - Positioned( - top: 0, - right: 10, - child: Container( - height: tileHeight, - width: max - 14, - padding: EdgeInsets.only(left: 20, right: 20), - color: Theme.of(context).backgroundColor, - alignment: Alignment.centerLeft, - child: Row( - //mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: <Widget>[ - image, - SizedBox(width: 10), - Text( - walletName, - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme.title.color - ), - ) - ], - ), - /*Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: <Widget>[ - image, - SizedBox(width: 10), - Text( - walletName, - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - color: Theme.of(context).primaryTextTheme.title.color - ), - ) - ], - ), - isCurrent ? SizedBox(height: 5) : Offstage(), - isCurrent - ? Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: <Widget>[ - SizedBox(width: 34), - Text( - walletAddress, - style: TextStyle( - fontSize: 12, - color: Theme.of(context).primaryTextTheme.caption.color - ), - ) - ], - ) - : Offstage() - ], - ),*/ - ), - ), - Positioned( - top: 0, - right: 0, - child: Opacity( - opacity: opacity, - child: Container( - height: tileHeight, - width: panelWidth, - decoration: BoxDecoration( - borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)), - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Theme.of(context).accentTextTheme.headline.color, - Theme.of(context).accentTextTheme.headline.backgroundColor - ] - ) - ), - ), - ) - ), - ], - ); - } - - @override - double get maxExtent => max; - - @override - double get minExtent => min; - - @override - bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true; - -} \ No newline at end of file diff --git a/lib/src/screens/welcome/welcome_page.dart b/lib/src/screens/welcome/welcome_page.dart index 78cd04835..aa0d5b80c 100644 --- a/lib/src/screens/welcome/welcome_page.dart +++ b/lib/src/screens/welcome/welcome_page.dart @@ -103,7 +103,7 @@ class WelcomePage extends BasePage { Padding( padding: EdgeInsets.only(top: 24), child: PrimaryImageButton( - onPressed: () => Navigator.pushNamed(context, Routes.newWalletFromWelcome), + onPressed: () => Navigator.pushNamed(context, Routes.newWallet), image: newWalletImage, text: S.of(context).create_new, color: Theme.of(context).accentTextTheme.subtitle.decorationColor, @@ -113,7 +113,7 @@ class WelcomePage extends BasePage { Padding( padding: EdgeInsets.only(top: 10), child: PrimaryImageButton( - onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletOptionsFromWelcome), + onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletOptions), image: restoreWalletImage, text: S.of(context).restore_wallet, color: Theme.of(context).accentTextTheme.caption.color, diff --git a/lib/src/widgets/alert_close_button.dart b/lib/src/widgets/alert_close_button.dart index 0f21be5df..9349eb5b7 100644 --- a/lib/src/widgets/alert_close_button.dart +++ b/lib/src/widgets/alert_close_button.dart @@ -8,7 +8,7 @@ class AlertCloseButton extends StatelessWidget { @override Widget build(BuildContext context) { return Positioned( - bottom: 24, + bottom: 60, child: GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( diff --git a/lib/src/widgets/seed_language_selector.dart b/lib/src/widgets/seed_language_selector.dart index 74420d370..57011f323 100644 --- a/lib/src/widgets/seed_language_selector.dart +++ b/lib/src/widgets/seed_language_selector.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; @@ -35,7 +36,7 @@ class SeedLanguageSelectorState extends State<SeedLanguageSelector> { image: null, text: seedLocales[seedLanguages.indexOf(selected)], onTap: () async { - final selected = await showDialog<String>( + final selected = await showPopUp<String>( context: context, builder: (BuildContext context) => SeedLanguagePicker(key: _pickerKey, selected: this.selected)); diff --git a/lib/store/app_store.dart b/lib/store/app_store.dart index 7b0cefe74..7421fa54e 100644 --- a/lib/store/app_store.dart +++ b/lib/store/app_store.dart @@ -4,7 +4,6 @@ import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/node_list_store.dart'; -import 'package:cake_wallet/store/contact_list_store.dart'; part 'app_store.g.dart'; @@ -15,7 +14,6 @@ abstract class AppStoreBase with Store { {this.authenticationStore, this.walletList, this.settingsStore, - this.contactListStore, this.nodeListStore}); AuthenticationStore authenticationStore; @@ -27,7 +25,5 @@ abstract class AppStoreBase with Store { SettingsStore settingsStore; - ContactListStore contactListStore; - NodeListStore nodeListStore; } diff --git a/lib/store/contact_list_store.dart b/lib/store/contact_list_store.dart deleted file mode 100644 index ca3d0bcf0..000000000 --- a/lib/store/contact_list_store.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/entities/contact.dart'; - -part 'contact_list_store.g.dart'; - -class ContactListStore = ContactListStoreBase with _$ContactListStore; - -abstract class ContactListStoreBase with Store { - ContactListStoreBase() : contacts = ObservableList<Contact>(); - - final ObservableList<Contact> contacts; -} diff --git a/lib/store/node_list_store.dart b/lib/store/node_list_store.dart index 0ff958e3f..56fe0333a 100644 --- a/lib/store/node_list_store.dart +++ b/lib/store/node_list_store.dart @@ -22,17 +22,13 @@ abstract class NodeListStoreBase with Store { final nodeSource = getIt.get<Box<Node>>(); _instance = NodeListStore(); - _instance.replaceValues(nodeSource.values); + _instance.nodes.clear(); + _instance.nodes.addAll(nodeSource.values); _onNodesSourceChange?.cancel(); - _onNodesSourceChange = bindBox(nodeSource, _instance.nodes); + _onNodesSourceChange = nodeSource.bindToList(_instance.nodes); return _instance; } final ObservableList<Node> nodes; - - void replaceValues(Iterable<Node> newNodes) { - nodes.clear(); - nodes.addAll(newNodes); - } } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index e17ce2de9..399cae107 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -1,5 +1,7 @@ import 'package:cake_wallet/entities/preferences_key.dart'; +import 'package:cake_wallet/themes.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:package_info/package_info.dart'; @@ -7,7 +9,7 @@ import 'package:devicelocale/devicelocale.dart'; import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:cake_wallet/entities/language.dart'; +import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/node.dart'; @@ -21,7 +23,6 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore; abstract class SettingsStoreBase with Store { SettingsStoreBase( {@required SharedPreferences sharedPreferences, - @required Box<Node> nodeSource, @required FiatCurrency initialFiatCurrency, @required TransactionPriority initialTransactionPriority, @required BalanceDisplayMode initialBalanceDisplayMode, @@ -30,7 +31,7 @@ abstract class SettingsStoreBase with Store { @required bool initialDarkTheme, @required int initialPinLength, @required String initialLanguageCode, - @required String initialCurrentLocale, + // @required String initialCurrentLocale, @required this.appVersion, @required Map<WalletType, Node> nodes, this.actionlistDisplayMode}) { @@ -42,11 +43,9 @@ abstract class SettingsStoreBase with Store { isDarkTheme = initialDarkTheme; pinCodeLength = initialPinLength; languageCode = initialLanguageCode; - currentLocale = initialCurrentLocale; - itemHeaders = {}; + currentNode = nodes[WalletType.monero]; this.nodes = ObservableMap<WalletType, Node>.of(nodes); _sharedPreferences = sharedPreferences; - _nodeSource = nodeSource; reaction( (_) => allowBiometricalAuthentication, @@ -58,6 +57,13 @@ abstract class SettingsStoreBase with Store { (_) => pinCodeLength, (int pinLength) => sharedPreferences.setInt( PreferencesKey.currentPinLength, pinLength)); + + reaction((_) => currentNode, + (Node node) => _saveCurrentNode(node, WalletType.monero)); + + reaction((_) => languageCode, + (String languageCode) => sharedPreferences.setString( + PreferencesKey.currentLanguageCode, languageCode)); } static const defaultPinLength = 4; @@ -88,16 +94,17 @@ abstract class SettingsStoreBase with Store { int pinCodeLength; @observable - Map<String, String> itemHeaders; + Node currentNode; + @computed + ThemeData get theme => isDarkTheme ? Themes.darkTheme : Themes.lightTheme; + + @observable String languageCode; - String currentLocale; - String appVersion; SharedPreferences _sharedPreferences; - Box<Node> _nodeSource; ObservableMap<WalletType, Node> nodes; @@ -135,8 +142,7 @@ abstract class SettingsStoreBase with Store { defaultPinLength; final savedLanguageCode = sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? - await Language.localeDetection(); - final initialCurrentLocale = await Devicelocale.currentLocale; + await LanguageService.localeDetection(); final nodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey); final bitcoinElectrumServerId = sharedPreferences .getInt(PreferencesKey.currentBitcoinElectrumSererIdKey); @@ -150,7 +156,6 @@ abstract class SettingsStoreBase with Store { WalletType.monero: moneroNode, WalletType.bitcoin: bitcoinElectrumServer }, - nodeSource: nodeSource, appVersion: packageInfo.version, initialFiatCurrency: currentFiatCurrency, initialTransactionPriority: currentTransactionPriority, @@ -160,11 +165,11 @@ abstract class SettingsStoreBase with Store { initialDarkTheme: savedDarkTheme, actionlistDisplayMode: actionListDisplayMode, initialPinLength: pinLength, - initialLanguageCode: savedLanguageCode, - initialCurrentLocale: initialCurrentLocale); + initialLanguageCode: savedLanguageCode + ); } - Future<void> setCurrentNode(Node node, WalletType walletType) async { + Future<void> _saveCurrentNode(Node node, WalletType walletType) async { switch (walletType) { case WalletType.bitcoin: await _sharedPreferences.setInt( diff --git a/lib/store/theme_changer_store.dart b/lib/store/theme_changer_store.dart deleted file mode 100644 index 8c2e366ca..000000000 --- a/lib/store/theme_changer_store.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:cake_wallet/theme_changer.dart'; -import 'package:mobx/mobx.dart'; - -part 'theme_changer_store.g.dart'; - -class ThemeChangerStore = ThemeChangerStoreBase with _$ThemeChangerStore; - -abstract class ThemeChangerStoreBase with Store { - ThemeChangerStoreBase({this.themeChanger}); - - @observable - ThemeChanger themeChanger; -} \ No newline at end of file diff --git a/lib/theme_changer.dart b/lib/theme_changer.dart deleted file mode 100644 index c26e0722c..000000000 --- a/lib/theme_changer.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class ThemeChanger with ChangeNotifier { - - ThemeChanger(this._themeData); - - ThemeData _themeData; - - ThemeData getTheme() => _themeData; - - void setTheme(ThemeData theme){ - _themeData = theme; - - notifyListeners(); - } -} \ No newline at end of file diff --git a/lib/utils/date_formatter.dart b/lib/utils/date_formatter.dart index cd64ef910..9707a9a70 100644 --- a/lib/utils/date_formatter.dart +++ b/lib/utils/date_formatter.dart @@ -4,7 +4,7 @@ import 'package:cake_wallet/store/settings_store.dart'; class DateFormatter { static String get currentLocalFormat { - final isUSA = getIt.get<SettingsStore>().currentLocale == 'en_US'; + final isUSA = getIt.get<SettingsStore>().languageCode.toLowerCase() == 'en'; final format = isUSA ? 'yyyy.MM.dd, HH:mm' : 'dd.MM.yyyy, HH:mm'; return format; diff --git a/lib/utils/item_cell.dart b/lib/utils/item_cell.dart index 4aca57b46..150df6d50 100644 --- a/lib/utils/item_cell.dart +++ b/lib/utils/item_cell.dart @@ -1,11 +1,18 @@ import 'package:flutter/foundation.dart'; +import 'package:mobx/mobx.dart'; import 'package:cake_wallet/utils/mobx.dart'; +// part 'node_list_view_model.g.dart'; +// +// class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel; + class ItemCell<Item> with Keyable { - ItemCell(this.value, {@required this.isSelected, @required dynamic key}) { + ItemCell(this.value, {this.isSelectedBuilder, @required dynamic key}) { keyIndex = key; } final Item value; - final bool isSelected; + + bool get isSelected => isSelectedBuilder(value); + bool Function(Item item) isSelectedBuilder; } diff --git a/lib/utils/mobx.dart b/lib/utils/mobx.dart index cb2d810e5..344e16b64 100644 --- a/lib/utils/mobx.dart +++ b/lib/utils/mobx.dart @@ -6,36 +6,6 @@ mixin Keyable { dynamic keyIndex; } -void connectWithTransform<T extends Keyable, Y extends Keyable>( - ObservableList<T> source, ObservableList<Y> dest, Y Function(T) transform, - {bool Function(T) filter}) { - source.observe((ListChange<T> change) { - change.elementChanges.forEach((change) { - switch (change.type) { - case OperationType.add: - if (filter?.call(change.newValue as T) ?? true) { - dest.add(transform(change.newValue as T)); - } - break; - case OperationType.remove: - // Hive could has equal index and key - dest.removeWhere( - (elem) => elem.keyIndex == (change.oldValue.key ?? change.index)); - break; - case OperationType.update: - for (var i = 0; i < dest.length; i++) { - final item = dest[i]; - - if (item.keyIndex == change.newValue.key) { - dest[i] = transform(change.newValue as T); - } - } - break; - } - }); - }); -} - void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>( ObservableMap<dynamic, T> source, ObservableList<Y> dest, @@ -50,8 +20,8 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>( break; case OperationType.remove: // Hive could has equal index and key - dest.removeWhere( - (elem) => elem.keyIndex == (change.key ?? change.newValue.keyIndex)); + dest.removeWhere((elem) => + elem.keyIndex == (change.key ?? change.newValue.keyIndex)); break; case OperationType.update: for (var i = 0; i < dest.length; i++) { @@ -66,54 +36,126 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>( }); } -void connect<T extends Keyable>( - ObservableList<T> source, ObservableList<T> dest) { - source.observe((ListChange<T> change) { - source.observe((ListChange<T> change) { - change.elementChanges.forEach((change) { - switch (change.type) { - case OperationType.add: - // if (filter?.call(change.newValue as T) ?? true) { - dest.add(change.newValue as T); - // } - break; - case OperationType.remove: - // Hive could has equal index and key - dest.removeWhere((elem) => - elem.keyIndex == (change.oldValue.key ?? change.index)); - break; - case OperationType.update: - for (var i = 0; i < dest.length; i++) { - final item = dest[i]; +typedef Filter<T> = bool Function(T); +typedef Transform<T, Y> = Y Function(T); - if (item.keyIndex == change.newValue.key) { - dest[i] = change.newValue as T; - } - } - break; - } - }); - }); - }); +enum ChangeType { update, delete, add } + +class EntityChange<T extends Keyable> { + EntityChange(this.value, this.type, {dynamic key}) : _key = key; + + dynamic get key => _key ?? value.keyIndex; + final T value; + final ChangeType type; + final dynamic _key; } -StreamSubscription<BoxEvent> bindBox<T extends Keyable>( - Box<T> source, ObservableList<T> dest) { - return source.watch().listen((event) { +extension MobxBindable<T extends Keyable> on Box<T> { + StreamSubscription<BoxEvent> bindToList( + ObservableList<T> dest, { + bool initialFire = false, + Filter<T> filter, + }) { + if (initialFire) { + dest.addAll(values); + } + + return watch().listen((event) { + if (filter != null && !filter(event.value as T)) { + return; + } + + dest.acceptBoxChange(event); + }); + } + + StreamSubscription<BoxEvent> bindToListWithTransform<Y extends Keyable>( + ObservableList<Y> dest, + Transform<T, Y> transform, { + bool initialFire = false, + Filter<T> filter, + }) { + if (initialFire) { + dest.addAll(values.map((value) => transform(value))); + } + + return watch().listen((event) { + if (filter != null && !filter(event.value as T)) { + return; + } + + dest.acceptBoxChange(event, + transformed: event.deleted ? null : transform(event.value as T)); + }); + } +} + +extension HiveBindable<T extends Keyable> on ObservableList<T> { + Stream<EntityChange<T>> listen() { + // ignore: close_sinks + final controller = StreamController<EntityChange<T>>(); + + observe((ListChange<T> change) { + change.elementChanges.forEach((change) { + ChangeType type; + + switch (change.type) { + case OperationType.add: + type = ChangeType.add; + break; + case OperationType.remove: + type = ChangeType.delete; + break; + case OperationType.update: + type = ChangeType.update; + break; + } + + final value = change.newValue as T; + controller.add(EntityChange(value, type, + key: type == ChangeType.delete ? change.index : value.keyIndex)); + }); + }); + + return controller.stream; + } + + StreamSubscription<EntityChange<T>> bindToList(ObservableList<T> dest) => + listen().listen((event) => dest.acceptEntityChange(event)); + + void acceptBoxChange(BoxEvent event, {T transformed}) { if (event.deleted) { - dest.removeWhere((el) => el.keyIndex == event.key); + removeWhere((el) => el.keyIndex == event.key); + } + + final dynamic value = transformed ?? event.value; + + if (value is T) { + final index = indexWhere((el) => el.keyIndex == value.keyIndex); + + if (index > -1) { + this.setAll(index, [value]); // FIXME: fixme + } else { + add(value); + } + } + } + + void acceptEntityChange(EntityChange<T> event) { + if (event.type == ChangeType.delete) { + removeWhere((el) => el.keyIndex == event.key); } final dynamic value = event.value; if (value is T) { - final elIndex = dest.indexWhere((el) => el.keyIndex == value.keyIndex); + final index = indexWhere((el) => el.keyIndex == value.keyIndex); - if (elIndex > -1) { - dest[elIndex] = value; + if (index > -1) { + this.setAll(index, [value]); // FIXME: fixme } else { - dest.add(value); + add(value); } } - }); + } } diff --git a/lib/utils/show_pop_up.dart b/lib/utils/show_pop_up.dart new file mode 100644 index 000000000..a97fb3762 --- /dev/null +++ b/lib/utils/show_pop_up.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +Future<T> showPopUp<T>({ + @required BuildContext context, + WidgetBuilder builder, + bool barrierDismissible = true, + Color barrierColor, + bool useSafeArea = false, + bool useRootNavigator = true, + RouteSettings routeSettings, + Widget child, +}) { + return showDialog<T>( + context: context, + builder: builder, + barrierDismissible: barrierDismissible, + barrierColor: barrierColor, + useSafeArea: useSafeArea, + useRootNavigator: useRootNavigator, + routeSettings: routeSettings, + child: child); +} diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart index d222cb6dd..8a59a0589 100644 --- a/lib/view_model/contact_list/contact_list_view_model.dart +++ b/lib/view_model/contact_list/contact_list_view_model.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/core/contact_service.dart'; -import 'package:cake_wallet/store/contact_list_store.dart'; +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/utils/mobx.dart'; @@ -12,22 +11,16 @@ class ContactListViewModel = ContactListViewModelBase with _$ContactListViewModel; abstract class ContactListViewModelBase with Store { - ContactListViewModelBase( - this.addressBookStore, this.contactService, this.contactSource) { - _subscription = bindBox(contactSource, addressBookStore.contacts); + ContactListViewModelBase(this.contactSource) + : contacts = ObservableList<ContactRecord>() { + _subscription = contactSource.bindToListWithTransform( + contacts, (Contact contact) => ContactRecord(contactSource, contact), + initialFire: true); } - final ContactListStore addressBookStore; - final ContactService contactService; final Box<Contact> contactSource; - - ObservableList<Contact> get contacts => addressBookStore.contacts; - + final ObservableList<ContactRecord> contacts; StreamSubscription<BoxEvent> _subscription; - void dispose() { - _subscription.cancel(); - } - - Future<void> delete(Contact contact) async => contactService.delete(contact); + Future<void> delete(ContactRecord contact) async => contact.original.delete(); } diff --git a/lib/view_model/contact_list/contact_view_model.dart b/lib/view_model/contact_list/contact_view_model.dart index 059b6a210..7e6312d1d 100644 --- a/lib/view_model/contact_list/contact_view_model.dart +++ b/lib/view_model/contact_list/contact_view_model.dart @@ -1,8 +1,8 @@ +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/core/wallet_base.dart'; -import 'package:cake_wallet/core/contact_service.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; @@ -11,13 +11,13 @@ part 'contact_view_model.g.dart'; class ContactViewModel = ContactViewModelBase with _$ContactViewModel; abstract class ContactViewModelBase with Store { - ContactViewModelBase(this._contacts, this._wallet, {Contact contact}) + ContactViewModelBase(this._contacts, {ContactRecord contact}) : state = InitialExecutionState(), currencies = CryptoCurrency.all, _contact = contact { name = _contact?.name; address = _contact?.address; - currency = _contact?.type; //_wallet.currency; + currency = _contact?.type; } @observable @@ -39,9 +39,8 @@ abstract class ContactViewModelBase with Store { (address?.isNotEmpty ?? false); final List<CryptoCurrency> currencies; - final WalletBase _wallet; final Box<Contact> _contacts; - final Contact _contact; + final ContactRecord _contact; @action void reset() { @@ -57,8 +56,8 @@ abstract class ContactViewModelBase with Store { if (_contact != null) { _contact.name = name; _contact.address = address; - _contact.updateCryptoCurrency(currency: currency); - await _contacts.put(_contact.key, _contact); + _contact.type = currency; + await _contact.save(); } else { await _contacts .add(Contact(name: name, address: address, type: currency)); diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 23fd578f1..58978c946 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/core/wallet_base.dart'; +import 'package:cake_wallet/entities/crypto_currency.dart'; import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount.dart'; @@ -92,6 +93,9 @@ abstract class BalanceViewModelBase with Store { return null; } + @computed + CryptoCurrency get currency => appStore.wallet.currency; + String _getFiatBalance({double price, String cryptoAmount}) { if (cryptoAmount == null) { return '0.00'; diff --git a/lib/view_model/node_list/node_list_view_model.dart b/lib/view_model/node_list/node_list_view_model.dart index 4ca46c9fc..2231ff7c9 100644 --- a/lib/view_model/node_list/node_list_view_model.dart +++ b/lib/view_model/node_list/node_list_view_model.dart @@ -1,45 +1,29 @@ import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/core/wallet_base.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/entities/node_list.dart'; -import 'package:cake_wallet/store/node_list_store.dart'; -import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/entities/default_settings_migration.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/utils/mobx.dart'; -import 'package:cake_wallet/utils/item_cell.dart'; part 'node_list_view_model.g.dart'; class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel; abstract class NodeListViewModelBase with Store { - NodeListViewModelBase( - this._nodeListStore, this._nodeSource, this._wallet, this._settingsStore) - : nodes = ObservableList<ItemCell<Node>>() { - final currentNode = _settingsStore.getCurrentNode(_wallet.type); - final values = _nodeListStore.nodes; - nodes.clear(); - nodes.addAll(values.where((Node node) => node.type == _wallet.type).map( - (Node val) => ItemCell<Node>(val, - isSelected: val.key == currentNode.key, key: val.key))); - connectWithTransform( - _nodeListStore.nodes, - nodes, - (Node val) => ItemCell<Node>(val, - isSelected: val.key == currentNode.key, key: val.key), - filter: (Node val) => val.type == _wallet.type); - reaction((_) => _settingsStore.nodes[_wallet.type], - (Node _) => _updateCurrentNode()); + NodeListViewModelBase(this._nodeSource, this._wallet, this.settingsStore) + : nodes = ObservableList<Node>() { + _nodeSource.bindToList(nodes, + filter: (Node val) => val.type == _wallet.type, initialFire: true); } - ObservableList<ItemCell<Node>> nodes; + final ObservableList<Node> nodes; + final SettingsStore settingsStore; final WalletBase _wallet; final Box<Node> _nodeSource; - final NodeListStore _nodeListStore; - final SettingsStore _settingsStore; Future<void> reset() async { await resetToDefault(_nodeSource); @@ -64,24 +48,6 @@ abstract class NodeListViewModelBase with Store { Future<void> delete(Node node) async => _nodeSource.delete(node.key); - Future<void> setAsCurrent(Node node) async { - await _settingsStore.setCurrentNode(node, _wallet.type); - _updateCurrentNode(); - await _wallet.connectToNode(node: node); - } - - @action - void _updateCurrentNode() { - final currentNode = _settingsStore.getCurrentNode(_wallet.type); - - for (var i = 0; i < nodes.length; i++) { - final item = nodes[i]; - final isSelected = item.value.key == currentNode.key; - - if (item.isSelected != isSelected) { - nodes[i] = ItemCell<Node>(item.value, - isSelected: isSelected, key: item.keyIndex); - } - } - } + Future<void> setAsCurrent(Node node) async => + settingsStore.currentNode = node; } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index a664690de..19678cd03 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -70,15 +70,17 @@ abstract class SendViewModelBase with Store { @computed String get balance { + String balance = '0.0'; + if (_wallet is MoneroWallet) { - _wallet.balance.formattedUnlockedBalance; + balance = _wallet.balance.formattedUnlockedBalance as String ?? ''; } if (_wallet is BitcoinWallet) { - _wallet.balance.confirmedFormatted; + balance = _wallet.balance.confirmedFormatted as String ?? ''; } - return '0.0'; + return balance; } @computed diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart index 61ffda19b..e0ce07738 100644 --- a/lib/view_model/settings/settings_view_model.dart +++ b/lib/view_model/settings/settings_view_model.dart @@ -1,27 +1,24 @@ -import 'package:cake_wallet/core/wallet_base.dart'; -import 'package:cake_wallet/entities/biometric_auth.dart'; -import 'package:cake_wallet/entities/wallet_type.dart'; -import 'package:cake_wallet/di.dart'; -import 'package:cake_wallet/store/theme_changer_store.dart'; -import 'package:cake_wallet/themes.dart'; -import 'package:cake_wallet/view_model/settings/version_list_item.dart'; import 'package:flutter/cupertino.dart'; import 'package:mobx/mobx.dart'; +import 'package:package_info/package_info.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/entities/biometric_auth.dart'; +import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; import 'package:cake_wallet/entities/action_list_display_mode.dart'; -import 'package:cake_wallet/src/screens/auth/auth_page.dart'; +import 'package:cake_wallet/view_model/settings/version_list_item.dart'; import 'package:cake_wallet/view_model/settings/link_list_item.dart'; import 'package:cake_wallet/view_model/settings/picker_list_item.dart'; import 'package:cake_wallet/view_model/settings/regular_list_item.dart'; import 'package:cake_wallet/view_model/settings/settings_list_item.dart'; import 'package:cake_wallet/view_model/settings/switcher_list_item.dart'; -import 'package:package_info/package_info.dart'; +import 'package:cake_wallet/src/screens/auth/auth_page.dart'; part 'settings_view_model.g.dart'; @@ -40,7 +37,9 @@ abstract class SettingsViewModelBase with Store { PickerListItem( title: S.current.settings_display_balance_as, items: BalanceDisplayMode.all, - selectedItem: () => balanceDisplayMode), + selectedItem: () => balanceDisplayMode, + onItemSelected: (BalanceDisplayMode mode) => + _settingsStore.balanceDisplayMode = mode), PickerListItem( title: S.current.settings_currency, items: FiatCurrency.all, @@ -109,13 +108,8 @@ abstract class SettingsViewModelBase with Store { SwitcherListItem( title: S.current.settings_dark_mode, value: () => _settingsStore.isDarkTheme, - onValueChange: (_, bool value) { - _settingsStore.isDarkTheme = value; - getIt - .get<ThemeChangerStore>() - .themeChanger - .setTheme(value ? Themes.darkTheme : Themes.lightTheme); - }) + onValueChange: (_, bool value) => + _settingsStore.isDarkTheme = value) ], [ LinkListItem( @@ -204,6 +198,7 @@ abstract class SettingsViewModelBase with Store { @action void setFiatCurrency(FiatCurrency value) => _settingsStore.fiatCurrency = value; + @action void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value; diff --git a/lib/view_model/wallet_list/wallet_list_view_model.dart b/lib/view_model/wallet_list/wallet_list_view_model.dart index 3be5d164c..8bb102620 100644 --- a/lib/view_model/wallet_list/wallet_list_view_model.dart +++ b/lib/view_model/wallet_list/wallet_list_view_model.dart @@ -35,7 +35,7 @@ abstract class WalletListViewModelBase with Store { @action Future<void> remove(WalletListItem wallet) async { - final walletService = getIt.get<WalletService>(); + final walletService = getIt.get<WalletService>(param1: wallet.type); await walletService.remove(wallet.name); await _walletInfoSource.delete(wallet.key); _updateList(); diff --git a/pubspec.lock b/pubspec.lock index 9b14f0555..f9bbbbd26 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -217,7 +217,7 @@ packages: name: connectivity url: "https://pub.dartlang.org" source: hosted - version: "0.4.9+2" + version: "0.4.9+3" connectivity_for_web: dependency: transitive description: @@ -395,7 +395,7 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "1.0.9" + version: "1.0.11" flutter_secure_storage: dependency: "direct main" description: @@ -470,7 +470,7 @@ packages: name: hive_generator url: "https://pub.dartlang.org" source: hosted - version: "0.7.1" + version: "0.7.2+1" html: dependency: transitive description: @@ -505,7 +505,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.17" + version: "2.1.18" intl: dependency: "direct main" description: @@ -533,14 +533,14 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.1.0" local_auth: dependency: "direct main" description: name: local_auth url: "https://pub.dartlang.org" source: hosted - version: "0.6.3+1" + version: "0.6.3+2" logging: dependency: transitive description: @@ -645,7 +645,7 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.17" + version: "1.6.18" path_provider_linux: dependency: transitive description: @@ -695,13 +695,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.1" - platform_detect: - dependency: transitive - description: - name: platform_detect - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" plugin_platform_interface: dependency: transitive description: @@ -785,14 +778,14 @@ packages: name: share url: "https://pub.dartlang.org" source: hosted - version: "0.6.5+1" + version: "0.6.5+2" shared_preferences: dependency: "direct main" description: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "0.5.11" + version: "0.5.12" shared_preferences_linux: dependency: transitive description: @@ -937,7 +930,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "5.7.0" + version: "5.7.2" url_launcher_linux: dependency: transitive description: @@ -965,7 +958,7 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.3+2" + version: "0.1.4+1" url_launcher_windows: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f15f131c1..d6ac4bf73 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ description: Cake Wallet. version: 1.0.5+5 environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.7.0 <3.0.0" dependencies: flutter: diff --git a/test/widget_test.dart b/test/widget_test.dart index 175df3eb4..2c7ba24a5 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -13,7 +13,7 @@ import 'package:cake_wallet/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(CakeWalletApp()); + await tester.pumpWidget(App()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget);