diff --git a/android/app/build.gradle b/android/app/build.gradle index 7ec98cc..d3a8776 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -25,8 +25,14 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + android { - namespace "com.Xperience.FaucetHub.fhub" + namespace "com.Xperience.FaucetHub" 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.Xperience.FaucetHub.fhub" + applicationId "com.Xperience.FaucetHub" // 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 flutter.minSdkVersion @@ -54,11 +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 { // 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 + signingConfig signingConfigs.release } } } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..b6abba8 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,63 @@ +{ + "project_info": { + "project_number": "471640736230", + "project_id": "faucethub-6ff75", + "storage_bucket": "faucethub-6ff75.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:471640736230:android:205f06495a3d96b1f41627", + "android_client_info": { + "package_name": "com.Xperience.FaucetHub" + } + }, + "oauth_client": [ + { + "client_id": "471640736230-264bor5j37konvpp5v6mbmioliqth2gj.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.Xperience.FaucetHub", + "certificate_hash": "9d0ebcd5631981e981ed1b9e7a69a220c0846950" + } + }, + { + "client_id": "471640736230-l3f55tf2qmc6nhuus7ha4jg2tlmuep72.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.Xperience.FaucetHub", + "certificate_hash": "7ba8fb82e48d60e8c5ce423488eb6d1a0d9394cc" + } + }, + { + "client_id": "471640736230-qblci878igh6ubrokkhlim9u99n19p0k.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.Xperience.FaucetHub", + "certificate_hash": "a766d93f9b8aa6e20fce9357bd401d63e3e69d5c" + } + }, + { + "client_id": "471640736230-lm7vslfmt2asvdf7folr7jk14j1culnr.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyA2djP4Bm2jyUWtkQ8a7uarkx2AIm29Vyk" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "471640736230-c23m2qce0m281qb2dbdt3pc4vve77q0m.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a0adcc1..73a9546 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ { - @override void initState() { // TODO: implement initState @@ -26,23 +26,68 @@ class _HomeState extends State { op3 = 1; }); } + + int selectedPageId = 0; + String TitleText = "Home"; @override Widget build(BuildContext context) { + final screenHeight = MediaQuery.of(context).size.height; + final screenWidth = MediaQuery.of(context).size.width; + return Scaffold( backgroundColor: Colors.black, extendBody: true, - body: SafeArea(child: CustomBody( + body: SafeArea( + child: CustomBody( context: context, - onAnimEnd: (){setState(() { - - });}, + onAnimEnd: () { + setState(() {}); + }, + bottomNav: [ + BottomNavBarItem( + icon: Icons.home, + active: selectedPageId == 0, + onPressed: () { + setState(() { + TitleText = "Home"; + selectedPageId = 0; + }); + }, + ), + BottomNavBarItem( + icon: Icons.wallet, + active: selectedPageId == 1, + onPressed: () { + setState(() { + TitleText = "Wallet"; + selectedPageId = 1; + }); + }), + BottomNavBarItem( + icon: Icons.settings, + active: selectedPageId == 2, + onPressed: () { + setState(() { + TitleText = "Settings"; + selectedPageId = 2; + }); + }), + ], child: Padding( padding: const EdgeInsets.all(16.0), - child: Column( - children:[ - Center(child: GradientText(text: "Home",gradient: LinearGradient(colors: [Colors.redAccent, Colors.pink, Colors.deepPurpleAccent]),style: TextStyle(fontSize: 50,fontWeight: FontWeight.bold),)) - ] - ), + child: Column(children: [ + Center( + child: + AnimatedSwitcher( + duration: Duration(milliseconds: 300), + transitionBuilder: + (Widget child, Animation animation) { + return FadeTransition(child: child,opacity: Tween(begin: 0, end: 1).animate(animation)); + }, + child: + GradientText(key: ValueKey(TitleText),text: TitleText,gradient: LinearGradient(colors: [Colors.deepPurpleAccent, Colors.purple,Colors.purpleAccent]),style: TextStyle(fontSize: 45,fontWeight: FontWeight.bold),), + )) + ]), ), )), ); diff --git a/lib/main.dart b/lib/main.dart index 9646205..1e1ead9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'dart:ui'; +import 'package:fhub/home.dart'; import 'package:fhub/src/CustomWidgets.dart'; import 'package:fhub/welcome.dart'; import 'package:flutter/material.dart'; @@ -23,7 +24,13 @@ class MyApp extends StatelessWidget { seedColor: Colors.deepPurple, brightness: Brightness.dark), useMaterial3: true, ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + home: const MyHomePage(), + // ignore: prefer_const_literals_to_create_immutables + routes: { + '/splash' : (context) => MyHomePage(), + '/home' : (context) => Home(), + + }, ); } } diff --git a/lib/src/CustomWidgets.dart b/lib/src/CustomWidgets.dart index b76fe8b..0174ac7 100644 --- a/lib/src/CustomWidgets.dart +++ b/lib/src/CustomWidgets.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; double op1 = 0; double op2 = 0; double op3 = 0; -Widget CustomBody({required Widget child,required BuildContext context, required Function() onAnimEnd}) { +Widget CustomBody({required Widget child,required BuildContext context, required Function() onAnimEnd, List? bottomNav}) { Duration opDuration = const Duration(milliseconds: 1500); var random = new Random(); @@ -110,11 +110,31 @@ Widget CustomBody({required Widget child,required BuildContext context, required ), ), ), + (bottomNav != null) ? Positioned( + bottom: 20, + right: screenWidth * 0.15, + child: Container( + width: screenWidth * 0.7, + height: 70, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(50), + boxShadow: [ + BoxShadow( + color: Colors.black26, offset: Offset.fromDirection(1, 2)) + ]), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: bottomNav, + )), + ) : Container(), AnimatedContainer(duration: opDuration,child: child) ])); } + + Widget NeonButton( {required void Function() onPressed, required String text, @@ -171,9 +191,37 @@ Widget NeonButton( ); } +class BottomNavBarItem extends StatelessWidget { + BottomNavBarItem({required this.active,required IconData this.icon, String? this.text, required Function() this.onPressed,}); + IconData icon; + String? text; + Function() onPressed; + bool active = false; + @override + Widget build(BuildContext context) { + // TODO: implement build + return InkWell( + onTap: (){ + onPressed(); + }, + child: Container( + margin: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AnimatedSize(duration: const Duration(milliseconds: 300),child: Icon(icon,size:active ? 45 : 25, color: active ? Colors.deepPurpleAccent : Colors.blue)), + (text!=null) ? Text(text!) : Container() + ], + ), + ), + ); + } +} + class GradientText extends StatelessWidget { const GradientText( - {required this.text, + {super.key, required this.text, required this.gradient, this.style, }); diff --git a/lib/welcome.dart b/lib/welcome.dart index 8906def..6dbc659 100644 --- a/lib/welcome.dart +++ b/lib/welcome.dart @@ -6,10 +6,10 @@ import 'package:fhub/src/CustomWidgets.dart'; import 'package:flutter/material.dart'; import 'package:google_sign_in/google_sign_in.dart'; -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); +import 'backend/DebugHelper.dart'; - final String title; +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key}); @override State createState() => _MyHomePageState(); @@ -17,7 +17,7 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { int counter = -1; - + bool loginLoading = false; @override void initState() { // TODO: implement initState @@ -132,7 +132,7 @@ class _MyHomePageState extends State { TextEditingController passwordController = TextEditingController(); Widget LoginPage() { - return Header(child: Column(mainAxisSize: MainAxisSize.max, + return Header(child: loginLoading ? const Center(child: Text("Loading...")) : Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Let's Get you ${isLogin ? "Logged-In" : "Registered"}!", @@ -170,12 +170,17 @@ class _MyHomePageState extends State { Dialogs.showAlertDialog(context, "Invalid Input", "Neither the username nor password can contain spaces"); return; } - + setState(() { + loginLoading = true; + }); if(isLogin){ + int loginResult = await LoginManager.Login(usernameController.text, passwordController.text); if(loginResult == 0){ loadHome(); + }else if(loginResult == 5){ + Dialogs.showAlertDialog(context, "Login Failed", "Incorrect username or password"); }else{ Dialogs.showAlertDialog(context, "Login Failed", "Error code : $loginResult"); } @@ -184,10 +189,15 @@ class _MyHomePageState extends State { if(regResult == 0){ loadHome(); + }else if(regResult == 5){ + Dialogs.showAlertDialog(context, "Register Failed", "Username Already exists, Please try again with a different username"); }else{ Dialogs.showAlertDialog(context, "Register Failed", "Error code : $regResult"); } } + setState(() { + loginLoading = false; + }); }, text: isLogin ? "Login" : "Register"), const SizedBox(height: 10,), @@ -245,6 +255,9 @@ class _MyHomePageState extends State { } Future SignWithGoogle() async { + setState(() { + loginLoading = true; + }); GoogleSignIn _googleSignIn = GoogleSignIn( scopes: [ 'email', @@ -255,14 +268,12 @@ class _MyHomePageState extends State { try { GoogleSignInAccount? account = await _googleSignIn.signIn(); - print(account?.email); - - int registerResult = await LoginManager.GoogleLogin(account!.email); - Dialogs.hide(); + String email = account!.email; + Debug.LogResponse(email); + int registerResult = await LoginManager.GoogleLogin(email); if(registerResult == 0){ - // Dialogs.showAlertDialog(context, "Success", "Login done, congrats!"); - Navigator.of(context).pushReplacementNamed('/home'); + loadHome(); }else if(registerResult == 1){ Dialogs.showAlertDialog(context, "Failed", "Servers are unreachable. Please check internet connection and try again."); }else if(registerResult == 5){ @@ -274,6 +285,8 @@ class _MyHomePageState extends State { print(error); print("google sign in failed"); } - + setState(() { + loginLoading = false; + }); } } \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 4ccbff1..81a6eaa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.3" + animated_text_kit: + dependency: "direct main" + description: + name: animated_text_kit + sha256: "37392a5376c9a1a503b02463c38bc0342ef814ddbb8f9977bc90f2a84b22fa92" + url: "https://pub.dev" + source: hosted + version: "4.2.2" async: dependency: transitive description: @@ -25,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + change_app_package_name: + dependency: "direct dev" + description: + name: change_app_package_name + sha256: f9ebaf68a4b5a68c581492579bb68273c523ef325fbf9ce2f1b57fb136ad023b + url: "https://pub.dev" + source: hosted + version: "1.1.0" characters: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a4996d1..1014a17 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,16 +37,15 @@ dependencies: flutter_spinkit: ^5.1.0 google_sign_in: ^5.4.4 firebase_auth: ^4.2.5 - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + animated_text_kit: ^4.2.2 cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter + change_app_package_name: ^1.1.0 + # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your