From 3e0ded0c04417d33f683e78e9da7ef0ff446227d Mon Sep 17 00:00:00 2001 From: "Martin L. Jensen" Date: Thu, 10 Jun 2021 17:59:27 +0200 Subject: [PATCH 1/2] Added functionality to the recieve button. Now it shows a QR and has ability to copy public address --- .../components/algorand/algorand_balance.dart | 2 +- lib/screens/components/text_clip.dart | 51 ++++++++++++ .../wallet/loaded_wallet_widget.dart | 6 +- .../components/wallet/recieve_widget.dart | 62 +++++++++++++++ .../components/wallet/wallet_widget.dart | 61 +++++++++++++- lib/screens/profile/profile.dart | 79 +++---------------- 6 files changed, 186 insertions(+), 75 deletions(-) create mode 100644 lib/screens/components/text_clip.dart create mode 100644 lib/screens/components/wallet/recieve_widget.dart diff --git a/lib/screens/components/algorand/algorand_balance.dart b/lib/screens/components/algorand/algorand_balance.dart index 22854d7..4ca02aa 100644 --- a/lib/screens/components/algorand/algorand_balance.dart +++ b/lib/screens/components/algorand/algorand_balance.dart @@ -14,7 +14,7 @@ class AlgorandBalance extends StatelessWidget { SizedBox( width: 16, height: 16, - child: Image.asset("assets/images/algo_icon.png"), + child: Image.asset('assets/images/algo_icon.png'), ), HorizontalSpacing(of: paddingSizeNormal), Text( diff --git a/lib/screens/components/text_clip.dart b/lib/screens/components/text_clip.dart new file mode 100644 index 0000000..11e914d --- /dev/null +++ b/lib/screens/components/text_clip.dart @@ -0,0 +1,51 @@ +import 'package:clipboard/clipboard.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_algo_wallet/theme/theme.dart'; + +class TextClip extends StatelessWidget { + const TextClip({ + Key? key, + required this.textToCopy, + this.snackBarText, + }) : super(key: key); + + final String textToCopy; + final String? snackBarText; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () async { + await FlutterClipboard.copy(textToCopy); + + if (snackBarText != null) { + final snackBar = SnackBar( + behavior: SnackBarBehavior.floating, + content: Text(snackBarText!), + ); + + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + }, + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: textToCopy, + style: regularTextStyle.copyWith(fontSize: fontSizeSmall), + ), + WidgetSpan( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Icon( + Icons.copy, + size: 20, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/components/wallet/loaded_wallet_widget.dart b/lib/screens/components/wallet/loaded_wallet_widget.dart index 4c30f8c..d4687db 100644 --- a/lib/screens/components/wallet/loaded_wallet_widget.dart +++ b/lib/screens/components/wallet/loaded_wallet_widget.dart @@ -2,6 +2,7 @@ import 'package:algorand_dart/algorand_dart.dart'; import 'package:flutter/material.dart'; import 'package:flutter_algo_wallet/global_providers/account/account_provider.dart'; import 'package:flutter_algo_wallet/screens/components/algorand/algorand_balance.dart'; +import 'package:flutter_algo_wallet/screens/components/wallet/recieve_widget.dart'; import 'package:flutter_algo_wallet/theme/theme.dart'; import 'package:flutter_algo_wallet/widgets/spacing.dart'; import 'package:provider/provider.dart'; @@ -58,10 +59,7 @@ class LoadedWalletWidget extends StatelessWidget { ), HorizontalSpacing(of: paddingSizeNormal), Expanded( - child: ElevatedButton( - onPressed: () {}, - child: Text('Recieve'), - ), + child: RecieveWidget(account: account), ), ], ), diff --git a/lib/screens/components/wallet/recieve_widget.dart b/lib/screens/components/wallet/recieve_widget.dart new file mode 100644 index 0000000..4bab63c --- /dev/null +++ b/lib/screens/components/wallet/recieve_widget.dart @@ -0,0 +1,62 @@ +import 'package:algorand_dart/algorand_dart.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_algo_wallet/screens/components/text_clip.dart'; +import 'package:flutter_algo_wallet/theme/dimens.dart'; +import 'package:flutter_algo_wallet/widgets/spacing.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +class RecieveWidget extends StatelessWidget { + const RecieveWidget({ + Key? key, + required this.account, + }) : super(key: key); + + final Account account; + + @override + Widget build(BuildContext context) { + return ElevatedButton( + child: Text('Recieve'), + onPressed: () { + showModalBottomSheet( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + context: context, + builder: (BuildContext context) { + return SafeArea( + child: Padding( + padding: const EdgeInsets.all(paddingSizeDefault), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + QrImage( + data: + 'https://testnet.algoexplorer.io/address/${account.publicAddress}', + version: QrVersions.auto, + size: 320, + gapless: false, + embeddedImage: AssetImage('assets/images/algo_icon.png'), + embeddedImageStyle: QrEmbeddedImageStyle( + size: Size(80, 80), + ), + ), + const VerticalSpacing(of: marginSizeDefault), + TextClip(textToCopy: account.publicAddress), + const VerticalSpacing(of: marginSizeDefault), + ElevatedButton( + child: const Text('Close'), + onPressed: () => Navigator.pop(context), + ), + ], + ), + ), + ); + }, + ); + }, + ); + } +} diff --git a/lib/screens/components/wallet/wallet_widget.dart b/lib/screens/components/wallet/wallet_widget.dart index 7daaf48..07d8619 100644 --- a/lib/screens/components/wallet/wallet_widget.dart +++ b/lib/screens/components/wallet/wallet_widget.dart @@ -1,5 +1,6 @@ import 'package:algorand_dart/algorand_dart.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_algo_wallet/bottom_navbar/bottom_navbar_provider.dart'; import 'package:flutter_algo_wallet/global_providers/account/account_provider.dart'; import 'package:flutter_algo_wallet/screens/dashboard/dashboard_screen_provider.dart'; import 'package:flutter_algo_wallet/theme/theme.dart'; @@ -16,6 +17,7 @@ class WalletWidget extends StatelessWidget { final algorand = context.watch(); final dashboardScreenMode = context.watch(); final account = context.watch(); + final navBarProvider = context.watch(); return Padding( padding: const EdgeInsets.all(paddingSizeDefault), @@ -37,6 +39,11 @@ class WalletWidget extends StatelessWidget { ); ScaffoldMessenger.of(context).showSnackBar(snackBar); + + // If we create a new wallet from the wallet tab (1) then we should navigate to the dashboard + if (navBarProvider.currentIndex != 0) { + navBarProvider.currentIndex = 0; + } }, child: Text('Create a new wallet'), style: ButtonStyle( @@ -50,7 +57,25 @@ class WalletWidget extends StatelessWidget { message: 'Currently unavailable!', child: ElevatedButton( key: Key('IMPORT_WALLET_BUTTON'), - onPressed: null, // TODO + onPressed: () async { + final restoredAccount = + await Account.fromSeedPhrase(seedPhrase); + account.account = restoredAccount; + dashboardScreenMode.currentWalletStatus = + DashboardScreenMode.LOADED_WALLET; + + final snackBar = SnackBar( + behavior: SnackBarBehavior.floating, + content: Text('Imported test wallet.'), + ); + + ScaffoldMessenger.of(context).showSnackBar(snackBar); + + // If we import a wallet from the wallet tab (1) then we should navigate to the dashboard + if (navBarProvider.currentIndex != 0) { + navBarProvider.currentIndex = 0; + } + }, child: Text('Import existing wallet'), style: ButtonStyle( fixedSize: MaterialStateProperty.all( @@ -64,3 +89,37 @@ class WalletWidget extends StatelessWidget { ); } } + +// TODO: Just for testing +// Random Algorand public address +final publicAddress = + 'D3ZUVRXN2KN44O6Z335HI6SOY7WLQW3RNP7HPGTAXBKZWPWKKOZDKJJT5Q'; + +// Random Algorand seed phrase +final seedPhrase = [ + 'certain', + 'social', + 'kidney', + 'magic', + 'special', + 'replace', + 'genuine', + 'meadow', + 'pulse', + 'tennis', + 'unable', + 'obey', + 'urban', + 'clerk', + 'domain', + 'sock', + 'belt', + 'slam', + 'hybrid', + 'tank', + 'lumber', + 'reason', + 'canvas', + 'about', + 'wink' +]; diff --git a/lib/screens/profile/profile.dart b/lib/screens/profile/profile.dart index d2bd2a1..2b2d82a 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -1,6 +1,7 @@ -import 'package:clipboard/clipboard.dart'; import 'package:flutter/material.dart'; import 'package:flutter_algo_wallet/global_providers/account/account_provider.dart'; +import 'package:flutter_algo_wallet/screens/components/text_clip.dart'; +import 'package:flutter_algo_wallet/screens/components/wallet/wallet_widget.dart'; import 'package:flutter_algo_wallet/screens/dashboard/dashboard_screen_provider.dart'; import 'package:flutter_algo_wallet/widgets/spacing.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -16,14 +17,10 @@ class ProfileScreen extends StatelessWidget { Widget build(BuildContext context) { final dashboardProvider = context.watch(); + // If a wallet has not been loaded then we should show the wallet. if (dashboardProvider.currentWalletStatus != DashboardScreenMode.LOADED_WALLET) { - // TODO: WIDGET TEST THIS - return Container( - child: Center( - child: Text('No account created or wallet'), - ), - ); + return WalletWidget(); } final accountProvider = context.watch(); @@ -40,36 +37,9 @@ class ProfileScreen extends StatelessWidget { style: boldTextStyle.copyWith(fontSize: fontSizeMedium), ), const VerticalSpacing(of: marginSizeSmall), - GestureDetector( - onTap: () async { - await FlutterClipboard.copy(account.publicAddress); - - final snackBar = SnackBar( - behavior: SnackBarBehavior.floating, - content: Text('Algorand address copied to clipboard'), - ); - - ScaffoldMessenger.of(context).showSnackBar(snackBar); - }, - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: account.publicAddress, - style: regularTextStyle.copyWith(fontSize: fontSizeSmall), - ), - WidgetSpan( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Icon( - Icons.copy, - size: 20, - ), - ), - ), - ], - ), - ), + TextClip( + textToCopy: account.publicAddress, + snackBarText: 'Algorand address copied to clipboard', ), const VerticalSpacing(of: marginSizeDefault), @@ -87,38 +57,9 @@ class ProfileScreen extends StatelessWidget { if (!snapshot.hasData) return CircularProgressIndicator(); final seedPhrase = (snapshot.data ?? []).join(' '); - return GestureDetector( - onTap: () async { - await FlutterClipboard.copy(seedPhrase); - - final snackBar = SnackBar( - behavior: SnackBarBehavior.floating, - content: Text('Word list copied to clipboard'), - ); - - ScaffoldMessenger.of(context).showSnackBar(snackBar); - }, - child: RichText( - text: TextSpan( - children: [ - TextSpan( - text: seedPhrase, - style: regularTextStyle.copyWith( - fontSize: fontSizeSmall), - ), - WidgetSpan( - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8.0), - child: Icon( - Icons.copy, - size: 20, - ), - ), - ), - ], - ), - ), + return TextClip( + textToCopy: seedPhrase, + snackBarText: 'Word list copied to clipboard', ); }), From 065dd8ba5d8b42ed72f785cb369372f49ef7f136 Mon Sep 17 00:00:00 2001 From: "Martin L. Jensen" Date: Thu, 10 Jun 2021 18:15:49 +0200 Subject: [PATCH 2/2] Made qr code smaller --- lib/screens/components/wallet/recieve_widget.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/components/wallet/recieve_widget.dart b/lib/screens/components/wallet/recieve_widget.dart index 4bab63c..b8d8a9a 100644 --- a/lib/screens/components/wallet/recieve_widget.dart +++ b/lib/screens/components/wallet/recieve_widget.dart @@ -36,7 +36,7 @@ class RecieveWidget extends StatelessWidget { data: 'https://testnet.algoexplorer.io/address/${account.publicAddress}', version: QrVersions.auto, - size: 320, + size: 250, gapless: false, embeddedImage: AssetImage('assets/images/algo_icon.png'), embeddedImageStyle: QrEmbeddedImageStyle(