Skip to content

Commit

Permalink
Merge pull request #10 from nhandrew/part21
Browse files Browse the repository at this point in the history
Part21
  • Loading branch information
nhandrew authored May 13, 2020
2 parents cdacdf3 + 82ac869 commit 3c9073c
Show file tree
Hide file tree
Showing 18 changed files with 575 additions and 141 deletions.
14 changes: 1 addition & 13 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3915B9972454B544000BD821 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3915B9962454B544000BD821 /* GoogleService-Info.plist */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
68A0E9B6A28F5130E373EEE2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FE17B991E2D6714A5E1D4FF5 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
Expand All @@ -28,8 +24,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -41,7 +35,6 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3915B9962454B544000BD821 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
4B20A56B8C0449CF4994B84D /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
65A2F69D4D2E6DBD65A20F91 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
6CE5340600B65B28702F21B5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
Expand All @@ -50,7 +43,6 @@
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand All @@ -64,8 +56,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
68A0E9B6A28F5130E373EEE2 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -84,9 +74,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
Expand Down Expand Up @@ -233,7 +221,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
79635FBF6A90A2364C399DB8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
Expand Down
42 changes: 37 additions & 5 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,33 +1,65 @@
import 'package:farmers_market/src/blocs/auth_bloc.dart';
import 'package:farmers_market/src/routes.dart';
import 'package:farmers_market/src/screens/landing.dart';
import 'package:farmers_market/src/screens/login.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:io';

class App extends StatelessWidget {
import 'package:provider/provider.dart';
final authBloc = AuthBloc();

class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}

class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return PlatformApp();
return MultiProvider(
providers: [
Provider(create: (context) => authBloc),
FutureProvider(create: (context) => authBloc.isLoggedIn())
],
child: PlatformApp());
}

@override
void dispose() {
authBloc.dispose();
super.dispose();
}
}

class PlatformApp extends StatelessWidget {

@override
Widget build(BuildContext context) {

var isLoggedIn = Provider.of<bool>(context);

if (Platform.isIOS) {
return CupertinoApp(
home: Login(),
home: (isLoggedIn == null) ? loadingScreen(true) : (isLoggedIn == true ) ? Landing() : Login(),
onGenerateRoute: Routes.cupertinoRoutes,
theme: CupertinoThemeData(
scaffoldBackgroundColor: Colors.white
)
);
);
} else {
return MaterialApp(
home: Login(),
home: (isLoggedIn == null) ? loadingScreen(false) : (isLoggedIn == true ) ? Landing() : Login(),
onGenerateRoute: Routes.materialRoutes,
theme: ThemeData(scaffoldBackgroundColor: Colors.white)
);
}
}

Widget loadingScreen(bool isIOS){
return (isIOS)
? CupertinoPageScaffold(child: Center(child: CupertinoActivityIndicator(),),)
: Scaffold(body: Center(child: CircularProgressIndicator()));
}

}
86 changes: 86 additions & 0 deletions lib/src/blocs/auth_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

import 'dart:async';

import 'package:farmers_market/src/models/user.dart';
import 'package:farmers_market/src/services/firestore_service.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:rxdart/rxdart.dart';
import 'package:rxdart/subjects.dart';

final RegExp regExpEmail = RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');

