feat: Replace buy action to use onramper (#1026)

Adegoke David committed Aug 8, 2023 at 16:09 UTC fb5a1112e2d1036004a116adb55c801108d2992d
2 files changed +199 -171
lib/entities/main_actions.dart
+1 -7
@@ -47,6 +47,7 @@ class MainActions {
47 case WalletType.bitcoin:
48 case WalletType.litecoin:
49 case WalletType.ethereum:
50 + case WalletType.monero:
51 if (viewModel.isEnabledBuyAction) {
52 final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
53 if (DeviceInfo.instance.isMobile) {
@@ -57,13 +58,6 @@ class MainActions {
58 }
59 }
60 break;
60 - case WalletType.monero:
61 - if (viewModel.isEnabledBuyAction) {
62 - // final uri = getIt.get<PayfuraBuyProvider>().requestUrl();
63 - final uri = Uri.parse("https://monero.com/trade");
64 - await launchUrl(uri);
65 - }
66 - break;
61 default:
62 await showPopUp<void>(
63 context: context,
lib/src/screens/dashboard/dashboard_page.dart
+198 -164
@@ -43,30 +43,31 @@ class DashboardPage extends StatelessWidget {
43
44 @override
45 Widget build(BuildContext context) {
46 - return Scaffold(body: LayoutBuilder(
47 - builder: (context, constraints) {
48 - if (DeviceInfo.instance.isDesktop) {
49 - if (constraints.maxWidth > ResponsiveLayoutUtil.kDesktopMaxDashBoardWidthConstraint) {
50 - return getIt.get<DesktopSidebarWrapper>();
51 - } else {
46 + return Scaffold(
47 + body: LayoutBuilder(
48 + builder: (context, constraints) {
49 + if (DeviceInfo.instance.isDesktop) {
50 + if (constraints.maxWidth > ResponsiveLayoutUtil.kDesktopMaxDashBoardWidthConstraint) {
51 + return getIt.get<DesktopSidebarWrapper>();
52 + } else {
53 + return _DashboardPageView(
54 + balancePage: balancePage,
55 + dashboardViewModel: dashboardViewModel,
56 + addressListViewModel: addressListViewModel,
57 + );
58 + }
59 + } else if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {
60 return _DashboardPageView(
61 balancePage: balancePage,
62 dashboardViewModel: dashboardViewModel,
63 addressListViewModel: addressListViewModel,
64 );
65 + } else {
66 + return getIt.get<DesktopSidebarWrapper>();
67 }
58 - } else if (ResponsiveLayoutUtil.instance.shouldRenderMobileUI()) {
59 - return _DashboardPageView(
60 - balancePage: balancePage,
61 - dashboardViewModel: dashboardViewModel,
62 - addressListViewModel: addressListViewModel,
63 - );
64 - } else {
65 - return getIt.get<DesktopSidebarWrapper>();
66 - }
67 -
68 - },
69 - ));
68 + },
69 + ),
70 + );
71 }
72 }
73
@@ -89,13 +90,19 @@ class _DashboardPageView extends BasePage {
90 @override
91 Widget Function(BuildContext, Widget) get rootWrapper =>
92 (BuildContext context, Widget scaffold) => Container(
92 - decoration: BoxDecoration(
93 - gradient: LinearGradient(colors: [
94 - Theme.of(context).colorScheme.secondary,
95 - Theme.of(context).scaffoldBackgroundColor,
96 - Theme.of(context).primaryColor,
97 - ], begin: Alignment.topRight, end: Alignment.bottomLeft)),
98 - child: scaffold);
93 + decoration: BoxDecoration(
94 + gradient: LinearGradient(
95 + colors: [
96 + Theme.of(context).colorScheme.secondary,
97 + Theme.of(context).scaffoldBackgroundColor,
98 + Theme.of(context).primaryColor,
99 + ],
100 + begin: Alignment.topRight,
101 + end: Alignment.bottomLeft,
102 + ),
103 + ),
104 + child: scaffold,
105 + );
106
107 @override
108 bool get resizeToAvoidBottomInset => false;
@@ -106,29 +113,30 @@ class _DashboardPageView extends BasePage {
113 @override
114 Widget middle(BuildContext context) {
115 return SyncIndicator(
109 - dashboardViewModel: dashboardViewModel,
110 - onTap: () => Navigator.of(context, rootNavigator: true).pushNamed(Routes.connectionSync));
116 + dashboardViewModel: dashboardViewModel,
117 + onTap: () => Navigator.of(context, rootNavigator: true).pushNamed(Routes.connectionSync),
118 + );
119 }
120
121 @override
122 Widget trailing(BuildContext context) {
115 - final menuButton = Image.asset('assets/images/menu.png',
116 - color: Theme.of(context)
117 - .accentTextTheme!
118 - .displayMedium!
119 - .backgroundColor);
123 + final menuButton = Image.asset(
124 + 'assets/images/menu.png',
125 + color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor,
126 + );
127
128 return Container(
122 - alignment: Alignment.centerRight,
123 - width: 40,
124 - child: TextButton(
125 - // FIX-ME: Style
126 - //highlightColor: Colors.transparent,
127 - //splashColor: Colors.transparent,
128 - //padding: EdgeInsets.all(0),
129 - onPressed: () => onOpenEndDrawer(),
130 - child: Semantics(
131 - label: S.of(context).wallet_menu, child: menuButton)));
129 + alignment: Alignment.centerRight,
130 + width: 40,
131 + child: TextButton(
132 + // FIX-ME: Style
133 + //highlightColor: Colors.transparent,
134 + //splashColor: Colors.transparent,
135 + //padding: EdgeInsets.all(0),
136 + onPressed: () => onOpenEndDrawer(),
137 + child: Semantics(label: S.of(context).wallet_menu, child: menuButton),
138 + ),
139 + );
140 }
141
142 final DashboardViewModel dashboardViewModel;
@@ -142,56 +150,65 @@ class _DashboardPageView extends BasePage {
150 Widget body(BuildContext context) {
151 final controller = PageController(initialPage: initialPage);
152
145 - reaction((_) => dashboardViewModel.shouldShowMarketPlaceInDashboard, (bool value) {
146 - if (!dashboardViewModel.shouldShowMarketPlaceInDashboard) {
147 - controller.jumpToPage(0);
148 - }
149 - pages.clear();
150 - _isEffectsInstalled = false;
151 - _setEffects(context);
153 + reaction(
154 + (_) => dashboardViewModel.shouldShowMarketPlaceInDashboard,
155 + (bool value) {
156 + if (!dashboardViewModel.shouldShowMarketPlaceInDashboard) {
157 + controller.jumpToPage(0);
158 + }
159 + pages.clear();
160 + _isEffectsInstalled = false;
161 + _setEffects(context);
162
153 - if (value) {
154 - controller.jumpToPage(1);
155 - } else {
156 - controller.jumpToPage(0);
157 - }
158 - });
163 + if (value) {
164 + controller.jumpToPage(1);
165 + } else {
166 + controller.jumpToPage(0);
167 + }
168 + },
169 + );
170 _setEffects(context);
171
172 return SafeArea(
162 - minimum: EdgeInsets.only(bottom: 24),
163 - child: Column(
164 - mainAxisSize: MainAxisSize.max,
165 - children: <Widget>[
166 - Expanded(
167 - child: Observer(builder: (context) {
168 - return PageView.builder(
173 + minimum: EdgeInsets.only(bottom: 24),
174 + child: Column(
175 + mainAxisSize: MainAxisSize.max,
176 + children: <Widget>[
177 + Expanded(
178 + child: Observer(
179 + builder: (context) {
180 + return PageView.builder(
181 controller: controller,
182 itemCount: pages.length,
171 - itemBuilder: (context, index) => pages[index]);
172 - })),
173 - Padding(
174 - padding: EdgeInsets.only(bottom: 24, top: 10),
175 - child: Observer(builder: (context) {
176 - return ExcludeSemantics(
177 - child: SmoothPageIndicator(
178 - controller: controller,
179 - count: pages.length,
180 - effect: ColorTransitionEffect(
181 - spacing: 6.0,
182 - radius: 6.0,
183 - dotWidth: 6.0,
184 - dotHeight: 6.0,
185 - dotColor: Theme.of(context).indicatorColor,
186 - activeDotColor: Theme.of(context)
187 - .accentTextTheme!
188 - .headlineMedium!
189 - .backgroundColor!),
183 + itemBuilder: (context, index) => pages[index],
184 + );
185 + },
186 + ),
187 + ),
188 + Padding(
189 + padding: EdgeInsets.only(bottom: 24, top: 10),
190 + child: Observer(
191 + builder: (context) {
192 + return ExcludeSemantics(
193 + child: SmoothPageIndicator(
194 + controller: controller,
195 + count: pages.length,
196 + effect: ColorTransitionEffect(
197 + spacing: 6.0,
198 + radius: 6.0,
199 + dotWidth: 6.0,
200 + dotHeight: 6.0,
201 + dotColor: Theme.of(context).indicatorColor,
202 + activeDotColor:
203 + Theme.of(context).accentTextTheme.headlineMedium!.backgroundColor!,
204 ),
191 - );
192 - }
193 - )),
194 - Observer(builder: (_) {
205 + ),
206 + );
207 + },
208 + ),
209 + ),
210 + Observer(
211 + builder: (_) {
212 return ClipRect(
213 child: Container(
214 margin: const EdgeInsets.only(left: 16, right: 16),
@@ -204,10 +221,7 @@ class _DashboardPageView extends BasePage {
221 : Colors.transparent,
222 width: 1,
223 ),
207 - color: Theme.of(context)
208 - .textTheme!
209 - .titleLarge!
210 - .backgroundColor!,
224 + color: Theme.of(context).textTheme.titleLarge!.backgroundColor!,
225 ),
226 child: Container(
227 padding: EdgeInsets.only(left: 32, right: 32),
@@ -215,48 +229,48 @@ class _DashboardPageView extends BasePage {
229 mainAxisAlignment: MainAxisAlignment.spaceBetween,
230 children: MainActions.all
231 .where((element) => element.canShow?.call(dashboardViewModel) ?? true)
218 - .map((action) => Semantics(
219 - button: true,
220 - enabled: (action.isEnabled
221 - ?.call(dashboardViewModel) ??
222 - true),
223 - child: ActionButton(
224 - image: Image.asset(action.image,
225 - height: 24,
226 - width: 24,
227 - color: action.isEnabled?.call(
228 - dashboardViewModel) ??
229 - true
230 - ? Theme.of(context)
231 - .accentTextTheme!
232 - .displayMedium!
233 - .backgroundColor!
234 - : Theme.of(context)
235 - .accentTextTheme!
236 - .displaySmall!
237 - .backgroundColor!),
238 - title: action.name(context),
239 - onClick: () async => await action.onTap(
240 - context, dashboardViewModel),
241 - textColor: action.isEnabled
242 - ?.call(dashboardViewModel) ??
243 - true
244 - ? null
232 + .map(
233 + (action) => Semantics(
234 + button: true,
235 + enabled: (action.isEnabled?.call(dashboardViewModel) ?? true),
236 + child: ActionButton(
237 + image: Image.asset(
238 + action.image,
239 + height: 24,
240 + width: 24,
241 + color: action.isEnabled?.call(dashboardViewModel) ?? true
242 + ? Theme.of(context)
243 + .accentTextTheme
244 + .displayMedium!
245 + .backgroundColor!
246 : Theme.of(context)
246 - .accentTextTheme!
247 + .accentTextTheme
248 .displaySmall!
249 .backgroundColor!,
250 ),
250 - ))
251 + title: action.name(context),
252 + onClick: () async =>
253 + await action.onTap(context, dashboardViewModel),
254 + textColor: action.isEnabled?.call(dashboardViewModel) ?? true
255 + ? null
256 + : Theme.of(context)
257 + .accentTextTheme
258 + .displaySmall!
259 + .backgroundColor!,
260 + ),
261 + ),
262 + )
263 .toList(),
264 ),
265 ),
266 ),
267 ),
268 );
257 - }),
258 - ],
259 - ));
269 + },
270 + ),
271 + ],
272 + ),
273 + );
274 }
275
276 void _setEffects(BuildContext context) async {
@@ -264,7 +278,8 @@ class _DashboardPageView extends BasePage {
278 return;
279 }
280 if (dashboardViewModel.shouldShowMarketPlaceInDashboard) {
267 - pages.add(Semantics(
281 + pages.add(
282 + Semantics(
283 label: S.of(context).market_place,
284 child: MarketPlacePage(
285 dashboardViewModel: dashboardViewModel,
@@ -274,73 +289,92 @@ class _DashboardPageView extends BasePage {
289 );
290 }
291 pages.add(Semantics(label: S.of(context).balance_page, child: balancePage));
277 - pages.add(Semantics(
292 + pages.add(
293 + Semantics(
294 label: S.of(context).settings_transactions,
279 - child: TransactionsPage(dashboardViewModel: dashboardViewModel)));
295 + child: TransactionsPage(dashboardViewModel: dashboardViewModel),
296 + ),
297 + );
298 _isEffectsInstalled = true;
299
282 - autorun((_) async {
283 - if (!dashboardViewModel.isOutdatedElectrumWallet) {
284 - return;
285 - }
300 + autorun(
301 + (_) async {
302 + if (!dashboardViewModel.isOutdatedElectrumWallet) {
303 + return;
304 + }
305
287 - await Future<void>.delayed(Duration(seconds: 1));
288 - if (context.mounted) {
289 - await showPopUp<void>(
290 - context: context,
291 - builder: (BuildContext context) {
292 - return AlertWithOneAction(
306 + await Future<void>.delayed(Duration(seconds: 1));
307 + if (context.mounted) {
308 + await showPopUp<void>(
309 + context: context,
310 + builder: (BuildContext context) {
311 + return AlertWithOneAction(
312 alertTitle: S.of(context).pre_seed_title,
313 alertContent: S.of(context).outdated_electrum_wallet_description,
314 buttonText: S.of(context).understand,
296 - buttonAction: () => Navigator.of(context).pop());
297 - });
298 - }
299 - });
315 + buttonAction: () => Navigator.of(context).pop(),
316 + );
317 + },
318 + );
319 + }
320 + },
321 + );
322
323 _showReleaseNotesPopup(context);
324
325 var needToPresentYat = false;
326 var isInactive = false;
327
306 - _onInactiveSub = rootKey.currentState!.isInactive.listen((inactive) {
307 - isInactive = inactive;
328 + _onInactiveSub = rootKey.currentState!.isInactive.listen(
329 + (inactive) {
330 + isInactive = inactive;
331
309 - if (needToPresentYat) {
310 - Future<void>.delayed(Duration(milliseconds: 500)).then((_) {
311 - showPopUp<void>(
312 - context: navigatorKey.currentContext!,
313 - builder: (_) => YatEmojiId(dashboardViewModel.yatStore.emoji));
314 - needToPresentYat = false;
315 - });
316 - }
317 - });
332 + if (needToPresentYat) {
333 + Future<void>.delayed(Duration(milliseconds: 500)).then(
334 + (_) {
335 + showPopUp<void>(
336 + context: navigatorKey.currentContext!,
337 + builder: (_) => YatEmojiId(dashboardViewModel.yatStore.emoji),
338 + );
339 + needToPresentYat = false;
340 + },
341 + );
342 + }
343 + },
344 + );
345
319 - dashboardViewModel.yatStore.emojiIncommingStream.listen((String emoji) {
320 - if (!_isEffectsInstalled || emoji.isEmpty) {
321 - return;
322 - }
346 + dashboardViewModel.yatStore.emojiIncommingStream.listen(
347 + (String emoji) {
348 + if (!_isEffectsInstalled || emoji.isEmpty) {
349 + return;
350 + }
351
324 - needToPresentYat = true;
325 - });
352 + needToPresentYat = true;
353 + },
354 + );
355 }
356
357 void _showReleaseNotesPopup(BuildContext context) async {
358 final sharedPrefs = await SharedPreferences.getInstance();
359 final currentAppVersion =
331 - VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
360 + VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
361 final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion);
362 final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall);
363
364 if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) {
336 - Future<void>.delayed(Duration(seconds: 1), () {
337 - showPopUp<void>(
338 - context: context,
339 - builder: (BuildContext context) {
340 - return ReleaseNotesScreen(
341 - title: 'Version ${dashboardViewModel.settingsStore.appVersion}');
342 - });
343 - });
365 + Future<void>.delayed(
366 + Duration(seconds: 1),
367 + () {
368 + showPopUp<void>(
369 + context: context,
370 + builder: (BuildContext context) {
371 + return ReleaseNotesScreen(
372 + title: 'Version ${dashboardViewModel.settingsStore.appVersion}',
373 + );
374 + },
375 + );
376 + },
377 + );
378
379 sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
380 } else if (isNewInstall!) {