Add Number Settings Screen UI

This commit is contained in:
OmarHatem28 2022-07-06 04:49:52 +02:00
parent 81e799c514
commit 31526d6b71
6 changed files with 301 additions and 168 deletions

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/cake_phone_entities/phone_number_service.dart';
import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
@ -70,6 +71,7 @@ import 'package:cake_wallet/src/screens/cake_phone/cake_phone_verification_page.
import 'package:cake_wallet/src/screens/cake_phone/cake_phone_products_page.dart'; import 'package:cake_wallet/src/screens/cake_phone/cake_phone_products_page.dart';
import 'package:cake_wallet/src/screens/cake_phone/cake_phone_products/phone_number_product_page.dart'; import 'package:cake_wallet/src/screens/cake_phone/cake_phone_products/phone_number_product_page.dart';
import 'package:cake_wallet/src/screens/cake_phone/active_services_page.dart'; import 'package:cake_wallet/src/screens/cake_phone/active_services_page.dart';
import 'package:cake_wallet/src/screens/cake_phone/number_settings_page.dart';
RouteSettings currentRouteSettings; RouteSettings currentRouteSettings;
@ -82,8 +84,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newWalletFromWelcome: case Routes.newWalletFromWelcome:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>( builder: (_) => getIt.get<SetupPinCodePage>(param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
if (availableWalletTypes.length == 1) { if (availableWalletTypes.length == 1) {
Navigator.of(context.context).pushNamed(Routes.newWallet, arguments: availableWalletTypes.first); Navigator.of(context.context).pushNamed(Routes.newWallet, arguments: availableWalletTypes.first);
} else { } else {
@ -96,47 +97,40 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<NewWalletTypePage>( builder: (_) => getIt.get<NewWalletTypePage>(
param1: (BuildContext context, WalletType type) => param1: (BuildContext context, WalletType type) =>
Navigator.of(context) Navigator.of(context).pushNamed(Routes.newWallet, arguments: type),
.pushNamed(Routes.newWallet, arguments: type),
param2: false)); param2: false));
case Routes.newWallet: case Routes.newWallet:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
final walletNewVM = getIt.get<WalletNewVM>(param1: type); final walletNewVM = getIt.get<WalletNewVM>(param1: type);
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM));
builder: (_) => NewWalletPage(walletNewVM));
case Routes.setupPin: case Routes.setupPin:
Function(PinCodeState<PinCodeWidget>, String) callback; Function(PinCodeState<PinCodeWidget>, String) callback;
if (settings.arguments is Function(PinCodeState<PinCodeWidget>, String)) { if (settings.arguments is Function(PinCodeState<PinCodeWidget>, String)) {
callback = callback = settings.arguments as Function(PinCodeState<PinCodeWidget>, String);
settings.arguments as Function(PinCodeState<PinCodeWidget>, String);
} }
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<SetupPinCodePage>(param1: callback));
builder: (_) => getIt.get<SetupPinCodePage>(param1: callback));
case Routes.moneroRestoreWalletFromWelcome: case Routes.moneroRestoreWalletFromWelcome:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>( builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) => param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
Navigator.pushNamed( Navigator.pushNamed(context.context, Routes.restoreWallet, arguments: WalletType.monero)),
context.context, Routes.restoreWallet, arguments: WalletType.monero)),
fullscreenDialog: true); fullscreenDialog: true);
case Routes.restoreWalletType: case Routes.restoreWalletType:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<NewWalletTypePage>( builder: (_) => getIt.get<NewWalletTypePage>(
param1: (BuildContext context, WalletType type) => param1: (BuildContext context, WalletType type) =>
Navigator.of(context) Navigator.of(context).pushNamed(Routes.restoreWallet, arguments: type),
.pushNamed(Routes.restoreWallet, arguments: type),
param2: false)); param2: false));
case Routes.restoreOptions: case Routes.restoreOptions:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<RestoreOptionsPage>());
builder: (_) => getIt.get<RestoreOptionsPage>());
case Routes.restoreWalletOptions: case Routes.restoreWalletOptions:
final type = WalletType.monero; //settings.arguments as WalletType; final type = WalletType.monero; //settings.arguments as WalletType;
@ -145,22 +139,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => RestoreWalletOptionsPage( builder: (_) => RestoreWalletOptionsPage(
type: type, type: type,
onRestoreFromSeed: (context) { onRestoreFromSeed: (context) {
final route = type == WalletType.monero final route = type == WalletType.monero ? Routes.seedLanguage : Routes.restoreWalletFromSeed;
? Routes.seedLanguage final args = type == WalletType.monero ? [type, Routes.restoreWalletFromSeed] : [type];
: Routes.restoreWalletFromSeed;
final args = type == WalletType.monero
? [type, Routes.restoreWalletFromSeed]
: [type];
Navigator.of(context).pushNamed(route, arguments: args); Navigator.of(context).pushNamed(route, arguments: args);
}, },
onRestoreFromKeys: (context) { onRestoreFromKeys: (context) {
final route = type == WalletType.monero final route = type == WalletType.monero ? Routes.seedLanguage : Routes.restoreWalletFromKeys;
? Routes.seedLanguage final args = type == WalletType.monero ? [type, Routes.restoreWalletFromKeys] : [type];
: Routes.restoreWalletFromKeys;
final args = type == WalletType.monero
? [type, Routes.restoreWalletFromKeys]
: [type];
Navigator.of(context).pushNamed(route, arguments: args); Navigator.of(context).pushNamed(route, arguments: args);
})); }));
@ -169,76 +155,58 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>( builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) => param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
Navigator.pushNamed( Navigator.pushNamed(context.context, Routes.restoreWalletType)),
context.context, Routes.restoreWalletType)),
fullscreenDialog: true); fullscreenDialog: true);
case Routes.seed: case Routes.seed:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<WalletSeedPage>(param1: settings.arguments as bool));
builder: (_) =>
getIt.get<WalletSeedPage>(param1: settings.arguments as bool));
case Routes.restoreWallet: case Routes.restoreWallet:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => getIt.get<WalletRestorePage>( builder: (_) => getIt.get<WalletRestorePage>(param1: settings.arguments as WalletType));
param1: settings.arguments as WalletType));
case Routes.restoreWalletFromSeed: case Routes.restoreWalletFromSeed:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => RestoreWalletFromSeedPage(type: type));
builder: (_) => RestoreWalletFromSeedPage(type: type));
case Routes.restoreWalletFromKeys: case Routes.restoreWalletFromKeys:
final args = settings.arguments as List<dynamic>; final args = settings.arguments as List<dynamic>;
final type = args.first as WalletType; final type = args.first as WalletType;
final language = final language = type == WalletType.monero ? args[1] as String : LanguageList.english;
type == WalletType.monero ? args[1] as String : LanguageList.english;
final walletRestorationFromKeysVM = final walletRestorationFromKeysVM = getIt.get<WalletRestorationFromKeysVM>(param1: [type, language]);
getIt.get<WalletRestorationFromKeysVM>(param1: [type, language]);
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletFromKeysPage( builder: (_) => RestoreWalletFromKeysPage(walletRestorationFromKeysVM: walletRestorationFromKeysVM));
walletRestorationFromKeysVM: walletRestorationFromKeysVM));
case Routes.dashboard: case Routes.dashboard:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<DashboardPage>());
builder: (_) => getIt.get<DashboardPage>());
case Routes.send: case Routes.send:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<SendPage>());
fullscreenDialog: true, builder: (_) => getIt.get<SendPage>());
case Routes.sendTemplate: case Routes.sendTemplate:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<SendTemplatePage>());
fullscreenDialog: true,
builder: (_) => getIt.get<SendTemplatePage>());
case Routes.receive: case Routes.receive:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<ReceivePage>());
fullscreenDialog: true, builder: (_) => getIt.get<ReceivePage>());
case Routes.addressPage: case Routes.addressPage:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<AddressPage>());
fullscreenDialog: true, builder: (_) => getIt.get<AddressPage>());
case Routes.transactionDetails: case Routes.transactionDetails:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true, fullscreenDialog: true,
builder: (_) => getIt.get<TransactionDetailsPage>( builder: (_) => getIt.get<TransactionDetailsPage>(param1: settings.arguments as TransactionInfo));
param1: settings.arguments as TransactionInfo));
case Routes.newSubaddress: case Routes.newSubaddress:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<AddressEditOrCreatePage>(param1: settings.arguments));
builder: (_) =>
getIt.get<AddressEditOrCreatePage>(param1: settings.arguments));
case Routes.disclaimer: case Routes.disclaimer:
return CupertinoPageRoute<void>(builder: (_) => DisclaimerPage()); return CupertinoPageRoute<void>(builder: (_) => DisclaimerPage());
case Routes.readDisclaimer: case Routes.readDisclaimer:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => DisclaimerPage(isReadOnly: true));
builder: (_) => DisclaimerPage(isReadOnly: true));
case Routes.seedLanguage: case Routes.seedLanguage:
final args = settings.arguments as List<dynamic>; final args = settings.arguments as List<dynamic>;
@ -247,114 +215,87 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>(builder: (_) { return CupertinoPageRoute<void>(builder: (_) {
return SeedLanguage( return SeedLanguage(
onConfirm: (context, lang) => Navigator.of(context) onConfirm: (context, lang) =>
.popAndPushNamed(redirectRoute, arguments: [type, lang])); Navigator.of(context).popAndPushNamed(redirectRoute, arguments: [type, lang]));
}); });
case Routes.walletList: case Routes.walletList:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
fullscreenDialog: true, builder: (_) => getIt.get<WalletListPage>());
case Routes.auth: case Routes.auth:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
fullscreenDialog: true, fullscreenDialog: true,
builder: (_) => getIt.get<AuthPage>( builder: (_) => getIt.get<AuthPage>(param1: settings.arguments as OnAuthenticationFinished, param2: true));
param1: settings.arguments as OnAuthenticationFinished,
param2: true));
case Routes.unlock: case Routes.unlock:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
fullscreenDialog: true, fullscreenDialog: true,
builder: (_) => WillPopScope( builder: (_) => WillPopScope(
child: getIt.get<AuthPage>( child: getIt.get<AuthPage>(param1: settings.arguments as OnAuthenticationFinished, param2: false),
param1: settings.arguments as OnAuthenticationFinished,
param2: false),
onWillPop: () async => false)); onWillPop: () async => false));
case Routes.nodeList: case Routes.nodeList:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<NodeListPage>());
builder: (_) => getIt.get<NodeListPage>());
case Routes.newNode: case Routes.newNode:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<NodeCreateOrEditPage>());
builder: (_) => getIt.get<NodeCreateOrEditPage>());
case Routes.login: case Routes.login:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (context) => WillPopScope( builder: (context) => WillPopScope(
child: getIt.get<AuthPage>(instanceName: 'login'), child: getIt.get<AuthPage>(instanceName: 'login'),
onWillPop: () => onWillPop: () => SystemChannels.platform.invokeMethod('SystemNavigator.pop')),
SystemChannels.platform.invokeMethod('SystemNavigator.pop')),
fullscreenDialog: true); fullscreenDialog: true);
case Routes.accountCreation: case Routes.accountCreation:
return CupertinoPageRoute<String>( return CupertinoPageRoute<String>(
builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>( builder: (_) => getIt.get<MoneroAccountEditOrCreatePage>(param1: settings.arguments as AccountListItem));
param1: settings.arguments as AccountListItem));
case Routes.addressBook: case Routes.addressBook:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<ContactListPage>(param1: true));
builder: (_) => getIt.get<ContactListPage>(param1: true));
case Routes.pickerAddressBook: case Routes.pickerAddressBook:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<ContactListPage>(param1: false));
builder: (_) => getIt.get<ContactListPage>(param1: false));
case Routes.addressBookAddContact: case Routes.addressBookAddContact:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<ContactPage>( builder: (_) => getIt.get<ContactPage>(param1: settings.arguments as ContactRecord));
param1: settings.arguments as ContactRecord));
case Routes.showKeys: case Routes.showKeys:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<WalletKeysPage>(), fullscreenDialog: true);
builder: (_) => getIt.get<WalletKeysPage>(), fullscreenDialog: true);
case Routes.exchangeTrade: case Routes.exchangeTrade:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTradePage>());
builder: (_) => getIt.get<ExchangeTradePage>());
case Routes.exchangeConfirm: case Routes.exchangeConfirm:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<ExchangeConfirmPage>());
builder: (_) => getIt.get<ExchangeConfirmPage>());
case Routes.tradeDetails: case Routes.tradeDetails:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
builder: (_) =>
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
case Routes.orderDetails: case Routes.orderDetails:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
builder: (_) =>
getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
case Routes.preOrder: case Routes.preOrder:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<PreOrderPage>());
builder: (_) =>
getIt.get<PreOrderPage>());
case Routes.buyWebView: case Routes.buyWebView:
final args = settings.arguments as List; final args = settings.arguments as List;
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<BuyWebViewPage>(param1: args));
builder: (_) =>
getIt.get<BuyWebViewPage>(param1: args));
case Routes.restoreWalletFromSeedDetails: case Routes.restoreWalletFromSeedDetails:
final args = settings.arguments as List; final args = settings.arguments as List;
final walletRestorationFromSeedVM = final walletRestorationFromSeedVM = getIt.get<WalletRestorationFromSeedVM>(param1: args);
getIt.get<WalletRestorationFromSeedVM>(param1: args);
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletFromSeedDetailsPage( builder: (_) => RestoreWalletFromSeedDetailsPage(walletRestorationFromSeedVM: walletRestorationFromSeedVM));
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
case Routes.exchange: case Routes.exchange:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangePage>());
builder: (_) => getIt.get<ExchangePage>());
case Routes.exchangeTemplate: case Routes.exchangeTemplate:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTemplatePage>());
builder: (_) => getIt.get<ExchangeTemplatePage>());
case Routes.settings: case Routes.settings:
return MaterialPageRoute<void>(builder: (_) => getIt.get<SettingsPage>()); return MaterialPageRoute<void>(builder: (_) => getIt.get<SettingsPage>());
@ -366,44 +307,33 @@ Route<dynamic> createRoute(RouteSettings settings) {
return MaterialPageRoute<void>(builder: (_) => getIt.get<FaqPage>()); return MaterialPageRoute<void>(builder: (_) => getIt.get<FaqPage>());
case Routes.preSeed: case Routes.preSeed:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<PreSeedPage>(param1: settings.arguments as WalletType));
builder: (_) =>
getIt.get<PreSeedPage>(param1: settings.arguments as WalletType));
case Routes.backup: case Routes.backup:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(fullscreenDialog: true, builder: (_) => getIt.get<BackupPage>());
fullscreenDialog: true, builder: (_) => getIt.get<BackupPage>());
case Routes.editBackupPassword: case Routes.editBackupPassword:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<EditBackupPasswordPage>());
builder: (_) => getIt.get<EditBackupPasswordPage>());
case Routes.restoreFromBackup: case Routes.restoreFromBackup:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<RestoreFromBackupPage>());
builder: (_) => getIt.get<RestoreFromBackupPage>());
case Routes.support: case Routes.support:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<SupportPage>());
builder: (_) => getIt.get<SupportPage>());
case Routes.unspentCoinsList: case Routes.unspentCoinsList:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<UnspentCoinsListPage>());
builder: (_) => getIt.get<UnspentCoinsListPage>());
case Routes.unspentCoinsDetails: case Routes.unspentCoinsDetails:
final args = settings.arguments as List; final args = settings.arguments as List;
return MaterialPageRoute<void>( return MaterialPageRoute<void>(builder: (_) => getIt.get<UnspentCoinsDetailsPage>(param1: args));
builder: (_) =>
getIt.get<UnspentCoinsDetailsPage>(
param1: args));
case Routes.fullscreenQR: case Routes.fullscreenQR:
final args = settings.arguments as Map<String, dynamic>; final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => builder: (_) => getIt.get<FullscreenQRPage>(
getIt.get<FullscreenQRPage>(
param1: args['qrData'] as String, param1: args['qrData'] as String,
param2: args['isLight'] as bool, param2: args['isLight'] as bool,
)); ));
@ -446,10 +376,17 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => ActiveServicesPage(), builder: (_) => ActiveServicesPage(),
); );
case Routes.numberSettings:
return MaterialPageRoute<NumberSettingsPage>(
settings: RouteSettings(name: Routes.numberSettings),
builder: (_) => NumberSettingsPage(
phoneNumberService: settings.arguments as PhoneNumberService,
phonePlanViewModel: getIt.get<PhonePlanViewModel>(),
),
);
default: default:
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => Scaffold( builder: (_) => Scaffold(body: Center(child: Text(S.current.router_no_route(settings.name)))));
body: Center(
child: Text(S.current.router_no_route(settings.name)))));
} }
} }

