Skip to content

Commit

Permalink
Add auth bloc and reconfigure melos
Browse files Browse the repository at this point in the history
  • Loading branch information
pmaite88 committed Mar 21, 2023
1 parent cb612ea commit 6dfca78
Show file tree
Hide file tree
Showing 185 changed files with 1,225 additions and 757 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ migrate_working_dir/
.pub-cache/
.pub/
/build/
apps/*/build/
packages/*/build/

# generated dart files
**/*.freezed.dart
**/*.g.dart
**/*.gr.dart
injection.config.dart

# Symbolication related
app.*.symbols
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions ios/Podfile.lock → apps/main/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ PODS:
- FirebaseAuth (~> 10.3.0)
- Firebase/CoreOnly (10.3.0):
- FirebaseCore (= 10.3.0)
- firebase_auth (4.2.9):
- firebase_auth (4.2.10):
- Firebase/Auth (= 10.3.0)
- firebase_core
- Flutter
- firebase_core (2.7.0):
- firebase_core (2.7.1):
- Firebase/CoreOnly (= 10.3.0)
- Flutter
- FirebaseAuth (10.3.0):
Expand Down Expand Up @@ -66,8 +66,8 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Firebase: f92fc551ead69c94168d36c2b26188263860acd9
firebase_auth: 4e8c693e848ed13b263de2d702d55fa82ed04a79
firebase_core: 128d8c43c3a453a4a67463314fc3761bedff860b
firebase_auth: e94093901bee37bdba241fd8647c1d3ea6f55c8b
firebase_core: 1ae9f9aa76e6e1edc14fb181637ad466fd6c6fa4
FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
FirebaseCoreInternal: e301297f4c15a17489e48ed722d733b1578e0c02
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
78 changes: 78 additions & 0 deletions apps/main/lib/app_router.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter_bootstrap/data/repositories/auth.dart';
import 'package:injectable/injectable.dart';

import 'bloc/auth_bloc.dart';
import 'pages/login.dart';
import 'pages/home.dart';
import 'pages/profile.dart';

part 'app_router.gr.dart';

@Injectable()
class AuthGuard extends AutoRedirectGuard {
final AuthBloc authBloc;
final AuthRepository authRepository;
late final StreamSubscription<AuthState> _stream;

AuthGuard(this.authBloc, this.authRepository) {
_stream = authBloc.stream.listen((state) {
state.maybeMap(
orElse: () {
reevaluate();
},
loaded: (_) {},
);
});
}

@override
void dispose() {
_stream.cancel();
super.dispose();
}

@override
void onNavigation(NavigationResolver resolver, StackRouter router) {
authBloc.state.maybeMap(
orElse: () {
if (authRepository.getUser() == null) {
router.push(
LoginRoute(authBloc: authBloc, authRepository: authRepository));
} else {
resolver.next(true);
}
},
loading: (_) => {},
loaded: (_) => resolver.next(true));
}

@override
Future<bool> canNavigate(RouteMatch route) {
return Future.value(authBloc.state is Loaded);
}
}

@MaterialAutoRouter(
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(
initial: true,
guards: [AuthGuard],
page: HomePage,
children: [
AutoRoute(page: ProfilePage),
],
),
AutoRoute(
page: LoginPage,
),
],
)
@Injectable()
class AppRouter extends _$AppRouter {
AppRouter({required super.authGuard});
}
45 changes: 45 additions & 0 deletions apps/main/lib/bloc/auth_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';

import '../data/repositories/auth.dart';

part 'auth_event.dart';
part 'auth_state.dart';
part 'auth_bloc.freezed.dart';

@singleton
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final AuthRepository authRepository;

AuthBloc(this.authRepository) : super(const Initial()) {
on<_Started>((event, emit) {
// nothing here for now
});

on<_SignIn>((event, emit) async {
emit(const Loading());

await authRepository.signInWithEmailAndPassword(
email: event.email, password: event.password);

if (authRepository.getUser() != null) {
emit(const Loaded());
} else {
emit(const Errored());
}
});

on<_Logout>((event, emit) async {
await authRepository.signOut();

emit(const Initial());
});

@disposeMethod
// ignore: unused_element
void dispose() {
close();
}
}
}
13 changes: 13 additions & 0 deletions apps/main/lib/bloc/auth_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
part of 'auth_bloc.dart';

@freezed
class AuthEvent with _$AuthEvent {
const factory AuthEvent.started() = _Started;

const factory AuthEvent.signIn({
email,
password
}) = _SignIn;

const factory AuthEvent.logout() = _Logout;
}
12 changes: 12 additions & 0 deletions apps/main/lib/bloc/auth_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
part of 'auth_bloc.dart';

@freezed
class AuthState with _$AuthState {
const factory AuthState.initial() = Initial;

const factory AuthState.loading() = Loading;

const factory AuthState.loaded() = Loaded;

const factory AuthState.error() = Errored;
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import 'package:auth/auth.dart';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';

import '../bloc/auth_bloc.dart';
import '../app_router.dart';
import '../data/repositories/auth_facade.dart';

// statefull app drawer
class AppDrawer extends StatefulWidget {
const AppDrawer({Key? key}) : super(key: key);
final AuthBloc _authBloc;

const AppDrawer({Key? key, required AuthBloc authBloc})
: _authBloc = authBloc,
super(key: key);

@override
State<AppDrawer> createState() => _AppDrawerState();
}

class _AppDrawerState extends State<AppDrawer> {
final _authFacade = AuthFacade();

void signOut(BuildContext context) async {
await _authFacade.signOut();

context.router.push(const LoginRoute());
void signOut(BuildContext context) {
widget._authBloc.add(const AuthEvent.logout());
}

@override
Expand Down
File renamed without changes.
35 changes: 35 additions & 0 deletions apps/main/lib/data/repositories/auth.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:authentication/authentication.dart';
import 'package:firebase_authentication/firebase_authentication.dart';
import 'package:injectable/injectable.dart';

import '../models/user.dart';

@Injectable()
class AuthRepository extends FirebaseAuthentication implements Authentication {
User? getUser() {
final user = super.currentUser;

return user == null
? null
: User(id: user.uid, email: user.email, username: user.displayName);
}

@override
Future<void> signInWithEmailAndPassword(
{required String email, required String password}) async {

return await super.signInWithEmailAndPassword(email: email, password: password);
}

@override
Future<void> createUserWithEmailAndPassword(
{required String email, required String password}) async {

return await super.createUserWithEmailAndPassword(email: email, password: password);
}

@override
Future<void> signOut() async {
return await super.signOut();
}
}
9 changes: 2 additions & 7 deletions lib/injection.dart → apps/main/lib/injection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';

import 'injection.config.dart';
import 'services/firebase_auth.dart';

final getIt = GetIt.instance;

Expand All @@ -11,10 +10,6 @@ final getIt = GetIt.instance;
preferRelativeImports: true,
asExtension: false,
)
Future<void> configureDependencies() async => await $initGetIt(getIt);

@module
abstract class AppModule {
@preResolve
Future<FirebaseAuthService> get authService => FirebaseAuthService.init();
}
void configureDependencies() async => $initGetIt(getIt);

20 changes: 10 additions & 10 deletions lib/main.dart → apps/main/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import 'package:firebase_authentication/firebase_authentication.dart';
import 'package:flutter/material.dart';

import 'package:flutter_bootstrap/data/repositories/auth_facade.dart';
import 'package:injectable/injectable.dart';

import 'injection.dart';
import 'app_router.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await configureDependencies();

// TODO: use a guard to redirect to home if logged in
final authFacade = AuthFacade();
await authFacade.signOut();
configureDependencies();
await FirebaseAuthentication.initialize();

runApp(MyApp());
runApp(MyApp(appRouter: getIt<AppRouter>()));
}

@Injectable()
class MyApp extends StatelessWidget {
MyApp({super.key});
final AppRouter _appRouter;

final _appRouter = AppRouter();
const MyApp({Key? key, required AppRouter appRouter})
: _appRouter = appRouter,
super(key: key);

@override
Widget build(BuildContext context) {
Expand Down
6 changes: 4 additions & 2 deletions lib/pages/home.dart → apps/main/lib/pages/home.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bootstrap/bloc/auth_bloc.dart';

import '../components/app_drawer.dart';
import '../injection.dart';

class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
Expand All @@ -22,7 +24,7 @@ class _HomePageState extends State<HomePage> {
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK')),
child: const Text('OK')),
],
);
},
Expand All @@ -35,7 +37,7 @@ class _HomePageState extends State<HomePage> {
appBar: AppBar(
title: const Text('Home'),
),
drawer: const AppDrawer(),
drawer: AppDrawer(authBloc: getIt<AuthBloc>()),
body: Center(
child: ElevatedButton(
onPressed: () {
Expand Down
Loading

0 comments on commit 6dfca78

Please sign in to comment.