Merge branch 'develop' into feature/fd-466

This commit is contained in:
J. A. Messias 2024-11-12 10:39:46 -03:00
commit 932234b983
11 changed files with 537 additions and 319 deletions

View File

@ -1,7 +1,124 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.freaccess.hub">
<!-- Flutter needs it to communicate with the running application package="com.freaccess.hub"
to allow setting breakpoints, to provide hot reload, etc.
--> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
</manifest> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE" />
<application
android:label="FRE ACCESS HUB"
tools:replace="android:label"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:showWhenLocked="true"
android:turnScreenOn="true">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="freaccess.com.br" android:pathPrefix="/freaccess/alterarSenha.php" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="freaccess" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="mensagem" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="frehub" android:host="frehub.com" />
</intent-filter>
<intent-filter>
<action android:name="visit_request" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="access" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="mensagem" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="enroll_cond" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/notification_icon" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- <receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver> -->
</application>
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>

View File

@ -1,119 +1,124 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.freaccess.hub"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE" />
<application package="com.freaccess.hub"
android:label="FRE ACCESS HUB"
tools:replace="android:label"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true">
<activity xmlns:tools="http://schemas.android.com/tools">
android:name="io.flutter.embedding.android.FlutterFragmentActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:showWhenLocked="true"
android:turnScreenOn="true">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE" />
<meta-data <application
android:name="io.flutter.embedding.android.NormalTheme" android:label="FRE ACCESS HUB"
android:resource="@style/NormalTheme" tools:replace="android:label"
/> android:icon="@mipmap/ic_launcher"
<meta-data android:requestLegacyExternalStorage="true"
android:name="io.flutter.embedding.android.SplashScreenDrawable" android:usesCleartextTraffic="true">
android:resource="@drawable/launch_background"
/>
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:showWhenLocked="true"
android:turnScreenOn="true">
<intent-filter> <meta-data
<action android:name="android.intent.action.MAIN" /> android:name="io.flutter.embedding.android.NormalTheme"
<category android:name="android.intent.category.LAUNCHER" /> android:resource="@style/NormalTheme"
</intent-filter> />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="freaccess.com.br" android:pathPrefix="/freaccess/alterarSenha.php" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="freaccess" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="mensagem" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="frehub" android:host="frehub.com" />
</intent-filter>
<intent-filter>
<action android:name="visit_request" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="access" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="mensagem" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="enroll_cond" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
</activity> <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data <intent-filter android:autoVerify="true">
android:name="com.google.firebase.messaging.default_notification_icon" <action android:name="android.intent.action.VIEW" />
android:resource="@drawable/notification_icon" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="freaccess.com.br" android:pathPrefix="/freaccess/alterarSenha.php" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="freaccess" />
</intent-filter>
<!-- Don't delete the meta-data below. <intent-filter android:autoVerify="true">
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <action android:name="mensagem" />
<meta-data <category android:name="android.intent.category.DEFAULT" />
android:name="flutterEmbedding" <category android:name="android.intent.category.BROWSABLE" />
android:value="2" /> <data android:scheme="frehub" android:host="frehub.com" />
</intent-filter>
<intent-filter>
<action android:name="visit_request" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- <receiver android:exported="false" <intent-filter>
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" /> <action android:name="access" />
<receiver android:exported="false" <category android:name="android.intent.category.DEFAULT" />
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" /> <action android:name="mensagem" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" /> <category android:name="android.intent.category.DEFAULT" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" /> </intent-filter>
</intent-filter>
</receiver> --> <intent-filter>
<action android:name="enroll_cond" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/notification_icon" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- <receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver> -->
</application>
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</application>
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest> </manifest>

View File

@ -1,5 +1,29 @@
package com.freaccess.hub package com.freaccess.hub
import android.os.Bundle
import android.provider.Settings
import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterFragmentActivity() {} class MainActivity: FlutterFragmentActivity() {
private val CHANNEL = "com.freaccess.hub/getAndroidId"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "getAndroidId") {
val androidId = getAndroidId()
if (androidId != null) {
result.success(androidId)
} else {
result.error("UNAVAILABLE", "Android ID not available.", null)
}
} else {
result.notImplemented()
}
}
}
private fun getAndroidId(): String? {
return Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
}
}

View File

