diff --git a/.gitignore b/.gitignore index b0e39e3..f0aa7ca 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ .history .svn/ migrate_working_dir/ +*.jks # IntelliJ related *.iml diff --git a/android/app/build.gradle b/android/app/build.gradle index b3bf5b2..82d6987 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -21,12 +21,18 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - namespace "com.example.dinogrow" + namespace "crypto.game.dinogrow" compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion @@ -45,7 +51,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.dinogrow" + applicationId "crypto.game.dinogrow" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 23 @@ -54,8 +60,20 @@ android { versionName flutterVersionName } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + buildTypes { release { + signingConfig signingConfigs.release + } + debug { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug diff --git a/android/app/src/main/kotlin/com/example/dinogrow/MainActivity.kt b/android/app/src/main/kotlin/com/example/dinogrow/MainActivity.kt index 1efcd0b..7aaa16d 100644 --- a/android/app/src/main/kotlin/com/example/dinogrow/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/dinogrow/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.dinogrow +package crypto.game.dinogrow import io.flutter.embedding.android.FlutterActivity diff --git a/lib/pages/home.dart b/lib/pages/home.dart index d096ba8..6f053f6 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -66,7 +66,10 @@ class _HomeScreenState extends State { fontWeight: FontWeight.bold, color: Colors.black), ), const SizedBox(width: 3), - Text(_balance ?? 'Loading...', + Text( + _balance != null + ? double.parse(_balance ?? '0').toStringAsFixed(2) + : 'Loading...', style: const TextStyle(color: Colors.black)), const SizedBox(width: 3), const Text('SOL', @@ -115,8 +118,12 @@ class _HomeScreenState extends State { children: [ const MiniGamesScreen(), RankingScreen(), - MydinogrowScreen(address: _publicKey ?? ''), - WalletScreen(address: _publicKey ?? '', balance: _balance), + MydinogrowScreen( + address: _publicKey ?? '', getBalance: () => _getBalance()), + WalletScreen( + address: _publicKey ?? '', + balance: _balance, + getBalance: () => _getBalance()), ], ), ), diff --git a/lib/pages/input_phrase.dart b/lib/pages/input_phrase.dart index a205f00..d44cd0f 100644 --- a/lib/pages/input_phrase.dart +++ b/lib/pages/input_phrase.dart @@ -13,7 +13,6 @@ class InputPhraseScreen extends StatefulWidget { class _InputPhraseScreenState extends State { final _formKey = GlobalKey(); - final _words = List.filled(12, ''); bool validationFailed = false; var controllers = List.generate(12, (i) => TextEditingController()); @@ -126,9 +125,18 @@ class _InputPhraseScreenState extends State { void _onSubmit(context) async { if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); - String wordsString = _words.join(' '); + // _formKey.currentState!.save(); + // String wordsString = _words.join(' '); + String wordsString = ''; + + for (var controller in controllers) { + wordsString = '$wordsString${controller.text} '; + } + + wordsString = wordsString.substring(0, wordsString.length - 1); + final t = bip39.validateMnemonic(wordsString); + if (t) { // GoRouter.of(context).push("/passwordSetup/$wordsString"); showModalBottomSheet( diff --git a/lib/pages/login.dart b/lib/pages/login.dart index 7ef5a88..3151f68 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -14,7 +14,6 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { final _formKey = GlobalKey(); final passwordController = TextEditingController(); - bool validationFailed = false; String? password; bool _loading = true; String? key; @@ -83,8 +82,6 @@ class _LoginScreenState extends State { ), ), const SizedBox(height: 8), - Text(validationFailed ? 'Invalid Password' : '', - style: const TextStyle(color: Colors.red)), const SizedBox(height: 8), IntroButtonWidget( text: 'Login', @@ -156,9 +153,16 @@ class _LoginScreenState extends State { } GoRouter.of(context).pushReplacement("/home"); } else { - setState(() { - validationFailed = true; - }); + const snackBar = SnackBar( + content: Text( + 'Error: Invalid Password', + style: TextStyle(color: Colors.white), + ), + backgroundColor: Colors.red, + ); + + ScaffoldMessenger.of(context).showSnackBar(snackBar); + setState(() { _loading = false; }); diff --git a/lib/pages/mini-games/mini_games.dart b/lib/pages/mini-games/mini_games.dart index 005af61..26bd56d 100644 --- a/lib/pages/mini-games/mini_games.dart +++ b/lib/pages/mini-games/mini_games.dart @@ -28,7 +28,8 @@ class _MiniGamesPageState extends State { children: [ GameCardWidget( text: 'UP', - route: "/mini_games/up", + route: "/mini_games/comming_soon", + // route: "/mini_games/up", ), GameCardWidget( text: 'COMING SOON', diff --git a/lib/pages/my-dinogrow/my_dinogrow.dart b/lib/pages/my-dinogrow/my_dinogrow.dart index a3e0c7d..17f5cbf 100644 --- a/lib/pages/my-dinogrow/my_dinogrow.dart +++ b/lib/pages/my-dinogrow/my_dinogrow.dart @@ -18,8 +18,10 @@ import '../../anchor_types/nft_parameters.dart' as anchor_types; class MydinogrowScreen extends StatefulWidget { final String address; + final Function getBalance; - const MydinogrowScreen({super.key, required this.address}); + const MydinogrowScreen( + {super.key, required this.address, required this.getBalance}); @override State createState() => _MydinogrowScreenState(); @@ -120,12 +122,26 @@ class _MydinogrowScreenState extends State { urlImage: userNfts.isNotEmpty ? userNfts[nftSelected]['imageUrl'] : '', ), + const SizedBox(height: 12), + Container( + color: Colors.black, + child: const Padding( + padding: EdgeInsets.all(3), + child: Text( + "Hi ^.^ Please select one Dino to use as character when you play minigames", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + ), const SizedBox(height: 30), IntroButtonWidget( text: 'Claim other Dino', - onPressed: createNft, + onPressed: beforeOtherNft, ), - // TextBoxWidget(text: "Hi ^.^ I'm $nameNft"), ]; bool showDinos = false; @@ -206,7 +222,7 @@ class _MydinogrowScreenState extends State { Future fetchNfts() async { try { - // print('widget.address: ${widget.address}'); + print('widget.address: ${widget.address}'); setState(() { _loading = true; userNfts = []; @@ -223,12 +239,7 @@ class _MydinogrowScreenState extends State { }, body: jsonEncode({ "method": "qn_fetchNFTs", - "params": { - "wallet": widget.address, - // "AUMbL5J7wQuNxV7tpj1mq4SzPxqReDA6VzfkCzpJjcUi", - "page": 1, - "perPage": 10 - } + "params": {"wallet": widget.address, "page": 1, "perPage": 10} })); final dataResponse = jsonDecode(response.body); @@ -242,15 +253,49 @@ class _MydinogrowScreenState extends State { } } finally { if (mounted) { - setState(() { - _loading = false; + Future.delayed(const Duration(seconds: 1), () async { + setState(() { + _loading = false; + }); + Future.delayed(const Duration(seconds: 2), () async { + widget.getBalance(); + }); }); } } } + beforeOtherNft() { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Claim other Dino'), + content: const Text( + 'Before to continue, are you sure to claim other Dino? Remember the transaction has a variable cost so please confirm if you have at least 0.05 SOL in your wallet balance.'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'Cancel'), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + createNft(); + Navigator.pop(context, 'OK'); + }, + child: const Text('Confimr'), + ), + ], + ), + ); + } + createNft() async { try { + if (_loading) { + // avoid double call + return null; + } + if (mounted) { setState(() { _loading = true; @@ -389,6 +434,13 @@ class _MydinogrowScreenState extends State { ); print('Tx successful with hash: $signature'); fetchNfts(); + } catch (e) { + final snackBar = SnackBar( + content: Text('Error: $e', style: const TextStyle(color: Colors.white)), + backgroundColor: Colors.red, + ); + + ScaffoldMessenger.of(context).showSnackBar(snackBar); } finally { if (mounted) { setState(() { diff --git a/lib/pages/wallet/wallet.dart b/lib/pages/wallet/wallet.dart index 46434f1..d2ac224 100644 --- a/lib/pages/wallet/wallet.dart +++ b/lib/pages/wallet/wallet.dart @@ -4,11 +4,30 @@ import 'package:qr_flutter/qr_flutter.dart'; import '../../ui/widgets/widgets.dart'; -class WalletScreen extends StatelessWidget { +class WalletScreen extends StatefulWidget { final String address; final String? balance; + final Function getBalance; - const WalletScreen({super.key, required this.address, this.balance}); + const WalletScreen( + {super.key, + required this.address, + this.balance, + required this.getBalance}); + + @override + State createState() => _WalletScreenState(); +} + +class _WalletScreenState extends State { + @override + void initState() { + super.initState(); + + Future.delayed(const Duration(seconds: 1), () async { + widget.getBalance(); + }); + } @override Widget build(BuildContext context) { @@ -29,7 +48,7 @@ class WalletScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(6), child: QrImageView( - data: address, + data: widget.address, version: QrVersions.auto, size: 200.0, ), @@ -41,7 +60,7 @@ class WalletScreen extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(3), child: Text( - "Your address: $address", + "Your address: ${widget.address}", textAlign: TextAlign.center, style: const TextStyle( color: Colors.white, @@ -54,7 +73,7 @@ class WalletScreen extends StatelessWidget { IntroButtonWidget( text: 'Copy', onPressed: () { - Clipboard.setData(ClipboardData(text: address)); + Clipboard.setData(ClipboardData(text: widget.address)); const snackBar = SnackBar( content: Text('Copied!'), ); @@ -65,7 +84,9 @@ class WalletScreen extends StatelessWidget { const SizedBox(height: 30), Row(children: [ Expanded( - child: TextBoxWidget(text: 'Balace: $balance SOL')), + child: TextBoxWidget( + text: + 'Balace: ${double.parse(widget.balance ?? '0').toStringAsFixed(2)} SOL')), const SizedBox(width: 12), IntroButtonWidget( text: 'Send',