| 1 | import 'package:cake_wallet/core/utilities.dart'; |
| 2 | import 'package:cake_wallet/di.dart'; |
| 3 | import 'package:cake_wallet/entities/new_ui_entities/list_item/list_Item_checkbox.dart'; |
| 4 | import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart'; |
| 5 | import 'package:cake_wallet/exchange/provider/exchange_provider.dart'; |
| 6 | import 'package:cake_wallet/generated/i18n.dart'; |
| 7 | import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; |
| 8 | import 'package:cake_wallet/new-ui/widgets/swap_page/trocador_providers_settings.dart'; |
| 9 | import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; |
| 10 | import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart'; |
| 11 | import 'package:cake_wallet/utils/show_pop_up.dart'; |
| 12 | import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; |
| 13 | import 'package:cake_wallet/view_model/settings/trocador_providers_view_model.dart'; |
| 14 | import 'package:flutter/cupertino.dart'; |
| 15 | import 'package:flutter/material.dart'; |
| 16 | import 'package:flutter_mobx/flutter_mobx.dart'; |
| 17 | import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; |
| 18 | |
| 19 | class ProviderOptionsPage extends StatelessWidget { |
| 20 | const ProviderOptionsPage({super.key, required this.exchangeViewModel}); |
| 21 | |
| 22 | final ExchangeViewModel exchangeViewModel; |
| 23 | |
| 24 | @override |
| 25 | Widget build(BuildContext context) { |
| 26 | return Observer( |
| 27 | builder: (_) { |
| 28 | final decentralizedProviders = exchangeViewModel.providerList |
| 29 | .where((provider) => !provider.description.isCentralized) |
| 30 | .toList(); |
| 31 | final centralizedProviders = exchangeViewModel.providerList |
| 32 | .where((provider) => provider.description.isCentralized) |
| 33 | .toList(); |
| 34 | return Column( |
| 35 | children: [ |
| 36 | ModalTopBar( |
| 37 | title: S.of(context).swap_providers, |
| 38 | onLeadingPressed: Navigator.of(context).pop, |
| 39 | leadingIcon: Icon(Icons.arrow_back_ios_new), |
| 40 | leadingSemanticLabel: S.of(context).seed_alert_back, |
| 41 | ), |
| 42 | Expanded( |
| 43 | child: SingleChildScrollView( |
| 44 | controller: ModalScrollController.of(context), |
| 45 | child: Padding( |
| 46 | padding: const EdgeInsets.symmetric(horizontal: 16.0), |
| 47 | child: Column( |
| 48 | children: [ |
| 49 | NewListSections(sections: { |
| 50 | "": [ |
| 51 | ListItemSelector( |
| 52 | options: [ |
| 53 | exchangeViewModel.forceDecentralizedExchanges |
| 54 | ? S.of(context).decentralized_only |
| 55 | : S.of(context).best_rate |
| 56 | ], |
| 57 | keyValue: "pref", |
| 58 | label: S.of(context).preference, |
| 59 | onTap: exchangeViewModel.toggleForceDecentralizedExchanges) |
| 60 | ] |
| 61 | }), |
| 62 | SizedBox(height: 24), |
| 63 | Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ |
| 64 | Text( |
| 65 | S.of(context).decentralized, |
| 66 | style: TextStyle( |
| 67 | fontSize: 14, |
| 68 | fontWeight: FontWeight.w400, |
| 69 | color: Theme.of(context).colorScheme.onSurfaceVariant), |
| 70 | ), |
| 71 | Row( |
| 72 | spacing: 20, |
| 73 | children: [ |
| 74 | GestureDetector( |
| 75 | onTap: () { |
| 76 | for (final provider in decentralizedProviders) { |
| 77 | _switchProviderStatus(provider, true, context); |
| 78 | } |
| 79 | }, |
| 80 | child: Text( |
| 81 | S.of(context).select_all, |
| 82 | style: TextStyle(color: Theme.of(context).colorScheme.primary), |
| 83 | ), |
| 84 | ), |
| 85 | GestureDetector( |
| 86 | onTap: () { |
| 87 | for (final provider in decentralizedProviders) { |
| 88 | _switchProviderStatus(provider, false, context); |
| 89 | } |
| 90 | }, |
| 91 | child: Text(S.of(context).unselect_all, |
| 92 | style: TextStyle(color: Theme.of(context).colorScheme.primary)), |
| 93 | ) |
| 94 | ], |
| 95 | ) |
| 96 | ]), |
| 97 | SizedBox(height: 12), |
| 98 | NewListSections( |
| 99 | getCheckboxValue: (key) => |
| 100 | exchangeViewModel.selectedProviders |
| 101 | .firstWhereOrNull((e) => e.title == key) != |
| 102 | null, |
| 103 | updateCheckboxValue: (key, val) {}, |
| 104 | sections: { |
| 105 | S.of(context).decentralized: decentralizedProviders.map((item) { |
| 106 | return ListItemCheckbox( |
| 107 | iconPath: item.description.image, |
| 108 | keyValue: item.title, |
| 109 | label: item.title, |
| 110 | value: exchangeViewModel.selectedProviders.contains(item), |
| 111 | onChanged: (val) { |
| 112 | _switchProviderStatus(item, val, context); |
| 113 | }); |
| 114 | }).toList(), |
| 115 | }), |
| 116 | SizedBox(height: 24), |
| 117 | Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ |
| 118 | Text(S.of(context).centralized, |
| 119 | style: TextStyle( |
| 120 | fontSize: 14, |
| 121 | fontWeight: FontWeight.w400, |
| 122 | color: Theme.of(context).colorScheme.onSurfaceVariant)), |
| 123 | Row( |
| 124 | spacing: 20, |
| 125 | children: [ |
| 126 | GestureDetector( |
| 127 | onTap: () { |
| 128 | for (final provider in centralizedProviders) { |
| 129 | _switchProviderStatus(provider, true, context); |
| 130 | } |
| 131 | }, |
| 132 | child: Text( |
| 133 | S.of(context).select_all, |
| 134 | style: TextStyle(color: Theme.of(context).colorScheme.primary), |
| 135 | ), |
| 136 | ), |
| 137 | GestureDetector( |
| 138 | onTap: () { |
| 139 | for (final provider in centralizedProviders) { |
| 140 | _switchProviderStatus(provider, false, context); |
| 141 | } |
| 142 | }, |
| 143 | child: Text(S.of(context).unselect_all, |
| 144 | style: TextStyle(color: Theme.of(context).colorScheme.primary)), |
| 145 | ) |
| 146 | ], |
| 147 | ) |
| 148 | ]), |
| 149 | SizedBox(height: 12), |
| 150 | Stack( |
| 151 | children: [ |
| 152 | NewListSections( |
| 153 | getCheckboxValue: (key) => |
| 154 | exchangeViewModel.selectedProviders |
| 155 | .firstWhereOrNull((e) => e.title == key) != |
| 156 | null, |
| 157 | updateCheckboxValue: (key, val) {}, |
| 158 | sections: { |
| 159 | S.of(context).centralized: centralizedProviders.map((item) { |
| 160 | return ListItemCheckbox( |
| 161 | iconPath: item.description.image, |
| 162 | keyValue: item.title, |
| 163 | label: item.title, |
| 164 | showArrow: item.title == "Trocador", |
| 165 | value: exchangeViewModel.selectedProviders.contains(item), |
| 166 | subtitle: item.title == "Trocador" |
| 167 | ? S.of(context).manage_providers |
| 168 | : null, |
| 169 | onTap: item.title == "Trocador" |
| 170 | ? () { |
| 171 | _openTrocadorProvidersPage(context); |
| 172 | } |
| 173 | : null, |
| 174 | onChanged: (val) { |
| 175 | _switchProviderStatus(item, val, context); |
| 176 | }); |
| 177 | }).toList(), |
| 178 | }), |
| 179 | if (exchangeViewModel.forceDecentralizedExchanges) |
| 180 | Positioned.fill( |
| 181 | child: Container( |
| 182 | decoration: BoxDecoration( |
| 183 | color: Colors.black12.withAlpha(128), |
| 184 | borderRadius: BorderRadius.circular(16)), |
| 185 | )) |
| 186 | ], |
| 187 | ), |
| 188 | SizedBox(height: 36) |
| 189 | ], |
| 190 | ), |
| 191 | ), |
| 192 | ), |
| 193 | ) |
| 194 | ], |
| 195 | ); |
| 196 | }, |
| 197 | ); |
| 198 | } |
| 199 | |
| 200 | void _switchProviderStatus(ExchangeProvider provider, bool status, BuildContext context) { |
| 201 | if (!provider.isAvailable) { |
| 202 | showPopUp<void>( |
| 203 | builder: (BuildContext popUpContext) => AlertWithOneAction( |
| 204 | alertTitle: 'Error', |
| 205 | alertContent: 'The exchange is blocked in your region.', |
| 206 | buttonText: S.of(context).ok, |
| 207 | buttonAction: () => Navigator.of(context).pop()), |
| 208 | context: context); |
| 209 | return; |
| 210 | } |
| 211 | if (status) { |
| 212 | exchangeViewModel.addExchangeProvider(provider); |
| 213 | } else { |
| 214 | exchangeViewModel.removeExchangeProvider(provider); |
| 215 | } |
| 216 | |
| 217 | exchangeViewModel.saveSelectedProviders(); |
| 218 | } |
| 219 | |
| 220 | void _openTrocadorProvidersPage(BuildContext context) { |
| 221 | final vm = getIt.get<TrocadorProvidersViewModel>(); |
| 222 | Navigator.of(context).push(CupertinoPageRoute( |
| 223 | builder: (context) => Material( |
| 224 | child: TrocadorProvidersSettings( |
| 225 | trocadorProvidersViewModel: vm, |
| 226 | )))); |
| 227 | } |
| 228 | } |