class AuthBloc {
final _email = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
final _user = BehaviorSubject<User>();
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirestoreService _firestoreService = FirestoreService();

//Get Data
Stream<String> get email => _email.stream.transform(validateEmail);
Stream<String> get password => _password.stream.transform(validatePassword);
Stream<bool> get isValid => CombineLatestStream.combine2(email, password, (email,password)=> true);
Stream<User> get user => _user.stream;

//Set Data
Function(String) get changeEmail => _email.sink.add;
Function(String) get changePassword => _password.sink.add;

dispose(){
_email.close();
_password.close();
_user.close();
}

//Transformers
final validateEmail = StreamTransformer<String,String>.fromHandlers(handleData: (email, sink){
if (regExpEmail.hasMatch(email.trim())){
sink.add(email.trim());
}else {
sink.addError('Must Be Valid Email Address');
}
});

final validatePassword = StreamTransformer<String,String>.fromHandlers(handleData: (password, sink){
if (password.length >= 8){
sink.add(password.trim());
}else {
sink.addError('8 Character Minimum');
}
});

//Functions
signupEmail() async{
try{
AuthResult authResult = await _auth.createUserWithEmailAndPassword(email: _email.value.trim(), password: _password.value.trim());
var user = User(userId: authResult.user.uid, email: _email.value.trim());
await _firestoreService.addUser(user);
_user.sink.add(user);
} catch (error){
print(error);
}
}

loginEmail() async{
try{
AuthResult authResult = await _auth.signInWithEmailAndPassword(email: _email.value.trim(), password: _password.value.trim());
var user = await _firestoreService.fetchUser(authResult.user.uid);
_user.sink.add(user);
} catch (error){
print(error);
}
}

Future<bool> isLoggedIn() async {
var firebaseUser = await _auth.currentUser();
if (firebaseUser == null) return false;

var user = await _firestoreService.fetchUser(firebaseUser.uid);
if (user == null) return false;

_user.sink.add(user);
return true;
}

}
17 changes: 17 additions & 0 deletions lib/src/models/user.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class User {
final String userId;
final String email;

User({this.email, this.userId});

Map<String,dynamic> toMap(){
return {
'userId': userId,
'email': email
};
}

User.fromFirestore(Map<String,dynamic> firestore)
: userId = firestore['userId'],
email = firestore['email'];
}
36 changes: 20 additions & 16 deletions lib/src/routes.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import 'package:farmers_market/src/screens/landing.dart';
import 'package:farmers_market/src/screens/login.dart';
import 'package:farmers_market/src/screens/signup.dart';
import 'package:farmers_market/src/screens/vendor.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

abstract class Routes {

static MaterialPageRoute materialRoutes(RouteSettings settings){
switch(settings.name){
case "/":
return MaterialPageRoute(builder: (context) => Landing());
static MaterialPageRoute materialRoutes(RouteSettings settings) {
switch (settings.name) {
case "/landing":
return MaterialPageRoute(builder: (context) => Landing());
case "/signup":
return MaterialPageRoute(builder: (context) => Signup());
return MaterialPageRoute(builder: (context) => Signup());
case "/login":
return MaterialPageRoute(builder: (context) => Login());
return MaterialPageRoute(builder: (context) => Login());
case "/vendor":
return MaterialPageRoute(builder: (context) => Vendor());
default:
return MaterialPageRoute(builder: (context) => Login());
return MaterialPageRoute(builder: (context) => Login());
}
}

static CupertinoPageRoute cupertinoRoutes(RouteSettings settings){
switch(settings.name){
case "/":
return CupertinoPageRoute(builder: (context) => Landing());
static CupertinoPageRoute cupertinoRoutes(RouteSettings settings) {
switch (settings.name) {
case "/landing":
return CupertinoPageRoute(builder: (context) => Landing());
case "/signup":
return CupertinoPageRoute(builder: (context) => Signup());
return CupertinoPageRoute(builder: (context) => Signup());
case "/login":
return CupertinoPageRoute(builder: (context) => Login());
return CupertinoPageRoute(builder: (context) => Login());
case "/vendor":
return CupertinoPageRoute(builder: (context) => Vendor());
default:
return CupertinoPageRoute(builder: (context) => Login());
return CupertinoPageRoute(builder: (context) => Login());
}
}
}
}
24 changes: 23 additions & 1 deletion lib/src/screens/landing.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import 'package:farmers_market/src/widgets/button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:io';

class Landing extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Scaffold();
if (Platform.isIOS){
return CupertinoPageScaffold(
child: pageBody(context),
);
} else {
return Scaffold(body:pageBody(context));
}
}

Widget pageBody(BuildContext context){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AppButton(
buttonText: 'Vendor Page',
buttonType: ButtonType.Straw,
onPressed: () => Navigator.pushNamed(context, '/vendor'),
)
],
);
}
}
Loading

0 comments on commit 3c9073c

Please sign in to comment.