From fcb23a5f0f6d5880ae2d31809d64a510a3cb5875 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 30 Jul 2019 13:12:42 +0530 Subject: [PATCH 01/37] Update README.md --- README.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/README.md b/README.md index 16558cf..7019c05 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,3 @@ # Numbers - Flutter Game -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. From d7aeb5621916ad60256dedfe0f1b0db08a95e3dc Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 30 Jul 2019 13:16:47 +0530 Subject: [PATCH 02/37] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7019c05..3d483c4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Numbers - Flutter Game -Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. +### Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. + + Demo Here From cf35503b119c17341fac95a18aecbb3270a51e14 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 30 Jul 2019 13:17:02 +0530 Subject: [PATCH 03/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d483c4..4ecea21 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ ### Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. - Demo Here + See Demo Here From a41022d34f407bcd6df4981f91bb3185d911f639 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 30 Jul 2019 13:17:19 +0530 Subject: [PATCH 04/37] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 4ecea21..1abb683 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ # Numbers - Flutter Game -### Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. - - See Demo Here +Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. See Demo Here From 1dfc6d833dae1b2b3a5c68324a0f19a83e844439 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Wed, 31 Jul 2019 15:03:25 +0530 Subject: [PATCH 05/37] firebase core added --- android/app/build.gradle | 9 ++- android/app/google-services.json | 40 ++++++++++ android/app/src/debug/AndroidManifest.xml | 2 +- android/app/src/main/AndroidManifest.xml | 2 +- .../numbers}/MainActivity.java | 2 +- android/app/src/profile/AndroidManifest.xml | 2 +- android/build.gradle | 3 +- ios/Podfile.lock | 74 +++++++++++++++++++ ios/Runner.xcodeproj/project.pbxproj | 6 +- lib/main.dart | 20 +++-- pubspec.lock | 7 ++ pubspec.yaml | 3 +- 12 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 android/app/google-services.json rename android/app/src/main/java/com/{example/add_numbers => thamaraiselvam/numbers}/MainActivity.java (90%) diff --git a/android/app/build.gradle b/android/app/build.gradle index ec84bef..12ab27e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -33,7 +33,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.numbers" + applicationId "com.thamaraiselvam.numbers" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() @@ -56,6 +56,9 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation 'com.google.firebase:firebase-core:17.0.1' } + +apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..ff04c0b --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,40 @@ +{ + "project_info": { + "project_number": "949039664482", + "firebase_url": "https://numbers-game-793c3.firebaseio.com", + "project_id": "numbers-game-793c3", + "storage_bucket": "numbers-game-793c3.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:949039664482:android:805680a6bc372b6a", + "android_client_info": { + "package_name": "com.thamaraiselvam.numbers" + } + }, + "oauth_client": [ + { + "client_id": "949039664482-2fvmt0aa8ngpmg70gtr9efuv2rm01se7.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBqA77WYFEVn_Ty7fER_21cHFjZAcHZQn8" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "949039664482-2fvmt0aa8ngpmg70gtr9efuv2rm01se7.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 99304d4..e5e564c 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.thamaraiselvam.numbers"> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0ec1c08..055b774 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.thamaraiselvam.numbers"> diff --git a/android/build.gradle b/android/build.gradle index bb8a303..3591193 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,8 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.google.gms:google-services:4.3.0' } } diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 734635c..d80597b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,20 +1,94 @@ PODS: + - Firebase/Core (6.4.0): + - Firebase/CoreOnly + - FirebaseAnalytics (= 6.0.3) + - Firebase/CoreOnly (6.4.0): + - FirebaseCore (= 6.0.4) + - firebase_core (0.0.1): + - Firebase/Core + - Flutter + - FirebaseAnalytics (6.0.3): + - FirebaseCore (~> 6.0) + - FirebaseInstanceID (~> 4.2) + - GoogleAppMeasurement (= 6.0.3) + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" + - nanopb (~> 0.3) + - FirebaseCore (6.0.4): + - GoogleUtilities/Environment (~> 6.0) + - GoogleUtilities/Logger (~> 6.0) + - FirebaseInstanceID (4.2.1): + - FirebaseCore (~> 6.0) + - GoogleUtilities/Environment (~> 6.0) + - GoogleUtilities/UserDefaults (~> 6.0) - Flutter (1.0.0) + - GoogleAppMeasurement (6.0.3): + - GoogleUtilities/AppDelegateSwizzler (~> 6.0) + - GoogleUtilities/MethodSwizzler (~> 6.0) + - GoogleUtilities/Network (~> 6.0) + - "GoogleUtilities/NSData+zlib (~> 6.0)" + - nanopb (~> 0.3) + - GoogleUtilities/AppDelegateSwizzler (6.2.3): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (6.2.3) + - GoogleUtilities/Logger (6.2.3): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (6.2.3): + - GoogleUtilities/Logger + - GoogleUtilities/Network (6.2.3): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (6.2.3)" + - GoogleUtilities/Reachability (6.2.3): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (6.2.3): + - GoogleUtilities/Logger + - nanopb (0.3.901): + - nanopb/decode (= 0.3.901) + - nanopb/encode (= 0.3.901) + - nanopb/decode (0.3.901) + - nanopb/encode (0.3.901) - shared_preferences (0.0.1): - Flutter DEPENDENCIES: + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - Flutter (from `.symlinks/flutter/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Firebase + - FirebaseAnalytics + - FirebaseCore + - FirebaseInstanceID + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + EXTERNAL SOURCES: + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" Flutter: :path: ".symlinks/flutter/ios" shared_preferences: :path: ".symlinks/plugins/shared_preferences/ios" SPEC CHECKSUMS: + Firebase: 9445469655a98e9010737f4bc4720e5bda465873 + firebase_core: b3b02d0b5e9d01aab5e50ba7cbcf84c73cb6883c + FirebaseAnalytics: 69fe25866d2ec87c6f02d72c3c9a82bce9c065a0 + FirebaseCore: 7ea99e200f0024262650be56623fbe6a7bef1707 + FirebaseInstanceID: 9782fcfb89e4d7da76cc28eac4b8543dc7be4a4b Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a + GoogleAppMeasurement: 1e45fa601e6280c180880d57010390f6679cd971 + GoogleUtilities: d2b0e277a95962e09bb27f5cd42f5f0b6a506c7d + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f3b7b3e..dcac373 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -390,7 +390,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; @@ -519,7 +519,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; @@ -542,7 +542,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; diff --git a/lib/main.dart b/lib/main.dart index f41155f..e675ac6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,18 +1,26 @@ +import 'package:flutter/material.dart'; + import 'package:flutter/services.dart'; import 'package:numbers/screens/GameScreen/GameScreen.dart'; import 'package:numbers/screens/TurorialScreen.dart'; import 'package:numbers/screens/LoadingScreen.dart'; -import 'package:flutter/material.dart'; import 'package:numbers/screens/SplashScreen.dart'; import 'package:numbers/screens/HomeScreen/HomeScreen.dart'; -Future main() async { + +void main() { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); - runApp( - new MaterialApp( + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( initialRoute: '/', routes: { '/': (BuildContext context) => SplashScreen(), @@ -21,5 +29,7 @@ Future main() async { '/game': (BuildContext context) => GameScreen(), '/tutorial': (BuildContext context) => TurorialScreen(), }, - )); + // navigatorObservers: [observer], + ); + } } diff --git a/pubspec.lock b/pubspec.lock index fdb6a09..2774af1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0+8" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 2952ed7..e3840b4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,7 +25,8 @@ dependencies: cupertino_icons: ^0.1.2 shared_preferences: ^0.5.3+4 timeago: ^2.0.18 - + firebase_core: ^0.4.0+8 + # firebase_analytics: ^4.0.2 dev_dependencies: flutter_test: From d62d8a2c953a0890b7ba21c2d93b0b6aa27e4de4 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Wed, 31 Jul 2019 15:17:41 +0530 Subject: [PATCH 06/37] Perfomance plugin added --- android/app/build.gradle | 5 ++++- android/build.gradle | 3 ++- android/gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 12ab27e..83a7dac 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -59,6 +59,9 @@ dependencies { androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation 'com.google.firebase:firebase-core:17.0.1' + implementation 'com.google.firebase:firebase-perf:18.0.1' } -apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin +apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.google.firebase.firebase-perf' + // Google Play services Gradle plugin diff --git a/android/build.gradle b/android/build.gradle index 3591193..e89031b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,8 +5,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:3.4.0' classpath 'com.google.gms:google-services:4.3.0' + classpath 'com.google.firebase:perf-plugin:1.3.0' } } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 2819f02..9b6616c 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip From dce7d73043b079edc7f3d75c8481af44d14734ac Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Wed, 31 Jul 2019 15:55:58 +0530 Subject: [PATCH 07/37] added firebase analytics --- android/app/build.gradle | 1 + android/build.gradle | 4 ++++ lib/main.dart | 8 +++++++- pubspec.lock | 7 +++++++ pubspec.yaml | 3 ++- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 83a7dac..3e8c7e3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -60,6 +60,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation 'com.google.firebase:firebase-core:17.0.1' implementation 'com.google.firebase:firebase-perf:18.0.1' + implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' } apply plugin: 'com.google.gms.google-services' diff --git a/android/build.gradle b/android/build.gradle index e89031b..25bdc38 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,6 +1,9 @@ buildscript { repositories { google() + maven { + url 'https://maven.fabric.io/public' + } jcenter() } @@ -8,6 +11,7 @@ buildscript { classpath 'com.android.tools.build:gradle:3.4.0' classpath 'com.google.gms:google-services:4.3.0' classpath 'com.google.firebase:perf-plugin:1.3.0' + classpath 'io.fabric.tools:gradle:1.31.0' // Crashlytics plugin } } diff --git a/lib/main.dart b/lib/main.dart index e675ac6..b9d08c0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,12 @@ +import 'package:firebase_analytics/observer.dart'; import 'package:flutter/material.dart'; - import 'package:flutter/services.dart'; import 'package:numbers/screens/GameScreen/GameScreen.dart'; import 'package:numbers/screens/TurorialScreen.dart'; import 'package:numbers/screens/LoadingScreen.dart'; import 'package:numbers/screens/SplashScreen.dart'; import 'package:numbers/screens/HomeScreen/HomeScreen.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; void main() { @@ -18,6 +19,8 @@ void main() { class MyApp extends StatelessWidget { + FirebaseAnalytics analytics = FirebaseAnalytics(); + @override Widget build(BuildContext context) { return MaterialApp( @@ -29,6 +32,9 @@ class MyApp extends StatelessWidget { '/game': (BuildContext context) => GameScreen(), '/tutorial': (BuildContext context) => TurorialScreen(), }, + navigatorObservers: [ + FirebaseAnalyticsObserver(analytics: analytics), + ], // navigatorObservers: [observer], ); } diff --git a/pubspec.lock b/pubspec.lock index 2774af1..c93635a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0+1" firebase_core: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index e3840b4..e6035e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,7 +26,8 @@ dependencies: shared_preferences: ^0.5.3+4 timeago: ^2.0.18 firebase_core: ^0.4.0+8 - # firebase_analytics: ^4.0.2 + firebase_analytics: ^1.0.2 + dev_dependencies: flutter_test: From 01d607cd3408bf0efc163a47748abb7809d736f6 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Wed, 31 Jul 2019 16:06:18 +0530 Subject: [PATCH 08/37] firebase re core added --- android/app/build.gradle | 7 ++-- android/app/google-services.json | 40 +++++++++++++++++++ android/app/src/debug/AndroidManifest.xml | 2 +- android/app/src/main/AndroidManifest.xml | 2 +- .../com/example/add_numbers/MainActivity.java | 2 +- android/app/src/profile/AndroidManifest.xml | 2 +- android/build.gradle | 4 +- ios/Runner.xcodeproj/project.pbxproj | 6 +-- lib/utils/Config.dart | 2 +- pubspec.lock | 7 ++++ pubspec.yaml | 1 + 11 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 android/app/google-services.json diff --git a/android/app/build.gradle b/android/app/build.gradle index ec84bef..6be5a56 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -33,7 +33,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.numbers" + applicationId "com.thamaraiselvam.numbers" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() @@ -56,6 +56,7 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'com.android.support.test:runner:1.1.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.1.1' + implementation 'com.google.firebase:firebase-core:17.0.1' } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..31f443a --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,40 @@ +{ + "project_info": { + "project_number": "949039664482", + "firebase_url": "https://numbers-game-793c3.firebaseio.com", + "project_id": "numbers-game-793c3", + "storage_bucket": "numbers-game-793c3.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:949039664482:android:805680a6bc372b6a", + "android_client_info": { + "package_name": "com.thamaraiselvam.numbers" + } + }, + "oauth_client": [ + { + "client_id": "949039664482-2fvmt0aa8ngpmg70gtr9efuv2rm01se7.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBqA77WYFEVn_Ty7fER_21cHFjZAcHZQn8" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "949039664482-2fvmt0aa8ngpmg70gtr9efuv2rm01se7.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" + } diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 99304d4..e5e564c 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.thamaraiselvam.numbers"> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0ec1c08..055b774 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.thamaraiselvam.numbers"> diff --git a/android/build.gradle b/android/build.gradle index bb8a303..647e14d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.google.gms:google-services:4.3.0' + } } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f3b7b3e..dcac373 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -390,7 +390,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; @@ -519,7 +519,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; @@ -542,7 +542,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.numbers; + PRODUCT_BUNDLE_IDENTIFIER = com.thamaraiselvam.numbers; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; diff --git a/lib/utils/Config.dart b/lib/utils/Config.dart index e473681..bbfb55e 100644 --- a/lib/utils/Config.dart +++ b/lib/utils/Config.dart @@ -1,3 +1,3 @@ -const int gameDuration = 60; +const int gameDuration = 5; const Map costs = {'success': 1000, 'fail': -500, 'block': 100}; const int maxKeepGameHistoryCount = 6; diff --git a/pubspec.lock b/pubspec.lock index fdb6a09..c217902 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + firebase_core: + dependency: "direct dev" + description: + name: firebase_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.0+8" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 2952ed7..76cde97 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,6 +31,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_launcher_icons: "^0.7.2" + firebase_core: ^0.4.0+8 flutter_icons: android: "launcher_icon" From 95b670a625a8b44dd507c98ec634d6131e458c0d Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Wed, 31 Jul 2019 16:55:12 +0530 Subject: [PATCH 09/37] firebase analytics added --- android/app/build.gradle | 2 ++ android/build.gradle | 1 - lib/main.dart | 31 +++++++++++++++++++------------ pubspec.lock | 7 +++++++ pubspec.yaml | 1 + 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 6be5a56..8717a02 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -60,3 +60,5 @@ dependencies { androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.1.1' implementation 'com.google.firebase:firebase-core:17.0.1' } + +apply plugin: 'com.google.gms.google-services' diff --git a/android/build.gradle b/android/build.gradle index 647e14d..3591193 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,7 +7,6 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.3.0' classpath 'com.google.gms:google-services:4.3.0' - } } diff --git a/lib/main.dart b/lib/main.dart index f41155f..b4cb52b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,21 +5,28 @@ import 'package:numbers/screens/LoadingScreen.dart'; import 'package:flutter/material.dart'; import 'package:numbers/screens/SplashScreen.dart'; import 'package:numbers/screens/HomeScreen/HomeScreen.dart'; +import 'package:firebase_analytics/observer.dart'; +import 'package:firebase_analytics/firebase_analytics.dart'; Future main() async { + FirebaseAnalytics analytics = FirebaseAnalytics(); + SystemChrome.setPreferredOrientations([ - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ]); + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); runApp( new MaterialApp( - initialRoute: '/', - routes: { - '/': (BuildContext context) => SplashScreen(), - '/home': (BuildContext context) => HomeScreen(), - '/loading': (BuildContext context) => LoadingScreen(), - '/game': (BuildContext context) => GameScreen(), - '/tutorial': (BuildContext context) => TurorialScreen(), - }, - )); + initialRoute: '/', + routes: { + '/': (BuildContext context) => SplashScreen(), + '/home': (BuildContext context) => HomeScreen(), + '/loading': (BuildContext context) => LoadingScreen(), + '/game': (BuildContext context) => GameScreen(), + '/tutorial': (BuildContext context) => TurorialScreen(), + }, + navigatorObservers: [ + FirebaseAnalyticsObserver(analytics: analytics), + ], + )); } diff --git a/pubspec.lock b/pubspec.lock index c217902..72c8af9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + firebase_analytics: + dependency: "direct dev" + description: + name: firebase_analytics + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0+1" firebase_core: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index 76cde97..8e0635f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,7 @@ dev_dependencies: sdk: flutter flutter_launcher_icons: "^0.7.2" firebase_core: ^0.4.0+8 + firebase_analytics: ^1.0.2 flutter_icons: android: "launcher_icon" From 451220c6ef56d9841894489972b1afd915186773 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 10:14:50 +0530 Subject: [PATCH 10/37] crashlytics added --- android/app/build.gradle | 1 + android/build.gradle | 2 + lib/main.dart | 51 ++++++++++++++----- .../HomeScreen/tutorialBtn.widget.dart | 5 +- lib/utils/Config.dart | 1 + pubspec.lock | 11 +++- pubspec.yaml | 1 + 7 files changed, 53 insertions(+), 19 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 8717a02..54893c7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -62,3 +62,4 @@ dependencies { } apply plugin: 'com.google.gms.google-services' +apply plugin: 'io.fabric' diff --git a/android/build.gradle b/android/build.gradle index 1682eb8..6431158 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -10,6 +10,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.3.0' classpath 'com.google.gms:google-services:4.3.0' + classpath 'io.fabric.tools:gradle:1.+' } } @@ -17,6 +18,7 @@ allprojects { repositories { google() jcenter() + maven { url 'https://maven.fabric.io/public' } } } diff --git a/lib/main.dart b/lib/main.dart index baa33b2..8b4aea2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:firebase_analytics/observer.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -6,28 +7,50 @@ import 'package:numbers/screens/TurorialScreen.dart'; import 'package:numbers/screens/LoadingScreen.dart'; import 'package:numbers/screens/SplashScreen.dart'; import 'package:numbers/screens/HomeScreen/HomeScreen.dart'; -import 'package:firebase_analytics/observer.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:flutter_crashlytics/flutter_crashlytics.dart'; +import 'package:numbers/utils/Config.dart'; Future main() async { - FirebaseAnalytics analytics = FirebaseAnalytics(); + + FirebaseAnalytics analytics = FirebaseAnalytics(); + + FlutterError.onError = (FlutterErrorDetails details) { + if (isInDebugMode) { + // In development mode simply print to console. + FlutterError.dumpErrorToConsole(details); + } else { + // In production mode report to the application zone to report to + // Crashlytics. + Zone.current.handleUncaughtError(details.exception, details.stack); + } + }; + + await FlutterCrashlytics().initialize(); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); - runApp( - new MaterialApp( - initialRoute: '/', - routes: { - '/': (BuildContext context) => SplashScreen(), - '/home': (BuildContext context) => HomeScreen(), - '/loading': (BuildContext context) => LoadingScreen(), - '/game': (BuildContext context) => GameScreen(), - '/tutorial': (BuildContext context) => TurorialScreen(), - }, - navigatorObservers: [ + + runZoned>(() async { + runApp(new MaterialApp( + initialRoute: '/', + routes: { + '/': (BuildContext context) => SplashScreen(), + '/home': (BuildContext context) => HomeScreen(), + '/loading': (BuildContext context) => LoadingScreen(), + '/game': (BuildContext context) => GameScreen(), + '/tutorial': (BuildContext context) => TurorialScreen(), + }, + navigatorObservers: [ FirebaseAnalyticsObserver(analytics: analytics), ], - )); + )); + }, onError: (error, stackTrace) async { + // Whenever an error occurs, call the `reportCrash` function. This will send + // Dart errors to our dev console or Crashlytics depending on the environment. + await FlutterCrashlytics() + .reportCrash(error, stackTrace, forceCrash: false); + }); } diff --git a/lib/screens/HomeScreen/tutorialBtn.widget.dart b/lib/screens/HomeScreen/tutorialBtn.widget.dart index 5abeb55..96ad3ed 100644 --- a/lib/screens/HomeScreen/tutorialBtn.widget.dart +++ b/lib/screens/HomeScreen/tutorialBtn.widget.dart @@ -1,6 +1,6 @@ - import 'package:flutter/material.dart'; import 'package:numbers/utils/constants.dart'; +import 'package:flutter_crashlytics/flutter_crashlytics.dart'; class TutorialWidget extends StatelessWidget { const TutorialWidget({ @@ -12,8 +12,7 @@ class TutorialWidget extends StatelessWidget { return Container( padding: EdgeInsets.all(10), child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), color: primaryColor, onPressed: () { Navigator.of(context).pushNamed('/tutorial'); diff --git a/lib/utils/Config.dart b/lib/utils/Config.dart index bbfb55e..cf26b4d 100644 --- a/lib/utils/Config.dart +++ b/lib/utils/Config.dart @@ -1,3 +1,4 @@ const int gameDuration = 5; const Map costs = {'success': 1000, 'fail': -500, 'block': 100}; const int maxKeepGameHistoryCount = 6; +const bool isInDebugMode = false; diff --git a/pubspec.lock b/pubspec.lock index 72c8af9..6192e79 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -65,14 +65,14 @@ packages: source: hosted version: "0.1.2" firebase_analytics: - dependency: "direct dev" + dependency: "direct main" description: name: firebase_analytics url: "https://pub.dartlang.org" source: hosted version: "1.2.0+1" firebase_core: - dependency: "direct dev" + dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" @@ -83,6 +83,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_crashlytics: + dependency: "direct dev" + description: + name: flutter_crashlytics + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" flutter_launcher_icons: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index 01d4990..6608f5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dev_dependencies: flutter_launcher_icons: "^0.7.2" firebase_core: ^0.4.0+8 firebase_analytics: ^1.0.2 + flutter_crashlytics: ^1.0.0 flutter_icons: android: "launcher_icon" From ddd0b59124b0c6c650c3722664598d11d4d5a7f0 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 10:21:18 +0530 Subject: [PATCH 11/37] packages moved to right place --- lib/screens/HomeScreen/tutorialBtn.widget.dart | 1 - pubspec.lock | 4 ++-- pubspec.yaml | 7 ++----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/screens/HomeScreen/tutorialBtn.widget.dart b/lib/screens/HomeScreen/tutorialBtn.widget.dart index 96ad3ed..2aa4d86 100644 --- a/lib/screens/HomeScreen/tutorialBtn.widget.dart +++ b/lib/screens/HomeScreen/tutorialBtn.widget.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:numbers/utils/constants.dart'; -import 'package:flutter_crashlytics/flutter_crashlytics.dart'; class TutorialWidget extends StatelessWidget { const TutorialWidget({ diff --git a/pubspec.lock b/pubspec.lock index 6192e79..a0aa6f9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -84,14 +84,14 @@ packages: source: sdk version: "0.0.0" flutter_crashlytics: - dependency: "direct dev" + dependency: "direct main" description: name: flutter_crashlytics url: "https://pub.dartlang.org" source: hosted version: "1.0.0" flutter_launcher_icons: - dependency: "direct dev" + dependency: "direct main" description: name: flutter_launcher_icons url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 6608f5a..e8f9ef3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,15 +27,12 @@ dependencies: timeago: ^2.0.18 firebase_core: ^0.4.0+8 firebase_analytics: ^1.0.2 - + flutter_crashlytics: ^1.0.0 + flutter_launcher_icons: "^0.7.2" dev_dependencies: flutter_test: sdk: flutter - flutter_launcher_icons: "^0.7.2" - firebase_core: ^0.4.0+8 - firebase_analytics: ^1.0.2 - flutter_crashlytics: ^1.0.0 flutter_icons: android: "launcher_icon" From f6135ab7f23a7d3a32821d74cd10cf176bde616b Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 12:00:19 +0530 Subject: [PATCH 12/37] Leadership board renamed to leaderboard --- android/app/build.gradle | 2 + lib/component/LeaderboardCard.dart | 67 +++++++++++++++++++ .../{ScoreCard.dart => RecentScoreCard.dart} | 17 +++-- lib/screens/GameScreen/GameScreen.dart | 2 + lib/screens/HomeScreen/HomeScreen.dart | 6 +- lib/service/leaderboardService.dart | 49 ++++++++++++++ lib/utils/Config.dart | 2 +- lib/widgets/leadershipBoardTable.dart | 22 ++++++ ...recentScore.dart => recentScoreTable.dart} | 2 +- pubspec.lock | 7 ++ pubspec.yaml | 1 + 11 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 lib/component/LeaderboardCard.dart rename lib/component/{ScoreCard.dart => RecentScoreCard.dart} (81%) create mode 100644 lib/service/leaderboardService.dart create mode 100644 lib/widgets/leadershipBoardTable.dart rename lib/widgets/{recentScore.dart => recentScoreTable.dart} (92%) diff --git a/android/app/build.gradle b/android/app/build.gradle index 54893c7..83168c8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -39,6 +39,7 @@ android { versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + multiDexEnabled true } buildTypes { @@ -59,6 +60,7 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.1.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.1.1' implementation 'com.google.firebase:firebase-core:17.0.1' + implementation 'com.android.support:multidex:1.0.3' } apply plugin: 'com.google.gms.google-services' diff --git a/lib/component/LeaderboardCard.dart b/lib/component/LeaderboardCard.dart new file mode 100644 index 0000000..8aa7dde --- /dev/null +++ b/lib/component/LeaderboardCard.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:numbers/service/leaderboardService.dart'; +import 'package:numbers/utils/constants.dart'; +import 'package:numbers/widgets/dashedLine.dart'; +import 'package:numbers/widgets/leadershipBoardTable.dart'; + +class LeaderboardCard extends StatefulWidget { + _LeaderboardCardState createState() => _LeaderboardCardState(); +} + +class _LeaderboardCardState extends State { + String title= 'Leaderboard'; + List scores = []; + + @override + void initState() { + super.initState(); + _getRecentScore(); + } + + void _getRecentScore() { + leaderboardService().getData().then((score) { + setState(() { + this.scores = score; + }); + }); + } + + + @override + Widget build(BuildContext context) { + return Container( + color: secondaryBGColor, + padding: const EdgeInsets.only(top: 5, left: 10, right: 10, bottom: 5), + child: Column( + children: [ + Card( + color: Colors.white, + child: Column( + children: [ + ListTile( + leading: Icon( + Icons.show_chart, + color: primaryColor, + ), + title: Text(title, + style: TextStyle( + color: primaryColor, fontWeight: FontWeight.bold)), + ), + dashedLineBreak(Colors.grey), + (this.scores.length == 0) + ? Padding( + padding: const EdgeInsets.only(top: 20), + child: Text('No data found, Play some games'), + ) + : leaderboardTable(this.scores), + SizedBox( + height: 15, + ) + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/component/ScoreCard.dart b/lib/component/RecentScoreCard.dart similarity index 81% rename from lib/component/ScoreCard.dart rename to lib/component/RecentScoreCard.dart index 2b91a83..ae86238 100644 --- a/lib/component/ScoreCard.dart +++ b/lib/component/RecentScoreCard.dart @@ -2,19 +2,18 @@ import 'package:flutter/material.dart'; import 'package:numbers/store/RecentScoreStore.dart'; import 'package:numbers/utils/constants.dart'; import 'package:numbers/widgets/dashedLine.dart'; -import 'package:numbers/widgets/recentScore.dart'; - -class ScoreBoard extends StatefulWidget { - final String title; - ScoreBoard(this.title); +import 'package:numbers/widgets/recentScoreTable.dart'; +class RecentScoreBoard extends StatefulWidget { @override - _ScoreBoardState createState() => _ScoreBoardState(); + _RecentScoreBoardState createState() => _RecentScoreBoardState(); } -class _ScoreBoardState extends State { +class _RecentScoreBoardState extends State { List recentScore = []; Map scoreCardMeta = {}; + String title = 'Recent Scores'; + @override void initState() { super.initState(); @@ -45,7 +44,7 @@ class _ScoreBoardState extends State { Icons.show_chart, color: primaryColor, ), - title: Text(widget.title, + title: Text(title, style: TextStyle( color: primaryColor, fontWeight: FontWeight.bold)), ), @@ -55,7 +54,7 @@ class _ScoreBoardState extends State { padding: const EdgeInsets.only(top: 20), child: Text('No data found, Play some games'), ) - : buildTableRow(this.recentScore), + : recentScoreTable(this.recentScore), SizedBox( height: 15, ) diff --git a/lib/screens/GameScreen/GameScreen.dart b/lib/screens/GameScreen/GameScreen.dart index bfb0d2f..5c305f6 100644 --- a/lib/screens/GameScreen/GameScreen.dart +++ b/lib/screens/GameScreen/GameScreen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:numbers/service/leaderboardService.dart'; import 'package:numbers/store/BestScore.dart'; import 'package:numbers/store/RecentScoreStore.dart'; import 'package:numbers/schema/BlockSchema.dart'; @@ -97,6 +98,7 @@ class _GameScreenState extends State { void updateScores() { RecentScoreStore().updateRecentScore(gameHistory['score']); BestScoreStore().updateScore(gameHistory['score']); + leaderboardService().setData(gameHistory); } void fillBlocksData() { diff --git a/lib/screens/HomeScreen/HomeScreen.dart b/lib/screens/HomeScreen/HomeScreen.dart index 488320a..89b59eb 100644 --- a/lib/screens/HomeScreen/HomeScreen.dart +++ b/lib/screens/HomeScreen/HomeScreen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:numbers/component/ScoreCard.dart'; +import 'package:numbers/component/LeaderboardCard.dart'; +import 'package:numbers/component/RecentScoreCard.dart'; import 'package:numbers/store/BestScore.dart'; import 'package:numbers/utils/constants.dart'; import 'package:numbers/widgets/dashedLine.dart'; @@ -66,7 +67,8 @@ class _HomeScreenState extends State { // SizedBox( // height: 10, // ), - ScoreBoard('Recent Scores'), + LeaderboardCard(), + RecentScoreBoard(), ], ), ), diff --git a/lib/service/leaderboardService.dart b/lib/service/leaderboardService.dart new file mode 100644 index 0000000..1325572 --- /dev/null +++ b/lib/service/leaderboardService.dart @@ -0,0 +1,49 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class leaderboardService { + final String collection = 'leaderboard'; + final String orderByKey = 'score'; + + setData(Map gameState) { + Map newData = this._formatSetData(gameState); + Firestore.instance.collection(this.collection).document().setData(newData); + } + + _formatSetData(Map gameState) { + return { + 'name': 'random', + 'device': 'random', + 'time': DateTime.now().millisecondsSinceEpoch.toString(), + 'total': gameState['total'], + 'success': gameState['success'], + 'fail': gameState['fail'], + 'score': gameState['score'], + 'selectedBlocks': gameState['selectedBlocks'], + }; + } + + getData({int limit = 6}) async { + try { + var resultData = await Firestore.instance + .collection(this.collection) + .orderBy(this.orderByKey, descending: true) + .limit(limit) + .getDocuments(); + + return this._formatGetData(resultData); + } catch (error) { + print(error); + } + } + + _formatGetData(resultData) { + List formattedData = []; + + int counter = 0; + for (var document in resultData.documents) { + document.data['rank'] = ++counter; + formattedData.add(document.data); + } + return formattedData; + } +} diff --git a/lib/utils/Config.dart b/lib/utils/Config.dart index cf26b4d..997959d 100644 --- a/lib/utils/Config.dart +++ b/lib/utils/Config.dart @@ -1,4 +1,4 @@ const int gameDuration = 5; const Map costs = {'success': 1000, 'fail': -500, 'block': 100}; const int maxKeepGameHistoryCount = 6; -const bool isInDebugMode = false; +const bool isInDebugMode = true; diff --git a/lib/widgets/leadershipBoardTable.dart b/lib/widgets/leadershipBoardTable.dart new file mode 100644 index 0000000..5ea9a2b --- /dev/null +++ b/lib/widgets/leadershipBoardTable.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +DataTable leaderboardTable(List listOfColumns) { + return DataTable( + columns: [ + DataColumn(label: Text('Rank')), + DataColumn(label: Text('Name')), + DataColumn(label: Text('Score')), + ], + rows: listOfColumns + .map( + ((element) => DataRow( + cells: [ + DataCell(Text(element['rank'].toString())), + DataCell(Text(element['name'].toString())), + DataCell(Text(element['score'].toString())), + ], + )), + ) + .toList(), + ); +} diff --git a/lib/widgets/recentScore.dart b/lib/widgets/recentScoreTable.dart similarity index 92% rename from lib/widgets/recentScore.dart rename to lib/widgets/recentScoreTable.dart index 4439f7f..c6c8fb5 100644 --- a/lib/widgets/recentScore.dart +++ b/lib/widgets/recentScoreTable.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:timeago/timeago.dart' as timeago; -DataTable buildTableRow(List listOfColumns) { +DataTable recentScoreTable(List listOfColumns) { return DataTable( columns: [ DataColumn(label: Text('Score')), diff --git a/pubspec.lock b/pubspec.lock index a0aa6f9..429a5f6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -36,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.2" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.9" collection: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e8f9ef3..f0e4815 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,7 @@ dependencies: firebase_analytics: ^1.0.2 flutter_crashlytics: ^1.0.0 flutter_launcher_icons: "^0.7.2" + cloud_firestore: ^0.12.9 dev_dependencies: flutter_test: From df9e8cd0db0786d9d385e024ae55fed8ca5a69d1 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 12:01:06 +0530 Subject: [PATCH 13/37] renamed --- lib/component/LeaderboardCard.dart | 4 ++-- lib/screens/GameScreen/GameScreen.dart | 4 ++-- lib/service/leaderboardService.dart | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/component/LeaderboardCard.dart b/lib/component/LeaderboardCard.dart index 8aa7dde..f585643 100644 --- a/lib/component/LeaderboardCard.dart +++ b/lib/component/LeaderboardCard.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:numbers/service/leaderboardService.dart'; +import 'package:numbers/service/LeaderboardService.dart'; import 'package:numbers/utils/constants.dart'; import 'package:numbers/widgets/dashedLine.dart'; import 'package:numbers/widgets/leadershipBoardTable.dart'; @@ -19,7 +19,7 @@ class _LeaderboardCardState extends State { } void _getRecentScore() { - leaderboardService().getData().then((score) { + LeaderboardService().getData().then((score) { setState(() { this.scores = score; }); diff --git a/lib/screens/GameScreen/GameScreen.dart b/lib/screens/GameScreen/GameScreen.dart index 5c305f6..4257f92 100644 --- a/lib/screens/GameScreen/GameScreen.dart +++ b/lib/screens/GameScreen/GameScreen.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'package:numbers/service/leaderboardService.dart'; +import 'package:numbers/service/LeaderboardService.dart'; import 'package:numbers/store/BestScore.dart'; import 'package:numbers/store/RecentScoreStore.dart'; import 'package:numbers/schema/BlockSchema.dart'; @@ -98,7 +98,7 @@ class _GameScreenState extends State { void updateScores() { RecentScoreStore().updateRecentScore(gameHistory['score']); BestScoreStore().updateScore(gameHistory['score']); - leaderboardService().setData(gameHistory); + LeaderboardService().setData(gameHistory); } void fillBlocksData() { diff --git a/lib/service/leaderboardService.dart b/lib/service/leaderboardService.dart index 1325572..2491863 100644 --- a/lib/service/leaderboardService.dart +++ b/lib/service/leaderboardService.dart @@ -1,6 +1,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -class leaderboardService { +class LeaderboardService { final String collection = 'leaderboard'; final String orderByKey = 'score'; From c2eea22ef87951e6c5665af957f8cc01bc4b2a16 Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 12:09:05 +0530 Subject: [PATCH 14/37] removed unused space --- lib/component/LeaderboardCard.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/component/LeaderboardCard.dart b/lib/component/LeaderboardCard.dart index f585643..cbdaa86 100644 --- a/lib/component/LeaderboardCard.dart +++ b/lib/component/LeaderboardCard.dart @@ -26,7 +26,6 @@ class _LeaderboardCardState extends State { }); } - @override Widget build(BuildContext context) { return Container( From eb969443c01f4da0a030880aa76221f646478c0a Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 13:04:44 +0530 Subject: [PATCH 15/37] Store score on game finsh to firebase --- lib/screens/GameScreen/GameScreen.dart | 2 +- lib/screens/HomeScreen/HomeScreen.dart | 74 +++++++++++++++++-- lib/service/leaderboardService.dart | 18 +++-- .../{BestScore.dart => BestScoreStore.dart} | 0 lib/store/SettingsStore.dart | 22 ++++++ lib/utils/common.dart | 5 ++ pubspec.lock | 7 ++ pubspec.yaml | 1 + 8 files changed, 116 insertions(+), 13 deletions(-) rename lib/store/{BestScore.dart => BestScoreStore.dart} (100%) create mode 100644 lib/store/SettingsStore.dart diff --git a/lib/screens/GameScreen/GameScreen.dart b/lib/screens/GameScreen/GameScreen.dart index 4257f92..5d3d051 100644 --- a/lib/screens/GameScreen/GameScreen.dart +++ b/lib/screens/GameScreen/GameScreen.dart @@ -1,6 +1,6 @@ import 'dart:async'; import 'package:numbers/service/LeaderboardService.dart'; -import 'package:numbers/store/BestScore.dart'; +import 'package:numbers/store/BestScoreStore.dart'; import 'package:numbers/store/RecentScoreStore.dart'; import 'package:numbers/schema/BlockSchema.dart'; import 'package:numbers/screens/GameScreen/summaryModel.dart'; diff --git a/lib/screens/HomeScreen/HomeScreen.dart b/lib/screens/HomeScreen/HomeScreen.dart index 89b59eb..aa77856 100644 --- a/lib/screens/HomeScreen/HomeScreen.dart +++ b/lib/screens/HomeScreen/HomeScreen.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:numbers/component/LeaderboardCard.dart'; import 'package:numbers/component/RecentScoreCard.dart'; -import 'package:numbers/store/BestScore.dart'; +import 'package:numbers/store/BestScoreStore.dart'; +import 'package:numbers/store/SettingsStore.dart'; +import 'package:numbers/utils/Common.dart'; import 'package:numbers/utils/constants.dart'; import 'package:numbers/widgets/dashedLine.dart'; @@ -15,7 +17,6 @@ class HomeScreen extends StatefulWidget { } class _HomeScreenState extends State { - int bestScore = 0; @override @@ -64,9 +65,6 @@ class _HomeScreenState extends State { ], ), ), - // SizedBox( - // height: 10, - // ), LeaderboardCard(), RecentScoreBoard(), ], @@ -75,8 +73,7 @@ class _HomeScreenState extends State { ), floatingActionButton: FloatingActionButton( onPressed: () { - Navigator.of(context).pushNamedAndRemoveUntil( - '/loading', (Route route) => false); + this.floatingBtnAction(); }, child: Icon(Icons.play_arrow), backgroundColor: primaryColor, @@ -85,4 +82,67 @@ class _HomeScreenState extends State { ), ); } + + void floatingBtnAction() async { + String name = await SettingsStore().getKey('name'); + + if (name != null) { + return this.navigateToGame(); + } + + _asyncNameDialog(context); + } + + Future _asyncNameDialog(BuildContext context) async { + String name = ''; + return showDialog( + context: context, + barrierDismissible: + false, // dialog is dismissible with a tap on the barrier + builder: (BuildContext context) { + return AlertDialog( + title: Text('Enter your name'), + content: new Row( + children: [ + new Expanded( + child: new TextField( + autofocus: true, + decoration: new InputDecoration( + labelText: 'Name', hintText: 'eg. Thamaraiselvam'), + onChanged: (value) { + name = value; + }, + )) + ], + ), + actions: [ + FlatButton( + child: Text('Randamize'), + onPressed: () { + String name = Common.getRandomName(); + this.saveName(name); + this.navigateToGame(); + }, + ), + FlatButton( + child: Text('Save'), + onPressed: () { + this.saveName(name); + this.navigateToGame(); + }, + ), + ], + ); + }, + ); + } + + void saveName(String name){ + SettingsStore().setKey('name', name); + } + + void navigateToGame() { + Navigator.of(context) + .pushNamedAndRemoveUntil('/loading', (Route route) => false); + } } diff --git a/lib/service/leaderboardService.dart b/lib/service/leaderboardService.dart index 2491863..3bd0652 100644 --- a/lib/service/leaderboardService.dart +++ b/lib/service/leaderboardService.dart @@ -1,18 +1,26 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:numbers/store/SettingsStore.dart'; +import 'package:numbers/utils/Common.dart'; class LeaderboardService { final String collection = 'leaderboard'; final String orderByKey = 'score'; - setData(Map gameState) { - Map newData = this._formatSetData(gameState); + setData(Map gameState) async { + Map newData = await this._formatSetData(gameState); Firestore.instance.collection(this.collection).document().setData(newData); } - _formatSetData(Map gameState) { + _formatSetData(Map gameState) async { + + String name = await SettingsStore().getKey('name'); + + if(name == null){ + name = Common.getRandomName(); + } + return { - 'name': 'random', - 'device': 'random', + 'name': name, 'time': DateTime.now().millisecondsSinceEpoch.toString(), 'total': gameState['total'], 'success': gameState['success'], diff --git a/lib/store/BestScore.dart b/lib/store/BestScoreStore.dart similarity index 100% rename from lib/store/BestScore.dart rename to lib/store/BestScoreStore.dart diff --git a/lib/store/SettingsStore.dart b/lib/store/SettingsStore.dart new file mode 100644 index 0000000..a390b87 --- /dev/null +++ b/lib/store/SettingsStore.dart @@ -0,0 +1,22 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +class SettingsStore { + + SharedPreferences prefs; + + init() async { + if (this.prefs == null) { + this.prefs = await SharedPreferences.getInstance(); + } + } + + setKey(String key, String value) async { + await this.init(); + return this.prefs.setString(key, value); + } + + Future getKey(String key) async { + await this.init(); + return this.prefs.getString(key); + } +} diff --git a/lib/utils/common.dart b/lib/utils/common.dart index 16e0708..254be60 100644 --- a/lib/utils/common.dart +++ b/lib/utils/common.dart @@ -1,4 +1,5 @@ import 'dart:math'; +import 'package:faker/faker.dart'; import 'package:flutter/material.dart'; class Common { @@ -57,4 +58,8 @@ class Common { return combinations; } + + static String getRandomName(){ + return Faker().person.name(); + } } diff --git a/pubspec.lock b/pubspec.lock index 429a5f6..b35ba84 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -71,6 +71,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + faker: + dependency: "direct main" + description: + name: faker + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" firebase_analytics: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index f0e4815..337fb17 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: flutter_crashlytics: ^1.0.0 flutter_launcher_icons: "^0.7.2" cloud_firestore: ^0.12.9 + faker: ^1.1.1 dev_dependencies: flutter_test: From 5b7e9278d2c824c274bcaaacb28359a59b89827a Mon Sep 17 00:00:00 2001 From: thamaraiselvam Date: Thu, 1 Aug 2019 14:40:53 +0530 Subject: [PATCH 16/37] deploy building confuguration added and tested --- .gitignore | 1 + android/app/build.gradle | 29 ++++++++++++++++++------ android/app/proguard-rules.pro | 7 ++++++ android/app/src/main/AndroidManifest.xml | 2 ++ android/gradle.properties | 3 ++- 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 android/app/proguard-rules.pro diff --git a/.gitignore b/.gitignore index ac4a906..511b40a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ **/android/gradlew **/android/gradlew.bat **/android/local.properties +**/android/key.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related diff --git a/android/app/build.gradle b/android/app/build.gradle index 83168c8..3296ff6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,6 +24,12 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' 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 { compileSdkVersion 28 @@ -42,13 +48,22 @@ android { multiDexEnabled true } - 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 - } - } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + } + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled true + useProguard true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } } flutter { diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..239ec33 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,7 @@ +## Flutter wrapper +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.** { *; } +-keep class io.flutter.plugins.** { *; } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 055b774..ae81bfe 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,8 @@ + +

Log Data

+ I want to inform you that whenever + you use my Service, in a case of an error in the + app I collect data and information (through third + party products) on your phone called Log Data. This Log Data + may include information such as your device Internet + Protocol (“IP”) address, device name, operating system + version, the configuration of the app when utilizing + my Service, the time and date of your use of the + Service, and other statistics. +

Cookies

+ Cookies are files with a small amount of data that are + commonly used as anonymous unique identifiers. These are + sent to your browser from the websites that you visit and + are stored on your device's internal memory. +

+ This Service does not use these “cookies” explicitly. + However, the app may use third party code and libraries that + use “cookies” to collect information and improve their + services. You have the option to either accept or refuse + these cookies and know when a cookie is being sent to your + device. If you choose to refuse our cookies, you may not be + able to use some portions of this Service. +

Service Providers

+ I may employ third-party companies + and individuals due to the following reasons: +

  • To facilitate our Service;
  • To provide the Service on our behalf;
  • To perform Service-related services; or
  • To assist us in analyzing how our Service is used.

+ I want to inform users of this + Service that these third parties have access to your + Personal Information. The reason is to perform the tasks + assigned to them on our behalf. However, they are obligated + not to disclose or use the information for any other + purpose. +

Security

+ I value your trust in providing us + your Personal Information, thus we are striving to use + commercially acceptable means of protecting it. But remember + that no method of transmission over the internet, or method + of electronic storage is 100% secure and reliable, and + I cannot guarantee its absolute security. +

