6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 57ad0c21
Changed files
.../authentication/authentication_repository.dart | 32 ++++++++++++ .../authentication/bloc/authentication_bloc.dart | 58 ++++++++++++++++++++++ .../authentication/bloc/authentication_event.dart | 14 ++++++ .../authentication/bloc/authentication_state.dart | 19 +++++++ .../authentication/enum/authentication_status.dart | 7 +++ comwell_key_app/lib/comwell_app.dart | 14 ++++-- comwell_key_app/lib/main.dart | 2 +- comwell_key_app/lib/routing/app_router.dart | 23 ++++++++- .../lib/utils/stream_to_listenable.dart | 27 ++++++++++ 9 files changed, 189 insertions(+), 7 deletions(-)
Diff
diff --git a/comwell_key_app/lib/authentication/authentication_repository.dart b/comwell_key_app/lib/authentication/authentication_repository.dart
new file mode 100644
index 00000000..3ea26b08
--- /dev/null
+++ b/comwell_key_app/lib/authentication/authentication_repository.dart
@@ -0,0 +1,32 @@
+import 'dart:async';
+
+import 'package:comwell_key_app/authentication/enum/authentication_status.dart';
+
+class AuthenticationRepository {
+ // Constructor
+ AuthenticationRepository();
+
+ final _controller = StreamController<AuthenticationStatus>();
+
+ Stream<AuthenticationStatus> get status async* {
+ await Future<void>.delayed(const Duration(seconds: 1));
+ yield AuthenticationStatus.unauthenticated;
+ yield* _controller.stream;
+ }
+
+ Future<void> logIn({
+ required String username,
+ required String password,
+ }) async {
+ await Future.delayed(
+ const Duration(milliseconds: 300),
+ () => _controller.add(AuthenticationStatus.authenticated),
+ );
+ }
+
+ void logOut() {
+ _controller.add(AuthenticationStatus.unauthenticated);
+ }
+
+ void dispose() => _controller.close();
+}
\ No newline at end of file
diff --git a/comwell_key_app/lib/authentication/bloc/authentication_bloc.dart b/comwell_key_app/lib/authentication/bloc/authentication_bloc.dart
new file mode 100644
index 00000000..e7c87c0e
--- /dev/null
+++ b/comwell_key_app/lib/authentication/bloc/authentication_bloc.dart
@@ -0,0 +1,58 @@
+import 'package:bloc/bloc.dart';
+import 'package:comwell_key_app/authentication/authentication_repository.dart';
+import 'package:comwell_key_app/authentication/enum/authentication_status.dart';
+import 'package:equatable/equatable.dart';
+
+part 'authentication_event.dart';
+part 'authentication_state.dart';
+
+class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState> {
+ AuthenticationBloc({
+ required AuthenticationRepository authenticationRepository,
+ }) : _authenticationRepository = authenticationRepository, super(const AuthenticationState.unknown()) {
+
+
+
+
+ on<AuthenticationSubscriptionRequested>(_onSubscriptionRequested);
+ on<AuthenticationLogoutPressed>(_onLogoutPressed);
+
+ }
+
+ final AuthenticationRepository _authenticationRepository;
+
+
+ void _onLogoutPressed(
+ AuthenticationLogoutPressed event,
+ Emitter<AuthenticationState> emit,
+ ) {
+ _authenticationRepository.logOut();
+ }
+
+ Future<void> _onSubscriptionRequested(
+ AuthenticationSubscriptionRequested event,
+ Emitter<AuthenticationState> emit,
+ ) {
+ return emit.onEach(
+ _authenticationRepository.status,
+ onData: (status) async {
+ switch (status) {
+ case AuthenticationStatus.unauthenticated:
+ return emit(const AuthenticationState.unauthenticated());
+ case AuthenticationStatus.authenticated:
+ //final user = await _tryGetUser(); TODO: this should check on tokens saved in secure storage
+ return emit(
+ /* user != null
+ ? AuthenticationState.authenticated(user)
+ : const AuthenticationState.unauthenticated(), */
+ AuthenticationState._()
+ );
+ case AuthenticationStatus.unknown:
+ return emit(const AuthenticationState.unknown());
+ }
+ },
+ onError: addError,
+ );
+ }
+}
+
diff --git a/comwell_key_app/lib/authentication/bloc/authentication_event.dart b/comwell_key_app/lib/authentication/bloc/authentication_event.dart
new file mode 100644
index 00000000..863c6a18
--- /dev/null
+++ b/comwell_key_app/lib/authentication/bloc/authentication_event.dart
@@ -0,0 +1,14 @@
+part of 'authentication_bloc.dart';
+
+sealed class AuthenticationEvent extends Equatable {
+ const AuthenticationEvent();
+
+ @override
+ List<Object> get props => [];
+}
+
+final class AuthenticationSubscriptionRequested extends AuthenticationEvent {}
+
+final class AuthenticationSubscriptionNotValid extends AuthenticationEvent {}
+
+final class AuthenticationLogoutPressed extends AuthenticationEvent {}
diff --git a/comwell_key_app/lib/authentication/bloc/authentication_state.dart b/comwell_key_app/lib/authentication/bloc/authentication_state.dart
new file mode 100644
index 00000000..34b4be35
--- /dev/null
+++ b/comwell_key_app/lib/authentication/bloc/authentication_state.dart
@@ -0,0 +1,19 @@
+part of 'authentication_bloc.dart';
+
+class AuthenticationState extends Equatable {
+ const AuthenticationState._({
+ this.status = AuthenticationStatus.unknown,
+ });
+
+const AuthenticationState.unknown() : this._();
+
+const AuthenticationState.authenticated() : this._(status: AuthenticationStatus.authenticated);
+
+const AuthenticationState.unauthenticated() : this._(status: AuthenticationStatus.unauthenticated);
+
+final AuthenticationStatus status;
+
+
+@override
+List<Object> get props => [status];
+}
diff --git a/comwell_key_app/lib/authentication/enum/authentication_status.dart b/comwell_key_app/lib/authentication/enum/authentication_status.dart
new file mode 100644
index 00000000..b2f12eaf
--- /dev/null
+++ b/comwell_key_app/lib/authentication/enum/authentication_status.dart
@@ -0,0 +1,7 @@
+enum AuthenticationStatus {
+ unknown,
+ authenticated,
+ unauthenticated,
+}
+
+
diff --git a/comwell_key_app/lib/comwell_app.dart b/comwell_key_app/lib/comwell_app.dart
index 1fe235ba..fa6c47fb 100644
--- a/comwell_key_app/lib/comwell_app.dart
+++ b/comwell_key_app/lib/comwell_app.dart
@@ -1,3 +1,5 @@
+import 'package:comwell_key_app/authentication/authentication_repository.dart';
+import 'package:comwell_key_app/authentication/bloc/authentication_bloc.dart';
import 'package:comwell_key_app/home/bloc/home_bloc.dart';
import 'package:comwell_key_app/home/home_repository.dart';
import 'package:comwell_key_app/key/bloc/key_bloc.dart';
@@ -14,23 +16,27 @@ import 'package:flutter_bloc/flutter_bloc.dart';
class ComwellApp extends StatelessWidget {
- const ComwellApp({super.key});
+ final AuthenticationBloc authBloc = AuthenticationBloc(authenticationRepository: AuthenticationRepository());
+ ComwellApp({super.key});
@override
Widget build(BuildContext context) {
- return MultiBlocProvider(
+ return BlocProvider<AuthenticationBloc>(
+
+ create: (context) => authBloc,
+ child: MultiBlocProvider(
providers: blocProviderList,
child:
MaterialApp.router(
title: 'Comwell Key App',
- routerConfig: goRouter(),
+ routerConfig: goRouter(authBloc),
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: lightTheme,
darkTheme: darkTheme,
themeMode: ThemeMode.system,
- ));
+ ),),);
}
diff --git a/comwell_key_app/lib/main.dart b/comwell_key_app/lib/main.dart
index 54f0ea27..34f9e060 100644
--- a/comwell_key_app/lib/main.dart
+++ b/comwell_key_app/lib/main.dart
@@ -17,7 +17,7 @@ void main() async {
path:
'assets/translations', // <-- change the path of the translation files
fallbackLocale: const Locale('da', 'DK'),
- child: const ComwellApp()));
+ child: ComwellApp()));
}
diff --git a/comwell_key_app/lib/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index 03f7f912..7fc45a99 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -1,21 +1,40 @@
+import 'package:comwell_key_app/authentication/bloc/authentication_bloc.dart';
+import 'package:comwell_key_app/authentication/enum/authentication_status.dart';
import 'package:comwell_key_app/home/home_page.dart';
import 'package:comwell_key_app/key/key_page.dart';
+import 'package:comwell_key_app/login/auth.dart';
import 'package:comwell_key_app/login/login_page.dart';
import 'package:comwell_key_app/profile/profile_page.dart';
import 'package:comwell_key_app/redeem_debug/redeem_page.dart';
import 'package:comwell_key_app/routing/app_routes.dart';
+import 'package:comwell_key_app/utils/stream_to_listenable.dart';
import 'package:comwell_key_app/welcome/welcome_page.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
final _rootNavigatorKey = GlobalKey<NavigatorState>();
-GoRouter goRouter() {
+GoRouter goRouter(AuthenticationBloc authBloc) {
+
return GoRouter(
initialLocation: '/login',
navigatorKey: _rootNavigatorKey,
debugLogDiagnostics: true,
- redirect: (context, state) {},
+ redirect: (context, state) {
+ final isAuthenticated = authBloc.state.status == AuthenticationStatus.authenticated;
+ final isUnAuthenticated = authBloc.state.status == AuthenticationStatus.unauthenticated;
+
+ // Redirect to the login page if the user is not authenticated, and if authenticated, do not show the login page
+ if (isUnAuthenticated && !state.matchedLocation.contains("/login")) {
+ return "/login";
+ }
+ // Redirect to the home page if the user is authenticated
+ else if (isAuthenticated) {
+ return "/oauthredirect";
+ }
+ return null;
+ },
+ refreshListenable: StreamToListenable([authBloc.stream]),
routes: <RouteBase>[
GoRoute(
path: "/",
diff --git a/comwell_key_app/lib/utils/stream_to_listenable.dart b/comwell_key_app/lib/utils/stream_to_listenable.dart
new file mode 100644
index 00000000..b2c1c56e
--- /dev/null
+++ b/comwell_key_app/lib/utils/stream_to_listenable.dart
@@ -0,0 +1,27 @@
+// for convert stream to listenable
+import 'dart:async';
+
+import 'package:flutter/widgets.dart';
+
+class StreamToListenable extends ChangeNotifier {
+ late final List<StreamSubscription> subscriptions;
+
+ StreamToListenable(List<Stream> streams) {
+ subscriptions = [];
+ for (var e in streams) {
+ var s = e.asBroadcastStream().listen(_tt);
+ subscriptions.add(s);
+ }
+ notifyListeners();
+ }
+
+ @override
+ void dispose() {
+ for (var e in subscriptions) {
+ e.cancel();
+ }
+ super.dispose();
+ }
+
+ void _tt(event) => notifyListeners();
+}
\ No newline at end of file