diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e15ab6cf..5dbf2dbf 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,6 +1,6 @@ import UIKit - import Flutter +import flutter_secure_storage @main @objc class AppDelegate: FlutterAppDelegate { @@ -9,6 +9,11 @@ import Flutter didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) + + // Configurar o Keychain para remover dados quando o app for desinstalado + let secureStorage = FlutterSecureStoragePlugin() + secureStorage.setAccessibility(.whenPasscodeSetThisDeviceOnly) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } -} +} \ No newline at end of file diff --git a/lib/app_state.dart b/lib/app_state.dart index 7052dc0e..47a419ee 100644 --- a/lib/app_state.dart +++ b/lib/app_state.dart @@ -4,6 +4,7 @@ import 'package:csv/csv.dart'; import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:synchronized/synchronized.dart'; class AppState extends ChangeNotifier { @@ -112,6 +113,7 @@ class AppState extends ChangeNotifier { _deviceDescription = await secureStorage.getString('deviceDescription') ?? _deviceDescription; }); + await loadFirstRun(); } void update(VoidCallback callback) { @@ -275,7 +277,11 @@ class AppState extends ChangeNotifier { AppState().deleteTokenAPNS(); AppState().deleteContext(); secureStorage.deleteAll(); + AppState().isLogged = false; + AppState().setFirstRun(false); + + AppState().update(() {}); } } diff --git a/lib/backend/api_requests/api_calls.dart b/lib/backend/api_requests/api_calls.dart index dab1d43b..2f5d1bf9 100644 --- a/lib/backend/api_requests/api_calls.dart +++ b/lib/backend/api_requests/api_calls.dart @@ -173,11 +173,13 @@ class UpdatePet { 'name': name, 'species': species, 'breed': breed, - 'color': color, - 'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), + if (color != '') 'color': color, + if (birthdayDate != '') + 'birthdayDate': + ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), 'gender': gender, 'size': size, - 'notes': notes, + if (notes != '') 'notes': notes, }, bodyType: BodyType.X_WWW_FORM_URL_ENCODED, returnBody: true, diff --git a/lib/components/atomic_components/shared_components_atoms/submit_button.dart b/lib/components/atomic_components/shared_components_atoms/submit_button.dart index c970dca3..1ca6c5d2 100644 --- a/lib/components/atomic_components/shared_components_atoms/submit_button.dart +++ b/lib/components/atomic_components/shared_components_atoms/submit_button.dart @@ -23,7 +23,7 @@ class SubmitButtonUtil extends StatelessWidget { width: 250.0, height: 36.0, disabledColor: FlutterFlowTheme.of(context).customColor5, - padding: const EdgeInsetsDirectional.fromSTEB(80.0, 0.0, 80.0, 0.0), + padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), iconPadding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), color: FlutterFlowTheme.of(context).primary, textStyle: FlutterFlowTheme.of(context).titleSmall.override( diff --git a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart index fb19fd44..7dfc1d7f 100644 --- a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart +++ b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart @@ -98,13 +98,21 @@ class _CardItemTemplateComponentWidgetState } Widget _generateImage() { - CachedNetworkImage.evictFromCache(widget.imagePath ?? ''); + // CachedNetworkImage.evictFromCache(widget.imagePath ?? ''); return ClipRRect( borderRadius: BorderRadius.circular(20), child: CachedNetworkImage( fadeInDuration: const Duration(milliseconds: 500), fadeOutDuration: const Duration(milliseconds: 500), imageUrl: widget.imagePath ?? '', + placeholder: (context, url) => const Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + Color(0xFF1AAB5F), + ), + ), + ), + errorWidget: (context, url, error) => const Icon(Icons.error), fit: BoxFit.cover, width: 90, height: 90, diff --git a/lib/components/templates_components/details_component/details_component_widget.dart b/lib/components/templates_components/details_component/details_component_widget.dart index 6aefc08a..48bf6691 100644 --- a/lib/components/templates_components/details_component/details_component_widget.dart +++ b/lib/components/templates_components/details_component/details_component_widget.dart @@ -65,7 +65,7 @@ class _DetailsComponentWidgetState extends State { @override Widget build(BuildContext context) { context.watch(); - CachedNetworkImage.evictFromCache(widget.imagePath ?? ''); + // CachedNetworkImage.evictFromCache(widget.imagePath ?? ''); return Container( constraints: BoxConstraints( diff --git a/lib/main.dart b/lib/main.dart index fdc091b4..9bf19a0f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,6 +31,10 @@ Future initializeApp() async { final appState = AppState(); await appState.initializePersistedState(); + if (AppState().firstRun == true) { + AppState().deleteAll(); + } + await Firebase.initializeApp(); await NotificationService.initialize(); diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index dbd834f3..f1e6ebe6 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; @@ -270,10 +271,9 @@ class PetsPageModel extends FlutterFlowModel { Future updatePet() async { var img = await actions.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; - await PhpGroup.updatePet - .call( + await PhpGroup.updatePet.call( petID: petId, - image: img, + image: imgBase64, birthdayDate: textControllerData!.text, color: textControllerColor!.text, breed: textControllerRace!.text, @@ -282,29 +282,39 @@ class PetsPageModel extends FlutterFlowModel { gender: dropDownValue1!, notes: textControllerObservation!.text, size: dropDownValue2!, - ) - .then((response) { - if (response.jsonBody['error'] == true || - isFormValid(buildContext!) == false) { - DialogUtil.error(buildContext!, - jsonDecode(response.jsonBody['error_msg'])[0]['message']); - } + ); + + if (response.jsonBody['error'] == false) { DialogUtil.success( - buildContext!, - FFLocalizations.of(buildContext!).getVariableText( - enText: 'Pet successfully updated', - ptText: 'Pet atualizado com sucesso', - )); + buildContext!, + FFLocalizations.of(buildContext!).getVariableText( + enText: 'Pet successfully updated', + ptText: 'Pet atualizado com sucesso', + ), + ); + + CachedNetworkImage.evictFromCache(url); onUpdatePet?.call(); switchTab(1); - }); + } else { + String errorMessage; + try { + errorMessage = + jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); + } catch (e) { + errorMessage = FFLocalizations.of(buildContext!).getVariableText( + enText: 'Failed to update pet', + ptText: 'Falha ao atualizar o pet', + ); + } + DialogUtil.error(buildContext!, errorMessage); + } } Future registerPet() async { var img = await actions.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; - await PhpGroup.registerPet - .call( + await PhpGroup.registerPet.call( image: img, birthdayDate: textControllerData!.text, color: textControllerColor!.text, @@ -314,35 +324,34 @@ class PetsPageModel extends FlutterFlowModel { gender: dropDownValue1!, size: dropDownValue2!, notes: textControllerObservation!.text, - ) - .then((response) { - if (response.jsonBody['error'] == true) { - String errorMessage = ''; - try { - errorMessage = jsonDecode(response.jsonBody['error_msg'])[0] - ['message'] - .toString(); - } catch (e) { - errorMessage = 'An error occurred.'; - if (response.jsonBody['error_msg'] == - "Limite de Cadastro de Pet Atingido.") { - errorMessage = FFLocalizations.of(buildContext!).getVariableText( - enText: 'Pet registration limit reached', - ptText: 'Limite de cadastro de pets atingido', - ); - } + ); + + if (response.jsonBody['error'] == false) { + DialogUtil.success( + buildContext!, + FFLocalizations.of(buildContext!).getVariableText( + enText: 'Pet successfully registered', + ptText: 'Pet cadastrado com sucesso', + ), + ); + onRegisterPet?.call(); + } else { + String errorMessage; + try { + errorMessage = + jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); + } catch (e) { + if (response.jsonBody['error_msg'] == + "Limite de Cadastro de Pet Atingido.") { + errorMessage = FFLocalizations.of(buildContext!).getVariableText( + enText: 'Pet registration limit reached', + ptText: 'Limite de cadastro de pets atingido', + ); + } else { + DialogUtil.errorDefault(buildContext!); } - DialogUtil.error(buildContext!, errorMessage); - } else if (response.jsonBody['error'] == false) { - DialogUtil.success( - buildContext!, - FFLocalizations.of(buildContext!).getVariableText( - enText: 'Pet successfully registered', - ptText: 'Pet cadastrado com sucesso', - )); - onRegisterPet?.call(); } - }); + } } void switchTab(int index) {