Links to Other Sites

+ This Service may contain links to other sites. If you click + on a third-party link, you will be directed to that site. + Note that these external sites are not operated by + me. Therefore, I strongly advise you to + review the Privacy Policy of these websites. + I have no control over and assume no + responsibility for the content, privacy policies, or + practices of any third-party sites or services. +

Children’s Privacy

+ These Services do not address anyone under the age of 13. + I do not knowingly collect personally + identifiable information from children under 13. In the case + I discover that a child under 13 has provided + me with personal information, + I immediately delete this from our servers. If you + are a parent or guardian and you are aware that your child + has provided us with personal information, please contact + me so that I will be able to do + necessary actions. +

Changes to This Privacy Policy

+ I may update our Privacy Policy from + time to time. Thus, you are advised to review this page + periodically for any changes. I will + notify you of any changes by posting the new Privacy Policy + on this page. These changes are effective immediately after + they are posted on this page. +

Contact Us

+ If you have any questions or suggestions about + my Privacy Policy, do not hesitate to contact + me at thamaraiselvam@live.com. +

+ This privacy policy page was created at + privacypolicytemplate.net + and modified/generated by + App Privacy Policy Generator

+ + + \ No newline at end of file From f7b24c3d4e53729781b02aa0a0bfbd3d39aafc03 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:07:35 +0530 Subject: [PATCH 19/37] Update and rename privacy_policy (1).html to privacy_policy.html --- privacy_policy (1).html => privacy_policy.html | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) rename privacy_policy (1).html => privacy_policy.html (92%) diff --git a/privacy_policy (1).html b/privacy_policy.html similarity index 92% rename from privacy_policy (1).html rename to privacy_policy.html index 8d317c8..b95980f 100644 --- a/privacy_policy (1).html +++ b/privacy_policy.html @@ -92,10 +92,10 @@

