Skip to content

Commit

Permalink
ref(#59): use command pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielCostaDeOliveira committed Dec 26, 2024
1 parent 05ac25a commit 83e9bcd
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 52 deletions.
47 changes: 47 additions & 0 deletions lib/core/state/command.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:async/async.dart';
import 'package:flutter/material.dart';

abstract class Command<T> extends ChangeNotifier {
Result<T>? _result;

bool _running = false;

Command();

bool get isError => result?.asError != null;

bool get isOk => result?.asValue != null;

Result<T>? get result => _result;

bool get running => _running;

Future<void> _execute(action) async {
if (running) return;

_result = null;
_running = true;
notifyListeners();

try {
_result = await action();
} catch (e) {
_result = Result.error(e);
} finally {
_running = false;
notifyListeners();
}
}
}

class Command0<T> extends Command<T> {
final Future<Result<T>> Function() action;

Command0(this.action);

Future<Result<T>> execute() async {
await _execute(action);

return _result!;
}
}
58 changes: 38 additions & 20 deletions lib/ui/register_account/view/RegisterAccount.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,46 @@ class _RegisterAccountState extends State<_RegisterAccount> {

Widget _buildRegisterButton() {
final viewModel = Provider.of<RegisterAccountViewModel>(context);
return SizedBox(
width: 291,
height: 64,
child: ElevatedButton(
onPressed: () async {
try {
await viewModel.register(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Cadastro concluído com sucesso!")));
} catch(e) {
showDialog<Object>(
context: context,
builder: (BuildContext context) => ErrorPopUp(content: Text('$e')),
//Ação ao clicar no botão de cadastro
);
}
},
child: Consumer<RegisterAccountViewModel>(
builder: (context, value, child) => value.isLoading

return ListenableBuilder(

listenable: viewModel.registercomand,
builder: (context, child) {
if (viewModel.registercomand.isError) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog<Object>(
context: context,
builder: (BuildContext context) => ErrorPopUp(
content: Text(
viewModel.registercomand.result!.asError!.error.toString()),
),
);
});
}

if (viewModel.registercomand.isOk) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'conta criada com sucesso!!!')),
);
});
}

return SizedBox(
width: 291,
height: 64,
child: ElevatedButton(
onPressed: () async {
viewModel.registercomand.execute();
},
child: viewModel.registercomand.running
? const CircularProgressIndicator(value: null)
: const Text('Registrar'),
)),
),
);
},
);
}

Expand Down
56 changes: 26 additions & 30 deletions lib/ui/register_account/viewModel/RegisterViewModel.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:aranduapp/ui/shared/ErrorPopUp.dart';
import 'package:aranduapp/core/state/command.dart';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import '../model/RegisterRequest.dart';
import '../service/RegisterService.dart';
Expand All @@ -12,42 +13,37 @@ class RegisterAccountViewModel extends ChangeNotifier {

final TextEditingController confPasswordController = TextEditingController();

bool isLoading = false;
bool isTermsAccepted = false;

void toggleTermsAccepted(bool value) {
isTermsAccepted = value;
notifyListeners();
late Command0<void> registercomand;

RegisterAccountViewModel() {
registercomand = Command0<void>(_register);
}

Future<void> register(BuildContext context) async {
if (isLoading) return;
// Valida se os termos foram aceitos
Future<Result<void>> _register() async {

if (!isTermsAccepted) {
throw Exception(
return Result.error(
'Você deve aceitar os termos de privacidade e políticas de uso.');
}
try {
isLoading = true;
notifyListeners();
// Valida os campos do formulário
if (!formKey.currentState!.validate()) {
throw Exception('Por favor, preencha todos os campos corretamente');
}
// Criação do objeto de requisição
final request = RegisterRequest(
email: emailController.text,
name: nameController.text,
userName: userNameController.text,
password: passwordController.text,
);
// Chamada do serviço de registro
await RegisterService.register(request);
} catch (e) {
rethrow;
} finally {
isLoading = false;
notifyListeners();

if (!formKey.currentState!.validate()) {
Result.error('Por favor, preencha todos os campos corretamente');
}

await RegisterService.register(RegisterRequest(
email: emailController.text,
name: nameController.text,
userName: userNameController.text,
password: passwordController.text,
));

return Result.value(null);
}

void toggleTermsAccepted(bool value) {
isTermsAccepted = value;
notifyListeners();
}
}
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ packages:
source: hosted
version: "2.6.0"
async:
dependency: transitive
dependency: "direct main"
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
Expand Down Expand Up @@ -577,7 +577,7 @@ packages:
dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ dependencies:
flutter_secure_storage: ^9.2.2
mockito: ^5.4.4
build_runner: ^2.4.13
async: ^2.11.0


dev_dependencies:
Expand Down

0 comments on commit 83e9bcd

Please sign in to comment.