From de70c8f33cda9c3b8453b0e70948deeb5a265e14 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 15:28:32 +0000 Subject: [PATCH 01/42] Migrate to Android embedding v2 --- android/app/src/main/AndroidManifest.xml | 17 ++++++++++------- .../co/appbrewery/flash_chat/MainActivity.java | 12 ++++-------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 29713595af..329cc0efeb 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - + + android:name="io.flutter.embedding.android.SplashScreenDrawable" + android:resource="@drawable/launch_background" /> + + + + diff --git a/android/app/src/main/java/co/appbrewery/flash_chat/MainActivity.java b/android/app/src/main/java/co/appbrewery/flash_chat/MainActivity.java index b68d4927dc..a75b890059 100644 --- a/android/app/src/main/java/co/appbrewery/flash_chat/MainActivity.java +++ b/android/app/src/main/java/co/appbrewery/flash_chat/MainActivity.java @@ -1,13 +1,9 @@ package co.appbrewery.flash_chat; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; + +import io.flutter.embedding.android.FlutterActivity; + public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } + } From 5f9242822a67fa8256ec3c0c4c73663a48073433 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 15:58:19 +0000 Subject: [PATCH 02/42] Upgrade cupertino icons dependency from 0.1.2 to 1.0.4 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index e6d5ae3d17..274d699da5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.4 dev_dependencies: flutter_test: From 462f6bafaf803af64d8ee4675ba71938de844243 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 16:45:38 +0000 Subject: [PATCH 03/42] Set bodyText1 TextStyle as TextTheme --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 6ea23d095c..a97abd52f5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,7 +12,7 @@ class FlashChat extends StatelessWidget { return MaterialApp( theme: ThemeData.dark().copyWith( textTheme: TextTheme( - body1: TextStyle(color: Colors.black54), + bodyText1: TextStyle(color: Colors.black54), ), ), home: WelcomeScreen(), From 224450c32c4a427e1598b190bafb0e0da9d567ac Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 16:47:46 +0000 Subject: [PATCH 04/42] distributionUrl gradle from 5.4.1 to 6.7 --- android/gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 63ab3ae08f..bc6a58afdd 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-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip From 9a858f9a5a1aefcaecdda2bfc434ec9b1e591214 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 16:51:26 +0000 Subject: [PATCH 05/42] Change deprecated jcenter to mavenCentral --- android/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 6de372893d..d8f8126d98 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,7 +1,7 @@ buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { @@ -12,7 +12,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } From 973908df4e4980f42f8febb1af9075b6b91a04f3 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 16:52:39 +0000 Subject: [PATCH 06/42] Update gradle dependency to 4.1.0 --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index d8f8126d98..0b4cf534e0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.1.0' } } From 1f9cd26365eda06aa36a360f9775efa535eacb68 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 17:14:01 +0000 Subject: [PATCH 07/42] Create id variable to use in named routes --- lib/screens/chat_screen.dart | 2 ++ lib/screens/login_screen.dart | 2 ++ lib/screens/registration_screen.dart | 2 ++ lib/screens/welcome_screen.dart | 1 + 4 files changed, 7 insertions(+) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 42d8b67b9b..6c1bdc9400 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; class ChatScreen extends StatefulWidget { + static String id = 'chat_screen'; + @override _ChatScreenState createState() => _ChatScreenState(); } diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 852e116a19..785f6dddc0 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; class LoginScreen extends StatefulWidget { + static String id = 'login_screen'; + @override _LoginScreenState createState() => _LoginScreenState(); } diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index bbc0d5195e..4e97aadce7 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; class RegistrationScreen extends StatefulWidget { + static String id = 'registration_screen'; + @override _RegistrationScreenState createState() => _RegistrationScreenState(); } diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index 6270ccf476..5c673bafed 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; class WelcomeScreen extends StatefulWidget { + static String id = 'welcome_screen'; @override _WelcomeScreenState createState() => _WelcomeScreenState(); } From b855fd4e8b12a0c6352b48943d671fc59876d179 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 17:15:42 +0000 Subject: [PATCH 08/42] Add named routes --- lib/main.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index a97abd52f5..4b13aa378e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,7 +15,13 @@ class FlashChat extends StatelessWidget { bodyText1: TextStyle(color: Colors.black54), ), ), - home: WelcomeScreen(), + initialRoute: WelcomeScreen.id, + routes: { + WelcomeScreen.id: (context) => WelcomeScreen(), + LoginScreen.id: (context) => LoginScreen(), + RegistrationScreen.id: (context) => RegistrationScreen(), + ChatScreen.id: (context) => ChatScreen(), + }, ); } } From 13a639848865f617e8cd2e86886e8550edecc971 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 17:21:10 +0000 Subject: [PATCH 09/42] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 11fe08c30f..e2a569954e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ We’re going to build a modern messaging app where users can sign up and log in - How to incorporate Firebase into your Flutter projects. - How to use Firebase authentication to register and sign in users. - How to create beautiful animations using the Flutter Hero widget. -- How to create custom aniamtions using Flutter's animation controller. +- How to create custom animations using Flutter's animation controller. - Learn all about mixins and how they differ from superclasses. - Learn about Streams and how they work. - Learn to use ListViews to build scrolling views. From 8bdc9e7da332158c69690f7237759cf34291661b Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 17:26:03 +0000 Subject: [PATCH 10/42] Make id variable constant - add const keyword --- lib/screens/chat_screen.dart | 2 +- lib/screens/login_screen.dart | 2 +- lib/screens/registration_screen.dart | 2 +- lib/screens/welcome_screen.dart | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 6c1bdc9400..35c708bf9c 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; class ChatScreen extends StatefulWidget { - static String id = 'chat_screen'; + static const String id = 'chat_screen'; @override _ChatScreenState createState() => _ChatScreenState(); diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 785f6dddc0..07a2cd6c3c 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class LoginScreen extends StatefulWidget { - static String id = 'login_screen'; + static const String id = 'login_screen'; @override _LoginScreenState createState() => _LoginScreenState(); diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 4e97aadce7..c592531e7e 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class RegistrationScreen extends StatefulWidget { - static String id = 'registration_screen'; + static const String id = 'registration_screen'; @override _RegistrationScreenState createState() => _RegistrationScreenState(); diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index 5c673bafed..3a769123fd 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class WelcomeScreen extends StatefulWidget { - static String id = 'welcome_screen'; + static const String id = 'welcome_screen'; @override _WelcomeScreenState createState() => _WelcomeScreenState(); } From 43074c1eb440caf3df27d64a2b7b3f2514a16ac5 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 17:40:54 +0000 Subject: [PATCH 11/42] Add text color --- lib/screens/welcome_screen.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index 3a769123fd..ba5ddc1134 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -1,3 +1,5 @@ +import 'package:flash_chat/screens/login_screen.dart'; +import 'package:flash_chat/screens/registration_screen.dart'; import 'package:flutter/material.dart'; class WelcomeScreen extends StatefulWidget { @@ -28,6 +30,7 @@ class _WelcomeScreenState extends State { style: TextStyle( fontSize: 45.0, fontWeight: FontWeight.w900, + color: Colors.black54, ), ), ], @@ -44,6 +47,7 @@ class _WelcomeScreenState extends State { child: MaterialButton( onPressed: () { //Go to login screen. + Navigator.pushNamed(context, LoginScreen.id); }, minWidth: 200.0, height: 42.0, @@ -62,6 +66,7 @@ class _WelcomeScreenState extends State { child: MaterialButton( onPressed: () { //Go to registration screen. + Navigator.pushNamed(context, RegistrationScreen.id); }, minWidth: 200.0, height: 42.0, From 40b56a1cd364fe25492fefe24cf75916328d808b Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 18:24:16 +0000 Subject: [PATCH 12/42] Add hero widget to animate the logo --- lib/screens/login_screen.dart | 9 ++++++--- lib/screens/registration_screen.dart | 9 ++++++--- lib/screens/welcome_screen.dart | 9 ++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 07a2cd6c3c..d64ed74135 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -18,9 +18,12 @@ class _LoginScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Container( - height: 200.0, - child: Image.asset('images/logo.png'), + Hero( + tag: 'logo', + child: Container( + height: 200.0, + child: Image.asset('images/logo.png'), + ), ), SizedBox( height: 48.0, diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index c592531e7e..5c25398f00 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -18,9 +18,12 @@ class _RegistrationScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Container( - height: 200.0, - child: Image.asset('images/logo.png'), + Hero( + tag: 'logo', + child: Container( + height: 200.0, + child: Image.asset('images/logo.png'), + ), ), SizedBox( height: 48.0, diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index ba5ddc1134..1fa22b591e 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -21,9 +21,12 @@ class _WelcomeScreenState extends State { children: [ Row( children: [ - Container( - child: Image.asset('images/logo.png'), - height: 60.0, + Hero( + tag: 'logo', + child: Container( + child: Image.asset('images/logo.png'), + height: 60.0, + ), ), Text( 'Flash Chat', From 072d748ff588b1a6681f1034530cfffadc06c4fe Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Sat, 15 Jan 2022 18:32:58 +0000 Subject: [PATCH 13/42] Set the color of the hint text --- lib/screens/login_screen.dart | 2 ++ lib/screens/registration_screen.dart | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index d64ed74135..0cd0f1f445 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -34,6 +34,7 @@ class _LoginScreenState extends State { }, decoration: InputDecoration( hintText: 'Enter your email', + hintStyle: TextStyle(color: Colors.black45), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( @@ -60,6 +61,7 @@ class _LoginScreenState extends State { }, decoration: InputDecoration( hintText: 'Enter your password.', + hintStyle: TextStyle(color: Colors.black45), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 5c25398f00..663a3a6bd2 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -34,6 +34,7 @@ class _RegistrationScreenState extends State { }, decoration: InputDecoration( hintText: 'Enter your email', + hintStyle: TextStyle(color: Colors.black45), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( @@ -58,6 +59,7 @@ class _RegistrationScreenState extends State { }, decoration: InputDecoration( hintText: 'Enter your password', + hintStyle: TextStyle(color: Colors.black45), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( From 25702cd249244678a12f63bdedf236ca7ffccf41 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 16:41:09 +0000 Subject: [PATCH 14/42] Animate the app's background color --- lib/screens/welcome_screen.dart | 34 +++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index 1fa22b591e..c5736bed4f 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -8,11 +8,41 @@ class WelcomeScreen extends StatefulWidget { _WelcomeScreenState createState() => _WelcomeScreenState(); } -class _WelcomeScreenState extends State { +class _WelcomeScreenState extends State + with SingleTickerProviderStateMixin { + AnimationController controller; + Animation animation; + + @override + void initState() { + super.initState(); + + controller = AnimationController( + vsync: this, + duration: Duration(seconds: 1), + ); + + animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) + .animate(controller); + + controller.forward(); + + controller.addListener(() { + setState(() {}); + print(animation.value); + }); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Colors.white, + backgroundColor: animation.value, body: Padding( padding: EdgeInsets.symmetric(horizontal: 24.0), child: Column( From 267683e59f23b5e99ab9bcab397731c0cf064903 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 16:53:55 +0000 Subject: [PATCH 15/42] Add animated_text_kit package dependency --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index 274d699da5..f78e08d44a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: sdk: flutter cupertino_icons: ^1.0.4 + animated_text_kit: ^4.2.1 dev_dependencies: flutter_test: From e3a914456fe91a4780483217183c87682a3ceb9e Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 18:44:32 +0000 Subject: [PATCH 16/42] Implement the animated text kit pacckage --- lib/screens/welcome_screen.dart | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index c5736bed4f..a78fc91a9b 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -1,6 +1,7 @@ import 'package:flash_chat/screens/login_screen.dart'; import 'package:flash_chat/screens/registration_screen.dart'; import 'package:flutter/material.dart'; +import 'package:animated_text_kit/animated_text_kit.dart'; class WelcomeScreen extends StatefulWidget { static const String id = 'welcome_screen'; @@ -58,13 +59,17 @@ class _WelcomeScreenState extends State height: 60.0, ), ), - Text( - 'Flash Chat', - style: TextStyle( - fontSize: 45.0, - fontWeight: FontWeight.w900, - color: Colors.black54, - ), + AnimatedTextKit( + animatedTexts: [ + TypewriterAnimatedText( + 'Flash Chat', + textStyle: TextStyle( + fontSize: 45.0, + fontWeight: FontWeight.w900, + color: Colors.black54, + ), + ), + ], ), ], ), From bd51b8a6075cab931fbcd6548a9d85dc8f0269f3 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 19:19:24 +0000 Subject: [PATCH 17/42] Extract Padding widget into a custom widget --- lib/screens/welcome_screen.dart | 76 +++++++++++++++++---------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index a78fc91a9b..64cb46eddb 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -76,47 +76,49 @@ class _WelcomeScreenState extends State SizedBox( height: 48.0, ), - Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Material( - elevation: 5.0, - color: Colors.lightBlueAccent, - borderRadius: BorderRadius.circular(30.0), - child: MaterialButton( - onPressed: () { - //Go to login screen. - Navigator.pushNamed(context, LoginScreen.id); - }, - minWidth: 200.0, - height: 42.0, - child: Text( - 'Log In', - ), - ), - ), - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Material( - color: Colors.blueAccent, - borderRadius: BorderRadius.circular(30.0), - elevation: 5.0, - child: MaterialButton( - onPressed: () { - //Go to registration screen. - Navigator.pushNamed(context, RegistrationScreen.id); - }, - minWidth: 200.0, - height: 42.0, - child: Text( - 'Register', - ), - ), - ), + RoundedButton( + colour: Colors.lightBlueAccent, + title: 'Log in', + onPressed: () { + Navigator.pushNamed(context, LoginScreen.id); + }, ), + RoundedButton( + colour: Colors.blueAccent, + title: 'Register', + onPressed: () { + Navigator.pushNamed(context, RegistrationScreen.id); + }, + ) ], ), ), ); } } + +class RoundedButton extends StatelessWidget { + const RoundedButton({this.colour, this.title, @required this.onPressed}); + + final Color colour; + final String title; + final Function onPressed; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(vertical: 16.0), + child: Material( + elevation: 5.0, + color: colour, + borderRadius: BorderRadius.circular(30.0), + child: MaterialButton( + onPressed: onPressed, + minWidth: 200.0, + height: 42.0, + child: Text(title), + ), + ), + ); + } +} From 034d085f3da387f84196242c8bcc992c03c4c435 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 19:28:38 +0000 Subject: [PATCH 18/42] New file for custom button --- lib/components/rounded_button.dart | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/components/rounded_button.dart diff --git a/lib/components/rounded_button.dart b/lib/components/rounded_button.dart new file mode 100644 index 0000000000..6c57dc1fa4 --- /dev/null +++ b/lib/components/rounded_button.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class RoundedButton extends StatelessWidget { + const RoundedButton({this.colour, this.title, @required this.onPressed}); + + final Color colour; + final String title; + final Function onPressed; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(vertical: 16.0), + child: Material( + elevation: 5.0, + color: colour, + borderRadius: BorderRadius.circular(30.0), + child: MaterialButton( + onPressed: onPressed, + minWidth: 200.0, + height: 42.0, + child: Text(title), + ), + ), + ); + } +} From 669c34698ad4b8904932412e0167de5fd0609dbb Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Mon, 17 Jan 2022 19:30:06 +0000 Subject: [PATCH 19/42] Move custom RoundedButton class into a new file --- lib/screens/welcome_screen.dart | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/lib/screens/welcome_screen.dart b/lib/screens/welcome_screen.dart index 64cb46eddb..d81f33276d 100644 --- a/lib/screens/welcome_screen.dart +++ b/lib/screens/welcome_screen.dart @@ -2,6 +2,7 @@ import 'package:flash_chat/screens/login_screen.dart'; import 'package:flash_chat/screens/registration_screen.dart'; import 'package:flutter/material.dart'; import 'package:animated_text_kit/animated_text_kit.dart'; +import 'package:flash_chat/components/rounded_button.dart'; class WelcomeScreen extends StatefulWidget { static const String id = 'welcome_screen'; @@ -96,29 +97,3 @@ class _WelcomeScreenState extends State ); } } - -class RoundedButton extends StatelessWidget { - const RoundedButton({this.colour, this.title, @required this.onPressed}); - - final Color colour; - final String title; - final Function onPressed; - - @override - Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Material( - elevation: 5.0, - color: colour, - borderRadius: BorderRadius.circular(30.0), - child: MaterialButton( - onPressed: onPressed, - minWidth: 200.0, - height: 42.0, - child: Text(title), - ), - ), - ); - } -} From 3125fe57bbbc542f5e325b2aeb9844c11baca070 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 15:08:03 +0000 Subject: [PATCH 20/42] Create a variable for InputDecoration --- lib/constants.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/constants.dart b/lib/constants.dart index 25e5f5c22f..de443a9457 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -17,3 +17,20 @@ const kMessageContainerDecoration = BoxDecoration( top: BorderSide(color: Colors.lightBlueAccent, width: 2.0), ), ); + +const kTextFieldDecoration = InputDecoration( + hintText: '', + hintStyle: TextStyle(color: Colors.black45), + contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.lightBlueAccent, width: 1.0), + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.lightBlueAccent, width: 2.0), + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), +); From ebb17d4054c7001d3647fec7edf690367db5f213 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 15:09:59 +0000 Subject: [PATCH 21/42] Refactor - Replace InputDecoration with a variable --- lib/screens/login_screen.dart | 66 +++++----------------------- lib/screens/registration_screen.dart | 61 ++++--------------------- 2 files changed, 18 insertions(+), 109 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 0cd0f1f445..2f94c697a6 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,4 +1,6 @@ +import 'package:flash_chat/constants.dart'; import 'package:flutter/material.dart'; +import 'package:flash_chat/components/rounded_button.dart'; class LoginScreen extends StatefulWidget { static const String id = 'login_screen'; @@ -32,25 +34,8 @@ class _LoginScreenState extends State { onChanged: (value) { //Do something with the user input. }, - decoration: InputDecoration( - hintText: 'Enter your email', - hintStyle: TextStyle(color: Colors.black45), - contentPadding: - EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), - border: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - enabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.lightBlueAccent, width: 1.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - focusedBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.lightBlueAccent, width: 2.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - ), + decoration: + kTextFieldDecoration.copyWith(hintText: 'Enter your email'), ), SizedBox( height: 8.0, @@ -59,47 +44,16 @@ class _LoginScreenState extends State { onChanged: (value) { //Do something with the user input. }, - decoration: InputDecoration( - hintText: 'Enter your password.', - hintStyle: TextStyle(color: Colors.black45), - contentPadding: - EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), - border: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - enabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.lightBlueAccent, width: 1.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - focusedBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.lightBlueAccent, width: 2.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - ), + decoration: kTextFieldDecoration.copyWith( + hintText: 'Enter your password'), ), SizedBox( height: 24.0, ), - Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Material( - color: Colors.lightBlueAccent, - borderRadius: BorderRadius.all(Radius.circular(30.0)), - elevation: 5.0, - child: MaterialButton( - onPressed: () { - //Implement login functionality. - }, - minWidth: 200.0, - height: 42.0, - child: Text( - 'Log In', - ), - ), - ), - ), + RoundedButton( + title: 'Log In', + colour: Colors.lightBlueAccent, + onPressed: () {}), ], ), ), diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 663a3a6bd2..983fe37371 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flash_chat/components/rounded_button.dart'; +import 'package:flash_chat/constants.dart'; class RegistrationScreen extends StatefulWidget { static const String id = 'registration_screen'; @@ -32,23 +34,8 @@ class _RegistrationScreenState extends State { onChanged: (value) { //Do something with the user input. }, - decoration: InputDecoration( - hintText: 'Enter your email', - hintStyle: TextStyle(color: Colors.black45), - contentPadding: - EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), - border: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.blueAccent, width: 1.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.blueAccent, width: 2.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - ), + decoration: + kTextFieldDecoration.copyWith(hintText: 'Enter your email'), ), SizedBox( height: 8.0, @@ -57,46 +44,14 @@ class _RegistrationScreenState extends State { onChanged: (value) { //Do something with the user input. }, - decoration: InputDecoration( - hintText: 'Enter your password', - hintStyle: TextStyle(color: Colors.black45), - contentPadding: - EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), - border: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.blueAccent, width: 1.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.blueAccent, width: 2.0), - borderRadius: BorderRadius.all(Radius.circular(32.0)), - ), - ), + decoration: kTextFieldDecoration.copyWith( + hintText: 'Enter your password'), ), SizedBox( height: 24.0, ), - Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Material( - color: Colors.blueAccent, - borderRadius: BorderRadius.all(Radius.circular(30.0)), - elevation: 5.0, - child: MaterialButton( - onPressed: () { - //Implement registration functionality. - }, - minWidth: 200.0, - height: 42.0, - child: Text( - 'Register', - style: TextStyle(color: Colors.white), - ), - ), - ), - ), + RoundedButton( + title: 'Register', colour: Colors.blueAccent, onPressed: () {}), ], ), ), From 03f3b23f46fc6db08dd0c86fc5712cc70408563d Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 15:29:25 +0000 Subject: [PATCH 22/42] Edit applicationId --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index e8d2b49ddc..39aabebacb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -34,7 +34,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "co.appbrewery.flash_chat" + applicationId "com.nnq.flash_chat" minSdkVersion 16 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() From cac1922af9519c246f0f4982f09cd4f171422763 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 15:47:09 +0000 Subject: [PATCH 23/42] Edit --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 07488ba61a..3cf40fa3aa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ .buildlog/ .history .svn/ +*.lock + # IntelliJ related *.iml @@ -61,6 +63,10 @@ **/ios/Flutter/flutter_assets/ **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* +*.sh + +# Firebase +*.json # Exceptions to above rules. !**/ios/**/default.mode1v3 From 197581b22ce024d3f93fe1d1f0914892f703aa29 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 16:01:46 +0000 Subject: [PATCH 24/42] Edit to inteegrate Firebase --- android/app/build.gradle | 2 ++ android/build.gradle | 1 + 2 files changed, 3 insertions(+) diff --git a/android/app/build.gradle b/android/app/build.gradle index 39aabebacb..cc6fc723c4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,6 +24,7 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +apply plugin: 'com.google.gms.google-services' android { compileSdkVersion 29 @@ -57,4 +58,5 @@ flutter { dependencies { implementation 'androidx.multidex:multidex:2.0.0' + implementation platform('com.google.firebase:firebase-bom:29.0.3') } diff --git a/android/build.gradle b/android/build.gradle index 0b4cf534e0..12a537a680 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,6 +6,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.google.gms:google-services:4.3.10' } } From 6503321e48a09c7d4a3bf7c0748a672f0a05e4a4 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 18:11:57 +0000 Subject: [PATCH 25/42] Add Firebase dependencies - core, auth, firestore --- pubspec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pubspec.yaml b/pubspec.yaml index f78e08d44a..f22b9b84fe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,6 +12,9 @@ dependencies: cupertino_icons: ^1.0.4 animated_text_kit: ^4.2.1 + firebase_core: ^1.11.0 + firebase_auth: ^3.3.5 + cloud_firestore: ^3.1.6 dev_dependencies: flutter_test: From 8bf3bdf88036d56be7ed25a79cbcee269be05b72 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 18:35:49 +0000 Subject: [PATCH 26/42] Assign user email and password to variables --- lib/screens/registration_screen.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 983fe37371..0cf0b7f425 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -10,6 +10,9 @@ class RegistrationScreen extends StatefulWidget { } class _RegistrationScreenState extends State { + String email; + String password; + @override Widget build(BuildContext context) { return Scaffold( @@ -32,7 +35,7 @@ class _RegistrationScreenState extends State { ), TextField( onChanged: (value) { - //Do something with the user input. + email = value; }, decoration: kTextFieldDecoration.copyWith(hintText: 'Enter your email'), @@ -42,7 +45,7 @@ class _RegistrationScreenState extends State { ), TextField( onChanged: (value) { - //Do something with the user input. + password = value; }, decoration: kTextFieldDecoration.copyWith( hintText: 'Enter your password'), From b3a322eb97c677e8c9b74b4331454cc3e87c4028 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 18:36:36 +0000 Subject: [PATCH 27/42] Set minSdkVersion to 19 --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index cc6fc723c4..3770f3e851 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -36,7 +36,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.nnq.flash_chat" - minSdkVersion 16 + minSdkVersion 19 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName From a09b6765ff269cf0654cad30373367e76793bfe6 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 18:44:16 +0000 Subject: [PATCH 28/42] Set text alignment, text obscurity & keyboard type --- lib/screens/login_screen.dart | 4 ++++ lib/screens/registration_screen.dart | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index 2f94c697a6..f85589bf80 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -31,6 +31,8 @@ class _LoginScreenState extends State { height: 48.0, ), TextField( + keyboardType: TextInputType.emailAddress, + textAlign: TextAlign.center, onChanged: (value) { //Do something with the user input. }, @@ -41,6 +43,8 @@ class _LoginScreenState extends State { height: 8.0, ), TextField( + obscureText: true, + textAlign: TextAlign.center, onChanged: (value) { //Do something with the user input. }, diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 0cf0b7f425..5763c3a1e6 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -34,6 +34,8 @@ class _RegistrationScreenState extends State { height: 48.0, ), TextField( + keyboardType: TextInputType.emailAddress, + textAlign: TextAlign.center, onChanged: (value) { email = value; }, @@ -44,6 +46,8 @@ class _RegistrationScreenState extends State { height: 8.0, ), TextField( + obscureText: true, + textAlign: TextAlign.center, onChanged: (value) { password = value; }, From e54cbbc2d7b1536c40c36f02741e871f0c6273e9 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:07:47 +0000 Subject: [PATCH 29/42] Create new user with FirebaseAuth --- lib/screens/registration_screen.dart | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 5763c3a1e6..1da276d8d8 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -1,6 +1,8 @@ +import 'package:flash_chat/screens/chat_screen.dart'; import 'package:flutter/material.dart'; import 'package:flash_chat/components/rounded_button.dart'; import 'package:flash_chat/constants.dart'; +import 'package:firebase_auth/firebase_auth.dart'; class RegistrationScreen extends StatefulWidget { static const String id = 'registration_screen'; @@ -13,6 +15,8 @@ class _RegistrationScreenState extends State { String email; String password; + final _auth = FirebaseAuth.instance; + @override Widget build(BuildContext context) { return Scaffold( @@ -58,7 +62,21 @@ class _RegistrationScreenState extends State { height: 24.0, ), RoundedButton( - title: 'Register', colour: Colors.blueAccent, onPressed: () {}), + title: 'Register', + colour: Colors.blueAccent, + onPressed: () async { + // create new user + try { + final newUser = await _auth.createUserWithEmailAndPassword( + email: email, password: password); + // if user already exists, navigate to chat screen + if (newUser != null) { + Navigator.pushNamed(context, ChatScreen.id); + } + } catch (e) { + print(e); + } + }), ], ), ), From 130183fe6945c3c714c5b775a67a76093cb399f9 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:09:01 +0000 Subject: [PATCH 30/42] Create email and password variables & Log in user --- lib/screens/login_screen.dart | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index f85589bf80..f4a2f04d10 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -1,6 +1,8 @@ import 'package:flash_chat/constants.dart'; +import 'package:flash_chat/screens/chat_screen.dart'; import 'package:flutter/material.dart'; import 'package:flash_chat/components/rounded_button.dart'; +import 'package:firebase_auth/firebase_auth.dart'; class LoginScreen extends StatefulWidget { static const String id = 'login_screen'; @@ -10,6 +12,11 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { + final _auth = FirebaseAuth.instance; + + String userEmail; + String userPassword; + @override Widget build(BuildContext context) { return Scaffold( @@ -34,7 +41,7 @@ class _LoginScreenState extends State { keyboardType: TextInputType.emailAddress, textAlign: TextAlign.center, onChanged: (value) { - //Do something with the user input. + userEmail = value; }, decoration: kTextFieldDecoration.copyWith(hintText: 'Enter your email'), @@ -46,7 +53,7 @@ class _LoginScreenState extends State { obscureText: true, textAlign: TextAlign.center, onChanged: (value) { - //Do something with the user input. + userPassword = value; }, decoration: kTextFieldDecoration.copyWith( hintText: 'Enter your password'), @@ -55,9 +62,20 @@ class _LoginScreenState extends State { height: 24.0, ), RoundedButton( - title: 'Log In', - colour: Colors.lightBlueAccent, - onPressed: () {}), + title: 'Log In', + colour: Colors.lightBlueAccent, + onPressed: () async { + try { + final registeredUser = await _auth.signInWithEmailAndPassword( + email: userEmail, password: userPassword); + if (registeredUser != null) { + Navigator.pushNamed(context, ChatScreen.id); + } + } catch (e) { + print(e); + } + }, + ), ], ), ), From 0a7a6234f2ab9de541f462a658ee03202ca06bc5 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:10:33 +0000 Subject: [PATCH 31/42] Get logged in user --- lib/screens/chat_screen.dart | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 35c708bf9c..c2f94a2828 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; +import 'package:firebase_auth/firebase_auth.dart'; class ChatScreen extends StatefulWidget { static const String id = 'chat_screen'; @@ -9,6 +10,26 @@ class ChatScreen extends StatefulWidget { } class _ChatScreenState extends State { + final _auth = FirebaseAuth.instance; + User loggedInUser; + + @override + void initState() { + super.initState(); + getCurrentUser(); + } + + void getCurrentUser() { + try { + final user = _auth.currentUser; + if (user != null) { + loggedInUser = user; + } + } catch (e) { + print(e); + } + } + @override Widget build(BuildContext context) { return Scaffold( From 1d16a94b3873b43695965852259f5fada82f2837 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:17:38 +0000 Subject: [PATCH 32/42] Implement log out functionality --- lib/screens/chat_screen.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index c2f94a2828..03889da58e 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -40,6 +40,7 @@ class _ChatScreenState extends State { icon: Icon(Icons.close), onPressed: () { //Implement logout functionality + _auth.signOut(); }), ], title: Text('⚡️Chat'), From 891eecdf093cb9be17347013877ab149cd86d5ab Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:24:58 +0000 Subject: [PATCH 33/42] Initialize app to use Firebase --- lib/main.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index 4b13aa378e..4164a00e32 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,8 +3,13 @@ import 'package:flash_chat/screens/welcome_screen.dart'; import 'package:flash_chat/screens/login_screen.dart'; import 'package:flash_chat/screens/registration_screen.dart'; import 'package:flash_chat/screens/chat_screen.dart'; +import 'package:firebase_core/firebase_core.dart'; -void main() => runApp(FlashChat()); +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + runApp(FlashChat()); +} class FlashChat extends StatelessWidget { @override From 68f1d57dfb44d958f2c47d3f71d46c366af649fd Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:50:46 +0000 Subject: [PATCH 34/42] Set navigation to welcome screen when user signs out --- lib/screens/chat_screen.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 03889da58e..1bdbd64b71 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -1,3 +1,4 @@ +import 'package:flash_chat/screens/welcome_screen.dart'; import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; import 'package:firebase_auth/firebase_auth.dart'; @@ -37,11 +38,13 @@ class _ChatScreenState extends State { leading: null, actions: [ IconButton( - icon: Icon(Icons.close), - onPressed: () { - //Implement logout functionality - _auth.signOut(); - }), + icon: Icon(Icons.close), + onPressed: () { + //Implement logout functionality + _auth.signOut(); + Navigator.pushNamed(context, WelcomeScreen.id); + }, + ), ], title: Text('⚡️Chat'), backgroundColor: Colors.lightBlueAccent, From 039303a2f560bf683d09fc83edcb482bbceb70bb Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:51:39 +0000 Subject: [PATCH 35/42] Set input text color to black --- lib/screens/registration_screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index 1da276d8d8..fdb1991cdd 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -40,6 +40,7 @@ class _RegistrationScreenState extends State { TextField( keyboardType: TextInputType.emailAddress, textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), onChanged: (value) { email = value; }, @@ -52,6 +53,7 @@ class _RegistrationScreenState extends State { TextField( obscureText: true, textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), onChanged: (value) { password = value; }, From f22c5bf3eec3d49aa2199ce43c1e2a3d76e3c5af Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Tue, 18 Jan 2022 20:52:10 +0000 Subject: [PATCH 36/42] Set input text color to black --- lib/screens/login_screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index f4a2f04d10..ba542810b7 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -40,6 +40,7 @@ class _LoginScreenState extends State { TextField( keyboardType: TextInputType.emailAddress, textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), onChanged: (value) { userEmail = value; }, @@ -52,6 +53,7 @@ class _LoginScreenState extends State { TextField( obscureText: true, textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), onChanged: (value) { userPassword = value; }, From 173bea991fccf48d34dd442df87970b9bdcd2152 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 10:29:57 +0000 Subject: [PATCH 37/42] Add spinner package - modal progress hud --- pubspec.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pubspec.yaml b/pubspec.yaml index f22b9b84fe..f25ea3e625 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,6 +15,8 @@ dependencies: firebase_core: ^1.11.0 firebase_auth: ^3.3.5 cloud_firestore: ^3.1.6 + modal_progress_hud: ^0.1.3 + dev_dependencies: flutter_test: From 95d25b5f31fe99bb61c77db41ca07eb51d0a1cf4 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 10:36:32 +0000 Subject: [PATCH 38/42] Implement modal progress hud package --- lib/screens/login_screen.dart | 125 ++++++++++++++------------ lib/screens/registration_screen.dart | 126 +++++++++++++++------------ 2 files changed, 137 insertions(+), 114 deletions(-) diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart index ba542810b7..be9c40a4a1 100644 --- a/lib/screens/login_screen.dart +++ b/lib/screens/login_screen.dart @@ -3,6 +3,7 @@ import 'package:flash_chat/screens/chat_screen.dart'; import 'package:flutter/material.dart'; import 'package:flash_chat/components/rounded_button.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:modal_progress_hud/modal_progress_hud.dart'; class LoginScreen extends StatefulWidget { static const String id = 'login_screen'; @@ -12,8 +13,8 @@ class LoginScreen extends StatefulWidget { } class _LoginScreenState extends State { + bool showSpinner = false; final _auth = FirebaseAuth.instance; - String userEmail; String userPassword; @@ -21,64 +22,74 @@ class _LoginScreenState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 24.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Hero( - tag: 'logo', - child: Container( - height: 200.0, - child: Image.asset('images/logo.png'), + body: ModalProgressHUD( + inAsyncCall: showSpinner, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Hero( + tag: 'logo', + child: Container( + height: 200.0, + child: Image.asset('images/logo.png'), + ), + ), + SizedBox( + height: 48.0, + ), + TextField( + keyboardType: TextInputType.emailAddress, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), + onChanged: (value) { + userEmail = value; + }, + decoration: + kTextFieldDecoration.copyWith(hintText: 'Enter your email'), + ), + SizedBox( + height: 8.0, ), - ), - SizedBox( - height: 48.0, - ), - TextField( - keyboardType: TextInputType.emailAddress, - textAlign: TextAlign.center, - style: TextStyle(color: Colors.black), - onChanged: (value) { - userEmail = value; - }, - decoration: - kTextFieldDecoration.copyWith(hintText: 'Enter your email'), - ), - SizedBox( - height: 8.0, - ), - TextField( - obscureText: true, - textAlign: TextAlign.center, - style: TextStyle(color: Colors.black), - onChanged: (value) { - userPassword = value; - }, - decoration: kTextFieldDecoration.copyWith( - hintText: 'Enter your password'), - ), - SizedBox( - height: 24.0, - ), - RoundedButton( - title: 'Log In', - colour: Colors.lightBlueAccent, - onPressed: () async { - try { - final registeredUser = await _auth.signInWithEmailAndPassword( - email: userEmail, password: userPassword); - if (registeredUser != null) { - Navigator.pushNamed(context, ChatScreen.id); + TextField( + obscureText: true, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), + onChanged: (value) { + userPassword = value; + }, + decoration: kTextFieldDecoration.copyWith( + hintText: 'Enter your password'), + ), + SizedBox( + height: 24.0, + ), + RoundedButton( + title: 'Log In', + colour: Colors.lightBlueAccent, + onPressed: () async { + setState(() { + showSpinner = true; + }); + try { + final registeredUser = + await _auth.signInWithEmailAndPassword( + email: userEmail, password: userPassword); + if (registeredUser != null) { + Navigator.pushNamed(context, ChatScreen.id); + } + setState(() { + showSpinner = false; + }); + } catch (e) { + print(e); } - } catch (e) { - print(e); - } - }, - ), - ], + }, + ), + ], + ), ), ), ); diff --git a/lib/screens/registration_screen.dart b/lib/screens/registration_screen.dart index fdb1991cdd..8d2b72ec6d 100644 --- a/lib/screens/registration_screen.dart +++ b/lib/screens/registration_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flash_chat/components/rounded_button.dart'; import 'package:flash_chat/constants.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:modal_progress_hud/modal_progress_hud.dart'; class RegistrationScreen extends StatefulWidget { static const String id = 'registration_screen'; @@ -12,6 +13,7 @@ class RegistrationScreen extends StatefulWidget { } class _RegistrationScreenState extends State { + bool showSpinner = false; String email; String password; @@ -21,65 +23,75 @@ class _RegistrationScreenState extends State { Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 24.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Hero( - tag: 'logo', - child: Container( - height: 200.0, - child: Image.asset('images/logo.png'), + body: ModalProgressHUD( + inAsyncCall: showSpinner, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Hero( + tag: 'logo', + child: Container( + height: 200.0, + child: Image.asset('images/logo.png'), + ), ), - ), - SizedBox( - height: 48.0, - ), - TextField( - keyboardType: TextInputType.emailAddress, - textAlign: TextAlign.center, - style: TextStyle(color: Colors.black), - onChanged: (value) { - email = value; - }, - decoration: - kTextFieldDecoration.copyWith(hintText: 'Enter your email'), - ), - SizedBox( - height: 8.0, - ), - TextField( - obscureText: true, - textAlign: TextAlign.center, - style: TextStyle(color: Colors.black), - onChanged: (value) { - password = value; - }, - decoration: kTextFieldDecoration.copyWith( - hintText: 'Enter your password'), - ), - SizedBox( - height: 24.0, - ), - RoundedButton( - title: 'Register', - colour: Colors.blueAccent, - onPressed: () async { - // create new user - try { - final newUser = await _auth.createUserWithEmailAndPassword( - email: email, password: password); - // if user already exists, navigate to chat screen - if (newUser != null) { - Navigator.pushNamed(context, ChatScreen.id); + SizedBox( + height: 48.0, + ), + TextField( + keyboardType: TextInputType.emailAddress, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), + onChanged: (value) { + email = value; + }, + decoration: + kTextFieldDecoration.copyWith(hintText: 'Enter your email'), + ), + SizedBox( + height: 8.0, + ), + TextField( + obscureText: true, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.black), + onChanged: (value) { + password = value; + }, + decoration: kTextFieldDecoration.copyWith( + hintText: 'Enter your password'), + ), + SizedBox( + height: 24.0, + ), + RoundedButton( + title: 'Register', + colour: Colors.blueAccent, + onPressed: () async { + setState(() { + showSpinner = true; + }); + // create new user + try { + final newUser = + await _auth.createUserWithEmailAndPassword( + email: email, password: password); + // if user already exists, navigate to chat screen + if (newUser != null) { + Navigator.pushNamed(context, ChatScreen.id); + } + setState(() { + showSpinner = false; + }); + } catch (e) { + print(e); } - } catch (e) { - print(e); - } - }), - ], + }), + ], + ), ), ), ); From e939dadef6528ea9f4225b7f7a538875b091c138 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 16:49:17 +0000 Subject: [PATCH 39/42] Navigate to Log In screen after sign out --- lib/screens/chat_screen.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 1bdbd64b71..4152f14184 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -1,4 +1,3 @@ -import 'package:flash_chat/screens/welcome_screen.dart'; import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; import 'package:firebase_auth/firebase_auth.dart'; @@ -42,7 +41,7 @@ class _ChatScreenState extends State { onPressed: () { //Implement logout functionality _auth.signOut(); - Navigator.pushNamed(context, WelcomeScreen.id); + Navigator.pop(context); }, ), ], From ccb25239cbfe4e84a888f33b0019e6e8fb0cc8c1 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 16:50:55 +0000 Subject: [PATCH 40/42] Assign user input to a variable --- lib/screens/chat_screen.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 4152f14184..d4783af847 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -12,6 +12,7 @@ class ChatScreen extends StatefulWidget { class _ChatScreenState extends State { final _auth = FirebaseAuth.instance; User loggedInUser; + String messageText; @override void initState() { @@ -62,6 +63,7 @@ class _ChatScreenState extends State { child: TextField( onChanged: (value) { //Do something with the user input. + messageText = value; }, decoration: kMessageTextFieldDecoration, ), From 2944d49c78b061ffa4b28664459ecbb8626bb920 Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 16:51:40 +0000 Subject: [PATCH 41/42] Change deprecated FlatButton to TextButton --- lib/screens/chat_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index d4783af847..bfc585c84c 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -68,7 +68,7 @@ class _ChatScreenState extends State { decoration: kMessageTextFieldDecoration, ), ), - FlatButton( + TextButton( onPressed: () { //Implement send functionality. }, From 9bc195277a9fa3cbc4965984dd49a6cb1ff8e1fa Mon Sep 17 00:00:00 2001 From: nananyanibaquartey Date: Wed, 19 Jan 2022 16:59:26 +0000 Subject: [PATCH 42/42] Implement send functionality - save message to DB --- lib/screens/chat_screen.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index bfc585c84c..d0e4e79439 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flash_chat/constants.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; class ChatScreen extends StatefulWidget { static const String id = 'chat_screen'; @@ -11,6 +12,7 @@ class ChatScreen extends StatefulWidget { class _ChatScreenState extends State { final _auth = FirebaseAuth.instance; + final _firestore = FirebaseFirestore.instance; User loggedInUser; String messageText; @@ -62,7 +64,7 @@ class _ChatScreenState extends State { Expanded( child: TextField( onChanged: (value) { - //Do something with the user input. + //save user input to a variable. messageText = value; }, decoration: kMessageTextFieldDecoration, @@ -70,7 +72,9 @@ class _ChatScreenState extends State { ), TextButton( onPressed: () { - //Implement send functionality. + //save message to database. + _firestore.collection('messages').add( + {'sender': loggedInUser.email, 'text': messageText}); }, child: Text( 'Send',