@ -14,7 +14,8 @@ import '/backend/api_requests/api_calls.dart';
import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_theme.dart';
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget { class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
const BottomArrowLinkedLocalsComponentWidget({super.key}); const BottomArrowLinkedLocalsComponentWidget({super.key, required this.response});
final ApiCallResponse? response;
@override @override
State<BottomArrowLinkedLocalsComponentWidget> createState() => _BottomArrowLinkedLocalsComponentWidgetState(); State<BottomArrowLinkedLocalsComponentWidget> createState() => _BottomArrowLinkedLocalsComponentWidgetState();
@ -71,16 +72,15 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLink
Future<ApiCallResponse?> _fetchLocals() async { Future<ApiCallResponse?> _fetchLocals() async {
try { try {
setState(() => _loading = true); setState(() => _loading = true);
var response = await PhpGroup.getLocalsCall.call(); final bool isError = widget.response?.jsonBody['error'];
final bool isError = response.jsonBody['error'];
if (isError) { if (isError) {
final String errorMsg = response.jsonBody['error_msg']; final String errorMsg = widget.response?.jsonBody['error_msg'];
_handleError(context, errorMsg); _handleError(context, errorMsg);
return response; return widget.response;
} }
final List<dynamic> locals = response.jsonBody['locais'] ?? []; final List<dynamic> locals = widget.response?.jsonBody['locais'] ?? [];
final bool isEmpty = locals.isEmpty; final bool isEmpty = locals.isEmpty;
final bool isUnique = locals.length == 1; final bool isUnique = locals.length == 1;
@ -99,7 +99,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLink
if (isDisabled) { if (isDisabled) {
context.go('/receptionPage'); context.go('/receptionPage');
return response; return widget.response;
} }
if (isEnabled) { if (isEnabled) {
final local = locals[0]; final local = locals[0];
@ -109,10 +109,10 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLink
await StorageHelper().set(SQLiteStorageKey.ownerUUID.value, local['CLU_OWNER_ID'], Storage.SQLiteStorage); await StorageHelper().set(SQLiteStorageKey.ownerUUID.value, local['CLU_OWNER_ID'], Storage.SQLiteStorage);
context.pop(); context.pop();
return response; return widget.response;
} }
return response; return widget.response;
} }
_showNoMoreDataSnackBar(context); _showNoMoreDataSnackBar(context);
setState(() { setState(() {
@ -131,7 +131,6 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLink
} }
static void _handleError(BuildContext context, String errorMsg) { static void _handleError(BuildContext context, String errorMsg) {
AuthenticationService.signOut(context);
DialogUtil.error(context, errorMsg); DialogUtil.error(context, errorMsg);
} }

View File

@ -20,7 +20,6 @@ class LocalProfileComponentModel extends FlutterFlowModel<LocalProfileComponentW
Future<void> getData() async { Future<void> getData() async {
cliName = (await StorageHelper().get(SQLiteStorageKey.clientName.value, Storage.SQLiteStorage)) ?? ''; cliName = (await StorageHelper().get(SQLiteStorageKey.clientName.value, Storage.SQLiteStorage)) ?? '';
cliUUID = (await StorageHelper().get(SQLiteStorageKey.clientUUID.value, Storage.SQLiteStorage)) ?? ''; cliUUID = (await StorageHelper().get(SQLiteStorageKey.clientUUID.value, Storage.SQLiteStorage)) ?? '';
;
setStateCallback?.call(); setStateCallback?.call();
} }

View File

@ -3,6 +3,8 @@ import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hub/shared/helpers/base_storage.dart';
import 'package:hub/shared/helpers/storage_helper.dart';
import '/flutter_flow/custom_functions.dart' as functions; import '/flutter_flow/custom_functions.dart' as functions;
import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_theme.dart';
@ -34,10 +36,15 @@ class _LocalProfileComponentWidgetState extends State<LocalProfileComponentWidge
_model = createModel(context, () => LocalProfileComponentModel()); _model = createModel(context, () => LocalProfileComponentModel());
_model.setOnUpdate(onUpdate: () => setState(() {})); _model.setOnUpdate(onUpdate: () => setState(() {}));
_model.setStateCallback = () => safeSetState(() {}); _model.setStateCallback = () => safeSetState(() {});
//
// WidgetsBinding.instance WidgetsBinding.instance.addPostFrameCallback((_) async {
// .addPostFrameCallback((_) async => await LocalizationService.processLocals(context).then((value) => value == true ? onUpdate() : null)); bool initialized = false;
// LocalizationService.processLocals(context).then((value) => value == true ? onUpdate() : null); bool isDevLinked = _model.cliUUID.isNotEmpty;
if (!isDevLinked && !initialized) {
initialized = true;
await LocalizationService.processLocals(context).then((value) => value == true ? onUpdate() : null);
}
});
} }
@override @override
@ -90,7 +97,8 @@ class _LocalProfileComponentWidgetState extends State<LocalProfileComponentWidge
hoverColor: Colors.transparent, hoverColor: Colors.transparent,
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
onTap: () async { onTap: () async {
await LocalizationService.selectLocal(context) await StorageHelper().set(SQLiteStorageKey.clientUUID.value, '', Storage.SQLiteStorage);
await LocalizationService.processLocals(context)
.then((value) => value == true ? onUpdate() : null); .then((value) => value == true ? onUpdate() : null);
}, },
child: ClipRRect( child: ClipRRect(

View File

@ -280,7 +280,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
if (state == AppLifecycleState.detached) { if (state == AppLifecycleState.detached) {
await LocalizationService.processLocals(context); await LocalizationService.processLocals(context);
FirebaseMessagingService().updateDeviceToken(); FirebaseMessagingService().updateDeviceToken();
} }
} }
@override @override

View File

@ -20,15 +20,10 @@ import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/validator_util.dart'; import 'package:hub/shared/utils/validator_util.dart';
class PetsPageModel extends FlutterFlowModel<PetsPageWidget> { class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
static PetsPageModel? _instance = PetsPageModel._internal();
PetsPageModel._internal();
factory PetsPageModel() => _instance ?? PetsPageModel._internal();
static void resetInstance() => _instance = null;
late final String devUUID; late final String devUUID;
late final String userUUID; late final String userUUID;
late final String cliUUID; late final String cliUUID;
late String petAmountRegister = '0'; late final String petAmountRegister;
dynamic item; dynamic item;
late final TabController tabBarController; late final TabController tabBarController;
@ -50,6 +45,8 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
FFUploadedFile? uploadedTempFile; FFUploadedFile? uploadedTempFile;
String? imgBase64; String? imgBase64;
late String defaultDropDownText = '';
String? dropDownValue1; String? dropDownValue1;
FormFieldController<String>? dropDownValueController1; FormFieldController<String>? dropDownValueController1;
@ -108,18 +105,23 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
String? Function(BuildContext, String?)? textControllerObservationValidator; String? Function(BuildContext, String?)? textControllerObservationValidator;
Future<void> initAsync() async { Future<void> initAsync() async {
defaultDropDownText = FFLocalizations.of(buildContext!).getVariableText(
enText: 'Select an option',
ptText: 'Selecione uma opção',
);
dropDownValueController1 = FormFieldController<String>(dropDownValue1 ??= defaultDropDownText);
dropDownValueController2 = FormFieldController<String>(dropDownValue2 ??= defaultDropDownText);
devUUID = (await StorageHelper().get(SQLiteStorageKey.devUUID.value, Storage.SQLiteStorage)) ?? ''; devUUID = (await StorageHelper().get(SQLiteStorageKey.devUUID.value, Storage.SQLiteStorage)) ?? '';
userUUID = (await StorageHelper().get(SQLiteStorageKey.userUUID.value, Storage.SQLiteStorage)) ?? ''; userUUID = (await StorageHelper().get(SQLiteStorageKey.userUUID.value, Storage.SQLiteStorage)) ?? '';
cliUUID = (await StorageHelper().get(SQLiteStorageKey.clientUUID.value, Storage.SQLiteStorage)) ?? ''; cliUUID = (await StorageHelper().get(SQLiteStorageKey.clientUUID.value, Storage.SQLiteStorage)) ?? '';
petAmountRegister = await StorageHelper().get(SQLiteStorageKey.petAmount.value, Storage.SQLiteStorage) ?? '0'; petAmountRegister = (await StorageHelper().get(SQLiteStorageKey.petAmount.value, Storage.SQLiteStorage)) ?? '';
safeSetState?.call(); safeSetState?.call();
} }
@override @override
void initState(BuildContext context) { void initState(BuildContext context) {
initAsync();
resetInstance();
tabBarController = TabController( tabBarController = TabController(
vsync: Navigator.of(context), vsync: Navigator.of(context),
length: 2, length: 2,
@ -143,35 +145,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
textFieldFocusObservation = FocusNode(); textFieldFocusObservation = FocusNode();
textControllerObservation = TextEditingController(); textControllerObservation = TextEditingController();
dropDownValueController1 = FormFieldController<String>(dropDownValue1 ??= 'Selecione uma opção'); initAsync();
dropDownValueController2 = FormFieldController<String>(dropDownValue2 ??= 'Selecione uma opção');
}
@override
void dispose() {
tabBarController.dispose();
textFieldFocusName?.dispose();
textControllerName?.dispose();
textFieldFocusSpecies?.dispose();
textControllerSpecies?.dispose();
textFieldFocusRace?.dispose();
textControllerRace?.dispose();
textFieldFocusColor?.dispose();
textControllerColor?.dispose();
textFieldFocusData?.dispose();
textControllerData?.dispose();
textFieldFocusObservation?.dispose();
textControllerObservation?.dispose();
dropDownValueController1?.dispose();
dropDownValueController2?.dispose();
} }
void setEditForm() { void setEditForm() {
@ -221,26 +195,65 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
dropDownValueController2 = FormFieldController<String>(dropDownValue2); dropDownValueController2 = FormFieldController<String>(dropDownValue2);
} }
@override
void dispose() {
tabBarController.dispose();
textFieldFocusName?.dispose();
textControllerName?.dispose();
textFieldFocusSpecies?.dispose();
textControllerSpecies?.dispose();
textFieldFocusRace?.dispose();
textControllerRace?.dispose();
textFieldFocusColor?.dispose();
textControllerColor?.dispose();
textFieldFocusData?.dispose();
textControllerData?.dispose();
textFieldFocusObservation?.dispose();
textControllerObservation?.dispose();
dropDownValueController1?.dispose();
dropDownValueController2?.dispose();
}
bool isFormValid(BuildContext context) { bool isFormValid(BuildContext context) {
if (uploadedLocalFile == null || uploadedLocalFile!.bytes!.isEmpty) { if (uploadedLocalFile == null || uploadedLocalFile!.bytes!.isEmpty) {
return false; return false;
} }
if (textControllerName!.text.isEmpty || textControllerName!.text.length > 80 || textControllerName!.text == '') { if (textControllerName.text.isEmpty || textControllerName.text.length > 80 || textControllerName.text == '') {
return false; return false;
} }
if (textControllerSpecies!.text.isEmpty || textControllerSpecies!.text == '') { if (textControllerSpecies.text.isEmpty || textControllerSpecies.text == '') {
return false; return false;
} }
if (textControllerRace!.text.isEmpty || textControllerRace!.text == '') { if (textControllerRace.text.isEmpty || textControllerRace.text == '') {
return false; return false;
} }
if (dropDownValue1 == null || dropDownValue1!.isEmpty || dropDownValue1 == '') { if (dropDownValueController1!.value == defaultDropDownText ||
dropDownValueController1!.value == '' ||
dropDownValueController1!.value == null) {
return false; return false;
} }
if (dropDownValue2 == null || dropDownValue2!.isEmpty || dropDownValue2 == '') { if (dropDownValueController2!.value == defaultDropDownText ||
dropDownValueController2!.value == '' ||
dropDownValueController2!.value == null) {
return false; return false;
} }
if (dropDownValue1 == 'Selecione uma opção' || dropDownValue1 == null || dropDownValue1 == '') {
return false;
}
if (dropDownValue2 == 'Selecione uma opção' || dropDownValue2 == null || dropDownValue2 == '') {
return false;
}
return true; return true;
} }
@ -263,7 +276,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
); );
if (response.jsonBody['error'] == false) { if (response.jsonBody['error'] == false) {
DialogUtil.success( await DialogUtil.success(
buildContext!, buildContext!,
FFLocalizations.of(buildContext!).getVariableText( FFLocalizations.of(buildContext!).getVariableText(
enText: 'Pet successfully updated', enText: 'Pet successfully updated',
@ -284,7 +297,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
ptText: 'Falha ao atualizar o pet', ptText: 'Falha ao atualizar o pet',
); );
} }
DialogUtil.error(buildContext!, errorMessage); await DialogUtil.error(buildContext!, errorMessage);
} }
} }
@ -304,7 +317,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
); );
if (response.jsonBody['error'] == false) { if (response.jsonBody['error'] == false) {
DialogUtil.success( await DialogUtil.success(
buildContext!, buildContext!,
FFLocalizations.of(buildContext!).getVariableText( FFLocalizations.of(buildContext!).getVariableText(
enText: 'Pet successfully registered', enText: 'Pet successfully registered',
@ -316,15 +329,16 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
String errorMessage; String errorMessage;
try { try {
errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString();
await DialogUtil.error(buildContext!, errorMessage);
} catch (e) { } catch (e) {
if (response.jsonBody['error_msg'] == "Limite de Cadastro de Pet Atingido.") { if (response.jsonBody['error_msg'] == "Limite de Cadastro de Pet Atingido.") {
errorMessage = FFLocalizations.of(buildContext!).getVariableText( errorMessage = FFLocalizations.of(buildContext!).getVariableText(
enText: 'Pet registration limit reached', enText: 'Pet registration limit reached',
ptText: 'Limite de cadastro de pets atingido', ptText: 'Limite de cadastro de pets atingido',
); );
DialogUtil.error(buildContext!, errorMessage); await DialogUtil.error(buildContext!, errorMessage);
} else { } else {
DialogUtil.errorDefault(buildContext!); await DialogUtil.errorDefault(buildContext!);
} }
} }
} }
@ -364,10 +378,8 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
// dropDownValue1 = ''; // dropDownValue1 = '';
// dropDownValue2 = ''; // dropDownValue2 = '';
// dropDownValueController1 = // dropDownValueController1 = FormFieldController<String>('Selecione uma opção');
// FormFieldController<String>('Selecione uma opção'); // dropDownValueController2 = FormFieldController<String>('Selecione uma opção');
// dropDownValueController2 =
// FormFieldController<String>('Selecione uma opção');
} }
Widget buildPetDetails({ Widget buildPetDetails({
@ -378,123 +390,120 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
required String cliUUID, required String cliUUID,
required String cliName, required String cliName,
required PetsPageModel model, required PetsPageModel model,
bool isInteractive = true,
}) { }) {
return DetailsComponentWidget( return DetailsComponentWidget(
buttons: [ buttons: [
// EDIT ACTION // EDIT ACTION
if (isInteractive) FFButtonWidget(
FFButtonWidget( text: FFLocalizations.of(context).getVariableText(
text: FFLocalizations.of(context).getVariableText( ptText: 'Editar',
ptText: 'Editar', enText: 'Edit',
enText: 'Edit',
),
icon: const Icon(Icons.edit),
onPressed: () async {
context.pop();
model.isEditing = true;
model.item = item;
model.switchTab(0);
model.setEditForm();
// model.safeSetState!();
},
options: FFButtonOptions(
width: 100,
height: 40,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15),
),
splashColor: const Color.fromARGB(95, 0, 146, 5),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
),
), ),
icon: const Icon(Icons.edit),
onPressed: () async {
context.pop();
model.isEditing = true;
model.item = item;
model.switchTab(0);
model.setEditForm();
// model.safeSetState!();
},
options: FFButtonOptions(
width: 100,
height: 40,
color: FlutterFlowTheme.of(context).primaryBackground,
elevation: 0,
textStyle: TextStyle(
color: FlutterFlowTheme.of(context).primaryText,
fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15),
),
splashColor: const Color.fromARGB(95, 0, 146, 5),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
),
),
// DELETE ACTION // DELETE ACTION
if (isInteractive) FFButtonWidget(
FFButtonWidget( text: FFLocalizations.of(context).getVariableText(
text: FFLocalizations.of(context).getVariableText( ptText: 'Excluir',
ptText: 'Excluir', enText: 'Delete',
enText: 'Delete', ),
), icon: const Icon(Icons.close),
icon: const Icon(Icons.close), onPressed: () async {
onPressed: () async { showAlertDialog(
showAlertDialog( context,
context, FFLocalizations.of(context).getVariableText(
FFLocalizations.of(context).getVariableText( ptText: 'Excluir Pet',
ptText: 'Excluir Pet', enText: 'Delete Pet',
enText: 'Delete Pet', ),
), FFLocalizations.of(context).getVariableText(
FFLocalizations.of(context).getVariableText( ptText: 'Você tem certeza que deseja excluir esse pet?',
ptText: 'Você tem certeza que deseja excluir esse pet?', enText: 'Are you sure you want to delete this pet?',
enText: 'Are you sure you want to delete this pet?', ), () async {
), () async { int id = item['id'];
int id = item['id']; await PhpGroup.deletePet
await PhpGroup.deletePet .call(
.call( petID: id,
petID: id, )
) .then((value) {
.then((value) { // Navigator.pop(context, value);
// Navigator.pop(context, value); context.pop(value);
context.pop(value); context.pop(value);
context.pop(value);
if (value == false) { if (value == false) {
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao excluir pet',
enText: 'Error deleting pet',
),
true,
);
} else if (value == true) {
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Success deleting pet',
ptText: 'Succeso ao excluir pet',
),
false,
);
}
}).catchError((err, stack) {
context.pop();
showSnackbar( showSnackbar(
context, context,
FFLocalizations.of(context).getVariableText( FFLocalizations.of(context).getVariableText(
enText: 'Error deleting pet',
ptText: 'Erro ao excluir pet', ptText: 'Erro ao excluir pet',
enText: 'Error deleting pet',
), ),
true, true,
); );
}); } else if (value == true) {
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Success deleting pet',
ptText: 'Succeso ao excluir pet',
),
false,
);
}
}).catchError((err, stack) {
context.pop();
showSnackbar(
context,
FFLocalizations.of(context).getVariableText(
enText: 'Error deleting pet',
ptText: 'Erro ao excluir pet',
),
true,
);
}); });
}, });
options: FFButtonOptions( },
width: 100, options: FFButtonOptions(
height: 40, width: 100,
color: FlutterFlowTheme.of(context).primaryBackground, height: 40,
elevation: 0, color: FlutterFlowTheme.of(context).primaryBackground,
textStyle: TextStyle( elevation: 0,
color: FlutterFlowTheme.of(context).primaryText, textStyle: TextStyle(
fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), color: FlutterFlowTheme.of(context).primaryText,
), fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15),
splashColor: const Color.fromARGB(131, 255, 17, 0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
), ),
splashColor: const Color.fromARGB(131, 255, 17, 0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primaryBackground,
width: 1,
),
// borderRadius: 12,
), ),
),
], ],
// 'MIN', 'PEQ', 'MED', 'GRA', 'GIG' // 'MIN', 'PEQ', 'MED', 'GRA', 'GIG'
labelsHashMap: Map<String, String>.from({ labelsHashMap: Map<String, String>.from({

View File

@ -6,6 +6,7 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/preferences_settings_page/preferences_settings_model.dart'; import 'package:hub/pages/preferences_settings_page/preferences_settings_model.dart';
import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -104,26 +105,26 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.toggleFingerprint(context); onPressed = () => model.toggleFingerprint(context);
isEnabled = model.isFingerprint; isEnabled = model.isFingerprint;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative a autenticação por impressão digital para login seguro.', ptText: 'Autenticar com impressão digital no QRCode',
enText: 'Enable fingerprint authentication for secure login.', enText: 'Authenticate with fingerprint on the QRCode',
); );
break; break;
case 1: case 1:
icon = Icons.person; icon = Icons.share;
onPressed = () => model.enablePerson(context); onPressed = () => model.enablePerson(context);
isEnabled = model.isPerson; isEnabled = model.isPerson;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Compartilhe o código de identificação remota', ptText: 'Compartilhar o código de identificação',
enText: 'Share the remote identification code', enText: 'Share the identification code',
); );
break; break;
case 2: case 2:
icon = Icons.info; icon = Icons.transfer_within_a_station_outlined;
onPressed = () => model.toggleIdentification(context); onPressed = () => model.toggleIdentification(context);
isEnabled = false; isEnabled = false;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Atualize suas informações de identificação de acesso.', ptText: 'Habilitar dispositivo para acesso',
enText: 'Update your access identification information.', enText: 'Enable device for access',
); );
break; break;
case 3: case 3:
@ -131,8 +132,8 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.toggleNotify(context); onPressed = () => model.toggleNotify(context);
isEnabled = model.isNotify; isEnabled = model.isNotify;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para receber sua notificação de acesso', ptText: 'Receber notificação de acesso',
enText: 'Enable to receive your access notification', enText: 'Receive access notification',
); );
break; break;
case 4: case 4:
@ -140,8 +141,8 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.toggleAccess(context); onPressed = () => model.toggleAccess(context);
isEnabled = model.isAccess; isEnabled = model.isAccess;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para inserir uma credencial de acesso para o QRCode', ptText: 'Registrar senha de acesso para o QRCode',
enText: 'Enable to enter an access credential for the QRCode', enText: 'Register access password for the QRCode',
); );
break; break;
case 5: case 5:
@ -149,19 +150,19 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.togglePanic(context); onPressed = () => model.togglePanic(context);
isEnabled = model.isPanic; isEnabled = model.isPanic;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para inserir uma credencial de pânico para o QRCode', ptText: 'Registrar senha de pânico para o QRCode',
enText: 'Enable to enter a panic credential for the QRCode', enText: 'Register panic password for the QRCode',
); );
break; break;
case 6: case 6:
icon = Icons.landscape; icon = Symbols.digital_out_of_home;
onPressed = () { onPressed = () {
model.localUnlink(context); model.localUnlink(context);
}; };
isEnabled = false; isEnabled = false;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Desative para se desvincular do local selecionado', ptText: 'Desvincular do local selecionado',
enText: 'Enable to unlink from the selected location', enText: 'Unlink from selected location',
); );
break; break;
case 7: case 7:
@ -169,8 +170,8 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.deleteAccount(context); onPressed = () => model.deleteAccount(context);
isEnabled = false; isEnabled = false;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Delete sua conta e todos os dados associados permanentemente.', ptText: 'Deletar conta permanentemente',
enText: 'Delete your account and all associated data permanently.', enText: 'Delete account permanently',
); );
break; break;
case 8: case 8:
@ -178,8 +179,8 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
onPressed = () => model.logout(context); onPressed = () => model.logout(context);
isEnabled = false; isEnabled = false;
content = FFLocalizations.of(context).getVariableText( content = FFLocalizations.of(context).getVariableText(
ptText: 'Sair da conta atual e voltar para a tela de login.', ptText: 'Sair da conta',
enText: 'Log out of the current account and return to the login screen.', enText: 'Logout',
); );
break; break;
default: default:
@ -187,7 +188,7 @@ class _PreferencesPageWidgetState extends State<PreferencesPageWidget> {
} }
return SizedBox( return SizedBox(
height: 100, height: 66,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
switch (index) { switch (index) {

View File

@ -3,6 +3,8 @@
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/src/response.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/helpers/base_storage.dart'; import 'package:hub/shared/helpers/base_storage.dart';
import 'package:hub/shared/helpers/storage_helper.dart'; import 'package:hub/shared/helpers/storage_helper.dart';
@ -21,12 +23,20 @@ class LocalizationService {
try { try {
final GetLocalsCall callback = PhpGroup.getLocalsCall; final GetLocalsCall callback = PhpGroup.getLocalsCall;
var response = await callback.call(); var response = await callback.call();
final bool isError = response.jsonBody['error']; final bool? isError = response.jsonBody['error'];
if (isError) { if (isError == true) {
_handleError(context, response.jsonBody['error_msg']); _handleError(context, response.jsonBody['error_msg']);
return; return;
} }
if (response.jsonBody == null) {
final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection',
ptText: 'Verifique sua conexão',
);
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response));
return;
}
final List<dynamic> locals = response.jsonBody['locais'] ?? []; final List<dynamic> locals = response.jsonBody['locais'] ?? [];
final bool isEmpty = locals.isEmpty; final bool isEmpty = locals.isEmpty;
@ -50,13 +60,21 @@ class LocalizationService {
try { try {
final GetLocalsCall callback = PhpGroup.getLocalsCall; final GetLocalsCall callback = PhpGroup.getLocalsCall;
final ApiCallResponse response = await callback.call(); final ApiCallResponse response = await callback.call();
final bool isError = response.jsonBody['error']; final bool? isError = response.jsonBody['error'];
if (isError) { if (isError == true) {
final String errorMsg = response.jsonBody['error_msg']; final String errorMsg = response.jsonBody['error_msg'];
_handleError(context, errorMsg); _handleError(context, errorMsg);
return false; return false;
} }
if (response.jsonBody == null) {
final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection',
ptText: 'Verifique sua conexão',
);
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response));
return false;
}
final List<dynamic> locals = response.jsonBody['locais'].toList() ?? []; final List<dynamic> locals = response.jsonBody['locais'].toList() ?? [];
_logLocalsStatus(locals); _logLocalsStatus(locals);
@ -82,7 +100,7 @@ class LocalizationService {
return await _handleEnabled(context, locals[0]); return await _handleEnabled(context, locals[0]);
} else if (isUnselected) { } else if (isUnselected) {
log('() => isUnselected'); log('() => isUnselected');
return await selectLocal(context); return await selectLocal(context, response);
} else if (isSelected) { } else if (isSelected) {
log('() => isSelected'); log('() => isSelected');
return await processData(context); return await processData(context);
@ -95,7 +113,7 @@ class LocalizationService {
if (!isUnique && isPending) log('() => not unique and pending'); if (!isUnique && isPending) log('() => not unique and pending');
if (!isUnique && isBlocked) log('() => not unique and blocked'); if (!isUnique && isBlocked) log('() => not unique and blocked');
log('() => else'); log('() => else');
return await selectLocal(context); return await selectLocal(context, response);
} }
} catch (e, s) { } catch (e, s) {
log('() => stack: $s'); log('() => stack: $s');
@ -105,7 +123,7 @@ class LocalizationService {
enText: 'Error getting locals, verify your connection', enText: 'Error getting locals, verify your connection',
ptText: 'Erro ao obter locais, verifique sua conexão', ptText: 'Erro ao obter locais, verifique sua conexão',
); );
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context)); DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, null));
return false; return false;
} }
} }
@ -114,11 +132,18 @@ class LocalizationService {
try { try {
final GetDadosCall callback = PhpGroup.getDadosCall; final GetDadosCall callback = PhpGroup.getDadosCall;
var response = await callback.call(); var response = await callback.call();
final bool error = response.jsonBody['error']; final bool? isError = response.jsonBody['error'];
if (error == true || error == 'true') { if (isError == true || isError == 'true') {
final String errorMsg = response.jsonBody['error_msg']; final String errorMsg = response.jsonBody['error_msg'];
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context)); DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response));
return false;
} else if (response.jsonBody == null) {
final String errorMsg = FFLocalizations.of(context).getVariableText(
enText: 'Verify your connection',
ptText: 'Verifique sua conexão',
);
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response));
return false; return false;
} else { } else {
await _updateStorageUtil(response.jsonBody); await _updateStorageUtil(response.jsonBody);
@ -131,14 +156,12 @@ class LocalizationService {
enText: 'Error getting data, verify your connection', enText: 'Error getting data, verify your connection',
ptText: 'Erro ao obter dados, verifique sua conexão', ptText: 'Erro ao obter dados, verifique sua conexão',
); );
DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context)); DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, null));
return false; return false;
} }
} }
static Future<bool> selectLocal(BuildContext context) async { static Future<bool> selectLocal(BuildContext context, ApiCallResponse? response) async {
final String? devUUID = await DeviceUtil.getSerialNumber();
log('() A => ${devUUID}');
return await showModalBottomSheet( return await showModalBottomSheet(
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
@ -151,7 +174,7 @@ class LocalizationService {
canPop: false, canPop: false,
child: Padding( child: Padding(
padding: MediaQuery.viewInsetsOf(context), padding: MediaQuery.viewInsetsOf(context),
child: const BottomArrowLinkedLocalsComponentWidget(), child: BottomArrowLinkedLocalsComponentWidget(response: response),
), ),
), ),
).then((_) async => await processData(context)); ).then((_) async => await processData(context));
@ -207,6 +230,7 @@ class LocalizationService {
final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty; final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty;
final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario');
log('() => isLinked: $errorMsg'); log('() => isLinked: $errorMsg');
log('() => isLinked: $errorMsg');
if (!isAuthenticated) { if (!isAuthenticated) {
errorMsg = FFLocalizations.of(context).getVariableText( errorMsg = FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao obter credenciais de autenticação', ptText: 'Erro ao obter credenciais de autenticação',
@ -224,7 +248,7 @@ class LocalizationService {
await DialogUtil.warning(context, errorMsg); await DialogUtil.warning(context, errorMsg);
return; return;
} }
await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context)); await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
} }
static Future<bool> _handleUnavailable(BuildContext context, List<dynamic> locals) async { static Future<bool> _handleUnavailable(BuildContext context, List<dynamic> locals) async {
@ -313,3 +337,4 @@ class LocalizationService {
await StorageHelper().set(SQLiteStorageKey.userName.value, jsonBody['visitado']['VDO_NOME'], Storage.SQLiteStorage); await StorageHelper().set(SQLiteStorageKey.userName.value, jsonBody['visitado']['VDO_NOME'], Storage.SQLiteStorage);
} }
} }

