Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@

#### Notes:
[extra note or considerations]

@rs-gpt-review Describe the changes in this PR. Recommend improvements (including code improvements), possible memory leaks, and best practices.
37 changes: 0 additions & 37 deletions .github/workflows/rs-gpt-review.yml

This file was deleted.

28 changes: 11 additions & 17 deletions app/lib/presentation/ui/custom/loading_screen.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
import 'package:flutter/material.dart';

class LoadingScreen extends StatelessWidget {
final bool isLoading;
final Color? color;

const LoadingScreen({
super.key,
required this.isLoading,
this.color,
});

@override
Widget build(BuildContext context) {
return Positioned.fill(
child: isLoading
? Container(
color: Colors.transparent,
child: Center(
child: SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
color: color,
),
),
),
)
: const SizedBox.shrink(),
return Container(
color: Theme.of(context).colorScheme.primaryContainer.withAlpha(50),
child: Center(
child: SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
color: color,
),
),
),
);
}
}
8 changes: 5 additions & 3 deletions app/lib/presentation/ui/pages/home/home_view.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:app/main/init.dart';
import 'package:domain/services/auth_service.dart';
import 'package:domain/bloc/auth/auth_cubit.dart';
import 'package:flutter/material.dart';
import 'package:app/presentation/ui/custom/app_theme_switch.dart';

