CW-59-New-update-highlight-popup (#863)
* add update pop up * add release notes for monero com * PR comments fixes * Pr coments fixes * minor fixes * update from main * [skip ci] remove unrelated mac os files * add check isNewInstall * update pop-up UI * fix size * Add update popup to desktop dashboard page [skip ci] --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Serhii committed
Apr 21, 2023 at 18:21 UTC
8ffac75e8c939c9dffc54c5b4744b0571a146920
15 files changed
+263
-37
assets/text/Monerocom_Release_Notes.txt
new
+13
@@ -0,0 +1,13 @@
1
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges
2
+WWEE(enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
3
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
4
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
5
+Keep screen awake while the synchronization function
6
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
7
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
8
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
9
+Keep screen awake while the synchronization function
10
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
11
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
12
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
13
+Keep screen awake while the synchronizatio
\ No newline at end of file
assets/text/Release_Notes.txt
new
+13
@@ -0,0 +1,13 @@
1
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges
2
+WWEE(enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
3
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
4
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
5
+Keep screen awake while the synchronization function
6
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
7
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
8
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
9
+Keep screen awake while the synchronization function
10
+Added Fixed Rate for exchanges (enter the "receive" amount on the exchange page to get the fixed rate)
11
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
12
+Changed algorithm for choosing of change address for BTC and LTC electrum wallets
13
+Keep screen awake while the synchronizatio
\ No newline at end of file
lib/di.dart
+2
-1
@@ -208,7 +208,7 @@ Future setup(
208
required Box<TransactionDescription> transactionDescriptionBox,
209
required Box<Order> ordersSource,
210
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
211
- required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource
211
+ required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
212
}) async {
213
_walletInfoSource = walletInfoSource;
214
_nodeSource = nodeSource;
@@ -396,6 +396,7 @@ Future setup(
396
dashboardViewModel: getIt.get<DashboardViewModel>(),
397
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
398
));
399
+
400
getIt.registerFactory<DesktopSidebarWrapper>(() {
401
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
402
return DesktopSidebarWrapper(
lib/entities/default_settings_migration.dart
+7
@@ -42,6 +42,13 @@ Future defaultSettingsMigration(
42
// check current nodes for nullability regardless of the version
43
await checkCurrentNodes(nodes, sharedPreferences);
44
45
+ final isNewInstall = sharedPreferences
46
+ .getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) == null;
47
+
48
+ await sharedPreferences.setBool(
49
+ PreferencesKey.isNewInstall, isNewInstall);
50
+
51
+
52
final currentVersion = sharedPreferences
53
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) ??
54
0;
lib/entities/preferences_key.dart
+3
-1
@@ -41,6 +41,8 @@ class PreferencesKey {
41
42
static const exchangeProvidersSelection = 'exchange-providers-selection';
43
static const clearnetDonationLink = 'clearnet_donation_link';
44
- static const onionDonationLink = 'onion_donation_link';
44
+ static const onionDonationLink = 'onion_donation_link';
45
+ static const lastSeenAppVersion = 'last_seen_app_version';
46
static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard';
47
+ static const isNewInstall = 'is_new_install';
48
}
lib/main.dart
+1
-2
@@ -187,8 +187,7 @@ Future<void> initialSetup(
187
transactionDescriptionBox: transactionDescriptions,
188
ordersSource: ordersSource,
189
anonpayInvoiceInfoSource: anonpayInvoiceInfo,
190
- unspentCoinsInfoSource: unspentCoinsInfoSource,
191
- );
190
+ unspentCoinsInfoSource: unspentCoinsInfoSource);
191
await bootstrap(navigatorKey);
192
monero?.onStartup();
193
}
lib/src/screens/dashboard/dashboard_page.dart
+27
-2
@@ -1,8 +1,10 @@
1
import 'dart:async';
2
+import 'package:cake_wallet/entities/preferences_key.dart';
3
import 'package:cake_wallet/di.dart';
4
import 'package:cake_wallet/entities/main_actions.dart';
5
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
6
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
7
+import 'package:cake_wallet/utils/version_comparator.dart';
8
import 'package:cake_wallet/wallet_type_utils.dart';
9
import 'package:cake_wallet/generated/i18n.dart';
10
import 'package:cake_wallet/routes.dart';
@@ -22,8 +24,12 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
24
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
25
import 'package:flutter_mobx/flutter_mobx.dart';
26
import 'package:mobx/mobx.dart';
27
+import 'package:shared_preferences/shared_preferences.dart';
28
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
29
import 'package:cake_wallet/main.dart';
30
+import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
31
+import 'package:url_launcher/url_launcher.dart';
32
+import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
33
34
class DashboardPage extends StatelessWidget {
35
DashboardPage({
@@ -117,7 +123,7 @@ class _DashboardPageView extends BasePage {
123
@override
124
Widget body(BuildContext context) {
125
final controller = PageController(initialPage: initialPage);
120
-
126
+
127
reaction((_) => dashboardViewModel.shouldShowMarketPlaceInDashboard, (bool value) {
128
if (!dashboardViewModel.shouldShowMarketPlaceInDashboard) {
129
controller.jumpToPage(0);
@@ -131,7 +137,7 @@ class _DashboardPageView extends BasePage {
137
} else {
138
controller.jumpToPage(0);
139
}
134
- });
140
+ });
141
_setEffects(context);
142
143
return SafeArea(
@@ -266,6 +272,25 @@ class _DashboardPageView extends BasePage {
272
}
273
});
274
275
+ final sharedPrefs = await SharedPreferences.getInstance();
276
+ final currentAppVersion =
277
+ VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
278
+ final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion);
279
+ final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall);
280
+
281
+ if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) {
282
+ await Future<void>.delayed(Duration(seconds: 1));
283
+ await showPopUp<void>(
284
+ context: context,
285
+ builder: (BuildContext context) {
286
+ return ReleaseNotesScreen(
287
+ title: 'Version ${dashboardViewModel.settingsStore.appVersion}');
288
+ });
289
+ sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
290
+ } else if (isNewInstall!) {
291
+ sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
292
+ }
293
+
294
var needToPresentYat = false;
295
var isInactive = false;
296
lib/src/screens/dashboard/desktop_dashboard_page.dart
+23
@@ -1,9 +1,12 @@
1
import 'dart:async';
2
+import 'package:cake_wallet/entities/preferences_key.dart';
3
import 'package:cake_wallet/generated/i18n.dart';
4
import 'package:cake_wallet/routes.dart';
5
+import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
6
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
7
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
8
import 'package:cake_wallet/utils/show_pop_up.dart';
9
+import 'package:cake_wallet/utils/version_comparator.dart';
10
import 'package:flutter/material.dart';
11
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
12
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
@@ -11,6 +14,7 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
14
import 'package:mobx/mobx.dart';
15
import 'package:cake_wallet/main.dart';
16
import 'package:cake_wallet/router.dart' as Router;
17
+import 'package:shared_preferences/shared_preferences.dart';
18
19
class DesktopDashboardPage extends StatelessWidget {
20
DesktopDashboardPage({
@@ -107,5 +111,24 @@ class DesktopDashboardPage extends StatelessWidget {
111
112
needToPresentYat = true;
113
});
114
+
115
+ final sharedPrefs = await SharedPreferences.getInstance();
116
+ final currentAppVersion =
117
+ VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
118
+ final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion);
119
+ final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall);
120
+
121
+ if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) {
122
+ await Future<void>.delayed(Duration(seconds: 1));
123
+ await showPopUp<void>(
124
+ context: context,
125
+ builder: (BuildContext context) {
126
+ return ReleaseNotesScreen(
127
+ title: 'Version ${dashboardViewModel.settingsStore.appVersion}');
128
+ });
129
+ sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
130
+ } else if (isNewInstall!) {
131
+ sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
132
+ }
133
}
134
}
lib/src/screens/dashboard/widgets/filter_widget.dart
+1
-2
@@ -16,7 +16,6 @@ class FilterWidget extends StatelessWidget {
16
FilterWidget({required this.dashboardViewModel});
17
18
final DashboardViewModel dashboardViewModel;
19
- final closeIcon = Image.asset('assets/images/close.png', color: Palette.darkBlueCraiola);
19
20
@override
21
Widget build(BuildContext context) {
@@ -101,7 +100,7 @@ class FilterWidget extends StatelessWidget {
100
),
101
],
102
),
104
- AlertCloseButton(image: closeIcon)
103
+ AlertCloseButton()
104
],
105
),
106
);
lib/src/screens/monero_accounts/monero_account_list_page.dart
+1
-4
@@ -27,9 +27,6 @@ class MoneroAccountListPage extends StatelessWidget {
27
}
28
29
final MoneroAccountListViewModel accountListViewModel;
30
- final closeIcon = Image.asset('assets/images/close.png',
31
- color: Palette.darkBlueCraiola,
32
- );
30
31
ScrollController controller;
32
double backgroundHeight;
@@ -163,7 +160,7 @@ class MoneroAccountListPage extends StatelessWidget {
160
)
161
],
162
),
166
- AlertCloseButton(image: closeIcon)
163
+ AlertCloseButton()
164
],
165
),
166
);
lib/src/screens/release_notes/release_notes_screen.dart
new
+141
@@ -0,0 +1,141 @@
1
+import 'dart:convert';
2
+import 'package:cake_wallet/src/widgets/alert_background.dart';
3
+import 'package:cake_wallet/src/widgets/alert_close_button.dart';
4
+import 'package:cake_wallet/wallet_type_utils.dart';
5
+import 'package:flutter/material.dart';
6
+import 'package:flutter/services.dart';
7
+
8
+class ReleaseNotesScreen extends StatelessWidget {
9
+ const ReleaseNotesScreen({
10
+ required this.title,
11
+ });
12
+
13
+ final String title;
14
+
15
+ Future<List<String>> _loadStrings() async {
16
+ String notesContent = await rootBundle.loadString(
17
+ isMoneroOnly ? 'assets/text/Monerocom_Release_Notes.txt' : 'assets/text/Release_Notes.txt');
18
+ return LineSplitter().convert(notesContent);
19
+ }
20
+
21
+ @override
22
+ Widget build(BuildContext context) {
23
+ return Stack(
24
+ alignment: Alignment.center,
25
+ children: [
26
+ AlertBackground(
27
+ child: AlertDialog(
28
+ insetPadding: EdgeInsets.only(left: 16, right: 16, bottom: 48),
29
+ elevation: 0.0,
30
+ contentPadding: EdgeInsets.zero,
31
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(30))),
32
+ content: Container(
33
+ decoration: BoxDecoration(
34
+ borderRadius: BorderRadius.circular(30.0),
35
+ gradient: LinearGradient(colors: [
36
+ Theme.of(context).colorScheme.secondary,
37
+ Theme.of(context).scaffoldBackgroundColor,
38
+ ], begin: Alignment.centerLeft, end: Alignment.centerRight)),
39
+ child: Padding(
40
+ padding: const EdgeInsets.symmetric(horizontal: 24.0),
41
+ child: Stack(
42
+ children: [
43
+ SingleChildScrollView(
44
+ child: Padding(
45
+ padding: const EdgeInsets.only(top: 16.0),
46
+ child: Container(
47
+ alignment: Alignment.bottomCenter,
48
+ child: DefaultTextStyle(
49
+ style: TextStyle(
50
+ decoration: TextDecoration.none,
51
+ fontSize: 24.0,
52
+ fontWeight: FontWeight.bold,
53
+ fontFamily: 'Lato',
54
+ color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
55
+ ),
56
+ child: Text(title),
57
+ ),
58
+ ),
59
+ ),
60
+ ),
61
+ SingleChildScrollView(
62
+ child: Padding(
63
+ padding: EdgeInsets.only(top: 48, bottom: 16),
64
+ child: Container(
65
+ width: double.maxFinite,
66
+ child: Column(
67
+ children: <Widget>[
68
+ ConstrainedBox(
69
+ constraints: BoxConstraints(
70
+ maxHeight: MediaQuery.of(context).size.height * 0.7,
71
+ ),
72
+ child: _getNotesWidget(),
73
+ )
74
+ ],
75
+ ),
76
+ ),
77
+ ),
78
+ ),
79
+ ],
80
+ ),
81
+ ),
82
+ ),
83
+ ),
84
+ ),
85
+ AlertCloseButton(
86
+ bottom: 30,
87
+ )
88
+ ],
89
+ );
90
+ }
91
+
92
+ Widget _getNotesWidget() {
93
+ return FutureBuilder<List<String>>(
94
+ future: _loadStrings(),
95
+ builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
96
+ if (snapshot.hasData) {
97
+ return ListView.builder(
98
+ shrinkWrap: true,
99
+ itemCount: snapshot.data!.length,
100
+ itemBuilder: (BuildContext context, int index) {
101
+ return _getNoteItemWidget(snapshot.data![index], context);
102
+ },
103
+ );
104
+ } else if (snapshot.hasError) {
105
+ return Text('Error: ${snapshot.error}');
106
+ } else {
107
+ return Center(child: CircularProgressIndicator());
108
+ }
109
+ },
110
+ );
111
+ }
112
+
113
+ Widget _getNoteItemWidget(String myString, BuildContext context) {
114
+ return Column(
115
+ children: [
116
+ DefaultTextStyle(
117
+ style: TextStyle(
118
+ decoration: TextDecoration.none,
119
+ fontSize: 16.0,
120
+ fontFamily: 'Lato',
121
+ color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
122
+ ),
123
+ child: Row(
124
+ crossAxisAlignment: CrossAxisAlignment.start,
125
+ children: [
126
+ Padding(
127
+ padding: const EdgeInsets.only(right: 8.0),
128
+ child: Text('•'),
129
+ ),
130
+ Expanded(
131
+ child: Text(myString),
132
+ ),
133
+ ],
134
+ )),
135
+ SizedBox(
136
+ height: 16.0,
137
+ )
138
+ ],
139
+ );
140
+ }
141
+}
lib/src/screens/seed_language/widgets/seed_language_picker.dart
+4
-8
@@ -47,23 +47,19 @@ const List<String> seedLanguages = [
47
enum Places { topLeft, topRight, bottomLeft, bottomRight, inside }
48
49
class SeedLanguagePicker extends StatefulWidget {
50
- SeedLanguagePicker(
51
- {Key? key,
52
- this.selected = defaultSeedLanguage,
53
- required this.onItemSelected})
50
+ SeedLanguagePicker({Key? key, this.selected = defaultSeedLanguage, required this.onItemSelected})
51
: super(key: key);
52
53
final String selected;
54
final Function(String) onItemSelected;
55
56
@override
60
- SeedLanguagePickerState createState() => SeedLanguagePickerState(
61
- selected: selected, onItemSelected: onItemSelected);
57
+ SeedLanguagePickerState createState() =>
58
+ SeedLanguagePickerState(selected: selected, onItemSelected: onItemSelected);
59
}
60
61
class SeedLanguagePickerState extends State<SeedLanguagePicker> {
65
- SeedLanguagePickerState(
66
- {required this.selected, required this.onItemSelected});
62
+ SeedLanguagePickerState({required this.selected, required this.onItemSelected});
63
64
final String selected;
65
final Function(String) onItemSelected;
lib/src/widgets/alert_close_button.dart
+13
-15
@@ -15,20 +15,18 @@ class AlertCloseButton extends StatelessWidget {
15
@override
16
Widget build(BuildContext context) {
17
return Positioned(
18
- bottom: bottom ?? 60,
19
- child: GestureDetector(
20
- onTap: () => Navigator.of(context).pop(),
21
- child: Container(
22
- height: 42,
23
- width: 42,
24
- decoration: BoxDecoration(
25
- color: Colors.white,
26
- shape: BoxShape.circle
27
- ),
28
- child: Center(
29
- child: image ?? closeButton,
30
- ),
18
+ bottom: bottom ?? 60,
19
+ child: GestureDetector(
20
+ onTap: () => Navigator.of(context).pop(),
21
+ child: Container(
22
+ height: 42,
23
+ width: 42,
24
+ decoration: BoxDecoration(color: Colors.white, shape: BoxShape.circle),
25
+ child: Center(
26
+ child: image ?? closeButton,
27
),
32
- ));
28
+ ),
29
+ ),
30
+ );
31
}
34
-}
\ No newline at end of file
32
+}
lib/utils/version_comparator.dart
new
+13
@@ -0,0 +1,13 @@
1
+class VersionComparator {
2
+ static bool isVersion1Greater({required String v1, required String v2}) {
3
+ int v1Number = getExtendedVersionNumber(v1);
4
+ int v2Number = getExtendedVersionNumber(v2);
5
+ return v1Number > v2Number;
6
+ }
7
+
8
+ static int getExtendedVersionNumber(String version) {
9
+ List<String> stringVersionCells = version.split('.');
10
+ List<int> intVersionCells = stringVersionCells.map((i) => int.parse(i)).toList();
11
+ return intVersionCells[0] * 100000 + intVersionCells[1] * 1000 + intVersionCells[2];
12
+ }
13
+}
lib/view_model/dashboard/dashboard_view_model.dart
+1
-2
@@ -43,8 +43,7 @@ abstract class DashboardViewModelBase with Store {
43
required this.settingsStore,
44
required this.yatStore,
45
required this.ordersStore,
46
- required this.anonpayTransactionsStore,
47
- })
46
+ required this.anonpayTransactionsStore})
47
: isOutdatedElectrumWallet = false,
48
hasSellAction = false,
49
isEnabledSellAction = false,