Privacy Policy

responsibility for the content, privacy policies, or practices of any third-party sites or services.

Children’s Privacy

- These Services do not address anyone under the age of 13. + These Services do not address anyone. I do not knowingly collect personally - identifiable information from children under 13. In the case - I discover that a child under 13 has provided + identifiable information from children. In the case + I discover that a child has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child @@ -113,11 +113,8 @@

Privacy Policy

If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at thamaraiselvam@live.com. -

- This privacy policy page was created at - privacypolicytemplate.net - and modified/generated by - App Privacy Policy Generator

+

+ - \ No newline at end of file + From 911056e9d12a120eac5a13ae26919f15f3822aea Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:08:21 +0530 Subject: [PATCH 20/37] Add files via upload --- privacy_policy.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 privacy_policy.md diff --git a/privacy_policy.md b/privacy_policy.md new file mode 100644 index 0000000..a5f50d2 --- /dev/null +++ b/privacy_policy.md @@ -0,0 +1,62 @@ +## Privacy Policy + +built the Numbers app as an Open Source app. This SERVICE is provided by at no cost and is intended for use as is. + +This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. + +If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy. + +The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at Numbers unless otherwise defined in this Privacy Policy. + +**Information Collection and Use** + +For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way. + +The app does use third party services that may collect information used to identify you. + +Link to privacy policy of third party service providers used by the app + +* [Google Play Services](https://www.google.com/policies/privacy/) + +**Log Data** + +I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics. + +**Cookies** + +Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory. + +This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service. + +**Service Providers** + +I may employ third-party companies and individuals due to the following reasons: + +* To facilitate our Service; +* To provide the Service on our behalf; +* To perform Service-related services; or +* To assist us in analyzing how our Service is used. + +I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose. + +**Security** + +I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security. + +**Links to Other Sites** + +This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services. + +**Children’s Privacy** + +These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13\. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. + +**Changes to This Privacy Policy** + +I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page. + +**Contact Us** + +If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at thamaraiselvam@live.com. + +This privacy policy page was created at [privacypolicytemplate.net](https://privacypolicytemplate.net) and modified/generated by [App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/) \ No newline at end of file From 02b06bc656e76b2f3e3eb6d7a7b18fd89ae8415b Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:08:30 +0530 Subject: [PATCH 21/37] Delete privacy_policy.html --- privacy_policy.html | 120 -------------------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 privacy_policy.html diff --git a/privacy_policy.html b/privacy_policy.html deleted file mode 100644 index b95980f..0000000 --- a/privacy_policy.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - Privacy Policy - - - -

