feat: Add QR code functionality and route

This commit is contained in:
jantunesmesias 2024-07-15 12:24:48 -03:00
parent 6b21d70d4c
commit d41a162562
12 changed files with 681 additions and 358 deletions

View File

@ -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/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:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'dart:developer' as developer;
import '/actions/actions.dart' as action_blocks;
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 '/flutter_flow/flutter_flow_theme.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;
Future repeatVisitScheduleAction(
@ -136,9 +139,13 @@ Future singInLoginAction(
FFAppState().status = PhpGroup.loginCall.userStatus(
(loginCall.jsonBody ?? ''),
)!;
FFAppState().userDevUUID = PhpGroup.loginCall.userDeviceId(
(loginCall.jsonBody ?? ''),
)!;
FFAppState().name = PhpGroup.loginCall.userName(
(loginCall.jsonBody ?? ''),
)!;
FFAppState().serialNumber = await getSerialNumber() ?? '';
FFAppState().isLogged = true;
await action_blocks.toggleHomePage(context);
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.
// }

View File

@ -61,7 +61,13 @@ class FFAppState extends ChangeNotifier {
_name = await secureStorage.getString('ff_name') ?? _name;
});
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;
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 get cliUUID => _cliUUID;
set cliUUID(String value) {
@ -83,6 +100,17 @@ class FFAppState extends ChangeNotifier {
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? get tokenAPNS => _tokenAPNS;

View File

@ -10,6 +10,7 @@ export 'package:collection/collection.dart' show ListEquality;
export 'package:flutter/material.dart' show Color, Colors;
export 'package:from_css_color/from_css_color.dart';
typedef StructBuilder<T> = T Function(Map<String, dynamic> data);
abstract class BaseStruct {

View File

@ -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,
),
},
);
}
}

View File

