Refactor MessageWellComponentWidget, update totalPageNumber handling, implement settings preferences page and fix share
This commit is contained in:
parent
630376e416
commit
ff43303205
|
@ -7,6 +7,8 @@
|
||||||
<uses-permission android:name="android.permission.WRITE_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_PRIVILEGED_PHONE_STATE"/>
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="FREHub"
|
android:label="FREHub"
|
||||||
tools:replace="android:label"
|
tools:replace="android:label"
|
||||||
|
@ -14,7 +16,7 @@
|
||||||
android:requestLegacyExternalStorage="true">
|
android:requestLegacyExternalStorage="true">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name="io.flutter.embedding.android.FlutterFragmentActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.freaccess.hub
|
package com.freaccess.hub
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
class MainActivity: FlutterFragmentActivity() {
|
||||||
}
|
}
|
|
@ -78,6 +78,8 @@
|
||||||
<string>Main</string>
|
<string>Main</string>
|
||||||
<key>UIRequiresFullScreen</key>
|
<key>UIRequiresFullScreen</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSFaceIDUsageDescription</key>
|
||||||
|
<string>Why is my app authenticating using face id?</string>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
|
|
@ -1,9 +1,67 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/permissions_util.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:csv/csv.dart';
|
import 'package:csv/csv.dart';
|
||||||
|
import 'package:local_auth/local_auth.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:synchronized/synchronized.dart';
|
import 'package:synchronized/synchronized.dart';
|
||||||
|
|
||||||
class FFAppState extends ChangeNotifier {
|
class FFAppState extends ChangeNotifier {
|
||||||
|
// Adiciona a variável para controle de autenticação biométrica
|
||||||
|
bool _isBiometricAuthenticated = false;
|
||||||
|
bool get isBiometricAuthenticated => _isBiometricAuthenticated;
|
||||||
|
|
||||||
|
// Instância do LocalAuthentication
|
||||||
|
final LocalAuthentication auth = LocalAuthentication();
|
||||||
|
|
||||||
|
// Verifica suporte biométrico
|
||||||
|
Future<bool> checkBiometrics() async {
|
||||||
|
try {
|
||||||
|
return await auth.canCheckBiometrics;
|
||||||
|
} catch (e) {
|
||||||
|
clearBiometricAuthentication();
|
||||||
|
debugPrint('Error checking biometrics: $e');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solicita autenticação biométrica
|
||||||
|
Future<void> authenticateBiometric() async {
|
||||||
|
bool authenticated = false;
|
||||||
|
try {
|
||||||
|
authenticated = await auth.authenticate(
|
||||||
|
localizedReason: 'Scan your fingerprint to authenticate',
|
||||||
|
options: const AuthenticationOptions(
|
||||||
|
biometricOnly: true,
|
||||||
|
stickyAuth: true,
|
||||||
|
useErrorDialogs: true,
|
||||||
|
sensitiveTransaction: true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (authenticated) {
|
||||||
|
_isBiometricAuthenticated = true;
|
||||||
|
notifyListeners();
|
||||||
|
// Salvar o estado de autenticação biométrica, se necessário
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
debugPrint('Error authenticating: $e');
|
||||||
|
clearBiometricAuthentication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Função para limpar o estado de autenticação biométrica
|
||||||
|
void clearBiometricAuthentication() {
|
||||||
|
_isBiometricAuthenticated = false;
|
||||||
|
notifyListeners();
|
||||||
|
// Limpar a informação salva, se necessário
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static FFAppState _instance = FFAppState._internal();
|
static FFAppState _instance = FFAppState._internal();
|
||||||
|
|
||||||
factory FFAppState() {
|
factory FFAppState() {
|
||||||
|
@ -69,6 +127,25 @@ class FFAppState extends ChangeNotifier {
|
||||||
await _safeInitAsync(() async {
|
await _safeInitAsync(() async {
|
||||||
_serialNumber = await secureStorage.getString('ff_serialNumber') ?? _serialNumber;
|
_serialNumber = await secureStorage.getString('ff_serialNumber') ?? _serialNumber;
|
||||||
});
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_fingerprintOPT = await secureStorage.getBool('fingerprint') ?? _fingerprintOPT;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_personOPT = await secureStorage.getBool('person') ?? _personOPT;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_passOPT = await secureStorage.getBool('pass') ?? _passOPT;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_notifyOPT = await secureStorage.getBool('notify') ?? _notifyOPT;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_accessPass = await secureStorage.getString('accessPass') ?? _accessPass;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_panicPass = await secureStorage.getString('panicPass') ?? _panicPass;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(VoidCallback callback) {
|
void update(VoidCallback callback) {
|
||||||
|
@ -78,6 +155,70 @@ class FFAppState extends ChangeNotifier {
|
||||||
|
|
||||||
late FlutterSecureStorage secureStorage;
|
late FlutterSecureStorage secureStorage;
|
||||||
|
|
||||||
|
String _accessPass = '';
|
||||||
|
String get accessPass => _accessPass;
|
||||||
|
set accessPass(String value) {
|
||||||
|
_accessPass = value;
|
||||||
|
secureStorage.setString('accessPass', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteAccessPass() {
|
||||||
|
secureStorage.delete(key: 'accessPass');
|
||||||
|
}
|
||||||
|
|
||||||
|
String _panicPass = '';
|
||||||
|
String get panicPass => _panicPass;
|
||||||
|
set panicPass(String value) {
|
||||||
|
_panicPass = value;
|
||||||
|
secureStorage.setString
|
||||||
|
('panicPass', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePanicPass() {
|
||||||
|
secureStorage.delete(key: 'panicPass');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _notifyOPT = false;
|
||||||
|
bool get notify => _notifyOPT;
|
||||||
|
set notify(bool value) {
|
||||||
|
_notifyOPT = value;
|
||||||
|
secureStorage.setBool('notify', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _passOPT = false;
|
||||||
|
bool get pass => _passOPT;
|
||||||
|
set pass(bool value) {
|
||||||
|
_passOPT =
|
||||||
|
value;
|
||||||
|
secureStorage.setBool('pass', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePass() {
|
||||||
|
secureStorage.delete(key: 'pass');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _personOPT = false;
|
||||||
|
bool get person => _personOPT;
|
||||||
|
set person(bool value) {
|
||||||
|
_personOPT = value;
|
||||||
|
secureStorage.setBool('person', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePerson() {
|
||||||
|
secureStorage.delete(key: 'person');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _fingerprintOPT = false;
|
||||||
|
bool get fingerprint => _fingerprintOPT;
|
||||||
|
set fingerprint(bool value) {
|
||||||
|
_fingerprintOPT = value;
|
||||||
|
secureStorage.setBool('fingerprint', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteFingerprint() {
|
||||||
|
secureStorage.delete(key: 'fingerprint');
|
||||||
|
}
|
||||||
|
|
||||||
String _serialNumber = '';
|
String _serialNumber = '';
|
||||||
String get serialNumber => _serialNumber;
|
String get serialNumber => _serialNumber;
|
||||||
set serialNumber(String value) {
|
set serialNumber(String value) {
|
||||||
|
@ -270,6 +411,10 @@ class FFAppState extends ChangeNotifier {
|
||||||
void deleteName() {
|
void deleteName() {
|
||||||
secureStorage.delete(key: 'ff_name');
|
secureStorage.delete(key: 'ff_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deleteAll() {
|
||||||
|
secureStorage.deleteAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _safeInit(Function() initializeField) {
|
void _safeInit(Function() initializeField) {
|
||||||
|
|
|
@ -41,8 +41,125 @@ class PhpGroup {
|
||||||
static GetLiberationsCopyCall getLiberationsCopyCall =
|
static GetLiberationsCopyCall getLiberationsCopyCall =
|
||||||
GetLiberationsCopyCall();
|
GetLiberationsCopyCall();
|
||||||
static GetMessagesCall getMessagesCall = GetMessagesCall();
|
static GetMessagesCall getMessagesCall = GetMessagesCall();
|
||||||
|
static ChangeNotifica changeNotifica = ChangeNotifica();
|
||||||
|
static RespondeVinculo resopndeVinculo = RespondeVinculo();
|
||||||
|
static ChangePass changePass = ChangePass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChangePass {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = '',
|
||||||
|
String? newSenha = '',
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'changePass',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'newSenha': newSenha,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? error(dynamic response) => castToType<bool>(getJsonField(
|
||||||
|
response,
|
||||||
|
r'''$.error''',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
class RespondeVinculo {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? tarefa = '',
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'respondeVinculo',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'tarefa': tarefa,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeNotifica {
|
||||||
|
Future<ApiCallResponse> call({
|
||||||
|
String? devUUID = '',
|
||||||
|
String? userUUID = '',
|
||||||
|
String? cliID = '',
|
||||||
|
String? atividade = '',
|
||||||
|
String? notifica = '',
|
||||||
|
}) async {
|
||||||
|
final baseUrl = PhpGroup.getBaseUrl();
|
||||||
|
|
||||||
|
return ApiManager.instance.makeApiCall(
|
||||||
|
callName: 'changeNotifica',
|
||||||
|
apiUrl: '$baseUrl/processRequest.php',
|
||||||
|
callType: ApiCallType.POST,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
'devUUID': devUUID,
|
||||||
|
'userUUID': userUUID,
|
||||||
|
'cliID': cliID,
|
||||||
|
'atividade': atividade,
|
||||||
|
'notifica': notifica,
|
||||||
|
},
|
||||||
|
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||||
|
returnBody: true,
|
||||||
|
encodeBodyUtf8: false,
|
||||||
|
decodeUtf8: false,
|
||||||
|
cache: false,
|
||||||
|
isStreamingApi: false,
|
||||||
|
alwaysAllowBody: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? error(dynamic response) => castToType<bool>(getJsonField(
|
||||||
|
response,
|
||||||
|
r'''$.error''',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
class UpdToken {
|
class UpdToken {
|
||||||
Future<ApiCallResponse> call({
|
Future<ApiCallResponse> call({
|
||||||
String? token = '',
|
String? token = '',
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import '/flutter_flow/form_field_controller.dart';
|
||||||
|
import 'opt_modal_widget.dart' show OptModalWidget;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class OptModalModel extends FlutterFlowModel<OptModalWidget> {
|
||||||
|
/// State fields for stateful widgets in this component.
|
||||||
|
|
||||||
|
// State field(s) for TextField widget.
|
||||||
|
FocusNode? textFieldFocusNode;
|
||||||
|
TextEditingController? textController;
|
||||||
|
String? Function(BuildContext, String?)? textControllerValidator;
|
||||||
|
// State field(s) for Checkbox widget.
|
||||||
|
bool? checkboxValue1;
|
||||||
|
// State field(s) for Checkbox widget.
|
||||||
|
bool? checkboxValue2;
|
||||||
|
// State field(s) for CheckboxGroup widget.
|
||||||
|
FormFieldController<List<String>>? checkboxGroupValueController;
|
||||||
|
List<String>? get checkboxGroupValues => checkboxGroupValueController?.value;
|
||||||
|
set checkboxGroupValues(List<String>? v) =>
|
||||||
|
checkboxGroupValueController?.value = v;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(BuildContext context) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
textFieldFocusNode?.dispose();
|
||||||
|
textController?.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
import 'package:f_r_e_hub/components/molecular_components/opt_modal/opt_modal_model.dart';
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
class OptModalWidget extends StatefulWidget {
|
||||||
|
final String defaultPersonType;
|
||||||
|
final String defaultAccessType;
|
||||||
|
|
||||||
|
const OptModalWidget({
|
||||||
|
Key? key,
|
||||||
|
this.defaultPersonType = '.*',
|
||||||
|
this.defaultAccessType = '.*',
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_OptModalWidgetState createState() => _OptModalWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OptModalWidgetState extends State<OptModalWidget> {
|
||||||
|
late OptModalModel _model;
|
||||||
|
|
||||||
|
late Map<String, dynamic> selected;
|
||||||
|
final List<Map<String, String>> personTypeOptions = [
|
||||||
|
{'title': 'zok7lu4w', 'value': 'E'},
|
||||||
|
{'title': 'oonqk812', 'value': 'O'},
|
||||||
|
];
|
||||||
|
final List<Map<String, String>> accessTypeOptions = [
|
||||||
|
{'title': '580z80ct', 'value': '0'},
|
||||||
|
{'title': '1nbwqtzs', 'value': '1'},
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setState(VoidCallback callback) {
|
||||||
|
super.setState(callback);
|
||||||
|
_model.onUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_model = createModel(context, () => OptModalModel());
|
||||||
|
|
||||||
|
_model.textController ??= TextEditingController();
|
||||||
|
_model.textFieldFocusNode ??= FocusNode();
|
||||||
|
|
||||||
|
selected = {
|
||||||
|
'personType': widget.defaultPersonType == '.*'
|
||||||
|
? ['E', 'O']
|
||||||
|
: [widget.defaultPersonType],
|
||||||
|
'accessType': widget.defaultAccessType == '.*'
|
||||||
|
? ['0', '1']
|
||||||
|
: [widget.defaultAccessType],
|
||||||
|
'search': '.*',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void _applyFilter() {
|
||||||
|
Map<String, String> filterResult = {
|
||||||
|
'personType': '',
|
||||||
|
'accessType': '',
|
||||||
|
'search': _model.textController.text == ''
|
||||||
|
? '.*'
|
||||||
|
: _model.textController.text.toLowerCase(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (selected['personType']!.isEmpty) {
|
||||||
|
filterResult['personType'] = '.*';
|
||||||
|
} else if (selected['personType']!.length > 1) {
|
||||||
|
filterResult['personType'] = '.*';
|
||||||
|
} else {
|
||||||
|
filterResult['personType'] = selected['personType']!.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected['accessType']!.isEmpty) {
|
||||||
|
filterResult['accessType'] = '.*';
|
||||||
|
} else if (selected['accessType']!.length > 1) {
|
||||||
|
filterResult['accessType'] = '.*';
|
||||||
|
} else {
|
||||||
|
filterResult['accessType'] = selected['accessType']!.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.pop(context, filterResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildCheckboxListTile(String key, List<Map<String, String>> options) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(0.0, 10.0, 0.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getText('l7tw8b92'),
|
||||||
|
textAlign: TextAlign
|
||||||
|
.left, // Adiciona esta linha para alinhar o texto à esquerda
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: options.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final option = options[index];
|
||||||
|
return CheckboxListTile(
|
||||||
|
title: Text(
|
||||||
|
FFLocalizations.of(context).getText(option['title']!),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dense: true,
|
||||||
|
value: selected[key]!.contains(option['value']),
|
||||||
|
onChanged: (bool? value) {
|
||||||
|
setState(() {
|
||||||
|
if (value == true) {
|
||||||
|
if (!selected[key]!.contains(option['value'])) {
|
||||||
|
selected[key]!.add(option['value']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selected[key]!.remove(option['value']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
activeColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
checkColor: FlutterFlowTheme.of(context).info,
|
||||||
|
checkboxShape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
enableFeedback: true,
|
||||||
|
side: BorderSide(
|
||||||
|
width: 10,
|
||||||
|
color: FlutterFlowTheme.of(context).secondaryText,
|
||||||
|
),
|
||||||
|
controlAffinity:
|
||||||
|
ListTileControlAffinity.leading, // Adiciona esta linha
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateSelection(String? value, String key) {
|
||||||
|
setState(() {
|
||||||
|
if (value == '.') {
|
||||||
|
selected[key] = [];
|
||||||
|
} else if (value != null) {
|
||||||
|
if (selected[key]!.contains(value)) {
|
||||||
|
selected[key]!.remove(value);
|
||||||
|
} else {
|
||||||
|
selected[key]!.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
child: Align(
|
||||||
|
alignment: const AlignmentDirectional(1.0, -1.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 50.0, 50.0, 0.0),
|
||||||
|
child: Container(
|
||||||
|
width: 300.0,
|
||||||
|
height: 450.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
10.0, 10.0, 0.0, 10.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context)
|
||||||
|
.getText('yfj9pd6k'), // Filtros
|
||||||
|
style: FlutterFlowTheme.of(context)
|
||||||
|
.headlineMedium
|
||||||
|
.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
|
.headlineMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 16.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.headlineMediumFamily),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
8.0, 0.0, 8.0, 0.0),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _model.textController,
|
||||||
|
focusNode: _model.textFieldFocusNode,
|
||||||
|
autofocus: false,
|
||||||
|
obscureText: false,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
labelText: FFLocalizations.of(context).getText(
|
||||||
|
'0enrtljz' /* Pesquise aqui..... */,
|
||||||
|
),
|
||||||
|
labelStyle: FlutterFlowTheme.of(context)
|
||||||
|
.labelMedium
|
||||||
|
.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
|
.labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.labelMediumFamily),
|
||||||
|
),
|
||||||
|
hintStyle: FlutterFlowTheme.of(context)
|
||||||
|
.labelMedium
|
||||||
|
.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
|
.labelMediumFamily,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.labelMediumFamily),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).alternate,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: FlutterFlowTheme.of(context).alternate,
|
||||||
|
suffixIcon: const Icon(
|
||||||
|
Icons.search_outlined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
),
|
||||||
|
validator:
|
||||||
|
_model.textControllerValidator.asValidator(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_buildCheckboxListTile(
|
||||||
|
'personType', personTypeOptions),
|
||||||
|
_buildCheckboxListTile(
|
||||||
|
'accessType', accessTypeOptions),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _applyFilter,
|
||||||
|
child:
|
||||||
|
Text(FFLocalizations.of(context).getText('88kshkph')),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: FlutterFlowTheme.of(context).info,
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,9 +101,9 @@ class MenuComponentModel extends FlutterFlowModel<MenuComponentWidget> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future acessHistoryOptAction(BuildContext context) async {
|
Future preferencesSettings(BuildContext context) async {
|
||||||
context.pushNamed(
|
context.pushNamed(
|
||||||
'acessHistoryPage',
|
'preferencesSettings',
|
||||||
extra: <String, dynamic>{
|
extra: <String, dynamic>{
|
||||||
kTransitionInfoKey: const TransitionInfo(
|
kTransitionInfoKey: const TransitionInfo(
|
||||||
hasTransition: true,
|
hasTransition: true,
|
||||||
|
|
|
@ -62,8 +62,8 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
await _model.peopleOnThePropertyAction(context);
|
await _model.peopleOnThePropertyAction(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
acessHistoryOptAction: () async {
|
preferencesSettings: () async {
|
||||||
await _model.acessHistoryOptAction(context);
|
await _model.preferencesSettings(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
liberationHistoryOptAction: () async {
|
liberationHistoryOptAction: () async {
|
||||||
|
@ -98,8 +98,8 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
await _model.peopleOnThePropertyAction(context);
|
await _model.peopleOnThePropertyAction(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
accessHistoryOptAction: () async {
|
preferencesSettings: () async {
|
||||||
await _model.acessHistoryOptAction(context);
|
await _model.preferencesSettings(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
liberationHistoryOptAction: () async {
|
liberationHistoryOptAction: () async {
|
||||||
|
|
|
@ -16,7 +16,7 @@ class MenuListViewComponentWidget extends StatefulWidget {
|
||||||
required this.registerVisitorOptAction,
|
required this.registerVisitorOptAction,
|
||||||
required this.scheduleVisitOptAction,
|
required this.scheduleVisitOptAction,
|
||||||
required this.peopleOnThePropertyOptAction,
|
required this.peopleOnThePropertyOptAction,
|
||||||
required this.acessHistoryOptAction,
|
required this.preferencesSettings,
|
||||||
required this.liberationHistoryOptAction,
|
required this.liberationHistoryOptAction,
|
||||||
required this.accessQRCodeOptAction,
|
required this.accessQRCodeOptAction,
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ class MenuListViewComponentWidget extends StatefulWidget {
|
||||||
final Future Function()? registerVisitorOptAction;
|
final Future Function()? registerVisitorOptAction;
|
||||||
final Future Function()? scheduleVisitOptAction;
|
final Future Function()? scheduleVisitOptAction;
|
||||||
final Future Function()? peopleOnThePropertyOptAction;
|
final Future Function()? peopleOnThePropertyOptAction;
|
||||||
final Future Function()? acessHistoryOptAction;
|
final Future Function()? preferencesSettings;
|
||||||
final Future Function()? liberationHistoryOptAction;
|
final Future Function()? liberationHistoryOptAction;
|
||||||
final Future Function()? accessQRCodeOptAction;
|
final Future Function()? accessQRCodeOptAction;
|
||||||
|
|
||||||
|
@ -876,7 +876,7 @@ Propriedade */
|
||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await widget.acessHistoryOptAction?.call();
|
await widget.preferencesSettings?.call();
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 100.0,
|
width: 100.0,
|
||||||
|
@ -931,7 +931,7 @@ Propriedade */
|
||||||
alignment:
|
alignment:
|
||||||
const AlignmentDirectional(0.0, 0.0),
|
const AlignmentDirectional(0.0, 0.0),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.history_sharp,
|
Icons.settings,
|
||||||
color: FlutterFlowTheme.of(context)
|
color: FlutterFlowTheme.of(context)
|
||||||
.accent1,
|
.accent1,
|
||||||
size: 24.0,
|
size: 24.0,
|
||||||
|
@ -953,8 +953,8 @@ Propriedade */
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
enText: 'Consult\nHistories',
|
enText: 'Preferences\nSystem',
|
||||||
ptText: 'Consultar\nHistóricos',
|
ptText: 'Preferências\ndo Sistema',
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context)
|
style: FlutterFlowTheme.of(context)
|
||||||
.titleLarge
|
.titleLarge
|
||||||
|
@ -979,6 +979,7 @@ Propriedade */
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
].divide(const SizedBox(width: 15.0)),
|
].divide(const SizedBox(width: 15.0)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -18,7 +18,7 @@ class MenuStaggeredViewComponentWidget extends StatefulWidget {
|
||||||
required this.registerVisitorOptAction,
|
required this.registerVisitorOptAction,
|
||||||
required this.scheduleVisitOptAction,
|
required this.scheduleVisitOptAction,
|
||||||
required this.peopleOnThePropertyOptAction,
|
required this.peopleOnThePropertyOptAction,
|
||||||
required this.accessHistoryOptAction,
|
required this.preferencesSettings,
|
||||||
required this.liberationHistoryOptAction,
|
required this.liberationHistoryOptAction,
|
||||||
required this.accessQRCodeOptAction,
|
required this.accessQRCodeOptAction,
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,7 @@ class MenuStaggeredViewComponentWidget extends StatefulWidget {
|
||||||
final Future Function()? registerVisitorOptAction;
|
final Future Function()? registerVisitorOptAction;
|
||||||
final Future Function()? scheduleVisitOptAction;
|
final Future Function()? scheduleVisitOptAction;
|
||||||
final Future Function()? peopleOnThePropertyOptAction;
|
final Future Function()? peopleOnThePropertyOptAction;
|
||||||
final Future Function()? accessHistoryOptAction;
|
final Future Function()? preferencesSettings;
|
||||||
final Future Function()? liberationHistoryOptAction;
|
final Future Function()? liberationHistoryOptAction;
|
||||||
final Future Function()? accessQRCodeOptAction;
|
final Future Function()? accessQRCodeOptAction;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class _MenuStaggeredViewComponentWidgetState
|
||||||
),
|
),
|
||||||
crossAxisSpacing: 10.0,
|
crossAxisSpacing: 10.0,
|
||||||
mainAxisSpacing: 10.0,
|
mainAxisSpacing: 10.0,
|
||||||
itemCount: 7,
|
itemCount: 8,
|
||||||
padding: const EdgeInsets.fromLTRB(
|
padding: const EdgeInsets.fromLTRB(
|
||||||
0,
|
0,
|
||||||
10.0,
|
10.0,
|
||||||
|
@ -900,6 +900,126 @@ Propriedade */
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
() => InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
focusColor: Colors.transparent,
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
onTap: () async {
|
||||||
|
await widget.preferencesSettings?.call();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
blurRadius: 4.0,
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context).customColor5,
|
||||||
|
offset: const Offset(
|
||||||
|
0.0,
|
||||||
|
2.0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
border: Border.all(
|
||||||
|
color: FlutterFlowTheme.of(context).alternate,
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment:
|
||||||
|
const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: const AlignmentDirectional(
|
||||||
|
-1.0, 0.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional
|
||||||
|
.fromSTEB(8.0, 0.0, 0.0, 0.0),
|
||||||
|
child: Container(
|
||||||
|
width: 30.0,
|
||||||
|
height: 30.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.primaryBackground,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
alignment:
|
||||||
|
const AlignmentDirectional(
|
||||||
|
0.0, 0.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.history_sharp,
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.accent1,
|
||||||
|
size: 24.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment:
|
||||||
|
const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: const AlignmentDirectional(
|
||||||
|
0.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context)
|
||||||
|
.getVariableText(
|
||||||
|
enText: 'Preferences\nSettings',
|
||||||
|
ptText: 'Preferências\ndo Sistema',
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context)
|
||||||
|
.titleLarge
|
||||||
|
.override(
|
||||||
|
fontFamily: 'Nunito',
|
||||||
|
color:
|
||||||
|
FlutterFlowTheme.of(context)
|
||||||
|
.primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts:
|
||||||
|
GoogleFonts.asMap()
|
||||||
|
.containsKey('Nunito'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
].divide(const SizedBox(height: 0.0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
][index]();
|
][index]();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:collection';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:f_r_e_hub/app_state.dart';
|
import 'package:f_r_e_hub/app_state.dart';
|
||||||
import 'package:f_r_e_hub/backend/api_requests/api_calls.dart';
|
import 'package:f_r_e_hub/backend/api_requests/api_calls.dart';
|
||||||
import 'package:f_r_e_hub/flutter_flow/flutter_flow_theme.dart';
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
import 'package:f_r_e_hub/flutter_flow/internationalization.dart';
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_util.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
|
final dropdown = BehaviorSubject<LinkedHashMap<String, String>>.seeded(
|
||||||
|
LinkedHashMap.from({
|
||||||
|
'All': 'A',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
class MessageWellComponentWidget extends StatefulWidget {
|
class MessageWellComponentWidget extends StatefulWidget {
|
||||||
const MessageWellComponentWidget({super.key});
|
const MessageWellComponentWidget({super.key});
|
||||||
|
@ -19,29 +28,29 @@ class MessageWellComponentWidget extends StatefulWidget {
|
||||||
|
|
||||||
class _MessageWellComponentWidgetState
|
class _MessageWellComponentWidgetState
|
||||||
extends State<MessageWellComponentWidget> {
|
extends State<MessageWellComponentWidget> {
|
||||||
late ScrollController _listViewController;
|
StreamSubscription? _dropdownSubscription;
|
||||||
late VoidCallback _scrollListener;
|
|
||||||
final dropdownValueNotifier = ValueNotifier<String>('All');
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_listViewController = ScrollController();
|
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||||
_scrollListener = MessageWellNotifier()._scrollListener;
|
context.read<MessageWellNotifier>().fetchMessages();
|
||||||
_listViewController.addListener(_scrollListener);
|
});
|
||||||
|
|
||||||
|
_dropdownSubscription = dropdown.stream.listen((_) {
|
||||||
|
context.read<MessageWellNotifier>().fetchMessages();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_listViewController.dispose();
|
_dropdownSubscription?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final state = context.watch<MessageWellNotifier>();
|
final messages = context.read<MessageWellNotifier>().getMessages();
|
||||||
final messages = state.getMessages();
|
|
||||||
final theme = FlutterFlowTheme.of(context);
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
@ -50,21 +59,17 @@ class _MessageWellComponentWidgetState
|
||||||
height: MediaQuery.of(context).size.height * 0.8,
|
height: MediaQuery.of(context).size.height * 0.8,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildHandleMessageWell(context, theme),
|
_buildHandleMessageWell(context, FlutterFlowTheme.of(context)),
|
||||||
_buildMenuMessageWell(context, theme, dropdownValueNotifier),
|
_buildMenuMessageWell(context, FlutterFlowTheme.of(context)),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NotificationListener<ScrollNotification>(
|
child: ListView.builder(
|
||||||
onNotification: _buildScrollMessageListManager,
|
itemCount: messages.length,
|
||||||
child: ListView.builder(
|
shrinkWrap: true,
|
||||||
controller: _listViewController,
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
itemCount: messages.length,
|
itemBuilder: (context, index) {
|
||||||
shrinkWrap: true,
|
var message = messages[index];
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
return _buildMessageItem(context, message, index);
|
||||||
itemBuilder: (context, index) {
|
},
|
||||||
var message = messages[index];
|
|
||||||
return _buildMessageItem(context, message, index);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -74,44 +79,61 @@ class _MessageWellComponentWidgetState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _buildScrollMessageListManager(ScrollNotification notification) {
|
|
||||||
final notifier = context.read<MessageWellNotifier>();
|
|
||||||
if (notification is ScrollUpdateNotification) {
|
|
||||||
log('Scrolling ...');
|
|
||||||
if (_listViewController.offset <= 0 && notification.scrollDelta! < 0) {
|
|
||||||
log('Scrolling up ...');
|
|
||||||
setState(() {});
|
|
||||||
} else {
|
|
||||||
log('Scrolling down ...');
|
|
||||||
if (_listViewController.position.extentAfter == 0) {
|
|
||||||
log('Reached end of list. Incrementing pageNumber...');
|
|
||||||
notifier.incrementPageNumber();
|
|
||||||
}
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMenuMessageWell(BuildContext context, FlutterFlowTheme theme,
|
|
||||||
ValueNotifier<String> dropdownValueNotifier) {
|
|
||||||
final locations = FFLocalizations.of(context);
|
|
||||||
final all = locations.getVariableText(enText: 'All', ptText: 'All');
|
|
||||||
final personal =
|
|
||||||
locations.getVariableText(enText: 'Personal', ptText: 'Pessoal');
|
|
||||||
final global = locations.getVariableText(enText: 'Global', ptText: 'Global');
|
|
||||||
|
|
||||||
|
Widget _buildMenuMessageWell(BuildContext context, FlutterFlowTheme theme) {
|
||||||
|
final dropdownItems = LinkedHashMap.from({
|
||||||
|
'All': 'A',
|
||||||
|
'Personal': 'O',
|
||||||
|
'Global': 'C',
|
||||||
|
});
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
key: UniqueKey(),
|
key: UniqueKey(),
|
||||||
width: 200,
|
width: 200,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: ValueListenableBuilder<String>(
|
child: StreamBuilder<String>(
|
||||||
valueListenable: dropdownValueNotifier,
|
stream: dropdown.stream.map((event) => event.keys.first),
|
||||||
builder: (context, value, child) {
|
builder: (context, snapshot) {
|
||||||
|
final value = snapshot.data;
|
||||||
return DropdownButtonFormField<String>(
|
return DropdownButtonFormField<String>(
|
||||||
value: value,
|
value: value,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10.0),
|
isDense: true,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: theme.error,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: theme.primary,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: theme.primary,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
disabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: theme.primary,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: theme.error,
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: theme.primary,
|
color: theme.primary,
|
||||||
|
@ -123,20 +145,16 @@ class _MessageWellComponentWidgetState
|
||||||
fillColor: theme.primary,
|
fillColor: theme.primary,
|
||||||
),
|
),
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
if (newValue != null) {
|
safeSetState(() => dropdown.value = LinkedHashMap.from({newValue!: dropdownItems[newValue].toString()}));
|
||||||
dropdownValueNotifier.value = newValue;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
items: [
|
items: dropdownItems.entries
|
||||||
DropdownMenuItem<String>(value: all, child: Text(all)),
|
.map((entry) => DropdownMenuItem<String>(
|
||||||
DropdownMenuItem<String>(value: personal, child: Text(personal)),
|
value: entry.key,
|
||||||
DropdownMenuItem<String>(value: global, child: Text(global)),
|
child: Text(entry.key),
|
||||||
],
|
))
|
||||||
style: theme.labelMedium.override(
|
.toList(),
|
||||||
fontFamily: theme.labelMediumFamily,
|
style: theme.bodyMedium.copyWith(
|
||||||
color: theme.primaryText,
|
color: theme.primaryText,
|
||||||
useGoogleFonts:
|
|
||||||
GoogleFonts.asMap().containsKey(theme.labelMediumFamily),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -144,21 +162,22 @@ class _MessageWellComponentWidgetState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Text _buildHandleMessageWell(
|
Text _buildHandleMessageWell(BuildContext context, FlutterFlowTheme theme) {
|
||||||
BuildContext context, FlutterFlowTheme theme) {
|
|
||||||
return Text(
|
return Text(
|
||||||
FFLocalizations.of(context).getText('8fworxmb'),
|
FFLocalizations.of(context).getVariableText(
|
||||||
style: theme.bodyMedium.override(
|
ptText: 'Mural de Mensagens',
|
||||||
|
enText: 'Message Wall',
|
||||||
|
),
|
||||||
|
style: theme.bodyMedium.copyWith(
|
||||||
fontFamily: 'Nunito Sans',
|
fontFamily: 'Nunito Sans',
|
||||||
letterSpacing: 0.0,
|
letterSpacing: 0.0,
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito Sans'),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMessageItem(
|
Widget _buildMessageItem(
|
||||||
BuildContext context, dynamic message, int index) {
|
BuildContext context, dynamic message, int index) {
|
||||||
final theme = Theme.of(context);
|
final theme = FlutterFlowTheme.of(context);
|
||||||
String formatMessageOrigin(String messageOrigin) {
|
String formatMessageOrigin(String messageOrigin) {
|
||||||
final words = messageOrigin.split(' ');
|
final words = messageOrigin.split(' ');
|
||||||
final formattedWords = words.map((word) {
|
final formattedWords = words.map((word) {
|
||||||
|
@ -168,17 +187,15 @@ class _MessageWellComponentWidgetState
|
||||||
});
|
});
|
||||||
return formattedWords.join(' ');
|
return formattedWords.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () =>
|
onTap: () => {},
|
||||||
log('Message tapped ...\nmessage[$index]: $message'),
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
|
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.9,
|
width: MediaQuery.of(context).size.width * 0.9,
|
||||||
height: 127.0,
|
height: 127.0,
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
@ -201,9 +218,9 @@ class _MessageWellComponentWidgetState
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}',
|
'~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}',
|
||||||
style: theme.textTheme.headlineMedium!.copyWith(
|
style: theme.bodyMedium.copyWith(
|
||||||
fontFamily: 'Nunito Sans',
|
fontFamily: 'Nunito Sans',
|
||||||
color: FlutterFlowTheme.of(context).primary,
|
color: theme.primary,
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
|
@ -215,9 +232,9 @@ class _MessageWellComponentWidgetState
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: Text(
|
child: Text(
|
||||||
formatMessageOrigin(message['MSG_TEXTO'].toString()),
|
formatMessageOrigin(message['MSG_TEXTO'].toString()),
|
||||||
style: theme.textTheme.bodyMedium!.copyWith(
|
style: theme.bodyMedium.copyWith(
|
||||||
fontFamily: 'Nunito Sans',
|
fontFamily: 'Nunito Sans',
|
||||||
color: FlutterFlowTheme.of(context).primaryText,
|
color: theme.bodyMedium.color,
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
),
|
),
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
|
@ -234,26 +251,25 @@ class _MessageWellComponentWidgetState
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MessageWellState {
|
class MessageWellState {
|
||||||
final List<dynamic> messages;
|
final List<dynamic> messages;
|
||||||
int pageNumber;
|
int pageNumber;
|
||||||
final bool allowScrollInSingleChildScrollView;
|
final bool allowScrollInSingleChildScrollView;
|
||||||
final ScrollController listViewController;
|
|
||||||
|
|
||||||
MessageWellState({
|
MessageWellState({
|
||||||
required this.messages,
|
required this.messages,
|
||||||
this.pageNumber = 1,
|
this.pageNumber = 1,
|
||||||
required this.allowScrollInSingleChildScrollView,
|
required this.allowScrollInSingleChildScrollView,
|
||||||
required this.listViewController,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
MessageWellState copyWith({
|
MessageWellState copyWith({
|
||||||
List<dynamic>? messages,
|
List<dynamic>? messages,
|
||||||
int? pageNumber,
|
int? pageNumber,
|
||||||
bool? allowScrollInSingleChildScrollView,
|
bool? allowScrollInSingleChildScrollView,
|
||||||
ScrollController? listViewController,
|
|
||||||
}) {
|
}) {
|
||||||
return MessageWellState(
|
return MessageWellState(
|
||||||
messages: messages ?? this.messages,
|
messages: messages ?? this.messages,
|
||||||
|
@ -261,7 +277,6 @@ class MessageWellState {
|
||||||
allowScrollInSingleChildScrollView:
|
allowScrollInSingleChildScrollView:
|
||||||
allowScrollInSingleChildScrollView ??
|
allowScrollInSingleChildScrollView ??
|
||||||
this.allowScrollInSingleChildScrollView,
|
this.allowScrollInSingleChildScrollView,
|
||||||
listViewController: listViewController ?? this.listViewController,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,17 +289,15 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
||||||
_totalPageNumber = value;
|
_totalPageNumber = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MessageWellNotifier()
|
MessageWellNotifier()
|
||||||
: super(MessageWellState(
|
: super(MessageWellState(
|
||||||
messages: [],
|
messages: [],
|
||||||
allowScrollInSingleChildScrollView: true,
|
allowScrollInSingleChildScrollView: true,
|
||||||
listViewController: ScrollController())) {
|
)) {
|
||||||
state.listViewController.addListener(_scrollListener);
|
|
||||||
fetchMessages();
|
fetchMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchMessages() async {
|
void fetchMessages() async {
|
||||||
if (state.pageNumber <= totalPageNumber) {
|
if (state.pageNumber <= totalPageNumber) {
|
||||||
var apiCall = GetMessagesCall();
|
var apiCall = GetMessagesCall();
|
||||||
var response = await apiCall.call(
|
var response = await apiCall.call(
|
||||||
|
@ -292,28 +305,20 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
||||||
userUUID: FFAppState().userUUID.toString(),
|
userUUID: FFAppState().userUUID.toString(),
|
||||||
cliID: FFAppState().cliUUID.toString(),
|
cliID: FFAppState().cliUUID.toString(),
|
||||||
atividade: 'getMensagens',
|
atividade: 'getMensagens',
|
||||||
pageSize: '10',
|
pageSize: '100',
|
||||||
pageNumber: state.pageNumber.toString(),
|
pageNumber: state.pageNumber.toString(),
|
||||||
tipoDestino: 'A',
|
tipoDestino: dropdown.value.values.first,
|
||||||
);
|
);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
var messagesData = response.jsonBody['mensagens'];
|
var messagesData = response.jsonBody['mensagens'];
|
||||||
log('inputs: ${FFAppState().devUUID}, ${FFAppState().userUUID}, ${FFAppState().cliUUID}');
|
|
||||||
log('response: ${response.jsonBody}');
|
|
||||||
log('response[mensagens]: $messagesData');
|
|
||||||
log('response[mensagens][0][MSG_TEXTO]: ${messagesData[0]['MSG_TEXTO']}');
|
|
||||||
var newMessages = [...state.messages, ...messagesData];
|
var newMessages = [...state.messages, ...messagesData];
|
||||||
var rExp = RegExp(r'\d+')
|
|
||||||
.allMatches(newMessages.toString())
|
|
||||||
.map((e) => e.group(0))
|
|
||||||
.toList();
|
|
||||||
log('rExp: $rExp');
|
|
||||||
log('newMessages: $newMessages');
|
|
||||||
state = state.copyWith(messages: newMessages);
|
state = state.copyWith(messages: newMessages);
|
||||||
log('total_pages :> ${response.jsonBody['total_pages']}');
|
// var rExp = RegExp(r'\d+')
|
||||||
|
// .allMatches(newMessages.toString())
|
||||||
|
// .map((e) => e.group(0))
|
||||||
|
// .toList();
|
||||||
// Provider.of<MessageCounter>(context, listen: false).setCounter(int.parse(response.jsonBody['total_pages']));
|
// Provider.of<MessageCounter>(context, listen: false).setCounter(int.parse(response.jsonBody['total_pages']));
|
||||||
totalPageNumber = int.parse(response.jsonBody['total_pages']);
|
// totalPageNumber = int.parse(response.jsonBody['total_pages']);
|
||||||
log('totalPageNumber: $totalPageNumber');
|
|
||||||
} else {
|
} else {
|
||||||
log('Error fetching messages: ${response.statusCode}');
|
log('Error fetching messages: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
|
@ -325,29 +330,9 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
||||||
List<dynamic> getMessages() {
|
List<dynamic> getMessages() {
|
||||||
return state.messages;
|
return state.messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _scrollListener() {
|
|
||||||
if (!state.allowScrollInSingleChildScrollView) {
|
|
||||||
if (state.pageNumber <= totalPageNumber) {
|
|
||||||
state = state.copyWith(pageNumber: state.pageNumber + 1);
|
|
||||||
log('state.pageNumber: ${state.pageNumber}');
|
|
||||||
fetchMessages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
state.listViewController.removeListener(_scrollListener);
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void incrementPageNumber() {
|
void incrementPageNumber() {
|
||||||
log('state.pageNumber: ${state.pageNumber}');
|
|
||||||
log('total_pages :>: $totalPageNumber');
|
|
||||||
if (state.pageNumber <= totalPageNumber) {
|
if (state.pageNumber <= totalPageNumber) {
|
||||||
state = state.copyWith(pageNumber: state.pageNumber + 1);
|
state = state.copyWith(pageNumber: state.pageNumber + 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'change_pass_widget.dart'
|
||||||
|
show PassKeyTemplateWidget;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PassKeyTemplateComponentModel
|
||||||
|
extends FlutterFlowModel<PassKeyTemplateWidget> {
|
||||||
|
/// State fields for stateful widgets in this component.
|
||||||
|
|
||||||
|
final formKey = GlobalKey<FormState>();
|
||||||
|
// State field(s) for keyTextField widget.
|
||||||
|
FocusNode? keyTextFieldFocusNode1;
|
||||||
|
FocusNode? keyTextFieldFocusNode2;
|
||||||
|
TextEditingController? keyTextFieldTextController1;
|
||||||
|
TextEditingController? keyTextFieldTextController2;
|
||||||
|
late bool keyTextFieldVisibility1;
|
||||||
|
late bool keyTextFieldVisibility2;
|
||||||
|
String? Function(BuildContext, String?)? keyTextFieldTextControllerValidator1;
|
||||||
|
String? Function(BuildContext, String?)? keyTextFieldTextControllerValidator2;
|
||||||
|
String? _keyTextFieldTextControllerValidator(
|
||||||
|
BuildContext context, String? val) {
|
||||||
|
if (val == null || val.isEmpty) {
|
||||||
|
return FFLocalizations.of(context).getText(
|
||||||
|
'f128ajey' /* Field is required */,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState(BuildContext context) {
|
||||||
|
keyTextFieldVisibility1 = false;
|
||||||
|
keyTextFieldVisibility2 = false;
|
||||||
|
keyTextFieldTextControllerValidator1 = _keyTextFieldTextControllerValidator;
|
||||||
|
keyTextFieldTextControllerValidator2 = _keyTextFieldTextControllerValidator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
keyTextFieldFocusNode1?.dispose();
|
||||||
|
keyTextFieldFocusNode2?.dispose();
|
||||||
|
keyTextFieldTextController1?.dispose();
|
||||||
|
keyTextFieldTextController2?.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,458 @@
|
||||||
|
import '/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import '/flutter_flow/flutter_flow_widgets.dart';
|
||||||
|
import 'package:easy_debounce/easy_debounce.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'change_pass_model.dart';
|
||||||
|
export 'change_pass_model.dart';
|
||||||
|
|
||||||
|
class PassKeyTemplateWidget extends StatefulWidget {
|
||||||
|
const PassKeyTemplateWidget({
|
||||||
|
super.key,
|
||||||
|
required this.toggleActionStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Future Function(String key)? toggleActionStatus;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PassKeyTemplateWidget> createState() =>
|
||||||
|
_PassKeyTemplateWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PassKeyTemplateWidgetState
|
||||||
|
extends State<PassKeyTemplateWidget> {
|
||||||
|
late PassKeyTemplateComponentModel _model;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setState(VoidCallback callback) {
|
||||||
|
super.setState(callback);
|
||||||
|
_model.onUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_model = createModel(context, () => PassKeyTemplateComponentModel());
|
||||||
|
|
||||||
|
_model.keyTextFieldTextController1 ??= TextEditingController();
|
||||||
|
_model.keyTextFieldFocusNode1 ??= FocusNode();
|
||||||
|
_model.keyTextFieldFocusNode1!.addListener(() => setState(() {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_model.maybeDispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 1.0),
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 400.0,
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 570.0,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(0.0),
|
||||||
|
bottomRight: Radius.circular(0.0),
|
||||||
|
topLeft: Radius.circular(15.0),
|
||||||
|
topRight: Radius.circular(15.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// This row exists for when the "app bar" is hidden on desktop, having a way back for the user can work well.
|
||||||
|
if (responsiveVisibility(
|
||||||
|
context: context,
|
||||||
|
phone: false,
|
||||||
|
tablet: false,
|
||||||
|
))
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 16.0, 8.0),
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
focusColor: Colors.transparent,
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
onTap: () async {
|
||||||
|
context.safePop();
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsetsDirectional.fromSTEB(
|
||||||
|
0.0, 12.0, 0.0, 12.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.arrow_back_rounded,
|
||||||
|
color: Color(0xFF15161E),
|
||||||
|
size: 24.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(12.0, 0.0, 0.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
'',
|
||||||
|
style:
|
||||||
|
FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: const Color(0xFF15161E),
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 0.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: FFAppState().accessPass != '' ? 'CHANGE PASSWORD' : 'INSERT PASSWORD',
|
||||||
|
ptText: FFAppState().accessPass != '' ? 'ALTERAR SENHA' : 'ADICIONAR SENHA',
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||||
|
fontFamily: 'Outfit',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 24.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey('Outfit'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 4.0, 16.0, 4.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Enter your password to continue',
|
||||||
|
ptText: 'Digite sua senha para continuar'
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts:
|
||||||
|
GoogleFonts.asMap().containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Form(
|
||||||
|
key: _model.formKey,
|
||||||
|
autovalidateMode: AutovalidateMode.always,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
if (FFAppState().accessPass.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 12.0, 16.0, 0.0),
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _model.keyTextFieldTextController1,
|
||||||
|
|
||||||
|
focusNode: _model.keyTextFieldFocusNode1,
|
||||||
|
onChanged: (_) => EasyDebounce.debounce(
|
||||||
|
'_model.keyTextFieldTextController',
|
||||||
|
const Duration(milliseconds: 2000),
|
||||||
|
() => setState(() {}),
|
||||||
|
),
|
||||||
|
autofillHints: const [AutofillHints.password],
|
||||||
|
textCapitalization: TextCapitalization.none,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
obscureText: !_model.keyTextFieldVisibility1,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Senha Antiga',
|
||||||
|
enText: 'Old Password',
|
||||||
|
),
|
||||||
|
labelStyle:
|
||||||
|
FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
hintText: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Digite a sua senha antiga.....',
|
||||||
|
enText: 'Enter your old password.....',
|
||||||
|
),
|
||||||
|
hintStyle:
|
||||||
|
FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).accent3,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
contentPadding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
24.0, 24.0, 20.0, 24.0),
|
||||||
|
suffixIcon: InkWell(
|
||||||
|
onTap: () => setState(
|
||||||
|
() => _model.keyTextFieldVisibility1 =
|
||||||
|
!_model.keyTextFieldVisibility1,
|
||||||
|
),
|
||||||
|
focusNode: FocusNode(skipTraversal: true),
|
||||||
|
child: Icon(
|
||||||
|
_model.keyTextFieldVisibility1
|
||||||
|
? Icons.visibility_outlined
|
||||||
|
: Icons.visibility_off_outlined,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
size: 22.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
maxLength: 4,
|
||||||
|
maxLengthEnforcement: MaxLengthEnforcement.none,
|
||||||
|
buildCounter: (context,
|
||||||
|
{required currentLength,
|
||||||
|
required isFocused,
|
||||||
|
maxLength}) =>
|
||||||
|
null,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
cursorColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
validator: _model.keyTextFieldTextControllerValidator1
|
||||||
|
.asValidator(context),
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.allow(RegExp('[0-9]'))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 12.0, 16.0, 0.0),
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _model.keyTextFieldTextController2,
|
||||||
|
|
||||||
|
focusNode: _model.keyTextFieldFocusNode2,
|
||||||
|
onChanged: (_) => EasyDebounce.debounce(
|
||||||
|
'_model.keyTextFieldTextController',
|
||||||
|
const Duration(milliseconds: 2000),
|
||||||
|
() => setState(() {}),
|
||||||
|
),
|
||||||
|
autofillHints: const [AutofillHints.password],
|
||||||
|
textCapitalization: TextCapitalization.none,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
obscureText: !_model.keyTextFieldVisibility2,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: FFAppState().accessPass != '' ? 'Nova Senha' : 'Senha',
|
||||||
|
enText: FFAppState().accessPass != '' ? 'New Password' : 'Password',
|
||||||
|
),
|
||||||
|
labelStyle:
|
||||||
|
FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
hintText: FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: FFAppState().accessPass != null ? 'Enter your new password.....' : 'Enter your password.....',
|
||||||
|
ptText: FFAppState().accessPass != null ? 'Digite a sua nova senha.....' : 'Digite a sua senha.....',
|
||||||
|
),
|
||||||
|
hintStyle:
|
||||||
|
FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).accent3,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: FlutterFlowTheme.of(context).error,
|
||||||
|
width: 2.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
contentPadding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
24.0, 24.0, 20.0, 24.0),
|
||||||
|
suffixIcon: InkWell(
|
||||||
|
onTap: () => setState(
|
||||||
|
() => _model.keyTextFieldVisibility1 =
|
||||||
|
!_model.keyTextFieldVisibility1,
|
||||||
|
),
|
||||||
|
focusNode: FocusNode(skipTraversal: true),
|
||||||
|
child: Icon(
|
||||||
|
_model.keyTextFieldVisibility1
|
||||||
|
? Icons.visibility_outlined
|
||||||
|
: Icons.visibility_off_outlined,
|
||||||
|
color: FlutterFlowTheme.of(context).accent1,
|
||||||
|
size: 22.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
maxLength: 4,
|
||||||
|
maxLengthEnforcement: MaxLengthEnforcement.none,
|
||||||
|
buildCounter: (context,
|
||||||
|
{required currentLength,
|
||||||
|
required isFocused,
|
||||||
|
maxLength}) =>
|
||||||
|
null,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
cursorColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
validator: _model.keyTextFieldTextControllerValidator2
|
||||||
|
.asValidator(context),
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.allow(RegExp('[0-9]'))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 24.0, 0.0, 0.0),
|
||||||
|
child: FFButtonWidget(
|
||||||
|
onPressed: () async {
|
||||||
|
if (_model.formKey.currentState == null ||
|
||||||
|
!_model.formKey.currentState!.validate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await widget.toggleActionStatus?.call(
|
||||||
|
_model.keyTextFieldTextController1.text.isEmpty ? _model.keyTextFieldTextController2.text : _model.keyTextFieldTextController1.text,
|
||||||
|
);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: FFAppState().accessPass != '' ? 'Alterar' : 'Adicionar',
|
||||||
|
enText: FFAppState().accessPass != '' ? 'Change' : 'Add',
|
||||||
|
),
|
||||||
|
options: FFButtonOptions(
|
||||||
|
width: 270.0,
|
||||||
|
height: 50.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: const Color(0xFF1AAB5F),
|
||||||
|
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
|
||||||
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey('Plus Jakarta Sans'),
|
||||||
|
),
|
||||||
|
elevation: 3.0,
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.transparent,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
showLoadingIndicator: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import '/flutter_flow/flutter_flow_theme.dart';
|
||||||
import '/flutter_flow/flutter_flow_util.dart';
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
import '/actions/actions.dart' as action_blocks;
|
import '/actions/actions.dart' as action_blocks;
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
@ -862,6 +863,11 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
log('IconButton pressed ...');
|
log('IconButton pressed ...');
|
||||||
|
// Implement share functionality here
|
||||||
|
Share.share(
|
||||||
|
'Visita agendada para ${widget.visitStartDate} com término previsto para ${widget.visitEndDate}. Motivo: ${widget.visitReasonStr}. Nível de acesso: ${widget.visitLevelStr}. Observações: ${widget.visitObsStr}.',
|
||||||
|
);
|
||||||
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:f_r_e_hub/pages/fast_pass_page/fast_pass_page_widget.dart';
|
import 'package:f_r_e_hub/pages/fast_pass_page/fast_pass_page_widget.dart';
|
||||||
import 'package:f_r_e_hub/pages/message_history_page/message_history_page_widget.dart';
|
import 'package:f_r_e_hub/pages/message_history_page/message_history_page_widget.dart';
|
||||||
|
import 'package:f_r_e_hub/pages/preferences_settings_page/preferences_settings_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -78,7 +79,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
||||||
path: '/visitHistoryPage',
|
path: '/visitHistoryPage',
|
||||||
builder: (context, params) => const VisitHistoryPageWidget(),
|
builder: (context, params) => const VisitHistoryPageWidget(),
|
||||||
),
|
),
|
||||||
FFRoute(name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => const MessageHistoryPageWidget()),
|
FFRoute(
|
||||||
|
name: 'messageHistoryPage',
|
||||||
|
path: '/messageHistoryPage',
|
||||||
|
builder: (context, params) => const MessageHistoryPageWidget()),
|
||||||
FFRoute(
|
FFRoute(
|
||||||
name: 'registerVisitorPage',
|
name: 'registerVisitorPage',
|
||||||
path: '/registerVisitorPage',
|
path: '/registerVisitorPage',
|
||||||
|
@ -138,6 +142,9 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
||||||
path: '/fastPassPage',
|
path: '/fastPassPage',
|
||||||
builder: (context, params) => /*const*/ FastPassPageWidget(),
|
builder: (context, params) => /*const*/ FastPassPageWidget(),
|
||||||
),
|
),
|
||||||
|
FFRoute(name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => const PreferencesPageWidget(
|
||||||
|
key: Key('preferencesSettings'),
|
||||||
|
)),
|
||||||
FFRoute(
|
FFRoute(
|
||||||
name: 'peopleOnThePropertyPage',
|
name: 'peopleOnThePropertyPage',
|
||||||
path: '/peopleOnThePropertyPage',
|
path: '/peopleOnThePropertyPage',
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
const kPermissionStateToBool = {
|
||||||
|
PermissionStatus.granted: true,
|
||||||
|
PermissionStatus.limited: true,
|
||||||
|
PermissionStatus.denied: false,
|
||||||
|
PermissionStatus.restricted: false,
|
||||||
|
PermissionStatus.permanentlyDenied: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Future<bool> getPermissionStatus(Permission setting) async {
|
||||||
|
final status = await setting.status;
|
||||||
|
return kPermissionStateToBool[status]!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> requestPermission(Permission setting) async =>
|
||||||
|
await setting.request();
|
|
@ -1,10 +1,3 @@
|
||||||
// import 'package:f_r_e_hub/backend/api_requests/api_calls.dart';
|
|
||||||
// import 'package:f_r_e_hub/backend/push_notification/pushNotificationService.dart';
|
|
||||||
// import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart';
|
|
||||||
// import 'package:firebase_messaging/firebase_messaging.dart';
|
|
||||||
// import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
||||||
// import 'package:firebase_analytics/firebase_analytics.dart';
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
|
@ -75,6 +75,7 @@ PreferredSizeWidget appBarLiberationHistoryPage(BuildContext context) {
|
||||||
return AppBar(
|
return AppBar(
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
leading: FlutterFlowIconButton(
|
leading: FlutterFlowIconButton(
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
borderRadius: 30.0,
|
borderRadius: 30.0,
|
||||||
|
@ -103,6 +104,7 @@ PreferredSizeWidget appBarLiberationHistoryPage(BuildContext context) {
|
||||||
),
|
),
|
||||||
actions: const [],
|
actions: const [],
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
|
elevation: 0.0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
leading: FlutterFlowIconButton(
|
leading: FlutterFlowIconButton(
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
borderRadius: 30.0,
|
borderRadius: 30.0,
|
||||||
|
@ -106,7 +107,6 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final columnGetPessoasLocalResponse = snapshot.data!;
|
final columnGetPessoasLocalResponse = snapshot.data!;
|
||||||
|
|
||||||
return Builder(
|
return Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final getPoepleProperty = PhpGroup.getPessoasLocalCall
|
final getPoepleProperty = PhpGroup.getPessoasLocalCall
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
|
||||||
|
import 'package:f_r_e_hub/backend/api_requests/api_calls.dart';
|
||||||
|
import 'package:f_r_e_hub/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart';
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:local_auth/local_auth.dart';
|
||||||
|
|
||||||
|
class PreferencesPageModel with ChangeNotifier {
|
||||||
|
final unfocusNode = FocusNode();
|
||||||
|
|
||||||
|
final LocalAuthentication auth = LocalAuthentication();
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> toggleFingerprint() async {
|
||||||
|
|
||||||
|
FFAppState().checkBiometrics().then((value) => FFAppState().authenticateBiometric().then( (value) => FFAppState().fingerprint = !FFAppState().fingerprint).whenComplete(() => notifyListeners()));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void enablePerson(BuildContext context) {
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(FFAppState().userDevUUID, style: TextStyle(color: FlutterFlowTheme.of(context).info) ),
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
duration: const Duration(seconds: 1),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleNotify() {
|
||||||
|
FFAppState().notify = !FFAppState().notify;
|
||||||
|
PhpGroup.changeNotifica.call(
|
||||||
|
userUUID: FFAppState().userUUID,
|
||||||
|
devUUID: FFAppState().devUUID,
|
||||||
|
cliID: FFAppState().cliUUID,
|
||||||
|
atividade: 'updVisitado',
|
||||||
|
notifica: FFAppState().notify ? 'S' : 'N',
|
||||||
|
);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void localLogout(){
|
||||||
|
PhpGroup.resopndeVinculo.call(
|
||||||
|
userUUID: FFAppState().userUUID,
|
||||||
|
devUUID: FFAppState().devUUID,
|
||||||
|
cliID: FFAppState().cliUUID,
|
||||||
|
tarefa: 'I',
|
||||||
|
);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteAccount(BuildContext context) {
|
||||||
|
FFAppState().deleteAll();
|
||||||
|
FFAppState().isLogged = false;
|
||||||
|
context.goNamed(
|
||||||
|
'welcomePage',
|
||||||
|
extra: <String, dynamic>{
|
||||||
|
kTransitionInfoKey: const TransitionInfo(
|
||||||
|
hasTransition: true,
|
||||||
|
transitionType: PageTransitionType.scale,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> togglePass(BuildContext context) async {
|
||||||
|
FFAppState().pass = true;
|
||||||
|
notifyListeners();
|
||||||
|
await showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
useSafeArea: true,
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return Padding(
|
||||||
|
padding:
|
||||||
|
MediaQuery.viewInsetsOf(context),
|
||||||
|
child:
|
||||||
|
PassKeyTemplateWidget(
|
||||||
|
toggleActionStatus: (key) async {
|
||||||
|
FFAppState().accessPass = key;
|
||||||
|
notifyListeners();
|
||||||
|
debugPrint('key: $key');
|
||||||
|
// PhpGroup.changePass.call(
|
||||||
|
// userUUID: FFAppState().userUUID,
|
||||||
|
// devUUID: FFAppState().devUUID,
|
||||||
|
// cliID: FFAppState().cliUUID,
|
||||||
|
// atividade: 'updVisitado',
|
||||||
|
// newSenha: FFAppState().accessPass,
|
||||||
|
// );
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
FFAppState().pass = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
unfocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import '/flutter_flow/flutter_flow_icon_button.dart';
|
||||||
|
import '/flutter_flow/flutter_flow_theme.dart';
|
||||||
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
|
import 'preferences_settings_model.dart';
|
||||||
|
|
||||||
|
class PreferencesPageWidget extends StatelessWidget {
|
||||||
|
const PreferencesPageWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ChangeNotifierProvider<PreferencesPageModel>(
|
||||||
|
create: (_) => PreferencesPageModel(),
|
||||||
|
child: Consumer<PreferencesPageModel>(
|
||||||
|
builder: (context, model, child) => GestureDetector(
|
||||||
|
onTap: () => model.unfocusNode.canRequestFocus
|
||||||
|
? FocusScope.of(context).requestFocus(model.unfocusNode)
|
||||||
|
: FocusScope.of(context).unfocus(),
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
|
leading: FlutterFlowIconButton(
|
||||||
|
borderColor: Colors.transparent,
|
||||||
|
borderRadius: 30.0,
|
||||||
|
borderWidth: 1.0,
|
||||||
|
buttonSize: 60.0,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.keyboard_arrow_left,
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
size: 30.0,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Preferences',
|
||||||
|
ptText: 'Preferências',
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||||
|
fontFamily: 'Nunito',
|
||||||
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
fontSize: 17.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
elevation: 0.0,
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Container(),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: GridView.builder(
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 3,
|
||||||
|
crossAxisSpacing: 12.0,
|
||||||
|
mainAxisSpacing: 12.0,
|
||||||
|
childAspectRatio: 1.0,
|
||||||
|
mainAxisExtent: 100.0,
|
||||||
|
),
|
||||||
|
itemCount: 6, // Assuming 4 items for simplicity
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return _buildIconButton(context, index, model);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildIconButton(BuildContext context, int index, PreferencesPageModel model) {
|
||||||
|
IconData icon;
|
||||||
|
Function() onPressed =() => {};
|
||||||
|
bool isEnabled;
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
icon = Icons.fingerprint;
|
||||||
|
onPressed = model.toggleFingerprint; // Desabilita se fingerprint for false
|
||||||
|
isEnabled = FFAppState().fingerprint;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
icon = Icons.person;
|
||||||
|
onPressed = () => model.enablePerson(context);
|
||||||
|
isEnabled = FFAppState().person;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
icon = Icons.notifications;
|
||||||
|
onPressed = model.toggleNotify;
|
||||||
|
isEnabled = FFAppState().notify;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
icon = Icons.lock_clock_sharp;
|
||||||
|
// onLongPress = model.togglePass(context, model);
|
||||||
|
isEnabled = FFAppState().pass;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
icon = Icons.landscape;
|
||||||
|
onPressed = model.localLogout;
|
||||||
|
isEnabled = false;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
icon = Icons.delete;
|
||||||
|
onPressed = () => model.deleteAccount(context);
|
||||||
|
isEnabled = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception('Invalid index: $index');
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlutterFlowIconButton(
|
||||||
|
icon: Icon(icon, color: isEnabled ? FlutterFlowTheme.of(context).primaryBackground : FlutterFlowTheme.of(context).primary, size: 40.0),
|
||||||
|
onPressed: index != 3 ? onPressed : () {model.togglePass(context);},
|
||||||
|
borderRadius: 20.0,
|
||||||
|
borderWidth: 1.0,
|
||||||
|
buttonSize: 40.0,
|
||||||
|
fillColor: isEnabled ? FlutterFlowTheme.of(context).primary : FlutterFlowTheme.of(context).alternate,
|
||||||
|
disabledColor: FlutterFlowTheme.of(context).alternate,
|
||||||
|
disabledIconColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,7 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
leading: FlutterFlowIconButton(
|
leading: FlutterFlowIconButton(
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
borderRadius: 30.0,
|
borderRadius: 30.0,
|
||||||
|
|
|
@ -165,6 +165,8 @@ PreferredSizeWidget appBarScheduleCompleteVisit(BuildContext context) {
|
||||||
return AppBar(
|
return AppBar(
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
|
elevation: 0.0,
|
||||||
leading: FlutterFlowIconButton(
|
leading: FlutterFlowIconButton(
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
borderRadius: 30.0,
|
borderRadius: 30.0,
|
||||||
|
|
|
@ -61,6 +61,7 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
|
forceMaterialTransparency: true,
|
||||||
leading: FlutterFlowIconButton(
|
leading: FlutterFlowIconButton(
|
||||||
borderColor: Colors.transparent,
|
borderColor: Colors.transparent,
|
||||||
borderRadius: 30.0,
|
borderRadius: 30.0,
|
||||||
|
|
112
pubspec.lock
112
pubspec.lock
|
@ -821,6 +821,46 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
local_auth:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: local_auth
|
||||||
|
sha256: "280421b416b32de31405b0a25c3bd42dfcef2538dfbb20c03019e02a5ed55ed0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
local_auth_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: local_auth_android
|
||||||
|
sha256: "33fcebe9c3cf1bb0033bc85caed354c1e75ff7f7670918a571bd3152a2b65bf4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.42"
|
||||||
|
local_auth_darwin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: local_auth_darwin
|
||||||
|
sha256: e424ebf90d5233452be146d4a7da4bcd7a70278b67791592f3fde1bda8eef9e2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
|
local_auth_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: local_auth_platform_interface
|
||||||
|
sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.10"
|
||||||
|
local_auth_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: local_auth_windows
|
||||||
|
sha256: "505ba3367ca781efb1c50d3132e44a2446bccc4163427bc203b9b4d8994d97ea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.10"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -973,6 +1013,62 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.2"
|
version: "4.2.2"
|
||||||
|
permission_handler:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: permission_handler
|
||||||
|
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "11.3.1"
|
||||||
|
permission_handler_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_android
|
||||||
|
sha256: b29a799ca03be9f999aa6c39f7de5209482d638e6f857f6b93b0875c618b7e54
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "12.0.7"
|
||||||
|
permission_handler_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_apple
|
||||||
|
sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.4.5"
|
||||||
|
permission_handler_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_html
|
||||||
|
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
|
permission_handler_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_platform_interface
|
||||||
|
sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.1"
|
||||||
|
permission_handler_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_windows
|
||||||
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
|
persistent_bottom_nav_bar:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: persistent_bottom_nav_bar
|
||||||
|
sha256: "6aa9b97ced1abd92c90cedd1997d34ea0b35c3ded762ac6063baccc299b0c4c5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1053,6 +1149,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.7"
|
version: "0.27.7"
|
||||||
|
share_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: share_plus
|
||||||
|
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.0.0"
|
||||||
|
share_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: share_plus_platform_interface
|
||||||
|
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -47,6 +47,7 @@ dependencies:
|
||||||
flutter_animate: 4.5.0
|
flutter_animate: 4.5.0
|
||||||
flutter_cache_manager: 3.3.2
|
flutter_cache_manager: 3.3.2
|
||||||
flutter_plugin_android_lifecycle: 2.0.20
|
flutter_plugin_android_lifecycle: 2.0.20
|
||||||
|
share_plus: ^9.0.0
|
||||||
flutter_secure_storage: 9.2.2
|
flutter_secure_storage: 9.2.2
|
||||||
flutter_secure_storage_linux: 1.2.1
|
flutter_secure_storage_linux: 1.2.1
|
||||||
flutter_secure_storage_macos: 3.1.2
|
flutter_secure_storage_macos: 3.1.2
|
||||||
|
@ -64,8 +65,10 @@ dependencies:
|
||||||
image_picker: 1.1.2
|
image_picker: 1.1.2
|
||||||
image_picker_android: 0.8.12+3
|
image_picker_android: 0.8.12+3
|
||||||
image_picker_for_web: 3.0.4
|
image_picker_for_web: 3.0.4
|
||||||
|
persistent_bottom_nav_bar: ^6.2.1
|
||||||
image_picker_ios: 0.8.12
|
image_picker_ios: 0.8.12
|
||||||
image_picker_platform_interface: 2.10.0
|
image_picker_platform_interface: 2.10.0
|
||||||
|
local_auth: ^2.2.0
|
||||||
intl: ^0.19.0
|
intl: ^0.19.0
|
||||||
json_path: 0.7.2
|
json_path: 0.7.2
|
||||||
mime_type: 1.0.0
|
mime_type: 1.0.0
|
||||||
|
@ -103,6 +106,7 @@ dependencies:
|
||||||
flutter_bloc: ^8.1.6
|
flutter_bloc: ^8.1.6
|
||||||
flutter_riverpod: ^2.5.1
|
flutter_riverpod: ^2.5.1
|
||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
|
permission_handler: ^11.3.1
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
http: 1.2.1
|
http: 1.2.1
|
||||||
|
|
Loading…
Reference in New Issue