Privacy Policy

- built the Numbers app as - an Open Source app. This SERVICE is provided by - at no cost and is intended for - use as is. -

- This page is used to inform visitors regarding - my policies with the collection, use, and - disclosure of Personal Information if anyone decided to use - my Service. -

- If you choose to use my Service, then you agree - to the collection and use of information in relation to this - policy. The Personal Information that I collect is - used for providing and improving the Service. - I will not use or share your - information with anyone except as described in this Privacy - Policy. -

- The terms used in this Privacy Policy have the same meanings - as in our Terms and Conditions, which is accessible at - Numbers unless otherwise defined in this Privacy - Policy. -

Information Collection and Use

- For a better experience, while using our Service, - I may require you to provide us with certain - personally identifiable information. The - information that I request will be - retained on your device and is not collected by me in any way. -

- The app does use third party services that may collect - information used to identify you. -

- Link to privacy policy of third party service providers - used by the app -

Log Data

- I want to inform you that whenever - you use my Service, in a case of an error in the - app I collect data and information (through third - party products) on your phone called Log Data. This Log Data - may include information such as your device Internet - Protocol (“IP”) address, device name, operating system - version, the configuration of the app when utilizing - my Service, the time and date of your use of the - Service, and other statistics. -

Cookies

- Cookies are files with a small amount of data that are - commonly used as anonymous unique identifiers. These are - sent to your browser from the websites that you visit and - are stored on your device's internal memory. -

