From 8e25e113e8501ee48417180833d3ebd3af181a57 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Sun, 29 Dec 2019 22:45:14 +0100 Subject: [PATCH 01/21] gitignore --- .gitignore | 2 ++ lib/{screens => UI}/LoadingScreen.dart | 0 lib/UI/chat_forrum.dart | 0 lib/{screens => UI}/coding_stats.dart | 0 lib/{ => UI}/dashboard.dart | 8 ++++---- lib/{screens => UI}/find_mentor.dart | 0 lib/{screens => UI}/gender_stats.dart | 0 lib/{screens => UI}/profile.dart | 0 lib/{Login => UI}/signin.dart | 0 lib/{Login => UI}/signup.dart | 0 lib/models/AppModel.dart | 0 lib/models/LoginModel.dart | 0 lib/models/SignUpModel.dart | 0 lib/services/service_locator.dart | 0 14 files changed, 6 insertions(+), 4 deletions(-) rename lib/{screens => UI}/LoadingScreen.dart (100%) create mode 100644 lib/UI/chat_forrum.dart rename lib/{screens => UI}/coding_stats.dart (100%) rename lib/{ => UI}/dashboard.dart (95%) rename lib/{screens => UI}/find_mentor.dart (100%) rename lib/{screens => UI}/gender_stats.dart (100%) rename lib/{screens => UI}/profile.dart (100%) rename lib/{Login => UI}/signin.dart (100%) rename lib/{Login => UI}/signup.dart (100%) create mode 100644 lib/models/AppModel.dart create mode 100644 lib/models/LoginModel.dart create mode 100644 lib/models/SignUpModel.dart create mode 100644 lib/services/service_locator.dart diff --git a/.gitignore b/.gitignore index 2ddde2a..cba8b95 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +.flutter-plugins-dependencies +.gitignore diff --git a/lib/screens/LoadingScreen.dart b/lib/UI/LoadingScreen.dart similarity index 100% rename from lib/screens/LoadingScreen.dart rename to lib/UI/LoadingScreen.dart diff --git a/lib/UI/chat_forrum.dart b/lib/UI/chat_forrum.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/screens/coding_stats.dart b/lib/UI/coding_stats.dart similarity index 100% rename from lib/screens/coding_stats.dart rename to lib/UI/coding_stats.dart diff --git a/lib/dashboard.dart b/lib/UI/dashboard.dart similarity index 95% rename from lib/dashboard.dart rename to lib/UI/dashboard.dart index e6b42ab..e12368f 100644 --- a/lib/dashboard.dart +++ b/lib/UI/dashboard.dart @@ -2,10 +2,10 @@ import 'package:bottom_navy_bar/bottom_navy_bar.dart'; import 'package:flutter/material.dart'; import './Login/signup.dart'; import './Login/signin.dart'; -import './screens/gender_stats.dart'; -import './screens/coding_stats.dart'; -import './screens/find_mentor.dart'; -import './screens/profile.dart'; +import 'UI/gender_stats.dart'; +import 'UI/coding_stats.dart'; +import 'UI/find_mentor.dart'; +import 'UI/profile.dart'; class Dashboard extends StatefulWidget { final String username; diff --git a/lib/screens/find_mentor.dart b/lib/UI/find_mentor.dart similarity index 100% rename from lib/screens/find_mentor.dart rename to lib/UI/find_mentor.dart diff --git a/lib/screens/gender_stats.dart b/lib/UI/gender_stats.dart similarity index 100% rename from lib/screens/gender_stats.dart rename to lib/UI/gender_stats.dart diff --git a/lib/screens/profile.dart b/lib/UI/profile.dart similarity index 100% rename from lib/screens/profile.dart rename to lib/UI/profile.dart diff --git a/lib/Login/signin.dart b/lib/UI/signin.dart similarity index 100% rename from lib/Login/signin.dart rename to lib/UI/signin.dart diff --git a/lib/Login/signup.dart b/lib/UI/signup.dart similarity index 100% rename from lib/Login/signup.dart rename to lib/UI/signup.dart diff --git a/lib/models/AppModel.dart b/lib/models/AppModel.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/models/LoginModel.dart b/lib/models/LoginModel.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/models/SignUpModel.dart b/lib/models/SignUpModel.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/services/service_locator.dart b/lib/services/service_locator.dart new file mode 100644 index 0000000..e69de29 From 7c82f8657eb0fe37300e88f07f4084b6749d3f3c Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:47:50 +0100 Subject: [PATCH 02/21] pubspec.lock --- pubspec.lock | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 77796e7..b8665a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -163,6 +163,13 @@ packages: description: flutter source: sdk version: "0.0.0" + get_it: + dependency: "direct main" + description: + name: get_it + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" google_sign_in: dependency: "direct main" description: @@ -282,6 +289,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.5" + scoped_model: + dependency: "direct main" + description: + name: scoped_model + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter From c4b2aab6273651d1d6e2e25702f67272988abfea Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:48:24 +0100 Subject: [PATCH 03/21] added a scopedModel and Get_it dependencies --- pubspec.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pubspec.yaml b/pubspec.yaml index 60315ca..d69d576 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,8 @@ dependencies: google_sign_in: ^4.1.1 firebase_auth: ^0.15.3 modal_progress_hud: ^0.1.3 + scoped_model: ^1.0.1 + get_it: ^3.1.0 dev_dependencies: From 885fa03be4b790aaf5faec56b6b13351db8c96c4 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:49:14 +0100 Subject: [PATCH 04/21] injected dependencies before runApp --- lib/main.dart | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 369ddc1..ee8371a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,19 +1,25 @@ import 'package:flutter/material.dart'; -import 'package:peer_learning/screens/LoadingScreen.dart'; -import './Login/signup.dart'; -import './Login/signin.dart'; +import 'package:peer_learning/UI/LoadingScreen.dart'; +import 'package:peer_learning/models/AppModel.dart'; +import 'package:peer_learning/services/service_locator.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'UI/signup.dart'; +import 'UI/signin.dart'; - -void main() => runApp(MyApp()); +void main() { + setupLocator(); + runApp(MyApp()); +} class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - debugShowCheckedModeBanner:false, - home: LoadingScreen(), - + debugShowCheckedModeBanner: false, + home: ScopedModel( + model: AppModel(), + child: LoadingScreen(), + ), ); } } From 947949bc55b301dc3291129f068640efd94a613a Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:51:15 +0100 Subject: [PATCH 05/21] register services and model here --- lib/services/service_locator.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/services/service_locator.dart b/lib/services/service_locator.dart index e69de29..5367672 100644 --- a/lib/services/service_locator.dart +++ b/lib/services/service_locator.dart @@ -0,0 +1,15 @@ +import 'package:get_it/get_it.dart'; +import 'package:peer_learning/models/AppModel.dart'; +import 'package:peer_learning/models/LoginModel.dart'; +import 'package:peer_learning/models/SignUpModel.dart'; + +GetIt locator = GetIt.instance; + +void setupLocator() { + //Register Services + + //Register Models + locator.registerFactory(() => AppModel()); + locator.registerFactory(() => LoginModel()); + locator.registerFactory(() => SignUpModel()); +} From 2442c72bc6747f449706600a261aed284e7c4e60 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:51:53 +0100 Subject: [PATCH 06/21] chat will be implemented using flowdialog --- lib/UI/chat_forrum.dart | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/UI/chat_forrum.dart b/lib/UI/chat_forrum.dart index e69de29..4a6dcc8 100644 --- a/lib/UI/chat_forrum.dart +++ b/lib/UI/chat_forrum.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; + +class ChatForrum extends StatefulWidget { + @override + _ChatForrumState createState() => _ChatForrumState(); +} + +class _ChatForrumState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Forrum"), + ), + body: Center( + child: Text("chat area "), + ), + ); + } +} From 39a88066e8559ec41a7c402b8128d91efba511c6 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:52:09 +0100 Subject: [PATCH 07/21] appModel --- lib/models/AppModel.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/models/AppModel.dart b/lib/models/AppModel.dart index e69de29..b772d78 100644 --- a/lib/models/AppModel.dart +++ b/lib/models/AppModel.dart @@ -0,0 +1,3 @@ +import 'package:scoped_model/scoped_model.dart'; + +class AppModel extends Model {} From c80427e2938fa1255f9220a3dad98df0f8469f65 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:52:54 +0100 Subject: [PATCH 08/21] login_model hold all the logic and variables --- lib/models/LoginModel.dart | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/lib/models/LoginModel.dart b/lib/models/LoginModel.dart index e69de29..a79f7c5 100644 --- a/lib/models/LoginModel.dart +++ b/lib/models/LoginModel.dart @@ -0,0 +1,71 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class LoginModel extends Model { + final FirebaseAuth auth = FirebaseAuth.instance; + final GoogleSignIn googleSignIn = GoogleSignIn(); + dynamic user; + final GlobalKey formKey = GlobalKey(); + final TextEditingController email = new TextEditingController(); + final TextEditingController password = new TextEditingController(); + bool _autoValidate = false; + bool _loadingVisible = false; + Animation animation; + + animate(controller) { + animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) + .animate(controller); + controller.forward(); + + controller.addListener(() { + notifyListeners(); + }); + } + + String status = "Not Authenticated"; + + bool get loadingVisible => _loadingVisible; + + bool get autoValidate => _autoValidate; + + Future changeLoadingVisible() async { + _loadingVisible = !_loadingVisible; + } + + Future login(context) async { + try { + user = await auth.signInWithEmailAndPassword( + email: email.text, password: password.text); + } catch (e) { + print(e); + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text("Sign in failed!"), + content: Text( + "Your email/username is incorrect. Please check again and retry."), + ); + }); + } + } + + void signInAnon() async { + FirebaseUser user = (await auth.signInAnonymously()).user; + if (user != null && user.isAnonymous == true) { + status = "Signed in Anonymously"; + } else { + status = "Sign in failed"; + } + notifyListeners(); + } + + void signOut() async { + await auth.signOut(); + + status = "Signed Out"; + //no need to call notifyListener since we will pop page + } +} From 638e808721db066cd1c4a42e8c28d1d735bcdef5 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Thu, 5 Dec 2019 22:53:22 +0100 Subject: [PATCH 09/21] sign_up model hold all the signup logic and variables --- lib/models/SignUpModel.dart | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/lib/models/SignUpModel.dart b/lib/models/SignUpModel.dart index e69de29..d191f70 100644 --- a/lib/models/SignUpModel.dart +++ b/lib/models/SignUpModel.dart @@ -0,0 +1,79 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class SignUpModel extends Model { + final FirebaseAuth auth = FirebaseAuth.instance; + final GoogleSignIn googleSignIn = GoogleSignIn(); + dynamic newUser; + dynamic myController = TextEditingController(); + bool isSwitched = false; + final GlobalKey formKey = GlobalKey(); + final TextEditingController userName = TextEditingController(); + final TextEditingController email = new TextEditingController(); + final TextEditingController password = new TextEditingController(); + Animation animation; + + animate(controller) { + animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) + .animate(controller); + controller.forward(); + + controller.addListener(() { + notifyListeners(); + }); + } + + bool _autoValidate = false; + bool _loadingVisible = false; + String currentValue = "Mentor or Mentee"; + + String currentProg = "Programming Language"; + + String status = "Not Authenticated"; + + bool get loadingVisible => _loadingVisible; + + bool get autoValidate => _autoValidate; + + Future changeLoadingVisible() async { + _loadingVisible = !_loadingVisible; + } + + Future signUp(context) async { + try { + newUser = await auth.createUserWithEmailAndPassword( + email: email.text, password: password.text); + } catch (e) { + print(e); + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text("Sign up failed!"), + content: + Text("Username already taken or You already got an account."), + ); + }, + ); + } + } + + void signInAnon() async { + FirebaseUser user = (await auth.signInAnonymously()).user; + if (user != null && user.isAnonymous == true) { + status = "Signed in Anonymously"; + } else { + status = "Sign in failed"; + } + notifyListeners(); + } + + void signOut() async { + await auth.signOut(); + + status = "Signed Out"; + //no need to call notifyListener since we will pop page + } +} From cf47b68eb35c2603fae03fabc066f09450d4905a Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:54:14 +0100 Subject: [PATCH 10/21] update --- lib/UI/dashboard.dart | 105 ++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/lib/UI/dashboard.dart b/lib/UI/dashboard.dart index e12368f..f766b19 100644 --- a/lib/UI/dashboard.dart +++ b/lib/UI/dashboard.dart @@ -1,11 +1,15 @@ import 'package:bottom_navy_bar/bottom_navy_bar.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; -import './Login/signup.dart'; -import './Login/signin.dart'; -import 'UI/gender_stats.dart'; -import 'UI/coding_stats.dart'; -import 'UI/find_mentor.dart'; -import 'UI/profile.dart'; +import 'package:peer_learning/UI/chat_forrum.dart'; +import 'signup.dart'; +import 'signin.dart'; +import 'gender_stats.dart'; +import 'coding_stats.dart'; +import 'find_mentor.dart'; +import 'profile.dart'; + +FirebaseUser loggedUser; class Dashboard extends StatefulWidget { final String username; @@ -15,6 +19,26 @@ class Dashboard extends StatefulWidget { } class _DashboardState extends State { + final _auth = FirebaseAuth.instance; + + @override + void initState() { + getRegisteredUser(); + super.initState(); + } + + void getRegisteredUser() async { + try { + final newUser = await _auth.currentUser(); + if (newUser != null) { + loggedUser = newUser; + print(loggedUser.email); + } + } catch (e) { + print(e); + } + } + var _selectedIndex = 0; final _pageController = PageController(); @@ -33,41 +57,44 @@ class _DashboardState extends State { @override Widget build(BuildContext context) { - return Scaffold( + return WillPopScope( + onWillPop: () async => true, + child: Scaffold( // bottomNavigationBar: allDestinations, - body: new Center( - child: _getWidget(), - ), - bottomNavigationBar: BottomNavyBar( - selectedIndex: _selectedIndex, - showElevation: true, // use this to remove appBar's elevation - onItemSelected: (index) => setState(() { - _selectedIndex = index; + body: new Center( + child: _getWidget(), + ), + bottomNavigationBar: BottomNavyBar( + selectedIndex: _selectedIndex, + showElevation: true, // use this to remove appBar's elevation + onItemSelected: (index) => setState(() { + _selectedIndex = index; - // _pageController.animateToPage(index, duration: Duration(milliseconds: 300), curve: Curves.ease); - }), - items: [ - BottomNavyBarItem( - icon: Icon(Icons.person), - title: Text('Find Mentor'), - activeColor: Colors.red, - ), - BottomNavyBarItem( - icon: Icon(Icons.people), - title: Text('Gender Stats'), - activeColor: Colors.purpleAccent, - ), - BottomNavyBarItem( - icon: Icon(Icons.code), - title: Text('Coding Stats'), - activeColor: Colors.pink), - BottomNavyBarItem( - icon: Icon(Icons.gps_fixed), - title: Text('Profile'), - activeColor: Colors.blue), - ], + // _pageController.animateToPage(index, duration: Duration(milliseconds: 300), curve: Curves.ease); + }), + items: [ + BottomNavyBarItem( + icon: Icon(Icons.person), + title: Text('Chat Area'), + activeColor: Colors.red, + ), + BottomNavyBarItem( + icon: Icon(Icons.people), + title: Text('Gender Stats'), + activeColor: Colors.purpleAccent, + ), + BottomNavyBarItem( + icon: Icon(Icons.code), + title: Text('Coding Stats'), + activeColor: Colors.pink), + BottomNavyBarItem( + icon: Icon(Icons.gps_fixed), + title: Text('Profile'), + activeColor: Colors.blue), + ], + ), + resizeToAvoidBottomInset: false, ), - resizeToAvoidBottomInset: false, ); } @@ -75,7 +102,7 @@ class _DashboardState extends State { switch (_selectedIndex) { case 0: return Container( - child: FindMentor(), + child: ChatForrum(), ); break; case 1: From 8bf19a427cba81979585e7bbe6afb3d0d02c84e9 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:54:48 +0100 Subject: [PATCH 11/21] will be visible once after user sign_up --- lib/UI/find_mentor.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/UI/find_mentor.dart b/lib/UI/find_mentor.dart index 1887819..a4fd49e 100644 --- a/lib/UI/find_mentor.dart +++ b/lib/UI/find_mentor.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:loader_search_bar/loader_search_bar.dart'; +import 'package:peer_learning/UI/chat_forrum.dart'; import 'package:peer_learning/components/mentorProfileCard.dart'; -import '../dashboard.dart'; +import 'dashboard.dart'; class FindMentor extends StatefulWidget { @override @@ -49,7 +50,7 @@ class FindMentorState extends State { // List _getItemListForQuery(String query) { ... } // Widget _buildItemWidget(Item item) { ... } ), - + body: Center( child: Padding( padding: const EdgeInsets.only( @@ -131,7 +132,7 @@ class FindMentorState extends State { RaisedButton( onPressed: () { setState(() { - Navigator.push( + Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => Dashboard(), @@ -147,7 +148,6 @@ class FindMentorState extends State { ], ), ], - ), ), ), From dab64c0cb58149084e1cbe0b1817fa7d4be9fe6b Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:54:59 +0100 Subject: [PATCH 12/21] update --- lib/UI/LoadingScreen.dart | 95 +-------------------------------------- 1 file changed, 1 insertion(+), 94 deletions(-) diff --git a/lib/UI/LoadingScreen.dart b/lib/UI/LoadingScreen.dart index c735314..f0e57e9 100644 --- a/lib/UI/LoadingScreen.dart +++ b/lib/UI/LoadingScreen.dart @@ -1,13 +1,7 @@ -import 'dart:io'; import 'package:splashscreen/splashscreen.dart'; import 'package:flutter/material.dart'; -import 'package:peer_learning/Login/signin.dart'; -import 'package:animated_text_kit/animated_text_kit.dart'; -import 'package:flutter/scheduler.dart'; - -import 'package:flutter/material.dart'; -import 'package:splashscreen/splashscreen.dart'; +import 'package:peer_learning/UI/signin.dart'; class LoadingScreen extends StatefulWidget { @override @@ -34,12 +28,6 @@ class _LoadingScreenState extends State }); } -// @override -// void dispose() { -// super.dispose(); -// controller.dispose(); -// } - @override Widget build(BuildContext context) { return Hero( @@ -68,84 +56,3 @@ class _LoadingScreenState extends State ); } } - -// -//class LoadingScreen extends StatefulWidget { -// @override -// _LoadingScreenState createState() => _LoadingScreenState(); -//} -// -//class _LoadingScreenState extends State -// with SingleTickerProviderStateMixin { -// AnimationController controller; -// Animation animation; -// -// @override -// void initState() { -// super.initState(); -// -// controller = -// AnimationController(duration: Duration(seconds: 1), vsync: this); -// animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) -// .animate(controller); -// controller.forward(); -// -// controller.addListener(() { -// setState(() {}); -// print(animation.value); -// }); -// } -// -//// @override -//// void dispose() { -//// super.dispose(); -//// controller.dispose(); -//// } -// -//// goToLogin() { -//// setState(() { -//// Navigator.push( -//// context, MaterialPageRoute(builder: (context) => SigninPage())); -//// }); -//// } -// -// @override -// Widget build(BuildContext context) { -// SchedulerBinding.instance.addPostFrameCallback((_) => setState(() { -// sleep(Duration(seconds: 10)); -// Navigator.pushReplacement( -// context, MaterialPageRoute(builder: (context) => SigninPage())); -// })); -// -// return Scaffold( -// backgroundColor: animation.value, -// body: Padding( -// padding: EdgeInsets.symmetric(horizontal: 24.0), -// child: Column( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.stretch, -// children: [ -// Row( -// children: [ -//// Hero( -//// tag: "logo", -//// child: Container( -//// child: Image.asset('images/logo.png'), -//// height: 60.0 * controller.value, -//// ), -//// ), -// TypewriterAnimatedTextKit( -// text: ['Peer Learning'], -// textStyle: TextStyle( -// fontSize: 45.0 * controller.value, -// fontWeight: FontWeight.w900, -// ), -// ), -// ], -// ), -// ], -// ), -// ), -// ); -// } -//} From b417620816c5c1d207498031b66db7641d86c340 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:55:17 +0100 Subject: [PATCH 13/21] update --- lib/UI/profile.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/UI/profile.dart b/lib/UI/profile.dart index 3f1f9ff..9f1fd33 100644 --- a/lib/UI/profile.dart +++ b/lib/UI/profile.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'dart:ui'; +import 'package:peer_learning/UI/signin.dart'; + class Profile extends StatefulWidget { @override State createState() { @@ -131,7 +133,6 @@ class _MyHomePageState extends State { ], ), ], - ), )) ], From 057129c5992d4b7909f6bef3a62f4252d86d3c27 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:55:47 +0100 Subject: [PATCH 14/21] sign in page hold only UI components --- lib/UI/signin.dart | 328 +++++++++++++++++++-------------------------- 1 file changed, 140 insertions(+), 188 deletions(-) diff --git a/lib/UI/signin.dart b/lib/UI/signin.dart index 2a4ed48..2b4e07f 100644 --- a/lib/UI/signin.dart +++ b/lib/UI/signin.dart @@ -3,13 +3,14 @@ import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:peer_learning/dashboard.dart'; -import 'package:peer_learning/Login/signup.dart'; +import 'package:peer_learning/UI/chat_forrum.dart'; +import 'package:peer_learning/UI/dashboard.dart'; +import 'package:peer_learning/UI/signup.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:modal_progress_hud/modal_progress_hud.dart'; - -final FirebaseAuth _auth = FirebaseAuth.instance; -final GoogleSignIn _googleSignIn = GoogleSignIn(); +import 'package:peer_learning/models/LoginModel.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:flutter/animation.dart'; class SigninPage extends StatefulWidget { static String tag = 'login'; @@ -22,48 +23,18 @@ class SigninPage extends StatefulWidget { class _SigninPageState extends State with SingleTickerProviderStateMixin { - String _status; - - dynamic user; - AnimationController controller; Animation animation; - void _signInAnon() async { - FirebaseUser user = (await _auth.signInAnonymously()).user; - if (user != null && user.isAnonymous == true) { - setState(() { - _status = "Signed in Anonymously"; - }); - } else { - setState(() { - _status = "Sign in failed"; - }); - } - } - - void _signOut() async { - await _auth.signOut(); - setState(() { - _status = "Signed Out"; - }); - } + dynamic customAlert; @override void initState() { super.initState(); - _status = "Not Authenticated"; - controller = AnimationController(duration: Duration(seconds: 1), vsync: this); - animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) - .animate(controller); - controller.forward(); - - controller.addListener(() { - setState(() {}); - }); + loginModel.animate(controller); } @override @@ -72,12 +43,7 @@ class _SigninPageState extends State controller.dispose(); } - final GlobalKey _formKey = GlobalKey(); - final TextEditingController _email = new TextEditingController(); - final TextEditingController _password = new TextEditingController(); - - bool _autoValidate = false; - bool _loadingVisible = false; + final LoginModel loginModel = LoginModel(); @override Widget build(BuildContext context) { @@ -85,165 +51,151 @@ class _SigninPageState extends State final _width = MediaQuery.of(context).size.width; final _height = MediaQuery.of(context).size.height; - return Scaffold( - appBar: AppBar( - centerTitle: true, - elevation: 0, - backgroundColor: Colors.blue, - title: Text( - 'Sign In', - style: TextStyle(fontSize: 30.0), + return ScopedModel( + model: loginModel, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + elevation: 0, + backgroundColor: Colors.blue, + title: Text( + 'Sign In', + style: TextStyle(fontSize: 30.0), + ), ), - ), - body: ModalProgressHUD( - inAsyncCall: _loadingVisible, - child: Center( - child: Container( - alignment: Alignment.center, - child: Form( - key: _formKey, - autovalidate: _autoValidate, - child: ListView( - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, + body: ScopedModelDescendant( + builder: (context, child, model) => ModalProgressHUD( + inAsyncCall: model.loadingVisible, + child: Center( + child: Container( + alignment: Alignment.center, + child: Form( + key: model.formKey, + autovalidate: model.autoValidate, + child: ListView( children: [ - Container( - child: Hero( - tag: 'logo', - child: Image.asset('assets/images/logo.png')), - height: _width < _height - ? (_width / 4) * controller.value - : (_height / 4) * controller.value, -// height: 150 * controller.value, - width: 150 * controller.value, - ), - SizedBox( - height: _width < _height ? _width / 20 : _height / 20, - ), - Padding( - padding: EdgeInsets.only( - left: 22, right: 22, top: 16, bottom: 8), - child: TextFormField( - autofocus: false, - controller: _email, -// validator: Validator.validateEmail, - keyboardType: TextInputType.emailAddress, - style: TextStyle(fontSize: 18), - decoration: InputDecoration( - labelText: 'Email', + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: Hero( + tag: 'logo', + child: Image.asset('assets/images/logo.png')), + height: _width < _height + ? (_width / 4) * controller.value + : (_height / 4) * controller.value, + width: 150 * controller.value, ), - ), - ), - Padding( - padding: EdgeInsets.only( - left: 22, right: 22, top: 8, bottom: 8), - child: TextFormField( - autofocus: false, - controller: _password, -// validator: Validator.validatePassword, - obscureText: true, - style: TextStyle(fontSize: 18), - keyboardType: TextInputType.text, - decoration: InputDecoration( - labelText: 'Password', + SizedBox( + height: + _width < _height ? _width / 20 : _height / 20, ), - ), - ), - SizedBox( - height: _width < _height ? _width / 20 : _height / 20, - ), - Padding( - padding: EdgeInsets.only( - left: 22, right: 22, top: 16, bottom: 8), - child: Container( - color: Colors.transparent, - width: MediaQuery.of(context).size.width, - height: 50, - child: FlatButton( - shape: new RoundedRectangleBorder( -// borderRadius: new BorderRadius.circular(30.0), - ), - onPressed: () async { - _changeLoadingVisible(); - try { - user = await _auth.signInWithEmailAndPassword( - email: _email.text, - password: _password.text); - } catch (e) { - print(e); - return showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: Text("Sign in failed!"), - content: Text( - "Your email/username is incorrect. Please check again and retry."), + Padding( + padding: EdgeInsets.only( + left: 22, right: 22, top: 16, bottom: 8), + child: TextFormField( + autofocus: false, + controller: model.email, + keyboardType: TextInputType.emailAddress, + style: TextStyle(fontSize: 18), + decoration: InputDecoration( + labelText: 'Email', + ), + ), + ), + Padding( + padding: EdgeInsets.only( + left: 22, right: 22, top: 8, bottom: 8), + child: TextFormField( + autofocus: false, + controller: model.password, + obscureText: true, + style: TextStyle(fontSize: 18), + keyboardType: TextInputType.text, + decoration: InputDecoration( + labelText: 'Password', + ), + ), + ), + SizedBox( + height: + _width < _height ? _width / 20 : _height / 20, + ), + Padding( + padding: EdgeInsets.only( + left: 22, right: 22, top: 16, bottom: 8), + child: Container( + color: Colors.transparent, + width: MediaQuery.of(context).size.width, + height: 50, + child: FlatButton( + shape: new RoundedRectangleBorder(), + onPressed: () async { + setState(() { + model.changeLoadingVisible(); + }); + await model.login(context + //context required to create alert if failure ); - }); - } - _changeLoadingVisible(); - if (user != null) { - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => Dashboard(), + setState(() { + model.changeLoadingVisible(); + }); + if (model.user != null) { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => Dashboard(), + ), + ); + } + /* Anonymous signIn + try { + _signInAnon(); + + if (_status == "Signed in Anonymously") {} + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => Dashboard())); + } catch (e) { + print(e); + } + + */ + }, + color: Colors.blue, + child: Text( + "Sign In", + style: TextStyle( + color: Colors.white, + fontFamily: 'Raleway', + fontSize: 22.0, ), - ); - } - - /* Anonymous signIn - try { - _signInAnon(); - - if (_status == "Signed in Anonymously") {} - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => Dashboard())); - } catch (e) { - print(e); - } - - */ - }, - color: Colors.blue, - child: Text( - "Sign In", - style: TextStyle( - color: Colors.white, - fontFamily: 'Raleway', - fontSize: 22.0, + ), ), ), ), - ), + Text("Create an account:"), + FlatButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SignUpPage())); + }, + child: Text("sign up"), + ) + ], ), - Text("Create an account:"), - FlatButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SignUpPage())); - }, - child: Text("sign up"), - ) ], ), - ], + ), ), ), ), - ), - )); - } - - Future _changeLoadingVisible() async { - setState(() { - _loadingVisible = !_loadingVisible; - }); + )), + ); } } From 7dde3113e722f102ed13c17dbe7384c4e4633db3 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:56:10 +0100 Subject: [PATCH 15/21] sign up page hold only UI components --- lib/UI/signup.dart | 349 +++++++++++++++++++++------------------------ 1 file changed, 160 insertions(+), 189 deletions(-) diff --git a/lib/UI/signup.dart b/lib/UI/signup.dart index d53d8c5..37ddfa7 100644 --- a/lib/UI/signup.dart +++ b/lib/UI/signup.dart @@ -2,8 +2,11 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:modal_progress_hud/modal_progress_hud.dart'; +import 'package:peer_learning/UI/find_mentor.dart'; +import 'package:peer_learning/models/SignUpModel.dart'; +import 'package:scoped_model/scoped_model.dart'; -import '../dashboard.dart'; +import 'dashboard.dart'; class SignUpPage extends StatefulWidget { @override @@ -12,27 +15,16 @@ class SignUpPage extends StatefulWidget { class _SignUpPageState extends State with SingleTickerProviderStateMixin { - final _auth = FirebaseAuth.instance; - - dynamic newUser; - AnimationController controller; Animation animation; - + dynamic customAlert; @override void initState() { super.initState(); controller = AnimationController(duration: Duration(seconds: 1), vsync: this); - animation = ColorTween(begin: Colors.blueGrey, end: Colors.white) - .animate(controller); - controller.forward(); - - controller.addListener(() { - setState(() {}); - print(animation.value); - }); + signUpModel.animate(controller); } @override @@ -41,205 +33,184 @@ class _SignUpPageState extends State controller.dispose(); } - dynamic myController = TextEditingController(); - bool isSwitched = false; - final GlobalKey _formKey = GlobalKey(); - final TextEditingController _userName = TextEditingController(); - final TextEditingController _email = new TextEditingController(); - final TextEditingController _password = new TextEditingController(); - - bool _autoValidate = false; - bool _loadingVisible = false; - String _currentValue = "Mentor or Mentee"; - - String _currentProg = "Programming Language"; - + final SignUpModel signUpModel = SignUpModel(); @override Widget build(BuildContext context) { final _width = MediaQuery.of(context).size.width; final _height = MediaQuery.of(context).size.height; - return Scaffold( - appBar: AppBar( - centerTitle: true, - title: Text( - "Sign Up", - style: TextStyle(fontSize: 30.0), + return ScopedModel( + model: signUpModel, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + "Sign Up", + style: TextStyle(fontSize: 30.0), + ), ), - ), - backgroundColor: Colors.white, - body: ModalProgressHUD( - inAsyncCall: _loadingVisible, - child: Container( - child: SafeArea( - child: ListView( - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + backgroundColor: Colors.white, + body: ScopedModelDescendant( + builder: (context, child, model) => ModalProgressHUD( + inAsyncCall: model.loadingVisible, + child: Container( + child: SafeArea( + child: ListView( children: [ - Container( - child: Hero( - tag: 'logo', - child: Image.asset('assets/images/logo.png')), - height: _width < _height - ? (_width / 4) * controller.value - : (_height / 4) * controller.value, - width: 100 * controller.value, - ), - SizedBox( - height: _width < _height ? _width / 20 : _height / 20, - ), - Padding( - padding: const EdgeInsets.only( - left: 22, right: 22, top: 16, bottom: 8), - child: TextFormField( - autofocus: false, - controller: _userName, -// validator: Validator.validateEmail, - keyboardType: TextInputType.text, - style: TextStyle(fontSize: 18), - decoration: InputDecoration( - labelText: 'Username', + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: Hero( + tag: 'logo', + child: Image.asset('assets/images/logo.png')), + height: _width < _height + ? (_width / 4) * controller.value + : (_height / 4) * controller.value, + width: 200 * controller.value, ), - ), - ), - Padding( - padding: const EdgeInsets.only( - left: 22, right: 22, top: 16, bottom: 8), - child: TextFormField( - autofocus: false, - controller: _email, -// validator: Validator.validateEmail, - keyboardType: TextInputType.emailAddress, - style: TextStyle(fontSize: 18), - decoration: InputDecoration( - labelText: 'Email', + SizedBox( + height: _width < _height ? _width / 20 : _height / 20, ), - ), - ), //textArea for email - Padding( - padding: const EdgeInsets.only( - left: 22, right: 22, top: 16, bottom: 8), - child: TextFormField( - autofocus: false, - controller: _password, -// validator: Validator.validatePassword, - obscureText: true, - style: TextStyle(fontSize: 18), - keyboardType: TextInputType.text, - decoration: InputDecoration( - labelText: 'Password', + Padding( + padding: const EdgeInsets.only( + left: 22, right: 22, top: 16, bottom: 8), + child: TextFormField( + autofocus: false, + controller: model.userName, + keyboardType: TextInputType.text, + style: TextStyle(fontSize: 18), + decoration: InputDecoration( + labelText: 'Username', + ), + ), ), + Padding( + padding: const EdgeInsets.only( + left: 22, right: 22, top: 16, bottom: 8), + child: Form( + key: model.formKey, + child: TextFormField( + autofocus: false, + controller: model.email, + keyboardType: TextInputType.emailAddress, + style: TextStyle(fontSize: 18), + decoration: InputDecoration( + labelText: 'Email', + ), + ), + ), + ), //textArea for email + Padding( + padding: const EdgeInsets.only( + left: 22, right: 22, top: 16, bottom: 8), + child: TextFormField( + autofocus: false, + controller: model.password, +// validator: Validator.validatePassword, + obscureText: true, + style: TextStyle(fontSize: 18), + keyboardType: TextInputType.text, + decoration: InputDecoration( + labelText: 'Password', + ), // onChanged: getPassword(myController.text), - ), - ), // - // textArea for password - DropdownButton( - hint: Text(_currentValue), - items: [ - "Mentor", - 'Mentee', - ].map((String value) { - return new DropdownMenuItem( - value: value, - child: new Text(value), - ); - }).toList(), - onChanged: (value) { - setState(() { - _currentValue = value; - }); - }, - ), - DropdownButton( - hint: Text(_currentProg), - items: [ - "C", - 'C++', - "Dart", - 'Kotlin', - "Python", - "JavaScript", - ].map((String value) { - return new DropdownMenuItem( - value: value, - child: new Text(value), - ); - }).toList(), - onChanged: (value) { - setState(() { - _currentProg = value; - }); - }, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text("male"), - Switch( - value: isSwitched, + ), + ), // + // textArea for password + DropdownButton( + hint: Text(model.currentValue), + items: [ + "Mentor", + 'Mentee', + ].map((String value) { + return new DropdownMenuItem( + value: value, + child: new Text(value), + ); + }).toList(), onChanged: (value) { setState(() { - isSwitched = value; + model.currentValue = value; }); }, - activeTrackColor: Colors.lightGreenAccent, - //activeColor: Colors.green, ), - Text('female'), - ], - ), - SizedBox( - height: _width < _height ? _width / 20 : _height / 20, - ), - RaisedButton( - onPressed: () async { - _changeLoadingVisible(); - try { - newUser = await _auth.createUserWithEmailAndPassword( - email: _email.text, password: _password.text); - } catch (e) { - print(e); - return showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: Text("Sign up failed!"), - content: Text( - "Username already taken or You already got an account."), - ); - }); - } - _changeLoadingVisible(); - if (newUser != null) { - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => - Dashboard(username: _userName.text), + DropdownButton( + hint: Text(model.currentProg), + items: [ + "C", + 'C++', + "Dart", + 'Kotlin', + "Python", + "JavaScript", + ].map((String value) { + return new DropdownMenuItem( + value: value, + child: new Text(value), + ); + }).toList(), + onChanged: (value) { + setState(() { + model.currentProg = value; + }); + }, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("male"), + Switch( + value: model.isSwitched, + onChanged: (value) { + setState(() { + model.isSwitched = value; + }); + }, + activeTrackColor: Colors.lightGreenAccent, + //activeColor: Colors.green, ), - ); - } - }, // upon login we navigate to the dashboard - child: Text("Sign Up"), - ), - SizedBox( - height: _width < _height ? _width / 20 : _height / 20, + Text('female'), + ], + ), + SizedBox( + height: _width < _height ? _width / 20 : _height / 20, + ), + RaisedButton( + onPressed: () async { + setState(() { + model.changeLoadingVisible(); + }); + await model.signUp( + context //Context require to generate alert if failure + ); + setState(() { + model.changeLoadingVisible(); + }); + if (model.newUser != null) { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => FindMentor(), + ), + ); + } + }, // upon login we navigate to the dashboard + child: Text("Sign Up"), + ), + SizedBox( + height: _width < _height ? _width / 20 : _height / 20, + ), + ], ), ], ), - ], + ), ), ), ), + resizeToAvoidBottomInset: false, ), - resizeToAvoidBottomInset: false, ); } - - Future _changeLoadingVisible() async { - setState(() { - _loadingVisible = !_loadingVisible; - }); - } } From 30df6988c2bb18e9cc1c9de751fe17e798a25ef7 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Tue, 10 Dec 2019 22:56:39 +0100 Subject: [PATCH 16/21] will hold constants like color, styles, etc.. --- lib/components/constants.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/constants.dart b/lib/components/constants.dart index e69de29..8b13789 100644 --- a/lib/components/constants.dart +++ b/lib/components/constants.dart @@ -0,0 +1 @@ + From b9be849369cab8a908e9714facb5508c3f12b678 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Sun, 29 Dec 2019 23:02:26 +0100 Subject: [PATCH 17/21] Moved to UI --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a3d3b7b..ce8f0e2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ # peer_learning -A new Flutter application. +Peer learning app help bring together mentors and mentees in local communities. Using this app, new developers will be able to connect with mentors while they learn the programming languages and technologies of their choice. ## 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) @@ -20,3 +17,13 @@ samples, guidance on mobile development, and a full API reference. The Peer Learning (PL) Meetup app is a platform that permits users to pair up with a mentor who codes in a particular programming/technology they are interested in learning, provide them with resources, an active coding community and visibility for the to scale in their respective career paths . The goal of this app is to provide a platform where newbies can learn how to code through the guidance of experienced persons in the field, and enable GDG Buea track the number of developers who code in the various technologies. This will facilitate the channelling of job opportunities for skilled persons in the community. +# Contribute + +To contribute to this project, you will need to: +- fork this repo, clone, open the project in your editor of choice and run "flutter packages get" to pull dependencies +- create a firebase account. +- go into firebase console and create a project named peer-learning +- integrate firebase to the app. Follow the instruction on [firebase integration](https://firebase.google.com/docs/flutter/setup) + +when all is done, run the app. +You can start making your pull requests From 345942cb5d92a9c410940563b0d879234463fc68 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Mon, 30 Dec 2019 05:47:30 +0100 Subject: [PATCH 18/21] constants --- lib/components/constants.dart | 36 +++++++++++++++++++++++++++++++++++ lib/models/chat_model.dart | 0 2 files changed, 36 insertions(+) create mode 100644 lib/models/chat_model.dart diff --git a/lib/components/constants.dart b/lib/components/constants.dart index 8b13789..dcaca5b 100644 --- a/lib/components/constants.dart +++ b/lib/components/constants.dart @@ -1 +1,37 @@ +import 'package:flutter/material.dart'; + +const kSendButtonTextStyle = TextStyle( + color: Colors.lightBlueAccent, + fontWeight: FontWeight.bold, + fontSize: 18.0, +); + +const kMessageTextFieldDecoration = InputDecoration( + contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), + hintText: 'Type your message here...', + border: InputBorder.none, +); + +const kMessageContainerDecoration = BoxDecoration( + border: Border( + top: BorderSide(color: Colors.lightBlueAccent, width: 2.0), + ), +); + +InputDecoration kmyInputDecoration({String text, Color colour}) => + InputDecoration( + hintText: text, + contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: colour, width: 1.0), + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: colour, width: 2.0), + borderRadius: BorderRadius.all(Radius.circular(32.0)), + ), + ); diff --git a/lib/models/chat_model.dart b/lib/models/chat_model.dart new file mode 100644 index 0000000..e69de29 From 69675dfb291e15b4e2d89f4879ca0e3e3fafea73 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Mon, 30 Dec 2019 05:48:11 +0100 Subject: [PATCH 19/21] A group chat for every user in community --- lib/models/chat_model.dart | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lib/models/chat_model.dart b/lib/models/chat_model.dart index e69de29..67a8720 100644 --- a/lib/models/chat_model.dart +++ b/lib/models/chat_model.dart @@ -0,0 +1,48 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:peer_learning/UI/chat_forrum.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class ChatModel extends Model { + final messageTextController = TextEditingController(); + String messageText; + FirebaseAuth auth = FirebaseAuth.instance; + + static final firestore = Firestore.instance; + + static getFirebaseMessage() { + dynamic snapshots = firestore.collection("messages").snapshots(); + + print(snapshots); + return snapshots; + } + + static FirebaseUser loggedUser; + + getMessage(value) { + messageText = value; + notifyListeners(); + } + + static List _messageBubbleList = []; + + List get messageBubbleList => _messageBubbleList; + + updateMessageBubble(bubble) { + _messageBubbleList.add(bubble); + notifyListeners(); + } + + sendMessage(String text) { + if (text != null && text != '') { + messageTextController.clear(); + firestore.collection("messages").add({ + "text": text, + "sender": loggedUser.email, + }); + messageText = ''; + } + notifyListeners(); + } +} From e562db652b473661101579a85b3208b56e4abca6 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Mon, 30 Dec 2019 05:48:56 +0100 Subject: [PATCH 20/21] registered chatModel --- lib/services/service_locator.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/services/service_locator.dart b/lib/services/service_locator.dart index 5367672..84a16e7 100644 --- a/lib/services/service_locator.dart +++ b/lib/services/service_locator.dart @@ -2,6 +2,7 @@ import 'package:get_it/get_it.dart'; import 'package:peer_learning/models/AppModel.dart'; import 'package:peer_learning/models/LoginModel.dart'; import 'package:peer_learning/models/SignUpModel.dart'; +import 'package:peer_learning/models/chat_model.dart'; GetIt locator = GetIt.instance; @@ -12,4 +13,5 @@ void setupLocator() { locator.registerFactory(() => AppModel()); locator.registerFactory(() => LoginModel()); locator.registerFactory(() => SignUpModel()); + locator.registerFactory(() => ChatModel()); } From dff35691e8008a3b569c8a46e4ef029af66a7b55 Mon Sep 17 00:00:00 2001 From: fonkamloic Date: Mon, 30 Dec 2019 05:49:17 +0100 Subject: [PATCH 21/21] chat screen --- lib/UI/chat_forrum.dart | 186 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 3 deletions(-) diff --git a/lib/UI/chat_forrum.dart b/lib/UI/chat_forrum.dart index 4a6dcc8..59603a0 100644 --- a/lib/UI/chat_forrum.dart +++ b/lib/UI/chat_forrum.dart @@ -1,4 +1,12 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; +import 'package:peer_learning/components/constants.dart'; +import 'package:peer_learning/models/chat_model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +final _firestore = Firestore.instance; +FirebaseUser loggedUser; class ChatForrum extends StatefulWidget { @override @@ -6,14 +14,186 @@ class ChatForrum extends StatefulWidget { } class _ChatForrumState extends State { + final _auth = FirebaseAuth.instance; + + final messageTextController = TextEditingController(); + String messageText; + + @override + void initState() { + super.initState(); + getRegisterUser(); + } + + void getRegisterUser() async { + try { + final newUser = await _auth.currentUser(); + if (newUser != null) { + loggedUser = newUser; + print(loggedUser.email); + } + } catch (e) { + print(e); + } + } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Forrum"), + leading: null, + actions: [ + IconButton( + icon: Icon(Icons.close), + onPressed: () { + _auth.signOut(); + Navigator.pop(context); + // getMessageStream(); + }), + ], + title: Text('♨Community'), + backgroundColor: Colors.lightBlueAccent, + ), + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + MessageStream(), + Container( + decoration: kMessageContainerDecoration, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: TextField( + controller: messageTextController, + onChanged: (value) { + messageText = value; + }, + decoration: kMessageTextFieldDecoration, + ), + ), + FlatButton( + onPressed: () { + if (messageText != null && messageText != '') { + messageTextController.clear(); + _firestore.collection("messages").add({ + "text": messageText, + "sender": loggedUser.email, + }); + messageText = ''; + } + }, + child: Icon( + Icons.send, + color: Colors.lightBlueAccent, + ), +// child: Text( +// 'Send', +// style: kSendButtonTextStyle, +// ), + ), + ], + ), + ), + ], + ), ), - body: Center( - child: Text("chat area "), + ); + } +} + +class MessageStream extends StatelessWidget { + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: _firestore.collection("messages").snapshots(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return Center( + child: CircularProgressIndicator( + backgroundColor: Colors.lightBlueAccent, + ), + ); + } + final messages = snapshot.data.documents; + List messageBubbleList = []; + for (var message in messages) { + String messageText = message.data['text']; + String messageSender = message.data['sender']; + + final currentUser = loggedUser.email; + + if (currentUser == messageSender) { + // + } + dynamic messageBubble = MessageBubble( + message: messageText, + sender: messageSender, + isMe: messageSender == currentUser, + ); + messageBubbleList.add(messageBubble); + } + + return Expanded( + child: ListView( + reverse: true, + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 20), + children: messageBubbleList, + ), + ); + }, + ); + } +} + +class MessageBubble extends StatelessWidget { + MessageBubble({this.message, this.sender, this.isMe}); + final String message, sender; + final bool isMe; + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start, + children: [ + Text( + sender, + style: TextStyle( + color: Colors.black54, + fontSize: 12, + ), + ), + Material( + borderRadius: isMe + ? BorderRadius.only( + topLeft: Radius.circular(30), + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30)) + : BorderRadius.only( + topRight: Radius.circular(30), + bottomLeft: Radius.circular(30), + bottomRight: Radius.circular(30)), + elevation: 5.0, + color: isMe ? Colors.lightBlueAccent : Colors.white, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 3.0, vertical: 7.0), + child: Text( + message, + style: TextStyle( + fontSize: 20.0, + color: isMe ? Colors.white : Colors.black), + ), + ), + ), + ), + ], ), ); }