CAKE-360 | added shouldShowYatPopup parameter to settings_store.dart and applied this parameter to dashboard_view_model.dart and dashboard_page.dart; added scrollbar to choose_yat_address_alert.dart; changed yat logo; fixed fetchYatAddress() method in the yat_store.dart; created class YatLink
OleksandrSobol committed
Oct 4, 2021 at 16:03 UTC
c728931b705b61cc9727fa7689a6dd26fab178cd
10 files changed
+167
-79
assets/images/yat_logo.png
Binary files a/assets/images/yat_logo.png and b/assets/images/yat_logo.png differ
lib/entities/preferences_key.dart
+1
@@ -20,4 +20,5 @@ class PreferencesKey {
20
static const moneroTransactionPriority = 'current_fee_priority_monero';
21
static const bitcoinTransactionPriority = 'current_fee_priority_bitcoin';
22
static const shouldShowReceiveWarning = 'should_show_receive_warning';
23
+ static const shouldShowYatPopup = 'should_show_yat_popup';
24
}
lib/src/screens/dashboard/dashboard_page.dart
+11
-8
@@ -156,14 +156,17 @@ class DashboardPage extends BasePage {
156
pages.add(BalancePage(dashboardViewModel: walletViewModel));
157
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
158
159
- await Future<void>.delayed(Duration(seconds: 1));
160
- await showPopUp<void>(
161
- context: context,
162
- builder: (BuildContext context) {
163
- return YatPopup(
164
- dashboardViewModel: walletViewModel,
165
- onClose: () => Navigator.of(context).pop());
166
- });
159
+ if (walletViewModel.shouldShowYatPopup) {
160
+ await Future<void>.delayed(Duration(seconds: 1));
161
+ await showPopUp<void>(
162
+ context: context,
163
+ builder: (BuildContext context) {
164
+ return YatPopup(
165
+ dashboardViewModel: walletViewModel,
166
+ onClose: () => Navigator.of(context).pop());
167
+ });
168
+ walletViewModel.furtherShowYatPopup(false);
169
+ }
170
171
autorun((_) async {
172
if (!walletViewModel.isOutdatedElectrumWallet) {
lib/src/screens/send/widgets/choose_yat_address_alert.dart
+92
-44
@@ -1,3 +1,4 @@
1
+import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
2
import 'package:flutter/material.dart';
3
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
4
@@ -22,51 +23,98 @@ class ChooseYatAddressAlert extends BaseAlertDialog {
23
bool get barrierDismissible => false;
24
25
@override
25
- Widget actionButtons(BuildContext context) {
26
- return Container(
27
- width: 300,
28
- height: 105,
29
- color: Theme.of(context).accentTextTheme.body1.backgroundColor,
30
- child: ListView.separated(
31
- padding: EdgeInsets.all(0),
32
- itemCount: addresses.length,
33
- separatorBuilder: (_, __) => Container(
34
- height: 1,
35
- color: Theme.of(context).dividerColor,
36
- ),
37
- itemBuilder: (context, index) {
38
- final address = addresses[index];
26
+ Widget actionButtons(BuildContext context) =>
27
+ ChooseYatAddressButtons(addresses);
28
+}
29
40
- return GestureDetector(
41
- onTap: () => Navigator.of(context).pop<String>(address),
42
- child: Container(
43
- width: 300,
44
- height: 52,
45
- padding: EdgeInsets.only(left: 24, right: 24),
46
- child: Row(
47
- mainAxisAlignment: MainAxisAlignment.center,
48
- crossAxisAlignment: CrossAxisAlignment.center,
49
- children: [
50
- Expanded(
51
- child: Text(
52
- address,
53
- textAlign: TextAlign.center,
54
- maxLines: 1,
55
- overflow: TextOverflow.ellipsis,
56
- style: TextStyle(
57
- fontSize: 15,
58
- fontWeight: FontWeight.w600,
59
- fontFamily: 'Lato',
60
- color: Theme.of(context).primaryTextTheme.title.color,
61
- decoration: TextDecoration.none,
62
- ),
63
- )
64
- )
65
- ],
66
- )
67
- ),
68
- );
69
- })
30
+class ChooseYatAddressButtons extends StatefulWidget {
31
+ ChooseYatAddressButtons(this.addresses);
32
+
33
+ final List<String> addresses;
34
+
35
+ @override
36
+ ChooseYatAddressButtonsState createState() =>
37
+ ChooseYatAddressButtonsState(addresses);
38
+}
39
+
40
+class ChooseYatAddressButtonsState extends State<ChooseYatAddressButtons> {
41
+ ChooseYatAddressButtonsState(this.addresses)
42
+ : itemCount = addresses?.length ?? 0;
43
+
44
+ final List<String> addresses;
45
+ final int itemCount;
46
+ final double backgroundHeight = 118;
47
+ final double thumbHeight = 72;
48
+ ScrollController controller = ScrollController();
49
+ double fromTop = 0;
50
+
51
+ @override
52
+ Widget build(BuildContext context) {
53
+ controller.addListener(() {
54
+ fromTop = controller.hasClients
55
+ ? (controller.offset / controller.position.maxScrollExtent *
56
+ (backgroundHeight - thumbHeight))
57
+ : 0;
58
+ setState(() {});
59
+ });
60
+
61
+ return Stack(
62
+ alignment: Alignment.center,
63
+ clipBehavior: Clip.none,
64
+ children: [
65
+ Container(
66
+ width: 300,
67
+ height: 158,
68
+ color: Theme.of(context).accentTextTheme.body1.backgroundColor,
69
+ child: ListView.separated(
70
+ controller: controller,
71
+ padding: EdgeInsets.all(0),
72
+ itemCount: itemCount,
73
+ separatorBuilder: (_, __) => Container(
74
+ height: 1,
75
+ color: Theme.of(context).dividerColor,
76
+ ),
77
+ itemBuilder: (context, index) {
78
+ final address = addresses[index];
79
+
80
+ return GestureDetector(
81
+ onTap: () => Navigator.of(context).pop<String>(address),
82
+ child: Container(
83
+ width: 300,
84
+ height: 52,
85
+ padding: EdgeInsets.only(left: 24, right: 24),
86
+ child: Row(
87
+ mainAxisAlignment: MainAxisAlignment.center,
88
+ crossAxisAlignment: CrossAxisAlignment.center,
89
+ children: [
90
+ Expanded(
91
+ child: Text(
92
+ address,
93
+ textAlign: TextAlign.center,
94
+ maxLines: 1,
95
+ overflow: TextOverflow.ellipsis,
96
+ style: TextStyle(
97
+ fontSize: 15,
98
+ fontWeight: FontWeight.w600,
99
+ fontFamily: 'Lato',
100
+ color: Theme.of(context).primaryTextTheme.title.color,
101
+ decoration: TextDecoration.none,
102
+ ),
103
+ )
104
+ )
105
+ ],
106
+ )
107
+ ),
108
+ );
109
+ })
110
+ ),
111
+ if (itemCount > 3) CakeScrollbar(
112
+ backgroundHeight: backgroundHeight,
113
+ thumbHeight: thumbHeight,
114
+ fromTop: fromTop,
115
+ //rightOffset: -15
116
+ )
117
+ ]
118
);
119
}
120
}
\ No newline at end of file
lib/src/screens/yat/widgets/yat_bar.dart
+1
-1
@@ -5,7 +5,7 @@ class YatBar extends StatelessWidget {
5
YatBar({this.onClose});
6
7
final VoidCallback onClose;
8
- final image = Image.asset('assets/images/yat_logo.png');
8
+ final image = Image.asset('assets/images/yat_logo.png', width: 81, height: 28);
9
10
@override
11
Widget build(BuildContext context) {
lib/src/screens/yat/yat_alert.dart
+6
-4
@@ -11,7 +11,9 @@ import 'package:lottie/lottie.dart';
11
12
class YatAlert extends StatelessWidget {
13
YatAlert(this.yatStore)
14
- : baseUrl = isYatDevMode ? baseDevUrl : baseReleaseUrl;
14
+ : baseUrl = YatLink.isDevMode
15
+ ? YatLink.baseDevUrl
16
+ : YatLink.baseReleaseUrl;
17
18
final YatStore yatStore;
19
final String baseUrl;
@@ -86,7 +88,7 @@ class YatAlert extends StatelessWidget {
88
.arrow_up_right_square,
89
mainAxisAlignment: MainAxisAlignment.end,
90
onPressed: () {
89
- final url = baseUrl + createSuffix;
91
+ final url = baseUrl + YatLink.createSuffix;
92
launch(url);
93
}),
94
Padding(
@@ -102,11 +104,11 @@ class YatAlert extends StatelessWidget {
104
.arrow_up_right_square,
105
mainAxisAlignment: MainAxisAlignment.end,
106
onPressed: () {
105
- String url = baseUrl + signInSuffix;
107
+ String url = baseUrl + YatLink.signInSuffix;
108
final parameters =
109
yatStore.defineQueryParameters();
110
if (parameters.isNotEmpty) {
109
- url += queryParameter + parameters;
111
+ url += YatLink.queryParameter + parameters;
112
}
113
launch(url);
114
})
lib/src/screens/yat/yat_popup.dart
+6
-4
@@ -14,7 +14,9 @@ import 'package:url_launcher/url_launcher.dart';
14
15
class YatPopup extends StatelessWidget {
16
YatPopup({this.dashboardViewModel, this.onClose})
17
- : baseUrl = isYatDevMode ? baseDevUrl : baseReleaseUrl;
17
+ : baseUrl = YatLink.isDevMode
18
+ ? YatLink.baseDevUrl
19
+ : YatLink.baseReleaseUrl;
20
21
static const durationInMilliseconds = 250;
22
@@ -157,15 +159,15 @@ class YatPopup extends StatelessWidget {
159
child: ThirdIntroduction(
160
onClose: onClose,
161
onGet: () {
160
- final url = baseUrl + createSuffix;
162
+ final url = baseUrl + YatLink.createSuffix;
163
launch(url);
164
},
165
onConnect: () {
164
- String url = baseUrl + signInSuffix;
166
+ String url = baseUrl + YatLink.signInSuffix;
167
final parameters = dashboardViewModel
168
.yatStore.defineQueryParameters();
169
if (parameters.isNotEmpty) {
168
- url += queryParameter + parameters;
170
+ url += YatLink.queryParameter + parameters;
171
}
172
launch(url);
173
}
lib/store/settings_store.dart
+14
-1
@@ -38,6 +38,7 @@ abstract class SettingsStoreBase with Store {
38
@required Map<WalletType, Node> nodes,
39
@required TransactionPriority initialBitcoinTransactionPriority,
40
@required TransactionPriority initialMoneroTransactionPriority,
41
+ @required this.shouldShowYatPopup,
42
@required this.isBitcoinBuyEnabled,
43
this.actionlistDisplayMode}) {
44
fiatCurrency = initialFiatCurrency;
@@ -59,6 +60,11 @@ abstract class SettingsStoreBase with Store {
60
(FiatCurrency fiatCurrency) => sharedPreferences.setString(
61
PreferencesKey.currentFiatCurrencyKey, fiatCurrency.serialize()));
62
63
+ reaction(
64
+ (_) => shouldShowYatPopup,
65
+ (bool shouldShowYatPopup) => sharedPreferences
66
+ .setBool(PreferencesKey.shouldShowYatPopup, shouldShowYatPopup));
67
+
68
priority.observe((change) {
69
final key = change.key == WalletType.monero
70
? PreferencesKey.moneroTransactionPriority
@@ -110,6 +116,9 @@ abstract class SettingsStoreBase with Store {
116
@observable
117
FiatCurrency fiatCurrency;
118
119
+ @observable
120
+ bool shouldShowYatPopup;
121
+
122
@observable
123
ObservableList<ActionListDisplayMode> actionlistDisplayMode;
124
@@ -217,6 +226,8 @@ abstract class SettingsStoreBase with Store {
226
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
227
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
228
final packageInfo = await PackageInfo.fromPlatform();
229
+ final shouldShowYatPopup =
230
+ sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
231
232
return SettingsStore(
233
sharedPreferences: sharedPreferences,
@@ -236,7 +247,8 @@ abstract class SettingsStoreBase with Store {
247
initialPinLength: pinLength,
248
initialLanguageCode: savedLanguageCode,
249
initialMoneroTransactionPriority: moneroTransactionPriority,
239
- initialBitcoinTransactionPriority: bitcoinTransactionPriority);
250
+ initialBitcoinTransactionPriority: bitcoinTransactionPriority,
251
+ shouldShowYatPopup: shouldShowYatPopup);
252
}
253
254
Future<void> reload(
@@ -270,6 +282,7 @@ abstract class SettingsStoreBase with Store {
282
pinCodeLength = settings.pinCodeLength;
283
languageCode = settings.languageCode;
284
appVersion = settings.appVersion;
285
+ shouldShowYatPopup = settings.shouldShowYatPopup;
286
}
287
288
Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
lib/store/yat/yat_store.dart
+30
-17
@@ -15,18 +15,24 @@ import 'package:http/http.dart';
15
16
part 'yat_store.g.dart';
17
18
-const baseDevUrl = 'https://yat.fyi';
19
-const baseReleaseUrl = 'https://y.at';
20
-const signInSuffix = '/partner/CW/link-email';
21
-const createSuffix = '/create';
22
-const queryParameter = '?addresses=';
23
-const requestDevUrl = 'https://a.yat.fyi/emoji_id/';
24
-const requestReleaseUrl = 'https://a.y.at/emoji_id/';
25
-const isYatDevMode = true;
18
+class YatLink {
19
+ static const baseDevUrl = 'https://yat.fyi';
20
+ static const baseReleaseUrl = 'https://y.at';
21
+ static const signInSuffix = '/partner/CW/link-email';
22
+ static const createSuffix = '/create';
23
+ static const queryParameter = '?addresses=';
24
+ static const requestDevUrl = 'https://a.yat.fyi/emoji_id/';
25
+ static const requestReleaseUrl = 'https://a.y.at/emoji_id/';
26
+ static const isDevMode = true;
27
+ static const tags = <String, List<String>>{"XMR" : ['0x1001', '0x1002'],
28
+ "BTC" : ['0x1003'], "LTC" : ['0x3fff']};
29
+}
30
31
Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
28
- final requestURL = isYatDevMode ? requestDevUrl : requestReleaseUrl;
29
- final url = requestURL + emojiId + '/' + ticker.toUpperCase();
32
+ final requestURL = YatLink.isDevMode
33
+ ? YatLink.requestDevUrl
34
+ : YatLink.requestReleaseUrl;
35
+ final url = requestURL + emojiId;
36
final response = await get(url);
37
38
if (response.statusCode != 200) {
@@ -41,11 +47,18 @@ Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
47
}
48
49
final List<String> addresses = [];
50
+ final currency = ticker.toUpperCase();
51
52
for (var elem in result) {
46
- final yatAddress = elem['data'] as String;
47
- if (yatAddress?.isNotEmpty ?? false) {
48
- addresses.add(yatAddress);
53
+ final tag = elem['tag'] as String;
54
+ if (tag?.isEmpty ?? true) {
55
+ continue;
56
+ }
57
+ if (YatLink.tags[currency]?.contains(tag) ?? false) {
58
+ final yatAddress = elem['data'] as String;
59
+ if (yatAddress?.isNotEmpty ?? false) {
60
+ addresses.add(yatAddress);
61
+ }
62
}
63
}
64
@@ -123,8 +136,8 @@ abstract class YatStoreBase with Store {
136
}
137
138
parameters += subaddress.address.startsWith('4')
126
- ? '0x1001%3D'
127
- : '0x1002%3D';
139
+ ? YatLink.tags["XMR"].first + '%3D'
140
+ : YatLink.tags["XMR"].last + '%3D';
141
142
parameters += subaddress.address;
143
});
@@ -141,7 +154,7 @@ abstract class YatStoreBase with Store {
154
isFirstAddress = !isFirstAddress;
155
}
156
144
- parameters += '0x1003%3D' + record.address;
157
+ parameters += YatLink.tags["BTC"].first + '%3D' + record.address;
158
});
159
break;
160
case WalletType.litecoin:
@@ -155,7 +168,7 @@ abstract class YatStoreBase with Store {
168
isFirstAddress = !isFirstAddress;
169
}
170
158
- parameters += '0x3fff%3D' + record.address;
171
+ parameters += YatLink.tags["LTC"].first + '%3D' + record.address;
172
});
173
break;
174
default:
lib/view_model/dashboard/dashboard_view_model.dart
+6
@@ -236,6 +236,12 @@ abstract class DashboardViewModelBase with Store {
236
237
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
238
239
+ bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
240
+
241
+ @action
242
+ void furtherShowYatPopup(bool shouldShow) =>
243
+ settingsStore.shouldShowYatPopup = shouldShow;
244
+
245
ReactionDisposer _onMoneroAccountChangeReaction;
246
247
ReactionDisposer _onMoneroBalanceChangeReaction;