diff --git a/assets/images/usdterc.png b/assets/images/usdterc.png new file mode 100644 index 000000000..212b301b5 Binary files /dev/null and b/assets/images/usdterc.png differ diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index 19810c636..e043e3b1e 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -38,6 +38,8 @@ class AddressValidator extends TextValidator { return '[0-9a-zA-Z]'; case CryptoCurrency.usdt: return '[0-9a-zA-Z]'; + case CryptoCurrency.usdterc20: + return '[0-9a-zA-Z]'; case CryptoCurrency.xlm: return '[0-9a-zA-Z]'; case CryptoCurrency.xrp: @@ -75,6 +77,8 @@ class AddressValidator extends TextValidator { return [34]; case CryptoCurrency.usdt: return [42]; + case CryptoCurrency.usdterc20: + return [42]; case CryptoCurrency.xlm: return [56]; case CryptoCurrency.xrp: diff --git a/lib/entities/crypto_currency.dart b/lib/entities/crypto_currency.dart index b836393bd..d5f23a0fa 100644 --- a/lib/entities/crypto_currency.dart +++ b/lib/entities/crypto_currency.dart @@ -22,6 +22,7 @@ class CryptoCurrency extends EnumerableItem with Serializable { CryptoCurrency.nano, CryptoCurrency.trx, CryptoCurrency.usdt, + CryptoCurrency.usdterc20, CryptoCurrency.xlm, CryptoCurrency.xrp ]; @@ -38,8 +39,9 @@ class CryptoCurrency extends EnumerableItem with Serializable { static const nano = CryptoCurrency(title: 'NANO', raw: 10); static const trx = CryptoCurrency(title: 'TRX', raw: 11); static const usdt = CryptoCurrency(title: 'USDT', raw: 12); - static const xlm = CryptoCurrency(title: 'XLM', raw: 13); - static const xrp = CryptoCurrency(title: 'XRP', raw: 14); + static const usdterc20 = CryptoCurrency(title: 'USDTERC20', raw: 13); + static const xlm = CryptoCurrency(title: 'XLM', raw: 14); + static const xrp = CryptoCurrency(title: 'XRP', raw: 15); static CryptoCurrency deserialize({int raw}) { switch (raw) { @@ -70,8 +72,10 @@ class CryptoCurrency extends EnumerableItem with Serializable { case 12: return CryptoCurrency.usdt; case 13: - return CryptoCurrency.xlm; + return CryptoCurrency.usdterc20; case 14: + return CryptoCurrency.xlm; + case 15: return CryptoCurrency.xrp; default: return null; @@ -106,6 +110,8 @@ class CryptoCurrency extends EnumerableItem with Serializable { return CryptoCurrency.trx; case 'usdt': return CryptoCurrency.usdt; + case 'usdterc20': + return CryptoCurrency.usdterc20; case 'xlm': return CryptoCurrency.xlm; case 'xrp': diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index 988246656..7d846b9de 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -236,6 +236,9 @@ class ContactListPage extends BasePage { case CryptoCurrency.usdt: image = Image.asset('assets/images/usdt.png', height: 24, width: 24); break; + case CryptoCurrency.usdterc20: + image = Image.asset('assets/images/usdterc.png', height: 24, width: 24); + break; case CryptoCurrency.xlm: image = Image.asset('assets/images/xlm.png', height: 24, width: 24); break; diff --git a/lib/src/screens/exchange/widgets/currency_picker.dart b/lib/src/screens/exchange/widgets/currency_picker.dart index 668f99e77..8a5c2794f 100644 --- a/lib/src/screens/exchange/widgets/currency_picker.dart +++ b/lib/src/screens/exchange/widgets/currency_picker.dart @@ -5,8 +5,9 @@ import 'package:flutter/material.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; import 'package:cake_wallet/src/widgets/alert_background.dart'; import 'package:cake_wallet/src/widgets/alert_close_button.dart'; +import 'package:cake_wallet/src/widgets/cake_scrollbar.dart'; -class CurrencyPicker extends StatelessWidget { +class CurrencyPicker extends StatefulWidget { CurrencyPicker({ @required this.selectedAtIndex, @required this.items, @@ -18,12 +19,47 @@ class CurrencyPicker extends StatelessWidget { final List items; final String title; final Function(CryptoCurrency) onItemSelected; + + @override + CurrencyPickerState createState() => CurrencyPickerState( + selectedAtIndex, + items, + title, + onItemSelected + ); +} + +class CurrencyPickerState extends State { + CurrencyPickerState( + this.selectedAtIndex, + this.items, + this.title, + this.onItemSelected): itemsCount = items.length; + + final int selectedAtIndex; + final List items; + final String title; + final Function(CryptoCurrency) onItemSelected; + final closeButton = Image.asset('assets/images/close.png', color: Palette.darkBlueCraiola, ); + final int crossAxisCount = 3; + final int itemsCount; + final double backgroundHeight = 280; + final double thumbHeight = 72; + ScrollController controller = ScrollController(); + double fromTop = 0; @override Widget build(BuildContext context) { + controller.addListener(() { + fromTop = controller.hasClients + ? (controller.offset / controller.position.maxScrollExtent * (backgroundHeight - thumbHeight)) + : 0; + setState(() {}); + }); + return AlertBackground( child: Stack( alignment: Alignment.center, @@ -52,54 +88,72 @@ class CurrencyPicker extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(14)), child: Container( - height: 400, - width: 300, - color: Theme.of(context).accentTextTheme.title.backgroundColor, - child: GridView.count( - shrinkWrap: true, - crossAxisCount: 3, - childAspectRatio: 1.25, - physics: const NeverScrollableScrollPhysics(), - crossAxisSpacing: 1, - mainAxisSpacing: 1, - children: List.generate(items.length, (index) { + height: 320, + width: 300, + color: Theme.of(context).accentTextTheme.title.backgroundColor, + child: Stack( + alignment: Alignment.center, + children: [ + GridView.count( + controller: controller, + crossAxisCount: crossAxisCount, + childAspectRatio: 1.25, + crossAxisSpacing: 1, + mainAxisSpacing: 1, + children: List.generate( + itemsCount + + getExtraEmptyTilesCount(crossAxisCount, itemsCount), + (index) { - final item = items[index]; - final isItemSelected = index == selectedAtIndex; + if (index >= itemsCount) { + return Container( + color: Theme.of(context).accentTextTheme.title.color, + ); + } - 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; + final item = items[index]; + final isItemSelected = index == selectedAtIndex; - return GestureDetector( - onTap: () { - if (onItemSelected == null) { - return; - } - Navigator.of(context).pop(); - onItemSelected(item); - }, - child: Container( - color: color, - child: Center( - child: Text( - item.toString(), - style: TextStyle( - fontSize: 18, - fontFamily: 'Poppins', - fontWeight: FontWeight.w600, - decoration: TextDecoration.none, - color: textColor - ), - ), - ), - ), - ); - }) - ), + 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( + color: color, + child: Center( + child: Text( + item.toString(), + style: TextStyle( + fontSize: 15, + fontFamily: 'Poppins', + fontWeight: FontWeight.w600, + decoration: TextDecoration.none, + color: textColor + ), + ), + ), + ), + ); + }) + ), + CakeScrollbar( + backgroundHeight: backgroundHeight, + thumbHeight: thumbHeight, + fromTop: fromTop + ) + ], + ) ), ), ), @@ -111,4 +165,9 @@ class CurrencyPicker extends StatelessWidget { ) ); } + + int getExtraEmptyTilesCount(int crossAxisCount, int itemsCount) { + final int tilesInNewRowCount = itemsCount % crossAxisCount; + return tilesInNewRowCount == 0 ? 0 : crossAxisCount - tilesInNewRowCount; + } } \ No newline at end of file