CAKE-306 | applied buy_webview_page.dart to the app; fixed order_details_view_model.dart and order_row.dart; applied localization to the pre_order_page.dart; deleted unused files
OleksandrSobol committed
Apr 13, 2021 at 21:40 UTC
19ffffa6ccd9462cc2722b841a8c236971801448
31 files changed
+310
-398
lib/buy/buy_provider.dart
+1
@@ -12,6 +12,7 @@ abstract class BuyProvider {
12
13
String get title;
14
BuyProviderDescription get description;
15
+ String get trackUrl;
16
17
WalletType get walletType => wallet.type;
18
String get walletAddress => wallet.address;
lib/buy/get_buy_provider_icon.dart
new
+23
@@ -0,0 +1,23 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:cake_wallet/buy/buy_provider_description.dart';
3
+
4
+Image getBuyProviderIcon(BuyProviderDescription providerDescription) {
5
+ final _wyreIcon =
6
+ Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
7
+ final _moonPayIcon =
8
+ Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
9
+
10
+ if (providerDescription != null) {
11
+ switch (providerDescription) {
12
+ case BuyProviderDescription.wyre:
13
+ return _wyreIcon;
14
+ case BuyProviderDescription.moonPay:
15
+ //return _moonPayIcon;
16
+ return null;
17
+ default:
18
+ return null;
19
+ }
20
+ } else {
21
+ return null;
22
+ }
23
+}
\ No newline at end of file
lib/buy/moonpay/moonpay_buy_provider.dart
+5
@@ -34,6 +34,11 @@ class MoonPayBuyProvider extends BuyProvider {
34
String get currencyCode =>
35
walletTypeToCryptoCurrency(walletType).title.toLowerCase();
36
37
+ @override
38
+ String get trackUrl => isTestEnvironment
39
+ ? ''
40
+ : ''; // FIXME
41
+
42
String baseApiUrl;
43
44
@override
lib/buy/wyre/wyre_buy_provider.dart
+5
-4
@@ -16,9 +16,6 @@ class WyreBuyProvider extends BuyProvider {
16
baseApiUrl = isTestEnvironment
17
? _baseTestApiUrl
18
: _baseProductApiUrl;
19
- trackUrl = isTestEnvironment
20
- ? _trackTestUrl
21
- : _trackProductUrl;
19
}
20
21
static const _baseTestApiUrl = 'https://api.testwyre.com';
@@ -40,8 +37,12 @@ class WyreBuyProvider extends BuyProvider {
37
@override
38
BuyProviderDescription get description => BuyProviderDescription.wyre;
39
40
+ @override
41
+ String get trackUrl => isTestEnvironment
42
+ ? _trackTestUrl
43
+ : _trackProductUrl;
44
+
45
String baseApiUrl;
44
- String trackUrl;
46
47
@override
48
Future<String> requestUrl(String amount, String sourceCurrency) async {
lib/di.dart
+13
-22
@@ -7,7 +7,6 @@ import 'package:cake_wallet/entities/load_current_wallet.dart';
7
import 'package:cake_wallet/buy/order.dart';
8
import 'package:cake_wallet/entities/transaction_description.dart';
9
import 'package:cake_wallet/entities/transaction_info.dart';
10
-import 'package:cake_wallet/entities/wyre_service.dart';
10
import 'package:cake_wallet/monero/monero_wallet_service.dart';
11
import 'package:cake_wallet/entities/contact.dart';
12
import 'package:cake_wallet/entities/node.dart';
@@ -15,6 +14,7 @@ import 'package:cake_wallet/exchange/trade.dart';
14
import 'package:cake_wallet/reactions/on_authentication_state_change.dart';
15
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
16
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
17
+import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
18
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
19
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
20
import 'package:cake_wallet/src/screens/contact/contact_page.dart';
@@ -42,7 +42,6 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
42
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
43
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
44
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
45
-import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
45
import 'package:cake_wallet/store/dashboard/orders_store.dart';
46
import 'package:cake_wallet/store/node_list_store.dart';
47
import 'package:cake_wallet/store/secret_store.dart';
@@ -91,7 +90,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
90
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
91
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
92
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
94
-import 'package:cake_wallet/view_model/wyre_view_model.dart';
93
import 'package:flutter/widgets.dart';
94
import 'package:get_it/get_it.dart';
95
import 'package:hive/hive.dart';
@@ -241,8 +239,7 @@ Future setup(
239
transactionFilterStore: getIt.get<TransactionFilterStore>(),
240
settingsStore: settingsStore,
241
ordersSource: _ordersSource,
244
- ordersStore: getIt.get<OrdersStore>(),
245
- wyreViewModel: getIt.get<WyreViewModel>()));
242
+ ordersStore: getIt.get<OrdersStore>()));
243
244
getIt.registerFactory<AuthService>(() => AuthService(
245
secureStorage: getIt.get<FlutterSecureStorage>(),
@@ -534,20 +531,6 @@ Future setup(
531
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
532
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
533
537
- getIt.registerFactory(() {
538
- final wallet = getIt.get<AppStore>().wallet;
539
- return WyreService(wallet: wallet);
540
- });
541
-
542
- getIt.registerFactory(() {
543
- return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
544
- wyreService: getIt.get<WyreService>());
545
- });
546
-
547
- getIt.registerFactoryParam<WyrePage, String, void>((String url, _) =>
548
- WyrePage(getIt.get<WyreViewModel>(),
549
- ordersStore: getIt.get<OrdersStore>(), url: url));
550
-
534
getIt.registerFactory(() => BuyAmountViewModel());
535
536
getIt.registerFactory(() {
@@ -561,10 +544,18 @@ Future setup(
544
return PreOrderPage(buyViewModel: getIt.get<BuyViewModel>());
545
});
546
547
+ getIt.registerFactoryParam<BuyWebViewPage, String, void>((String url, _) =>
548
+ BuyWebViewPage(getIt.get<BuyViewModel>(),
549
+ ordersStore: getIt.get<OrdersStore>(), url: url));
550
+
551
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
565
- (order, _) => OrderDetailsViewModel(
566
- wyreViewModel: getIt.get<WyreViewModel>(),
567
- orderForDetails: order));
552
+ (order, _) {
553
+ final wallet = getIt.get<AppStore>().wallet;
554
+
555
+ return OrderDetailsViewModel(
556
+ wallet: wallet,
557
+ orderForDetails: order);
558
+ });
559
560
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
561
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
lib/entities/wyre_exception.dart
deleted
-8
@@ -1,8 +0,0 @@
1
-class WyreException implements Exception {
2
- WyreException(this.description);
3
-
4
- String description;
5
-
6
- @override
7
- String toString() => description;
8
-}
\ No newline at end of file
lib/entities/wyre_service.dart
deleted
-151
@@ -1,151 +0,0 @@
1
-import 'dart:convert';
2
-import 'package:cake_wallet/core/wallet_base.dart';
3
-import 'package:cake_wallet/entities/wyre_exception.dart';
4
-import 'package:cake_wallet/exchange/trade_state.dart';
5
-import 'package:flutter/foundation.dart';
6
-import 'package:http/http.dart';
7
-import 'package:cake_wallet/.secrets.g.dart' as secrets;
8
-import 'package:cake_wallet/buy/order.dart';
9
-import 'package:cake_wallet/entities/wallet_type.dart';
10
-
11
-class WyreService {
12
- WyreService({
13
- @required this.wallet,
14
- this.isTestEnvironment = false}) {
15
- baseApiUrl = isTestEnvironment
16
- ? _baseTestApiUrl
17
- : _baseProductApiUrl;
18
- trackUrl = isTestEnvironment
19
- ? _trackTestUrl
20
- : _trackProductUrl;
21
- }
22
-
23
- static const _baseTestApiUrl = 'https://api.testwyre.com';
24
- static const _baseProductApiUrl = 'https://api.sendwyre.com';
25
- static const _trackTestUrl = 'https://dash.testwyre.com/track/';
26
- static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
27
- static const _ordersSuffix = '/v3/orders';
28
- static const _reserveSuffix = '/reserve';
29
- static const _quoteSuffix = '/quote/partner';
30
- static const _timeStampSuffix = '?timestamp=';
31
- static const _transferSuffix = '/v2/transfer/';
32
- static const _trackSuffix = '/track';
33
-
34
- final bool isTestEnvironment;
35
- final WalletBase wallet;
36
-
37
- WalletType get walletType => wallet.type;
38
- String get walletAddress => wallet.address;
39
- String get walletId => wallet.id;
40
-
41
- String baseApiUrl;
42
- String trackUrl;
43
-
44
- Future<String> getWyreUrl() async {
45
- final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
46
- final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
47
- _timeStampSuffix + timestamp;
48
- final secretKey = secrets.wyreSecretKey;
49
- final accountId = secrets.wyreAccountId;
50
- final body = {
51
- 'amount': '1',
52
- 'sourceCurrency': 'USD',
53
- 'destCurrency': walletTypeToCryptoCurrency(walletType).title,
54
- 'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
55
- 'referrerAccountId': accountId,
56
- 'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
57
- };
58
-
59
- final response = await post(url,
60
- headers: {
61
- 'Authorization': 'Bearer $secretKey',
62
- 'Content-Type': 'application/json',
63
- 'cache-control': 'no-cache'
64
- },
65
- body: json.encode(body));
66
-
67
- if (response.statusCode != 200) {
68
- throw WyreException('Url $url is not found!');
69
- }
70
-
71
- final responseJSON = json.decode(response.body) as Map<String, dynamic>;
72
- final urlFromResponse = responseJSON['url'] as String;
73
- return urlFromResponse;
74
- }
75
-
76
- Future<Order> findOrderById(String id) async {
77
- final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
78
- final orderResponse = await get(orderUrl);
79
-
80
- if (orderResponse.statusCode != 200) {
81
- throw WyreException('Order $id is not found!');
82
- }
83
-
84
- final orderResponseJSON =
85
- json.decode(orderResponse.body) as Map<String, dynamic>;
86
- final transferId = orderResponseJSON['transferId'] as String;
87
- final from = orderResponseJSON['sourceCurrency'] as String;
88
- final to = orderResponseJSON['destCurrency'] as String;
89
- final status = orderResponseJSON['status'] as String;
90
- final state = TradeState.deserialize(raw: status.toLowerCase());
91
- final createdAtRaw = orderResponseJSON['createdAt'] as int;
92
- final createdAt =
93
- DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
94
-
95
- final transferUrl =
96
- baseApiUrl + _transferSuffix + transferId + _trackSuffix;
97
- final transferResponse = await get(transferUrl);
98
-
99
- if (transferResponse.statusCode != 200) {
100
- throw WyreException('Transfer $transferId is not found!');
101
- }
102
-
103
- final transferResponseJSON =
104
- json.decode(transferResponse.body) as Map<String, dynamic>;
105
- final amount = transferResponseJSON['destAmount'] as double;
106
-
107
- return Order(
108
- id: id,
109
- transferId: transferId,
110
- from: from,
111
- to: to,
112
- state: state,
113
- createdAt: createdAt,
114
- amount: amount.toString(),
115
- receiveAddress: walletAddress,
116
- walletId: walletId
117
- );
118
- }
119
-
120
- Future<double> getAmount() async {
121
- final quoteUrl = baseApiUrl + _ordersSuffix + _quoteSuffix;
122
-
123
- final secretKey = secrets.wyreSecretKey;
124
- final accountId = secrets.wyreAccountId;
125
- final body = {
126
- 'amount': '1',
127
- 'sourceCurrency': 'USD',
128
- 'destCurrency': walletTypeToCryptoCurrency(walletType).title,
129
- 'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
130
- 'accountId': accountId,
131
- 'country': 'US'
132
- };
133
-
134
- final response = await post(quoteUrl,
135
- headers: {
136
- 'Authorization': 'Bearer $secretKey',
137
- 'Content-Type': 'application/json',
138
- 'cache-control': 'no-cache'
139
- },
140
- body: json.encode(body));
141
-
142
- if (response.statusCode != 200) {
143
- throw WyreException('Quote is not found! ');
144
- }
145
-
146
- final responseJSON = json.decode(response.body) as Map<String, dynamic>;
147
- final amount = responseJSON['destAmount'] as double;
148
-
149
- return amount;
150
- }
151
-}
\ No newline at end of file
lib/router.dart
+3
-3
@@ -3,6 +3,7 @@ import 'package:cake_wallet/buy/order.dart';
3
import 'package:cake_wallet/entities/transaction_description.dart';
4
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
5
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
6
+import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
7
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
8
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
9
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
@@ -10,7 +11,6 @@ import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
11
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
12
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
13
import 'package:cake_wallet/src/screens/support/support_page.dart';
13
-import 'package:cake_wallet/src/screens/wyre/wyre_page.dart';
14
import 'package:cake_wallet/store/settings_store.dart';
15
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
16
import 'package:flutter/cupertino.dart';
@@ -303,10 +303,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
303
builder: (_) =>
304
getIt.get<PreOrderPage>());
305
306
- case Routes.wyre:
306
+ case Routes.buyWebView:
307
return MaterialPageRoute<void>(
308
builder: (_) =>
309
- getIt.get<WyrePage>(param1: settings.arguments as String));
309
+ getIt.get<BuyWebViewPage>(param1: settings.arguments as String));
310
311
case Routes.restoreWalletFromSeedDetails:
312
final args = settings.arguments as List;
lib/routes.dart
+1
-1
@@ -53,6 +53,6 @@ class Routes {
53
static const restoreFromBackup = '/restore_from_backup';
54
static const support = '/support';
55
static const orderDetails = '/order_details';
56
- static const wyre = '/wyre';
56
static const preOrder = '/pre_order';
57
+ static const buyWebView = '/buy_web_view';
58
}
\ No newline at end of file
lib/src/screens/buy/buy_webview_page.dart
new
+108
@@ -0,0 +1,108 @@
1
+import 'dart:async';
2
+import 'dart:io';
3
+import 'package:cake_wallet/buy/buy_provider.dart';
4
+import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
5
+import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
6
+import 'package:cake_wallet/generated/i18n.dart';
7
+import 'package:cake_wallet/palette.dart';
8
+import 'package:cake_wallet/src/screens/base_page.dart';
9
+import 'package:cake_wallet/store/dashboard/orders_store.dart';
10
+import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
11
+import 'package:flutter/material.dart';
12
+import 'package:webview_flutter/webview_flutter.dart';
13
+
14
+class BuyWebViewPage extends BasePage {
15
+ BuyWebViewPage(this.buyViewModel,
16
+ {@required this.ordersStore, @required this.url});
17
+
18
+ final OrdersStore ordersStore;
19
+ final String url;
20
+ final BuyViewModel buyViewModel;
21
+
22
+ @override
23
+ String get title => S.current.buy;
24
+
25
+ @override
26
+ Color get backgroundDarkColor => Colors.white;
27
+
28
+ @override
29
+ Color get titleColor => Palette.darkBlueCraiola;
30
+
31
+ @override
32
+ Widget body(BuildContext context) =>
33
+ BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url);
34
+}
35
+
36
+class BuyWebViewPageBody extends StatefulWidget {
37
+ BuyWebViewPageBody(this.buyViewModel, {this.ordersStore, this.url});
38
+
39
+ final OrdersStore ordersStore;
40
+ final String url;
41
+ final BuyViewModel buyViewModel;
42
+
43
+ @override
44
+ BuyWebViewPageBodyState createState() => BuyWebViewPageBodyState();
45
+}
46
+
47
+class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
48
+ String orderId;
49
+ WebViewController _webViewController;
50
+ GlobalKey _webViewkey;
51
+ Timer _timer;
52
+ bool _isSaving;
53
+ BuyProvider _provider;
54
+
55
+ @override
56
+ void initState() {
57
+ super.initState();
58
+ _webViewkey = GlobalKey();
59
+ _isSaving = false;
60
+ widget.ordersStore.orderId = '';
61
+ _provider = widget.buyViewModel.selectedProvider;
62
+
63
+ if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
64
+
65
+ if (_provider is WyreBuyProvider) {
66
+ _timer?.cancel();
67
+ _timer = Timer.periodic(Duration(seconds: 1), (timer) async {
68
+
69
+ try {
70
+ if (_webViewController == null || _isSaving) {
71
+ return;
72
+ }
73
+
74
+ final url = await _webViewController.currentUrl();
75
+
76
+ if (url.contains('completed')) {
77
+ final urlParts = url.split('/');
78
+ orderId = urlParts.last;
79
+ widget.ordersStore.orderId = orderId;
80
+
81
+ if (orderId.isNotEmpty) {
82
+ _isSaving = true;
83
+ await widget.buyViewModel.saveOrder(orderId);
84
+ timer.cancel();
85
+ }
86
+ }
87
+ } catch (e) {
88
+ _isSaving = false;
89
+ print(e);
90
+ }
91
+ });
92
+ }
93
+
94
+ if (_provider is MoonPayBuyProvider) {
95
+ // FIXME: fetch orderId
96
+ }
97
+ }
98
+
99
+ @override
100
+ Widget build(BuildContext context) {
101
+ return WebView(
102
+ key: _webViewkey,
103
+ initialUrl: widget.url,
104
+ javascriptMode: JavascriptMode.unrestricted,
105
+ onWebViewCreated: (WebViewController controller) =>
106
+ setState(() => _webViewController = controller));
107
+ }
108
+}
lib/src/screens/buy/pre_order_page.dart
+23
-9
@@ -14,6 +14,7 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
14
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
15
import 'package:cake_wallet/generated/i18n.dart';
16
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
17
+import 'package:mobx/mobx.dart';
18
19
class PreOrderPage extends BasePage {
20
PreOrderPage({@required this.buyViewModel})
@@ -31,14 +32,22 @@ class PreOrderPage extends BasePage {
32
buyViewModel.selectedProvider = null;
33
}
34
});
35
+
36
+ reaction((_) => buyViewModel.buyAmountViewModel.amount, (String amount) {
37
+ if (_amountController.text != amount) {
38
+ _amountController.text = amount;
39
+ }
40
+ });
41
}
42
43
+ static const _amountPattern = '^([0-9]+([.\,][0-9]{0,2})?|[.\,][0-9]{1,2})\$';
44
+
45
final BuyViewModel buyViewModel;
46
final FocusNode _amountFocus;
47
final TextEditingController _amountController;
48
49
@override
41
- String get title => 'Buy Bitcoin';
50
+ String get title => S.current.buy_bitcoin;
51
52
@override
53
Color get titleColor => Colors.white;
@@ -96,7 +105,7 @@ class PreOrderPage extends BasePage {
105
signed: false, decimal: true),
106
inputFormatters: [
107
FilteringTextInputFormatter
99
- .allow(RegExp('^([0-9]+([.\,][0-9]{0,2})?|[.\,][0-9]{1,2})\$'))
108
+ .allow(RegExp(_amountPattern))
109
],
110
prefixIcon: Padding(
111
padding: EdgeInsets.only(top: 2),
@@ -130,7 +139,7 @@ class PreOrderPage extends BasePage {
139
Padding(
140
padding: EdgeInsets.only(top: 38, bottom: 18),
141
child: Text(
133
- 'Buy with:',
142
+ S.of(context).buy_with + ':',
143
textAlign: TextAlign.center,
144
style: TextStyle(
145
color: Theme.of(context).primaryTextTheme.title.color,
@@ -185,16 +194,21 @@ class PreOrderPage extends BasePage {
194
return LoadingPrimaryButton(
195
onPressed: buyViewModel.isRunning
196
? null
188
- : () {
197
+ : () async {
198
buyViewModel.isRunning = true;
190
-
191
- // FIXME: Start WebView
192
-
199
+ final url =
200
+ await buyViewModel.fetchUrl();
201
+ if (url.isNotEmpty) {
202
+ await Navigator.of(context)
203
+ .pushNamed(Routes.buyWebView, arguments: url);
204
+ buyViewModel.reset();
205
+ }
206
buyViewModel.isRunning = false;
207
},
208
text: buyViewModel.selectedProvider == null
196
- ? 'Buy'
197
- : 'Buy with ${buyViewModel.selectedProvider
209
+ ? S.of(context).buy
210
+ : S.of(context).buy_with +
211
+ ' ${buyViewModel.selectedProvider
212
.description.title}',
213
color: Theme.of(context).accentTextTheme.body2.color,
214
textColor: Colors.white,
lib/src/screens/buy/widgets/buy_list_item.dart
+2
-19
@@ -1,5 +1,5 @@
1
-import 'package:cake_wallet/buy/buy_provider_description.dart';
1
import 'package:cake_wallet/buy/buy_provider.dart';
2
+import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
3
import 'package:cake_wallet/entities/crypto_currency.dart';
4
import 'package:cake_wallet/entities/fiat_currency.dart';
5
import 'package:cake_wallet/palette.dart';
@@ -16,11 +16,6 @@ class BuyListItem extends StatelessWidget {
16
@required this.onTap
17
});
18
19
- final _wyreIcon =
20
- Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
21
- final _mooonPayIcon =
22
- Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
23
-
19
final BuyProvider selectedProvider;
20
final BuyProvider provider;
21
final double sourceAmount;
@@ -31,7 +26,7 @@ class BuyListItem extends StatelessWidget {
26
27
@override
28
Widget build(BuildContext context) {
34
- final providerIcon = _getProviderIcon(provider.description);
29
+ final providerIcon = getBuyProviderIcon(provider.description);
30
31
final backgroundColor = selectedProvider != null
32
? selectedProvider.description == provider.description
@@ -116,16 +111,4 @@ class BuyListItem extends StatelessWidget {
111
)
112
);
113
}
119
-
120
- Image _getProviderIcon(BuyProviderDescription providerDescription) {
121
- switch (providerDescription) {
122
- case BuyProviderDescription.wyre:
123
- return _wyreIcon;
124
- case BuyProviderDescription.moonPay:
125
- //return _mooonPayIcon;
126
- return null;
127
- default:
128
- return null;
129
- }
130
- }
114
}
\ No newline at end of file
lib/src/screens/dashboard/widgets/order_row.dart
+7
-3
@@ -1,22 +1,26 @@
1
+import 'package:cake_wallet/buy/buy_provider_description.dart';
2
+import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
3
import 'package:flutter/material.dart';
4
5
class OrderRow extends StatelessWidget {
6
OrderRow({
7
@required this.onTap,
8
+ @required this.provider,
9
this.from,
10
this.to,
11
this.createdAtFormattedDate,
12
this.formattedAmount});
13
final VoidCallback onTap;
14
+ final BuyProviderDescription provider;
15
final String from;
16
final String to;
17
final String createdAtFormattedDate;
18
final String formattedAmount;
15
- final wyreImage =
16
- Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
19
20
@override
21
Widget build(BuildContext context) {
22
+ final providerIcon = getBuyProviderIcon(provider);
23
+
24
return InkWell(
25
onTap: onTap,
26
child: Container(
@@ -26,7 +30,7 @@ class OrderRow extends StatelessWidget {
30
mainAxisSize: MainAxisSize.max,
31
crossAxisAlignment: CrossAxisAlignment.center,
32
children: [
29
- wyreImage,
33
+ providerIcon ?? Offstage(),
34
SizedBox(width: 12),
35
Expanded(
36
child: Column(
lib/src/screens/dashboard/widgets/transactions_page.dart
+1
@@ -84,6 +84,7 @@ class TransactionsPage extends StatelessWidget {
84
onTap: () => Navigator.of(context).pushNamed(
85
Routes.orderDetails,
86
arguments: order),
87
+ provider: order.provider,
88
from: order.from,
89
to: order.to,
90
createdAtFormattedDate:
lib/src/screens/wyre/wyre_page.dart
deleted
-97
@@ -1,97 +0,0 @@
1
-import 'dart:async';
2
-import 'dart:io';
3
-import 'package:cake_wallet/generated/i18n.dart';
4
-import 'package:cake_wallet/palette.dart';
5
-import 'package:cake_wallet/src/screens/base_page.dart';
6
-import 'package:cake_wallet/store/dashboard/orders_store.dart';
7
-import 'package:cake_wallet/view_model/wyre_view_model.dart';
8
-import 'package:flutter/material.dart';
9
-import 'package:webview_flutter/webview_flutter.dart';
10
-
11
-class WyrePage extends BasePage {
12
- WyrePage(this.wyreViewModel,
13
- {@required this.ordersStore, @required this.url});
14
-
15
- final OrdersStore ordersStore;
16
- final String url;
17
- final WyreViewModel wyreViewModel;
18
-
19
- @override
20
- String get title => S.current.buy;
21
-
22
- @override
23
- Color get backgroundDarkColor => Colors.white;
24
-
25
- @override
26
- Color get titleColor => Palette.darkBlueCraiola;
27
-
28
- @override
29
- Widget body(BuildContext context) =>
30
- WyrePageBody(wyreViewModel, ordersStore: ordersStore, url: url);
31
-}
32
-
33
-class WyrePageBody extends StatefulWidget {
34
- WyrePageBody(this.wyreViewModel, {this.ordersStore, this.url});
35
-
36
- final OrdersStore ordersStore;
37
- final String url;
38
- final WyreViewModel wyreViewModel;
39
-
40
- @override
41
- WyrePageBodyState createState() => WyrePageBodyState();
42
-}
43
-
44
-class WyrePageBodyState extends State<WyrePageBody> {
45
- String orderId;
46
- WebViewController _webViewController;
47
- GlobalKey _webViewkey;
48
- Timer _timer;
49
- bool _isSaving;
50
-
51
- @override
52
- void initState() {
53
- super.initState();
54
- _webViewkey = GlobalKey();
55
- _isSaving = false;
56
- widget.ordersStore.orderId = '';
57
-
58
- if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
59
-
60
- _timer?.cancel();
61
- _timer = Timer.periodic(Duration(seconds: 1), (timer) async {
62
-
63
- try {
64
- if (_webViewController == null || _isSaving) {
65
- return;
66
- }
67
-
68
- final url = await _webViewController.currentUrl();
69
-
70
- if (url.contains('completed')) {
71
- final urlParts = url.split('/');
72
- orderId = urlParts.last;
73
- widget.ordersStore.orderId = orderId;
74
-
75
- if (orderId.isNotEmpty) {
76
- _isSaving = true;
77
- await widget.wyreViewModel.saveOrder(orderId);
78
- timer.cancel();
79
- }
80
- }
81
- } catch (e) {
82
- _isSaving = false;
83
- print(e);
84
- }
85
- });
86
- }
87
-
88
- @override
89
- Widget build(BuildContext context) {
90
- return WebView(
91
- key: _webViewkey,
92
- initialUrl: widget.url,
93
- javascriptMode: JavascriptMode.unrestricted,
94
- onWebViewCreated: (WebViewController controller) =>
95
- setState(() => _webViewController = controller));
96
- }
97
-}
lib/view_model/buy/buy_view_model.dart
+11
-3
@@ -59,14 +59,17 @@ abstract class BuyViewModelBase with Store {
59
60
CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type);
61
62
- Future createOrder() async {
62
+ Future <String> fetchUrl() async {
63
+ String _url = '';
64
+
65
try {
64
- final url = await selectedProvider
66
+ _url = await selectedProvider
67
?.requestUrl(doubleAmount?.toString(), fiatCurrency.title);
66
- // FIXME: Start WebView
68
} catch (e) {
69
print(e.toString());
70
}
71
+
72
+ return _url;
73
}
74
75
Future<void> saveOrder(String orderId) async {
@@ -78,4 +81,9 @@ abstract class BuyViewModelBase with Store {
81
print(e.toString());
82
}
83
}
84
+
85
+ void reset() {
86
+ buyAmountViewModel.amount = '';
87
+ selectedProvider = null;
88
+ }
89
}
\ No newline at end of file
lib/view_model/dashboard/dashboard_view_model.dart
+1
-5
@@ -28,7 +28,6 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
28
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
29
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
30
import 'package:cake_wallet/view_model/dashboard/action_list_display_mode.dart';
31
-import 'package:cake_wallet/view_model/wyre_view_model.dart';
31
import 'package:crypto/crypto.dart';
32
import 'package:flutter/services.dart';
33
import 'package:hive/hive.dart';
@@ -59,8 +58,7 @@ abstract class DashboardViewModelBase with Store {
58
this.transactionFilterStore,
59
this.settingsStore,
60
this.ordersSource,
62
- this.ordersStore,
63
- this.wyreViewModel}) {
61
+ this.ordersStore}) {
62
filterItems = {
63
S.current.transactions: [
64
FilterItem(
@@ -230,8 +228,6 @@ abstract class DashboardViewModelBase with Store {
228
229
TransactionFilterStore transactionFilterStore;
230
233
- WyreViewModel wyreViewModel;
234
-
231
Map<String, List<FilterItem>> filterItems;
232
233
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
lib/view_model/order_details_view_model.dart
+58
-27
@@ -1,12 +1,16 @@
1
import 'dart:async';
2
+import 'package:cake_wallet/buy/buy_provider.dart';
3
+import 'package:cake_wallet/buy/buy_provider_description.dart';
4
import 'package:cake_wallet/buy/order.dart';
5
import 'package:cake_wallet/utils/date_formatter.dart';
4
-import 'package:cake_wallet/view_model/wyre_view_model.dart';
6
import 'package:mobx/mobx.dart';
7
import 'package:cake_wallet/generated/i18n.dart';
8
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
9
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
10
import 'package:url_launcher/url_launcher.dart';
11
+import 'package:cake_wallet/core/wallet_base.dart';
12
+import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
13
+import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
14
15
part 'order_details_view_model.g.dart';
16
@@ -14,16 +18,27 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
18
with _$OrderDetailsViewModel;
19
20
abstract class OrderDetailsViewModelBase with Store {
17
- OrderDetailsViewModelBase({this.wyreViewModel, Order orderForDetails}) {
21
+ OrderDetailsViewModelBase({WalletBase wallet, Order orderForDetails}) {
22
order = orderForDetails;
23
24
+ if (order.provider != null) {
25
+ switch (order.provider) {
26
+ case BuyProviderDescription.wyre:
27
+ _provider = WyreBuyProvider(wallet: wallet);
28
+ break;
29
+ case BuyProviderDescription.moonPay:
30
+ _provider = MoonPayBuyProvider(wallet: wallet);
31
+ break;
32
+ }
33
+ }
34
+
35
items = ObservableList<StandartListItem>();
36
37
_updateItems();
38
39
_updateOrder();
40
26
- _timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
41
+ timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
42
}
43
44
@observable
@@ -32,21 +47,20 @@ abstract class OrderDetailsViewModelBase with Store {
47
@observable
48
ObservableList<StandartListItem> items;
49
35
- WyreViewModel wyreViewModel;
50
+ BuyProvider _provider;
51
37
- Timer _timer;
52
+ Timer timer;
53
54
@action
55
Future<void> _updateOrder() async {
56
try {
42
- final updatedOrder =
43
- await wyreViewModel.wyreService.findOrderById(order.id);
44
-
45
- updatedOrder.receiveAddress = order.receiveAddress;
46
- updatedOrder.walletId = order.walletId;
47
- order = updatedOrder;
48
-
49
- _updateItems();
57
+ if (_provider != null) {
58
+ final updatedOrder = await _provider.findOrderById(order.id);
59
+ updatedOrder.receiveAddress = order.receiveAddress;
60
+ updatedOrder.walletId = order.walletId;
61
+ order = updatedOrder;
62
+ _updateItems();
63
+ }
64
} catch (e) {
65
print(e.toString());
66
}
@@ -54,8 +68,6 @@ abstract class OrderDetailsViewModelBase with Store {
68
69
void _updateItems() {
70
final dateFormat = DateFormatter.withCurrentLocal();
57
- final buildURL =
58
- wyreViewModel.trackUrl + '${order.transferId}';
71
72
items?.clear();
73
@@ -68,18 +80,37 @@ abstract class OrderDetailsViewModelBase with Store {
80
value: order.state != null
81
? order.state.toString()
82
: S.current.trade_details_fetching),
71
- TrackTradeListItem(
72
- title: 'Track',
73
- value: buildURL,
74
- onTap: () {
75
- launch(buildURL);
76
- }),
77
- StandartListItem(
78
- title: S.current.trade_details_created_at,
79
- value: dateFormat.format(order.createdAt).toString()),
80
- StandartListItem(
81
- title: S.current.trade_details_pair,
82
- value: '${order.from} → ${order.to}')
83
]);
84
+
85
+ if (order.provider != null) {
86
+ items.add(
87
+ StandartListItem(
88
+ title: 'Buy provider',
89
+ value: order.provider.title)
90
+ );
91
+ }
92
+
93
+ if (_provider.trackUrl.isNotEmpty) {
94
+ final buildURL = _provider.trackUrl + '${order.transferId}';
95
+ items.add(
96
+ TrackTradeListItem(
97
+ title: 'Track',
98
+ value: buildURL,
99
+ onTap: () => launch(buildURL)
100
+ )
101
+ );
102
+ }
103
+
104
+ items.add(
105
+ StandartListItem(
106
+ title: S.current.trade_details_created_at,
107
+ value: dateFormat.format(order.createdAt).toString())
108
+ );
109
+
110
+ items.add(
111
+ StandartListItem(
112
+ title: S.current.trade_details_pair,
113
+ value: '${order.from} → ${order.to}')
114
+ );
115
}
116
}
\ No newline at end of file
lib/view_model/wyre_view_model.dart
deleted
-34
@@ -1,34 +0,0 @@
1
-import 'package:cake_wallet/entities/wyre_service.dart';
2
-import 'package:flutter/foundation.dart';
3
-import 'package:hive/hive.dart';
4
-import 'package:cake_wallet/buy/order.dart';
5
-import 'package:cake_wallet/store/dashboard/orders_store.dart';
6
-import 'package:mobx/mobx.dart';
7
-
8
-part 'wyre_view_model.g.dart';
9
-
10
-class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
11
-
12
-abstract class WyreViewModelBase with Store {
13
- WyreViewModelBase(this.ordersSource, this.ordersStore,
14
- {@required this.wyreService});
15
-
16
- Future<String> get wyreUrl => wyreService.getWyreUrl();
17
-
18
- String get trackUrl => wyreService.trackUrl;
19
-
20
- final Box<Order> ordersSource;
21
- final OrdersStore ordersStore;
22
-
23
- final WyreService wyreService;
24
-
25
- Future<void> saveOrder(String orderId) async {
26
- try {
27
- final order = await wyreService.findOrderById(orderId);
28
- await ordersSource.add(order);
29
- ordersStore.setOrder(order);
30
- } catch (e) {
31
- print(e.toString());
32
- }
33
- }
34
-}
\ No newline at end of file
res/values/strings_de.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Unbestätigt",
470
"displayable" : "Anzeigebar",
471
472
- "submit_request" : "Einen Antrag stellen"
472
+ "submit_request" : "Einen Antrag stellen",
473
+
474
+ "buy_bitcoin" : "Bitcoin kaufen",
475
+ "buy_with" : "Kaufen mit"
476
}
\ No newline at end of file
res/values/strings_en.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Unconfirmed",
470
"displayable" : "Displayable",
471
472
- "submit_request" : "submit a request"
472
+ "submit_request" : "submit a request",
473
+
474
+ "buy_bitcoin" : "Buy Bitcoin",
475
+ "buy_with" : "Buy with"
476
}
\ No newline at end of file
res/values/strings_es.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Inconfirmado",
470
"displayable" : "Visualizable",
471
472
- "submit_request" : "presentar una solicitud"
472
+ "submit_request" : "presentar una solicitud",
473
+
474
+ "buy_bitcoin" : "Comprar Bitcoin",
475
+ "buy_with" : "Compra con"
476
}
\ No newline at end of file
res/values/strings_hi.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "अपुष्ट",
470
"displayable" : "प्रदर्शन योग्य",
471
472
- "submit_request" : "एक अनुरोध सबमिट करें"
472
+ "submit_request" : "एक अनुरोध सबमिट करें",
473
+
474
+ "buy_bitcoin" : "बिटकॉइन खरीदें",
475
+ "buy_with" : "के साथ खरीदें"
476
}
\ No newline at end of file
res/values/strings_ja.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "未確認",
470
"displayable" : "表示可能",
471
472
- "submit_request" : "リクエストを送信する"
472
+ "submit_request" : "リクエストを送信する",
473
+
474
+ "buy_bitcoin" : "ビットコインを購入する",
475
+ "buy_with" : "で購入"
476
}
\ No newline at end of file
res/values/strings_ko.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "미확인",
470
"displayable" : "표시 가능",
471
472
- "submit_request" : "요청을 제출"
472
+ "submit_request" : "요청을 제출",
473
+
474
+ "buy_bitcoin" : "비트 코인 구매",
475
+ "buy_with" : "구매"
476
}
\ No newline at end of file
res/values/strings_nl.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Niet bevestigd",
470
"displayable" : "Weer te geven",
471
472
- "submit_request" : "een verzoek indienen"
472
+ "submit_request" : "een verzoek indienen",
473
+
474
+ "buy_bitcoin" : "Koop Bitcoin",
475
+ "buy_with" : "Koop met"
476
}
\ No newline at end of file
res/values/strings_pl.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Niepotwierdzony",
470
"displayable" : "Wyświetlane",
471
472
- "submit_request" : "złożyć wniosek"
472
+ "submit_request" : "złożyć wniosek",
473
+
474
+ "buy_bitcoin" : "Kup Bitcoin",
475
+ "buy_with" : "Kup za pomocą"
476
}
\ No newline at end of file
res/values/strings_pt.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Não confirmado",
470
"displayable" : "Exibível",
471
472
- "submit_request" : "enviar um pedido"
472
+ "submit_request" : "enviar um pedido",
473
+
474
+ "buy_bitcoin" : "Compre Bitcoin",
475
+ "buy_with" : "Compre com"
476
}
\ No newline at end of file
res/values/strings_ru.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Неподтвержденный",
470
"displayable" : "Отображаемый",
471
472
- "submit_request" : "отправить запрос"
472
+ "submit_request" : "отправить запрос",
473
+
474
+ "buy_bitcoin" : "Купить Bitcoin",
475
+ "buy_with" : "Купить с помощью"
476
}
\ No newline at end of file
res/values/strings_uk.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "Непідтверджений",
470
"displayable" : "Відображуваний",
471
472
- "submit_request" : "надіслати запит"
472
+ "submit_request" : "надіслати запит",
473
+
474
+ "buy_bitcoin" : "Купити Bitcoin",
475
+ "buy_with" : "Купити за допомогою"
476
}
\ No newline at end of file
res/values/strings_zh.arb
+4
-1
@@ -469,5 +469,8 @@
469
"unconfirmed" : "未经证实",
470
"displayable" : "可显示",
471
472
- "submit_request" : "提交請求"
472
+ "submit_request" : "提交請求",
473
+
474
+ "buy_bitcoin" : "購買比特幣",
475
+ "buy_with" : "與一起購買"
476
}
\ No newline at end of file