cake pay country picker (#1779)

* cake pay country picker

* UI changes

* hide picker after the country is set

* Revert "hide picker after the country is set"

This reverts commit cce358b94f55c22e0807b4d3641a13ebd299106c.

* show country picker initially

* flags

* minor ui fixes

* Update lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart

---------

Co-authored-by: tuxpizza <tuxsudo@tux.pizza>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Serhii
2024-11-07 07:50:48 +02:00
committed by GitHub
co-authored by tuxpizza Omar Hatem
parent c8cfc2cff1
commit 48457fdd6d
132 changed files with 601 additions and 78 deletions
@@ -1,5 +1,6 @@
import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:cake_wallet/entities/country.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
@@ -8,6 +9,7 @@ import 'package:cake_wallet/src/screens/cake_pay/widgets/card_menu.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
@@ -20,6 +22,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class CakePayCardsPage extends BasePage {
CakePayCardsPage(this._cardsListViewModel) : searchFocusNode = FocusNode() {
@@ -80,9 +83,25 @@ class CakePayCardsPage extends BasePage {
@override
Widget body(BuildContext context) {
if (_cardsListViewModel.settingsStore.selectedCakePayCountry == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
reaction((_) => _cardsListViewModel.shouldShowCountryPicker, (bool shouldShowCountryPicker) async {
if (shouldShowCountryPicker) {
_cardsListViewModel.storeInitialFilterStates();
await showCountryPicker(context, _cardsListViewModel);
if (_cardsListViewModel.hasFiltersChanged) {
_cardsListViewModel.resetLoadingNextPageState();
_cardsListViewModel.getVendors();
}
}
});
});
}
final filterButton = Semantics(
label: S.of(context).filter_by,
child: InkWell(
child: GestureDetector(
onTap: () async {
_cardsListViewModel.storeInitialFilterStates();
await showFilterWidget(context);
@@ -92,50 +111,87 @@ class CakePayCardsPage extends BasePage {
}
},
child: Container(
width: 32,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 32,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
border: Border.all(
color: Colors.transparent,
),
borderRadius: BorderRadius.circular(10),
),
borderRadius: BorderRadius.circular(10),
child: Image.asset(
'assets/images/filter.png',
color: Theme.of(context).extension<FilterTheme>()!.iconColor,
))),
);
final _countryPicker = Semantics(
label: S.of(context).filter_by,
child: GestureDetector(
onTap: () async {
_cardsListViewModel.storeInitialFilterStates();
await showCountryPicker(context, _cardsListViewModel);
if (_cardsListViewModel.hasFiltersChanged) {
_cardsListViewModel.resetLoadingNextPageState();
_cardsListViewModel.getVendors();
}
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6),
decoration: BoxDecoration(
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
border: Border.all(color: Colors.transparent),
borderRadius: BorderRadius.circular(10),
),
child: Container(
margin: EdgeInsets.symmetric(vertical: 2),
child: Row(
children: [
Image.asset(
_cardsListViewModel.selectedCountry.iconPath,
width: 24,
height: 24,
errorBuilder: (context, error, stackTrace) => Container(
width: 24,
height: 24,
),
),
SizedBox(width: 6),
Text(
_cardsListViewModel.selectedCountry.countryCode,
style: TextStyle(
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
fontSize: 16,
fontWeight: FontWeight.w700,
),
),
],
),
child: Image.asset(
'assets/images/filter.png',
color: Theme.of(context).extension<FilterTheme>()!.iconColor,
),
)),
),
),
),
);
return Padding(
padding: const EdgeInsets.all(14.0),
child: Column(
children: [
padding: const EdgeInsets.all(14.0),
child: Column(children: [
Container(
padding: EdgeInsets.only(left: 2, right: 22),
height: 32,
child: Row(
children: [
padding: EdgeInsets.only(left: 2, right: 22),
height: 32,
child: Row(children: [
Expanded(
child: _SearchWidget(
controller: _searchController,
focusNode: searchFocusNode,
)),
SizedBox(width: 10),
filterButton
],
),
),
SizedBox(width: 5),
filterButton,
SizedBox(width: 5),
_countryPicker
])),
SizedBox(height: 8),
Expanded(
child: CakePayCardsPageBody(
cardsListViewModel: _cardsListViewModel,
),
),
],
),
);
Expanded(child: CakePayCardsPageBody(cardsListViewModel: _cardsListViewModel))
]));
}
Future<void> showFilterWidget(BuildContext context) async {
@@ -148,6 +204,32 @@ class CakePayCardsPage extends BasePage {
}
}
Future<void> showCountryPicker(BuildContext context, CakePayCardsListViewModel cardsListViewModel) async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
title: S.of(context).select_your_country,
items: cardsListViewModel.availableCountries,
images: cardsListViewModel.availableCountries
.map((e) => Image.asset(
e.iconPath,
errorBuilder: (context, error, stackTrace) => Container(
width: 58,
height: 58,
),
))
.toList(),
selectedAtIndex: cardsListViewModel.availableCountries
.indexOf(cardsListViewModel.selectedCountry),
onItemSelected: (Country country) =>
cardsListViewModel.setSelectedCountry(country),
isSeparated: false,
hintText: S.of(context).search,
matchingCriteria: (Country country, String searchText) =>
country.fullName.toLowerCase().contains(searchText.toLowerCase())));
}
class CakePayCardsPageBody extends StatefulWidget {
const CakePayCardsPageBody({
Key? key,
@@ -304,15 +386,9 @@ class _SearchWidget extends StatelessWidget {
alignLabelWithHint: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
suffixIcon: searchIcon,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white.withOpacity(0.2),
),
borderRadius: BorderRadius.circular(10),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white.withOpacity(0.2),
color: Colors.transparent,
),
borderRadius: BorderRadius.circular(10),
),
@@ -9,7 +9,7 @@ class CardItem extends StatelessWidget {
required this.backgroundColor,
required this.titleColor,
required this.subtitleColor,
this.hideBorder = false,
this.hideBorder = true,
this.discount = 0.0,
this.isAmount = false,
this.discountBackground,