class HomeView extends StatelessWidget {
AuthService get _authService => getIt();
/// Given this is a global cubit, we can access it directly from getIt
/// otherwise use context.read<AuthCubit>() to read the Cubit under that context
AuthCubit get _authCubit => getIt();

const HomeView({super.key});

Expand All @@ -14,7 +16,7 @@ class HomeView extends StatelessWidget {
appBar: AppBar(
actions: [
IconButton(
onPressed: () => _authService.onLogout(),
onPressed: () => _authCubit.logOut(),
icon: const Icon(Icons.logout),
),
const AppThemeSwitch(),
Expand Down
34 changes: 19 additions & 15 deletions app/lib/presentation/ui/pages/login/login_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@ import 'package:app/presentation/ui/custom/app_theme_switch.dart';
import 'package:app/presentation/ui/custom/loading_screen.dart';
import 'package:common/core/resource.dart';
import 'package:domain/bloc/auth/auth_cubit.dart';
import 'package:domain/services/auth_service.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../custom/environment_selector.dart';

class LoginPage extends StatelessWidget {
AuthService get _authService => getIt();

const LoginPage({super.key});

AuthCubit get _authCubit => getIt();

@override
Widget build(BuildContext context) {
return Stack(
children: [
Scaffold(
appBar: AppBar(),
backgroundColor: context.theme.colorScheme.surface,
body: Padding(
return Scaffold(
body: Stack(
children: [
Padding(
padding: EdgeInsets.all(spacing.m),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
Expand All @@ -36,7 +33,7 @@ class LoginPage extends StatelessWidget {
child: ElevatedButton(
child: const Text('Login'),
onPressed: () {
_authService.logInWithCredentials(
_authCubit.login(
'Rootstrap',
'12345678',
);
Expand All @@ -50,9 +47,9 @@ class LoginPage extends StatelessWidget {
],
),
),
),
const _Loading(),
],
const _Loading(),
],
),
);
}
}
Expand All @@ -64,8 +61,15 @@ class _Loading extends StatelessWidget {
Widget build(BuildContext context) {
return BlocBuilder<AuthCubit, Resource>(
builder: (context, state) {
return LoadingScreen(
isLoading: state is RLoading,
if (state is! RLoading) {
return const SizedBox.shrink();
}

return Container(
color: Colors.black.withAlpha(50),
width: double.maxFinite,
height: double.maxFinite,
child: const LoadingScreen(),
);
},
);
Expand Down
13 changes: 10 additions & 3 deletions app/lib/presentation/ui/pages/splash/splash_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:app/main/init.dart';
import 'package:domain/services/auth_service.dart';
import 'package:domain/bloc/auth/auth_cubit.dart';
import 'package:flutter/material.dart';

class SplashPage extends StatefulWidget {
Expand All @@ -10,12 +10,19 @@ class SplashPage extends StatefulWidget {
}

class _SplashPageState extends State<SplashPage> {
AuthService get _authService => getIt();
/// Given this is a global cubit, we can access it directly from getIt
/// otherwise use context.read<AuthCubit>() to read the Cubit under that context
AuthCubit get _authCubit => getIt();

@override
void initState() {
super.initState();
_authService.onValidate();

/// Add post frame callback to avoid calling bloc methods during build
WidgetsBinding.instance.addPostFrameCallback((_) async {
await Future.delayed(const Duration(seconds: 1));
_authCubit.onValidate();
});
}

@override
Expand Down
6 changes: 5 additions & 1 deletion melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ packages:
- modules/*

scripts:
run:web:
description: Run the app in development mode for web.
run: melos exec --scope="app" -- \
flutter run -t lib/main.dart --dart-define-from-file=env/.dev -d chrome
lint:all:
run: melos run analyze && melos run format
description: Run all static analysis checks.
Expand Down Expand Up @@ -38,4 +42,4 @@ scripts:
description: Run `dart doctor` in selected or all packages. Includes prompt for packages.
packageFilters:
dirExists:
- lib
- lib
28 changes: 27 additions & 1 deletion modules/domain/lib/bloc/auth/auth_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
import 'package:common/core/resource.dart';
import 'package:common/core/result_type.dart';
import 'package:domain/bloc/base_cubit.dart';
import 'package:domain/bloc/auth/auth_state.dart';
import 'package:domain/services/auth_service.dart';

class AuthCubit extends BaseCubit<AuthState> {
AuthCubit() : super(RSuccess(data: AuthStateUnknown()));
final AuthService _authService;
AuthCubit(this._authService) : super(RSuccess(data: AuthStateUnknown()));

Future<void> login(String username, String password) async {
isLoading();
final authResult =
await _authService.logInWithCredentials(username, password);

authResult
..mapSuccess((_) => isLogin())
..mapError((failure) => isError(failure));
}

Future<void> onValidate() async {
if (_authService.isLoggedIn()) {
isLogin();
} else {
isLogOut();
}
}

Future<void> logOut() async {
await _authService.onLogout();
isLogOut();
}

void isLogin() => isSuccess(AuthStateAuthenticated());

Expand Down
10 changes: 5 additions & 5 deletions modules/domain/lib/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import 'package:get_it/get_it.dart';

class DomainInit {
static Future<void> initialize(GetIt getIt) async {
//Cubits
getIt.registerSingleton(AppCubit(getIt()));
getIt.registerSingleton(AuthCubit());

//Services
getIt.registerLazySingleton(() => AuthService(getIt(), getIt()));
getIt.registerLazySingleton(() => AuthService(getIt()));

//Global Cubits
getIt.registerSingleton(AppCubit(getIt()));
getIt.registerSingleton(AuthCubit(getIt()));
}
}
26 changes: 5 additions & 21 deletions modules/domain/lib/services/auth_service.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,18 @@
import 'package:common/core/result_type.dart';
import 'package:domain/bloc/auth/auth_cubit.dart';
import 'package:domain/repositories/auth_repository.dart';

class AuthService {
final AuthRepository _authRepository;
final AuthCubit _sessionCubit;

AuthService(this._authRepository, this._sessionCubit);
AuthService(this._authRepository);

Future<void> logInWithCredentials(String username, String password) async {
_sessionCubit.isLoading();
final result = await _authRepository.login(username, password);
switch (result) {
case TSuccess<void> _:
_sessionCubit.isLogin();
case TError<void> _:
_sessionCubit.isError(result.error);
}
}
Future<ResultType<void>> logInWithCredentials(
String username, String password) =>
_authRepository.login(username, password);

void onValidate() {
if (_authRepository.isLoggedIn()) {
_sessionCubit.isLogin();
} else {
_sessionCubit.isLogOut();
}
}
bool isLoggedIn() => _authRepository.isLoggedIn();

Future<void> onLogout() async {
await _authRepository.logout();
_sessionCubit.isLogOut();
}
}
48 changes: 0 additions & 48 deletions modules/domain/test/auth_cubit_test.dart

This file was deleted.

Loading