- This Service does not use these “cookies” explicitly. - However, the app may use third party code and libraries that - use “cookies” to collect information and improve their - services. You have the option to either accept or refuse - these cookies and know when a cookie is being sent to your - device. If you choose to refuse our cookies, you may not be - able to use some portions of this Service. -

Service Providers

- I may employ third-party companies - and individuals due to the following reasons: -

  • To facilitate our Service;
  • To provide the Service on our behalf;
  • To perform Service-related services; or
  • To assist us in analyzing how our Service is used.

- I want to inform users of this - Service that these third parties have access to your - Personal Information. The reason is to perform the tasks - assigned to them on our behalf. However, they are obligated - not to disclose or use the information for any other - purpose. -

Security

- I value your trust in providing us - your Personal Information, thus we are striving to use - commercially acceptable means of protecting it. But remember - that no method of transmission over the internet, or method - of electronic storage is 100% secure and reliable, and - I cannot guarantee its absolute security. -

Links to Other Sites

- This Service may contain links to other sites. If you click - on a third-party link, you will be directed to that site. - Note that these external sites are not operated by - me. Therefore, I strongly advise you to - review the Privacy Policy of these websites. - I have no control over and assume no - responsibility for the content, privacy policies, or - practices of any third-party sites or services. -

Children’s Privacy

