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