feat: Add QR code functionality and route
This commit is contained in:
parent
6b21d70d4c
commit
d41a162562
|
@ -1,6 +1,11 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:f_r_e_hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
|
import 'package:f_r_e_hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
|
||||||
|
import 'package:f_r_e_hub/custom_code/actions/get_dev_u_u_i_d.dart';
|
||||||
import 'package:f_r_e_hub/pages/home_page/home_page_widget.dart';
|
import 'package:f_r_e_hub/pages/home_page/home_page_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
import 'dart:developer' as developer;
|
||||||
|
|
||||||
import '/actions/actions.dart' as action_blocks;
|
import '/actions/actions.dart' as action_blocks;
|
||||||
import '/backend/api_requests/api_calls.dart';
|
import '/backend/api_requests/api_calls.dart';
|
||||||
|
@ -8,8 +13,6 @@ import '/components/molecular_components/throw_exception/throw_exception_widget.
|
||||||
import '/custom_code/actions/index.dart' as actions;
|
import '/custom_code/actions/index.dart' as actions;
|
||||||
import '/flutter_flow/flutter_flow_theme.dart';
|
import '/flutter_flow/flutter_flow_theme.dart';
|
||||||
import '/flutter_flow/flutter_flow_util.dart';
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
import '/flutter_flow/flutter_flow_util.dart';
|
|
||||||
|
|
||||||
import '/flutter_flow/random_data_util.dart' as random_data;
|
import '/flutter_flow/random_data_util.dart' as random_data;
|
||||||
|
|
||||||
Future repeatVisitScheduleAction(
|
Future repeatVisitScheduleAction(
|
||||||
|
@ -136,9 +139,13 @@ Future singInLoginAction(
|
||||||
FFAppState().status = PhpGroup.loginCall.userStatus(
|
FFAppState().status = PhpGroup.loginCall.userStatus(
|
||||||
(loginCall.jsonBody ?? ''),
|
(loginCall.jsonBody ?? ''),
|
||||||
)!;
|
)!;
|
||||||
|
FFAppState().userDevUUID = PhpGroup.loginCall.userDeviceId(
|
||||||
|
(loginCall.jsonBody ?? ''),
|
||||||
|
)!;
|
||||||
FFAppState().name = PhpGroup.loginCall.userName(
|
FFAppState().name = PhpGroup.loginCall.userName(
|
||||||
(loginCall.jsonBody ?? ''),
|
(loginCall.jsonBody ?? ''),
|
||||||
)!;
|
)!;
|
||||||
|
FFAppState().serialNumber = await getSerialNumber() ?? '';
|
||||||
FFAppState().isLogged = true;
|
FFAppState().isLogged = true;
|
||||||
await action_blocks.toggleHomePage(context);
|
await action_blocks.toggleHomePage(context);
|
||||||
return;
|
return;
|
||||||
|
@ -495,3 +502,173 @@ Future changeStatusAction(
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// QR Code
|
||||||
|
|
||||||
|
|
||||||
|
Uint8List assembleQRPacket(int direction, String identifier, String password) {
|
||||||
|
Uint8List packet = Uint8List(20);
|
||||||
|
int position = 0;
|
||||||
|
int check = 0;
|
||||||
|
|
||||||
|
// Direction
|
||||||
|
packet[position++] = direction;
|
||||||
|
|
||||||
|
// Identifier
|
||||||
|
Uint8List ide = hexStringToByteArray(("000000000000000000000000000000" + identifier).substring(identifier.length));
|
||||||
|
for (int i = 0; i < ide.length; i++) {
|
||||||
|
packet[position++] = ide[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date and time
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
int day = int.parse(DateFormat('dd').format(now));
|
||||||
|
int month = int.parse(DateFormat('MM').format(now));
|
||||||
|
int year = int.parse(DateFormat('yy').format(now));
|
||||||
|
int hour = int.parse(DateFormat('HH').format(now));
|
||||||
|
int minute = int.parse(DateFormat('mm').format(now));
|
||||||
|
|
||||||
|
int sumDate = year + month + day + hour + minute;
|
||||||
|
packet[position++] = (sumDate == 0x0D || sumDate == 0x0A) ? 0xFF : sumDate;
|
||||||
|
|
||||||
|
// Log the sumDate
|
||||||
|
developer.log("Soma Data: $sumDate", name: "ROTINAS");
|
||||||
|
|
||||||
|
// Password
|
||||||
|
Uint8List passBytes = hexStringToByteArray(password);
|
||||||
|
packet[position++] = passBytes[0];
|
||||||
|
packet[position++] = passBytes[1];
|
||||||
|
|
||||||
|
// Checksum
|
||||||
|
for (int i = 0; i < packet.length - 1; i++) {
|
||||||
|
check ^= packet[i];
|
||||||
|
}
|
||||||
|
packet[position] = (check == 0x0D || check == 0x0A) ? 0xFF : check;
|
||||||
|
|
||||||
|
// Log the checksum
|
||||||
|
developer.log("Checksum: $check", name: "ROTINAS");
|
||||||
|
|
||||||
|
// Convert packet to hex string and log it
|
||||||
|
String hexPacket = byteToHexa(packet);
|
||||||
|
developer.log("Pacote final: $hexPacket", name: "ROTINAS");
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8List hexStringToByteArray(String s) {
|
||||||
|
int len = s.length;
|
||||||
|
Uint8List data = Uint8List(len ~/ 2);
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
data[i ~/ 2] = ((int.parse(s[i], radix: 16) << 4) + int.parse(s[i + 1], radix: 16));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
String byteToHexa(List<int> pDados) {
|
||||||
|
return pDados.map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase()).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String byteToString(Uint8List bytes) {
|
||||||
|
return utf8.decode(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildQrCode(
|
||||||
|
{
|
||||||
|
required String data,
|
||||||
|
required String type,
|
||||||
|
required double dimension,
|
||||||
|
required int errorCorrectLevel,
|
||||||
|
required int version,
|
||||||
|
required int maskPattern,
|
||||||
|
required String identifier,
|
||||||
|
required String pass,
|
||||||
|
required int direction
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
debugPrint('remoteID: ${FFAppState().userDevUUID}');
|
||||||
|
debugPrint('androidId: ${FFAppState().devUUID}');
|
||||||
|
debugPrint('Serial Number: ${FFAppState().serialNumber}');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Verifica se os dados estão de acordo com as regras de negócio
|
||||||
|
if (data.isEmpty) {
|
||||||
|
throw Exception("Dados do QR Code estão vazios.");
|
||||||
|
}
|
||||||
|
// Aqui você pode adicionar mais lógica de validação conforme necessário
|
||||||
|
|
||||||
|
// Geração do QR Code com a biblioteca qr_flutter
|
||||||
|
const Color backgroundColor = Colors.white;
|
||||||
|
const Color foregroundColor = Colors.black;
|
||||||
|
return QrImageView(
|
||||||
|
data: byteToString(assembleQRPacket(direction, identifier, pass)),
|
||||||
|
version: version, //QrVersions.auto
|
||||||
|
size: dimension,
|
||||||
|
// errorCorrectionLevel: errorCorrectLevel,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
foregroundColor: foregroundColor,
|
||||||
|
gapless: false, // Ajuste conforme necessário
|
||||||
|
// Adicione mais customizações aqui conforme os arquivos Java
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// Tratamento de erros
|
||||||
|
return Text("Erro ao gerar QR Code: ${e.toString()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// // Retorna o conteúdo a ser codificado no QR Code.
|
||||||
|
// String getContents() {
|
||||||
|
// return data;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Retorna uma versão do conteúdo otimizada para exibição.
|
||||||
|
// String getDisplayContents() {
|
||||||
|
// return data.trim();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Retorna o título baseado no tipo de conteúdo.
|
||||||
|
// String getTitle() {
|
||||||
|
// return type;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Codifica o conteúdo em uma string adequada para o QR Code.
|
||||||
|
// Future<String> encodeContents() async {
|
||||||
|
// // Implementação específica para codificar o conteúdo.
|
||||||
|
// return data; // Exemplo simplificado.
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Codifica o conteúdo específico do QR Code.
|
||||||
|
// Future<Widget> encodeQRCodeContents() async {
|
||||||
|
// return getQrCode();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Gera o QR Code como um widget.
|
||||||
|
|
||||||
|
|
||||||
|
// // Codifica o conteúdo como um bitmap (pode ser útil para operações de baixo nível).
|
||||||
|
// // Future<Image> encodeAsBitmap() async {
|
||||||
|
// // // Implementação para codificar como bitmap.
|
||||||
|
// // return Image(image); // Exemplo simplificado.
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // Adivinha a codificação apropriada para o conteúdo.
|
||||||
|
// String guessAppropriateEncoding(String content) {
|
||||||
|
// // Implementação para adivinhar a codificação.
|
||||||
|
// return "UTF-8"; // Exemplo simplificado.
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Remove espaços em branco do início e do fim do conteúdo.
|
||||||
|
// String trim(String content) {
|
||||||
|
// return content.trim();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Escapa caracteres especiais para o formato MECARD.
|
||||||
|
// String escapeMECARD(String content) {
|
||||||
|
// // Implementação para escapar caracteres.
|
||||||
|
// return content.replaceAll(':', '\\:'); // Exemplo simplificado.
|
||||||
|
// }
|
|
@ -61,7 +61,13 @@ class FFAppState extends ChangeNotifier {
|
||||||
_name = await secureStorage.getString('ff_name') ?? _name;
|
_name = await secureStorage.getString('ff_name') ?? _name;
|
||||||
});
|
});
|
||||||
await _safeInitAsync(() async {
|
await _safeInitAsync(() async {
|
||||||
_name = await secureStorage.getString('ff_tokenAPNS') ?? _name;
|
_tokenAPNS = await secureStorage.getString('ff_tokenAPNS') ?? _tokenAPNS;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_userDevUUID = await secureStorage.getString('ff_user_dev_id') ?? _userDevUUID;
|
||||||
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_serialNumber = await secureStorage.getString('ff_serialNumber') ?? _serialNumber;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +78,17 @@ class FFAppState extends ChangeNotifier {
|
||||||
|
|
||||||
late FlutterSecureStorage secureStorage;
|
late FlutterSecureStorage secureStorage;
|
||||||
|
|
||||||
|
String _serialNumber = '';
|
||||||
|
String get serialNumber => _serialNumber;
|
||||||
|
set serialNumber(String value) {
|
||||||
|
_serialNumber = value;
|
||||||
|
secureStorage.setString('ff_serialNumber', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteSerialNumber() {
|
||||||
|
secureStorage.delete(key: 'ff_serialNumber');
|
||||||
|
}
|
||||||
|
|
||||||
String _cliUUID = '';
|
String _cliUUID = '';
|
||||||
String get cliUUID => _cliUUID;
|
String get cliUUID => _cliUUID;
|
||||||
set cliUUID(String value) {
|
set cliUUID(String value) {
|
||||||
|
@ -83,6 +100,17 @@ class FFAppState extends ChangeNotifier {
|
||||||
secureStorage.delete(key: 'ff_cliUUID');
|
secureStorage.delete(key: 'ff_cliUUID');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _userDevUUID = '';
|
||||||
|
String get userDevUUID => _userDevUUID;
|
||||||
|
set userDevUUID(String value) {
|
||||||
|
_userDevUUID = value;
|
||||||
|
secureStorage.setString('ff_user_dev_id', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteRemoteId() {
|
||||||
|
secureStorage.delete(key: 'ff_user_dev_id');
|
||||||
|
}
|
||||||
|
|
||||||
String? _tokenAPNS = '';
|
String? _tokenAPNS = '';
|
||||||
String? get tokenAPNS => _tokenAPNS;
|
String? get tokenAPNS => _tokenAPNS;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ export 'package:collection/collection.dart' show ListEquality;
|
||||||
export 'package:flutter/material.dart' show Color, Colors;
|
export 'package:flutter/material.dart' show Color, Colors;
|
||||||
export 'package:from_css_color/from_css_color.dart';
|
export 'package:from_css_color/from_css_color.dart';
|
||||||
|
|
||||||
|
|
||||||
typedef StructBuilder<T> = T Function(Map<String, dynamic> data);
|
typedef StructBuilder<T> = T Function(Map<String, dynamic> data);
|
||||||
|
|
||||||
abstract class BaseStruct {
|
abstract class BaseStruct {
|
||||||
|
|
|
@ -117,4 +117,19 @@ class _MenuComponentWidgetState extends State<MenuComponentWidget> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future accessQRCodeOptAction(BuildContext context) async {
|
||||||
|
context.pushNamed(
|
||||||
|
'qrCodePage',
|
||||||
|
extra: <String, dynamic>{
|
||||||
|
kTransitionInfoKey: const TransitionInfo(
|
||||||
|
hasTransition: true,
|
||||||
|
transitionType: PageTransitionType.scale,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -842,9 +842,8 @@ Propriedade */
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context)
|
FFLocalizations.of(context)
|
||||||
.getVariableText(
|
.getVariableText(
|
||||||
ptText: 'Consultar\nConsultar
|
ptText: 'Consultar\nConsultar',
|
||||||
Históricos */
|
enText: 'Consult\nHistories',
|
||||||
,
|
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context)
|
style: FlutterFlowTheme.of(context)
|
||||||
.titleLarge
|
.titleLarge
|
||||||
|
@ -953,9 +952,9 @@ Históricos */
|
||||||
Align(
|
Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
'589qufkw' /* Históricos',
|
|
||||||
enText: 'Consult\nHistories',
|
enText: 'Consult\nHistories',
|
||||||
|
ptText: 'Consultar\nHistóricos',
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context)
|
style: FlutterFlowTheme.of(context)
|
||||||
.titleLarge
|
.titleLarge
|
||||||
|
|
|
@ -38,3 +38,28 @@ Future<String?> getDevUUID() async {
|
||||||
return androidDeviceInfo.id; // unique ID on Android
|
return androidDeviceInfo.id; // unique ID on Android
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> getSerialNumber() async {
|
||||||
|
var deviceInfo = DeviceInfoPlugin();
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
// import 'dart:io'
|
||||||
|
var iosDeviceInfo = await deviceInfo.iosInfo;
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.utsname.machine: ${iosDeviceInfo.utsname.machine}'); // e.g. "iPod7,1"
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.systemName: ${iosDeviceInfo.systemName}'); // e.g. "iOS"
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.systemVersion: ${iosDeviceInfo.systemVersion}'); // e.g. "13.3"
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.model: ${iosDeviceInfo.model}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.localizedModel: ${iosDeviceInfo.localizedModel}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPlugin => iosDeviceInfo.identifierForVendor: ${iosDeviceInfo.identifierForVendor}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
|
||||||
|
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
|
||||||
|
} else if (Platform.isAndroid) {
|
||||||
|
var androidDeviceInfo = await deviceInfo.androidInfo;
|
||||||
|
print(AndroidDeviceInfo);
|
||||||
|
// debugPrint('Running on ${androidDeviceInfo.androidId}'); // e.g. "A8E9F7C8-4D1F-4D97-9C3B-3A3D0F0F3E9E"
|
||||||
|
debugPrint('DeviceInfoPLugin => androidDeviceInfo.model: ${androidDeviceInfo.model}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPLugin => androidDeviceInfo.manufacturer: ${androidDeviceInfo.manufacturer}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPLugin => androidDeviceInfo.product: ${androidDeviceInfo.product}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPLugin => androidDeviceInfo.device: ${androidDeviceInfo.device}'); // e.g. "iPhone"
|
||||||
|
debugPrint('DeviceInfoPLugin => androidDeviceInfo.id: ${androidDeviceInfo.id}'); // e.g. "iPhone"
|
||||||
|
return androidDeviceInfo.serialNumber; // unique ID on Android
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -106,6 +106,14 @@ String jsonToStr(dynamic json) {
|
||||||
return jsonString;
|
return jsonString;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getProgressValue(int percentage) {
|
Stream<double> getProgressValue() {
|
||||||
return percentage / 100;
|
final startTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
}
|
final endTime = startTime + 20000;
|
||||||
|
final duration = Duration(milliseconds: 100);
|
||||||
|
return Stream.periodic(duration, (int count) {
|
||||||
|
final currentTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
final elapsedTime = currentTime - startTime;
|
||||||
|
final progress = math.min(1.0, elapsedTime / (endTime - startTime));
|
||||||
|
return progress;
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,3 +1,8 @@
|
||||||
|
import 'package:barcode_widget/barcode_widget.dart';
|
||||||
|
import 'package:f_r_e_hub/actions/actions.dart';
|
||||||
|
import 'package:f_r_e_hub/flutter_flow/custom_functions.dart';
|
||||||
|
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||||
|
|
||||||
import '/components/templates_components/qr_code_pass_key_template_component/qr_code_pass_key_template_component_widget.dart';
|
import '/components/templates_components/qr_code_pass_key_template_component/qr_code_pass_key_template_component_widget.dart';
|
||||||
import '/flutter_flow/flutter_flow_animations.dart';
|
import '/flutter_flow/flutter_flow_animations.dart';
|
||||||
import '/flutter_flow/flutter_flow_icon_button.dart';
|
import '/flutter_flow/flutter_flow_icon_button.dart';
|
||||||
|
@ -6,72 +11,91 @@ import '/flutter_flow/flutter_flow_util.dart';
|
||||||
import '/flutter_flow/flutter_flow_widgets.dart';
|
import '/flutter_flow/flutter_flow_widgets.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import '/flutter_flow/custom_functions.dart' as functions;
|
import '/flutter_flow/custom_functions.dart' as functions;
|
||||||
import 'package:barcode_widget/barcode_widget.dart';
|
// import 'package:barcode_widget/barcode_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:percent_indicator/percent_indicator.dart';
|
// import 'package:percent_indicator/percent_indicator.dart';
|
||||||
import 'qr_code_page_model.dart';
|
import 'qr_code_page_model.dart';
|
||||||
export 'qr_code_page_model.dart';
|
export 'qr_code_page_model.dart';
|
||||||
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QrCodePageWidget extends StatefulWidget {
|
class QrCodePageWidget extends StatefulWidget {
|
||||||
const QrCodePageWidget({super.key});
|
const QrCodePageWidget({super.key});
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<QrCodePageWidget> createState() => _QrCodePageWidgetState();
|
State<QrCodePageWidget> createState() => _QrCodePageWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
late QrCodePageModel _model;
|
late QrCodePageModel _model;
|
||||||
|
|
||||||
|
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
final animationsMap = <String, AnimationInfo>{};
|
final animationsMap = <String, AnimationInfo>{};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_model = createModel(context, () => QrCodePageModel());
|
_model = createModel(context, () => QrCodePageModel());
|
||||||
|
|
||||||
// On page load action.
|
// On page load action.
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
||||||
animationsMap['barcodeOnActionTriggerAnimation']!.controller.repeat();
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.fling();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
animationsMap.addAll({
|
animationsMap.addAll({
|
||||||
'barcodeOnActionTriggerAnimation': AnimationInfo(
|
'barcodeOnActionTriggerAnimation': AnimationInfo(
|
||||||
trigger: AnimationTrigger.onActionTrigger,
|
trigger: AnimationTrigger.onActionTrigger,
|
||||||
applyInitialState: true,
|
applyInitialState: true,
|
||||||
effectsBuilder: () => [
|
effectsBuilder: () => [
|
||||||
VisibilityEffect(duration: 1.ms),
|
VisibilityEffect(duration: 1.ms),
|
||||||
BlurEffect(
|
BlurEffect(
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
delay: 0.0.ms,
|
delay: 0.0.ms,
|
||||||
duration: 600.0.ms,
|
duration: 600.0.ms,
|
||||||
begin: const Offset(0.0, 0.0),
|
begin: const Offset(0.0, 0.0),
|
||||||
end: const Offset(4.0, 4.0),
|
end: const Offset(10.0, 10.0),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
setupAnimations(
|
setupAnimations(
|
||||||
animationsMap.values.where((anim) =>
|
animationsMap.values.where((anim) =>
|
||||||
anim.trigger == AnimationTrigger.onActionTrigger ||
|
anim.trigger == AnimationTrigger.onActionTrigger ||
|
||||||
!anim.applyInitialState),
|
!anim.applyInitialState),
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
// // Adicionando um ouvinte de status à animação para reiniciá-la após a conclusão
|
||||||
@override
|
// animationsMap['barcodeOnActionTriggerAnimation']?.controller.addStatusListener((status) {
|
||||||
void dispose() {
|
// if (status == AnimationStatus.completed) {
|
||||||
_model.dispose();
|
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
|
||||||
|
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
|
||||||
super.dispose();
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// Removendo o ouvinte antes de chamar super.dispose para evitar vazamentos de memória
|
||||||
|
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
||||||
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.removeStatusListener((status) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -82,66 +106,65 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
appBar: AppBar(
|
appBar: buildAppBar(context),
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
body: buildBody(context),
|
||||||
automaticallyImplyLeading: false,
|
),
|
||||||
leading: FlutterFlowIconButton(
|
);
|
||||||
borderColor: Colors.transparent,
|
}
|
||||||
borderRadius: 30.0,
|
|
||||||
borderWidth: 1.0,
|
Widget buildBody(BuildContext context) {
|
||||||
buttonSize: 60.0,
|
double screenWidth = MediaQuery.of(context).size.width;
|
||||||
icon: Icon(
|
double screenHeight = MediaQuery.of(context).size.height;
|
||||||
Icons.keyboard_arrow_left,
|
double smallerDimension = screenWidth < screenHeight ? screenWidth : screenHeight;
|
||||||
color: FlutterFlowTheme.of(context).primaryText,
|
double dimension = smallerDimension * 0.75;
|
||||||
size: 30.0,
|
|
||||||
),
|
double totalTimeInSeconds = 100.0;
|
||||||
onPressed: () async {
|
return SafeArea(
|
||||||
context.pop();
|
top: true,
|
||||||
},
|
child: Column(
|
||||||
),
|
mainAxisSize: MainAxisSize.max,
|
||||||
title: Text(
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
FFLocalizations.of(context).getText(
|
children: [
|
||||||
'ku7jqe53' /* QR Code de Acesso */,
|
if (_model.isAccess == true)
|
||||||
),
|
Text(
|
||||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
FFLocalizations.of(context).getVariableText(
|
||||||
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
|
ptText: 'QR Code de Acesso',
|
||||||
color: FlutterFlowTheme.of(context).primaryText,
|
enText: 'Access QR Code',
|
||||||
fontSize: 16.0,
|
|
||||||
letterSpacing: 0.0,
|
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
|
||||||
FlutterFlowTheme.of(context).headlineMediumFamily),
|
|
||||||
),
|
),
|
||||||
),
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
actions: const [],
|
fontFamily:
|
||||||
centerTitle: true,
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
elevation: 0.0,
|
fontSize: 20.0,
|
||||||
),
|
letterSpacing: 0.0,
|
||||||
body: SafeArea(
|
fontWeight: FontWeight.bold,
|
||||||
top: true,
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
child: Column(
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
mainAxisSize: MainAxisSize.max,
|
),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
),
|
||||||
children: [
|
Stack(
|
||||||
if (_model.isAccess == true)
|
children: [
|
||||||
Text(
|
if (_model.isAccess == true)
|
||||||
FFLocalizations.of(context).getText(
|
Align(
|
||||||
'vd84zgfe' /* Use esse QR Code para acesso */,
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
// this.errorCorrectLevel = 3,
|
||||||
|
// this.version = 10,
|
||||||
|
// this.maskPattern = -1,
|
||||||
|
child: buildQrCode(
|
||||||
|
data: 'example.com',
|
||||||
|
type: 'URl',
|
||||||
|
dimension: dimension,
|
||||||
|
errorCorrectLevel: QrErrorCorrectLevel.H,
|
||||||
|
maskPattern: -1,
|
||||||
|
version: QrVersions.auto,
|
||||||
|
identifier: FFAppState().userDevUUID,
|
||||||
|
pass: '12313123',
|
||||||
|
direction: 5,
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
|
||||||
fontFamily:
|
|
||||||
FlutterFlowTheme.of(context).bodyMediumFamily,
|
|
||||||
fontSize: 20.0,
|
|
||||||
letterSpacing: 0.0,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
|
||||||
FlutterFlowTheme.of(context).bodyMediumFamily),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Stack(
|
if(_model.isAccess == false)
|
||||||
children: [
|
Align(
|
||||||
Align(
|
alignment: const AlignmentDirectional(0, 0),
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
child: BarcodeWidget(
|
||||||
child: BarcodeWidget(
|
|
||||||
data: 'Barcode',
|
data: 'Barcode',
|
||||||
barcode: Barcode.qrCode(),
|
barcode: Barcode.qrCode(),
|
||||||
width: 300.0,
|
width: 300.0,
|
||||||
|
@ -156,219 +179,273 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
).animateOnActionTrigger(
|
).animateOnActionTrigger(
|
||||||
animationsMap['barcodeOnActionTriggerAnimation']!,
|
animationsMap['barcodeOnActionTriggerAnimation']!,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (_model.isAccess == true)
|
|
||||||
Align(
|
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
|
||||||
child: InkWell(
|
|
||||||
splashColor: Colors.transparent,
|
|
||||||
focusColor: Colors.transparent,
|
|
||||||
hoverColor: Colors.transparent,
|
|
||||||
highlightColor: Colors.transparent,
|
|
||||||
onLongPress: () async {
|
|
||||||
await _model.qrCodeEncoder(
|
|
||||||
context,
|
|
||||||
key: _model.key,
|
|
||||||
);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 200.0,
|
|
||||||
height: 200.0,
|
|
||||||
decoration: const BoxDecoration(),
|
|
||||||
child: Align(
|
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
|
||||||
child: FFButtonWidget(
|
|
||||||
onPressed: () async {
|
|
||||||
await showModalBottomSheet(
|
|
||||||
isScrollControlled: true,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
useSafeArea: true,
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: () => _model
|
|
||||||
.unfocusNode.canRequestFocus
|
|
||||||
? FocusScope.of(context)
|
|
||||||
.requestFocus(_model.unfocusNode)
|
|
||||||
: FocusScope.of(context).unfocus(),
|
|
||||||
child: Padding(
|
|
||||||
padding:
|
|
||||||
MediaQuery.viewInsetsOf(context),
|
|
||||||
child:
|
|
||||||
QrCodePassKeyTemplateComponentWidget(
|
|
||||||
toggleActionStatus: (key) async {
|
|
||||||
_model.key = key;
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
).then((value) => safeSetState(() {}));
|
|
||||||
|
|
||||||
unawaited(
|
|
||||||
() async {
|
|
||||||
await _model.qrCodeEncoder(
|
|
||||||
context,
|
|
||||||
key: _model.key,
|
|
||||||
);
|
|
||||||
setState(() {});
|
|
||||||
}(),
|
|
||||||
);
|
|
||||||
if (animationsMap[
|
|
||||||
'barcodeOnActionTriggerAnimation'] !=
|
|
||||||
null) {
|
|
||||||
animationsMap[
|
|
||||||
'barcodeOnActionTriggerAnimation']!
|
|
||||||
.controller
|
|
||||||
.reverse();
|
|
||||||
}
|
|
||||||
if (animationsMap[
|
|
||||||
'barcodeOnActionTriggerAnimation'] !=
|
|
||||||
null) {
|
|
||||||
animationsMap[
|
|
||||||
'barcodeOnActionTriggerAnimation']!
|
|
||||||
.controller
|
|
||||||
.stop();
|
|
||||||
}
|
|
||||||
_model.isAccess = !_model.isAccess;
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
text: FFLocalizations.of(context).getText(
|
|
||||||
'mxdrsbmy' /* Liberar QR Code */,
|
|
||||||
),
|
|
||||||
options: FFButtonOptions(
|
|
||||||
height: 40.0,
|
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
||||||
24.0, 0.0, 24.0, 0.0),
|
|
||||||
iconPadding: const EdgeInsetsDirectional.fromSTEB(
|
|
||||||
0.0, 0.0, 0.0, 0.0),
|
|
||||||
color: FlutterFlowTheme.of(context).primary,
|
|
||||||
textStyle: FlutterFlowTheme.of(context)
|
|
||||||
.titleSmall
|
|
||||||
.override(
|
|
||||||
fontFamily: FlutterFlowTheme.of(context)
|
|
||||||
.titleSmallFamily,
|
|
||||||
color: Colors.white,
|
|
||||||
letterSpacing: 0.0,
|
|
||||||
useGoogleFonts: GoogleFonts.asMap()
|
|
||||||
.containsKey(
|
|
||||||
FlutterFlowTheme.of(context)
|
|
||||||
.titleSmallFamily),
|
|
||||||
),
|
|
||||||
elevation: 3.0,
|
|
||||||
borderSide: const BorderSide(
|
|
||||||
color: Colors.transparent,
|
|
||||||
width: 1.0,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (_model.isAccess == true)
|
|
||||||
Container(
|
|
||||||
width: 300.0,
|
|
||||||
decoration: const BoxDecoration(),
|
|
||||||
child: Visibility(
|
|
||||||
visible: _model.isAccess == true,
|
|
||||||
child: Text(
|
|
||||||
FFLocalizations.of(context).getText(
|
|
||||||
'6z6kvmhl' /* Certifique-se de que o QRCode ... */,
|
|
||||||
),
|
|
||||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
|
||||||
fontFamily:
|
|
||||||
FlutterFlowTheme.of(context).bodyMediumFamily,
|
|
||||||
letterSpacing: 0.0,
|
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
|
||||||
FlutterFlowTheme.of(context).bodyMediumFamily),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (_model.isAccess == true)
|
if (_model.isAccess == false)
|
||||||
Container(
|
Align(
|
||||||
width: 250.0,
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
height: 80.0,
|
child: InkWell(
|
||||||
decoration: BoxDecoration(
|
splashColor: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(100.0),
|
focusColor: Colors.transparent,
|
||||||
border: Border.all(
|
hoverColor: Colors.transparent,
|
||||||
color: FlutterFlowTheme.of(context).primary,
|
highlightColor: Colors.transparent,
|
||||||
),
|
onLongPress: () async {
|
||||||
),
|
await _model.qrCodeEncoder(
|
||||||
child: Row(
|
context,
|
||||||
mainAxisSize: MainAxisSize.max,
|
key: _model.key,
|
||||||
children: [
|
);
|
||||||
Expanded(
|
setState(() {});
|
||||||
child: Padding(
|
},
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
child: Container(
|
||||||
10.0, 0.0, 0.0, 0.0),
|
width: 200.0,
|
||||||
child: Text(
|
height: 200.0,
|
||||||
FFLocalizations.of(context).getText(
|
decoration: const BoxDecoration(),
|
||||||
'wkjkxd2e' /* Trocando QR code em */,
|
child: Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: FFButtonWidget(
|
||||||
|
onPressed: () async {
|
||||||
|
await _showQrCodeBottomSheet(context);
|
||||||
|
_toggleQrCodeAccess();
|
||||||
|
},
|
||||||
|
text: FFLocalizations.of(context).getText(
|
||||||
|
'mxdrsbmy' /* Liberar QR Code */,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
options: FFButtonOptions(
|
||||||
style: FlutterFlowTheme.of(context)
|
height: 40.0,
|
||||||
.bodyMedium
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
.override(
|
24.0, 0.0, 24.0, 0.0),
|
||||||
fontFamily: FlutterFlowTheme.of(context)
|
iconPadding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
.bodyMediumFamily,
|
0.0, 0.0, 0.0, 0.0),
|
||||||
letterSpacing: 0.0,
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
fontWeight: FontWeight.w600,
|
textStyle: FlutterFlowTheme.of(context)
|
||||||
useGoogleFonts: GoogleFonts.asMap()
|
.titleSmall
|
||||||
.containsKey(FlutterFlowTheme.of(context)
|
|
||||||
.bodyMediumFamily),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Align(
|
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
|
||||||
0.0, 0.0, 20.0, 0.0),
|
|
||||||
child: CircularPercentIndicator(
|
|
||||||
percent: functions.getProgressValue(1),
|
|
||||||
radius: 30.0,
|
|
||||||
lineWidth: 7.0,
|
|
||||||
animation: true,
|
|
||||||
animateFromLastPercent: true,
|
|
||||||
progressColor: FlutterFlowTheme.of(context).primary,
|
|
||||||
backgroundColor:
|
|
||||||
FlutterFlowTheme.of(context).primaryText,
|
|
||||||
center: Text(
|
|
||||||
FFLocalizations.of(context).getText(
|
|
||||||
'3bfr2tjr' /* 20 */,
|
|
||||||
),
|
|
||||||
style: FlutterFlowTheme.of(context)
|
|
||||||
.headlineSmall
|
|
||||||
.override(
|
.override(
|
||||||
fontFamily: FlutterFlowTheme.of(context)
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
.headlineSmallFamily,
|
.titleSmallFamily,
|
||||||
fontSize: 14.0,
|
color: Colors.white,
|
||||||
letterSpacing: 0.0,
|
letterSpacing: 0.0,
|
||||||
useGoogleFonts: GoogleFonts.asMap()
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
.containsKey(
|
.containsKey(
|
||||||
FlutterFlowTheme.of(context)
|
FlutterFlowTheme.of(context)
|
||||||
.headlineSmallFamily),
|
.titleSmallFamily),
|
||||||
),
|
),
|
||||||
|
elevation: 3.0,
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.transparent,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
),
|
),
|
||||||
startAngle: 20.0,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (_model.isAccess == true)
|
||||||
|
Container(
|
||||||
|
width: 300.0,
|
||||||
|
decoration: const BoxDecoration(),
|
||||||
|
child: Visibility(
|
||||||
|
visible: _model.isAccess == false,
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Certifique-se de que o QRCode está visivel para o leitor',
|
||||||
|
enText: 'Make sure the QRCode is visible to the reader',
|
||||||
|
// '6z6kvmhl' /* Certifique-se de que o QRCode ... */,
|
||||||
|
),
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
if (_model.isAccess == true)
|
||||||
|
Container(
|
||||||
|
width: 250.0,
|
||||||
|
height: 80.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(100.0),
|
||||||
|
border: Border.all(
|
||||||
|
color: FlutterFlowTheme.of(context).primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
10.0, 0.0, 0.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Changing QR code in',
|
||||||
|
ptText: 'Trocando QR code em',
|
||||||
|
// 'wkjkxd2e' /* Trocando QR code em */,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: FlutterFlowTheme.of(context)
|
||||||
|
.bodyMedium
|
||||||
|
.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context)
|
||||||
|
.bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap()
|
||||||
|
.containsKey(FlutterFlowTheme.of(context)
|
||||||
|
.bodyMediumFamily),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
|
0.0, 0.0, 20.0, 0.0),
|
||||||
|
child: StreamBuilder<double>(
|
||||||
|
stream: functions.getProgressValue(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return CircularProgressIndicator();
|
||||||
|
} else if (snapshot.hasError) {
|
||||||
|
return Text('Error: ${snapshot.error}');
|
||||||
|
} else if (!snapshot.hasData) {
|
||||||
|
return Text('No data');
|
||||||
|
} else {
|
||||||
|
final progress = snapshot.data!;
|
||||||
|
return CircularPercentIndicator(
|
||||||
|
percent: progress,
|
||||||
|
radius: 30.0,
|
||||||
|
lineWidth: 7.0,
|
||||||
|
animation: true,
|
||||||
|
animateFromLastPercent: true,
|
||||||
|
onAnimationEnd: () {
|
||||||
|
_resetAnimationAndToggleAccess();
|
||||||
|
},
|
||||||
|
progressColor: FlutterFlowTheme.of(context).primary,
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
center: Text(
|
||||||
|
'${(progress * totalTimeInSeconds / 5).toStringAsFixed(1)}s',
|
||||||
|
style: FlutterFlowTheme.of(context).headlineSmall.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).headlineSmallFamily,
|
||||||
|
fontSize: 14.0,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
FlutterFlowTheme.of(context).headlineSmallFamily),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
startAngle: 20.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toggleQrCodeAccess() {
|
||||||
|
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
||||||
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.stop();
|
||||||
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reverse();
|
||||||
|
}
|
||||||
|
_model.isAccess = !_model.isAccess;
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showQrCodeBottomSheet(BuildContext context) async {
|
||||||
|
await showModalBottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
useSafeArea: true,
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => _model
|
||||||
|
.unfocusNode.canRequestFocus
|
||||||
|
? FocusScope.of(context)
|
||||||
|
.requestFocus(_model.unfocusNode)
|
||||||
|
: FocusScope.of(context).unfocus(),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
MediaQuery.viewInsetsOf(context),
|
||||||
|
child:
|
||||||
|
QrCodePassKeyTemplateComponentWidget(
|
||||||
|
toggleActionStatus: (key) async {
|
||||||
|
_model.key = key;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).then((value) => safeSetState(() {}));
|
||||||
|
|
||||||
|
unawaited(
|
||||||
|
() async {
|
||||||
|
await _model.qrCodeEncoder(
|
||||||
|
context,
|
||||||
|
key: _model.key,
|
||||||
|
);
|
||||||
|
setState(() {});
|
||||||
|
}(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _resetAnimationAndToggleAccess() {
|
||||||
|
setState(() {
|
||||||
|
// Reinicia a animação
|
||||||
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
|
||||||
|
animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
|
||||||
|
// Alterna o estado de acesso
|
||||||
|
_model.isAccess = !_model.isAccess;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AppBar buildAppBar(BuildContext context) {
|
||||||
|
return AppBar(
|
||||||
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
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).getText(
|
||||||
|
'ku7jqe53' /* QR Code de Acesso */,
|
||||||
|
),
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: const [],
|
||||||
|
centerTitle: true,
|
||||||
|
elevation: 0.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@ import 'package:f_r_e_hub/flutter_flow/request_manager.dart';
|
||||||
|
|
||||||
import '/flutter_flow/flutter_flow_util.dart';
|
import '/flutter_flow/flutter_flow_util.dart';
|
||||||
import '/flutter_flow/form_field_controller.dart';
|
import '/flutter_flow/form_field_controller.dart';
|
||||||
import '/flutter_flow/request_manager.dart';
|
|
||||||
|
|
||||||
import 'schedule_complete_visit_page_widget.dart'
|
import 'schedule_complete_visit_page_widget.dart'
|
||||||
show ScheduleCompleteVisitPageWidget;
|
show ScheduleCompleteVisitPageWidget;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -71,23 +69,6 @@ class ScheduleCompleteVisitPageModel
|
||||||
TextEditingController? textController3;
|
TextEditingController? textController3;
|
||||||
String? Function(BuildContext, String?)? textController3Validator;
|
String? Function(BuildContext, String?)? textController3Validator;
|
||||||
|
|
||||||
/// Query cache managers for this widget.
|
|
||||||
|
|
||||||
final _visitHistoryManager = FutureRequestManager<ApiCallResponse>();
|
|
||||||
Future<ApiCallResponse> visitHistory({
|
|
||||||
String? uniqueQueryKey,
|
|
||||||
bool? overrideCache,
|
|
||||||
required Future<ApiCallResponse> Function() requestFn,
|
|
||||||
}) =>
|
|
||||||
_visitHistoryManager.performRequest(
|
|
||||||
uniqueQueryKey: uniqueQueryKey,
|
|
||||||
overrideCache: overrideCache,
|
|
||||||
requestFn: requestFn,
|
|
||||||
);
|
|
||||||
void clearVisitHistoryCache() => _visitHistoryManager.clear();
|
|
||||||
void clearVisitHistoryCacheKey(String? uniqueKey) =>
|
|
||||||
_visitHistoryManager.clearRequest(uniqueKey);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState(BuildContext context) {}
|
void initState(BuildContext context) {}
|
||||||
|
|
||||||
|
@ -125,4 +106,4 @@ class ScheduleCompleteVisitPageModel
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -100,35 +100,6 @@ class _ScheduleCompleteVisitPageWidgetState
|
||||||
_model.switchValue = true;
|
_model.switchValue = true;
|
||||||
_model.textController3 ??= TextEditingController();
|
_model.textController3 ??= TextEditingController();
|
||||||
_model.textFieldFocusNode3 ??= FocusNode();
|
_model.textFieldFocusNode3 ??= FocusNode();
|
||||||
|
|
||||||
|
|
||||||
debugPrint('widget.visitStartDateStr: ${DateTime.parse(widget.visitStartDateStr!)}');
|
|
||||||
debugPrint('widget.visitEndDateStr: ${DateTime.parse(widget.visitEndDateStr!)}');
|
|
||||||
if (widget.visitEndDateStr != null && widget.visitStartDateStr != null) {
|
|
||||||
_model.datePicked1 = DateTime.parse(widget.visitStartDateStr!);
|
|
||||||
_model.datePicked2 = DateTime.parse(widget.visitEndDateStr!);
|
|
||||||
_model.textController1?.text = DateFormat('dd-MM-yyyy HH:mm:ss').format(DateFormat('yyyy-MM-dd HH:mm:ss').parse(widget.visitStartDateStr!));
|
|
||||||
_model.textController2?.text = DateFormat('dd-MM-yyyy HH:mm:ss').format(DateFormat('yyyy-MM-dd HH:mm:ss').parse(widget.visitEndDateStr!));;
|
|
||||||
// _model.textController1?.selection = TextSelection.collapsed(
|
|
||||||
|
|
||||||
// _model.textController1?.text =
|
|
||||||
// dateTimeFormat(
|
|
||||||
// 'd/M/y H:mm:ss',
|
|
||||||
// _model.datePicked1,
|
|
||||||
// locale:
|
|
||||||
// FFLocalizations.of(context)
|
|
||||||
// .languageCode,
|
|
||||||
// );
|
|
||||||
// _model.textController1
|
|
||||||
// ?.selection =
|
|
||||||
// TextSelection.collapsed(
|
|
||||||
// offset: _model
|
|
||||||
// .textController1!
|
|
||||||
// .text
|
|
||||||
// .length);
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadMoreVisitHistory() async {
|
void _loadMoreVisitHistory() async {
|
||||||
|
@ -406,10 +377,10 @@ Widget scheduleVisit(
|
||||||
fadeOutDuration: const Duration(
|
fadeOutDuration: const Duration(
|
||||||
milliseconds: 500),
|
milliseconds: 500),
|
||||||
imageUrl: valueOrDefault<String>(
|
imageUrl: valueOrDefault<String>(
|
||||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
|
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
|
||||||
visitorListViewItem,
|
visitorListViewItem,
|
||||||
r'''$.VTE_DOCUMENTO''',
|
r'''$.VTE_DOCUMENTO''',
|
||||||
).toString()}&tipo=E',
|
).toString()}&tipo=E",
|
||||||
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
|
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -2510,4 +2481,4 @@ Widget visitHistory(
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
40
pubspec.lock
40
pubspec.lock
|
@ -41,6 +41,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
|
barcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: barcode
|
||||||
|
sha256: ab180ce22c6555d77d45f0178a523669db67f95856e3378259ef2ffeb43e6003
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.8"
|
||||||
|
barcode_widget:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: barcode_widget
|
||||||
|
sha256: ea0c0578b5db3ca3a583d80e05eb47bfb70419e3a23b920d93ae7968c45c20ce
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
bloc:
|
bloc:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -949,6 +965,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
|
percent_indicator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: percent_indicator
|
||||||
|
sha256: cec41f67181fbd5322aa68b355621d1a4eea827426b8eeb613f6cbe195ff7b4a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.2"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -981,6 +1005,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.2"
|
||||||
|
qr:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: qr
|
||||||
|
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
|
qr_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: qr_flutter
|
||||||
|
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
responsive_framework:
|
responsive_framework:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -102,6 +102,7 @@ dependencies:
|
||||||
cupertino_icons: ^1.0.0
|
cupertino_icons: ^1.0.0
|
||||||
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
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
http: 1.2.1
|
http: 1.2.1
|
||||||
|
|
Loading…
Reference in New Issue