- These Services do not address anyone. - I do not knowingly collect personally - identifiable information from children. In the case - I discover that a child has provided - me with personal information, - I immediately delete this from our servers. If you - are a parent or guardian and you are aware that your child - has provided us with personal information, please contact - me so that I will be able to do - necessary actions. -

Changes to This Privacy Policy

- I may update our Privacy Policy from - time to time. Thus, you are advised to review this page - periodically for any changes. I will - notify you of any changes by posting the new Privacy Policy - on this page. These changes are effective immediately after - they are posted on this page. -

Contact Us

- If you have any questions or suggestions about - my Privacy Policy, do not hesitate to contact - me at thamaraiselvam@live.com. -

- - - - From ff0196ccab292e0ae677a6b63e5f10a1ee246fb4 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:10:04 +0530 Subject: [PATCH 22/37] Update privacy_policy.md --- privacy_policy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/privacy_policy.md b/privacy_policy.md index a5f50d2..0f95d30 100644 --- a/privacy_policy.md +++ b/privacy_policy.md @@ -49,7 +49,7 @@ This Service may contain links to other sites. If you click on a third-party lin **Children’s Privacy** -These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13\. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. +These Services do not address anyone. I do not knowingly collect personally identifiable information from children. In the case I discover that a child has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. **Changes to This Privacy Policy** @@ -59,4 +59,4 @@ I may update our Privacy Policy from time to time. Thus, you are advised to revi If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at thamaraiselvam@live.com. -This privacy policy page was created at [privacypolicytemplate.net](https://privacypolicytemplate.net) and modified/generated by [App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/) \ No newline at end of file +This privacy policy page was created at [privacypolicytemplate.net](https://privacypolicytemplate.net) and modified/generated by [App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/) From 025878368189072933e6f4091186342fd18e9365 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:11:17 +0530 Subject: [PATCH 23/37] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1abb683..f4a43be 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # Numbers - Flutter Game Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. See Demo Here + + +Read Privacy Policy From de5ad3e67cc1e05dddc1e90aac23a9ad8eb31905 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:12:45 +0530 Subject: [PATCH 24/37] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4a43be..576aca2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Numbers - Flutter Game -Numbers is simple flutter game, Just match the target shown by adding one or more number blocks. See Demo Here +Numbers is simple game built in Flutter Framework. +This game is purely based on numbers to improve problem solving skills. + + +### How to play + +Just match the target shown by adding one or more number blocks. See Demo Here + +### Privacy Policy Read Privacy Policy From e2c72cf6168f8563bc48fd0e30d628408ebd56f5 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:19:31 +0530 Subject: [PATCH 25/37] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 576aca2..e0c2805 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ Numbers is simple game built in Flutter Framework. This game is purely based on numbers to improve problem solving skills. +### Screenshots + + + + + + + + ### How to play From 3157af5e05919c623e917c268a4cc4daf7f7f7e9 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:21:21 +0530 Subject: [PATCH 26/37] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e0c2805..895211d 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,14 @@ This game is purely based on numbers to improve problem solving skills. ### Screenshots - - - - - - - +
+ + + + + + +
### How to play From f45eeb0381b09b8246d067e5ad62285b5ee22499 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:22:27 +0530 Subject: [PATCH 27/37] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 895211d..8ae212a 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ This game is purely based on numbers to improve problem solving skills. ### Screenshots
- - - - - - + + + + + +
From aa671f6c18b50ae9ad6f0a8247980f2b716620b7 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Thu, 1 Aug 2019 16:24:10 +0530 Subject: [PATCH 28/37] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 8ae212a..a969e9b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Numbers - Flutter Game -Numbers is simple game built in Flutter Framework. - -This game is purely based on numbers to improve problem solving skills. +Numbers is simple game built in Flutter Framework and is purely based on numbers to improve problem solving skills. ### Screenshots From 6ae12de877b6a2559ba5126bdcbc5d29c5343500 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Fri, 2 Aug 2019 13:11:08 +0530 Subject: [PATCH 29/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a969e9b..e7b1d29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Numbers - Flutter Game -Numbers is simple game built in Flutter Framework and is purely based on numbers to improve problem solving skills. +Numbers is a simple game built in Flutter Framework and is purely based on numbers to improve problem solving skills. ### Screenshots From 0257e73b5e0b3781b1ee4f48d67c850925fac1e3 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Fri, 2 Aug 2019 14:44:25 +0530 Subject: [PATCH 30/37] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c6c4b44 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Thamaraiselvam + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From f6b7ced0cf378cff83f28a52cd6bc360dd9eed82 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Fri, 2 Aug 2019 14:45:23 +0530 Subject: [PATCH 31/37] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From f79183092d2c87dbf5d42018e7603a433f866b6b Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Fri, 2 Aug 2019 14:46:26 +0530 Subject: [PATCH 32/37] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea7..1015322 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,11 +23,6 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - **Smartphone (please complete the following information):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] From 953df5a1363eb2e46344d85e0d6fb4fcb5f85f91 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Fri, 2 Aug 2019 14:46:55 +0530 Subject: [PATCH 33/37] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..90474e8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at thamaraiselvam@live.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq From e227512ccbc1a003685aa41c2686b3e661d7c04f Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Sat, 3 Aug 2019 21:48:23 +0530 Subject: [PATCH 34/37] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e7b1d29..73e8eb0 100644 --- a/README.md +++ b/README.md @@ -18,5 +18,4 @@ Numbers is a simple game built in Flutter Framework and is purely based on numbe Just match the target shown by adding one or more number blocks. See Demo Here -### Privacy Policy -Read Privacy Policy +Privacy Policy From 0c2d1bee5151b6a12d4eb7b2c3ec62715caf279c Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 13 Aug 2019 10:57:28 +0530 Subject: [PATCH 35/37] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 73e8eb0..c2fb551 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Numbers is a simple game built in Flutter Framework and is purely based on numbers to improve problem solving skills. +Get it on Google Play + ### Screenshots
From c862a0f40e604b840a424025153751ab43d33676 Mon Sep 17 00:00:00 2001 From: Thamaraiselvam Date: Tue, 13 Aug 2019 10:58:32 +0530 Subject: [PATCH 36/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c2fb551..a833c18 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Numbers is a simple game built in Flutter Framework and is purely based on numbers to improve problem solving skills. -Get it on Google Play +Get it on Google Play ### Screenshots From 3197284740436902e0fdf47e0582f02d1465868e Mon Sep 17 00:00:00 2001 From: SamiK28 Date: Tue, 1 Oct 2019 01:13:46 +0530 Subject: [PATCH 37/37] added google signin page --- assets/images/gvector.png | Bin 0 -> 15221 bytes ios/Flutter/flutter_export_environment.sh | 10 +++ lib/models/userModel/user_model.dart | 33 ++++++++ lib/screens/login_screen.dart | 90 ++++++++++++++++++++++ lib/service/googleSignIn.dart | 27 +++++++ lib/service/leaderboardService.dart | 3 +- pubspec.lock | 28 +++++-- pubspec.yaml | 4 +- 8 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 assets/images/gvector.png create mode 100644 ios/Flutter/flutter_export_environment.sh create mode 100644 lib/models/userModel/user_model.dart create mode 100644 lib/screens/login_screen.dart create mode 100644 lib/service/googleSignIn.dart diff --git a/assets/images/gvector.png b/assets/images/gvector.png new file mode 100644 index 0000000000000000000000000000000000000000..92889d81f2711499de69f46e40285438b7a3af18 GIT binary patch literal 15221 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 literal 0 HcmV?d00001 diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh new file mode 100644 index 0000000..72835d8 --- /dev/null +++ b/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=C:\Users\samar\flutter" +export "FLUTTER_APPLICATION_PATH=C:\Flutter Projects\HacktoberFest 2019\Numbers-Flutter-Game" +export "FLUTTER_TARGET=lib\main.dart" +export "FLUTTER_BUILD_DIR=build" +export "SYMROOT=${SOURCE_ROOT}/../build\ios" +export "FLUTTER_FRAMEWORK_DIR=C:\Users\samar\flutter\bin\cache\artifacts\engine\ios" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" diff --git a/lib/models/userModel/user_model.dart b/lib/models/userModel/user_model.dart new file mode 100644 index 0000000..b3db6f0 --- /dev/null +++ b/lib/models/userModel/user_model.dart @@ -0,0 +1,33 @@ +class User { + User._internal(); + + static final User _singleton = User._internal(); + + factory User() => _singleton; + String name; + String email; + String phone; + String uid; + toJson() { + return { + "name": this.name, + "phone": this.phone, + "email": this.email, + "userID": this.uid, + }; + } + + fromJson(Map json) { + this.email = json["email"]; + this.name = json["name"]; + this.phone = json["phone"]; + this.uid = json["userID"]; + } + + setDetails(String email, String name, String phone, String uid) { + this.email = email; + this.phone = phone; + this.name = name; + this.uid = uid; + } +} diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart new file mode 100644 index 0000000..9c03212 --- /dev/null +++ b/lib/screens/login_screen.dart @@ -0,0 +1,90 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:numbers/models/userModel/user_model.dart'; +import 'package:numbers/service/googleSignIn.dart'; + +Size size = Size(0, 0); +TextEditingController phone = new TextEditingController(); + +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + final TextEditingController _email = new TextEditingController(); + final TextEditingController _password = new TextEditingController(); + bool check = true; + @override + Widget build(BuildContext context) { + size = MediaQuery.of(context).size; + + return Scaffold( + backgroundColor: Colors.white, + body: Center( + child: ListView( + shrinkWrap: true, + padding: EdgeInsets.only(left: 24.0, right: 24.0), + children: [ + SizedBox( + height: 28, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: google(), + ) + ], + ), + ), + ); + } + + Widget google() { + MediaQueryData queryData = MediaQuery.of(context); + return RaisedButton( + onPressed: () async { + final user = await signInWithGoogle(); + User().fromJson({ + "name": user.displayName, + "phone": '12345', + "email": user.email, + "userID": user.uid, + }); + Navigator.of(context) + .pushNamedAndRemoveUntil('/game', (Route route) => false); + }, + child: Container( + alignment: Alignment.center, + height: queryData.size.height / 14, + width: queryData.size.width / 1.52, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(right: 15.0), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Image.asset( + "images/gvector.png", + height: queryData.size.height / 26, + ), + ), + Padding( + padding: const EdgeInsets.only(right: 27.0), + ), + Text( + 'Sign in with Google', + textAlign: TextAlign.center, + style: TextStyle(fontFamily: "Product Sans"), + ), + ], + ), + ), + animationDuration: Duration(seconds: 3), + highlightElevation: 20.0, + color: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)), + ); + } +} diff --git a/lib/service/googleSignIn.dart b/lib/service/googleSignIn.dart new file mode 100644 index 0000000..9a896ea --- /dev/null +++ b/lib/service/googleSignIn.dart @@ -0,0 +1,27 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +final GoogleSignIn googleSignIn = GoogleSignIn(); + +Future signInWithGoogle() async { + final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); + final GoogleSignInAuthentication googleSignInAuthentication = + await googleSignInAccount.authentication; + + final AuthCredential credential = GoogleAuthProvider.getCredential( + accessToken: googleSignInAuthentication.accessToken, + idToken: googleSignInAuthentication.idToken, + ); + + final AuthResult authResult = + await FirebaseAuth.instance.signInWithCredential(credential); + final FirebaseUser user = authResult.user; + assert(!user.isAnonymous); + assert(await user.getIdToken() != null); + + final FirebaseUser currentUser = await FirebaseAuth.instance.currentUser(); + assert(user.uid == currentUser.uid); + + print("User Sign In"); + return user; +} diff --git a/lib/service/leaderboardService.dart b/lib/service/leaderboardService.dart index 3bd0652..f7381c1 100644 --- a/lib/service/leaderboardService.dart +++ b/lib/service/leaderboardService.dart @@ -12,10 +12,9 @@ class LeaderboardService { } _formatSetData(Map gameState) async { - String name = await SettingsStore().getKey('name'); - if(name == null){ + if (name == null) { name = Common.getRandomName(); } diff --git a/pubspec.lock b/pubspec.lock index b35ba84..07fde14 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,14 +21,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.3.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.5" charcode: dependency: transitive description: @@ -85,6 +85,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0+1" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+5" firebase_core: dependency: "direct main" description: @@ -116,6 +123,13 @@ packages: description: flutter source: sdk version: "0.0.0" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.7" image: dependency: transitive description: @@ -136,21 +150,21 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.1.7" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" + version: "1.6.4" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0+1" petitparser: dependency: transitive description: @@ -164,7 +178,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.5" shared_preferences: dependency: "direct main" description: @@ -204,7 +218,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.5" term_glyph: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 337fb17..45a4498 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,6 +19,8 @@ environment: dependencies: flutter: sdk: flutter + firebase_auth: ^0.14.0+5 + google_sign_in: ^4.0.7 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -48,7 +50,7 @@ flutter_icons: # The following section is specific to Flutter. flutter: assets: - - assets/images/ + - assets/images/gvector.png # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in