Skip to content

Commit

Permalink
fix(#58): Adiciona command a viewmodel
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielCostaDeOliveira committed Jan 10, 2025
1 parent 61ad837 commit f8a4241
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 166 deletions.
3 changes: 1 addition & 2 deletions lib/ui/home/view/HomeView.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ class HomeView extends StatelessWidget {

@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
return const Text('Home', style: TextStyle(fontSize: 20));
}


Expand Down
85 changes: 40 additions & 45 deletions lib/ui/login/view/login_view.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:aranduapp/core/log/Log.dart';
import 'package:aranduapp/ui/navbar/view/navBarView.dart';
import 'package:aranduapp/ui/shared/TextAndLink.dart';
import 'package:aranduapp/ui/shared/requestbutton.dart';
import 'package:flutter/material.dart';
Expand All @@ -22,61 +23,49 @@ class Login extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => LoginViewModel(context),
create: (context) => LoginViewModel(),
child: const LoginScreen(),
);
}
}

class LoginScreen extends StatefulWidget {
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});

@override
State<StatefulWidget> createState() {
return _LoginScreenState();
}
}

class _LoginScreenState extends State<LoginScreen> {
late Future<void> _future;

@override
void initState() {
super.initState();
_future =
Provider.of<LoginViewModel>(context, listen: false).validateToken();
}

@override
Widget build(BuildContext context) {
LoginViewModel viewModel = Provider.of<LoginViewModel>(context);

return Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return _loadingScreen(viewModel);
} else if (!snapshot.hasError) {
return _authDevice(viewModel);
} else {
return _emailAndPassword(viewModel);
}
}));
body: ListenableBuilder(
listenable: viewModel.validadeTokenCommand,
builder: (context, child) {
if (viewModel.validadeTokenCommand.isOk) {
return _authDevice(viewModel, context);
} else if (viewModel.validadeTokenCommand.isError) {
return _emailAndPassword(viewModel, context);
} else {
return _loadingScreen(viewModel, context);
}
},
),
);
}

Widget _loadingScreen(LoginViewModel viewModel) {
Widget _loadingScreen(LoginViewModel viewModel, BuildContext context) {
return const Center(
child: CircularProgressIndicator(value: null),
);
}

Widget _authDevice(LoginViewModel viewModel) {
Widget _authDevice(LoginViewModel viewModel, BuildContext context) {
Log.d("Mostrando tela de autorização do dispositivo");

viewModel.loginWithDeviceAuth().then((ok) {
if (ok) {
viewModel.goToHome();
WidgetsBinding.instance.addPostFrameCallback((_) {
goToNavbar(context);
});
}
});

Expand All @@ -100,7 +89,9 @@ class _LoginScreenState extends State<LoginScreen> {
child: ElevatedButton(
onPressed: () async {
viewModel.loginWithDeviceAuth().then((ok) {
viewModel.goToHome();
WidgetsBinding.instance.addPostFrameCallback((_) {
goToNavbar(context);
});
});
},
child: const Text('Usar senha do celular'),
Expand All @@ -111,7 +102,7 @@ class _LoginScreenState extends State<LoginScreen> {
);
}

Widget _emailAndPassword(LoginViewModel viewModel) {
Widget _emailAndPassword(LoginViewModel viewModel, BuildContext context) {
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
Expand All @@ -121,11 +112,11 @@ class _LoginScreenState extends State<LoginScreen> {
const SizedBox(height: 80),
const SizedBox(height: 10),
_formSection(viewModel),
_forgotPasswordLink(),
_forgotPasswordLink(context),
const SizedBox(height: 80),
_loginButtonSection(),
_loginButtonSection(context),
const OrDivider(),
_loggingInWithOther(),
_loggingInWithOther(context),
TextAndLink(
text: 'É novo pro aqui?',
link: 'Cria a sua conta',
Expand Down Expand Up @@ -158,7 +149,7 @@ class _LoginScreenState extends State<LoginScreen> {
);
}

Widget _forgotPasswordLink() {
Widget _forgotPasswordLink(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
Expand All @@ -183,7 +174,7 @@ class _LoginScreenState extends State<LoginScreen> {
);
}

Widget _loginButtonSection() {
Widget _loginButtonSection(BuildContext context) {
LoginViewModel viewModel = Provider.of<LoginViewModel>(context);

return Requestbutton(
Expand All @@ -195,16 +186,12 @@ class _LoginScreenState extends State<LoginScreen> {
);
},
onSuccessCallback: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Bem-vindo(a) a bordo! Seu login foi feito com sucesso!')),
);
goToNavbar(context);
},
nameButton: 'Entrar');
}

Widget _loggingInWithOther() {
Widget _loggingInWithOther(BuildContext context) {
return GestureDetector(
onTap: () => Log.d(""),
child: Container(
Expand All @@ -223,4 +210,12 @@ class _LoginScreenState extends State<LoginScreen> {
),
);
}

void goToNavbar(BuildContext context) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const NavbarView(),
),
);
}
}
56 changes: 16 additions & 40 deletions lib/ui/login/viewModel/login_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,69 +8,45 @@ import 'package:aranduapp/ui/login/service/LoginService.dart';
import 'package:aranduapp/ui/login/model/LoginRequest.dart';

class LoginViewModel extends ChangeNotifier {
final BuildContext context;
late Command0<void> loginCommand;

bool isLoading;
late Command0<void> loginCommand;
late Command0<void> validadeTokenCommand;

final GlobalKey<FormState> formKey;
final TextEditingController emailController;
final TextEditingController passwordController;

LoginViewModel(this.context)
: isLoading = false,
formKey = GlobalKey<FormState>(),
LoginViewModel()
: formKey = GlobalKey<FormState>(),
emailController = TextEditingController(),
passwordController = TextEditingController() {

loginCommand = Command0<void>(loginWithEmailAndPassword);

validadeTokenCommand = Command0<void>(validateToken);
validadeTokenCommand.execute();
}

Future<Result<void>> loginWithEmailAndPassword() async {
if (isLoading) {
return Result.value(null);
if (!formKey.currentState!.validate()) {
return Result.error(Exception('Valores inválidos'));
}

try {
isLoading = true;
notifyListeners();

if (!formKey.currentState!.validate()) {
return Result.error(Exception('Valores inválidos'));
}
await LoginService.login(
LoginRequest(emailController.text, passwordController.text));

await LoginService.login(
LoginRequest(emailController.text, passwordController.text));
return Result.value(null);
} catch (e) {
return Result.error(e);
} finally {
isLoading = false;
notifyListeners();
}
return Result.value(null);
}

Future<void> validateToken() async {
Future<Result<void>> validateToken() async {
await LoginService.validateToken();

return Result.value(null);
}

Future<bool> loginWithDeviceAuth() async {
Log.d('init loginWithDeviceAuth');
return await LocalAuthentication()
.authenticate(localizedReason: 'Toque com o dedo no sensor para logar');
}

void goToHome() {
try {
if (context.mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const NavbarView(),
),
);
}
} catch (e) {
Log.e(e);
rethrow;
}
}
}
Loading

0 comments on commit f8a4241

Please sign in to comment.