From 1d59de64f89f33265b4beb99bb84d169b9c3f44c Mon Sep 17 00:00:00 2001 From: bugudiramu Date: Fri, 2 Aug 2019 11:07:32 +0530 Subject: [PATCH] added dataConnectionChecker package instead of connectivity,cleaned up code --- lib/main.dart | 2 +- lib/screens/login.dart | 221 ------------ lib/screens/no_internet.dart | 36 -- .../googleSignIn.dart | 0 lib/{ => ui}/articleDetail.dart | 0 lib/ui/articles.dart | 333 +++++++++--------- lib/ui/login.dart | 209 +++++++++++ pubspec.lock | 14 +- pubspec.yaml | 4 +- 9 files changed, 383 insertions(+), 436 deletions(-) delete mode 100644 lib/screens/login.dart delete mode 100644 lib/screens/no_internet.dart rename lib/{firebaseDb => services}/googleSignIn.dart (100%) rename lib/{ => ui}/articleDetail.dart (100%) create mode 100644 lib/ui/login.dart diff --git a/lib/main.dart b/lib/main.dart index 40e050b..0fae108 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:news_app/screens/login.dart'; +import 'package:news_app/ui/login.dart'; void main() async { runApp( diff --git a/lib/screens/login.dart b/lib/screens/login.dart deleted file mode 100644 index 1dbcb63..0000000 --- a/lib/screens/login.dart +++ /dev/null @@ -1,221 +0,0 @@ -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/material.dart'; -import 'package:news_app/firebaseDb/googleSignIn.dart'; -import 'package:news_app/screens/no_internet.dart'; -import 'package:news_app/services/usermanagement.dart'; -import 'package:news_app/ui/articles.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:connectivity/connectivity.dart'; - -class Login extends StatefulWidget { - @override - _LoginState createState() => _LoginState(); -} - -class _LoginState extends State with SingleTickerProviderStateMixin { - Animation _animation; - AnimationController _controller; - Tween _tween; - // **** Auth class from googleSignIn.dart **** - Auth _auth = Auth(); - FirebaseAuth firebaseAuth = FirebaseAuth.instance; - UserManagement userManagement = UserManagement(); - FirebaseUser currentUser; - // **** SharedPreferences is used to store local data that when the user wants to launch the app again it won't show splash screen or starter notes again. **** - SharedPreferences preferences; - - // bool loading = false; - bool isLogedin = false; - - @override - void initState() { - super.initState(); - // **** Check whether the device is connected to any network or not **** - _checkConnectivity(); - _controller = AnimationController( - vsync: this, - duration: Duration(milliseconds: 1500), - ); - _tween = Tween(begin: 0.0, end: 100.0); - - _animation = _tween.animate(_controller); - _animation.addListener(() { - setState(() {}); - }); - _controller.forward(); - // Checking if the user is already signedin or not if signed in then directly return him to homescreen else he/she will be authenticated(should be signin first) - this.isSignedIn(); - } - - @override - void dispose() { - // **** Cancelling all the resources of animation **** - _controller.dispose(); - super.dispose(); - } - - void isSignedIn() async { - // **** check if user is already logged in or not if yes the set isLogedin value to true. - await firebaseAuth.currentUser().then((user) { - if (user != null) { - setState(() => isLogedin = true); - } - }); - // **** if isLogedin is true then return the user to our Homescreen **** - if (isLogedin) { - Navigator.pushReplacement( - context, MaterialPageRoute(builder: (context) => AllNews())); - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - // **** Beautiful gradient background **** - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Colors.purple, - Colors.purpleAccent, - ], - begin: Alignment.topRight, - tileMode: TileMode.mirror, - ), - ), - child: ListView( - children: [ - SizedBox( - height: 50.0, - ), - Image.asset( - "images/icon/launcherIcon.png", - // **** Resizing the image as per the animation value **** - height: _animation.value, - width: _animation.value, - ), - Container( - padding: - const EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0), - child: Text( - "Welcome to BuzzyFeed.From now I hope you will never miss any update.", - style: TextStyle( - color: Colors.white, - // **** fontSize: 100 - 84 = 16 **** - fontSize: _animation.value - 84, - ), - ), - ), - SizedBox( - height: _animation.value, - ), - MaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50.0), - ), - color: Colors.purpleAccent, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20.0, vertical: 15.0), - child: Text( - "Sign In With Google", - style: TextStyle( - color: Colors.white, fontSize: _animation.value - 78), - ), - ), - onPressed: () async { - // **** Show Loading Indicator when button is pressed **** - showDialog( - context: context, - barrierDismissible: false, - builder: (context) { - return AlertDialog( - content: Row( - children: [ - CircularProgressIndicator(), - SizedBox( - width: 20.0, - ), - Text("Loading!") - ], - ), - ); - }); - // **** We are checkng whether googleUser is empty or not if not empty then send Email Verification and show the dialog **** - FirebaseUser user = await _auth.googleSignIn(); - - if (user != null) { - user.sendEmailVerification().then((val) { - _showCofirmDialog(); - }); - // **** Create the user in Firebase Realtime Database by using UserManagemet class **** - userManagement.createUser(user.uid.toString(), { - "userName": user.displayName, - "email": user.email, - "photoUrl": user.photoUrl, - "userId": user.uid, - }); - - Navigator.of(context) - .push(MaterialPageRoute(builder: (context) => AllNews())); - Navigator.of(context).pop(); - } - }, - ), - ], - ), - ), - ); - } - - Future _checkConnectivity() async { - // **** Check the connectivity **** - var result = await Connectivity().checkConnectivity(); - if (result == ConnectivityResult.none) { - Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (context) => NoInternet())); - } - // else if (result == ConnectivityResult.mobile || - // result == ConnectivityResult.wifi) { - // return Navigator.of(context) - // .pushReplacement(MaterialPageRoute(builder: (context) => AllNews())); - // } - } - - _showCofirmDialog() { - // **** Showing confirmation dialog **** - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text("Verify Your Email."), - content: Text( - "Confirmation email has been sent to your email id please verify."), - actions: [ - FlatButton( - onPressed: () => Navigator.of(context).pop(), - child: Text("OK"), - ), - ], - ); - }, - ); - } -} - -// Dark Mode -// bool _darkmode = false; - -// theme: _darkmode ? ThemeData.dark() : ThemeData.light(), - -// ListTile( -// title: Text("DarkMode"), -// trailing: Switch( -// value: _darkmode, -// onChanged: (val) { -// setState(() { -// _darkmode = val; -// }); -// }, -// ), -// ), diff --git a/lib/screens/no_internet.dart b/lib/screens/no_internet.dart deleted file mode 100644 index 6c2b3d9..0000000 --- a/lib/screens/no_internet.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoInternet extends StatefulWidget { - @override - _NoInternetState createState() => _NoInternetState(); -} - -class _NoInternetState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Padding( - padding: const EdgeInsets.all(10.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset("images/no_internet.gif"), - Container( - child: Text( - "You are offine", - style: Theme.of(context).textTheme.display1, - ), - ), - Container( - padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), - child: Text( - "Please check your connection and try agian!", - style: Theme.of(context).textTheme.subtitle, - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/firebaseDb/googleSignIn.dart b/lib/services/googleSignIn.dart similarity index 100% rename from lib/firebaseDb/googleSignIn.dart rename to lib/services/googleSignIn.dart diff --git a/lib/articleDetail.dart b/lib/ui/articleDetail.dart similarity index 100% rename from lib/articleDetail.dart rename to lib/ui/articleDetail.dart diff --git a/lib/ui/articles.dart b/lib/ui/articles.dart index 4768a9e..3ca666c 100644 --- a/lib/ui/articles.dart +++ b/lib/ui/articles.dart @@ -2,10 +2,10 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import 'package:http/http.dart' as http; -import 'package:news_app/articleDetail.dart'; import 'dart:convert'; -import 'package:news_app/screens/login.dart'; +import 'package:news_app/ui/articleDetail.dart'; +import 'package:news_app/ui/login.dart'; class AllNews extends StatefulWidget { @override @@ -188,197 +188,194 @@ class _AllNewsState extends State with SingleTickerProviderStateMixin { // **** Building list of trending news from news[] list **** // **** RefreshIndicator is used to implement the functionality of Swipe down to refresh it requires a GlobalKey and onRefresh callback **** // RefreshIndicator( - // key: _refreshKey1, - // onRefresh: _refresh1, - ListView.builder( - itemCount: news == null ? 0 : news.length, - itemBuilder: (_, int i) { - return Column( - children: [ - Padding( - padding: const EdgeInsets.all(2.0), - child: Card( - color: Colors.blueGrey, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5.0), - ), - child: ListTile( - onTap: () { - debugPrint("ListTile tapped!"); - }, - title: Container( - child: Stack( - // **** AlignmentDirectional is used to place the text whereever we wanted on the image - alignment: AlignmentDirectional(0, 1), - children: [ - // **** Hero animation **** - Hero( - tag: news[i]['title'], - // **** FadeinImage is used to get more UX **** - child: FadeInImage.assetNetwork( - placeholder: 'images/loading.gif', - image: news[i]['urlToImage'] == null - ? Image.asset( - 'images/imgPlaceholder.png', - ).toString() - : news[i]['urlToImage'], - ), - ), - Padding( - padding: const EdgeInsets.all(5.0), - child: Text( - news[i]['title'] == null - ? Text("Title here").toString() - : news[i]['title'].toString(), - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: 16.0, - fontWeight: FontWeight.bold), - ), - ), - ], - ), - ), - subtitle: Row( - mainAxisAlignment: MainAxisAlignment.end, + // key: _refreshKey1, + // onRefresh: _refresh1, + ListView.builder( + itemCount: news == null ? 0 : news.length, + itemBuilder: (_, int i) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(2.0), + child: Card( + color: Colors.blueGrey, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + child: ListTile( + onTap: () { + debugPrint("ListTile tapped!"); + }, + title: Container( + child: Stack( + // **** AlignmentDirectional is used to place the text whereever we wanted on the image + alignment: AlignmentDirectional(0, 1), children: [ + // **** Hero animation **** + Hero( + tag: news[i]['title'], + // **** FadeinImage is used to get more UX **** + child: FadeInImage.assetNetwork( + placeholder: 'images/loading.gif', + image: news[i]['urlToImage'] == null + ? Image.asset( + 'images/imgPlaceholder.png', + ).toString() + : news[i]['urlToImage'], + ), + ), Padding( - padding: const EdgeInsets.symmetric( - vertical: 2.0), - child: FlatButton( - splashColor: Colors.grey, - onPressed: () { - // **** Navigate the user to articleDetail page when the button is pressed along with passing the data by using constructor methods. - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => - ArticleDetail( - articles: news[i] == null - ? Text("Loading!") - : news[i], - ), - ), - ); - }, - child: Text( - "Read More", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.white, - fontSize: 18.0, - letterSpacing: 0.8), - ), + padding: const EdgeInsets.all(5.0), + child: Text( + news[i]['title'] == null + ? Text("Title here").toString() + : news[i]['title'].toString(), + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 16.0, + fontWeight: FontWeight.bold), ), ), ], ), ), + subtitle: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 2.0), + child: FlatButton( + splashColor: Colors.grey, + onPressed: () { + // **** Navigate the user to articleDetail page when the button is pressed along with passing the data by using constructor methods. + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + ArticleDetail( + articles: news[i] == null + ? Text("Loading!") + : news[i], + ), + ), + ); + }, + child: Text( + "Read More", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 18.0, + letterSpacing: 0.8), + ), + ), + ), + ], + ), ), ), - Container(), - ], - ); - }, - ), - + ), + Container(), + ], + ); + }, + ), // // Building list of allnews from allnews[] list // RefreshIndicator( // key: _refreshKey2, // onRefresh: _refresh2, - ListView.builder( - itemCount: allnews == null ? 0 : allnews.length, - itemBuilder: (_, int i) { - return Column( - children: [ - Padding( - padding: const EdgeInsets.all(2.0), - child: Card( - color: Colors.blueGrey, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5.0), - ), - child: ListTile( - onTap: () { - debugPrint("Hello"); - }, - title: Container( - child: Stack( - alignment: AlignmentDirectional(0, 1), - children: [ - Hero( - tag: allnews[i]['title'], - child: FadeInImage.assetNetwork( - placeholder: 'images/loading.gif', - image: - allnews[i]['urlToImage'] == null - ? Image.asset( - 'images/imgPlaceholder.png', - ).toString() - : allnews[i]['urlToImage'], - ), - ), - Padding( - padding: const EdgeInsets.all(5.0), - child: Text( - allnews[i]['title'] == null - ? Text("Title here").toString() - : allnews[i]['title'].toString(), - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: 18.0, - fontWeight: FontWeight.bold), - ), - ), - ], - ), - ), - subtitle: Row( - mainAxisAlignment: MainAxisAlignment.end, + ListView.builder( + itemCount: allnews == null ? 0 : allnews.length, + itemBuilder: (_, int i) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(2.0), + child: Card( + color: Colors.blueGrey, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + ), + child: ListTile( + onTap: () { + debugPrint("Hello"); + }, + title: Container( + child: Stack( + alignment: AlignmentDirectional(0, 1), children: [ + Hero( + tag: allnews[i]['title'], + child: FadeInImage.assetNetwork( + placeholder: 'images/loading.gif', + image: allnews[i]['urlToImage'] == null + ? Image.asset( + 'images/imgPlaceholder.png', + ).toString() + : allnews[i]['urlToImage'], + ), + ), Padding( - padding: const EdgeInsets.symmetric( - vertical: 2.0), - child: FlatButton( - splashColor: Colors.black, - // color: Colors.black54, - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => - ArticleDetail( - articles: news[i] == null - ? Text("Loading!") - : allnews[i], - ), - ), - ); - }, - child: Text( - "Read More", - style: TextStyle( - fontWeight: FontWeight.bold, + padding: const EdgeInsets.all(5.0), + child: Text( + allnews[i]['title'] == null + ? Text("Title here").toString() + : allnews[i]['title'].toString(), + textAlign: TextAlign.center, + style: TextStyle( color: Colors.white, fontSize: 18.0, - ), - ), + fontWeight: FontWeight.bold), ), ), ], ), ), + subtitle: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 2.0), + child: FlatButton( + splashColor: Colors.black, + // color: Colors.black54, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + ArticleDetail( + articles: news[i] == null + ? Text("Loading!") + : allnews[i], + ), + ), + ); + }, + child: Text( + "Read More", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 18.0, + ), + ), + ), + ), + ], + ), ), ), - Container(), - ], - ); - }, - ), - + ), + Container(), + ], + ); + }, + ), ], ), ], diff --git a/lib/ui/login.dart b/lib/ui/login.dart new file mode 100644 index 0000000..89d1b64 --- /dev/null +++ b/lib/ui/login.dart @@ -0,0 +1,209 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:news_app/services/googleSignIn.dart'; +import 'package:news_app/services/usermanagement.dart'; +import 'package:news_app/ui/articles.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:data_connection_checker/data_connection_checker.dart'; + +class Login extends StatefulWidget { + @override + _LoginState createState() => _LoginState(); +} + +class _LoginState extends State with SingleTickerProviderStateMixin { + Animation animation; + AnimationController controller; + // **** Auth class from googleSignIn.dart **** + Auth _auth = Auth(); + FirebaseAuth firebaseAuth = FirebaseAuth.instance; + UserManagement userManagement = UserManagement(); + FirebaseUser currentUser; + // **** SharedPreferences is used to store local data that when the user wants to launch the app again it won't show splash screen or starter notes again. **** + SharedPreferences preferences; + + // bool loading = false; + bool isLogedin = false; + bool isLoading = false; + + @override + void initState() { + super.initState(); + + // **** Check whether the device is connected to any network or not **** + _checkDataConnectivity(); + controller = AnimationController( + vsync: this, + duration: Duration(milliseconds: 1500), + ); + animation = Tween(begin: 0.0, end: 100.0).animate( + CurvedAnimation( + curve: Interval(0.0, 0.5, curve: Curves.bounceInOut), + parent: controller), + ); + + controller.forward(); + // Checking if the user is already signedin or not if signed in then directly return him to homescreen else he/she will be authenticated(should be signin first) + this.isSignedIn(); + } + + @override + void dispose() { + // **** Cancelling all the resources of animation **** + controller.dispose(); + super.dispose(); + } + + void isSignedIn() async { + // **** check if user is already logged in or not if yes the set isLogedin value to true. + await firebaseAuth.currentUser().then((user) { + if (user != null) { + setState(() => isLogedin = true); + } + }); + // **** if isLogedin is true then return the user to our Homescreen **** + if (isLogedin) { + Navigator.pushReplacement( + context, MaterialPageRoute(builder: (context) => AllNews())); + } + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: animation, + builder: (BuildContext context, Widget child) { + return Scaffold( + body: Container( + child: ListView( + children: [ + SizedBox( + height: 50.0, + ), + Image.asset( + "images/icon/launcherIcon.png", + // **** Resizing the image as per the animation value **** + height: 100.0, + width: 100.0, + ), + // Container( + // padding: + // const EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0), + // child: Text( + // "Welcome to BuzzyFeed.From now I hope you will never miss any update.", + // style: TextStyle(), + // ), + // ), + + Container( + height: MediaQuery.of(context).size.height / 2, + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.all(2.0), + child: MaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50.0), + ), + color: Colors.purpleAccent, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 40.0, vertical: 15.0), + child: Text( + "Sign In With Google", + style: TextStyle( + color: Colors.white, + fontSize: 22.0, + ), + ), + ), + onPressed: () async { + // **** Show Loading Indicator when button is pressed **** + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return AlertDialog( + content: Row( + children: [ + CircularProgressIndicator(), + SizedBox( + width: 20.0, + ), + Text("Loading!") + ], + ), + ); + }); + // **** We are checkng whether googleUser is empty or not if not empty then send Email Verification and show the dialog **** + FirebaseUser user = await _auth.googleSignIn(); + + if (user != null) { + // Send email verification + // user.sendEmailVerification().then((val) { + // _showCofirmDialog(); + // }); + // **** Create the user in Firebase Realtime Database by using UserManagemet class **** + userManagement.createUser(user.uid.toString(), { + "userName": user.displayName, + "email": user.email, + "photoUrl": user.photoUrl, + "userId": user.uid, + }); + + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => AllNews())); + Navigator.of(context).pop(); + } + }, + ), + ), + ), + ], + ), + ), + ); + }); + } + + Future _checkDataConnectivity() async { + // **** Check the connectivity **** + var result = await DataConnectionChecker().hasConnection; + if (result == true) { + print("COnnected"); + } else { + // **** Showing confirmation dialog **** + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + content: Text("No Internet Please Connect To Network!"), + actions: [ + FlatButton( + onPressed: () => Navigator.of(context).pop(), + child: Text("OK"), + ) + ], + ); + }); + print('No internet :( Reason:'); + print(DataConnectionChecker().lastTryResults); + } + } +} + +// Dark Mode +// bool _darkmode = false; + +// theme: _darkmode ? ThemeData.dark() : ThemeData.light(), + +// ListTile( +// title: Text("DarkMode"), +// trailing: Switch( +// value: _darkmode, +// onChanged: (val) { +// setState(() { +// _darkmode = val; +// }); +// }, +// ), +// ), diff --git a/pubspec.lock b/pubspec.lock index d063891..9667968 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -43,13 +43,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.14.11" - connectivity: - dependency: "direct main" - description: - name: connectivity - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3+4" convert: dependency: transitive description: @@ -80,6 +73,13 @@ packages: url: "https://github.com/MarkOSullivan94/dart_config.git" source: git version: "0.5.0" + data_connection_checker: + dependency: "direct main" + description: + name: data_connection_checker + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" firebase_auth: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ed3ab04..8f7da0d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,14 +27,12 @@ dependencies: intl: ^0.15.8 url_launcher: ^5.0.2 flutter_launcher_icons: "^0.6.1" - # Firebase Plugins firebase_core: ^0.4.0+6 firebase_auth: ^0.11.1+6 google_sign_in: ^4.0.2 - # cloud_firestore: ^0.12.5 firebase_database: shared_preferences: ^0.4.3 - connectivity: ^0.4.3+4 + data_connection_checker: 0.3.4 flutter_icons: android: "launcher_icon"