View File

@ -2,42 +2,73 @@ import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/services.dart';
class DeviceUtil { class DeviceUtil {
static const MethodChannel _channel = MethodChannel("com.freaccess.hub/getAndroidId");
static Future<String?> getAndroidId() async {
try {
final String? androidId = await _channel.invokeMethod('getAndroidId');
return androidId;
} on PlatformException catch (e) {
print("Failed to get Android ID: '${e.message}'.");
return null;
}
}
static Future<String?> getDevUUID() async { static Future<String?> getDevUUID() async {
var deviceInfo = DeviceInfoPlugin(); var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { if (Platform.isIOS) {
// import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo; var iosDeviceInfo = await deviceInfo.iosInfo;
return iosDeviceInfo.identifierForVendor; // unique ID on iOS return iosDeviceInfo.identifierForVendor;
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo; try {
return androidDeviceInfo.id; // unique ID on Android final String? secureAndroidId = await getAndroidId();
return secureAndroidId;
} catch (e) {
final build = await deviceInfo.androidInfo;
return build.id;
}
} }
return null; return null;
} }
static Future<String?> getSerialNumber() async { static Future<String?> getSerialNumber() async {
var deviceInfo = DeviceInfoPlugin(); var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { if (Platform.isIOS) {
// import 'dart:io' // import 'dart:io'
var iosDeviceInfo = await deviceInfo.iosInfo; var iosDeviceInfo = await deviceInfo.iosInfo;
return iosDeviceInfo.identifierForVendor; // unique ID on iOS return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo; var androidDeviceInfo = await deviceInfo.androidInfo;
return androidDeviceInfo.serialNumber; // unique ID on Android return androidDeviceInfo.serialNumber; // unique ID on Android
} }
return null; return null;
} }
static Future<String?> getDeviceOSVersion() async { static Future<String?> getDeviceOSVersion() async {
var deviceInfo = DeviceInfoPlugin(); var deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) { if (Platform.isIOS) {
var iosDeviceInfo = await deviceInfo.iosInfo; var iosDeviceInfo = await deviceInfo.iosInfo;
return iosDeviceInfo.systemVersion; // unique ID on iOS. e.g. 14.5 return iosDeviceInfo.systemVersion; // unique ID on iOS. e.g. 14.5
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
var androidDeviceInfo = await deviceInfo.androidInfo; var androidDeviceInfo = await deviceInfo.androidInfo;
return androidDeviceInfo.version.release; // unique ID on Android. e.g . 11 return androidDeviceInfo.version.release; // unique ID on Android. e.g . 11
} }
return null; return null;
} }
} }