@ -842,9 +842,8 @@ Propriedade */
child: Text(
FFLocalizations.of(context)
.getVariableText(
ptText: 'Consultar\nConsultar
Históricos */
,
ptText: 'Consultar\nConsultar',
enText: 'Consult\nHistories',
),
style: FlutterFlowTheme.of(context)
.titleLarge
@ -953,9 +952,9 @@ Históricos */
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'589qufkw' /* Históricos',
FFLocalizations.of(context).getVariableText(
enText: 'Consult\nHistories',
ptText: 'Consultar\nHistóricos',
),
style: FlutterFlowTheme.of(context)
.titleLarge

View File

@ -38,3 +38,28 @@ Future<String?> getDevUUID() async {
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
}
}

View File

@ -106,6 +106,14 @@ String jsonToStr(dynamic json) {
return jsonString;
}
double getProgressValue(int percentage) {
return percentage / 100;
}
Stream<double> getProgressValue() {
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;
});
}

View File

@ -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 '/flutter_flow/flutter_flow_animations.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 'dart:async';
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/scheduler.dart';
import 'package:flutter_animate/flutter_animate.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';
export 'qr_code_page_model.dart';
import 'package:qr_flutter/qr_flutter.dart';
class QrCodePageWidget extends StatefulWidget {
const QrCodePageWidget({super.key});
@override
State<QrCodePageWidget> createState() => _QrCodePageWidgetState();
}
class _QrCodePageWidgetState extends State<QrCodePageWidget>
with TickerProviderStateMixin {
late QrCodePageModel _model;
final scaffoldKey = GlobalKey<ScaffoldState>();
final animationsMap = <String, AnimationInfo>{};
@override
void initState() {
super.initState();
_model = createModel(context, () => QrCodePageModel());
@override
void initState() {
super.initState();
_model = createModel(context, () => QrCodePageModel());
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.repeat();
}
});
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!.controller.fling();
}
});
animationsMap.addAll({
'barcodeOnActionTriggerAnimation': AnimationInfo(
trigger: AnimationTrigger.onActionTrigger,
applyInitialState: true,
effectsBuilder: () => [
VisibilityEffect(duration: 1.ms),
BlurEffect(
curve: Curves.linear,
delay: 0.0.ms,
duration: 600.0.ms,
begin: const Offset(0.0, 0.0),
end: const Offset(4.0, 4.0),
),
],
),
});
setupAnimations(
animationsMap.values.where((anim) =>
anim.trigger == AnimationTrigger.onActionTrigger ||
!anim.applyInitialState),
this,
);
}
@override
void dispose() {
_model.dispose();
super.dispose();
animationsMap.addAll({
'barcodeOnActionTriggerAnimation': AnimationInfo(
trigger: AnimationTrigger.onActionTrigger,
applyInitialState: true,
effectsBuilder: () => [
VisibilityEffect(duration: 1.ms),
BlurEffect(
curve: Curves.linear,
delay: 0.0.ms,
duration: 600.0.ms,
begin: const Offset(0.0, 0.0),
end: const Offset(10.0, 10.0),
),
],
),
});
setupAnimations(
animationsMap.values.where((anim) =>
anim.trigger == AnimationTrigger.onActionTrigger ||
!anim.applyInitialState),
this,
);
// // Adicionando um ouvinte de status à animação para reiniciá-la após a conclusão
// animationsMap['barcodeOnActionTriggerAnimation']?.controller.addStatusListener((status) {
// if (status == AnimationStatus.completed) {
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.reset();
// animationsMap['barcodeOnActionTriggerAnimation']!.controller.forward();
// }
// });
}
@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
Widget build(BuildContext context) {
@ -82,66 +106,65 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
child: Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: 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),
appBar: buildAppBar(context),
body: buildBody(context),
),
);
}
Widget buildBody(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
double smallerDimension = screenWidth < screenHeight ? screenWidth : screenHeight;
double dimension = smallerDimension * 0.75;
double totalTimeInSeconds = 100.0;
return SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (_model.isAccess == true)
Text(
FFLocalizations.of(context).getVariableText(
ptText: 'QR Code de Acesso',
enText: 'Access QR Code',
),
),
actions: const [],
centerTitle: true,
elevation: 0.0,
),
body: SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (_model.isAccess == true)
Text(
FFLocalizations.of(context).getText(
'vd84zgfe' /* Use esse QR Code para acesso */,
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(
children: [
if (_model.isAccess == true)
Align(
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(
children: [
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: BarcodeWidget(
if(_model.isAccess == false)
Align(
alignment: const AlignmentDirectional(0, 0),
child: BarcodeWidget(
data: 'Barcode',
barcode: Barcode.qrCode(),
width: 300.0,
@ -156,219 +179,273 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
).animateOnActionTrigger(
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)
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).getText(
'wkjkxd2e' /* Trocando QR code em */,
if (_model.isAccess == false)
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 _showQrCodeBottomSheet(context);
_toggleQrCodeAccess();
},
text: FFLocalizations.of(context).getText(
'mxdrsbmy' /* Liberar QR Code */,
),
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: 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
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)
.headlineSmallFamily,
fontSize: 14.0,
.titleSmallFamily,
color: Colors.white,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap()
.containsKey(
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,
);
}
}

View File

@ -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/form_field_controller.dart';
import '/flutter_flow/request_manager.dart';
import 'schedule_complete_visit_page_widget.dart'
show ScheduleCompleteVisitPageWidget;
import 'package:flutter/material.dart';
@ -71,23 +69,6 @@ class ScheduleCompleteVisitPageModel
TextEditingController? textController3;
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
void initState(BuildContext context) {}
@ -125,4 +106,4 @@ class ScheduleCompleteVisitPageModel
return false;
}
}
}

View File

@ -100,35 +100,6 @@ class _ScheduleCompleteVisitPageWidgetState
_model.switchValue = true;
_model.textController3 ??= TextEditingController();
_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 {
@ -406,10 +377,10 @@ Widget scheduleVisit(
fadeOutDuration: const Duration(
milliseconds: 500),
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,
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',
),
fit: BoxFit.cover,
@ -2510,4 +2481,4 @@ Widget visitHistory(
);
}
}

View File

@ -41,6 +41,22 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@ -949,6 +965,14 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:
@ -981,6 +1005,22 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct main"
description:

View File

@ -102,6 +102,7 @@ dependencies:
cupertino_icons: ^1.0.0
flutter_bloc: ^8.1.6
flutter_riverpod: ^2.5.1
qr_flutter: ^4.1.0
dependency_overrides:
http: 1.2.1