diff --git a/assets/images/flags/aus.png b/assets/images/flags/aus.png new file mode 100644 index 000000000..c8837731c Binary files /dev/null and b/assets/images/flags/aus.png differ diff --git a/assets/images/flags/bgr.png b/assets/images/flags/bgr.png new file mode 100644 index 000000000..a89509f1f Binary files /dev/null and b/assets/images/flags/bgr.png differ diff --git a/assets/images/flags/bra.png b/assets/images/flags/bra.png new file mode 100644 index 000000000..ecac6f5a3 Binary files /dev/null and b/assets/images/flags/bra.png differ diff --git a/assets/images/flags/cad.png b/assets/images/flags/cad.png new file mode 100644 index 000000000..106cea5b9 Binary files /dev/null and b/assets/images/flags/cad.png differ diff --git a/assets/images/flags/che.png b/assets/images/flags/che.png new file mode 100644 index 000000000..427db0fbc Binary files /dev/null and b/assets/images/flags/che.png differ diff --git a/assets/images/flags/chn.png b/assets/images/flags/chn.png new file mode 100644 index 000000000..7a03dd26e Binary files /dev/null and b/assets/images/flags/chn.png differ diff --git a/assets/images/flags/czk.png b/assets/images/flags/czk.png new file mode 100644 index 000000000..a6c13a773 Binary files /dev/null and b/assets/images/flags/czk.png differ diff --git a/assets/images/flags/deu.png b/assets/images/flags/deu.png new file mode 100644 index 000000000..95b88a0ea Binary files /dev/null and b/assets/images/flags/deu.png differ diff --git a/assets/images/flags/dnk.png b/assets/images/flags/dnk.png new file mode 100644 index 000000000..69dd1b2b8 Binary files /dev/null and b/assets/images/flags/dnk.png differ diff --git a/assets/images/flags/esp.png b/assets/images/flags/esp.png new file mode 100644 index 000000000..0193a6a44 Binary files /dev/null and b/assets/images/flags/esp.png differ diff --git a/assets/images/flags/eur.png b/assets/images/flags/eur.png new file mode 100644 index 000000000..1312b0200 Binary files /dev/null and b/assets/images/flags/eur.png differ diff --git a/assets/images/flags/fra.png b/assets/images/flags/fra.png new file mode 100644 index 000000000..91dce8ff2 Binary files /dev/null and b/assets/images/flags/fra.png differ diff --git a/assets/images/flags/gbr.png b/assets/images/flags/gbr.png new file mode 100644 index 000000000..151f06db5 Binary files /dev/null and b/assets/images/flags/gbr.png differ diff --git a/assets/images/flags/hkg.png b/assets/images/flags/hkg.png new file mode 100644 index 000000000..85925604e Binary files /dev/null and b/assets/images/flags/hkg.png differ diff --git a/assets/images/flags/hrv.png b/assets/images/flags/hrv.png new file mode 100644 index 000000000..9c87c5d0e Binary files /dev/null and b/assets/images/flags/hrv.png differ diff --git a/assets/images/flags/hun.png b/assets/images/flags/hun.png new file mode 100644 index 000000000..9722561a8 Binary files /dev/null and b/assets/images/flags/hun.png differ diff --git a/assets/images/flags/idn.png b/assets/images/flags/idn.png new file mode 100644 index 000000000..52c965921 Binary files /dev/null and b/assets/images/flags/idn.png differ diff --git a/assets/images/flags/ind.png b/assets/images/flags/ind.png new file mode 100644 index 000000000..ef721a2aa Binary files /dev/null and b/assets/images/flags/ind.png differ diff --git a/assets/images/flags/isl.png b/assets/images/flags/isl.png new file mode 100644 index 000000000..ed545e905 Binary files /dev/null and b/assets/images/flags/isl.png differ diff --git a/assets/images/flags/isr.png b/assets/images/flags/isr.png new file mode 100644 index 000000000..9f815dcbd Binary files /dev/null and b/assets/images/flags/isr.png differ diff --git a/assets/images/flags/ita.png b/assets/images/flags/ita.png new file mode 100644 index 000000000..768f5a181 Binary files /dev/null and b/assets/images/flags/ita.png differ diff --git a/assets/images/flags/jpn.png b/assets/images/flags/jpn.png new file mode 100644 index 000000000..a13ef4178 Binary files /dev/null and b/assets/images/flags/jpn.png differ diff --git a/assets/images/flags/kor.png b/assets/images/flags/kor.png new file mode 100644 index 000000000..3ce5e45a6 Binary files /dev/null and b/assets/images/flags/kor.png differ diff --git a/assets/images/flags/mex.png b/assets/images/flags/mex.png new file mode 100644 index 000000000..9531a3ea2 Binary files /dev/null and b/assets/images/flags/mex.png differ diff --git a/assets/images/flags/mys.png b/assets/images/flags/mys.png new file mode 100644 index 000000000..022476291 Binary files /dev/null and b/assets/images/flags/mys.png differ diff --git a/assets/images/flags/nld.png b/assets/images/flags/nld.png new file mode 100644 index 000000000..62dbc2058 Binary files /dev/null and b/assets/images/flags/nld.png differ diff --git a/assets/images/flags/nor.png b/assets/images/flags/nor.png new file mode 100644 index 000000000..bd226c0a6 Binary files /dev/null and b/assets/images/flags/nor.png differ diff --git a/assets/images/flags/nzl.png b/assets/images/flags/nzl.png new file mode 100644 index 000000000..11c6ade9c Binary files /dev/null and b/assets/images/flags/nzl.png differ diff --git a/assets/images/flags/phl.png b/assets/images/flags/phl.png new file mode 100644 index 000000000..b453f3933 Binary files /dev/null and b/assets/images/flags/phl.png differ diff --git a/assets/images/flags/pol.png b/assets/images/flags/pol.png new file mode 100644 index 000000000..30d5a9371 Binary files /dev/null and b/assets/images/flags/pol.png differ diff --git a/assets/images/flags/prt.png b/assets/images/flags/prt.png new file mode 100644 index 000000000..ff5a25fa9 Binary files /dev/null and b/assets/images/flags/prt.png differ diff --git a/assets/images/flags/rou.png b/assets/images/flags/rou.png new file mode 100644 index 000000000..49b36b438 Binary files /dev/null and b/assets/images/flags/rou.png differ diff --git a/assets/images/flags/rus.png b/assets/images/flags/rus.png new file mode 100644 index 000000000..2633dcbd0 Binary files /dev/null and b/assets/images/flags/rus.png differ diff --git a/assets/images/flags/saf.png b/assets/images/flags/saf.png new file mode 100644 index 000000000..3b9cbded8 Binary files /dev/null and b/assets/images/flags/saf.png differ diff --git a/assets/images/flags/sgp.png b/assets/images/flags/sgp.png new file mode 100644 index 000000000..5782ea144 Binary files /dev/null and b/assets/images/flags/sgp.png differ diff --git a/assets/images/flags/swe.png b/assets/images/flags/swe.png new file mode 100644 index 000000000..ef73086f6 Binary files /dev/null and b/assets/images/flags/swe.png differ diff --git a/assets/images/flags/tha.png b/assets/images/flags/tha.png new file mode 100644 index 000000000..1bdb04d00 Binary files /dev/null and b/assets/images/flags/tha.png differ diff --git a/assets/images/flags/ukr.png b/assets/images/flags/ukr.png new file mode 100644 index 000000000..61071e338 Binary files /dev/null and b/assets/images/flags/ukr.png differ diff --git a/assets/images/flags/usa.png b/assets/images/flags/usa.png new file mode 100644 index 000000000..a8c44ce75 Binary files /dev/null and b/assets/images/flags/usa.png differ diff --git a/assets/images/flags/ven.png b/assets/images/flags/ven.png new file mode 100644 index 000000000..fcc25ef2b Binary files /dev/null and b/assets/images/flags/ven.png differ diff --git a/assets/images/search_icon.png b/assets/images/search_icon.png new file mode 100644 index 000000000..cf4ec0772 Binary files /dev/null and b/assets/images/search_icon.png differ diff --git a/lib/di.dart b/lib/di.dart index 763a82834..7391e59ca 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -38,7 +38,6 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart'; import 'package:cake_wallet/src/screens/seed/pre_seed_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/support/support_page.dart'; @@ -507,8 +506,6 @@ Future setup( getIt.registerFactory(() => FaqPage(getIt.get())); - getIt.registerFactory(() => LanguageListPage(getIt.get())); - getIt.registerFactoryParam( (type, _) => WalletRestoreViewModel(getIt.get(), getIt.get(param1: type), _walletInfoSource, diff --git a/lib/entities/fiat_currency.dart b/lib/entities/fiat_currency.dart index c5fa3a602..1e5c61e1e 100644 --- a/lib/entities/fiat_currency.dart +++ b/lib/entities/fiat_currency.dart @@ -1,43 +1,46 @@ import 'package:cw_core/enumerable_item.dart'; class FiatCurrency extends EnumerableItem with Serializable { - const FiatCurrency({String symbol}) : super(title: symbol, raw: symbol); + const FiatCurrency({String symbol, this.countryCode, this.fullName}) : super(title: symbol, raw: symbol); + + final String countryCode; + final String fullName; static List get all => _all.values.toList(); - static const aud = FiatCurrency(symbol: 'AUD'); - static const bgn = FiatCurrency(symbol: 'BGN'); - static const brl = FiatCurrency(symbol: 'BRL'); - static const cad = FiatCurrency(symbol: 'CAD'); - static const chf = FiatCurrency(symbol: 'CHF'); - static const cny = FiatCurrency(symbol: 'CNY'); - static const czk = FiatCurrency(symbol: 'CZK'); - static const eur = FiatCurrency(symbol: 'EUR'); - static const dkk = FiatCurrency(symbol: 'DKK'); - static const gbp = FiatCurrency(symbol: 'GBP'); - static const hkd = FiatCurrency(symbol: 'HKD'); - static const hrk = FiatCurrency(symbol: 'HRK'); - static const huf = FiatCurrency(symbol: 'HUF'); - static const idr = FiatCurrency(symbol: 'IDR'); - static const ils = FiatCurrency(symbol: 'ILS'); - static const inr = FiatCurrency(symbol: 'INR'); - static const isk = FiatCurrency(symbol: 'ISK'); - static const jpy = FiatCurrency(symbol: 'JPY'); - static const krw = FiatCurrency(symbol: 'KRW'); - static const mxn = FiatCurrency(symbol: 'MXN'); - static const myr = FiatCurrency(symbol: 'MYR'); - static const nok = FiatCurrency(symbol: 'NOK'); - static const nzd = FiatCurrency(symbol: 'NZD'); - static const php = FiatCurrency(symbol: 'PHP'); - static const pln = FiatCurrency(symbol: 'PLN'); - static const ron = FiatCurrency(symbol: 'RON'); - static const rub = FiatCurrency(symbol: 'RUB'); - static const sek = FiatCurrency(symbol: 'SEK'); - static const sgd = FiatCurrency(symbol: 'SGD'); - static const thb = FiatCurrency(symbol: 'THB'); - static const usd = FiatCurrency(symbol: 'USD'); - static const zar = FiatCurrency(symbol: 'ZAR'); - static const vef = FiatCurrency(symbol: 'VEF'); + static const aud = FiatCurrency(symbol: 'AUD', countryCode: "aus", fullName: "Australian Dollar"); + static const bgn = FiatCurrency(symbol: 'BGN', countryCode: "bgr", fullName: "Bulgarian Lev"); + static const brl = FiatCurrency(symbol: 'BRL', countryCode: "bra", fullName: "Brazilian Real"); + static const cad = FiatCurrency(symbol: 'CAD', countryCode: "cad", fullName: "Canadian Dollar"); + static const chf = FiatCurrency(symbol: 'CHF', countryCode: "che", fullName: "Swiss Franc"); + static const cny = FiatCurrency(symbol: 'CNY', countryCode: "chn", fullName: "Chinese Yuan"); + static const czk = FiatCurrency(symbol: 'CZK', countryCode: "czk", fullName: "Czech Koruna"); + static const eur = FiatCurrency(symbol: 'EUR', countryCode: "eur", fullName: "Euro"); + static const dkk = FiatCurrency(symbol: 'DKK', countryCode: "dnk", fullName: "Danish Krone"); + static const gbp = FiatCurrency(symbol: 'GBP', countryCode: "gbr", fullName: "Pound sterling"); + static const hkd = FiatCurrency(symbol: 'HKD', countryCode: "hkg", fullName: "Hong Kong Dollar"); + static const hrk = FiatCurrency(symbol: 'HRK', countryCode: "hrv", fullName: "Croatian Kuna"); + static const huf = FiatCurrency(symbol: 'HUF', countryCode: "hun", fullName: "Hungarian Forint"); + static const idr = FiatCurrency(symbol: 'IDR', countryCode: "idn", fullName: "Indonesian Rupiah"); + static const ils = FiatCurrency(symbol: 'ILS', countryCode: "isr", fullName: "Israeli New Shekel"); + static const inr = FiatCurrency(symbol: 'INR', countryCode: "ind", fullName: "Indian Rupee"); + static const isk = FiatCurrency(symbol: 'ISK', countryCode: "isl", fullName: "Icelandic Króna"); + static const jpy = FiatCurrency(symbol: 'JPY', countryCode: "jpn", fullName: "Japanese Yen equals"); + static const krw = FiatCurrency(symbol: 'KRW', countryCode: "kor", fullName: "South Korean won"); + static const mxn = FiatCurrency(symbol: 'MXN', countryCode: "mex", fullName: "Mexican Peso"); + static const myr = FiatCurrency(symbol: 'MYR', countryCode: "mys", fullName: "Malaysian Ringgit"); + static const nok = FiatCurrency(symbol: 'NOK', countryCode: "nor", fullName: "Norwegian Krone"); + static const nzd = FiatCurrency(symbol: 'NZD', countryCode: "nzl", fullName: "New Zealand Dollar"); + static const php = FiatCurrency(symbol: 'PHP', countryCode: "phl", fullName: "Philippine peso"); + static const pln = FiatCurrency(symbol: 'PLN', countryCode: "pol", fullName: "Poland złoty"); + static const ron = FiatCurrency(symbol: 'RON', countryCode: "rou", fullName: "Romanian Leu"); + static const rub = FiatCurrency(symbol: 'RUB', countryCode: "rus", fullName: "Russian Ruble"); + static const sek = FiatCurrency(symbol: 'SEK', countryCode: "swe", fullName: "Swedish Krona"); + static const sgd = FiatCurrency(symbol: 'SGD', countryCode: "sgp", fullName: "Singapore Dollar"); + static const thb = FiatCurrency(symbol: 'THB', countryCode: "tha", fullName: "Thai Baht"); + static const usd = FiatCurrency(symbol: 'USD', countryCode: "usa", fullName: "United States Dollar"); + static const zar = FiatCurrency(symbol: 'ZAR', countryCode: "saf", fullName: "South African Rand"); + static const vef = FiatCurrency(symbol: 'VEF', countryCode: "ven", fullName: "Venezuelan Bolívar"); static final _all = { FiatCurrency.aud.raw: FiatCurrency.aud, diff --git a/lib/entities/language_service.dart b/lib/entities/language_service.dart index fc3349dee..367223e0d 100644 --- a/lib/entities/language_service.dart +++ b/lib/entities/language_service.dart @@ -20,6 +20,25 @@ class LanguageService { 'hr': 'Hrvatski (Croatian)', 'it': 'Italiano (Italian)' }; + + static const Map localeCountryCode = { + 'en': 'usa', + 'de': 'deu', + 'es': 'esp', + 'fr': 'fra', + 'hi': 'ind', + 'ja': 'jpn', + 'ko': 'kor', + 'nl': 'nld', + 'pl': 'pol', + 'pt': 'prt', + 'ru': 'rus', + 'uk': 'ukr', + 'zh': 'chn', + 'hr': 'hrv', + 'it': 'ita' + }; + static final list = {}; static void loadLocaleList() { diff --git a/lib/router.dart b/lib/router.dart index 01443a138..a3c7573ea 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -47,7 +47,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_c 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/wallet_keys/wallet_keys_page.dart'; -import 'package:cake_wallet/src/screens/settings/change_language.dart'; import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; import 'package:cake_wallet/src/screens/settings/settings.dart'; @@ -359,10 +358,6 @@ Route createRoute(RouteSettings settings) { case Routes.faq: return MaterialPageRoute(builder: (_) => getIt.get()); - case Routes.changeLanguage: - return MaterialPageRoute( - builder: (_) => getIt.get()); - case Routes.preSeed: return MaterialPageRoute( builder: (_) => diff --git a/lib/routes.dart b/lib/routes.dart index eea2b7488..1200d558a 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -41,7 +41,6 @@ class Routes { static const unlock = '/auth_not_closable'; static const rescan = '/rescan'; static const faq = '/faq'; - static const changeLanguage = '/change_language'; static const newWalletType = '/new_wallet_type'; static const sendTemplate = '/send_template'; static const exchangeTemplate = '/exchange_template'; diff --git a/lib/src/screens/settings/change_language.dart b/lib/src/screens/settings/change_language.dart deleted file mode 100644 index d4c7c36d8..000000000 --- a/lib/src/screens/settings/change_language.dart +++ /dev/null @@ -1,63 +0,0 @@ -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:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/entities/language_service.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; - -class LanguageListPage extends BasePage { - LanguageListPage(this.settingsStore); - - final SettingsStore settingsStore; - - @override - String get title => S.current.settings_change_language; - - @override - Widget body(BuildContext context) { - 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( - 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()); - }); - } - }, - ); - }); - }, - )); - } -} diff --git a/lib/src/screens/settings/settings.dart b/lib/src/screens/settings/settings.dart index feda1cf61..168b8d297 100644 --- a/lib/src/screens/settings/settings.dart +++ b/lib/src/screens/settings/settings.dart @@ -1,4 +1,6 @@ +import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart'; +import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; import 'package:cake_wallet/view_model/settings/version_list_item.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; @@ -46,6 +48,10 @@ class SettingsPage extends BasePage { selectedItem: item.selectedItem(), items: item.items, onItemSelected: (dynamic value) => item.onItemSelected(value), + images: item.images, + searchHintText: item.searchHintText, + isGridView: item.isGridView, + matchingCriteria: (dynamic value, String searchText) => item.matchingCriteria(value, searchText), ); }); } @@ -80,6 +86,10 @@ class SettingsPage extends BasePage { }); } + if (item is ChoicesListItem) { + return SettingsChoicesCell(item); + } + return Container(); }); } diff --git a/lib/src/screens/settings/widgets/language_row.dart b/lib/src/screens/settings/widgets/language_row.dart deleted file mode 100644 index 0f807a843..000000000 --- a/lib/src/screens/settings/widgets/language_row.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:cake_wallet/palette.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; - -class LanguageRow extends StandardListRow { - LanguageRow({@required String title, @required this.isSelected, @required Function(BuildContext context) handler}) : - super(title: title, isSelected: isSelected, onTap: handler); - - @override - final bool isSelected; - - @override - Widget buildCenter(BuildContext context, {@required bool hasLeftOffset}) { - return Expanded( - child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [ - if (hasLeftOffset) SizedBox(width: 10), - Text(title, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: titleColor(context))) - ])); - } - - @override - Widget buildTrailing(BuildContext context) => - isSelected - ? Icon(Icons.done, color: Palette.blueCraiola) - : Offstage(); -} \ No newline at end of file diff --git a/lib/src/screens/settings/widgets/settings_choices_cell.dart b/lib/src/screens/settings/widgets/settings_choices_cell.dart new file mode 100644 index 000000000..abbd33231 --- /dev/null +++ b/lib/src/screens/settings/widgets/settings_choices_cell.dart @@ -0,0 +1,71 @@ +import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; +import 'package:flutter/material.dart'; + +class SettingsChoicesCell extends StatelessWidget { + const SettingsChoicesCell(this.choicesListItem, {Key key}) : super(key: key); + + final ChoicesListItem choicesListItem; + + @override + Widget build(BuildContext context) { + return Container( + color: Theme.of(context).backgroundColor, + padding: EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + choicesListItem.title, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + ], + ), + const SizedBox(height: 24), + Center( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + color: Theme.of(context).accentTextTheme.display2.color, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: choicesListItem.items.map((dynamic e) { + final isSelected = choicesListItem.selectedItem == e; + return GestureDetector( + onTap: () { + choicesListItem.onItemSelected?.call(e); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 32, vertical: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30), + color: isSelected ? Theme.of(context).accentTextTheme.body2.color : null, + ), + child: Text( + choicesListItem.displayItem?.call(e) ?? e.toString(), + style: TextStyle( + color: isSelected ? Colors.white : Theme.of(context).primaryTextTheme.caption.color, + fontWeight: isSelected ? FontWeight.w700 : FontWeight.normal, + ), + ), + ), + ); + }).toList(), + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/screens/settings/widgets/settings_picker_cell.dart b/lib/src/screens/settings/widgets/settings_picker_cell.dart index 691b73835..6116a6ea5 100644 --- a/lib/src/screens/settings/widgets/settings_picker_cell.dart +++ b/lib/src/screens/settings/widgets/settings_picker_cell.dart @@ -2,7 +2,6 @@ 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'; -import 'package:cake_wallet/generated/i18n.dart'; class SettingsPickerCell extends StandardListRow { SettingsPickerCell( @@ -10,29 +9,43 @@ class SettingsPickerCell extends StandardListRow { @required this.displayItem, this.selectedItem, this.items, + this.images, + this.searchHintText, + this.isGridView = false, + this.matchingCriteria, this.onItemSelected}) : super( - title: title, - isSelected: false, - onTap: (BuildContext context) async { - final selectedAtIndex = items.indexOf(selectedItem); + title: title, + isSelected: false, + onTap: (BuildContext context) async { + final selectedAtIndex = items.indexOf(selectedItem); - await showPopUp( - context: context, - builder: (_) => Picker( - items: items, - displayItem: displayItem, - selectedAtIndex: selectedAtIndex, - title: S.current.please_select, - mainAxisAlignment: MainAxisAlignment.center, - onItemSelected: (ItemType item) => - onItemSelected?.call(item))); - }); + await showPopUp( + context: context, + builder: (_) => Picker( + items: items, + displayItem: displayItem, + selectedAtIndex: selectedAtIndex, + mainAxisAlignment: MainAxisAlignment.start, + onItemSelected: (ItemType item) => onItemSelected?.call(item), + images: images, + isSeparated: false, + hintText: searchHintText, + isGridView: isGridView, + matchingCriteria: matchingCriteria, + ), + ); + }, + ); final ItemType selectedItem; final List items; final void Function(ItemType item) onItemSelected; final String Function(ItemType item) displayItem; + final List images; + final String searchHintText; + final bool isGridView; + final bool Function(ItemType, String) matchingCriteria; @override Widget buildTrailing(BuildContext context) { @@ -40,9 +53,7 @@ class SettingsPickerCell extends StandardListRow { displayItem?.call(selectedItem) ?? selectedItem.toString(), textAlign: TextAlign.right, style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryTextTheme.overline.color), + fontSize: 14.0, fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.overline.color), ); } } diff --git a/lib/src/widgets/alert_background.dart b/lib/src/widgets/alert_background.dart index db73e7c0d..e8368e27c 100644 --- a/lib/src/widgets/alert_background.dart +++ b/lib/src/widgets/alert_background.dart @@ -10,15 +10,19 @@ class AlertBackground extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - height: double.infinity, - width: double.infinity, - color: Colors.transparent, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), - child: Container( - decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)), - child: child, + return Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: Colors.transparent, + body: Container( + height: double.infinity, + width: double.infinity, + color: Colors.transparent, + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), + child: Container( + decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)), + child: child, + ), ), ), ); diff --git a/lib/src/widgets/picker.dart b/lib/src/widgets/picker.dart index 3748bf28f..b5cad676b 100644 --- a/lib/src/widgets/picker.dart +++ b/lib/src/widgets/picker.dart @@ -2,7 +2,6 @@ import 'dart:ui'; 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/cake_scrollbar.dart'; import 'package:cake_wallet/src/widgets/alert_close_button.dart'; import 'package:cake_wallet/palette.dart'; @@ -10,13 +9,19 @@ class Picker extends StatefulWidget { Picker({ @required this.selectedAtIndex, @required this.items, - @required this.title, @required this.onItemSelected, + this.title, this.displayItem, this.images, this.description, this.mainAxisAlignment = MainAxisAlignment.start, - }); + this.isGridView = false, + this.isSeparated = true, + this.hintText, + this.matchingCriteria, + }) : assert(hintText == null || + matchingCriteria != + null); // make sure that if the search field is enabled then there is a searching criteria provided final int selectedAtIndex; final List items; @@ -26,6 +31,10 @@ class Picker extends StatefulWidget { final Function(Item) onItemSelected; final MainAxisAlignment mainAxisAlignment; final String Function(Item) displayItem; + final bool isGridView; + final bool isSeparated; + final String hintText; + final bool Function(Item, String) matchingCriteria; @override PickerState createState() => PickerState(items, images, onItemSelected); @@ -35,8 +44,10 @@ class PickerState extends State { PickerState(this.items, this.images, this.onItemSelected); final Function(Item) onItemSelected; - final List items; - final List images; + List items; + List images; + + final TextEditingController searchController = TextEditingController(); final closeButton = Image.asset( 'assets/images/close.png', @@ -44,161 +55,248 @@ class PickerState extends State { ); ScrollController controller = ScrollController(); - final double backgroundHeight = 193; - final double thumbHeight = 72; - double fromTop = 0; + @override + void initState() { + super.initState(); + + searchController.addListener(() { + items = []; + images = []; + for (int i=0;i 3 : false; - return AlertBackground( - child: Stack( - alignment: Alignment.center, - children: [ - Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.only(left: 24, right: 24), - child: Text( - widget.title, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - fontFamily: 'Lato', - fontWeight: FontWeight.bold, - decoration: TextDecoration.none, - color: Colors.white), - ), - ), - Padding( - padding: EdgeInsets.only(left: 24, right: 24, top: 24), - child: GestureDetector( - onTap: () => null, - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(14)), - child: Container( - height: 233, + child: Stack( + alignment: Alignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.title?.isNotEmpty ?? false) + Container( + padding: EdgeInsets.symmetric(horizontal: 24), + child: Text( + widget.title, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontFamily: 'Lato', + fontWeight: FontWeight.bold, + decoration: TextDecoration.none, + color: Colors.white, + ), + ), + ), + Padding( + padding: EdgeInsets.only(left: 24, right: 24, top: 24), + child: GestureDetector( + onTap: () => null, + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(30)), + child: Container( color: Theme.of(context).accentTextTheme.title.color, - child: Stack( - alignment: Alignment.center, - children: [ - ListView.separated( - padding: EdgeInsets.all(0), - controller: controller, - separatorBuilder: (context, index) => Divider( - color: Theme.of(context) - .accentTextTheme - .title - .backgroundColor, - height: 1, - ), - itemCount: items == null ? 0 : items.length, - itemBuilder: (context, index) { - final item = items[index]; - final image = - images != null ? images[index] : null; - final isItemSelected = - index == widget.selectedAtIndex; - - final color = isItemSelected - ? Theme.of(context).textTheme.body2.color - : Theme.of(context) - .accentTextTheme - .title - .color; - final textColor = isItemSelected - ? Palette.blueCraiola - : Theme.of(context) - .primaryTextTheme - .title - .color; - - return GestureDetector( - onTap: () { - if (onItemSelected == null) { - return; - } - Navigator.of(context).pop(); - onItemSelected(item); - }, - child: Container( - height: 77, - padding: EdgeInsets.only(left: 24, right: 24), - color: color, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: widget.mainAxisAlignment, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - image ?? Offstage(), - Padding( - padding: EdgeInsets.only( - left: image != null ? 12 : 0), - child: Text( - widget.displayItem?.call(item) ?? - item.toString(), - style: TextStyle( - fontSize: 18, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: textColor, - decoration: TextDecoration.none, - ), - ), - ) - ], + child: ConstrainedBox( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.65, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.hintText != null) + Padding( + padding: const EdgeInsets.all(16), + child: TextFormField( + controller: searchController, + style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color), + decoration: InputDecoration( + hintText: widget.hintText, + prefixIcon: Image.asset("assets/images/search_icon.png"), + filled: true, + fillColor: Theme.of(context).accentTextTheme.display2.color, + alignLabelWithHint: false, + contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(14), + borderSide: const BorderSide( + color: Colors.transparent, + )), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(14), + borderSide: const BorderSide( + color: Colors.transparent, + )), ), ), - ); - }, - ), - ((widget.description != null) && - (widget.description.isNotEmpty)) - ? Positioned( - bottom: 24, - left: 24, - right: 24, - child: Text( - widget.description, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, - fontFamily: 'Lato', - decoration: TextDecoration.none, - color: Theme.of(context) - .primaryTextTheme - .title - .color), - )) - : Offstage(), - isShowScrollThumb - ? CakeScrollbar( - backgroundHeight: backgroundHeight, - thumbHeight: thumbHeight, - fromTop: fromTop) - : Offstage(), - ], - )), + ), + Divider( + color: Theme.of(context).accentTextTheme.title.backgroundColor, + height: 1, + ), + if (widget.selectedAtIndex != -1) buildSelectedItem(), + Flexible( + child: Stack( + alignment: Alignment.center, + children: [ + (items?.length ?? 0) > 3 ? Scrollbar( + controller: controller, + child: itemsList(), + ) : itemsList(), + (widget.description?.isNotEmpty ?? false) + ? Positioned( + bottom: 24, + left: 24, + right: 24, + child: Text( + widget.description, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + fontFamily: 'Lato', + decoration: TextDecoration.none, + color: Theme.of(context).primaryTextTheme.title.color, + ), + ), + ) + : Offstage(), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ) + ], + ), + AlertCloseButton(image: closeButton) + ], + ), + ); + } + + Widget itemsList() { + return Container( + color: Theme.of(context).accentTextTheme.headline6.backgroundColor, + child: widget.isGridView + ? GridView.builder( + padding: EdgeInsets.zero, + controller: controller, + itemCount: items == null || items.isEmpty ? 0 : items.length, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 2, + childAspectRatio: 3, + ), + itemBuilder: (context, index) => buildItem(index), + ) + : ListView.separated( + padding: EdgeInsets.zero, + controller: controller, + shrinkWrap: true, + separatorBuilder: (context, index) => widget.isSeparated + ? Divider( + color: Theme.of(context).accentTextTheme.title.backgroundColor, + height: 1, + ) + : const SizedBox(), + itemCount: items == null || items.isEmpty ? 0 : items.length, + itemBuilder: (context, index) => buildItem(index), + ), + ); + } + + Widget buildItem(int index) { + /// don't show selected item in the list view + if (widget.items[widget.selectedAtIndex] == items[index] && !widget.isGridView) { + return const SizedBox(); + } + + final item = items[index]; + final image = images != null ? images[index] : null; + + return GestureDetector( + onTap: () { + if (onItemSelected == null) { + return; + } + Navigator.of(context).pop(); + onItemSelected(item); + }, + child: Container( + height: 55, + color: Theme.of(context).accentTextTheme.headline6.color, + padding: EdgeInsets.only(left: 24, right: 24), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: widget.mainAxisAlignment, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + image ?? Offstage(), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: image != null ? 12 : 0), + child: Text( + widget.displayItem?.call(item) ?? item.toString(), + style: TextStyle( + fontSize: 14, + fontFamily: 'Lato', + fontWeight: FontWeight.w600, + color: Theme.of(context).primaryTextTheme.title.color, + decoration: TextDecoration.none, + ), ), ), - ) + ), ], ), - AlertCloseButton(image: closeButton) - ], - )); + ), + ); + } + + Widget buildSelectedItem() { + final item = widget.items[widget.selectedAtIndex]; + final image = images != null ? widget.images[widget.selectedAtIndex] : null; + + return Container( + height: 55, + color: Theme.of(context).accentTextTheme.headline6.color, + padding: EdgeInsets.only(left: 24, right: 24), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: widget.mainAxisAlignment, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + image ?? Offstage(), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: image != null ? 12 : 0), + child: Text( + widget.displayItem?.call(item) ?? item.toString(), + style: TextStyle( + fontSize: 16, + fontFamily: 'Lato', + fontWeight: FontWeight.w700, + color: Theme.of(context).primaryTextTheme.title.color, + decoration: TextDecoration.none, + ), + ), + ), + ), + Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color), + ], + ), + ); } } diff --git a/lib/src/widgets/standard_list.dart b/lib/src/widgets/standard_list.dart index c12f1b347..572f03791 100644 --- a/lib/src/widgets/standard_list.dart +++ b/lib/src/widgets/standard_list.dart @@ -37,11 +37,15 @@ class StandardListRow extends StatelessWidget { return Expanded( child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [ if (hasLeftOffset) SizedBox(width: 10), - Text(title, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.normal, - color: titleColor(context))) + Expanded( + child: Text(title, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: titleColor(context), + ), + ), + ) ])); } diff --git a/lib/src/widgets/standart_switch.dart b/lib/src/widgets/standart_switch.dart index 8760279a1..06d13d6aa 100644 --- a/lib/src/widgets/standart_switch.dart +++ b/lib/src/widgets/standart_switch.dart @@ -24,7 +24,7 @@ class StandartSwitchState extends State { height: 28, decoration: BoxDecoration( color: widget.value - ? Colors.green + ? Theme.of(context).accentTextTheme.body2.color : Theme.of(context).accentTextTheme.display4.color, borderRadius: BorderRadius.all(Radius.circular(14.0))), child: Container( diff --git a/lib/themes/bright_theme.dart b/lib/themes/bright_theme.dart index 5adb5d2f1..67f4e20bf 100644 --- a/lib/themes/bright_theme.dart +++ b/lib/themes/bright_theme.dart @@ -78,6 +78,14 @@ class BrightTheme extends ThemeBase { decorationColor: Colors.white, // menu background ) ), + scrollbarTheme: ScrollbarThemeData( + thumbColor: MaterialStateProperty.all(Palette.moderatePurpleBlue), + trackColor: MaterialStateProperty.all(Palette.periwinkleCraiola), + radius: Radius.circular(3), + thickness: MaterialStateProperty.all(6), + isAlwaysShown: true, + crossAxisMargin: 6, + ), primaryTextTheme: TextTheme( title: TextStyle( color: Palette.darkBlueCraiola, // title color diff --git a/lib/themes/dark_theme.dart b/lib/themes/dark_theme.dart index 646afc964..3a1361913 100644 --- a/lib/themes/dark_theme.dart +++ b/lib/themes/dark_theme.dart @@ -77,6 +77,14 @@ class DarkTheme extends ThemeBase { decorationColor: PaletteDark.deepPurpleBlue, // menu background ) ), + scrollbarTheme: ScrollbarThemeData( + thumbColor: MaterialStateProperty.all(PaletteDark.wildBlueGrey), + trackColor: MaterialStateProperty.all(PaletteDark.violetBlue), + radius: Radius.circular(3), + thickness: MaterialStateProperty.all(6), + isAlwaysShown: true, + crossAxisMargin: 6, + ), primaryTextTheme: TextTheme( title: TextStyle( color: Colors.white, // title color diff --git a/lib/themes/light_theme.dart b/lib/themes/light_theme.dart index 763872efe..a00b07f91 100644 --- a/lib/themes/light_theme.dart +++ b/lib/themes/light_theme.dart @@ -78,6 +78,14 @@ class LightTheme extends ThemeBase { decorationColor: Colors.white, // menu background ) ), + scrollbarTheme: ScrollbarThemeData( + thumbColor: MaterialStateProperty.all(Palette.moderatePurpleBlue), + trackColor: MaterialStateProperty.all(Palette.periwinkleCraiola), + radius: Radius.circular(3), + thickness: MaterialStateProperty.all(6), + isAlwaysShown: true, + crossAxisMargin: 6, + ), primaryTextTheme: TextTheme( title: TextStyle( color: Palette.darkBlueCraiola, // title color diff --git a/lib/themes/theme_list.dart b/lib/themes/theme_list.dart index b4cea1391..06bdde3f7 100644 --- a/lib/themes/theme_list.dart +++ b/lib/themes/theme_list.dart @@ -4,7 +4,7 @@ import 'package:cake_wallet/themes/light_theme.dart'; import 'package:cake_wallet/themes/theme_base.dart'; class ThemeList { - static final all = [lightTheme, brightTheme, darkTheme]; + static final all = [brightTheme, lightTheme, darkTheme]; static final lightTheme = LightTheme(raw: 0); static final brightTheme = BrightTheme(raw: 1); diff --git a/lib/view_model/settings/choices_list_item.dart b/lib/view_model/settings/choices_list_item.dart new file mode 100644 index 000000000..040968597 --- /dev/null +++ b/lib/view_model/settings/choices_list_item.dart @@ -0,0 +1,25 @@ +import 'package:flutter/foundation.dart'; +import 'package:cake_wallet/view_model/settings/settings_list_item.dart'; +import 'package:flutter/material.dart'; + +class ChoicesListItem extends SettingsListItem { + ChoicesListItem( + {@required String title, + @required this.selectedItem, + @required this.items, + this.displayItem, + void Function(ItemType item) onItemSelected}) + : _onItemSelected = onItemSelected, + super(title); + + final ItemType selectedItem; + final List items; + final String Function(ItemType item) displayItem; + final void Function(ItemType item) _onItemSelected; + + void onItemSelected(dynamic item) { + if (item is ItemType) { + _onItemSelected?.call(item); + } + } +} diff --git a/lib/view_model/settings/picker_list_item.dart b/lib/view_model/settings/picker_list_item.dart index 0785232bb..ae4bfd128 100644 --- a/lib/view_model/settings/picker_list_item.dart +++ b/lib/view_model/settings/picker_list_item.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:cake_wallet/view_model/settings/settings_list_item.dart'; +import 'package:flutter/material.dart'; class PickerListItem extends SettingsListItem { PickerListItem( @@ -7,18 +8,34 @@ class PickerListItem extends SettingsListItem { @required this.selectedItem, @required this.items, this.displayItem, - void Function(ItemType item) onItemSelected}) + this.images, + this.searchHintText, + this.isGridView = false, + void Function(ItemType item) onItemSelected, + bool Function(ItemType item, String searchText) matchingCriteria}) : _onItemSelected = onItemSelected, + _matchingCriteria = matchingCriteria, super(title); final ItemType Function() selectedItem; final List items; final String Function(ItemType item) displayItem; final void Function(ItemType item) _onItemSelected; + final List images; + final String searchHintText; + final bool isGridView; + final bool Function(ItemType, String) _matchingCriteria; void onItemSelected(dynamic item) { if (item is ItemType) { _onItemSelected?.call(item); } } + + bool matchingCriteria(dynamic item, String searchText) { + if (item is ItemType) { + return _matchingCriteria?.call(item, searchText); + } + return true; + } } diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart index 555b0d2a0..67cf35635 100644 --- a/lib/view_model/settings/settings_view_model.dart +++ b/lib/view_model/settings/settings_view_model.dart @@ -1,6 +1,7 @@ +import 'package:cake_wallet/di.dart'; +import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cake_wallet/view_model/settings/link_list_item.dart'; +import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; import 'package:flutter/cupertino.dart'; import 'package:mobx/mobx.dart'; import 'package:package_info/package_info.dart'; @@ -75,7 +76,7 @@ abstract class SettingsViewModelBase with Store { //var connectYatUrl = YatLink.baseUrl + YatLink.signInSuffix; //final connectYatUrlParameters = // _yatStore.defineQueryParameters(); - + //if (connectYatUrlParameters.isNotEmpty) { // connectYatUrl += YatLink.queryParameter + connectYatUrlParameters; //} @@ -83,7 +84,7 @@ abstract class SettingsViewModelBase with Store { //var manageYatUrl = YatLink.baseUrl + YatLink.managePath; //final manageYatUrlParameters = // _yatStore.defineQueryParameters(); - + //if (manageYatUrlParameters.isNotEmpty) { // manageYatUrl += YatLink.queryParameter + manageYatUrlParameters; //} @@ -91,27 +92,41 @@ abstract class SettingsViewModelBase with Store { //var createNewYatUrl = YatLink.startFlowUrl; //final createNewYatUrlParameters = // _yatStore.defineQueryParameters(); - + //if (createNewYatUrlParameters.isNotEmpty) { // createNewYatUrl += '?sub1=' + createNewYatUrlParameters; //} - + sections = [ [ - PickerListItem( - title: S.current.settings_display_balance_as, - items: BalanceDisplayMode.all, - selectedItem: () => balanceDisplayMode, - onItemSelected: (BalanceDisplayMode mode) => - _settingsStore.balanceDisplayMode = mode), + SwitcherListItem( + title: S.current.settings_display_balance, + value: () => balanceDisplayMode == BalanceDisplayMode.displayableBalance, + onValueChange: (_, bool value) { + if (value) { + _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance; + } else { + _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance; + } + }, + ), if (!isHaven) PickerListItem( title: S.current.settings_currency, + searchHintText: S.current.search_currency, items: FiatCurrency.all, selectedItem: () => fiatCurrency, onItemSelected: (FiatCurrency currency) => - setFiatCurrency(currency)), + setFiatCurrency(currency), + images: FiatCurrency.all.map( + (e) => Image.asset("assets/images/flags/${e.countryCode}.png")) + .toList(), + isGridView: true, + matchingCriteria: (FiatCurrency currency, String searchText) { + return currency.title.toLowerCase().contains(searchText) || currency.fullName.toLowerCase().contains(searchText); + }, + ), PickerListItem( title: S.current.settings_fee_priority, items: priorityForWalletType(wallet.type), @@ -150,10 +165,23 @@ abstract class SettingsViewModelBase with Store { } }); }), - RegularListItem( - title: S.current.settings_change_language, - handler: (BuildContext context) => - Navigator.of(context).pushNamed(Routes.changeLanguage), + PickerListItem( + title: S.current.settings_change_language, + searchHintText: S.current.search_language, + items: LanguageService.list.keys.toList(), + displayItem: (dynamic code) { + return LanguageService.list[code]; + }, + selectedItem: () => getIt.get().languageCode, + onItemSelected: (String code) { + getIt.get().languageCode = code; + }, + images: LanguageService.list.keys.map( + (e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png")) + .toList(), + matchingCriteria: (String code, String searchText) { + return LanguageService.list[code].toLowerCase().contains(searchText); + }, ), SwitcherListItem( title: S.current.settings_allow_biometrical_authentication, @@ -180,12 +208,12 @@ abstract class SettingsViewModelBase with Store { setAllowBiometricalAuthentication(value); } }), - PickerListItem( - title: S.current.color_theme, - items: ThemeList.all, - selectedItem: () => theme, - onItemSelected: (ThemeBase theme) => - _settingsStore.currentTheme = theme) + ChoicesListItem( + title: S.current.color_theme, + items: ThemeList.all, + selectedItem: theme, + onItemSelected: (ThemeBase theme) => _settingsStore.currentTheme = theme, + ), ], //[ //if (_yatStore.emoji.isNotEmpty) ...[ diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 8d1c098ae..83d461546 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -76,6 +76,7 @@ flutter: assets: - assets/images/ + - assets/images/flags/ - assets/node_list.yml - assets/haven_node_list.yml - assets/bitcoin_electrum_server_list.yml diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index fa34eeced..304e91a1b 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Knoten", "settings_current_node" : "Aktueller Knoten", "settings_wallets" : "Wallets", - "settings_display_balance_as" : "Kontostand anzeigen in", + "settings_display_balance" : "Kontostand anzeigen", "settings_currency" : "Währung", "settings_fee_priority" : "Gebührenpriorität", "settings_save_recipient_address" : "Empfängeradresse speichern", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats leben auch außerhalb von Cake Wallet. Jede Wallet-Adresse auf der Welt kann durch ein Yat ersetzt werden!", "learn_more" : "Erfahren Sie mehr", "search": "Suche", + "search_language": "Sprache suchen", + "search_currency": "Währung suchen", "new_template" : "neue Vorlage", "electrum_address_disclaimer": "Wir generieren jedes Mal neue Adressen, wenn Sie eine verwenden, aber vorherige Adressen funktionieren weiterhin" } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 25c449929..2f9b0cf78 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Nodes", "settings_current_node" : "Current node", "settings_wallets" : "Wallets", - "settings_display_balance_as" : "Display balance as", + "settings_display_balance" : "Display balance", "settings_currency" : "Currency", "settings_fee_priority" : "Fee priority", "settings_save_recipient_address" : "Save recipient address", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats live outside of Cake Wallet, too. Any wallet address on earth can be replaced with a Yat!", "learn_more" : "Learn More", "search": "Search", + "search_language": "Search language", + "search_currency": "Search currency", "new_template" : "New Template", "electrum_address_disclaimer": "We generate new addresses each time you use one, but previous addresses continue to work" } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index e520ff727..76284f46d 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Nodos", "settings_current_node" : "Nodo actual", "settings_wallets" : "Carteras", - "settings_display_balance_as" : "Mostrar saldo como", + "settings_display_balance" : "Mostrar saldo", "settings_currency" : "Moneda", "settings_fee_priority" : "Prioridad de tasa", "settings_save_recipient_address" : "Guardar dirección del destinatario", @@ -530,6 +530,8 @@ "third_intro_content" : "Los Yats también viven fuera de Cake Wallet. Cualquier dirección de billetera en la tierra se puede reemplazar con un Yat!", "learn_more" : "Aprende más", "search": "Búsqueda", + "search_language": "Idioma de búsqueda", + "search_currency": "Moneda de búsqueda", "new_template" : "Nueva plantilla", "electrum_address_disclaimer": "Generamos nuevas direcciones cada vez que usa una, pero las direcciones anteriores siguen funcionando" } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index af41bb225..32abb9ac7 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -226,7 +226,7 @@ "settings_nodes" : "Nœuds", "settings_current_node" : "Nœud actuel", "settings_wallets" : "Portefeuilles", - "settings_display_balance_as" : "Afficher le solde en", + "settings_display_balance" : "Afficher le solde", "settings_currency" : "Devise", "settings_fee_priority" : "Priorité des frais", "settings_save_recipient_address" : "Sauvegarder l'adresse du bénéficiaire", @@ -527,7 +527,9 @@ "third_intro_title" : "Yat joue bien avec les autres", "third_intro_content" : "Les Yats existent aussi en dehors de Cake Wallet. Toute adresse sur terre peut être remplacée par un Yat !", "learn_more" : "En savoir plus", - + "search": "Chercher", + "search_language": "Langue de recherche", + "search_currency": "Devise de recherche", "new_template" : "Nouveau Modèle", "electrum_address_disclaimer": "Nous générons de nouvelles adresses à chaque fois que vous en utilisez une, mais les adresses précédentes continuent à fonctionner" } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 9c61e180f..c8b738277 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -228,7 +228,7 @@ "settings_nodes" : "नोड्स", "settings_current_node" : "वर्तमान नोड", "settings_wallets" : "पर्स", - "settings_display_balance_as" : "के रूप में संतुलन प्रदर्शित करें", + "settings_display_balance" : "प्रदर्शन संतुलन", "settings_currency" : "मुद्रा", "settings_fee_priority" : "शुल्क प्राथमिकता", "settings_save_recipient_address" : "प्राप्तकर्ता का पता सहेजें", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats Cake Wallet के बाहर भी रहता है। धरती पर किसी भी वॉलेट पते को Yat से बदला जा सकता है!", "learn_more" : "और अधिक जानें", "search": "खोज", + "search_language": "भाषा खोजें", + "search_currency": "मुद्रा खोजें", "new_template" : "नया टेम्पलेट", "electrum_address_disclaimer": "हर बार जब आप एक का उपयोग करते हैं तो हम नए पते उत्पन्न करते हैं, लेकिन पिछले पते काम करना जारी रखते हैं" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 16142ccd3..48a0ef4e2 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Nodovi", "settings_current_node" : "Trenutni node", "settings_wallets" : "Novčanik", - "settings_display_balance_as" : "Prikaži stanje računa kao", + "settings_display_balance" : "Prikaži stanje računa", "settings_currency" : "Valuta", "settings_fee_priority" : "Prioritet naknade", "settings_save_recipient_address" : "Spremi primateljevu adresu", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats žive i izvan Cake Wallet -a. Bilo koja adresa novčanika na svijetu može se zamijeniti Yat!", "learn_more" : "Saznajte više", "search": "Traži", + "search_language": "Jezik pretraživanja", + "search_currency": "Traži valutu", "new_template" : "novi predložak", "electrum_address_disclaimer": "Minden egyes alkalommal új címeket generálunk, de a korábbi címek továbbra is működnek" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 10c22001a..cb21d43dd 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Nodi", "settings_current_node" : "Nodo attuale", "settings_wallets" : "Portafogli", - "settings_display_balance_as" : "Mostra saldo come", + "settings_display_balance" : "Mostra saldo", "settings_currency" : "Moneta", "settings_fee_priority" : "Priorità commissione", "settings_save_recipient_address" : "Salva indirizzo di destinazione", @@ -530,6 +530,8 @@ "third_intro_content" : "Anche Yats vive fuori da Cake Wallet. Qualsiasi indirizzo di portafoglio sulla terra può essere sostituito con un Yat!", "learn_more" : "Impara di più", "search": "Ricerca", + "search_language": "Cerca lingua", + "search_currency": "Cerca valuta", "new_template" : "Nuovo modello", "electrum_address_disclaimer": "Generiamo nuovi indirizzi ogni volta che ne utilizzi uno, ma gli indirizzi precedenti continuano a funzionare" } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 3e2c3e886..6f162b8dc 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -228,7 +228,7 @@ "settings_nodes" : "ノード", "settings_current_node" : "現在のノード", "settings_wallets" : "財布", - "settings_display_balance_as" : "残高を表示", + "settings_display_balance" : "ディスプレイバランス", "settings_currency" : "通貨", "settings_fee_priority" : "料金優先", "settings_save_recipient_address" : "受信者のアドレスを保存", @@ -530,6 +530,8 @@ "third_intro_content" : "YatsはCakeWalletの外にも住んでいます。 地球上のどのウォレットアドレスもYatに置き換えることができます!", "learn_more" : "もっと詳しく知る", "search": "検索", + "search_language": "検索言語", + "search_currency": "検索通貨", "new_template" : "新しいテンプレート", "electrum_address_disclaimer": "使用するたびに新しいアドレスが生成されますが、以前のアドレスは引き続き機能します" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index ad3e3ac5b..124edbd7c 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -228,7 +228,7 @@ "settings_nodes" : "노드", "settings_current_node" : "현재 노드", "settings_wallets" : "지갑", - "settings_display_balance_as" : "잔액 표시", + "settings_display_balance" : "디스플레이 잔액", "settings_currency" : "통화", "settings_fee_priority" : "수수료 우선", "settings_save_recipient_address" : "수신자 주소 저장", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats는 Cake Wallet 밖에서도 살고 있습니다. 지구상의 모든 지갑 주소는 Yat!", "learn_more" : "더 알아보기", "search": "찾다", + "search_language": "검색 언어", + "search_currency": "통화 검색", "new_template" : "새 템플릿", "electrum_address_disclaimer": "사용할 때마다 새 주소가 생성되지만 이전 주소는 계속 작동합니다." } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 834da2c02..9ac238793 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -228,7 +228,7 @@ "settings_nodes" : "knooppunten", "settings_current_node" : "Huidige knooppunt", "settings_wallets" : "Portemonnee", - "settings_display_balance_as" : "Toon saldo als", + "settings_display_balance" : "Saldo weergeven", "settings_currency" : "Valuta", "settings_fee_priority" : "Tariefprioriteit", "settings_save_recipient_address" : "Adres ontvanger opslaan", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats wonen ook buiten Cake Wallet. Elk portemonnee-adres op aarde kan worden vervangen door een Yat!", "learn_more" : "Kom meer te weten", "search": "Zoekopdracht", + "search_language": "Zoektaal", + "search_currency": "Zoek valuta", "new_template" : "Nieuwe sjabloon", "electrum_address_disclaimer": "We generate new addresses each time you use one, but previous addresses continue to work" } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 6bcccb1e1..d6db3d206 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Węzły", "settings_current_node" : "Bieżący węzeł", "settings_wallets" : "Portfele", - "settings_display_balance_as" : "Wyświetl saldo jako", + "settings_display_balance" : "Wyświetl saldo", "settings_currency" : "Waluta", "settings_fee_priority" : "Priorytet opłaty", "settings_save_recipient_address" : "Zapisz adres odbiorcy", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats mieszkają również poza Cake Wallet. Każdy adres portfela na ziemi można zastąpić Yat!", "learn_more" : "Ucz się więcej", "search": "Szukaj", + "search_language": "Wyszukaj język", + "search_currency": "Wyszukaj walutę", "new_template" : "Nowy szablon", "electrum_address_disclaimer": "Za każdym razem, gdy korzystasz z jednego z nich, generujemy nowe adresy, ale poprzednie adresy nadal działają" } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8737de6c0..f44ffaf6f 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Nós", "settings_current_node" : "Nó atual", "settings_wallets" : "Carteiras", - "settings_display_balance_as" : "Saldo a exibir", + "settings_display_balance" : "Exibir saldo", "settings_currency" : "Moeda", "settings_fee_priority" : "Prioridade da taxa", "settings_save_recipient_address" : "Salvar endereço do destinatário", @@ -530,6 +530,8 @@ "third_intro_content" : "Yats também mora fora da Cake Wallet. Qualquer endereço de carteira na Terra pode ser substituído por um Yat!", "learn_more" : "Saber mais", "search": "Procurar", + "search_language": "Idioma de pesquisa", + "search_currency": "Pesquisar moeda", "new_template" : "Novo modelo", "electrum_address_disclaimer": "Geramos novos endereços cada vez que você usa um, mas os endereços anteriores continuam funcionando" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 7df0463fb..bbb3482b2 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -228,7 +228,7 @@ "settings_nodes" : "Ноды", "settings_current_node" : "Текущая нода", "settings_wallets" : "Кошельки", - "settings_display_balance_as" : "Отображать баланс как", + "settings_display_balance" : "Отображать баланс", "settings_currency" : "Валюта", "settings_fee_priority" : "Приоритет транзакции", "settings_save_recipient_address" : "Сохранять адрес получателя", @@ -530,6 +530,8 @@ "third_intro_content" : "Yat находятся за пределами Cake Wallet. Любой адрес кошелька на земле можно заменить на Yat!", "learn_more" : "Узнать больше", "search": "Поиск", + "search_language": "Язык поиска", + "search_currency": "Валюта поиска", "new_template" : "Новый шаблон", "electrum_address_disclaimer": "Мы генерируем новые адреса каждый раз, когда вы их используете, но предыдущие адреса продолжают работать." } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 2ef8cbb6b..ec13da291 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -227,7 +227,7 @@ "settings_nodes" : "Вузли", "settings_current_node" : "Поточний вузол", "settings_wallets" : "Гаманці", - "settings_display_balance_as" : "Відображати баланс як", + "settings_display_balance" : "Відображати баланс", "settings_currency" : "Валюта", "settings_fee_priority" : "Пріоритет транзакції", "settings_save_recipient_address" : "Зберігати адресу отримувача", @@ -529,6 +529,8 @@ "third_intro_content" : "Yat знаходиться за межами Cake Wallet. Будь-яку адресу гаманця на землі можна замінити на Yat!", "learn_more" : "Дізнатися більше", "search": "Пошук", + "search_language": "Мова пошуку", + "search_currency": "Шукати валюту", "new_template" : "Новий шаблон", "electrum_address_disclaimer": "Ми створюємо нові адреси щоразу, коли ви використовуєте їх, але попередні адреси продовжують працювати" } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index f8632ee98..d1cb625ee 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -228,7 +228,7 @@ "settings_nodes" : "节点数", "settings_current_node" : "当前节点", "settings_wallets" : "钱包", - "settings_display_balance_as" : "将余额显示为", + "settings_display_balance" : "显示余额为", "settings_currency" : "货币", "settings_fee_priority" : "交易优先级", "settings_save_recipient_address" : "保存收件人地址", @@ -528,6 +528,8 @@ "third_intro_content" : "Yats 也住在 Cake Wallet 之外。 地球上任何一個錢包地址都可以用一個Yat來代替!", "learn_more" : "了解更多", "search": "搜索", + "search_language": "搜索语言", + "search_currency": "搜索货币", "new_template" : "新模板", "electrum_address_disclaimer": "每次您使用一个地址时,我们都会生成新地址,但之前的地址仍然有效" }