This commit is contained in:
Felipe
2024-02-16 11:14:01 -05:00
parent 9ca2b62be3
commit d9d6b50d78
15 changed files with 452 additions and 294 deletions
+31 -6
View File
@@ -1,19 +1,44 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injector/injector.dart';
import 'package:prosappco/blocs/authentication_bloc/authentication_bloc.dart'; import 'package:prosappco/blocs/authentication_bloc/authentication_bloc.dart';
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/blocs/sign_up_bloc/sign_up_bloc.dart';
import 'package:prosappco/blocs/sing_in_bloc/sign_in_bloc.dart';
import 'package:prosappco/blocs/update_user_info_bloc/update_user_info_bloc.dart';
import 'package:prosappco/screens/home/home_screen.dart';
import 'package:user_repository/user_repository.dart'; import 'package:user_repository/user_repository.dart';
import 'app_view.dart'; import 'app_view.dart';
class MainApp extends StatelessWidget { class MainApp extends StatelessWidget {
final UserRepository userRepository; const MainApp({super.key});
const MainApp(this.userRepository, {super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiRepositoryProvider(providers: [ return MultiBlocProvider(
RepositoryProvider<AuthenticationBloc>( providers: [
create: (_) => AuthenticationBloc(myUserRepository: userRepository)) BlocProvider<AuthenticationBloc>(
], child: const MyAppView()); create: (context) => Injector.appInstance.get<AuthenticationBloc>(),
),
BlocProvider<MyUserBloc>(
create: (context) => Injector.appInstance.get<MyUserBloc>(),
),
BlocProvider<UpdateUserInfoBloc>(
create: (context) => Injector.appInstance.get<UpdateUserInfoBloc>(),
),
BlocProvider<SignInBloc>(
create: (context) => Injector.appInstance.get<SignInBloc>(),
),
BlocProvider<SignUpBloc>(
create: (context) => Injector.appInstance.get<SignUpBloc>(),
)
// RepositoryProvider<AuthenticationBloc>(
// create: (_) => AuthenticationBloc(myUserRepository: userRepository),
// ),
],
child: BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
return const MyAppView();
}));
} }
} }
+24 -23
View File
@@ -32,29 +32,30 @@ class MyAppView extends StatelessWidget {
home: BlocBuilder<AuthenticationBloc, AuthenticationState>( home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) { builder: (context, state) {
if (state.status == AuthenticationStatus.authenticated) { if (state.status == AuthenticationStatus.authenticated) {
return MultiBlocProvider( // MultiBlocProvider(
providers: [ // providers: [
BlocProvider( // BlocProvider(
create: (context) => SignInBloc( // create: (context) => SignInBloc(
userRepository: // userRepository:
context.read<AuthenticationBloc>().userRepository), // context.read<AuthenticationBloc>().userRepository),
), // ),
BlocProvider( // BlocProvider(
create: (context) => UpdateUserInfoBloc( // create: (context) => UpdateUserInfoBloc(
userRepository: // userRepository:
context.read<AuthenticationBloc>().userRepository), // context.read<AuthenticationBloc>().userRepository),
), // ),
BlocProvider( // BlocProvider(
create: (context) => MyUserBloc( // create: (context) => MyUserBloc(
myUserRepository: // myUserRepository:
context.read<AuthenticationBloc>().userRepository) // context.read<AuthenticationBloc>().userRepository)
..add(GetMyUser( // ..add(GetMyUser(
myUserId: // myUserId:
context.read<AuthenticationBloc>().state.user!.uid)), // context.read<AuthenticationBloc>().state.user!.uid)),
), // ),
], // ],
child: const HomeScreen(), // child: const HomeScreen(),
); // );
return const HomeScreen();
} else { } else {
return const WelcomeScreen(); return const WelcomeScreen();
} }
@@ -12,12 +12,12 @@ part 'authentication_state.dart';
class AuthenticationBloc class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> { extends Bloc<AuthenticationEvent, AuthenticationState> {
final UserRepository userRepository; final UserRepository userRepository;
late final StreamSubscription<User?> _userSubscription; late final StreamSubscription<MyUser?> _userSubscription;
AuthenticationBloc({required UserRepository myUserRepository}) AuthenticationBloc({required UserRepository myUserRepository})
: userRepository = myUserRepository, : userRepository = myUserRepository,
super(const AuthenticationState.unknown()) { super(const AuthenticationState.unknown()) {
_userSubscription = userRepository.user.listen((authUser) { _userSubscription = userRepository.streamUser().listen((authUser) {
add(AuthenticationUserChanged(authUser)); add(AuthenticationUserChanged(authUser));
}); });
on<AuthenticationUserChanged>((event, emit) { on<AuthenticationUserChanged>((event, emit) {
@@ -11,7 +11,7 @@ abstract class AuthenticationEvent extends Equatable {
class AuthenticationUserChanged extends AuthenticationEvent { class AuthenticationUserChanged extends AuthenticationEvent {
const AuthenticationUserChanged(this.user); const AuthenticationUserChanged(this.user);
final User? user; final MyUser? user;
} }
class AuthenticationLogoutRequested extends AuthenticationEvent {} class AuthenticationLogoutRequested extends AuthenticationEvent {}
@@ -4,7 +4,7 @@ enum AuthenticationStatus { authenticated, unauthenticated, unknown }
class AuthenticationState extends Equatable { class AuthenticationState extends Equatable {
final AuthenticationStatus status; final AuthenticationStatus status;
final User? user; final MyUser? user;
const AuthenticationState._({ const AuthenticationState._({
this.status = AuthenticationStatus.unknown, this.status = AuthenticationStatus.unknown,
@@ -13,7 +13,7 @@ class AuthenticationState extends Equatable {
const AuthenticationState.unknown() : this._(); const AuthenticationState.unknown() : this._();
const AuthenticationState.authenticated(User user) const AuthenticationState.authenticated(MyUser user)
: this._(status: AuthenticationStatus.authenticated, user: user); : this._(status: AuthenticationStatus.authenticated, user: user);
const AuthenticationState.unauthenticated() const AuthenticationState.unauthenticated()
+56 -7
View File
@@ -1,3 +1,6 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:user_repository/user_repository.dart'; import 'package:user_repository/user_repository.dart';
@@ -11,16 +14,62 @@ class MyUserBloc extends Bloc<MyUserEvent, MyUserState> {
MyUserBloc({required UserRepository myUserRepository}) MyUserBloc({required UserRepository myUserRepository})
: _userRepository = myUserRepository, : _userRepository = myUserRepository,
super(const MyUserState.loading()) { super(const MyUserState.loading()) {
on<GetMyUser>(_onGetMyUser); _userRepository.streamUser().listen((event) {
log('xd ---: ${event}');
if (event == null) {
log('UserChanged: ${event}');
emit(const MyUserState.failure());
} else {
log('UserChanged: ${event}');
emit(MyUserState.success(event!));
}
});
// on<UserChanged>(_onUserChanged);
// _userRepository.user.first.then((user) {
// log('xd: ${user}');
// if (user != null) {
// add(UserChanged(user: user));
// _userSubscription = _userRepository.user.listen((user) {
// log('xd: ${user}');
// add(UserChanged(user: user));
// });
// }
// }).catchError((e) {
// log('xd: ${e}');
// add(UserChanged(user: null));
// });
// on<GetMyUser>(_onGetMyUser);
// _userRepository.user.listen((user) {
// if (user != null) {
// add(GetMyUser(myUserId: user.uid));
// }
// });
// emit(MyUserState.success(MyUser(
// name: 'John', id: '123', email: 'johndoe@gmail.com', picture: '')));
} }
void _onGetMyUser(GetMyUser event, Emitter<MyUserState> emit) async { void _onUserChanged(UserChanged event, Emitter<MyUserState> emit) {
emit(const MyUserState.loading()); log('UserChanged: ${event.user}');
try { if (event.user == null) {
MyUser myUser = await _userRepository.getMyUser(event.myUserId); log('UserChanged: ${event.user}');
emit(MyUserState.success(myUser));
} catch (e) {
emit(const MyUserState.failure()); emit(const MyUserState.failure());
} else {
log('UserChanged: ${event.user}');
emit(MyUserState.success(event.user!));
} }
} }
// void _onGetMyUser(GetMyUser event, Emitter<MyUserState> emit) async {
// log('GetMyUser: ${event.myUserId}');
// emit(const MyUserState.loading());
// try {
// MyUser myUser = await _userRepository.getMyUser(event.myUserId);
// log('GetMyUser: $myUser');
// emit(MyUserState.success(myUser));
// } catch (e) {
// log('GetMyUser: $e');
// emit(const MyUserState.failure());
// }
// }
} }
+14 -5
View File
@@ -4,14 +4,23 @@ abstract class MyUserEvent extends Equatable {
const MyUserEvent(); const MyUserEvent();
@override @override
List<Object> get props => []; List<Object?> get props => [];
} }
class GetMyUser extends MyUserEvent { // class GetMyUser extends MyUserEvent {
final String myUserId; // final String myUserId;
const GetMyUser({required this.myUserId}); // const GetMyUser({required this.myUserId});
// @override
// List<Object> get props => [myUserId];
// }
class UserChanged extends MyUserEvent {
final MyUser? user;
const UserChanged({required this.user});
@override @override
List<Object> get props => [myUserId]; List<Object?> get props => [user];
} }
+32
View File
@@ -0,0 +1,32 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:injector/injector.dart';
import 'package:prosappco/blocs/authentication_bloc/authentication_bloc.dart';
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/blocs/sign_up_bloc/sign_up_bloc.dart';
import 'package:prosappco/blocs/sing_in_bloc/sign_in_bloc.dart';
import 'package:prosappco/blocs/update_user_info_bloc/update_user_info_bloc.dart';
import 'package:user_repository/user_repository.dart';
class UserDI {
void register() {
final injector = Injector.appInstance;
injector.registerSingleton<UserRepository>(
(() => FirebaseUserRepository(FirebaseAuth.instance)));
injector.registerSingleton<AuthenticationBloc>((() =>
AuthenticationBloc(myUserRepository: injector.get<UserRepository>())));
injector.registerSingleton<MyUserBloc>(
(() => MyUserBloc(myUserRepository: injector.get<UserRepository>())));
injector.registerSingleton<UpdateUserInfoBloc>((() =>
UpdateUserInfoBloc(userRepository: injector.get<UserRepository>())));
injector.registerSingleton<SignInBloc>(
(() => SignInBloc(userRepository: injector.get<UserRepository>())));
injector.registerSingleton<SignUpBloc>(
(() => SignUpBloc(userRepository: injector.get<UserRepository>())));
}
}
+3 -1
View File
@@ -173,6 +173,7 @@ import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:prosappco/dependency_user/user_di.dart';
import 'package:user_repository/user_repository.dart'; import 'package:user_repository/user_repository.dart';
import 'app.dart'; import 'app.dart';
import 'simple_bloc_observer.dart'; import 'simple_bloc_observer.dart';
@@ -182,5 +183,6 @@ void main() async {
await Firebase.initializeApp(); await Firebase.initializeApp();
Bloc.observer = SimpleBlocObserver(); Bloc.observer = SimpleBlocObserver();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(MainApp(FirebaseUserRepository())); UserDI().register();
runApp(const MainApp());
} }
+12 -8
View File
@@ -1,7 +1,6 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/blocs/sing_in_bloc/sign_in_bloc.dart'; import 'package:prosappco/blocs/sing_in_bloc/sign_in_bloc.dart';
import 'package:prosappco/blocs/update_user_info_bloc/update_user_info_bloc.dart'; import 'package:prosappco/blocs/update_user_info_bloc/update_user_info_bloc.dart';
@@ -27,7 +26,8 @@ class _HomeScreenState extends State<HomeScreen> {
}, },
child: Scaffold( child: Scaffold(
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
drawer: BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) { drawer:
BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
if (state.status == MyUserStatus.success) { if (state.status == MyUserStatus.success) {
return Drawer( return Drawer(
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
@@ -83,7 +83,7 @@ class _HomeScreenState extends State<HomeScreen> {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(
context.read<MyUserBloc>().state.user!.name, state.user!.name,
style: const TextStyle( style: const TextStyle(
fontSize: 24, fontSize: 24,
color: Colors.white, color: Colors.white,
@@ -128,12 +128,16 @@ class _HomeScreenState extends State<HomeScreen> {
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
child: const Center( child: const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
));
}
}),
appBar: AppBar(),
body: const Placeholder(),
), ),
); );
} }
}),
appBar: AppBar(),
body: Center(
child: Text(
context.read<MyUserBloc>().state.user?.name ?? 'null',
),
)),
);
}
} }
+24 -23
View File
@@ -17,22 +17,26 @@ class ProfileScreen extends StatefulWidget {
class _ProfileScreenState extends State<ProfileScreen> { class _ProfileScreenState extends State<ProfileScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiBlocProvider( return
providers: [
BlocProvider( // MultiBlocProvider(
create: (context) => MyUserBloc( // providers: [
myUserRepository: // BlocProvider(
context.read<AuthenticationBloc>().userRepository) // create: (context) => MyUserBloc(
..add(GetMyUser( // myUserRepository:
myUserId: context.read<AuthenticationBloc>().state.user!.uid)), // context.read<AuthenticationBloc>().userRepository)
), // ..add(GetMyUser(
BlocProvider( // myUserId: context.read<AuthenticationBloc>().state.user!.uid)),
create: (context) => UpdateUserInfoBloc( // ),
userRepository: context.read<AuthenticationBloc>().userRepository, // BlocProvider(
), // create: (context) => UpdateUserInfoBloc(
) // userRepository: context.read<AuthenticationBloc>().userRepository,
], // ),
child: BlocListener<UpdateUserInfoBloc, UpdateUserInfoState>( // )
// ],
// child:
BlocListener<UpdateUserInfoBloc, UpdateUserInfoState>(
listener: (context, state) { listener: (context, state) {
if (state is UploadPictureSuccess) { if (state is UploadPictureSuccess) {
setState(() { setState(() {
@@ -47,8 +51,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
}, },
label: 'Perfil', label: 'Perfil',
), ),
body: body: BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
if (state.status == MyUserStatus.success) { if (state.status == MyUserStatus.success) {
return Padding( return Padding(
padding: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(20.0),
@@ -115,8 +118,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
borderSide: BorderSide(color: Colors.red), borderSide: BorderSide(color: Colors.red),
), ),
focusedErrorBorder: OutlineInputBorder( focusedErrorBorder: OutlineInputBorder(
borderSide: borderSide: BorderSide(color: Colors.red, width: 2.0),
BorderSide(color: Colors.red, width: 2.0),
), ),
), ),
validator: (value) { validator: (value) {
@@ -141,8 +143,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
borderSide: BorderSide(color: Colors.red), borderSide: BorderSide(color: Colors.red),
), ),
focusedErrorBorder: OutlineInputBorder( focusedErrorBorder: OutlineInputBorder(
borderSide: borderSide: BorderSide(color: Colors.red, width: 2.0),
BorderSide(color: Colors.red, width: 2.0),
), ),
), ),
validator: (value) { validator: (value) {
@@ -163,7 +164,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
})), })),
), // ),
); );
} }
} }
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'dart:io'; import 'dart:io';
@@ -9,21 +10,46 @@ import 'entities/entities.dart';
import 'user_repo.dart'; import 'user_repo.dart';
class FirebaseUserRepository implements UserRepository { class FirebaseUserRepository implements UserRepository {
FirebaseUserRepository({
FirebaseAuth? firebaseAuth,
}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
final FirebaseAuth _firebaseAuth; final FirebaseAuth _firebaseAuth;
final usersCollection = FirebaseFirestore.instance.collection('users'); final usersCollection = FirebaseFirestore.instance.collection('users');
final StreamController<MyUser?> _userStreamController =
StreamController<MyUser?>.broadcast();
@override FirebaseUserRepository(this._firebaseAuth) {
Stream<User?> get user { _firebaseAuth.userChanges().listen((user) async {
return _firebaseAuth.authStateChanges().map((firebaseUser) { if (user != null) {
final user = firebaseUser; try {
return user; final myUser = await getMyUser(user.uid);
_userStreamController.add(myUser);
} catch (e) {
log('Error en FirebaseUserRepository ${e.toString()}');
_userStreamController.add(null);
}
} else {
_userStreamController.add(null);
}
});
this.streamUser().listen((event) {
log('xd - : ${event}');
}); });
} }
// Stream<MyUser?> get user => _userStreamController.stream;
@override
Stream<MyUser?> streamUser() {
return _userStreamController.stream;
}
// @override
// Stream<User?> get user {
// return _firebaseAuth.authStateChanges().map((firebaseUser) {
// final user = firebaseUser;
// return user;
// });
// }
// Sign up // Sign up
@override @override
Future<MyUser> signUp(MyUser myUser, String password) async { Future<MyUser> signUp(MyUser myUser, String password) async {
@@ -3,7 +3,8 @@ import 'package:firebase_auth/firebase_auth.dart';
import '../user_repository.dart'; import '../user_repository.dart';
abstract class UserRepository { abstract class UserRepository {
Stream<User?> get user; // Stream<User?> get user;
Stream<MyUser?> streamUser();
Future<void> signIn(String email, String password); Future<void> signIn(String email, String password);
+8
View File
@@ -741,6 +741,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.1+1" version: "0.2.1+1"
injector:
dependency: "direct main"
description:
name: injector
sha256: ed389bed5b48a699d5b9561c985023d0d5cc88dd5ff2237aadcce5a5ab433e4e
url: "https://pub.dev"
source: hosted
version: "3.0.0"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
+1 -1
View File
@@ -39,6 +39,7 @@ dependencies:
google_sign_in: ^6.1.4 google_sign_in: ^6.1.4
http: ^1.1.0 http: ^1.1.0
image_picker: ^1.0.7 image_picker: ^1.0.7
injector: ^3.0.0
intl: any intl: any
intl_phone_field: null intl_phone_field: null
location: ^5.0.3 location: ^5.0.3
@@ -60,7 +61,6 @@ dev_dependencies:
sdk: flutter sdk: flutter
flutter: flutter:
uses-material-design: true uses-material-design: true
assets: assets: