BIN
assets/images/flags/aus.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/flags/bgr.png
Normal file
After Width: | Height: | Size: 735 B |
BIN
assets/images/flags/bra.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/flags/cad.png
Normal file
After Width: | Height: | Size: 1,005 B |
BIN
assets/images/flags/che.png
Normal file
After Width: | Height: | Size: 855 B |
BIN
assets/images/flags/chn.png
Normal file
After Width: | Height: | Size: 860 B |
BIN
assets/images/flags/czk.png
Normal file
After Width: | Height: | Size: 915 B |
BIN
assets/images/flags/deu.png
Normal file
After Width: | Height: | Size: 703 B |
BIN
assets/images/flags/dnk.png
Normal file
After Width: | Height: | Size: 801 B |
BIN
assets/images/flags/esp.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/flags/eur.png
Normal file
After Width: | Height: | Size: 1,005 B |
BIN
assets/images/flags/fra.png
Normal file
After Width: | Height: | Size: 700 B |
BIN
assets/images/flags/gbr.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/flags/hkg.png
Normal file
After Width: | Height: | Size: 1,023 B |
BIN
assets/images/flags/hrv.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/flags/hun.png
Normal file
After Width: | Height: | Size: 728 B |
BIN
assets/images/flags/idn.png
Normal file
After Width: | Height: | Size: 684 B |
BIN
assets/images/flags/ind.png
Normal file
After Width: | Height: | Size: 845 B |
BIN
assets/images/flags/isl.png
Normal file
After Width: | Height: | Size: 867 B |
BIN
assets/images/flags/isr.png
Normal file
After Width: | Height: | Size: 937 B |
BIN
assets/images/flags/ita.png
Normal file
After Width: | Height: | Size: 705 B |
BIN
assets/images/flags/jpn.png
Normal file
After Width: | Height: | Size: 896 B |
BIN
assets/images/flags/kor.png
Normal file
After Width: | Height: | Size: 997 B |
BIN
assets/images/flags/mex.png
Normal file
After Width: | Height: | Size: 1,013 B |
BIN
assets/images/flags/mys.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/flags/nld.png
Normal file
After Width: | Height: | Size: 762 B |
BIN
assets/images/flags/nor.png
Normal file
After Width: | Height: | Size: 898 B |
BIN
assets/images/flags/nzl.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/flags/phl.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/flags/pol.png
Normal file
After Width: | Height: | Size: 707 B |
BIN
assets/images/flags/prt.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/flags/rou.png
Normal file
After Width: | Height: | Size: 705 B |
BIN
assets/images/flags/rus.png
Normal file
After Width: | Height: | Size: 702 B |
BIN
assets/images/flags/saf.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/flags/sgp.png
Normal file
After Width: | Height: | Size: 902 B |
BIN
assets/images/flags/swe.png
Normal file
After Width: | Height: | Size: 752 B |
BIN
assets/images/flags/tha.png
Normal file
After Width: | Height: | Size: 774 B |
BIN
assets/images/flags/ukr.png
Normal file
After Width: | Height: | Size: 695 B |
BIN
assets/images/flags/usa.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/flags/ven.png
Normal file
After Width: | Height: | Size: 1,009 B |
BIN
assets/images/search_icon.png
Normal file
After Width: | Height: | Size: 469 B |
|
@ -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<SettingsStore>()));
|
||||
|
||||
getIt.registerFactory(() => LanguageListPage(getIt.get<SettingsStore>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>(
|
||||
(type, _) => WalletRestoreViewModel(getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
||||
|
|
|
@ -1,43 +1,46 @@
|
|||
import 'package:cw_core/enumerable_item.dart';
|
||||
|
||||
class FiatCurrency extends EnumerableItem<String> with Serializable<String> {
|
||||
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<FiatCurrency> 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,
|
||||
|
|
|
@ -20,6 +20,25 @@ class LanguageService {
|
|||
'hr': 'Hrvatski (Croatian)',
|
||||
'it': 'Italiano (Italian)'
|
||||
};
|
||||
|
||||
static const Map<String, String> 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 = <String, String> {};
|
||||
|
||||
static void loadLocaleList() {
|
||||
|
|
|
@ -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<dynamic> createRoute(RouteSettings settings) {
|
|||
case Routes.faq:
|
||||
return MaterialPageRoute<void>(builder: (_) => getIt.get<FaqPage>());
|
||||
|
||||
case Routes.changeLanguage:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<LanguageListPage>());
|
||||
|
||||
case Routes.preSeed:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) =>
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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<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());
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
71
lib/src/screens/settings/widgets/settings_choices_cell.dart
Normal file
|
@ -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(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<ItemType> extends StandardListRow {
|
||||
SettingsPickerCell(
|
||||
|
@ -10,29 +9,43 @@ class SettingsPickerCell<ItemType> 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<void>(
|
||||
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<void>(
|
||||
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<ItemType> items;
|
||||
final void Function(ItemType item) onItemSelected;
|
||||
final String Function(ItemType item) displayItem;
|
||||
final List<Image> images;
|
||||
final String searchHintText;
|
||||
final bool isGridView;
|
||||
final bool Function(ItemType, String) matchingCriteria;
|
||||
|
||||
@override
|
||||
Widget buildTrailing(BuildContext context) {
|
||||
|
@ -40,9 +53,7 @@ class SettingsPickerCell<ItemType> 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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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<Item extends Object> 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<Item> items;
|
||||
|
@ -26,6 +31,10 @@ class Picker<Item extends Object> 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<Item>(items, images, onItemSelected);
|
||||
|
@ -35,8 +44,10 @@ class PickerState<Item> extends State<Picker> {
|
|||
PickerState(this.items, this.images, this.onItemSelected);
|
||||
|
||||
final Function(Item) onItemSelected;
|
||||
final List<Item> items;
|
||||
final List<Image> images;
|
||||
List<Item> items;
|
||||
List<Image> images;
|
||||
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
||||
final closeButton = Image.asset(
|
||||
'assets/images/close.png',
|
||||
|
@ -44,161 +55,248 @@ class PickerState<Item> extends State<Picker> {
|
|||
);
|
||||
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<widget.items.length;i++) {
|
||||
if (widget.matchingCriteria?.call(widget.items[i], searchController.text) ?? true) {
|
||||
items.add(widget.items[i] as Item);
|
||||
images.add(widget.images[i]);
|
||||
}
|
||||
}
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
controller.addListener(() {
|
||||
fromTop = controller.hasClients
|
||||
? (controller.offset /
|
||||
controller.position.maxScrollExtent *
|
||||
(backgroundHeight - thumbHeight))
|
||||
: 0;
|
||||
setState(() {});
|
||||
});
|
||||
|
||||
final isShowScrollThumb = items != null ? items.length > 3 : false;
|
||||
|
||||
return AlertBackground(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
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: <Widget>[
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
(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: <Widget>[
|
||||
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: <Widget>[
|
||||
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),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
)
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ class StandartSwitchState extends State<StandartSwitch> {
|
|||
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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
25
lib/view_model/settings/choices_list_item.dart
Normal file
|
@ -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<ItemType> 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<ItemType> items;
|
||||
final String Function(ItemType item) displayItem;
|
||||
final void Function(ItemType item) _onItemSelected;
|
||||
|
||||
void onItemSelected(dynamic item) {
|
||||
if (item is ItemType) {
|
||||
_onItemSelected?.call(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ItemType> extends SettingsListItem {
|
||||
PickerListItem(
|
||||
|
@ -7,18 +8,34 @@ class PickerListItem<ItemType> 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<ItemType> items;
|
||||
final String Function(ItemType item) displayItem;
|
||||
final void Function(ItemType item) _onItemSelected;
|
||||
final List<Image> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -99,19 +100,33 @@ abstract class SettingsViewModelBase with Store {
|
|||
|
||||
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<SettingsStore>().languageCode,
|
||||
onItemSelected: (String code) {
|
||||
getIt.get<SettingsStore>().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) ...[
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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": "हर बार जब आप एक का उपयोग करते हैं तो हम नए पते उत्पन्न करते हैं, लेकिन पिछले पते काम करना जारी रखते हैं"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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": "使用するたびに新しいアドレスが生成されますが、以前のアドレスは引き続き機能します"
|
||||
}
|
||||
|
|
|
@ -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": "사용할 때마다 새 주소가 생성되지만 이전 주소는 계속 작동합니다."
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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ą"
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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": "Мы генерируем новые адреса каждый раз, когда вы их используете, но предыдущие адреса продолжают работать."
|
||||
}
|
||||
|
|
|
@ -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": "Ми створюємо нові адреси щоразу, коли ви використовуєте їх, але попередні адреси продовжують працювати"
|
||||
}
|
||||
|
|
|
@ -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": "每次您使用一个地址时,我们都会生成新地址,但之前的地址仍然有效"
|
||||
}
|
||||
|
|