View file

@ -66,4 +66,5 @@ class Routes {
static const cakePhoneProducts = '/cake_phone_products'; static const cakePhoneProducts = '/cake_phone_products';
static const phoneNumberProduct = '/phone_number_product'; static const phoneNumberProduct = '/phone_number_product';
static const cakePhoneActiveServices = '/cake_phone_active_services'; static const cakePhoneActiveServices = '/cake_phone_active_services';
static const numberSettings = '/number_settings';
} }

View file

@ -7,7 +7,6 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:cake_wallet/view_model/cake_phone/phone_plan_view_model.dart'; import 'package:cake_wallet/view_model/cake_phone/phone_plan_view_model.dart';
import 'package:country_pickers/country.dart'; import 'package:country_pickers/country.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -48,14 +47,10 @@ class PhoneNumberProductBody extends StatefulWidget {
final PhonePlanViewModel phonePlanViewModel; final PhonePlanViewModel phonePlanViewModel;
@override @override
PhoneNumberProductBodyState createState() => PhoneNumberProductBodyState(phonePlanViewModel); PhoneNumberProductBodyState createState() => PhoneNumberProductBodyState();
} }
class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> { class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
PhoneNumberProductBodyState(this.phonePlanViewModel);
final PhonePlanViewModel phonePlanViewModel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -94,7 +89,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row( child: Row(
children: phonePlanViewModel.servicePlans.map((e) => planCard(e)).toList(), children: widget.phonePlanViewModel.servicePlans.map((e) => planCard(e)).toList(),
), ),
), ),
); );
@ -123,9 +118,9 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
), ),
child: Observer(builder: (_) { child: Observer(builder: (_) {
return Text( return Text(
"${phonePlanViewModel.selectedPlan.quantity}, " + "${widget.phonePlanViewModel.selectedPlan.quantity}, " +
"${S.of(context).then} " + "${S.of(context).then} " +
"\$${(phonePlanViewModel.rateInCents / 100).toStringAsFixed(2)} " + "\$${(widget.phonePlanViewModel.rateInCents / 100).toStringAsFixed(2)} " +
"${S.of(context).per_message}", "${S.of(context).per_message}",
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
@ -162,10 +157,10 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
final Country _country = country as Country; final Country _country = country as Country;
return "${_country.name} (+${_country.phoneCode})"; return "${_country.name} (+${_country.phoneCode})";
}, },
selectedAtIndex: countryList.indexOf(phonePlanViewModel.selectedCountry), selectedAtIndex: countryList.indexOf(widget.phonePlanViewModel.selectedCountry),
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
onItemSelected: (Country country) { onItemSelected: (Country country) {
phonePlanViewModel.selectedCountry = country; widget.phonePlanViewModel.selectedCountry = country;
}, },
images: countryList images: countryList
.map((e) => Image.asset( .map((e) => Image.asset(
@ -193,7 +188,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
return Row( return Row(
children: [ children: [
Image.asset( Image.asset(
CountryPickerUtils.getFlagImageAssetPath(phonePlanViewModel.selectedCountry.isoCode), CountryPickerUtils.getFlagImageAssetPath(widget.phonePlanViewModel.selectedCountry.isoCode),
height: 20.0, height: 20.0,
width: 36.0, width: 36.0,
fit: BoxFit.fill, fit: BoxFit.fill,
@ -206,7 +201,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 8, right: 6), padding: const EdgeInsets.only(left: 8, right: 6),
child: Text( child: Text(
phonePlanViewModel.selectedCountry.name, widget.phonePlanViewModel.selectedCountry.name,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@ -216,7 +211,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
), ),
), ),
Text( Text(
"(+${phonePlanViewModel.selectedCountry.phoneCode})", "(+${widget.phonePlanViewModel.selectedCountry.phoneCode})",
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@ -254,7 +249,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
child: Row( child: Row(
children: [ children: [
GestureDetector( GestureDetector(
onTap: () => phonePlanViewModel.removeAdditionalSms(), onTap: () => widget.phonePlanViewModel.removeAdditionalSms(),
child: Container( child: Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
margin: const EdgeInsets.all(4), margin: const EdgeInsets.all(4),
@ -269,7 +264,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Observer(builder: (_) { child: Observer(builder: (_) {
return Text( return Text(
phonePlanViewModel.additionalSms.toString(), widget.phonePlanViewModel.additionalSms.toString(),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
@ -279,7 +274,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
}), }),
), ),
GestureDetector( GestureDetector(
onTap: () => phonePlanViewModel.addAdditionalSms(), onTap: () => widget.phonePlanViewModel.addAdditionalSms(),
child: Container( child: Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
margin: const EdgeInsets.all(4), margin: const EdgeInsets.all(4),
@ -309,7 +304,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
children: [ children: [
TextSpan(text: "${S.of(context).due_today} "), TextSpan(text: "${S.of(context).due_today} "),
TextSpan( TextSpan(
text: "\$${phonePlanViewModel.totalPrice}", text: "\$${widget.phonePlanViewModel.totalPrice}",
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: Theme.of(context).primaryTextTheme.title.color, color: Theme.of(context).primaryTextTheme.title.color,
@ -336,7 +331,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
contentWidget: Column( contentWidget: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
receiptRow(S.of(context).amount, amountText(phonePlanViewModel.totalPrice)), receiptRow(S.of(context).amount, amountText(widget.phonePlanViewModel.totalPrice)),
receiptRow("${S.of(context).cake_pay_balance}: ", amountText(100)), receiptRow("${S.of(context).cake_pay_balance}: ", amountText(100)),
], ],
), ),
@ -370,7 +365,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
contentWidget: Column( contentWidget: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
receiptRow(S.of(context).amount, cryptoAmount(phonePlanViewModel.totalPrice)), receiptRow(S.of(context).amount, cryptoAmount(widget.phonePlanViewModel.totalPrice)),
receiptRow( receiptRow(
S.of(context).send_fee, S.of(context).send_fee,
cryptoAmount(getIt cryptoAmount(getIt
@ -378,7 +373,7 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
.wallet .wallet
.calculateEstimatedFee( .calculateEstimatedFee(
getIt.get<AppStore>().settingsStore.priority[getIt.get<AppStore>().wallet.type], getIt.get<AppStore>().settingsStore.priority[getIt.get<AppStore>().wallet.type],
phonePlanViewModel.totalPrice.floor(), widget.phonePlanViewModel.totalPrice.floor(),
) )
.toDouble())), .toDouble())),
], ],
@ -403,11 +398,11 @@ class PhoneNumberProductBodyState extends State<PhoneNumberProductBody> {
} }
Widget planCard(ServicePlan e) { Widget planCard(ServicePlan e) {
final isSelected = phonePlanViewModel.selectedPlan == e; final isSelected = widget.phonePlanViewModel.selectedPlan == e;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
if (!isSelected) { if (!isSelected) {
phonePlanViewModel.selectedPlan = e; widget.phonePlanViewModel.selectedPlan = e;
} }
}, },
child: Container( child: Container(

View file

@ -0,0 +1,186 @@
import 'package:cake_wallet/entities/cake_phone_entities/service_plan.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/view_model/cake_phone/phone_plan_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/standart_switch.dart';
import 'package:cake_wallet/entities/cake_phone_entities/phone_number_service.dart';
class NumberSettingsPage extends BasePage {
NumberSettingsPage({@required this.phoneNumberService, @required this.phonePlanViewModel});
final PhoneNumberService phoneNumberService;
final PhonePlanViewModel phonePlanViewModel;
@override
Widget body(BuildContext context) => NumberSettingsBody(phoneNumberService, phonePlanViewModel);
@override
Widget middle(BuildContext context) {
return Text(
S.of(context).number_settings,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
fontFamily: 'Lato',
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color),
);
}
}
class NumberSettingsBody extends StatefulWidget {
NumberSettingsBody(this.phoneNumberService, this.phonePlanViewModel);
final PhoneNumberService phoneNumberService;
final PhonePlanViewModel phonePlanViewModel;
@override
NumberSettingsBodyState createState() => NumberSettingsBodyState();
}
class NumberSettingsBodyState extends State<NumberSettingsBody> {
ServicePlan selectedPhoneNumberPlan;
bool blockIncomingSMS = true;
@override
void initState() {
super.initState();
try {
selectedPhoneNumberPlan = widget.phonePlanViewModel.servicePlans
.firstWhere((element) => element.id == widget.phoneNumberService.planId);
} catch (err) {
// the current phone plan is no longer available so check for nullability
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(24, 60, 24, 20),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
numberSettingsTile(
title: S.of(context).phone_number,
value: Text(
widget.phoneNumberService.phoneNumber,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).primaryTextTheme.title.color,
),
),
),
numberSettingsTile(
title: S.of(context).auto_renew_settings,
value: InkWell(
onTap: () {},
child: Row(
children: [
Expanded(
child: Text(
"${S.of(context).renews_every} ${selectedPhoneNumberPlan?.duration ?? 0} ${S.of(context).month} " +
"${S.of(context).for_amount} \$${selectedPhoneNumberPlan?.price ?? 0}",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).primaryTextTheme.title.color,
),
),
),
Icon(
Icons.arrow_forward_ios,
color: Theme.of(context).primaryTextTheme.title.color,
size: 16,
),
],
),
),
),
numberSettingsTile(
title: S.of(context).manually_add_balance,
value: InkWell(
onTap: () {},
child: Row(
children: [
Expanded(
child: Text(
"${widget.phoneNumberService.usedUntil.difference(DateTime.now()).inDays} ${S.of(context).days_of_service_remaining}",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700,
color: Theme.of(context).primaryTextTheme.title.color,
),
),
),
Icon(
Icons.arrow_forward_ios,
color: Theme.of(context).primaryTextTheme.title.color,
size: 16,
),
],
),
),
),
numberSettingsTile(
value: Row(
children: [
Expanded(
child: Text(
S.of(context).block_incoming_sms,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color,
),
),
),
StandartSwitch(
value: blockIncomingSMS,
onTaped: () {
// TODO: block and unblock incoming sms
blockIncomingSMS = !blockIncomingSMS;
// TODO: remove setState and wrap with observer after creating the view model
setState(() {});
},
),
],
),
),
],
),
),
);
}
Widget numberSettingsTile({String title, @required Widget value}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null)
Text(
title,
style: TextStyle(
color: Theme.of(context).accentTextTheme.subhead.color,
),
),
Container(
padding: const EdgeInsets.only(top: 8, bottom: 16),
width: double.infinity,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context).accentTextTheme.title.backgroundColor,
),
),
),
child: value,
),
const SizedBox(height: 24),
],
);
}
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/routes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/entities/cake_phone_entities/phone_number_service.dart'; import 'package:cake_wallet/entities/cake_phone_entities/phone_number_service.dart';
@ -14,10 +15,14 @@ class SubscribedPhoneNumbers extends StatefulWidget {
class _SubscribedPhoneNumbersState extends State<SubscribedPhoneNumbers> { class _SubscribedPhoneNumbersState extends State<SubscribedPhoneNumbers> {
int selectedTab = 0; int selectedTab = 0;
final List<PhoneNumberService> subscribedPhoneNumbers = [ final List<PhoneNumberService> subscribedPhoneNumbers = [
PhoneNumberService(id: "1", phoneNumber: "+1 888-888-8888", usedUntil: DateTime.now().add(Duration(days: 24))), PhoneNumberService(
PhoneNumberService(id: "2", phoneNumber: "+1 888-888-8888", usedUntil: DateTime.now().add(Duration(days: 26))), id: "1", planId: "1", phoneNumber: "+1 888-888-8888", usedUntil: DateTime.now().add(Duration(days: 24))),
PhoneNumberService(id: "3", phoneNumber: "+1 999-999-9999", usedUntil: DateTime.now().subtract(Duration(days: 24))), PhoneNumberService(
PhoneNumberService(id: "4", phoneNumber: "+1 999-999-9999", usedUntil: DateTime.now().subtract(Duration(days: 26))), id: "2", planId: "2", phoneNumber: "+1 888-888-8888", usedUntil: DateTime.now().add(Duration(days: 26))),
PhoneNumberService(
id: "3", planId: "3", phoneNumber: "+1 999-999-9999", usedUntil: DateTime.now().subtract(Duration(days: 24))),
PhoneNumberService(
id: "4", planId: "4", phoneNumber: "+1 999-999-9999", usedUntil: DateTime.now().subtract(Duration(days: 26))),
]; ];
final List<PhoneNumberService> activePhoneNumbers = []; final List<PhoneNumberService> activePhoneNumbers = [];
@ -66,6 +71,9 @@ class _SubscribedPhoneNumbersState extends State<SubscribedPhoneNumbers> {
? "${e.usedUntil.difference(DateTime.now()).inDays} ${S.of(context).days_of_service_remaining}" ? "${e.usedUntil.difference(DateTime.now()).inDays} ${S.of(context).days_of_service_remaining}"
: S.of(context).expired, : S.of(context).expired,
), ),
onTap: () {
Navigator.pushNamed(context, Routes.numberSettings, arguments: e);
},
), ),
), ),
), ),

View file

@ -575,5 +575,11 @@
"free_data_balance": "Free Data Balance", "free_data_balance": "Free Data Balance",
"account_balance": "Account Balance", "account_balance": "Account Balance",
"days_of_service_remaining": "days of service remaining", "days_of_service_remaining": "days of service remaining",
"active": "Active" "active": "Active",
"number_settings": "Number Settings",
"auto_renew_settings": "Auto Renew Settings",
"renews_every": "Renews every",
"for_amount": "for",
"manually_add_balance": "Manually Add Balance",
"block_incoming_sms": "Block incoming SMS"
} }