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.READ_PRIVILEGED_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||
|
||||
<application
|
||||
android:label="FREHub"
|
||||
tools:replace="android:label"
|
||||
|
@ -14,7 +16,7 @@
|
|||
android:requestLegacyExternalStorage="true">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name="io.flutter.embedding.android.FlutterFragmentActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Why is my app authenticating using face id?</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<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_secure_storage/flutter_secure_storage.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';
|
||||
|
||||
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();
|
||||
|
||||
factory FFAppState() {
|
||||
|
@ -69,6 +127,25 @@ class FFAppState extends ChangeNotifier {
|
|||
await _safeInitAsync(() async {
|
||||
_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) {
|
||||
|
@ -78,6 +155,70 @@ class FFAppState extends ChangeNotifier {
|
|||
|
||||
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 get serialNumber => _serialNumber;
|
||||
set serialNumber(String value) {
|
||||
|
@ -270,6 +411,10 @@ class FFAppState extends ChangeNotifier {
|
|||
void deleteName() {
|
||||
secureStorage.delete(key: 'ff_name');
|
||||
}
|
||||
|
||||
void deleteAll() {
|
||||
secureStorage.deleteAll();
|
||||
}
|
||||
}
|
||||
|
||||
void _safeInit(Function() initializeField) {
|
||||
|
|
|
@ -41,6 +41,123 @@ class PhpGroup {
|
|||
static GetLiberationsCopyCall getLiberationsCopyCall =
|
||||
GetLiberationsCopyCall();
|
||||
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 {
|
||||
|
|
|
@ -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(
|
||||
'acessHistoryPage',
|
||||
'preferencesSettings',
|
||||
extra: <String, dynamic>{
|
||||
kTransitionInfoKey: const TransitionInfo(
|
||||
hasTransition: true,
|
||||
|
|
|
@ -62,8 +62,8 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
|||
await _model.peopleOnThePropertyAction(context);
|
||||
setState(() {});
|
||||
},
|
||||
acessHistoryOptAction: () async {
|
||||
await _model.acessHistoryOptAction(context);
|
||||
preferencesSettings: () async {
|
||||
await _model.preferencesSettings(context);
|
||||
setState(() {});
|
||||
},
|
||||
liberationHistoryOptAction: () async {
|
||||
|
@ -98,8 +98,8 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
|||
await _model.peopleOnThePropertyAction(context);
|
||||
setState(() {});
|
||||
},
|
||||
accessHistoryOptAction: () async {
|
||||
await _model.acessHistoryOptAction(context);
|
||||
preferencesSettings: () async {
|
||||
await _model.preferencesSettings(context);
|
||||
setState(() {});
|
||||
},
|
||||
liberationHistoryOptAction: () async {
|
||||
|
|
|
@ -16,7 +16,7 @@ class MenuListViewComponentWidget extends StatefulWidget {
|
|||
required this.registerVisitorOptAction,
|
||||
required this.scheduleVisitOptAction,
|
||||
required this.peopleOnThePropertyOptAction,
|
||||
required this.acessHistoryOptAction,
|
||||
required this.preferencesSettings,
|
||||
required this.liberationHistoryOptAction,
|
||||
required this.accessQRCodeOptAction,
|
||||
});
|
||||
|
@ -25,7 +25,7 @@ class MenuListViewComponentWidget extends StatefulWidget {
|
|||
final Future Function()? registerVisitorOptAction;
|
||||
final Future Function()? scheduleVisitOptAction;
|
||||
final Future Function()? peopleOnThePropertyOptAction;
|
||||
final Future Function()? acessHistoryOptAction;
|
||||
final Future Function()? preferencesSettings;
|
||||
final Future Function()? liberationHistoryOptAction;
|
||||
final Future Function()? accessQRCodeOptAction;
|
||||
|
||||
|
@ -876,7 +876,7 @@ Propriedade */
|
|||
hoverColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: () async {
|
||||
await widget.acessHistoryOptAction?.call();
|
||||
await widget.preferencesSettings?.call();
|
||||
},
|
||||
child: Container(
|
||||
width: 100.0,
|
||||
|
@ -931,7 +931,7 @@ Propriedade */
|
|||
alignment:
|
||||
const AlignmentDirectional(0.0, 0.0),
|
||||
child: Icon(
|
||||
Icons.history_sharp,
|
||||
Icons.settings,
|
||||
color: FlutterFlowTheme.of(context)
|
||||
.accent1,
|
||||
size: 24.0,
|
||||
|
@ -953,8 +953,8 @@ Propriedade */
|
|||
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||
child: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Consult\nHistories',
|
||||
ptText: 'Consultar\nHistóricos',
|
||||
enText: 'Preferences\nSystem',
|
||||
ptText: 'Preferências\ndo Sistema',
|
||||
),
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.titleLarge
|
||||
|
@ -979,6 +979,7 @@ Propriedade */
|
|||
),
|
||||
),
|
||||
),
|
||||
|
||||
].divide(const SizedBox(width: 15.0)),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -18,7 +18,7 @@ class MenuStaggeredViewComponentWidget extends StatefulWidget {
|
|||
required this.registerVisitorOptAction,
|
||||
required this.scheduleVisitOptAction,
|
||||
required this.peopleOnThePropertyOptAction,
|
||||
required this.accessHistoryOptAction,
|
||||
required this.preferencesSettings,
|
||||
required this.liberationHistoryOptAction,
|
||||
required this.accessQRCodeOptAction,
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ class MenuStaggeredViewComponentWidget extends StatefulWidget {
|
|||
final Future Function()? registerVisitorOptAction;
|
||||
final Future Function()? scheduleVisitOptAction;
|
||||
final Future Function()? peopleOnThePropertyOptAction;
|
||||
final Future Function()? accessHistoryOptAction;
|
||||
final Future Function()? preferencesSettings;
|
||||
final Future Function()? liberationHistoryOptAction;
|
||||
final Future Function()? accessQRCodeOptAction;
|
||||
|
||||
|
@ -85,7 +85,7 @@ class _MenuStaggeredViewComponentWidgetState
|
|||
),
|
||||
crossAxisSpacing: 10.0,
|
||||
mainAxisSpacing: 10.0,
|
||||
itemCount: 7,
|
||||
itemCount: 8,
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
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]();
|
||||
},
|
||||
),
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:developer';
|
||||
|
||||
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/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/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.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 {
|
||||
const MessageWellComponentWidget({super.key});
|
||||
|
@ -19,29 +28,29 @@ class MessageWellComponentWidget extends StatefulWidget {
|
|||
|
||||
class _MessageWellComponentWidgetState
|
||||
extends State<MessageWellComponentWidget> {
|
||||
late ScrollController _listViewController;
|
||||
late VoidCallback _scrollListener;
|
||||
final dropdownValueNotifier = ValueNotifier<String>('All');
|
||||
StreamSubscription? _dropdownSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_listViewController = ScrollController();
|
||||
_scrollListener = MessageWellNotifier()._scrollListener;
|
||||
_listViewController.addListener(_scrollListener);
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
context.read<MessageWellNotifier>().fetchMessages();
|
||||
});
|
||||
|
||||
_dropdownSubscription = dropdown.stream.listen((_) {
|
||||
context.read<MessageWellNotifier>().fetchMessages();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listViewController.dispose();
|
||||
_dropdownSubscription?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.watch<MessageWellNotifier>();
|
||||
final messages = state.getMessages();
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final messages = context.read<MessageWellNotifier>().getMessages();
|
||||
return Align(
|
||||
alignment: Alignment.center,
|
||||
child: Padding(
|
||||
|
@ -50,13 +59,10 @@ class _MessageWellComponentWidgetState
|
|||
height: MediaQuery.of(context).size.height * 0.8,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildHandleMessageWell(context, theme),
|
||||
_buildMenuMessageWell(context, theme, dropdownValueNotifier),
|
||||
_buildHandleMessageWell(context, FlutterFlowTheme.of(context)),
|
||||
_buildMenuMessageWell(context, FlutterFlowTheme.of(context)),
|
||||
Expanded(
|
||||
child: NotificationListener<ScrollNotification>(
|
||||
onNotification: _buildScrollMessageListManager,
|
||||
child: ListView.builder(
|
||||
controller: _listViewController,
|
||||
itemCount: messages.length,
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
|
@ -66,7 +72,6 @@ class _MessageWellComponentWidgetState
|
|||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -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(
|
||||
key: UniqueKey(),
|
||||
width: 200,
|
||||
height: 40,
|
||||
child: ValueListenableBuilder<String>(
|
||||
valueListenable: dropdownValueNotifier,
|
||||
builder: (context, value, child) {
|
||||
child: StreamBuilder<String>(
|
||||
stream: dropdown.stream.map((event) => event.keys.first),
|
||||
builder: (context, snapshot) {
|
||||
final value = snapshot.data;
|
||||
return DropdownButtonFormField<String>(
|
||||
value: value,
|
||||
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(
|
||||
borderSide: BorderSide(
|
||||
color: theme.primary,
|
||||
|
@ -123,20 +145,16 @@ class _MessageWellComponentWidgetState
|
|||
fillColor: theme.primary,
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue != null) {
|
||||
dropdownValueNotifier.value = newValue;
|
||||
}
|
||||
safeSetState(() => dropdown.value = LinkedHashMap.from({newValue!: dropdownItems[newValue].toString()}));
|
||||
},
|
||||
items: [
|
||||
DropdownMenuItem<String>(value: all, child: Text(all)),
|
||||
DropdownMenuItem<String>(value: personal, child: Text(personal)),
|
||||
DropdownMenuItem<String>(value: global, child: Text(global)),
|
||||
],
|
||||
style: theme.labelMedium.override(
|
||||
fontFamily: theme.labelMediumFamily,
|
||||
items: dropdownItems.entries
|
||||
.map((entry) => DropdownMenuItem<String>(
|
||||
value: entry.key,
|
||||
child: Text(entry.key),
|
||||
))
|
||||
.toList(),
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.primaryText,
|
||||
useGoogleFonts:
|
||||
GoogleFonts.asMap().containsKey(theme.labelMediumFamily),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -144,21 +162,22 @@ class _MessageWellComponentWidgetState
|
|||
);
|
||||
}
|
||||
|
||||
Text _buildHandleMessageWell(
|
||||
BuildContext context, FlutterFlowTheme theme) {
|
||||
Text _buildHandleMessageWell(BuildContext context, FlutterFlowTheme theme) {
|
||||
return Text(
|
||||
FFLocalizations.of(context).getText('8fworxmb'),
|
||||
style: theme.bodyMedium.override(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Mural de Mensagens',
|
||||
enText: 'Message Wall',
|
||||
),
|
||||
style: theme.bodyMedium.copyWith(
|
||||
fontFamily: 'Nunito Sans',
|
||||
letterSpacing: 0.0,
|
||||
useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito Sans'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMessageItem(
|
||||
BuildContext context, dynamic message, int index) {
|
||||
final theme = Theme.of(context);
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
String formatMessageOrigin(String messageOrigin) {
|
||||
final words = messageOrigin.split(' ');
|
||||
final formattedWords = words.map((word) {
|
||||
|
@ -168,17 +187,15 @@ class _MessageWellComponentWidgetState
|
|||
});
|
||||
return formattedWords.join(' ');
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () =>
|
||||
log('Message tapped ...\nmessage[$index]: $message'),
|
||||
onTap: () => {},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 5, 20, 5),
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * 0.9,
|
||||
height: 127.0,
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
@ -201,9 +218,9 @@ class _MessageWellComponentWidgetState
|
|||
Center(
|
||||
child: Text(
|
||||
'~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}',
|
||||
style: theme.textTheme.headlineMedium!.copyWith(
|
||||
style: theme.bodyMedium.copyWith(
|
||||
fontFamily: 'Nunito Sans',
|
||||
color: FlutterFlowTheme.of(context).primary,
|
||||
color: theme.primary,
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
|
@ -215,9 +232,9 @@ class _MessageWellComponentWidgetState
|
|||
scrollDirection: Axis.vertical,
|
||||
child: Text(
|
||||
formatMessageOrigin(message['MSG_TEXTO'].toString()),
|
||||
style: theme.textTheme.bodyMedium!.copyWith(
|
||||
style: theme.bodyMedium.copyWith(
|
||||
fontFamily: 'Nunito Sans',
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
color: theme.bodyMedium.color,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
softWrap: true,
|
||||
|
@ -234,26 +251,25 @@ class _MessageWellComponentWidgetState
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MessageWellState {
|
||||
final List<dynamic> messages;
|
||||
int pageNumber;
|
||||
final bool allowScrollInSingleChildScrollView;
|
||||
final ScrollController listViewController;
|
||||
|
||||
MessageWellState({
|
||||
required this.messages,
|
||||
this.pageNumber = 1,
|
||||
required this.allowScrollInSingleChildScrollView,
|
||||
required this.listViewController,
|
||||
});
|
||||
|
||||
MessageWellState copyWith({
|
||||
List<dynamic>? messages,
|
||||
int? pageNumber,
|
||||
bool? allowScrollInSingleChildScrollView,
|
||||
ScrollController? listViewController,
|
||||
}) {
|
||||
return MessageWellState(
|
||||
messages: messages ?? this.messages,
|
||||
|
@ -261,7 +277,6 @@ class MessageWellState {
|
|||
allowScrollInSingleChildScrollView:
|
||||
allowScrollInSingleChildScrollView ??
|
||||
this.allowScrollInSingleChildScrollView,
|
||||
listViewController: listViewController ?? this.listViewController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -274,13 +289,11 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
|||
_totalPageNumber = value;
|
||||
}
|
||||
|
||||
|
||||
MessageWellNotifier()
|
||||
: super(MessageWellState(
|
||||
messages: [],
|
||||
allowScrollInSingleChildScrollView: true,
|
||||
listViewController: ScrollController())) {
|
||||
state.listViewController.addListener(_scrollListener);
|
||||
)) {
|
||||
fetchMessages();
|
||||
}
|
||||
|
||||
|
@ -292,28 +305,20 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
|||
userUUID: FFAppState().userUUID.toString(),
|
||||
cliID: FFAppState().cliUUID.toString(),
|
||||
atividade: 'getMensagens',
|
||||
pageSize: '10',
|
||||
pageSize: '100',
|
||||
pageNumber: state.pageNumber.toString(),
|
||||
tipoDestino: 'A',
|
||||
tipoDestino: dropdown.value.values.first,
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
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 rExp = RegExp(r'\d+')
|
||||
.allMatches(newMessages.toString())
|
||||
.map((e) => e.group(0))
|
||||
.toList();
|
||||
log('rExp: $rExp');
|
||||
log('newMessages: $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']));
|
||||
totalPageNumber = int.parse(response.jsonBody['total_pages']);
|
||||
log('totalPageNumber: $totalPageNumber');
|
||||
// totalPageNumber = int.parse(response.jsonBody['total_pages']);
|
||||
} else {
|
||||
log('Error fetching messages: ${response.statusCode}');
|
||||
}
|
||||
|
@ -325,29 +330,9 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
|||
List<dynamic> getMessages() {
|
||||
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() {
|
||||
log('state.pageNumber: ${state.pageNumber}');
|
||||
log('total_pages :>: $totalPageNumber');
|
||||
if (state.pageNumber <= totalPageNumber) {
|
||||
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 '/actions/actions.dart' as action_blocks;
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
@ -862,6 +863,11 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
|
|||
),
|
||||
onPressed: () {
|
||||
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/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:provider/provider.dart';
|
||||
|
||||
|
@ -78,7 +79,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
|||
path: '/visitHistoryPage',
|
||||
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(
|
||||
name: 'registerVisitorPage',
|
||||
path: '/registerVisitorPage',
|
||||
|
@ -138,6 +142,9 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
|||
path: '/fastPassPage',
|
||||
builder: (context, params) => /*const*/ FastPassPageWidget(),
|
||||
),
|
||||
FFRoute(name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => const PreferencesPageWidget(
|
||||
key: Key('preferencesSettings'),
|
||||
)),
|
||||
FFRoute(
|
||||
name: '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:provider/provider.dart';
|
||||
|
|
|
@ -75,6 +75,7 @@ PreferredSizeWidget appBarLiberationHistoryPage(BuildContext context) {
|
|||
return AppBar(
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
|
@ -103,6 +104,7 @@ PreferredSizeWidget appBarLiberationHistoryPage(BuildContext context) {
|
|||
),
|
||||
actions: const [],
|
||||
centerTitle: true,
|
||||
elevation: 0.0,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ class _PeopleOnThePropertyPageWidgetState
|
|||
appBar: AppBar(
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
|
@ -106,7 +107,6 @@ class _PeopleOnThePropertyPageWidgetState
|
|||
);
|
||||
}
|
||||
final columnGetPessoasLocalResponse = snapshot.data!;
|
||||
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
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(
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
|
|
|
@ -165,6 +165,8 @@ PreferredSizeWidget appBarScheduleCompleteVisit(BuildContext context) {
|
|||
return AppBar(
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
elevation: 0.0,
|
||||
leading: FlutterFlowIconButton(
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
|
|
|
@ -61,6 +61,7 @@ class _ScheduleProvisionalVisitPageWidgetState
|
|||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
forceMaterialTransparency: true,
|
||||
leading: FlutterFlowIconButton(
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
|
|
112
pubspec.lock
112
pubspec.lock
|
@ -821,6 +821,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -973,6 +1013,62 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1053,6 +1149,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -47,6 +47,7 @@ dependencies:
|
|||
flutter_animate: 4.5.0
|
||||
flutter_cache_manager: 3.3.2
|
||||
flutter_plugin_android_lifecycle: 2.0.20
|
||||
share_plus: ^9.0.0
|
||||
flutter_secure_storage: 9.2.2
|
||||
flutter_secure_storage_linux: 1.2.1
|
||||
flutter_secure_storage_macos: 3.1.2
|
||||
|
@ -64,8 +65,10 @@ dependencies:
|
|||
image_picker: 1.1.2
|
||||
image_picker_android: 0.8.12+3
|
||||
image_picker_for_web: 3.0.4
|
||||
persistent_bottom_nav_bar: ^6.2.1
|
||||
image_picker_ios: 0.8.12
|
||||
image_picker_platform_interface: 2.10.0
|
||||
local_auth: ^2.2.0
|
||||
intl: ^0.19.0
|
||||
json_path: 0.7.2
|
||||
mime_type: 1.0.0
|
||||
|
@ -103,6 +106,7 @@ dependencies:
|
|||
flutter_bloc: ^8.1.6
|
||||
flutter_riverpod: ^2.5.1
|
||||
qr_flutter: ^4.1.0
|
||||
permission_handler: ^11.3.1
|
||||
|
||||
dependency_overrides:
|
||||
http: 1.2.1
|
||||
|
|
Loading…
Reference in New Issue