CAKE-279 | applied order details to the app
OleksandrSobol committed
Mar 12, 2021 at 21:04 UTC
60333e235df5c3dafba48e9f7a89ec3d2247245a
16 files changed
+498
-7
android/app/src/main/AndroidManifest.xml
+2
@@ -27,6 +27,8 @@
27
<intent-filter>
28
<action android:name="android.intent.action.MAIN"/>
29
<category android:name="android.intent.category.LAUNCHER"/>
30
+ <data android:scheme="cakewallet"/>
31
+ <data android:host="wyre-trade-success"/>
32
</intent-filter>
33
</activity>
34
android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
+31
@@ -1,15 +1,46 @@
1
package com.cakewallet.cake_wallet;
2
3
+import android.content.Intent;
4
+import android.os.Bundle;
5
+import android.os.Handler;
6
+import android.os.Looper;
7
+
8
import androidx.annotation.NonNull;
9
+import androidx.annotation.Nullable;
10
+
11
+import java.nio.ByteBuffer;
12
+
13
import io.flutter.embedding.android.FlutterFragmentActivity;
14
import io.flutter.embedding.engine.FlutterEngine;
15
+import io.flutter.plugin.common.BasicMessageChannel;
16
+import io.flutter.plugin.common.BinaryCodec;
17
import io.flutter.plugins.GeneratedPluginRegistrant;
18
19
20
public class MainActivity extends FlutterFragmentActivity {
21
+ public static final int DATA_EXISTS = 1;
22
+ public static final int DATA_NOT_EXISTS = 0;
23
+ BasicMessageChannel<ByteBuffer> dataChannel;
24
+ Handler handler = new Handler(Looper.getMainLooper());
25
26
@Override
27
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
28
GeneratedPluginRegistrant.registerWith(flutterEngine);
29
+
30
+ dataChannel = new BasicMessageChannel<ByteBuffer>(
31
+ flutterEngine.getDartExecutor().getBinaryMessenger(),
32
+ "data_change", BinaryCodec.INSTANCE);
33
+ }
34
+
35
+ @Override
36
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
37
+ super.onActivityResult(requestCode, resultCode, data);
38
+ ByteBuffer buffer = ByteBuffer.allocateDirect(4);
39
+ if (data != null) {
40
+ buffer.putInt(DATA_EXISTS);
41
+ } else {
42
+ buffer.putInt(DATA_NOT_EXISTS);
43
+ }
44
+ handler.post(() -> dataChannel.send(buffer));
45
}
46
}
\ No newline at end of file
assets/images/wyre-icon.png
Binary files /dev/null and b/assets/images/wyre-icon.png differ
lib/di.dart
+19
-2
@@ -4,6 +4,7 @@ import 'package:cake_wallet/core/wallet_service.dart';
4
import 'package:cake_wallet/entities/biometric_auth.dart';
5
import 'package:cake_wallet/entities/contact_record.dart';
6
import 'package:cake_wallet/entities/load_current_wallet.dart';
7
+import 'package:cake_wallet/entities/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/monero/monero_wallet_service.dart';
@@ -22,6 +23,7 @@ import 'package:cake_wallet/src/screens/faq/faq_page.dart';
23
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
24
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
25
import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart';
26
+import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
27
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
28
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
29
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
@@ -39,6 +41,7 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
41
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
42
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
43
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
44
+import 'package:cake_wallet/store/dashboard/orders_store.dart';
45
import 'package:cake_wallet/store/node_list_store.dart';
46
import 'package:cake_wallet/store/secret_store.dart';
47
import 'package:cake_wallet/store/settings_store.dart';
@@ -63,6 +66,7 @@ import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
66
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
67
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
68
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
69
+import 'package:cake_wallet/view_model/order_details_view_model.dart';
70
import 'package:cake_wallet/view_model/rescan_view_model.dart';
71
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
72
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
@@ -115,6 +119,7 @@ Box<Trade> _tradesSource;
119
Box<Template> _templates;
120
Box<ExchangeTemplate> _exchangeTemplates;
121
Box<TransactionDescription> _transactionDescriptionBox;
122
+Box<Order> _ordersSource;
123
124
Future setup(
125
{Box<WalletInfo> walletInfoSource,
@@ -123,7 +128,8 @@ Future setup(
128
Box<Trade> tradesSource,
129
Box<Template> templates,
130
Box<ExchangeTemplate> exchangeTemplates,
126
- Box<TransactionDescription> transactionDescriptionBox}) async {
131
+ Box<TransactionDescription> transactionDescriptionBox,
132
+ Box<Order> ordersSource}) async {
133
_walletInfoSource = walletInfoSource;
134
_nodeSource = nodeSource;
135
_contactSource = contactSource;
@@ -131,6 +137,7 @@ Future setup(
137
_templates = templates;
138
_exchangeTemplates = exchangeTemplates;
139
_transactionDescriptionBox = transactionDescriptionBox;
140
+ _ordersSource = ordersSource;
141
142
if (!_isSetupFinished) {
143
getIt.registerSingletonAsync<SharedPreferences>(
@@ -157,6 +164,8 @@ Future setup(
164
nodeListStore: getIt.get<NodeListStore>()));
165
getIt.registerSingleton<TradesStore>(TradesStore(
166
tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
167
+ getIt.registerSingleton<OrdersStore>(OrdersStore(
168
+ ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
169
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
170
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore());
171
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
@@ -219,7 +228,9 @@ Future setup(
228
appStore: getIt.get<AppStore>(),
229
tradesStore: getIt.get<TradesStore>(),
230
tradeFilterStore: getIt.get<TradeFilterStore>(),
222
- transactionFilterStore: getIt.get<TransactionFilterStore>()));
231
+ transactionFilterStore: getIt.get<TransactionFilterStore>(),
232
+ ordersSource: _ordersSource,
233
+ ordersStore: getIt.get<OrdersStore>()));
234
235
getIt.registerFactory<AuthService>(() => AuthService(
236
secureStorage: getIt.get<FlutterSecureStorage>(),
@@ -482,6 +493,9 @@ Future setup(
493
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
494
TradeDetailsViewModel(tradeForDetails: trade, trades: _tradesSource));
495
496
+ getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) =>
497
+ OrderDetailsViewModel(orderForDetails: order));
498
+
499
getIt.registerFactory(() => BackupService(
500
getIt.get<FlutterSecureStorage>(),
501
_walletInfoSource,
@@ -511,6 +525,9 @@ Future setup(
525
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
526
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
527
528
+ getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
529
+ OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
530
+
531
getIt.registerFactory(() => SupportViewModel());
532
533
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
lib/entities/find_order_by_id.dart
new
+40
@@ -0,0 +1,40 @@
1
+import 'dart:convert';
2
+import 'package:cake_wallet/entities/order.dart';
3
+import 'package:cake_wallet/exchange/trade_state.dart';
4
+import 'package:http/http.dart';
5
+
6
+Future<Order> findOrderById(String id) async {
7
+ final orderUrl = 'https://api.testwyre.com/v3/orders/' + id;
8
+
9
+ final orderResponse = await get(orderUrl);
10
+
11
+ final orderResponseJSON =
12
+ json.decode(orderResponse.body) as Map<String, dynamic>;
13
+ final transferId = orderResponseJSON['transferId'] as String;
14
+ final from = orderResponseJSON['sourceCurrency'] as String;
15
+ final to = orderResponseJSON['destCurrency'] as String;
16
+ final status = orderResponseJSON['status'] as String;
17
+ final state = TradeState.deserialize(raw: status.toLowerCase());
18
+ final createdAtRaw = orderResponseJSON['createdAt'] as int;
19
+ final createdAt =
20
+ DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
21
+
22
+ final transferUrl =
23
+ 'https://api.testwyre.com/v2/transfer/' + transferId + '/track';
24
+
25
+ final transferResponse = await get(transferUrl);
26
+
27
+ final transferResponseJSON =
28
+ json.decode(transferResponse.body) as Map<String, dynamic>;
29
+ final amount = transferResponseJSON['destAmount'] as double;
30
+
31
+ return Order(
32
+ id: id,
33
+ transferId: transferId,
34
+ from: from,
35
+ to: to,
36
+ state: state,
37
+ createdAt: createdAt,
38
+ amount: amount.toString()
39
+ );
40
+}
\ No newline at end of file
lib/entities/order.dart
new
+55
@@ -0,0 +1,55 @@
1
+import 'package:hive/hive.dart';
2
+import 'package:cake_wallet/exchange/trade_state.dart';
3
+import 'package:cake_wallet/entities/format_amount.dart';
4
+
5
+part 'order.g.dart';
6
+
7
+@HiveType(typeId: Order.typeId)
8
+class Order extends HiveObject {
9
+ Order(
10
+ {this.id,
11
+ this.transferId,
12
+ this.from,
13
+ this.to,
14
+ TradeState state,
15
+ this.createdAt,
16
+ this.amount,
17
+ this.receiveAddress,
18
+ this.walletId})
19
+ : stateRaw = state?.raw;
20
+
21
+ static const typeId = 8;
22
+ static const boxName = 'Orders';
23
+ static const boxKey = 'ordersBoxKey';
24
+
25
+ @HiveField(0)
26
+ String id;
27
+
28
+ @HiveField(1)
29
+ String transferId;
30
+
31
+ @HiveField(2)
32
+ String from;
33
+
34
+ @HiveField(3)
35
+ String to;
36
+
37
+ @HiveField(4)
38
+ String stateRaw;
39
+
40
+ TradeState get state => TradeState.deserialize(raw: stateRaw);
41
+
42
+ @HiveField(5)
43
+ DateTime createdAt;
44
+
45
+ @HiveField(6)
46
+ String amount;
47
+
48
+ @HiveField(7)
49
+ String receiveAddress;
50
+
51
+ @HiveField(8)
52
+ String walletId;
53
+
54
+ String amountFormatted() => formatAmount(amount);
55
+}
\ No newline at end of file
lib/main.dart
+13
-1
@@ -1,3 +1,4 @@
1
+import 'package:cake_wallet/entities/order.dart';
2
import 'package:flutter/material.dart';
3
import 'package:flutter/services.dart';
4
import 'package:hive/hive.dart';
@@ -69,11 +70,17 @@ Future<void> main() async {
70
Hive.registerAdapter(ExchangeTemplateAdapter());
71
}
72
73
+ if (!Hive.isAdapterRegistered(Order.typeId)) {
74
+ Hive.registerAdapter(OrderAdapter());
75
+ }
76
+
77
final secureStorage = FlutterSecureStorage();
78
final transactionDescriptionsBoxKey = await getEncryptionKey(
79
secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
80
final tradesBoxKey = await getEncryptionKey(
81
secureStorage: secureStorage, forKey: Trade.boxKey);
82
+ final ordersBoxKey = await getEncryptionKey(
83
+ secureStorage: secureStorage, forKey: Order.boxKey);
84
final contacts = await Hive.openBox<Contact>(Contact.boxName);
85
final nodes = await Hive.openBox<Node>(Node.boxName);
86
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
@@ -81,6 +88,8 @@ Future<void> main() async {
88
encryptionKey: transactionDescriptionsBoxKey);
89
final trades =
90
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
91
+ final orders =
92
+ await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
93
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
94
final templates = await Hive.openBox<Template>(Template.boxName);
95
final exchangeTemplates =
@@ -91,6 +100,7 @@ Future<void> main() async {
100
walletInfoSource: walletInfoSource,
101
contactSource: contacts,
102
tradesSource: trades,
103
+ ordersSource: orders,
104
// fiatConvertationService: fiatConvertationService,
105
templates: templates,
106
exchangeTemplates: exchangeTemplates,
@@ -118,6 +128,7 @@ Future<void> initialSetup(
128
@required Box<WalletInfo> walletInfoSource,
129
@required Box<Contact> contactSource,
130
@required Box<Trade> tradesSource,
131
+ @required Box<Order> ordersSource,
132
// @required FiatConvertationService fiatConvertationService,
133
@required Box<Template> templates,
134
@required Box<ExchangeTemplate> exchangeTemplates,
@@ -139,7 +150,8 @@ Future<void> initialSetup(
150
tradesSource: tradesSource,
151
templates: templates,
152
exchangeTemplates: exchangeTemplates,
142
- transactionDescriptionBox: transactionDescriptions);
153
+ transactionDescriptionBox: transactionDescriptions,
154
+ ordersSource: ordersSource);
155
await bootstrap(navigatorKey);
156
monero_wallet.onStartup();
157
}
lib/router.dart
+7
@@ -1,7 +1,9 @@
1
import 'package:cake_wallet/entities/contact_record.dart';
2
+import 'package:cake_wallet/entities/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/order_details/order_details_page.dart';
7
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
8
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
9
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
@@ -285,6 +287,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
287
builder: (_) =>
288
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
289
290
+ case Routes.orderDetails:
291
+ return MaterialPageRoute<void>(
292
+ builder: (_) =>
293
+ getIt.get<OrderDetailsPage>(param1: settings.arguments as Order));
294
+
295
case Routes.restoreWalletFromSeedDetails:
296
final args = settings.arguments as List;
297
final walletRestorationFromSeedVM =
lib/routes.dart
+1
@@ -52,4 +52,5 @@ class Routes {
52
static const editBackupPassword = '/edit_backup_passowrd';
53
static const restoreFromBackup = '/restore_from_backup';
54
static const support = '/support';
55
+ static const orderDetails = '/order_details';
56
}
\ No newline at end of file
lib/src/screens/dashboard/widgets/order_row.dart
new
+72
@@ -0,0 +1,72 @@
1
+import 'package:flutter/material.dart';
2
+
3
+class OrderRow extends StatelessWidget {
4
+ OrderRow({
5
+ @required this.onTap,
6
+ this.from,
7
+ this.to,
8
+ this.createdAtFormattedDate,
9
+ this.formattedAmount});
10
+ final VoidCallback onTap;
11
+ final String from;
12
+ final String to;
13
+ final String createdAtFormattedDate;
14
+ final String formattedAmount;
15
+ final wyreImage =
16
+ Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
17
+
18
+ @override
19
+ Widget build(BuildContext context) {
20
+ return InkWell(
21
+ onTap: onTap,
22
+ child: Container(
23
+ padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
24
+ color: Colors.transparent,
25
+ child: Row(
26
+ mainAxisSize: MainAxisSize.max,
27
+ crossAxisAlignment: CrossAxisAlignment.center,
28
+ children: [
29
+ wyreImage,
30
+ SizedBox(width: 12),
31
+ Expanded(
32
+ child: Column(
33
+ mainAxisSize: MainAxisSize.min,
34
+ children: [
35
+ Row(
36
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
37
+ children: <Widget>[
38
+ Text('$from → $to',
39
+ style: TextStyle(
40
+ fontSize: 16,
41
+ fontWeight: FontWeight.w500,
42
+ color: Theme.of(context).accentTextTheme.
43
+ display3.backgroundColor
44
+ )),
45
+ formattedAmount != null
46
+ ? Text(formattedAmount + ' ' + to,
47
+ style: TextStyle(
48
+ fontSize: 16,
49
+ fontWeight: FontWeight.w500,
50
+ color: Theme.of(context).accentTextTheme.
51
+ display3.backgroundColor
52
+ ))
53
+ : Container()
54
+ ]),
55
+ SizedBox(height: 5),
56
+ Row(
57
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
58
+ children: <Widget>[
59
+ Text(createdAtFormattedDate,
60
+ style: TextStyle(
61
+ fontSize: 14,
62
+ color: Theme.of(context).textTheme
63
+ .overline.backgroundColor))
64
+ ])
65
+ ],
66
+ )
67
+ )
68
+ ],
69
+ ),
70
+ ));
71
+ }
72
+}
\ No newline at end of file
lib/src/screens/dashboard/widgets/transactions_page.dart
+17
@@ -1,3 +1,5 @@
1
+import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
2
+import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
3
import 'package:flutter/material.dart';
4
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
5
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -75,6 +77,21 @@ class TransactionsPage extends StatelessWidget {
77
);
78
}
79
80
+ if (item is OrderListItem) {
81
+ final order = item.order;
82
+
83
+ return OrderRow(
84
+ onTap: () => Navigator.of(context).pushNamed(
85
+ Routes.orderDetails,
86
+ arguments: order),
87
+ from: order.from,
88
+ to: order.to,
89
+ createdAtFormattedDate:
90
+ DateFormat('HH:mm').format(order.createdAt),
91
+ formattedAmount: item.orderFormattedAmount,
92
+ );
93
+ }
94
+
95
return Container(
96
color: Colors.transparent,
97
height: 1);
lib/src/screens/order_details/order_details_page.dart
new
+47
@@ -0,0 +1,47 @@
1
+import 'package:cake_wallet/src/widgets/standard_list.dart';
2
+import 'package:cake_wallet/utils/show_bar.dart';
3
+import 'package:cake_wallet/view_model/order_details_view_model.dart';
4
+import 'package:flutter/material.dart';
5
+import 'package:flutter/cupertino.dart';
6
+import 'package:flutter/services.dart';
7
+import 'package:flutter_mobx/flutter_mobx.dart';
8
+import 'package:cake_wallet/generated/i18n.dart';
9
+import 'package:cake_wallet/src/screens/base_page.dart';
10
+import 'package:cake_wallet/src/widgets/standart_list_row.dart';
11
+import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
12
+
13
+class OrderDetailsPage extends BasePage {
14
+ OrderDetailsPage(this.orderDetailsViewModel);
15
+
16
+ @override
17
+ String get title => 'Order Details';
18
+
19
+ final OrderDetailsViewModel orderDetailsViewModel;
20
+
21
+ @override
22
+ Widget body(BuildContext context) {
23
+ return Observer(builder: (_) {
24
+ return SectionStandardList(
25
+ sectionCount: 1,
26
+ itemCounter: (int _) => orderDetailsViewModel.items.length,
27
+ itemBuilder: (_, __, index) {
28
+ final item = orderDetailsViewModel.items[index];
29
+
30
+ if (item is TrackTradeListItem) {
31
+ return GestureDetector(
32
+ onTap: item.onTap,
33
+ child: StandartListRow(
34
+ title: '${item.title}', value: '${item.value}'));
35
+ } else {
36
+ return GestureDetector(
37
+ onTap: () {
38
+ Clipboard.setData(ClipboardData(text: '${item.value}'));
39
+ showBar<void>(context, S.of(context).copied_to_clipboard);
40
+ },
41
+ child: StandartListRow(
42
+ title: '${item.title}', value: '${item.value}'));
43
+ }
44
+ });
45
+ });
46
+ }
47
+}
\ No newline at end of file
lib/store/dashboard/orders_store.dart
new
+40
@@ -0,0 +1,40 @@
1
+import 'dart:async';
2
+import 'package:cake_wallet/entities/order.dart';
3
+import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
4
+import 'package:hive/hive.dart';
5
+import 'package:mobx/mobx.dart';
6
+import 'package:cake_wallet/store/settings_store.dart';
7
+
8
+part 'orders_store.g.dart';
9
+
10
+class OrdersStore = OrdersStoreBase with _$OrdersStore;
11
+
12
+abstract class OrdersStoreBase with Store {
13
+ OrdersStoreBase({this.ordersSource, this.settingsStore}) {
14
+ orders = <OrderListItem>[];
15
+
16
+ _onOrdersChanged =
17
+ ordersSource.watch().listen((_) async => await updateOrderList());
18
+
19
+ updateOrderList();
20
+ }
21
+
22
+ Box<Order> ordersSource;
23
+ StreamSubscription<BoxEvent> _onOrdersChanged;
24
+ SettingsStore settingsStore;
25
+
26
+ @observable
27
+ List<OrderListItem> orders;
28
+
29
+ @observable
30
+ Order order;
31
+
32
+ @action
33
+ void setOrder(Order order) => this.order = order;
34
+
35
+ @action
36
+ Future updateOrderList() async => orders =
37
+ ordersSource.values.map((order) => OrderListItem(
38
+ order: order,
39
+ displayMode: settingsStore.balanceDisplayMode)).toList();
40
+}
\ No newline at end of file
lib/view_model/dashboard/dashboard_view_model.dart
+51
-4
@@ -4,7 +4,10 @@ import 'dart:io';
4
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
5
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
6
import 'package:cake_wallet/entities/balance.dart';
7
+import 'package:cake_wallet/entities/find_order_by_id.dart';
8
+import 'package:cake_wallet/entities/order.dart';
9
import 'package:cake_wallet/entities/transaction_history.dart';
10
+import 'package:cake_wallet/exchange/trade_state.dart';
11
import 'package:cake_wallet/monero/account.dart';
12
import 'package:cake_wallet/monero/monero_balance.dart';
13
import 'package:cake_wallet/monero/monero_transaction_history.dart';
@@ -16,14 +19,18 @@ import 'package:cake_wallet/entities/transaction_direction.dart';
19
import 'package:cake_wallet/entities/transaction_info.dart';
20
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
21
import 'package:cake_wallet/exchange/trade.dart';
22
+import 'package:cake_wallet/store/dashboard/orders_store.dart';
23
import 'package:cake_wallet/utils/mobx.dart';
24
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
25
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
26
+import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
27
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:crypto/crypto.dart';
32
+import 'package:flutter/services.dart';
33
+import 'package:hive/hive.dart';
34
import 'package:http/http.dart';
35
import 'package:mobx/mobx.dart';
36
import 'package:cake_wallet/core/wallet_base.dart';
@@ -49,7 +56,9 @@ abstract class DashboardViewModelBase with Store {
56
this.appStore,
57
this.tradesStore,
58
this.tradeFilterStore,
52
- this.transactionFilterStore}) {
59
+ this.transactionFilterStore,
60
+ this.ordersSource,
61
+ this.ordersStore}) {
62
filterItems = {
63
S.current.transactions: [
64
FilterItem(
@@ -135,8 +144,27 @@ abstract class DashboardViewModelBase with Store {
144
145
return true;
146
});
147
+
148
+ dataChannel.setMessageHandler((ByteData message) async {
149
+ final type = ByteData.view(message.buffer, 0, 4).getInt32(0);
150
+
151
+ switch (type) {
152
+ case _dataExists:
153
+ print('Wyre: Data exists');
154
+ break;
155
+ case _dataNotExists:
156
+ print('Wyre: Data not exists');
157
+ break;
158
+ }
159
+
160
+ return ByteData(0);
161
+ });
162
}
163
164
+ static const dataChannel = BasicMessageChannel('data_change', BinaryCodec());
165
+ static const _dataExists = 1;
166
+ static const _dataNotExists = 0;
167
+
168
@observable
169
WalletType type;
170
@@ -179,6 +207,11 @@ abstract class DashboardViewModelBase with Store {
207
.where((trade) => trade.trade.walletId == wallet.id)
208
.toList();
209
210
+ @computed
211
+ List<OrderListItem> get orders => ordersStore.orders
212
+ .where((item) => item.order.walletId == wallet.id)
213
+ .toList();
214
+
215
@computed
216
double get price => balanceViewModel.price;
217
@@ -188,6 +221,7 @@ abstract class DashboardViewModelBase with Store {
221
222
_items.addAll(transactionFilterStore.filtered(transactions: transactions));
223
_items.addAll(tradeFilterStore.filtered(trades: trades, wallet: wallet));
224
+ _items.addAll(orders);
225
226
return formattedItemsList(_items);
227
}
@@ -197,12 +231,16 @@ abstract class DashboardViewModelBase with Store {
231
232
bool get hasRescan => wallet.type == WalletType.monero;
233
234
+ Box<Order> ordersSource;
235
+
236
BalanceViewModel balanceViewModel;
237
238
AppStore appStore;
239
240
TradesStore tradesStore;
241
242
+ OrdersStore ordersStore;
243
+
244
TradeFilterStore tradeFilterStore;
245
246
TransactionFilterStore transactionFilterStore;
@@ -296,10 +334,12 @@ abstract class DashboardViewModelBase with Store {
334
final secretKey = secrets.wyre_secret_key;
335
final accountId = secrets.wyre_account_id;
336
final body = {
299
- 'destCurrency' : walletTypeToCryptoCurrency(type).title,
300
- 'dest' : walletTypeToString(type).toLowerCase() + ':' + address,
337
+ //'destCurrency' : walletTypeToCryptoCurrency(type).title,
338
+ //'dest' : walletTypeToString(type).toLowerCase() + ':' + address,
339
'referrerAccountId' : accountId,
302
- 'lockFields' : ['destCurrency', 'dest']
340
+ 'redirectUrl' : 'http://google.com'
341
+ //'redirectUrl' : 'cakewallet://wyre-trade-success'
342
+ //'lockFields' : ['destCurrency', 'dest']
343
};
344
345
final response = await post(url,
@@ -315,6 +355,13 @@ abstract class DashboardViewModelBase with Store {
355
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
356
final urlFromResponse = responseJSON['url'] as String;
357
if (await canLaunch(urlFromResponse)) await launch(urlFromResponse);
358
+
359
+ /*final orderId = '';
360
+ final order = await findOrderById(orderId);
361
+ order.receiveAddress = address;
362
+ order.walletId = wallet.id;
363
+ await ordersSource.add(order);
364
+ ordersStore.setOrder(order);*/
365
}
366
}
367
}
lib/view_model/dashboard/order_list_item.dart
new
+21
@@ -0,0 +1,21 @@
1
+import 'package:cake_wallet/entities/order.dart';
2
+import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
3
+import 'package:cake_wallet/entities/balance_display_mode.dart';
4
+
5
+class OrderListItem extends ActionListItem {
6
+ OrderListItem({this.order, this.displayMode});
7
+
8
+ final Order order;
9
+ final BalanceDisplayMode displayMode;
10
+
11
+ String get orderFormattedAmount {
12
+ return order.amount != null
13
+ ? displayMode == BalanceDisplayMode.hiddenBalance
14
+ ? '---'
15
+ : order.amountFormatted()
16
+ : order.amount;
17
+ }
18
+
19
+ @override
20
+ DateTime get date => order.createdAt;
21
+}
\ No newline at end of file
lib/view_model/order_details_view_model.dart
new
+82
@@ -0,0 +1,82 @@
1
+import 'dart:async';
2
+import 'package:cake_wallet/entities/find_order_by_id.dart';
3
+import 'package:cake_wallet/entities/order.dart';
4
+import 'package:cake_wallet/utils/date_formatter.dart';
5
+import 'package:mobx/mobx.dart';
6
+import 'package:cake_wallet/generated/i18n.dart';
7
+import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
8
+import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
9
+import 'package:url_launcher/url_launcher.dart';
10
+
11
+part 'order_details_view_model.g.dart';
12
+
13
+class OrderDetailsViewModel = OrderDetailsViewModelBase
14
+ with _$OrderDetailsViewModel;
15
+
16
+abstract class OrderDetailsViewModelBase with Store {
17
+ OrderDetailsViewModelBase({Order orderForDetails}) {
18
+ order = orderForDetails;
19
+
20
+ items = ObservableList<StandartListItem>();
21
+
22
+ _updateItems();
23
+
24
+ _updateOrder();
25
+
26
+ _timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
27
+ }
28
+
29
+ @observable
30
+ Order order;
31
+
32
+ @observable
33
+ ObservableList<StandartListItem> items;
34
+
35
+ Timer _timer;
36
+
37
+ @action
38
+ Future<void> _updateOrder() async {
39
+ try {
40
+ final updatedOrder = await findOrderById(order.id);
41
+
42
+ updatedOrder.receiveAddress = order.receiveAddress;
43
+ updatedOrder.walletId = order.walletId;
44
+ order = updatedOrder;
45
+
46
+ _updateItems();
47
+ } catch (e) {
48
+ print(e.toString());
49
+ }
50
+ }
51
+
52
+ void _updateItems() {
53
+ final dateFormat = DateFormatter.withCurrentLocal();
54
+ final buildURL =
55
+ 'https://dashboard-test.testwyre.com/track/${order.transferId}';
56
+
57
+ items?.clear();
58
+
59
+ items.addAll([
60
+ StandartListItem(
61
+ title: 'Transfer ID',
62
+ value: order.transferId),
63
+ StandartListItem(
64
+ title: S.current.trade_details_state,
65
+ value: order.state != null
66
+ ? order.state.toString()
67
+ : S.current.trade_details_fetching),
68
+ TrackTradeListItem(
69
+ title: 'Track',
70
+ value: buildURL,
71
+ onTap: () {
72
+ launch(buildURL);
73
+ }),
74
+ StandartListItem(
75
+ title: S.current.trade_details_created_at,
76
+ value: dateFormat.format(order.createdAt).toString()),
77
+ StandartListItem(
78
+ title: S.current.trade_details_pair,
79
+ value: '${order.from} → ${order.to}')
80
+ ]);
81
+ }
82
+}
\ No newline at end of file