From ff7a217d8417eee05f6942198bb23bef031d96a9 Mon Sep 17 00:00:00 2001 From: Rafael Saes <76502841+saltrafael@users.noreply.github.com> Date: Fri, 14 Apr 2023 11:52:07 -0300 Subject: [PATCH] CW-338: Currency picker UI when keyboard is showing (#854) * fix: Currency picker UI when keyboard is showing * refactor: move picker logic into the common Picker widget - CurrencyPicker uses the common Picker widget in grid mode - SeedLanguagePicker uses the common Picker widget in grid mode - Added logic for keyboard showing UI into Picker widget - Added `softWrap: true` to the item text, so it doesn't overflow * fix: remove subPickerItemsList * fix: add final * fix: move function out of initState() * fix: keep build functions separate to remove boolean comparisons * fix: remove onItemSelected from already selected item * fix: change Expanded for Flexible widget --- .../exchange/widgets/currency_picker.dart | 162 +----- .../wallet_restore_from_seed_form.dart | 12 +- .../widgets/seed_language_picker.dart | 151 +----- lib/src/widgets/alert_close_button.dart | 9 +- lib/src/widgets/picker.dart | 503 ++++++++++++------ lib/src/widgets/seed_language_selector.dart | 26 +- 6 files changed, 427 insertions(+), 436 deletions(-) diff --git a/lib/src/screens/exchange/widgets/currency_picker.dart b/lib/src/screens/exchange/widgets/currency_picker.dart index 5ed9c6f7..0fe1d4e6 100644 --- a/lib/src/screens/exchange/widgets/currency_picker.dart +++ b/lib/src/screens/exchange/widgets/currency_picker.dart @@ -1,13 +1,8 @@ -import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker_item_widget.dart'; -import 'package:cake_wallet/src/screens/exchange/widgets/picker_item.dart'; -import 'package:cake_wallet/src/widgets/alert_close_button.dart'; -import 'package:cake_wallet/utils/responsive_layout_util.dart'; -import 'package:cw_core/currency.dart'; import 'package:flutter/material.dart'; +import 'package:cake_wallet/src/screens/exchange/widgets/picker_item.dart'; import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/palette.dart'; -import 'currency_picker_widget.dart'; +import 'package:cake_wallet/src/widgets/picker.dart'; +import 'package:cw_core/currency.dart'; class CurrencyPicker extends StatefulWidget { CurrencyPicker( @@ -19,7 +14,7 @@ class CurrencyPicker extends StatefulWidget { this.isMoneroWallet = false, this.isConvertFrom = false}); - int selectedAtIndex; + final int selectedAtIndex; final List items; final String? title; final Function(Currency) onItemSelected; @@ -35,144 +30,39 @@ class CurrencyPickerState extends State { CurrencyPickerState(this.items) : isSearchBarActive = false, textFieldValue = '', - subPickerItemsList = items, - appBarTextStyle = - TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white), - pickerItemsList = >[]; + appBarTextStyle = TextStyle( + fontSize: 20, + fontFamily: 'Lato', + backgroundColor: Colors.transparent, + color: Colors.white), + pickerItemsList = >[]; List> pickerItemsList; List items; bool isSearchBarActive; String textFieldValue; - List subPickerItemsList; TextStyle appBarTextStyle; - void cleanSubPickerItemsList() => subPickerItemsList = items; - - void currencySearchBySubstring(String subString) { - setState(() { - if (subString.isNotEmpty) { - subPickerItemsList = items - .where((element) => - element.name.toLowerCase().contains(subString.toLowerCase()) || - (element.tag != null ? element.tag!.toLowerCase().contains(subString.toLowerCase()) : false) || - (element.fullName != null ? element.fullName!.toLowerCase().contains(subString.toLowerCase()) : false)) - .toList(); - return; - } - cleanSubPickerItemsList(); - }); + bool currencySearchBySubstring(Currency currency, String subString) { + return currency.name.toLowerCase().contains(subString.toLowerCase()) || + (currency.tag != null + ? currency.tag!.toLowerCase().contains(subString.toLowerCase()) + : false) || + (currency.fullName != null + ? currency.fullName!.toLowerCase().contains(subString.toLowerCase()) + : false); } @override Widget build(BuildContext context) { - return AlertBackground( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - 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: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: Container( - color: Theme.of(context).accentTextTheme.headline6!.color!, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.65, - maxWidth: ResponsiveLayoutUtil.kPopupWidth - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.hintText != null) - Padding( - padding: const EdgeInsets.all(16), - child: TextFormField( - style: TextStyle(color: Palette.darkBlueCraiola), - decoration: InputDecoration( - hintText: widget.hintText, - prefixIcon: Image.asset("assets/images/search_icon.png"), - filled: true, - fillColor: const Color(0xffF2F0FA), - 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, - )), - ), - onChanged: (value) { - this.textFieldValue = value; - cleanSubPickerItemsList(); - currencySearchBySubstring(textFieldValue); - }, - ), - ), - Divider( - color: Theme.of(context).accentTextTheme.headline6!.backgroundColor!, - height: 1, - ), - if (widget.selectedAtIndex != -1) - AspectRatio( - aspectRatio: 6, - child: PickerItemWidget( - title: items[widget.selectedAtIndex].name, - iconPath: items[widget.selectedAtIndex].iconPath, - isSelected: true, - tag: items[widget.selectedAtIndex].tag, - ), - ), - Flexible( - child: CurrencyPickerWidget( - crossAxisCount: 2, - selectedAtIndex: widget.selectedAtIndex, - pickerItemsList: subPickerItemsList, - pickListItem: (int index) { - setState(() { - widget.selectedAtIndex = index; - }); - widget.onItemSelected(subPickerItemsList[index]); - if (widget.isConvertFrom && - !widget.isMoneroWallet && - (subPickerItemsList[index] == CryptoCurrency.xmr)) { - } else { - Navigator.of(context).pop(); - } - }, - ), - ), - ], - ), - ), - ), - ), - ), - SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight), - AlertCloseButton(), - ], - ), + return Picker( + selectedAtIndex: widget.selectedAtIndex, + items: items, + isGridView: true, + title: widget.title, + hintText: widget.hintText, + matchingCriteria: currencySearchBySubstring, + onItemSelected: widget.onItemSelected, ); } } diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart index 5849eb2e..3071d9a8 100644 --- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart +++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart @@ -113,16 +113,10 @@ class WalletRestoreFromSeedFormState extends State { if (widget.displayLanguageSelector) GestureDetector( onTap: () async { - final selected = await showPopUp( + await showPopUp( context: context, - builder: (BuildContext context) => - SeedLanguagePicker(selected: language)); - - if (selected == null || selected.isEmpty) { - return; - } - - _changeLanguage(selected); + builder: (_) => SeedLanguagePicker( + selected: language, onItemSelected: _changeLanguage)); }, child: Container( color: Colors.transparent, diff --git a/lib/src/screens/seed_language/widgets/seed_language_picker.dart b/lib/src/screens/seed_language/widgets/seed_language_picker.dart index 64e05014..0e1e63f5 100644 --- a/lib/src/screens/seed_language/widgets/seed_language_picker.dart +++ b/lib/src/screens/seed_language/widgets/seed_language_picker.dart @@ -1,9 +1,6 @@ -import 'dart:ui'; -import 'package:cake_wallet/src/widgets/alert_background.dart'; -import 'package:cake_wallet/src/widgets/alert_close_button.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/src/widgets/picker.dart'; +import 'package:flutter/cupertino.dart'; import 'package:cake_wallet/generated/i18n.dart'; List flagImages = [ @@ -50,138 +47,40 @@ const List seedLanguages = [ enum Places { topLeft, topRight, bottomLeft, bottomRight, inside } class SeedLanguagePicker extends StatefulWidget { - SeedLanguagePicker({ - Key? key, - this.selected = defaultSeedLanguage}) + SeedLanguagePicker( + {Key? key, + this.selected = defaultSeedLanguage, + required this.onItemSelected}) : super(key: key); final String selected; + final Function(String) onItemSelected; @override - SeedLanguagePickerState createState() => - SeedLanguagePickerState(selected: selected); + SeedLanguagePickerState createState() => SeedLanguagePickerState( + selected: selected, onItemSelected: onItemSelected); } class SeedLanguagePickerState extends State { - SeedLanguagePickerState({required this.selected}); + SeedLanguagePickerState( + {required this.selected, required this.onItemSelected}); - final closeButton = Image.asset('assets/images/close.png'); - String selected; + final String selected; + final Function(String) onItemSelected; @override Widget build(BuildContext context) { - return AlertBackground( - child: Stack( - alignment: Alignment.center, - children: [ - Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.only(left: 24, right: 24), - child: Text( - S.of(context).seed_choose, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - fontFamily: 'Lato', - decoration: TextDecoration.none, - color: Colors.white), - ), - ), - Padding( - padding: EdgeInsets.only(top: 24), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(14)), - child: Container( - height: 300, - width: 300, - color: - Theme.of(context).accentTextTheme!.headline6!.backgroundColor!, - child: GridView.count( - padding: EdgeInsets.all(0), - shrinkWrap: true, - crossAxisCount: 3, - childAspectRatio: 4 / 3, - physics: const NeverScrollableScrollPhysics(), - crossAxisSpacing: 1, - mainAxisSpacing: 1, - children: List.generate(11, (index) { - if (index == 10) { - return gridTile( - isCurrent: false, - image: null, - text: '', - onTap: () {}); - } - - final code = languageCodes[index]; - final flag = flagImages[index]; - final isCurrent = - index == seedLanguages.indexOf(selected); - - return gridTile( - isCurrent: isCurrent, - image: flag, - text: code, - onTap: () { - selected = seedLanguages[index]; - Navigator.of(context).pop(selected); - }); - }), - ), - ), - ), - ) - ], - ), - AlertCloseButton(image: closeButton) - ], - )); - } - - Widget gridTile( - {required bool isCurrent, - required String text, - required VoidCallback onTap, - Image? image}) { - final color = isCurrent - ? Theme.of(context).textTheme!.bodyText1!.color! - : Theme.of(context).accentTextTheme!.headline6!.color!; - final textColor = isCurrent - ? Palette.blueCraiola - : Theme.of(context).primaryTextTheme!.headline6!.color!; - - return GestureDetector( - onTap: onTap, - child: Container( - padding: EdgeInsets.all(10), - color: color, - child: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - image ?? Offstage(), - Padding( - padding: image != null - ? EdgeInsets.only(left: 10) - : EdgeInsets.only(left: 0), - child: Text( - text, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - fontFamily: 'Lato', - decoration: TextDecoration.none, - color: textColor), - ), - ) - ], - ), - ), - )); + return Picker( + selectedAtIndex: seedLanguages.indexOf(selected), + items: seedLanguages, + images: flagImages, + isGridView: true, + title: S.of(context).seed_choose, + hintText: S.of(context).seed_choose, + matchingCriteria: (String language, String searchText) { + return language.toLowerCase().contains(searchText); + }, + onItemSelected: onItemSelected, + ); } } diff --git a/lib/src/widgets/alert_close_button.dart b/lib/src/widgets/alert_close_button.dart index e8e20f12..1aa8277f 100644 --- a/lib/src/widgets/alert_close_button.dart +++ b/lib/src/widgets/alert_close_button.dart @@ -2,9 +2,10 @@ import 'package:cake_wallet/palette.dart'; import 'package:flutter/material.dart'; class AlertCloseButton extends StatelessWidget { - AlertCloseButton({this.image}); + AlertCloseButton({this.image, this.bottom}); final Image? image; + final double? bottom; final closeButton = Image.asset( 'assets/images/close.png', @@ -13,7 +14,9 @@ class AlertCloseButton extends StatelessWidget { @override Widget build(BuildContext context) { - return GestureDetector( + return Positioned( + bottom: bottom ?? 60, + child: GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( height: 42, @@ -26,6 +29,6 @@ class AlertCloseButton extends StatelessWidget { child: image ?? closeButton, ), ), - ); + )); } } \ No newline at end of file diff --git a/lib/src/widgets/picker.dart b/lib/src/widgets/picker.dart index ccf922d4..34ff1031 100644 --- a/lib/src/widgets/picker.dart +++ b/lib/src/widgets/picker.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/src/widgets/alert_background.dart'; import 'package:cake_wallet/src/widgets/alert_close_button.dart'; +import 'package:cw_core/currency.dart'; class Picker extends StatefulWidget { Picker({ @@ -37,7 +38,8 @@ class Picker extends StatefulWidget { final bool Function(Item, String)? matchingCriteria; @override - _PickerState createState() => _PickerState(items, images, onItemSelected); + _PickerState createState() => + _PickerState(items, images, onItemSelected); } class _PickerState extends State> { @@ -46,132 +48,235 @@ class _PickerState extends State> { final Function(Item) onItemSelected; List items; List images; + List filteredItems = []; + List filteredImages = []; final TextEditingController searchController = TextEditingController(); ScrollController controller = ScrollController(); + void clearFilteredItemsList() { + filteredItems = List.from( + items, + growable: true, + ); + filteredImages = List.from( + images, + growable: true, + ); + + if (widget.selectedAtIndex != -1) { + if (widget.selectedAtIndex < filteredItems.length) { + filteredItems.removeAt(widget.selectedAtIndex); + } + + if (widget.selectedAtIndex < filteredImages.length) { + filteredImages.removeAt(widget.selectedAtIndex); + } + } + } + @override void initState() { super.initState(); + clearFilteredItemsList(); + searchController.addListener(() { - items = []; - images = []; - for (int i=0;i 0) { + // increase a bit or it gets too squished in the top + containerHeight = height * 0.75; + + final containerCenter = containerHeight / 2; + final containerBottom = screenCenter - containerCenter; + + final hasTitle = widget.title == null || widget.title!.isEmpty; + + // position the close button right below the search container + closeButtonBottom = closeButtonBottom - + containerBottom + + (hasTitle ? padding : padding / 1.5); + } + return AlertBackground( child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - 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: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: Container( - color: Theme.of(context).accentTextTheme.headline6!.color!, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height * 0.65, - maxWidth: ResponsiveLayoutUtil.kPopupWidth, - ), - 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.headline6!.color!), - decoration: InputDecoration( - hintText: widget.hintText, - prefixIcon: Image.asset("assets/images/search_icon.png"), - filled: true, - fillColor: Theme.of(context).accentTextTheme.headline3!.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, - )), - ), - ), + children: [ + Expanded( + flex: 1, + child: Stack( + alignment: Alignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (widget.title?.isNotEmpty ?? false) + Container( + padding: EdgeInsets.symmetric(horizontal: padding), + child: Text( + widget.title!, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + fontFamily: 'Lato', + fontWeight: FontWeight.bold, + decoration: TextDecoration.none, + color: Colors.white, ), - Divider( - color: Theme.of(context).accentTextTheme.headline6!.backgroundColor!, - height: 1, ), - if (widget.selectedAtIndex != -1) buildSelectedItem(), - Flexible( - child: Stack( - alignment: Alignment.center, - children: [ - items.length > 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.headline6!.color!, - ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: padding), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(30)), + child: Container( + color: Theme.of(context) + .accentTextTheme + .headline6! + .color!, + child: ConstrainedBox( + constraints: BoxConstraints( + maxHeight: containerHeight, + maxWidth: ResponsiveLayoutUtil.kPopupWidth, + ), + 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 + .headline6! + .color!), + decoration: InputDecoration( + hintText: widget.hintText, + prefixIcon: Image.asset( + "assets/images/search_icon.png"), + filled: true, + fillColor: Theme.of(context) + .accentTextTheme + .headline3! + .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, + )), ), - ) - : Offstage(), - ], + ), + ), + Divider( + color: Theme.of(context) + .accentTextTheme + .headline6! + .backgroundColor!, + height: 1, + ), + if (widget.selectedAtIndex != -1) + buildSelectedItem(widget.selectedAtIndex), + Flexible( + child: Stack( + alignment: Alignment.center, + children: [ + filteredItems.length > 3 + ? Scrollbar( + controller: controller, + child: itemsList(), + ) + : itemsList(), + (widget.description?.isNotEmpty ?? false) + ? Positioned( + bottom: padding, + left: padding, + right: padding, + child: Text( + widget.description!, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + fontFamily: 'Lato', + decoration: + TextDecoration.none, + color: Theme.of(context) + .primaryTextTheme + .headline6! + .color!, + ), + ), + ) + : Offstage(), + ], + ), + ), + ], + ), ), ), - ], - ), + ), + ) + ], ), - ), + SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight), + AlertCloseButton(bottom: closeButtonBottom), + ], ), ), - SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight), - AlertCloseButton(), + // gives the extra spacing using MediaQuery.viewInsets.bottom + // to simulate a keyboard area + SizedBox( + height: bottom, + ) ], ), ); @@ -185,7 +290,7 @@ class _PickerState extends State> { padding: EdgeInsets.zero, controller: controller, shrinkWrap: true, - itemCount: items.isEmpty ? 0 : items.length, + itemCount: filteredItems.isEmpty ? 0 : filteredItems.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 2, @@ -199,34 +304,42 @@ class _PickerState extends State> { shrinkWrap: true, separatorBuilder: (context, index) => widget.isSeparated ? Divider( - color: Theme.of(context).accentTextTheme.headline6!.backgroundColor!, + color: Theme.of(context) + .accentTextTheme + .headline6! + .backgroundColor!, height: 1, ) : const SizedBox(), - itemCount: items.isEmpty ? 0 : items.length, + itemCount: filteredItems.isEmpty ? 0 : filteredItems.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 = filteredItems[index]; + final tag = item is Currency ? item.tag : null; - final item = items[index]; - final image = images.isNotEmpty ? images[index] : null; + final icon = item is Currency && item.iconPath != null + ? Image.asset( + item.iconPath!, + height: 20.0, + width: 20.0, + ) + : null; + + final image = images.isNotEmpty ? filteredImages[index] : icon; return GestureDetector( onTap: () { Navigator.of(context).pop(); - onItemSelected(item); + onItemSelected(item!); }, child: Container( height: 55, color: Theme.of(context).accentTextTheme.headline6!.color!, - padding: EdgeInsets.only(left: 24, right: 24), + padding: EdgeInsets.symmetric(horizontal: 24), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: widget.mainAxisAlignment, @@ -236,15 +349,53 @@ class _PickerState extends State> { 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.headline6!.color!, - decoration: TextDecoration.none, - ), + child: Row( + children: [ + Flexible( + child: Text( + widget.displayItem?.call(item) ?? item.toString(), + softWrap: true, + style: TextStyle( + fontSize: 14, + fontFamily: 'Lato', + fontWeight: FontWeight.w600, + color: Theme.of(context) + .primaryTextTheme + .headline6! + .color!, + decoration: TextDecoration.none, + ), + ), + ), + if (tag != null) + Align( + alignment: Alignment.topCenter, + child: Container( + width: 35.0, + height: 18.0, + child: Center( + child: Text( + tag, + style: TextStyle( + fontSize: 7.0, + fontFamily: 'Lato', + color: Theme.of(context) + .textTheme + .bodyText2! + .color!), + ), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.0), + //border: Border.all(color: ), + color: Theme.of(context) + .textTheme + .bodyText2! + .decorationColor!, + ), + ), + ), + ], ), ), ), @@ -254,37 +405,91 @@ class _PickerState extends State> { ); } - Widget buildSelectedItem() { - final item = widget.items[widget.selectedAtIndex]; - final image = images.isNotEmpty ? widget.images[widget.selectedAtIndex] : null; + Widget buildSelectedItem(int index) { + final item = items[index]; + final tag = item is Currency ? item.tag : 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.headline6!.color!, - decoration: TextDecoration.none, + final icon = item is Currency && item.iconPath != null + ? Image.asset( + item.iconPath!, + height: 20.0, + width: 20.0, + ) + : null; + + final image = images.isNotEmpty ? images[index] : icon; + + return GestureDetector( + onTap: () { + Navigator.of(context).pop(); + }, + child: Container( + height: 55, + color: Theme.of(context).accentTextTheme.headline6!.color!, + padding: EdgeInsets.symmetric(horizontal: 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: Row( + children: [ + Flexible( + child: Text( + widget.displayItem?.call(item) ?? item.toString(), + softWrap: true, + style: TextStyle( + fontSize: 16, + fontFamily: 'Lato', + fontWeight: FontWeight.w700, + color: Theme.of(context) + .primaryTextTheme + .headline6! + .color!, + decoration: TextDecoration.none, + ), + ), + ), + if (tag != null) + Align( + alignment: Alignment.topCenter, + child: Container( + width: 35.0, + height: 18.0, + child: Center( + child: Text( + tag, + style: TextStyle( + fontSize: 7.0, + fontFamily: 'Lato', + color: Theme.of(context) + .textTheme + .bodyText2! + .color!), + ), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.0), + //border: Border.all(color: ), + color: Theme.of(context) + .textTheme + .bodyText2! + .decorationColor!, + ), + ), + ), + ], ), ), ), - ), - Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.bodyText1!.color!), - ], + Icon(Icons.check_circle, + color: Theme.of(context).accentTextTheme.bodyText1!.color!), + ], + ), ), ); } diff --git a/lib/src/widgets/seed_language_selector.dart b/lib/src/widgets/seed_language_selector.dart index f874d62a..4db3684a 100644 --- a/lib/src/widgets/seed_language_selector.dart +++ b/lib/src/widgets/seed_language_selector.dart @@ -5,7 +5,8 @@ import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart'; import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart'; class SeedLanguageSelector extends StatefulWidget { - SeedLanguageSelector({Key? key, required this.initialSelected}) : super(key: key); + SeedLanguageSelector({Key? key, required this.initialSelected}) + : super(key: key); final String initialSelected; @@ -30,21 +31,20 @@ class SeedLanguageSelectorState extends State { S.current.seed_language_italian, ]; String selected; - final _pickerKey = GlobalKey(); @override Widget build(BuildContext context) { return SelectButton( - image: null, - text: seedLocales[seedLanguages.indexOf(selected)], - onTap: () async { - final selected = await showPopUp( - context: context, - builder: (BuildContext context) => - SeedLanguagePicker(key: _pickerKey, selected: this.selected)); - if (selected != null) { - setState(() => this.selected = selected); - } - }); + image: null, + text: seedLocales[seedLanguages.indexOf(selected)], + onTap: () async { + await showPopUp( + context: context, + builder: (_) => SeedLanguagePicker( + selected: this.selected, + onItemSelected: (String selected) => + setState(() => this.selected = selected))); + }, + ); } }