Merge pull request #99 from FRE-Informatica/feat/fd-465
FEAT/FD-465: Documentação no APP
This commit is contained in:
commit
fb5f755d70
|
@ -4,26 +4,34 @@
|
|||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "flutter-freaccesss-hub",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"args": [
|
||||
"--no-enable-impeller"
|
||||
"--no-enable-impeller",
|
||||
" --enable-experiment=macros"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter-freaccesss-hub (profile mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
"flutterMode": "profile",
|
||||
"args": [
|
||||
"--no-enable-impeller",
|
||||
" --enable-experiment=macros"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter-freaccesss-hub (release mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
"flutterMode": "release",
|
||||
"args": [
|
||||
"--no-enable-impeller",
|
||||
" --enable-experiment=macros"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2,3 +2,4 @@ description: This file stores settings for Dart & Flutter DevTools.
|
|||
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||
extensions:
|
||||
- provider: true
|
||||
- patrol: true
|
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
|
@ -1,5 +1,5 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
|
@ -26,7 +26,6 @@ import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart
|
|||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:flutter_web_plugins/url_strategy.dart';
|
||||
import 'package:patrol/patrol.dart';
|
||||
|
||||
import 'app_test.dart';
|
||||
import 'fuzzer/fuzzer.dart';
|
||||
|
|
|
@ -48,11 +48,11 @@ class AuthenticationTest {
|
|||
await _navigateToSignIn($);
|
||||
|
||||
for (var credential in credentials) {
|
||||
print('Função: ${credential.functionName}');
|
||||
print('Entradas: ${credential.inputs}');
|
||||
print('Saída: ${credential.output}');
|
||||
print('Mensagem: ${credential.message}');
|
||||
print('---');
|
||||
log('Função: ${credential.functionName}');
|
||||
log('Entradas: ${credential.inputs}');
|
||||
log('Saída: ${credential.output}');
|
||||
log('Mensagem: ${credential.message}');
|
||||
log('---');
|
||||
|
||||
await _auth(credential.output, $, throwsException);
|
||||
}
|
||||
|
@ -156,11 +156,11 @@ class AuthenticationTest {
|
|||
await $.pumpWidgetAndSettle(const App());
|
||||
|
||||
for (var credential in credentials) {
|
||||
print('Função: ${credential.functionName}');
|
||||
print('Entradas: ${credential.inputs}');
|
||||
print('Saída: ${credential.output}');
|
||||
print('Mensagem: ${credential.message}');
|
||||
print('---');
|
||||
log('Função: ${credential.functionName}');
|
||||
log('Entradas: ${credential.inputs}');
|
||||
log('Saída: ${credential.output}');
|
||||
log('Mensagem: ${credential.message}');
|
||||
log('---');
|
||||
|
||||
await _navigateToSignUp($);
|
||||
await _auth(credential.output, $, throwsException);
|
||||
|
@ -255,10 +255,3 @@ Future<void> _submit(
|
|||
_navigateBackUsingSystemGesture();
|
||||
}
|
||||
}
|
||||
|
||||
String _generateRandomString(int length) {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
final rand = Random();
|
||||
return List.generate(length, (index) => chars[rand.nextInt(chars.length)])
|
||||
.join();
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ class MenuTest {
|
|||
route = entry.key;
|
||||
title = entry.value;
|
||||
|
||||
print('route: $route');
|
||||
print('title: $title');
|
||||
log('route: $route');
|
||||
log('title: $title');
|
||||
|
||||
if (route == '/petsPage') continue;
|
||||
if (route == '/fastPassPage') continue;
|
||||
|
@ -326,7 +326,6 @@ class MenuTest {
|
|||
final Key? widgetKey = entry.key;
|
||||
expect(widgetKey, isNotNull);
|
||||
|
||||
print('WIDGETKEY = $widgetKey');
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-FASTPASS')) continue;
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-QRCODE')) continue;
|
||||
if (widgetKey == ValueKey<String>('FRE-HUB-RESERVATIONS')) continue;
|
||||
|
|
|
@ -25,7 +25,7 @@ Future<void> _loggedWithMultiLocalsAccount(
|
|||
.set(ProfileStorageKey.ownerUUID.key, '7');
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||
await PhpGroup //
|
||||
await FreAccessWSGlobal //
|
||||
.resopndeVinculo
|
||||
.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl() //
|
||||
|
@ -58,7 +58,7 @@ Future<void> _loggedWithSomeoneLocalAccount(
|
|||
.set(ProfileStorageKey.ownerUUID.key, '7');
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||
await PhpGroup //
|
||||
await FreAccessWSGlobal //
|
||||
.resopndeVinculo
|
||||
.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl() //
|
||||
|
|
|
@ -33,7 +33,7 @@ class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double limitedInputTextSize = LimitedFontSizeUtil.getInputFontSize(context);
|
||||
bool _isLoading = false;
|
||||
bool isLoading = false;
|
||||
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
|
@ -72,7 +72,7 @@ class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
|||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
isLoading = true;
|
||||
});
|
||||
final selectedMedia =
|
||||
await selectMediaWithSourceBottomSheet(
|
||||
|
@ -120,7 +120,7 @@ class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
|||
showUploadMessage(context, message);
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
isLoading = false;
|
||||
});
|
||||
final message = FFLocalizations.of(context)
|
||||
.getVariableText(
|
||||
|
@ -131,7 +131,7 @@ class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
|||
}
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -150,7 +150,7 @@ class _MediaUploadButtonUtilState extends State<MediaUploadButtonUtil> {
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_isLoading
|
||||
isLoading
|
||||
? SizedBox(
|
||||
width: 30.0,
|
||||
height: 30.0,
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:hub/shared/utils/log_util.dart';
|
|||
|
||||
import '/flutter_flow/flutter_flow_theme.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
||||
BottomArrowLinkedLocalsComponentWidget({super.key, required this.response});
|
||||
ApiCallResponse? response;
|
||||
|
@ -76,7 +77,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
Future<ApiCallResponse?> _fetchLocals() async {
|
||||
try {
|
||||
setState(() => _loading = true);
|
||||
widget.response = await PhpGroup.getLocalsCall.call();
|
||||
widget.response = await FreAccessWSGlobal.getLocalsCall.call();
|
||||
final bool isError = widget.response?.jsonBody['error'];
|
||||
|
||||
if (isError) {
|
||||
|
@ -148,7 +149,8 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
Future<dynamic> _fetchResponseLink(String status, String cliID) async {
|
||||
try {
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, cliID);
|
||||
var response = await PhpGroup.resopndeVinculo.call(tarefa: status);
|
||||
var response =
|
||||
await FreAccessWSGlobal.resopndeVinculo.call(tarefa: status);
|
||||
|
||||
if (response.jsonBody['error'] == false) {
|
||||
return {
|
||||
|
@ -204,7 +206,6 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
}
|
||||
|
||||
Widget _item(BuildContext context, dynamic local) {
|
||||
log('local: ${local['CLI_NOME']}');
|
||||
return CardItemTemplateComponentWidget(
|
||||
key: ValueKey<String>(local['CLI_NOME']),
|
||||
imagePath: _imagePath(local),
|
||||
|
|
|
@ -781,7 +781,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
|||
IconButton(
|
||||
onPressed: () async {
|
||||
_model.postScheduleVisit =
|
||||
await PhpGroup.postScheduleVisitCall.call(
|
||||
await FreAccessWSGlobal.postScheduleVisitCall.call(
|
||||
devDesc: widget.visitObsStr,
|
||||
idVisitante: widget.visitorStrList,
|
||||
dtInicio:
|
||||
|
@ -793,13 +793,14 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
|||
obs: widget.visitObsStr,
|
||||
);
|
||||
|
||||
if (PhpGroup.postScheduleVisitCall.error(
|
||||
if (FreAccessWSGlobal.postScheduleVisitCall.error(
|
||||
(_model.postScheduleVisit?.jsonBody ?? ''),
|
||||
) ==
|
||||
false) {
|
||||
context.pop();
|
||||
} else {
|
||||
final String? msg = PhpGroup.postScheduleVisitCall.errorMsg(
|
||||
final String? msg =
|
||||
FreAccessWSGlobal.postScheduleVisitCall.errorMsg(
|
||||
(_model.postScheduleVisit?.jsonBody ?? ''),
|
||||
);
|
||||
await DialogUtil.error(context, msg!)
|
||||
|
|
|
@ -75,7 +75,7 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
|||
),
|
||||
),
|
||||
child: FutureBuilder<ApiCallResponse>(
|
||||
future: PhpGroup.getLocalsCall.call(),
|
||||
future: FreAccessWSGlobal.getLocalsCall.call(),
|
||||
builder: (context, snapshot) {
|
||||
// Customize what your widget looks like when it's loading.
|
||||
if (!snapshot.hasData) {
|
||||
|
@ -94,7 +94,7 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
|||
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
final eachLocals = (PhpGroup.getLocalsCall
|
||||
final eachLocals = (FreAccessWSGlobal.getLocalsCall
|
||||
.locais(
|
||||
gridViewGetLocalsResponse.jsonBody,
|
||||
)
|
||||
|
|
|
@ -63,14 +63,14 @@ class AccessNotificationModalTemplateComponentModel
|
|||
}) async {
|
||||
ApiCallResponse? visitRequest;
|
||||
|
||||
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
||||
visitRequest = await FreAccessWSGlobal.respondeSolicitacaoCall.call(
|
||||
referencia: refUUID,
|
||||
tarefa: actionValue,
|
||||
resposta: responseValue,
|
||||
idVisitante: vteUUID,
|
||||
);
|
||||
|
||||
if (PhpGroup.respondeSolicitacaoCall.error(
|
||||
if (FreAccessWSGlobal.respondeSolicitacaoCall.error(
|
||||
(visitRequest.jsonBody ?? ''),
|
||||
) ==
|
||||
false) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import 'package:cached_network_image/cached_network_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import '/flutter_flow/flutter_flow_theme.dart';
|
||||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
|
@ -159,6 +158,7 @@ class _CardItemTemplateComponentWidgetState
|
|||
}
|
||||
|
||||
Widget _generateImage() {
|
||||
log('img: ${widget.imagePath ?? ''}');
|
||||
// CachedNetworkImage.evictFromCache(widget.imagePath ?? '');
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
|
|
|
@ -67,7 +67,9 @@ class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
|||
// CachedNetworkImage.evictFromCache(widget.imagePath ?? '');
|
||||
final double limitedBodyFontSize =
|
||||
LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
return Container(
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width,
|
||||
maxHeight: MediaQuery.of(context).size.height,
|
||||
|
@ -143,7 +145,8 @@ class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
|||
fontWeight: FontWeight.bold,
|
||||
color: FlutterFlowTheme.of(context).info,
|
||||
letterSpacing: 0.0,
|
||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||
useGoogleFonts:
|
||||
GoogleFonts.asMap().containsKey(
|
||||
FlutterFlowTheme.of(context)
|
||||
.labelMediumFamily,
|
||||
),
|
||||
|
@ -156,7 +159,8 @@ class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
|||
.labelMediumFamily,
|
||||
color: FlutterFlowTheme.of(context).info,
|
||||
letterSpacing: 0.0,
|
||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||
useGoogleFonts:
|
||||
GoogleFonts.asMap().containsKey(
|
||||
FlutterFlowTheme.of(context)
|
||||
.labelMediumFamily,
|
||||
),
|
||||
|
@ -179,7 +183,8 @@ class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
|||
color: FlutterFlowTheme.of(context).info,
|
||||
letterSpacing: 0.0,
|
||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||
FlutterFlowTheme.of(context).labelMediumFamily,
|
||||
FlutterFlowTheme.of(context)
|
||||
.labelMediumFamily,
|
||||
),
|
||||
fontSize: limitedBodyFontSize,
|
||||
),
|
||||
|
@ -295,6 +300,7 @@ class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
|||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ class _MessageNotificationModalTemplateComponentWidgetState
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
double limitedSubHeaderFontSize =
|
||||
LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
||||
|
||||
return Container(
|
||||
|
|
|
@ -951,7 +951,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
|||
? null
|
||||
: () async {
|
||||
try {
|
||||
model.provVisitSchedule = await PhpGroup
|
||||
model.provVisitSchedule =
|
||||
await FreAccessWSGlobal
|
||||
.postProvVisitSchedulingCall
|
||||
.call(
|
||||
data: DateFormat('dd/MM/yyyy HH:mm:ss')
|
||||
|
@ -964,7 +965,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
|||
nome: model.personNameTextController.text,
|
||||
proID: model.ownerUUID,
|
||||
);
|
||||
if (PhpGroup.postProvVisitSchedulingCall
|
||||
if (FreAccessWSGlobal
|
||||
.postProvVisitSchedulingCall
|
||||
.error((model.provVisitSchedule
|
||||
?.jsonBody ??
|
||||
'')) ==
|
||||
|
@ -982,7 +984,7 @@ class _ScheduleProvisionalVisitPageWidgetState
|
|||
model.notesTextController?.clear();
|
||||
});
|
||||
} else {
|
||||
var message = PhpGroup
|
||||
var message = FreAccessWSGlobal
|
||||
.postProvVisitSchedulingCall
|
||||
.msg((model.provVisitSchedule
|
||||
?.jsonBody ??
|
||||
|
|
|
@ -46,7 +46,7 @@ class RegisiterVistorTemplateComponentModel
|
|||
|
||||
Future<bool> getVisitanteByDocument(
|
||||
String document, BuildContext context) async {
|
||||
final response = await PhpGroup.getVisitorByDocCall.call(
|
||||
final response = await FreAccessWSGlobal.getVisitorByDocCall.call(
|
||||
documento: document,
|
||||
);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import '/flutter_flow/flutter_flow_theme.dart';
|
|||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
import '/flutter_flow/flutter_flow_widgets.dart';
|
||||
import '/flutter_flow/form_field_controller.dart';
|
||||
import '/flutter_flow/upload_data.dart';
|
||||
import 'regisiter_vistor_template_component_model.dart';
|
||||
|
||||
export 'regisiter_vistor_template_component_model.dart';
|
||||
|
@ -43,10 +42,6 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
void _resetForm() {
|
||||
_formKey.currentState?.reset();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
@ -766,7 +761,7 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
_model.uploadedLocalFile,
|
||||
);
|
||||
_model.scheduleVisitor =
|
||||
await PhpGroup.postScheduleVisitorCall
|
||||
await FreAccessWSGlobal.postScheduleVisitorCall
|
||||
.call(
|
||||
documento: _model.textController2.text,
|
||||
nome: _model.textController1.text,
|
||||
|
@ -781,7 +776,7 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
.onError((e, s) async {
|
||||
return await DialogUtil.errorDefault(context);
|
||||
});
|
||||
if (PhpGroup.postScheduleVisitorCall.error(
|
||||
if (FreAccessWSGlobal.postScheduleVisitorCall.error(
|
||||
(_model.scheduleVisitor?.jsonBody ?? ''),
|
||||
) ==
|
||||
false) {
|
||||
|
@ -828,8 +823,8 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
} else {
|
||||
return await DialogUtil.error(
|
||||
context,
|
||||
PhpGroup.postScheduleVisitorCall.errorMsg(
|
||||
_model
|
||||
FreAccessWSGlobal.postScheduleVisitorCall
|
||||
.errorMsg(_model
|
||||
.scheduleVisitor?.jsonBody) ==
|
||||
null
|
||||
? FFLocalizations.of(context)
|
||||
|
@ -838,7 +833,8 @@ class _RegisiterVistorTemplateComponentWidgetState
|
|||
'Erro ao se conectar com o servidor',
|
||||
enText: 'Error connecting to server',
|
||||
)
|
||||
: PhpGroup.postScheduleVisitorCall
|
||||
: FreAccessWSGlobal
|
||||
.postScheduleVisitorCall
|
||||
.errorMsg(
|
||||
_model.scheduleVisitor?.jsonBody)
|
||||
.toString());
|
||||
|
|
|
@ -107,9 +107,9 @@ class _SignUpTemplateComponentWidgetState
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MediaQueryData mediaQuery = MediaQuery.of(context);
|
||||
final double screenWidth = mediaQuery.size.width;
|
||||
final double screenHeight = mediaQuery.size.height;
|
||||
// final MediaQueryData mediaQuery = MediaQuery.of(context);
|
||||
// final double screenWidth = mediaQuery.size.width;
|
||||
// final double screenHeight = mediaQuery.size.height;
|
||||
|
||||
double limitedHeaderFontSize =
|
||||
LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
|
|
|
@ -818,11 +818,11 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
|
|||
),
|
||||
onPressed: () async {
|
||||
_model.deleteVisit =
|
||||
await PhpGroup.deleteVisitCall.call(
|
||||
await FreAccessWSGlobal.deleteVisitCall.call(
|
||||
idVisita: widget.visitIdStr,
|
||||
);
|
||||
|
||||
if (PhpGroup.deleteVisitCall.error(
|
||||
if (FreAccessWSGlobal.deleteVisitCall.error(
|
||||
(_model.deleteVisit?.jsonBody ?? ''),
|
||||
) ==
|
||||
false) {
|
||||
|
|
|
@ -406,23 +406,23 @@ class _VisitorSearchModalTemplateComponentWidgetState
|
|||
_model.textController?.selection =
|
||||
TextSelection.collapsed(offset: _model.textController!.text.length);
|
||||
});
|
||||
_model.getVisitorByDoc = await PhpGroup.getVisitorByDocCall.call(
|
||||
_model.getVisitorByDoc = await FreAccessWSGlobal.getVisitorByDocCall.call(
|
||||
documento: _model.textController.text.replaceFirst(RegExp(r'^0+'), ''));
|
||||
|
||||
if (PhpGroup.getVisitorByDocCall
|
||||
if (FreAccessWSGlobal.getVisitorByDocCall
|
||||
.vistanteId((_model.getVisitorByDoc?.jsonBody ?? '')) !=
|
||||
'0' &&
|
||||
PhpGroup.getVisitorByDocCall
|
||||
FreAccessWSGlobal.getVisitorByDocCall
|
||||
.error((_model.getVisitorByDoc?.jsonBody ?? '')) ==
|
||||
false &&
|
||||
PhpGroup.getVisitorByDocCall
|
||||
FreAccessWSGlobal.getVisitorByDocCall
|
||||
.vistanteId((_model.getVisitorByDoc?.jsonBody ?? '')) !=
|
||||
null) {
|
||||
String newDoc =
|
||||
_model.textController.text.replaceFirst(RegExp(r'^0+'), '');
|
||||
bool existDoc = _model.docs.contains(newDoc);
|
||||
if (existDoc == false) {
|
||||
_model.addToVisitors(PhpGroup.getVisitorByDocCall
|
||||
_model.addToVisitors(FreAccessWSGlobal.getVisitorByDocCall
|
||||
.visitante((_model.getVisitorByDoc?.jsonBody ?? '')));
|
||||
safeSetState(() {});
|
||||
_model.addToDocs(
|
||||
|
|
|
@ -14,7 +14,7 @@ import '../../../flutter_flow/random_data_util.dart';
|
|||
class AuthenticationService {
|
||||
static Future<void> login(BuildContext context) async {
|
||||
try {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||
final response = await callback.call();
|
||||
|
||||
if (response.jsonBody['error']) {
|
||||
|
@ -46,7 +46,7 @@ class AuthenticationService {
|
|||
}) async {
|
||||
try {
|
||||
final ApiCallResponse? response;
|
||||
final LoginCall callback = PhpGroup.loginCall;
|
||||
final LoginCall callback = FreAccessWSGlobal.loginCall;
|
||||
String deviceDescription = randomString(10, 10, true, false, false);
|
||||
await StorageHelper()
|
||||
.set(SecureStorageKey.deviceDescription.value, deviceDescription);
|
||||
|
@ -111,7 +111,7 @@ class AuthenticationService {
|
|||
if ((email != null && email != '') &&
|
||||
(passwd != null && passwd != '' && passwd.length > 7) &&
|
||||
(name != null && name != '')) {
|
||||
response = await PhpGroup.registerCall.call(
|
||||
response = await FreAccessWSGlobal.registerCall.call(
|
||||
name: name,
|
||||
password: passwd,
|
||||
email: email,
|
||||
|
@ -137,7 +137,7 @@ class AuthenticationService {
|
|||
}
|
||||
|
||||
static Future<void> signOut(BuildContext context) async {
|
||||
await PhpGroup.unregisterDevice.call();
|
||||
await FreAccessWSGlobal.unregisterDevice.call();
|
||||
final Map<String, dynamic> extra = <String, dynamic>{
|
||||
kTransitionInfoKey: const TransitionInfo(
|
||||
hasTransition: true,
|
||||
|
@ -158,7 +158,7 @@ class AuthenticationService {
|
|||
static Future<bool> forgotPassword(BuildContext context, String email) async {
|
||||
try {
|
||||
final ApiCallResponse? response;
|
||||
final ForgotPasswordCall callback = PhpGroup.forgotPasswordCall;
|
||||
final ForgotPasswordCall callback = FreAccessWSGlobal.forgotPasswordCall;
|
||||
final String message = FFLocalizations.of(context).getVariableText(
|
||||
enText: "Send E-mail Successful!",
|
||||
ptText: "E-mail Enviado com Sucesso!");
|
||||
|
@ -183,7 +183,8 @@ class AuthenticationService {
|
|||
static Future<bool> changePassword(
|
||||
BuildContext context, String email, String password, String token) async {
|
||||
try {
|
||||
final ApiCallResponse response = await PhpGroup.changePasswordCall
|
||||
final ApiCallResponse response = await FreAccessWSGlobal
|
||||
.changePasswordCall
|
||||
.call(email: email, psswd: password, token: token);
|
||||
|
||||
if (response.jsonBody['error'] == false) {
|
||||
|
@ -209,7 +210,7 @@ class AuthenticationService {
|
|||
static Future<void> deleteAccount(BuildContext context) async {
|
||||
String content;
|
||||
try {
|
||||
await PhpGroup.deleteAccount.call().then((value) async {
|
||||
await FreAccessWSGlobal.deleteAccount.call().then((value) async {
|
||||
if (value.jsonBody['error'] == false) {
|
||||
content = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Account deleted successfully',
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
// ignore_for_file: unused_element
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hub/features/documents/documents.dart' as doc;
|
||||
import 'package:hub/features/notification/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
import 'package:hub/shared/utils/validator_util.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
|
||||
import '/flutter_flow/flutter_flow_util.dart';
|
||||
import 'api_manager.dart';
|
||||
|
@ -22,7 +26,9 @@ abstract class Api {
|
|||
GetLicense getLicense = GetLicense();
|
||||
}
|
||||
|
||||
class PhpGroup extends Api {
|
||||
abstract interface class Endpoint {}
|
||||
|
||||
class FreAccessWSGlobal extends Api {
|
||||
static String getBaseUrl() => 'https://freaccess.com.br/freaccess';
|
||||
static Map<String, String> headers = {};
|
||||
static LoginCall loginCall = LoginCall();
|
||||
|
@ -73,6 +79,9 @@ class PhpGroup extends Api {
|
|||
static UpdateVehicle updateVehicle = UpdateVehicle();
|
||||
static DeleteVehicle deleteVehicle = DeleteVehicle();
|
||||
static CancelDeleteVehicle cancelDelete = CancelDeleteVehicle();
|
||||
static GetPDF getPDF = GetPDF();
|
||||
static GetCategories getCategories = GetCategories();
|
||||
static GetDocuments getDocuments = GetDocuments();
|
||||
}
|
||||
|
||||
class CancelDeleteVehicle {
|
||||
|
@ -82,7 +91,7 @@ class CancelDeleteVehicle {
|
|||
required final String model,
|
||||
required final String color,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -124,7 +133,7 @@ class DeleteVehicle {
|
|||
required final String model,
|
||||
required final String color,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -167,7 +176,7 @@ class RegisterVehicle {
|
|||
final String? color,
|
||||
final String? model,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -211,7 +220,7 @@ class UpdateVehicle {
|
|||
final String? color,
|
||||
final String? model,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -246,11 +255,115 @@ class UpdateVehicle {
|
|||
alwaysAllowBody: false,
|
||||
);
|
||||
}
|
||||
|
||||
static GetCategories getCategories = GetCategories();
|
||||
static GetDocuments getDocuments = GetDocuments();
|
||||
}
|
||||
|
||||
class GetProvSchedules {
|
||||
class GetPDF extends Endpoint {
|
||||
Future<Uri> call(final int id) async {
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? '';
|
||||
final String cliUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
const String atividade = 'visualizarDocumento';
|
||||
const String callname = 'getDocumento.php';
|
||||
|
||||
return Uri.parse(
|
||||
"$baseUrl/$callname?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=$atividade&documentId=$id");
|
||||
}
|
||||
}
|
||||
|
||||
class GetCategories extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? '';
|
||||
final String cliID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
const String atividade = 'listaCategoriasDocumentos';
|
||||
const String pageSize = '10';
|
||||
// final bool isFiltered = filter != '' && filter != '.*';
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'listaCategoriasDocumentos',
|
||||
apiUrl: '$baseUrl/processRequest.php',
|
||||
callType: ApiCallType.POST,
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
params: {
|
||||
// if (isFiltered) 'filter': filter,
|
||||
'devUUID': devUUID,
|
||||
'userUUID': userUUID,
|
||||
'cliID': cliID,
|
||||
'atividade': atividade,
|
||||
'pageSize': pageSize,
|
||||
},
|
||||
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||
returnBody: true,
|
||||
encodeBodyUtf8: false,
|
||||
decodeUtf8: false,
|
||||
cache: false,
|
||||
isStreamingApi: false,
|
||||
alwaysAllowBody: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetDocuments extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call(
|
||||
final dynamic page,
|
||||
final Query query,
|
||||
) async {
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? '';
|
||||
final String cliID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
const String atividade = 'listaDocumentos';
|
||||
const String pageSize = '10';
|
||||
// final bool isFiltered = filter != '' && filter != '.*';
|
||||
// final isCategory = !category;
|
||||
// final isDescription = !desc.isNullOrEmpty;
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'listaDocumentos',
|
||||
apiUrl: '$baseUrl/processRequest.php',
|
||||
callType: ApiCallType.POST,
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
params: {
|
||||
// if (isFiltered) 'filter': filter,
|
||||
|
||||
'devUUID': devUUID,
|
||||
'userUUID': userUUID,
|
||||
'cliID': cliID,
|
||||
'atividade': atividade,
|
||||
'page': page.toString(),
|
||||
'pageSize': pageSize,
|
||||
if (query is doc.Category) 'categoryId': query.id,
|
||||
if (query is doc.Document) 'searh': query.description,
|
||||
},
|
||||
bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
|
||||
returnBody: true,
|
||||
encodeBodyUtf8: false,
|
||||
decodeUtf8: false,
|
||||
cache: false,
|
||||
isStreamingApi: false,
|
||||
alwaysAllowBody: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetProvSchedules extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call(final String page, final String status) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -286,9 +399,10 @@ class GetProvSchedules {
|
|||
}
|
||||
}
|
||||
|
||||
class GetOpenedVisits {
|
||||
class GetOpenedVisits extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call(final String page) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -321,9 +435,10 @@ class GetOpenedVisits {
|
|||
}
|
||||
}
|
||||
|
||||
class GetResidentsByProperty {
|
||||
class GetResidentsByProperty extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call(final String page) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -355,9 +470,10 @@ class GetResidentsByProperty {
|
|||
}
|
||||
}
|
||||
|
||||
class GetVehiclesByProperty {
|
||||
class GetVehiclesByProperty extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call(final String page) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -391,9 +507,10 @@ class GetVehiclesByProperty {
|
|||
static GetLicense getLicense = GetLicense();
|
||||
}
|
||||
|
||||
class GetLicense {
|
||||
class GetLicense extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -425,9 +542,10 @@ class GetLicense {
|
|||
}
|
||||
}
|
||||
|
||||
class UnregisterDevice {
|
||||
class UnregisterDevice extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -455,9 +573,10 @@ class UnregisterDevice {
|
|||
}
|
||||
}
|
||||
|
||||
class DeletePet {
|
||||
class DeletePet extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({final int? petID = 0}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -491,7 +610,8 @@ class DeletePet {
|
|||
}
|
||||
}
|
||||
|
||||
class UpdatePet {
|
||||
class UpdatePet extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final int? petID,
|
||||
final String? image,
|
||||
|
@ -504,7 +624,7 @@ class UpdatePet {
|
|||
final String? size,
|
||||
final String? notes,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -550,12 +670,13 @@ class UpdatePet {
|
|||
}
|
||||
}
|
||||
|
||||
class GetPets {
|
||||
class GetPets extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final int? page,
|
||||
final int? pageSize,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -590,9 +711,10 @@ class GetPets {
|
|||
}
|
||||
}
|
||||
|
||||
class GetPetPhoto {
|
||||
class GetPetPhoto extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({final int? petId}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -626,7 +748,8 @@ class GetPetPhoto {
|
|||
}
|
||||
}
|
||||
|
||||
class RegisterPet {
|
||||
class RegisterPet extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? image,
|
||||
final String? name,
|
||||
|
@ -638,7 +761,7 @@ class RegisterPet {
|
|||
final String? size,
|
||||
final String? notes,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -683,7 +806,8 @@ class RegisterPet {
|
|||
}
|
||||
}
|
||||
|
||||
class BuscaEnconcomendas {
|
||||
class BuscaEnconcomendas extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? page,
|
||||
final String? pageSize,
|
||||
|
@ -698,7 +822,7 @@ class BuscaEnconcomendas {
|
|||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
const String atividade = 'getEncomendas';
|
||||
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'getEncomendas',
|
||||
|
@ -727,7 +851,8 @@ class BuscaEnconcomendas {
|
|||
}
|
||||
}
|
||||
|
||||
class CancelaVisita {
|
||||
class CancelaVisita extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final int? idDestino,
|
||||
final int? idVisita,
|
||||
|
@ -735,7 +860,7 @@ class CancelaVisita {
|
|||
final String? UsuEmail,
|
||||
final String? DevDesc,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -772,14 +897,15 @@ class CancelaVisita {
|
|||
}
|
||||
}
|
||||
|
||||
class DeleteAccount {
|
||||
class DeleteAccount extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? '';
|
||||
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'deleteAccount',
|
||||
apiUrl: '$baseUrl/deleteAccount.php',
|
||||
|
@ -802,11 +928,12 @@ class DeleteAccount {
|
|||
}
|
||||
}
|
||||
|
||||
class ChangePanic {
|
||||
class ChangePanic extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? newSenhaPanico,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -841,11 +968,12 @@ class ChangePanic {
|
|||
}
|
||||
}
|
||||
|
||||
class ChangePass {
|
||||
class ChangePass extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? newSenha,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -880,11 +1008,12 @@ class ChangePass {
|
|||
}
|
||||
}
|
||||
|
||||
class RespondeVinculo {
|
||||
class RespondeVinculo extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? tarefa,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -917,11 +1046,12 @@ class RespondeVinculo {
|
|||
}
|
||||
}
|
||||
|
||||
class ChangeNotifica {
|
||||
class ChangeNotifica extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? notifica,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -956,9 +1086,10 @@ class ChangeNotifica {
|
|||
}
|
||||
}
|
||||
|
||||
class UpdateIDE {
|
||||
class UpdateIDE extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -995,9 +1126,10 @@ class UpdateIDE {
|
|||
}
|
||||
}
|
||||
|
||||
class UpdToken {
|
||||
class UpdToken extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1028,9 +1160,10 @@ class UpdToken {
|
|||
}
|
||||
}
|
||||
|
||||
class LoginCall {
|
||||
class LoginCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String email =
|
||||
|
@ -1078,7 +1211,8 @@ class LoginCall {
|
|||
}
|
||||
}
|
||||
|
||||
class RegisterCall {
|
||||
class RegisterCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
required final String name,
|
||||
required final String email,
|
||||
|
@ -1088,7 +1222,7 @@ class RegisterCall {
|
|||
required final String tipo,
|
||||
required final String descricao,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'register',
|
||||
|
@ -1117,13 +1251,14 @@ class RegisterCall {
|
|||
}
|
||||
}
|
||||
|
||||
class ChangePasswordCall {
|
||||
class ChangePasswordCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
required final String email,
|
||||
required final String token,
|
||||
required final String psswd,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
final String userUUID =
|
||||
|
@ -1157,11 +1292,12 @@ class ChangePasswordCall {
|
|||
}
|
||||
}
|
||||
|
||||
class ForgotPasswordCall {
|
||||
class ForgotPasswordCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? email,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
return await ApiManager.instance.makeApiCall(
|
||||
callName: 'forgotPassword',
|
||||
|
@ -1184,9 +1320,10 @@ class ForgotPasswordCall {
|
|||
}
|
||||
}
|
||||
|
||||
class GetLocalsCall {
|
||||
class GetLocalsCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
||||
|
@ -1223,14 +1360,15 @@ class GetLocalsCall {
|
|||
) as List?;
|
||||
}
|
||||
|
||||
class PostScheduleVisitorCall {
|
||||
class PostScheduleVisitorCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
required final String documento,
|
||||
required final String nome,
|
||||
required final String tipo,
|
||||
required final String foto,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1277,7 +1415,8 @@ class PostScheduleVisitorCall {
|
|||
));
|
||||
}
|
||||
|
||||
class PostScheduleVisitCall {
|
||||
class PostScheduleVisitCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? devDesc,
|
||||
final String? idVisitante,
|
||||
|
@ -1288,7 +1427,7 @@ class PostScheduleVisitCall {
|
|||
final int? idNAC,
|
||||
final String? obs,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1339,13 +1478,14 @@ class PostScheduleVisitCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetScheduleVisitCall {
|
||||
class GetScheduleVisitCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final int? pageSize,
|
||||
final int? pageNumber,
|
||||
final String? chaveBusca,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1620,9 +1760,10 @@ class GetScheduleVisitCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetDadosCall {
|
||||
class GetDadosCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1866,11 +2007,12 @@ class GetDadosCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetVisitorByDocCall {
|
||||
class GetVisitorByDocCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? documento,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1922,12 +2064,13 @@ class GetVisitorByDocCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetFotoVisitanteCall {
|
||||
class GetFotoVisitanteCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? documento,
|
||||
final String? tipo,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -1962,14 +2105,15 @@ class GetFotoVisitanteCall {
|
|||
}
|
||||
}
|
||||
|
||||
class PostProvVisitSchedulingCall {
|
||||
class PostProvVisitSchedulingCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? data,
|
||||
final String? motivo,
|
||||
final String? nome,
|
||||
final String? proID,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2016,12 +2160,13 @@ class PostProvVisitSchedulingCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetVisitsCall {
|
||||
class GetVisitsCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final int? pageSize,
|
||||
final int? pageNumber,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2283,11 +2428,12 @@ class GetVisitsCall {
|
|||
.toList();
|
||||
}
|
||||
|
||||
class DeleteVisitCall {
|
||||
class DeleteVisitCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? idVisita,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2331,9 +2477,10 @@ class DeleteVisitCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetPessoasLocalCall {
|
||||
class GetPessoasLocalCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call() async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2396,14 +2543,15 @@ class GetPessoasLocalCall {
|
|||
.toList();
|
||||
}
|
||||
|
||||
class RespondeSolicitacaoCall {
|
||||
class RespondeSolicitacaoCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? referencia,
|
||||
final String? tarefa,
|
||||
final String? resposta,
|
||||
final String? idVisitante,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2450,13 +2598,14 @@ class RespondeSolicitacaoCall {
|
|||
));
|
||||
}
|
||||
|
||||
class GetAccessCall {
|
||||
class GetAccessCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? pageSize,
|
||||
final String? pageNumber,
|
||||
final String? pesTipo,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
@ -2704,9 +2853,10 @@ class GetAccessCall {
|
|||
.toList();
|
||||
}
|
||||
|
||||
class GetLiberationsCall {
|
||||
class GetLiberationsCall extends Endpoint {
|
||||
@override
|
||||
Stream<ApiCallResponse> call() {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
final StreamController<ApiCallResponse> controller = StreamController();
|
||||
|
||||
Future.microtask(() async {
|
||||
|
@ -2897,13 +3047,14 @@ class GetLiberationsCall {
|
|||
.toList();
|
||||
}
|
||||
|
||||
class GetMessagesCall {
|
||||
class GetMessagesCall extends Endpoint {
|
||||
@override
|
||||
Future<ApiCallResponse> call({
|
||||
final String? pageSize,
|
||||
final String? pageNumber,
|
||||
final String? tipoDestino,
|
||||
}) async {
|
||||
final String baseUrl = PhpGroup.getBaseUrl();
|
||||
final String baseUrl = FreAccessWSGlobal.getBaseUrl();
|
||||
|
||||
final String devUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? '';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
|
|
|
@ -0,0 +1,788 @@
|
|||
import 'dart:developer';
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
|
||||
import 'package:hub/features/backend/index.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/shared/extensions.dart';
|
||||
import 'package:hub/shared/utils.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_rx_bloc/flutter_rx_bloc.dart';
|
||||
import 'package:rx_bloc/rx_bloc.dart';
|
||||
import 'package:rxdart/rxdart.dart' as rx;
|
||||
|
||||
part 'documents.rxb.g.dart';
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [TypeDefs] -----------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
typedef DocumentKey = GlobalKey<DocumentPageState>;
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Extensions] ---------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
extension ExplicitRxdartStartWithExtension<T> on Stream<T?> {
|
||||
Stream<T?> rxdartStartWith(T? value) =>
|
||||
rx.StartWithExtension(this).startWith(value);
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Pages] ---------------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
class DocumentPage extends StatefulPage {
|
||||
const DocumentPage({super.key});
|
||||
|
||||
@override
|
||||
State<DocumentPage> createState() => DocumentPageState();
|
||||
}
|
||||
|
||||
class DocumentPageState extends PageState<DocumentPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RxBlocMultiBuilder2<DocumentPageBlocType, bool, (Document, Uri)?>(
|
||||
state1: (bloc) => bloc.states.isDocumentSelected,
|
||||
state2: (bloc) => bloc.states.currentDocument,
|
||||
bloc: context.read<DocumentPageBloc>(),
|
||||
builder: (context, isSelect, current, bloc) {
|
||||
if (isSelect.hasData && isSelect.data!) {
|
||||
return _buildDocumentViewScreen(current, bloc);
|
||||
} else {
|
||||
return _buildDocumentManagerScreen();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDocumentManagerScreen() {
|
||||
final model = context.read<DocumentPageBloc>().model;
|
||||
|
||||
return DocumentManagerScreen(
|
||||
model: model,
|
||||
state: this,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDocumentViewScreen(
|
||||
AsyncSnapshot<(Document, Uri)?> snapshot, DocumentPageBlocType bloc) {
|
||||
if (snapshot.hasData) {
|
||||
return DocumentViewerScreen(
|
||||
doc: snapshot.data!,
|
||||
bloc: bloc,
|
||||
);
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Screens] ------------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
class DocumentManagerScreen extends StatelessScreen {
|
||||
final DocumentModel model;
|
||||
final DocumentPageState state;
|
||||
|
||||
const DocumentManagerScreen({
|
||||
super.key,
|
||||
required this.model,
|
||||
required this.state,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String title = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Documents',
|
||||
ptText: 'Documentos',
|
||||
);
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
action() => Navigator.pop(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.primaryBackground,
|
||||
appBar: buildAppBar(title, context, action),
|
||||
body: buildBody(context),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildBody(BuildContext context) {
|
||||
const SizedBox space = SizedBox(height: 10);
|
||||
final controller = EnhancedListViewController(
|
||||
headerBuilder: model.itemHeaderBuilder<SearchField>,
|
||||
bodyBuilder: model.itemBodyBuilder<Document>,
|
||||
footerBuilder: model.itemFooterBuilder<Category>,
|
||||
);
|
||||
final repository = EnhancedListViewRepository(
|
||||
fetchHeader: model.generateHeaderItems<SearchField>,
|
||||
fetchBody: model.generateBodyItems<Document, Query>,
|
||||
fetchFooter: model.generateFooterItems<Category>,
|
||||
);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: EnhancedListView<Document, SearchField, Category, Query>(
|
||||
key: model.enhancedListViewKey,
|
||||
controller: controller,
|
||||
repository: repository,
|
||||
),
|
||||
),
|
||||
] //
|
||||
.addToStart(space)
|
||||
.addToEnd(space),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DocumentViewerScreen extends StatefulScreen {
|
||||
const DocumentViewerScreen({
|
||||
super.key,
|
||||
required this.doc,
|
||||
required this.bloc,
|
||||
});
|
||||
|
||||
final (Document, Uri) doc;
|
||||
final DocumentPageBlocType bloc;
|
||||
|
||||
@override
|
||||
ScreenState<DocumentViewerScreen> createState() =>
|
||||
_DocumentViewerScreenState();
|
||||
}
|
||||
|
||||
class _DocumentViewerScreenState extends ScreenState<DocumentViewerScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
backAction() => widget.bloc.events.unselectDocument();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String title = widget.doc.$1.description;
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final locale = FFLocalizations.of(context);
|
||||
|
||||
infoAction() => DetailsComponentWidget(
|
||||
buttons: [],
|
||||
statusHashMap: [
|
||||
Map<String, Color>.from({
|
||||
widget.doc.$1.description: widget.doc.$1.category.color,
|
||||
})
|
||||
],
|
||||
labelsHashMap: Map<String, String>.from({
|
||||
locale.getVariableText(
|
||||
enText: 'Description',
|
||||
ptText: 'Descrição',
|
||||
): widget.doc.$1.description,
|
||||
locale.getVariableText(
|
||||
enText: 'Category',
|
||||
ptText: 'Categoria',
|
||||
): widget.doc.$1.category.title,
|
||||
if (widget.doc.$1.person.isNotEmpty)
|
||||
locale.getVariableText(
|
||||
enText: 'Person',
|
||||
ptText: 'Pessoa',
|
||||
): widget.doc.$1.person,
|
||||
if (widget.doc.$1.property.isNotEmpty)
|
||||
locale.getVariableText(
|
||||
enText: 'Property',
|
||||
ptText: 'Propriedade',
|
||||
): widget.doc.$1.property,
|
||||
locale.getVariableText(
|
||||
enText: 'Created At',
|
||||
ptText: 'Criado em',
|
||||
): ValidatorUtil.toLocalDateTime(
|
||||
'yyyy-MM-dd', widget.doc.$1.createdAt),
|
||||
locale.getVariableText(
|
||||
enText: 'Updated At',
|
||||
ptText: 'Atualizado em',
|
||||
): ValidatorUtil.toLocalDateTime(
|
||||
'yyyy-MM-dd', widget.doc.$1.updatedAt),
|
||||
}),
|
||||
);
|
||||
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => backAction(),
|
||||
child: Scaffold(
|
||||
backgroundColor: theme.primaryBackground,
|
||||
appBar: buildAppBar(title, context, backAction, infoAction),
|
||||
body: buildBody(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildBody(BuildContext context) {
|
||||
return ReadView(
|
||||
title: widget.doc.$1.description,
|
||||
url: widget.doc.$2.toString(),
|
||||
onError: backAction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Models] --------------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
class DocumentModel extends FlutterFlowModel<DocumentPage> {
|
||||
final DocumentPageBlocType bloc;
|
||||
DocumentModel(this.bloc);
|
||||
|
||||
late EnhancedListViewKey<Document, SearchField, Category, Query>
|
||||
enhancedListViewKey;
|
||||
late EnhancedCarouselViewKey<Category> carouselViewKey;
|
||||
|
||||
late DocumentKey vehicleScreenViewer;
|
||||
|
||||
/// ------------
|
||||
|
||||
@override
|
||||
void initState(BuildContext context) {
|
||||
enhancedListViewKey =
|
||||
EnhancedListViewKey<Document, SearchField, Category, Query>();
|
||||
carouselViewKey = EnhancedCarouselViewKey<Category>();
|
||||
vehicleScreenViewer = DocumentKey();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
enhancedListViewKey.currentState?.dispose();
|
||||
carouselViewKey.currentState?.dispose();
|
||||
vehicleScreenViewer.currentState?.dispose();
|
||||
}
|
||||
|
||||
/// ------------
|
||||
|
||||
/// [Body]
|
||||
|
||||
void onView(Document document, BuildContext context) async {
|
||||
bloc.events.selectDocument(document);
|
||||
}
|
||||
|
||||
Widget itemBodyBuilder<T extends Document>(
|
||||
BuildContext context, T item, int index) {
|
||||
log('ItemBuilder -> $index');
|
||||
|
||||
return DocumentComponent(
|
||||
document: item,
|
||||
onPressed: onView,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<T?>> generateBodyItems<T extends Document, Q extends Query>(
|
||||
int pageKey, int pageSize, Q query) async {
|
||||
final List<T?> error = [null];
|
||||
log('Query: ${query is Document}');
|
||||
final GetDocuments getDocuments = FreAccessWSGlobal.getDocuments;
|
||||
final ApiCallResponse newItems = await getDocuments.call(pageKey, query);
|
||||
|
||||
if (newItems.jsonBody == null) return error;
|
||||
if (newItems.jsonBody['error'] == true) return error;
|
||||
|
||||
final List<dynamic> list = newItems.jsonBody['value']['list'];
|
||||
|
||||
late final List<Document> docs = [];
|
||||
|
||||
for (var item in list) {
|
||||
final String description = item['description'];
|
||||
final String type = item['type'];
|
||||
final String category = item['category']['description'];
|
||||
final String color = item['category']['color'];
|
||||
final String person = item['person'] ?? '';
|
||||
final String property = item['property'] ?? '';
|
||||
final String createdAt = item['createdAt'];
|
||||
final String updatedAt = item['updatedAt'];
|
||||
final int categoryId = item['category']['id'];
|
||||
final int documentId = item['id'];
|
||||
|
||||
final doc = Document(
|
||||
id: documentId,
|
||||
description: description,
|
||||
type: type,
|
||||
category: Category(
|
||||
id: categoryId,
|
||||
color: color.toColor(),
|
||||
title: category,
|
||||
),
|
||||
person: person,
|
||||
property: property,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
);
|
||||
|
||||
docs.add(doc);
|
||||
}
|
||||
|
||||
return docs as List<T?>;
|
||||
}
|
||||
|
||||
/// [Footer]
|
||||
|
||||
Widget itemFooterBuilder<T extends Category>(
|
||||
Future<List<T?>> Function() fetchData) =>
|
||||
Builder(builder: (context) {
|
||||
CategoryComponent categoryItemBuilder<T>(T? item, bool isSelected) {
|
||||
return CategoryComponent(
|
||||
category: item! as Category, isSelected: isSelected);
|
||||
}
|
||||
|
||||
return EnhancedCarouselView<T>(
|
||||
key: carouselViewKey,
|
||||
dataProvider: fetchData,
|
||||
itemBuilder: categoryItemBuilder,
|
||||
filter: filterByCategory<T>,
|
||||
showIndicator: true,
|
||||
);
|
||||
});
|
||||
|
||||
Future<List<T?>> generateFooterItems<T extends Category>() async {
|
||||
final List<T?> error = [null];
|
||||
|
||||
final GetCategories getCategories = FreAccessWSGlobal.getCategories;
|
||||
final ApiCallResponse newItems = await getCategories.call();
|
||||
|
||||
if (newItems.jsonBody['error'] == true) return error;
|
||||
if (newItems.jsonBody == null) return error;
|
||||
final list = newItems.jsonBody['value'] as List<dynamic>;
|
||||
late final List<Category> cats = [];
|
||||
for (var item in list) {
|
||||
final String color = item['color'];
|
||||
final String title = item['description'];
|
||||
final int id = item['id'];
|
||||
|
||||
final cat = Category(
|
||||
id: id,
|
||||
color: color.toColor(),
|
||||
title: title,
|
||||
);
|
||||
cats.add(cat);
|
||||
}
|
||||
return cats as List<T?>;
|
||||
}
|
||||
|
||||
/// [Header]
|
||||
|
||||
Widget itemHeaderBuilder<T extends SearchField>(
|
||||
Future<List<T?>> Function() generateHeaderItems) {
|
||||
return Builder(builder: (context) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final locale = FFLocalizations.of(context);
|
||||
TextEditingController editingController = TextEditingController();
|
||||
return TextFormField(
|
||||
controller: editingController,
|
||||
onChanged: (value) => EasyDebounce.debounce(
|
||||
'_model.keyTextFieldTextController',
|
||||
const Duration(milliseconds: 500),
|
||||
() => filterBySearchBar(Document.from(value), context),
|
||||
),
|
||||
cursorColor: theme.primaryText,
|
||||
showCursor: false,
|
||||
cursorWidth: 2.0,
|
||||
cursorRadius: Radius.circular(100),
|
||||
style: TextStyle(
|
||||
color: theme.primaryText,
|
||||
fontSize: 16.0,
|
||||
decorationColor: Colors.amber,
|
||||
),
|
||||
keyboardType: TextInputType.text,
|
||||
textInputAction: TextInputAction.search,
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(Icons.search, color: theme.primary),
|
||||
labelText: locale.getVariableText(
|
||||
ptText: 'Pesquisar',
|
||||
enText: 'Search',
|
||||
),
|
||||
labelStyle: TextStyle(
|
||||
color: theme.primaryText,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
hintText: locale.getVariableText(
|
||||
ptText: 'Digite sua pesquisa',
|
||||
enText: 'Enter your search',
|
||||
),
|
||||
hintStyle: TextStyle(
|
||||
color: theme.accent2,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.transparent,
|
||||
helperStyle: TextStyle(
|
||||
color: theme.primaryText,
|
||||
decorationColor: theme.primaryText,
|
||||
),
|
||||
focusColor: theme.primaryText,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
borderSide: BorderSide(color: theme.primaryText),
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
borderSide: BorderSide(color: theme.primaryText),
|
||||
),
|
||||
errorBorder: UnderlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
borderSide: BorderSide(color: theme.primaryText),
|
||||
),
|
||||
focusedErrorBorder: UnderlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
borderSide: BorderSide(color: theme.primaryText, width: 2.0),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<T?>> generateHeaderItems<T extends SearchField>() async {
|
||||
final SearchField item = SearchField();
|
||||
return [item] as List<T?>;
|
||||
}
|
||||
|
||||
/// [Filter]
|
||||
|
||||
void filterBySearchBar<T>(T query, BuildContext context) {
|
||||
final enhancedListViewState = enhancedListViewKey.currentState;
|
||||
return enhancedListViewState?.filterBodyItems(query);
|
||||
}
|
||||
|
||||
void filterByCategory<T>(T? query, BuildContext context) {
|
||||
final enhancedListViewState = enhancedListViewKey.currentState;
|
||||
|
||||
enhancedListViewState?.filterBodyItems(query);
|
||||
}
|
||||
|
||||
/// [Exception]
|
||||
void onFetchError(Object e, StackTrace s) {
|
||||
DialogUtil.errorDefault(vehicleScreenViewer.currentContext!);
|
||||
LogUtil.requestAPIFailed(
|
||||
"proccessRequest.php", "", "Consulta de Veículo", e, s);
|
||||
}
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [BLoCs] ---------------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
abstract class DocumentPageBlocEvents {
|
||||
void selectDocument(Document document);
|
||||
void unselectDocument();
|
||||
}
|
||||
|
||||
abstract class DocumentPageBlocStates {
|
||||
Stream<bool> get isDocumentSelected;
|
||||
Stream<(Document, Uri)?> get currentDocument;
|
||||
}
|
||||
|
||||
@RxBloc()
|
||||
class DocumentPageBloc extends $DocumentPageBloc {
|
||||
late final DocumentModel model;
|
||||
|
||||
DocumentPageBloc(BuildContext context) {
|
||||
model = DocumentModel(this);
|
||||
model.initState(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<(Document, Uri)?> _mapToCurrentDocumentState() => _$selectDocumentEvent
|
||||
.switchMap((event) async* {
|
||||
final uri = await GetPDF().call(event.id);
|
||||
yield (event, uri);
|
||||
})
|
||||
.rxdartStartWith(null)
|
||||
.mergeWith([_$unselectDocumentEvent.map((_) => null)]);
|
||||
|
||||
@override
|
||||
Stream<bool> _mapToIsDocumentSelectedState() => _mapToCurrentDocumentState()
|
||||
.map((document) => document != null)
|
||||
.rxdartStartWith(false)
|
||||
.map((isSelected) => isSelected ?? false);
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Interfaces] ---------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
abstract interface class Archive extends Entity {}
|
||||
|
||||
interface class SearchField extends Archive {
|
||||
SearchField();
|
||||
}
|
||||
|
||||
interface class Document extends Archive {
|
||||
final int id;
|
||||
final String description;
|
||||
final String type;
|
||||
final Category category;
|
||||
final String person;
|
||||
final String property;
|
||||
String createdAt;
|
||||
String updatedAt;
|
||||
|
||||
Document({
|
||||
required this.id,
|
||||
required this.description,
|
||||
required this.type,
|
||||
required this.category,
|
||||
required this.person,
|
||||
required this.property,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
factory Document.from(String desc) => Document(
|
||||
id: 0,
|
||||
description: desc,
|
||||
type: '',
|
||||
category: Category.fromDesc(''),
|
||||
person: '',
|
||||
property: '',
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
);
|
||||
}
|
||||
|
||||
interface class Category extends Archive {
|
||||
final int id;
|
||||
final Color color;
|
||||
final String title;
|
||||
|
||||
Category({
|
||||
required this.id,
|
||||
required this.color,
|
||||
required this.title,
|
||||
});
|
||||
|
||||
factory Category.fromDesc(String desc) {
|
||||
return Category(
|
||||
id: 0,
|
||||
color: Colors.transparent,
|
||||
title: desc,
|
||||
);
|
||||
}
|
||||
|
||||
static Color isSelected() => Colors.black;
|
||||
}
|
||||
|
||||
/// -----------------------------------------------
|
||||
/// [Components] -------------------------------------
|
||||
/// -----------------------------------------------
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class DocumentComponent extends StatelessComponent {
|
||||
final Document document;
|
||||
void Function(Document, BuildContext) onPressed;
|
||||
|
||||
DocumentComponent({
|
||||
super.key,
|
||||
required this.document,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
Tooltip _buildTooltip(String text, Color color, BuildContext context,
|
||||
BoxConstraints constraints) {
|
||||
final Color textColor = FlutterFlowTheme.of(context).info;
|
||||
|
||||
final area = (MediaQuery.of(context).size.height +
|
||||
MediaQuery.of(context).size.width) /
|
||||
2;
|
||||
|
||||
final double boxHeight = area * 0.033;
|
||||
final double boxWidth = area * 0.19;
|
||||
|
||||
return Tooltip(
|
||||
message: text,
|
||||
child: Container(
|
||||
width: boxWidth,
|
||||
height: boxHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Center(
|
||||
child: AutoText(
|
||||
text,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Color primaryText = FlutterFlowTheme.of(context).primaryText;
|
||||
final Color primaryColor = FlutterFlowTheme.of(context).primary;
|
||||
|
||||
final TextStyle textStyleMajor = TextStyle(
|
||||
color: primaryText,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
final TextStyle textStyleMinor = TextStyle(
|
||||
color: primaryText,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontStyle: FontStyle.italic,
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final double boxHeight = constraints.maxHeight > 350
|
||||
? MediaQuery.of(context).size.height * 0.07
|
||||
: MediaQuery.of(context).size.height * 2;
|
||||
final color = document.category.color;
|
||||
// final color = FlutterFlowTheme.of(context).primary;
|
||||
final icon = Icons.description;
|
||||
const space = SizedBox(width: 10);
|
||||
final description = document.description;
|
||||
final title = document.category.title;
|
||||
const double size = 20;
|
||||
final date = ValidatorUtil.toLocalDateTime(
|
||||
'yyyy-MM-dd',
|
||||
document.updatedAt,
|
||||
);
|
||||
|
||||
return Tooltip(
|
||||
message: description,
|
||||
child: InkWell(
|
||||
onTap: () => onPressed(document, context),
|
||||
enableFeedback: true,
|
||||
overlayColor: WidgetStateProperty.all<Color>(primaryColor),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: SizedBox(
|
||||
height: boxHeight,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
spacing: size,
|
||||
children: [
|
||||
// const SizedBox(width: 10),
|
||||
Icon(icon, color: color),
|
||||
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Tooltip(
|
||||
message: description,
|
||||
child: AutoText(
|
||||
description,
|
||||
style: textStyleMajor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Tooltip(
|
||||
message: date,
|
||||
child: AutoText(
|
||||
date,
|
||||
style: textStyleMinor,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
_buildTooltip(title, color, context, constraints),
|
||||
],
|
||||
),
|
||||
),
|
||||
// const SizedBox(width: 10),
|
||||
Center(
|
||||
child: Icon(
|
||||
Icons.arrow_right,
|
||||
color: primaryText,
|
||||
),
|
||||
),
|
||||
] //
|
||||
.addToStart(space)
|
||||
.addToEnd(space),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DocumentComponent copyWith({
|
||||
Document? document,
|
||||
}) {
|
||||
return DocumentComponent(
|
||||
document: document ?? this.document,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryComponent extends StatelessComponent {
|
||||
final Category category;
|
||||
final bool isSelected;
|
||||
|
||||
const CategoryComponent({
|
||||
super.key,
|
||||
required this.category,
|
||||
this.isSelected = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final backgroundTheme = FlutterFlowTheme.of(context).primaryBackground;
|
||||
final textTheme = FlutterFlowTheme.of(context).primaryText;
|
||||
final color = isSelected ? category.color.highlight : category.color;
|
||||
return ColoredBox(
|
||||
color: backgroundTheme,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.folder,
|
||||
color: Colors.white,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
category.title,
|
||||
style: TextStyle(
|
||||
color: textTheme,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// dart format width=80
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: RxBlocGeneratorForAnnotation
|
||||
// **************************************************************************
|
||||
|
||||
part of 'documents.dart';
|
||||
|
||||
/// Used as a contractor for the bloc, events and states classes
|
||||
/// @nodoc
|
||||
abstract class DocumentPageBlocType extends RxBlocTypeBase {
|
||||
DocumentPageBlocEvents get events;
|
||||
DocumentPageBlocStates get states;
|
||||
}
|
||||
|
||||
/// [$DocumentPageBloc] extended by the [DocumentPageBloc]
|
||||
/// @nodoc
|
||||
abstract class $DocumentPageBloc extends RxBlocBase
|
||||
implements
|
||||
DocumentPageBlocEvents,
|
||||
DocumentPageBlocStates,
|
||||
DocumentPageBlocType {
|
||||
final _compositeSubscription = rx.CompositeSubscription();
|
||||
|
||||
/// Тhe [Subject] where events sink to by calling [selectDocument]
|
||||
final _$selectDocumentEvent = rx.PublishSubject<Document>();
|
||||
|
||||
/// Тhe [Subject] where events sink to by calling [unselectDocument]
|
||||
final _$unselectDocumentEvent = rx.PublishSubject<void>();
|
||||
|
||||
/// The state of [isDocumentSelected] implemented in
|
||||
/// [_mapToIsDocumentSelectedState]
|
||||
late final Stream<bool> _isDocumentSelectedState =
|
||||
_mapToIsDocumentSelectedState();
|
||||
|
||||
/// The state of [currentDocument] implemented in [_mapToCurrentDocumentState]
|
||||
late final Stream<(Document, Uri)?> _currentDocumentState =
|
||||
_mapToCurrentDocumentState();
|
||||
|
||||
@override
|
||||
void selectDocument(Document document) => _$selectDocumentEvent.add(document);
|
||||
|
||||
@override
|
||||
void unselectDocument() => _$unselectDocumentEvent.add(null);
|
||||
|
||||
@override
|
||||
Stream<bool> get isDocumentSelected => _isDocumentSelectedState;
|
||||
|
||||
@override
|
||||
Stream<(Document, Uri)?> get currentDocument => _currentDocumentState;
|
||||
|
||||
Stream<bool> _mapToIsDocumentSelectedState();
|
||||
|
||||
Stream<(Document, Uri)?> _mapToCurrentDocumentState();
|
||||
|
||||
@override
|
||||
DocumentPageBlocEvents get events => this;
|
||||
|
||||
@override
|
||||
DocumentPageBlocStates get states => this;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_$selectDocumentEvent.close();
|
||||
_$unselectDocumentEvent.close();
|
||||
_compositeSubscription.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
|
@ -201,7 +201,7 @@ class _AccessHistoryState extends State<AccessHistoryScreen> {
|
|||
Future<ApiCallResponse?> fetchAccessHistoryService() async {
|
||||
try {
|
||||
setState(() => _loading = true);
|
||||
var response = await PhpGroup.getAccessCall.call(
|
||||
var response = await FreAccessWSGlobal.getAccessCall.call(
|
||||
pageSize: _pageSize.toString(),
|
||||
pageNumber: _pageNumber.toString(),
|
||||
pesTipo: _personType != 'E' && _personType != 'O' ? 'T' : _personType,
|
||||
|
|
|
@ -222,8 +222,8 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
|
|||
Future<ApiCallResponse?> fetchHistoryService() async {
|
||||
try {
|
||||
setState(() => _loading = true);
|
||||
var response =
|
||||
await PhpGroup.getProvSchedules(_pageNumber.toString(), status);
|
||||
var response = await FreAccessWSGlobal.getProvSchedules(
|
||||
_pageNumber.toString(), status);
|
||||
|
||||
final List<dynamic> history =
|
||||
response.jsonBody['agendamento']['value'] ?? [];
|
||||
|
@ -350,6 +350,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
String _imageUrlAtomWidget(String document, String type) {
|
||||
return valueOrDefault<String>(
|
||||
"https://freaccess.com.br/freaccess/getImage.php?&cliID=&atividade=getFoto&Documento=$document&tipo=$type",
|
||||
|
@ -404,6 +405,7 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
|
|||
}
|
||||
|
||||
Map<String, Color> _getStatusMap(BuildContext context, dynamic json) {
|
||||
// ignore: unused_local_variable
|
||||
late Map<String, Color> statusColorMap;
|
||||
log(DateTime.parse(json['AGP_DT_VISITA']).toString());
|
||||
log(DateTime.now().toString());
|
||||
|
|
|
@ -187,6 +187,7 @@ class _AccessFilterState extends State<AccessFilter> {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
void _updateSelection(String? value, String key) {
|
||||
setState(() {
|
||||
if (value == '.') {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
@ -8,8 +7,6 @@ import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
|
|||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||
import 'package:hub/flutter_flow/internationalization.dart';
|
||||
import 'package:hub/shared/utils/log_util.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
|
|
@ -136,6 +136,7 @@ class DrawerWidget extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
Padding _buildSearchBar(BuildContext context, HomeState state) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final errorColor = theme.error;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:hub/features/storage/constants/locals_constants.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
|
@ -75,7 +74,7 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource {
|
|||
await DatabaseService.database
|
||||
.delete(LocalsConstants.tableLocalsKeychain);
|
||||
} catch (e, s) {
|
||||
log('() => clearAll keychain: $e', stackTrace: s);
|
||||
log('() => clearAll keychain: $e stackTrace: $s');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,22 +32,15 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
@override
|
||||
Future<void> linkLocal(BuildContext context) async {
|
||||
try {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||
var response = await callback.call();
|
||||
final bool? isError = response.jsonBody['error'];
|
||||
if (response.jsonBody == null) return;
|
||||
|
||||
final bool? isError = response.jsonBody['error'];
|
||||
if (isError == true) {
|
||||
LocalUtil.handleError(context, response.jsonBody['error_msg']);
|
||||
return;
|
||||
}
|
||||
if (response.jsonBody == null) {
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return;
|
||||
}
|
||||
|
||||
final List<dynamic> locals = response.jsonBody['locais'] ?? [];
|
||||
final bool isEmpty = locals.isEmpty;
|
||||
|
@ -70,9 +63,9 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
|
||||
@override
|
||||
Future<bool> processLocals(BuildContext context) async {
|
||||
log('() => processLocals');
|
||||
log('-> processLocals');
|
||||
try {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||
final ApiCallResponse response = await callback.call();
|
||||
final bool? isError = response.jsonBody['error'];
|
||||
|
||||
|
@ -82,10 +75,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
return false;
|
||||
}
|
||||
if (response.jsonBody == null) {
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Verify your connection',
|
||||
// ptText: 'Verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
}
|
||||
|
@ -114,36 +107,35 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
} else if (isEnabled) {
|
||||
return await LocalUtil.handleEnabled(context, locals[0]);
|
||||
} else if (isUnselected) {
|
||||
log('() => isUnselected');
|
||||
log('-> isUnselected');
|
||||
return await selectLocal(context, response);
|
||||
} else if (isSelected) {
|
||||
log('() => isSelected');
|
||||
log('-> isSelected');
|
||||
return await processProperty(context).then((v) async {
|
||||
if (v == true) return await LicenseRepositoryImpl().updateLicense();
|
||||
return v;
|
||||
});
|
||||
} else if (isAvailable) {
|
||||
log('() => isAvailable');
|
||||
log('-> isAvailable');
|
||||
return await processProperty(context).then((v) async {
|
||||
if (v == true) return await LicenseRepositoryImpl().updateLicense();
|
||||
return v;
|
||||
});
|
||||
} else {
|
||||
if (!isUnique && !isActive) log('() => not unique and not active');
|
||||
if (!isUnique && isInactived) log('() => not unique and inactived');
|
||||
if (!isUnique && isPending) log('() => not unique and pending');
|
||||
if (!isUnique && isBlocked) log('() => not unique and blocked');
|
||||
log('() => else');
|
||||
if (!isUnique && !isActive) log('-> not unique and not active');
|
||||
if (!isUnique && isInactived) log('-> not unique and inactived');
|
||||
if (!isUnique && isPending) log('-> not unique and pending');
|
||||
if (!isUnique && isBlocked) log('-> not unique and blocked');
|
||||
log('-> else');
|
||||
return await selectLocal(context, response);
|
||||
}
|
||||
} catch (e, s) {
|
||||
log('() => stack: $s');
|
||||
log('() => catch: $e', stackTrace: s);
|
||||
log('-> catch: $e', stackTrace: s);
|
||||
// return await selectLocal(context);
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error getting locals, verify your connection',
|
||||
ptText: 'Erro ao obter locais, verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Error getting locals, verify your connection',
|
||||
// ptText: 'Erro ao obter locais, verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
|
||||
return false;
|
||||
}
|
||||
|
@ -163,25 +155,25 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
@override
|
||||
Future<bool> processProperty(BuildContext context) async {
|
||||
try {
|
||||
final GetDadosCall callback = PhpGroup.getDadosCall;
|
||||
final GetDadosCall callback = FreAccessWSGlobal.getDadosCall;
|
||||
ApiCallResponse? response = await callback.call();
|
||||
if (response.jsonBody == null) {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||
response = await callback.call();
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Verify your connection',
|
||||
ptText: 'Verifique sua conexão',
|
||||
);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Verify your connection',
|
||||
// ptText: 'Verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
}
|
||||
|
||||
final bool? isError = response.jsonBody['error'];
|
||||
if (isError == true) {
|
||||
final GetLocalsCall callback = PhpGroup.getLocalsCall;
|
||||
final GetLocalsCall callback = FreAccessWSGlobal.getLocalsCall;
|
||||
response = await callback.call();
|
||||
final String errorMsg =
|
||||
response.jsonBody['error_msg'] ?? 'Local indisponível';
|
||||
// final String errorMsg =
|
||||
// response.jsonBody['error_msg'] ?? 'Local indisponível';
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response));
|
||||
return false;
|
||||
} else {
|
||||
|
@ -189,11 +181,11 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
return true;
|
||||
}
|
||||
} catch (e, s) {
|
||||
log('() => error processData: $e', stackTrace: s);
|
||||
final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
enText: 'Error getting data, verify your connection',
|
||||
ptText: 'Erro ao obter dados, verifique sua conexão',
|
||||
);
|
||||
log('-> error processData: $e', stackTrace: s);
|
||||
// final String errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Error getting data, verify your connection',
|
||||
// ptText: 'Erro ao obter dados, verifique sua conexão',
|
||||
// );
|
||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null));
|
||||
return false;
|
||||
}
|
||||
|
@ -231,8 +223,9 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
enText: 'Device unlinked successfully',
|
||||
ptText: 'Dispositivo desvinculado com sucesso',
|
||||
);
|
||||
final bool status =
|
||||
await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async {
|
||||
final bool status = await FreAccessWSGlobal.resopndeVinculo
|
||||
.call(tarefa: 'I')
|
||||
.then((value) async {
|
||||
if (value.jsonBody['error'] == false) {
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, '');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerName.key, '');
|
||||
|
|
|
@ -106,6 +106,7 @@ class LocalsRepositoryImpl implements LocalsRepository {
|
|||
await DialogUtil.error(context, errorMsg);
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
Future<void> _notifyBlocs(BuildContext context) async {
|
||||
context.read<LocalProfileBloc>().add(LocalProfileEvent());
|
||||
context.read<MenuBloc>().add(MenuEvent());
|
||||
|
|
|
@ -52,7 +52,7 @@ class LocalUtil {
|
|||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']);
|
||||
|
||||
var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A');
|
||||
var response = await FreAccessWSGlobal.resopndeVinculo.call(tarefa: 'A');
|
||||
if (response.jsonBody['error'] == true) {
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '');
|
||||
|
|
|
@ -37,7 +37,8 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||
}
|
||||
|
||||
Future<void> _onMenuEvent(MenuEvent event, Emitter<MenuState> emit) async {
|
||||
await LicenseRemoteDataSourceImpl(PhpGroup()).waitForSaveCompletion();
|
||||
await LicenseRemoteDataSourceImpl(FreAccessWSGlobal())
|
||||
.waitForSaveCompletion();
|
||||
|
||||
final List<MenuItem?> newEntries =
|
||||
await MenuRepositoryImpl().entries2Items(entries, item);
|
||||
|
|
|
@ -204,6 +204,16 @@ class MenuEntry implements BaseModule {
|
|||
route: '/messageHistoryPage',
|
||||
types: [MenuEntryType.Home, MenuEntryType.Drawer],
|
||||
),
|
||||
MenuEntry(
|
||||
key: 'FRE-HUB-DOCUMENT',
|
||||
icon: Icons.description,
|
||||
name: FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
|
||||
ptText: 'Documentos',
|
||||
enText: 'Documents',
|
||||
),
|
||||
route: '/documentPage',
|
||||
types: [MenuEntryType.Home, MenuEntryType.Drawer],
|
||||
),
|
||||
MenuEntry(
|
||||
key: 'FRE-HUB-ABOUT-PROPERTY',
|
||||
icon: Icons.home,
|
||||
|
|
|
@ -17,7 +17,7 @@ class LicenseRepositoryImpl implements LicenseRepository {
|
|||
|
||||
LicenseRepositoryImpl([Database? database, Api? api])
|
||||
: database = database ?? DatabaseService.database,
|
||||
api = api ?? PhpGroup() {
|
||||
api = api ?? FreAccessWSGlobal() {
|
||||
localDataSource = LicenseLocalDataSourceImpl(this.database);
|
||||
remoteDataSource = LicenseRemoteDataSourceImpl(this.api);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ enum LicenseKeys {
|
|||
people('FRE-HUB-PEOPLE'),
|
||||
petsHistory('FRE-HUB-PETS-HISTORY'),
|
||||
settings('FRE-HUB-SETTINGS'),
|
||||
logout('FRE-HUB-LOGOUT');
|
||||
logout('FRE-HUB-LOGOUT'),
|
||||
document('FRE-HUB-DOCUMENT');
|
||||
|
||||
final String value;
|
||||
const LicenseKeys(this.value);
|
||||
|
@ -138,6 +139,13 @@ class License {
|
|||
startDate: '',
|
||||
quantity: 0,
|
||||
),
|
||||
Module(
|
||||
key: LicenseKeys.document.value,
|
||||
display: ModuleStatus.active.key,
|
||||
expirationDate: '',
|
||||
startDate: '',
|
||||
quantity: 0,
|
||||
),
|
||||
Module(
|
||||
key: LicenseKeys.openedVisits.value,
|
||||
display: isNewVersionWithModule
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'package:app_links/app_links.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
|
@ -21,7 +22,7 @@ class DeepLinkService {
|
|||
if (_isInitialized) return;
|
||||
try {
|
||||
_appLinks = AppLinks();
|
||||
print('initDeepLinks');
|
||||
log('initDeepLinks');
|
||||
_linkSubscription = _appLinks.uriLinkStream.listen((uri) async {
|
||||
if (!StorageHelper().isRecovered) {
|
||||
await _handleDeepLink(uri);
|
||||
|
@ -29,25 +30,25 @@ class DeepLinkService {
|
|||
});
|
||||
_isInitialized = true;
|
||||
} catch (e) {
|
||||
print('Error initializing deep links: $e');
|
||||
log('Error initializing deep links: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleDeepLink(Uri uri) async {
|
||||
try {
|
||||
print('Handling deep link: $uri');
|
||||
log('Handling deep link: $uri');
|
||||
if (StorageHelper().isRecovered) return;
|
||||
|
||||
StorageHelper().isRecovered = true;
|
||||
final email = uri.queryParameters['email'] ?? '';
|
||||
final token = uri.queryParameters['token'] ?? '';
|
||||
print('email: $email, token: $token');
|
||||
log('email: $email, token: $token');
|
||||
|
||||
if (email.isNotEmpty && token.isNotEmpty) {
|
||||
await _showForgotPasswordScreen(email, token);
|
||||
}
|
||||
} catch (e, s) {
|
||||
print('Error handling deep link: $e, $s');
|
||||
log('Error handling deep link: $e, $s');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,11 +73,11 @@ class DeepLinkService {
|
|||
enableDrag: true,
|
||||
).whenComplete(() {
|
||||
StorageHelper().isRecovered = false;
|
||||
print('showModalBottomSheet completed');
|
||||
log('showModalBottomSheet completed');
|
||||
});
|
||||
});
|
||||
} catch (e, s) {
|
||||
print('Error showing forgot password screen: $e, $s');
|
||||
log('Error showing forgot password screen: $e, $s');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ class FirebaseMessagingService {
|
|||
await StorageHelper().set(SecureStorageKey.token.value, deviceToken);
|
||||
final ApiCallResponse? response;
|
||||
|
||||
response = await PhpGroup.updToken.call();
|
||||
response = await FreAccessWSGlobal.updToken.call();
|
||||
|
||||
if (response.jsonBody['error'] == false) {
|
||||
log('Token Atualizado com Sucesso!');
|
||||
|
|
|
@ -25,7 +25,8 @@ Future<void> onMessageReceived(
|
|||
required String? response,
|
||||
required String? id}) async {
|
||||
final ApiCallResponse? respondeSolicitacaoCall;
|
||||
final RespondeSolicitacaoCall callback = PhpGroup.respondeSolicitacaoCall;
|
||||
final RespondeSolicitacaoCall callback =
|
||||
FreAccessWSGlobal.respondeSolicitacaoCall;
|
||||
|
||||
respondeSolicitacaoCall = await callback.call(
|
||||
referencia: ref,
|
||||
|
|
|
@ -9,8 +9,6 @@ extension SharedPreferencesKeyExtension on SharedPreferencesKey {
|
|||
switch (this) {
|
||||
case SharedPreferencesKey.isFirstRun:
|
||||
return 'fre_isFirstRun';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:hub/features/module/index.dart';
|
||||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
@ -33,29 +35,29 @@ class DatabaseService {
|
|||
onOpen: _onOpen,
|
||||
onConfigure: _onConfigure,
|
||||
);
|
||||
print('Database initialized');
|
||||
log('Database initialized');
|
||||
await LicenseRepositoryImpl().updateLicense();
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
Future<void> _onConfigure(Database database) async {
|
||||
print('Configuring database...');
|
||||
log('Configuring database...');
|
||||
}
|
||||
|
||||
Future<void> _onOpen(Database database) async {
|
||||
print('Opening database...');
|
||||
log('Opening database...');
|
||||
await _executePragmas(database);
|
||||
}
|
||||
|
||||
Future<void> _onCreate(Database database, int version) async {
|
||||
print('Creating database...');
|
||||
log('Creating database...');
|
||||
await database.execute(createKeychainTable);
|
||||
await _onUpgrade(database, 1, _dbVersion);
|
||||
}
|
||||
|
||||
Future<void> _onUpgrade(
|
||||
Database database, int oldVersion, int newVersion) async {
|
||||
print('Upgrading database from version $oldVersion to $newVersion...');
|
||||
log('Upgrading database from version $oldVersion to $newVersion...');
|
||||
if (oldVersion < 2 && newVersion >= 2) {
|
||||
await database.execute(LicenseConstants.createLicenseTable);
|
||||
await database.execute(LicenseConstants.updatePetsHistoryTrigger);
|
||||
|
@ -70,7 +72,7 @@ class DatabaseService {
|
|||
|
||||
Future<void> _onDowngrade(
|
||||
Database database, int oldVersion, int newVersion) async {
|
||||
print('Downgrading database from version $oldVersion to $newVersion...');
|
||||
log('Downgrading database from version $oldVersion to $newVersion...');
|
||||
if (oldVersion >= 2 && newVersion < 2) {
|
||||
await database.execute(LicenseConstants.deleteLicenseTable);
|
||||
await database.execute(LicenseConstants.dropPeopleDisplayTrigger);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:developer' as dev;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
@ -50,7 +51,7 @@ Future<Map<String, String>> stringToMap(String v) async {
|
|||
}),
|
||||
));
|
||||
} catch (e) {
|
||||
print('Error parsing string to map: $e');
|
||||
dev.log('Error parsing string to map: $e');
|
||||
return Future.value({});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ class LightModeTheme extends FlutterFlowTheme {
|
|||
|
||||
late Color primary = const Color(0xFF1AAB5F);
|
||||
late Color secondary = const Color(0xFFB59E9E);
|
||||
late Color tertiary = const Color(0xFF984BB6);
|
||||
late Color tertiary = const Color(0xFF000000);
|
||||
late Color alternate = const Color(0xFFF2F2F2);
|
||||
late Color alternate2 = const Color(0xFF232323);
|
||||
late Color primaryText = const Color(0xFF000000);
|
||||
|
@ -192,7 +192,7 @@ class DarkModeTheme extends FlutterFlowTheme {
|
|||
|
||||
late Color primary = const Color(0xFF1AAB5F);
|
||||
late Color secondary = const Color(0xFF18AA99);
|
||||
late Color tertiary = const Color(0xFF984BB6);
|
||||
late Color tertiary = const Color(0xFF000000);
|
||||
late Color alternate = const Color(0xFF232323);
|
||||
late Color alternate2 = const Color(0xFF171717);
|
||||
late Color primaryText = const Color(0xFFFFFFFF);
|
||||
|
|
|
@ -3,7 +3,9 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_rx_bloc/flutter_rx_bloc.dart';
|
||||
import 'package:hub/features/backend/index.dart';
|
||||
import 'package:hub/features/documents/documents.dart';
|
||||
import 'package:hub/features/history/index.dart';
|
||||
import 'package:hub/features/home/index.dart';
|
||||
import 'package:hub/features/local/index.dart';
|
||||
|
@ -298,6 +300,29 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) {
|
|||
return PetsPageWidget(pet: pet);
|
||||
},
|
||||
),
|
||||
FFRoute(
|
||||
name: 'documentPage',
|
||||
path: '/documentPage',
|
||||
builder: (context, params) {
|
||||
return RxBlocProvider<DocumentPageBloc>(
|
||||
create: (context) => DocumentPageBloc(context),
|
||||
child: DocumentPage(),
|
||||
);
|
||||
},
|
||||
),
|
||||
// FFRoute(
|
||||
// name: 'documentViewerScreen',
|
||||
// path: '/documentViewerScreen',
|
||||
// builder: (context, params) {
|
||||
// final Document doc = params.getParam('doc', ParamType.Function);
|
||||
// final Uri uri = params.getParam('uri', ParamType.Function);
|
||||
// return DocumentViewScreen(
|
||||
// key: UniqueKey(),
|
||||
// doc: (doc,
|
||||
// uri: uri,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget())
|
||||
].map((r) => r.toRoute(appStateNotifier)).toList(),
|
||||
);
|
||||
|
|
|
@ -218,9 +218,6 @@ dynamic deserializeParam<T>(
|
|||
|
||||
case ParamType.Enum:
|
||||
return deserializeEnum<T>(param);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
|
|
|
@ -44,21 +44,21 @@ Future<void> _initializeAppTrackingTransparency() async {
|
|||
}
|
||||
|
||||
Future<void> _initializeFirebase() async {
|
||||
print('Initializing Firebase...');
|
||||
log('Initializing Firebase...');
|
||||
await Firebase.initializeApp();
|
||||
print('Firebase initialized');
|
||||
log('Firebase initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeNotificationService() async {
|
||||
print('Initializing Notification Service...');
|
||||
log('Initializing Notification Service...');
|
||||
await NotificationService.initialize();
|
||||
print('Notification Service initialized');
|
||||
log('Notification Service initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeUrlStrategy() async {
|
||||
print('Initializing URL Strategy...');
|
||||
setUrlStrategy(PathUrlStrategy());
|
||||
print('URL Strategy initialized');
|
||||
log('URL Strategy initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeSystemSettings() async {
|
||||
|
@ -71,7 +71,18 @@ Future<void> _initializeSystemSettings() async {
|
|||
print('Debug mode');
|
||||
await crashlyticsInstance.setCrashlyticsCollectionEnabled(false);
|
||||
} else {
|
||||
print('Release mode');
|
||||
log('Release mode');
|
||||
|
||||
// bool unsentReports =
|
||||
// await FirebaseCrashlytics.instance.checkForUnsentReports();
|
||||
// if (unsentReports) {
|
||||
// // Existem relatórios não enviados
|
||||
// await crashlyticsInstance.sendUnsentReports();
|
||||
// log('Existem relatórios de falhas não enviados.');
|
||||
// } else {
|
||||
// // Não existem relatórios não enviados
|
||||
// log('Todos os relatórios de falhas foram enviados.');
|
||||
// }
|
||||
|
||||
await crashlyticsInstance.setCrashlyticsCollectionEnabled(true);
|
||||
if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
|
||||
|
@ -94,15 +105,15 @@ Future<void> _initializeSystemSettings() async {
|
|||
}
|
||||
|
||||
Future<void> _initializeFlutterFlow() async {
|
||||
print('Initializing FlutterFlow...');
|
||||
log('Initializing FlutterFlow...');
|
||||
await FlutterFlowTheme.initialize();
|
||||
await FFLocalizations.initialize();
|
||||
print('FlutterFlow initialized');
|
||||
log('FlutterFlow initialized');
|
||||
}
|
||||
|
||||
Future<void> _initializeNav() async {
|
||||
print('Initializing Nav...');
|
||||
log('Initializing Nav...');
|
||||
GoRouter.optionURLReflectsImperativeAPIs = true;
|
||||
usePathUrlStrategy();
|
||||
print('Nav initialized');
|
||||
log('Nav initialized');
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'dart:io';
|
|||
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
@ -21,6 +22,15 @@ import 'initialization.dart';
|
|||
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
class CustomScrollBehavior extends MaterialScrollBehavior {
|
||||
// Override behavior methods and getters like dragDevices
|
||||
@override
|
||||
Set<PointerDeviceKind> get dragDevices => {
|
||||
PointerDeviceKind.touch,
|
||||
PointerDeviceKind.mouse,
|
||||
};
|
||||
}
|
||||
|
||||
void main() async {
|
||||
await initializeBindings();
|
||||
runApp(const ProviderScope(child: App()));
|
||||
|
@ -65,38 +75,6 @@ class _AppState extends State<App> {
|
|||
late GoRouter _router;
|
||||
bool displaySplashImage = true;
|
||||
|
||||
final ThemeData _darkTheme = ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbVisibility: WidgetStateProperty.all(false),
|
||||
interactive: false,
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.dragged)) {
|
||||
return const Color(0xff1aab5f);
|
||||
}
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return const Color(0xff1aab5f);
|
||||
}
|
||||
return const Color(0xff1aab5f);
|
||||
}),
|
||||
),
|
||||
);
|
||||
final ThemeData _theme = ThemeData(
|
||||
brightness: Brightness.light,
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbVisibility: WidgetStateProperty.all(false),
|
||||
interactive: false,
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.dragged)) {
|
||||
return const Color(0xff1aab5f);
|
||||
}
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return const Color(0xff1aab5f);
|
||||
}
|
||||
return const Color(0xff1aab5f);
|
||||
}),
|
||||
),
|
||||
);
|
||||
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates =
|
||||
const [
|
||||
FFLocalizationsDelegate(),
|
||||
|
@ -192,15 +170,49 @@ class _AppState extends State<App> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeSchema = FlutterFlowTheme.of(context);
|
||||
|
||||
final ThemeData darkTheme = ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbVisibility: WidgetStateProperty.all(false),
|
||||
interactive: false,
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.dragged)) return themeSchema.primary;
|
||||
if (states.contains(WidgetState.hovered)) return themeSchema.primary;
|
||||
return themeSchema.primary;
|
||||
}),
|
||||
),
|
||||
);
|
||||
final ThemeData lightTheme = ThemeData(
|
||||
brightness: Brightness.light,
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
cursorColor: themeSchema.primaryText, // Cor do cursor
|
||||
selectionColor: themeSchema.accent2, // Cor da seleção de texto
|
||||
selectionHandleColor:
|
||||
themeSchema.primaryText, // Cor do manipulador de seleção
|
||||
),
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbVisibility: WidgetStateProperty.all(false),
|
||||
interactive: false,
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.dragged)) return themeSchema.primary;
|
||||
if (states.contains(WidgetState.hovered)) return themeSchema.primary;
|
||||
return themeSchema.primary;
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return MaterialApp.router(
|
||||
scrollBehavior: CustomScrollBehavior(),
|
||||
key: navigatorKey,
|
||||
title: 'FRE ACCESS HUB',
|
||||
builder: builder,
|
||||
localizationsDelegates: localizationsDelegates,
|
||||
locale: _locale,
|
||||
supportedLocales: supportedLocales,
|
||||
theme: _theme,
|
||||
darkTheme: _darkTheme,
|
||||
theme: lightTheme,
|
||||
darkTheme: darkTheme,
|
||||
themeMode: _themeMode,
|
||||
routerConfig: _router,
|
||||
);
|
||||
|
|
|
@ -50,7 +50,8 @@ class LiberationHistoryModel extends FlutterFlowModel<LiberationHistoryWidget> {
|
|||
required String? response,
|
||||
required String? id}) async {
|
||||
final ApiCallResponse? respondeSolicitacaoCall;
|
||||
final RespondeSolicitacaoCall callback = PhpGroup.respondeSolicitacaoCall;
|
||||
final RespondeSolicitacaoCall callback =
|
||||
FreAccessWSGlobal.respondeSolicitacaoCall;
|
||||
|
||||
respondeSolicitacaoCall = await callback.call(
|
||||
referencia: ref,
|
||||
|
|
|
@ -333,7 +333,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
|
|||
Future<ApiCallResponse?> _fetchRequests() async {
|
||||
try {
|
||||
safeSetState(() => _loading = true);
|
||||
var response = await PhpGroup.getLiberationsCall.call().first;
|
||||
var response = await FreAccessWSGlobal.getLiberationsCall.call().first;
|
||||
|
||||
final List<dynamic> requests = response.jsonBody['solicitacoes'] ?? [];
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
|
|||
try {
|
||||
setState(() => _loading = true);
|
||||
|
||||
var response = await PhpGroup.getMessagesCall.call(
|
||||
var response = await FreAccessWSGlobal.getMessagesCall.call(
|
||||
pageSize: _pageSize.toString(),
|
||||
pageNumber: _pageNumber.toString(),
|
||||
tipoDestino: _destinyType,
|
||||
|
|
|
@ -97,7 +97,7 @@ class _PackageOrderPage extends State<PackageOrderPage> {
|
|||
try {
|
||||
setState(() => _loading = true);
|
||||
|
||||
var response = await PhpGroup.buscaEnconcomendas.call(
|
||||
var response = await FreAccessWSGlobal.buscaEnconcomendas.call(
|
||||
pageSize: _pageSize.toString(),
|
||||
page: _pageNumber.toString(),
|
||||
adresseeType: _adresseeType == '.*' ? 'TOD' : _adresseeType,
|
||||
|
@ -314,7 +314,7 @@ class _PackageOrderPage extends State<PackageOrderPage> {
|
|||
}
|
||||
|
||||
String _imagePath(dynamic order) {
|
||||
return '${PhpGroup.getBaseUrl()}/getImage.php?cliID=$cliUUID&atividade=getFotoEncomenda&orderId=${order['id'] ?? ''}';
|
||||
return '${FreAccessWSGlobal.getBaseUrl()}/getImage.php?cliID=$cliUUID&atividade=getFotoEncomenda&orderId=${order['id'] ?? ''}';
|
||||
}
|
||||
|
||||
Map<String, String> _labelsHashMap(dynamic order) {
|
||||
|
|
|
@ -82,7 +82,7 @@ class _PeopleOnThePropertyPageState extends State<PeopleOnThePropertyPage> {
|
|||
body: SafeArea(
|
||||
top: true,
|
||||
child: FutureBuilder<ApiCallResponse>(
|
||||
future: PhpGroup.getPessoasLocalCall.call(),
|
||||
future: FreAccessWSGlobal.getPessoasLocalCall.call(),
|
||||
builder: (context, snapshot) {
|
||||
// Customize what your widget looks like when it's loading.
|
||||
if (!snapshot.hasData) {
|
||||
|
@ -123,7 +123,7 @@ class _PeopleOnThePropertyPageState extends State<PeopleOnThePropertyPage> {
|
|||
}
|
||||
|
||||
final columnGetPessoasLocalResponse = snapshot.data!;
|
||||
final getPoepleProperty = PhpGroup.getPessoasLocalCall
|
||||
final getPoepleProperty = FreAccessWSGlobal.getPessoasLocalCall
|
||||
.pessoas(
|
||||
columnGetPessoasLocalResponse.jsonBody,
|
||||
)
|
||||
|
|
|
@ -100,7 +100,7 @@ class _PetsHistoryScreenState extends State<PetsHistoryScreen>
|
|||
try {
|
||||
setState(() => _loading = true);
|
||||
|
||||
var response = await PhpGroup.getPets.call(
|
||||
var response = await FreAccessWSGlobal.getPets.call(
|
||||
pageSize: _pageSize,
|
||||
page: _pageNumber,
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -163,8 +164,10 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
|
||||
// updateImage!();
|
||||
(() async {
|
||||
Response response = await get(Uri.parse(
|
||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'));
|
||||
final String url =
|
||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
|
||||
log('img: $url');
|
||||
Response response = await get(Uri.parse(url));
|
||||
String base64 = base64Encode(response.bodyBytes);
|
||||
uploadedTempFile = await ImageUtils.convertToUploadFile(base64);
|
||||
updateImage?.call();
|
||||
|
@ -280,7 +283,8 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
img = "base64;jpeg,$img";
|
||||
final url =
|
||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
|
||||
final response = await PhpGroup.updatePet.call(
|
||||
log('img: $url');
|
||||
final response = await FreAccessWSGlobal.updatePet.call(
|
||||
petID: petId,
|
||||
image: img,
|
||||
birthdayDate: textControllerData!.text,
|
||||
|
@ -323,7 +327,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
Future<void> registerPet() async {
|
||||
var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!);
|
||||
img = "base64;jpeg,$img";
|
||||
final response = await PhpGroup.registerPet.call(
|
||||
final response = await FreAccessWSGlobal.registerPet.call(
|
||||
image: img,
|
||||
birthdayDate: textControllerData!.text,
|
||||
color: textControllerColor!.text,
|
||||
|
@ -464,7 +468,7 @@ class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
|
|||
enText: 'Are you sure you want to delete this pet?',
|
||||
), () async {
|
||||
int id = item['id'];
|
||||
await PhpGroup.deletePet
|
||||
await FreAccessWSGlobal.deletePet
|
||||
.call(
|
||||
petID: id,
|
||||
)
|
||||
|
|
|
@ -62,7 +62,7 @@ class PreferencesPageModel with ChangeNotifier {
|
|||
onConfirm() async {
|
||||
String content;
|
||||
String value = !isNotify ? 'S' : 'N';
|
||||
await PhpGroup.changeNotifica
|
||||
await FreAccessWSGlobal.changeNotifica
|
||||
.call(notifica: value)
|
||||
.then((value) async {
|
||||
if (value.jsonBody['error'] == false) {
|
||||
|
@ -109,7 +109,7 @@ class PreferencesPageModel with ChangeNotifier {
|
|||
);
|
||||
onConfirm() async {
|
||||
String content;
|
||||
await PhpGroup.updateIDE.call().then((value) async {
|
||||
await FreAccessWSGlobal.updateIDE.call().then((value) async {
|
||||
if (value.jsonBody['error'] == false) {
|
||||
notifyListeners();
|
||||
content = FFLocalizations.of(context).getVariableText(
|
||||
|
@ -141,7 +141,7 @@ class PreferencesPageModel with ChangeNotifier {
|
|||
Future<void> toggleAccess(BuildContext context) async {
|
||||
onChange(String key) async {
|
||||
await StorageHelper().set(SecureStorageKey.accessPass.value, key);
|
||||
await PhpGroup.changePass
|
||||
await FreAccessWSGlobal.changePass
|
||||
.call(newSenha: key)
|
||||
.then((value) async {
|
||||
final String content;
|
||||
|
@ -180,7 +180,7 @@ class PreferencesPageModel with ChangeNotifier {
|
|||
Future<void> togglePanic(BuildContext context) async {
|
||||
onChange(String key) async {
|
||||
await StorageHelper().set(SecureStorageKey.panicPass.value, key);
|
||||
await PhpGroup.changePanic
|
||||
await FreAccessWSGlobal.changePanic
|
||||
.call(newSenhaPanico: key)
|
||||
.then((value) async {
|
||||
final String content;
|
||||
|
|
|
@ -103,7 +103,6 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
|||
screenWidth < screenHeight ? screenWidth : screenHeight;
|
||||
double dimension = smallerDimension * 0.75;
|
||||
double totalTimeInSeconds = 100.0;
|
||||
double limitedHeaderTextSize =
|
||||
LimitedFontSizeUtil.getCalculateFontSize(context, 18, 18, 16);
|
||||
double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
|
||||
|
|
|
@ -29,9 +29,7 @@ class _ReceptionPageWidgetState extends State<ReceptionPageWidget>
|
|||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
() async {
|
||||
final lifecycle = await AwesomeNotifications().getAppLifeCycle();
|
||||
}();
|
||||
() async {}();
|
||||
|
||||
FirebaseMessagingService().updateDeviceToken();
|
||||
LocalsRepositoryImpl().validateLocal(context);
|
||||
|
@ -183,7 +181,7 @@ class _ReceptionPageWidgetState extends State<ReceptionPageWidget>
|
|||
padding: const EdgeInsets.fromLTRB(60, 0, 60, 25),
|
||||
child: FFButtonWidget(
|
||||
onPressed: () async {
|
||||
PhpGroup.unregisterDevice();
|
||||
FreAccessWSGlobal.unregisterDevice();
|
||||
AuthenticationService.signOut(context);
|
||||
setState(() {});
|
||||
},
|
||||
|
|
|
@ -175,8 +175,8 @@ class _ResidentsOnThePropertyState extends State<ResidentsOnTheProperty>
|
|||
try {
|
||||
setState(() => _loading = true);
|
||||
|
||||
var response =
|
||||
await PhpGroup.getResidentsByProperty.call(_pageNumber.toString());
|
||||
var response = await FreAccessWSGlobal.getResidentsByProperty
|
||||
.call(_pageNumber.toString());
|
||||
|
||||
final List<dynamic> residents = response.jsonBody['residents'] ?? [];
|
||||
safeSetState(() => count = response.jsonBody['total_rows'] ?? 0);
|
||||
|
|
|
@ -361,7 +361,7 @@ class ScheduleCompleteVisitPageModel
|
|||
required String? accessKey,
|
||||
required String? email}) async {
|
||||
final ApiCallResponse? response;
|
||||
final CancelaVisita callback = PhpGroup.cancelaVisita;
|
||||
final CancelaVisita callback = FreAccessWSGlobal.cancelaVisita;
|
||||
|
||||
response = await callback.call(
|
||||
idDestino: idDestino,
|
||||
|
|
|
@ -90,6 +90,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
void _scrollListener() {
|
||||
if (_visitHistoryController.position.pixels ==
|
||||
_visitHistoryController.position.maxScrollExtent) {
|
||||
|
@ -1071,7 +1072,8 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
height: scaledSizedBoxSize * 0.5,
|
||||
decoration: const BoxDecoration(),
|
||||
child: FutureBuilder<ApiCallResponse>(
|
||||
future: PhpGroup.getDadosCall.call(),
|
||||
future:
|
||||
FreAccessWSGlobal.getDadosCall.call(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
|
@ -1088,11 +1090,12 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
);
|
||||
}
|
||||
|
||||
final reasonsJsonList =
|
||||
PhpGroup.getDadosCall.reasonsJsonList(
|
||||
snapshot.data!.jsonBody);
|
||||
final reasonsOptionLabels = PhpGroup
|
||||
final reasonsJsonList = FreAccessWSGlobal
|
||||
.getDadosCall
|
||||
.reasonsJsonList(
|
||||
snapshot.data!.jsonBody);
|
||||
final reasonsOptionLabels =
|
||||
FreAccessWSGlobal.getDadosCall
|
||||
.reasonsMotDescStrList(
|
||||
snapshot.data!.jsonBody);
|
||||
|
||||
|
@ -1195,7 +1198,8 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
height: scaledSizedBoxSize * 0.5,
|
||||
decoration: const BoxDecoration(),
|
||||
child: FutureBuilder<ApiCallResponse>(
|
||||
future: PhpGroup.getDadosCall.call(),
|
||||
future:
|
||||
FreAccessWSGlobal.getDadosCall.call(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
|
@ -1212,11 +1216,12 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
);
|
||||
}
|
||||
|
||||
final lavelsJsonList =
|
||||
PhpGroup.getDadosCall.levelJsonList(
|
||||
snapshot.data!.jsonBody);
|
||||
final lavelsOptionLabels = PhpGroup
|
||||
final lavelsJsonList = FreAccessWSGlobal
|
||||
.getDadosCall
|
||||
.levelJsonList(
|
||||
snapshot.data!.jsonBody);
|
||||
final lavelsOptionLabels =
|
||||
FreAccessWSGlobal.getDadosCall
|
||||
.levelNACDescricaoStrList(
|
||||
snapshot.data!.jsonBody);
|
||||
model.processDropDown2(lavelsJsonList!);
|
||||
|
@ -1556,7 +1561,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
onPressed: model.isValid()
|
||||
? () async {
|
||||
Future<void> scheduleVisit() async {
|
||||
await PhpGroup.postScheduleVisitCall
|
||||
await FreAccessWSGlobal.postScheduleVisitCall
|
||||
.call(
|
||||
devDesc: model.textController3.text,
|
||||
idVisitante: model.visitorStrList,
|
||||
|
@ -1572,7 +1577,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
|||
.catchError((e) async =>
|
||||
await DialogUtil.errorDefault(context))
|
||||
.then((value) async {
|
||||
if (PhpGroup.postScheduleVisitCall.error(
|
||||
if (FreAccessWSGlobal.postScheduleVisitCall.error(
|
||||
(value.jsonBody ?? ''),
|
||||
) ==
|
||||
false) {
|
||||
|
|
|
@ -76,7 +76,7 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget>
|
|||
setState(() => _loading = true);
|
||||
|
||||
var response = await ScheduleCompleteVisitPageModel().visitHistory(
|
||||
requestFn: () => PhpGroup.getVisitsCall.call(
|
||||
requestFn: () => FreAccessWSGlobal.getVisitsCall.call(
|
||||
pageSize: _pageSize,
|
||||
pageNumber: _pageNumber,
|
||||
),
|
||||
|
|
|
@ -10,7 +10,7 @@ class VehicleHistoryScreen extends StatefulWidget {
|
|||
|
||||
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
|
||||
with Pageable {
|
||||
final apiCall = PhpGroup.getVehiclesByProperty;
|
||||
final apiCall = FreAccessWSGlobal.getVehiclesByProperty;
|
||||
int totalOwnerVehicles = 0;
|
||||
final PagingController<int, dynamic> _pagingController =
|
||||
PagingController<int, dynamic>(firstPageKey: 1);
|
||||
|
|
|
@ -7,8 +7,8 @@ import 'package:hub/features/backend/index.dart';
|
|||
import 'package:hub/features/storage/index.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart';
|
||||
import 'package:hub/shared/extensions/index.dart';
|
||||
import 'package:hub/shared/utils/index.dart';
|
||||
import 'package:hub/shared/extensions.dart';
|
||||
import 'package:hub/shared/utils.dart';
|
||||
|
||||
/// [VehicleModel] is a class that contains the business logic of the vehicle page.
|
||||
class VehicleModel extends FlutterFlowModel<VehiclePage>
|
||||
|
@ -196,7 +196,7 @@ mixin class _BaseVehiclePage {
|
|||
/// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page.
|
||||
mixin _VehicleRegisterScreenModel on _BaseVehiclePage {
|
||||
Future<void> registerVehicle() async {
|
||||
final response = await PhpGroup.registerVehicle.call(
|
||||
final response = await FreAccessWSGlobal.registerVehicle.call(
|
||||
licensePlate: textFieldControllerLicensePlate!.text,
|
||||
color: textFieldControllerColor!.text,
|
||||
model: textFieldControllerModel!.text,
|
||||
|
@ -218,7 +218,7 @@ mixin _VehicleRegisterScreenModel on _BaseVehiclePage {
|
|||
/// [_VehicleUpdateScreenModel] is a mixin that contains the business logic of the vehicle update page.
|
||||
mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
|
||||
Future<void> updateVehicle() async {
|
||||
final response = await PhpGroup.updateVehicle.call(
|
||||
final response = await FreAccessWSGlobal.updateVehicle.call(
|
||||
licensePlate: textFieldControllerLicensePlate!.text,
|
||||
color: textFieldControllerColor!.text,
|
||||
model: textFieldControllerModel!.text,
|
||||
|
@ -403,7 +403,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
|
||||
Future<bool> processDeleteRequest(dynamic item) async {
|
||||
log('processDeleteRequest -> item[$item]');
|
||||
bool result = await PhpGroup.deleteVehicle
|
||||
bool result = await FreAccessWSGlobal.deleteVehicle
|
||||
.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
|
@ -493,7 +493,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
}
|
||||
|
||||
Future<ApiCallResponse> processCancelDeleteRequest(dynamic item) async {
|
||||
return await PhpGroup.deleteVehicle.call(
|
||||
return await FreAccessWSGlobal.deleteVehicle.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
model: item['model'],
|
||||
|
@ -502,7 +502,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
}
|
||||
|
||||
Future<ApiCallResponse> processCancelUpdateRequest(dynamic item) async {
|
||||
return await PhpGroup.deleteVehicle.call(
|
||||
return await FreAccessWSGlobal.deleteVehicle.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
model: item['model'],
|
||||
|
@ -511,7 +511,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
|||
}
|
||||
|
||||
Future<ApiCallResponse> processCancelCreateRequest(dynamic item) async {
|
||||
return await PhpGroup.cancelDelete.call(
|
||||
return await FreAccessWSGlobal.cancelDelete.call(
|
||||
vehicleId: item['vehicleId'],
|
||||
licensePlate: item['licensePlate'],
|
||||
model: item['model'],
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'package:hub/features/backend/index.dart';
|
|||
import 'package:hub/features/module/index.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart';
|
||||
import 'package:hub/shared/extensions/index.dart';
|
||||
import 'package:hub/shared/extensions.dart';
|
||||
import 'package:hub/shared/mixins/pageable_mixin.dart';
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/utils/license_util.dart';
|
||||
|
|
|
@ -54,8 +54,8 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
late final limitedBodyTextSize =
|
||||
LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
// late final limitedBodyTextSize =
|
||||
// LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
late final limitedHeaderTextSize =
|
||||
LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
|
||||
|
@ -176,7 +176,7 @@ class _VisitsOnThePropertyState extends State<VisitsOnTheProperty>
|
|||
setState(() => _loading = true);
|
||||
|
||||
var response =
|
||||
await PhpGroup.getOpenedVisits.call(_pageNumber.toString());
|
||||
await FreAccessWSGlobal.getOpenedVisits.call(_pageNumber.toString());
|
||||
|
||||
final List<dynamic> visits = response.jsonBody['visitas'] ?? [];
|
||||
safeSetState(() => count = response.jsonBody['total_rows'] ?? 0);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
export 'enums/enum_throw_exception.dart';
|
|
@ -1 +0,0 @@
|
|||
export 'enum_throw_exception.dart';
|
|
@ -0,0 +1,3 @@
|
|||
export 'extensions/dialog_extensions.dart';
|
||||
export 'extensions/flutter_secure_storage_extensions.dart';
|
||||
export 'extensions/string_extensions.dart';
|
|
@ -1,3 +0,0 @@
|
|||
export 'dialog_extensions.dart';
|
||||
export 'flutter_secure_storage_extensions.dart';
|
||||
export 'string_extensions.dart';
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:ui';
|
||||
|
||||
extension StringNullableExtensions on String? {
|
||||
bool get toBoolean {
|
||||
if (this == null) return false;
|
||||
|
@ -24,3 +26,16 @@ extension StringExtensions on String {
|
|||
}
|
||||
|
||||
extension StringExtension on String? {}
|
||||
|
||||
extension HexColor on String {
|
||||
Color toColor() {
|
||||
final hexCode = replaceAll('#', '');
|
||||
final buffer = StringBuffer();
|
||||
if (hexCode.length == 6) {
|
||||
buffer
|
||||
.write('ff'); // Adiciona opacidade total caso não esteja especificada
|
||||
}
|
||||
buffer.write(hexCode);
|
||||
return Color(int.parse(buffer.toString(), radix: 16));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
export 'mixins/pegeable_mixin.dart';
|
||||
export 'mixins/status_mixin.dart';
|
||||
export 'mixins/switcher_mixin.dart';
|
||||
export 'mixins/template_mixin.dart';
|
|
@ -1,2 +0,0 @@
|
|||
export 'status_mixin.dart';
|
||||
export 'switcher_mixin.dart';
|
|
@ -0,0 +1,139 @@
|
|||
// import 'package:flutter/material.dart';
|
||||
// import 'package:hub/flutter_flow/index.dart';
|
||||
// import 'package:hub/shared/utils/limited_text_size.dart';
|
||||
// import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
|
||||
// extension PagedListViewExtension<PageKeyType, ItemType>
|
||||
// on PagedSliverList<PageKeyType, ItemType> {}
|
||||
|
||||
// typedef PaginatedListViewHeaderBuilder<T> = Widget Function<T>(
|
||||
// Future<List<T?>> Function() gen);
|
||||
// typedef PaginatedListViewBodyBuilder<T> = Widget Function(BuildContext, T, int);
|
||||
|
||||
// mixin Pageable<T extends StatefulWidget> on State<T> {
|
||||
// Expanded buildPaginatedListView<PageKeyType, BodyType, HeaderType>(
|
||||
// String noDataFound,
|
||||
// PagingController<PageKeyType, BodyType> pg,
|
||||
// Future<List<HeaderType?>> Function() headerItems,
|
||||
// PaginatedListViewHeaderBuilder<BodyType> headerBuilder,
|
||||
// PaginatedListViewBodyBuilder<BodyType> bodyBuilder) {
|
||||
// final theme = FlutterFlowTheme.of(context);
|
||||
// return Expanded(
|
||||
// child: RefreshIndicator(
|
||||
// backgroundColor: theme.primaryBackground,
|
||||
// color: theme.primary,
|
||||
// onRefresh: () async => pg.refresh(),
|
||||
// child: PagedListView<PageKeyType, BodyType>(
|
||||
// pagingController: pg,
|
||||
// builderDelegate: PagedChildBuilderDelegate<BodyType>(
|
||||
// animateTransitions: true,
|
||||
// itemBuilder: (context, item, int index) {
|
||||
// return Column(children: [
|
||||
// if (index == 0) headerBuilder(headerItems),
|
||||
// bodyBuilder(context, item, index),
|
||||
// ]);
|
||||
// },
|
||||
// newPageProgressIndicatorBuilder: (context) =>
|
||||
// buildLoadingIndicator(context),
|
||||
// firstPageProgressIndicatorBuilder: (context) =>
|
||||
// buildLoadingIndicator(context),
|
||||
// noItemsFoundIndicatorBuilder: (context) =>
|
||||
// buildNoDataFound<HeaderType>(
|
||||
// context, noDataFound, headerItems, headerBuilder),
|
||||
// firstPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||
// newPageErrorIndicatorBuilder: (context) => const Placeholder(),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
// Future<void> showError(PagingStatus status, PagingController pg) async {
|
||||
// if (status == PagingStatus.subsequentPageError) {
|
||||
// final message = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Something went wrong while fetching a new page.',
|
||||
// ptText: 'Algo deu errado ao buscar uma nova página.',
|
||||
// );
|
||||
// final retry = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Retry',
|
||||
// ptText: 'Recarregar',
|
||||
// );
|
||||
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text(message),
|
||||
// action: SnackBarAction(
|
||||
// label: retry,
|
||||
// onPressed: () => pg.retryLastFailedRequest(),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> fetchPage({
|
||||
// required Future<(bool, dynamic)> Function() dataProvider,
|
||||
// required void Function(dynamic data) onDataAvailable,
|
||||
// required void Function() onDataUnavailable,
|
||||
// required void Function(Object error, StackTrace stackTrace) onFetchError,
|
||||
// }) async {
|
||||
// try {
|
||||
// final (bool isDataAvailable, dynamic data) = await dataProvider();
|
||||
// if (isDataAvailable) {
|
||||
// onDataAvailable(data);
|
||||
// } else {
|
||||
// onDataUnavailable();
|
||||
// }
|
||||
// } catch (error, stackTrace) {
|
||||
// onFetchError(error, stackTrace);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void showNoMoreDataSnackBar(BuildContext context) {
|
||||
// final message = FFLocalizations.of(context).getVariableText(
|
||||
// ptText: "Não há mais dados.",
|
||||
// enText: "No more data.",
|
||||
// );
|
||||
|
||||
// showSnackbar(context, message, true);
|
||||
// }
|
||||
|
||||
// Widget buildNoDataFound<T>(
|
||||
// BuildContext context,
|
||||
// String title,
|
||||
// Future<List<T?>> Function() items,
|
||||
// Widget Function<T>(Future<List<T?>> Function() items) headerBuilder,
|
||||
// ) {
|
||||
// final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
// // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context);
|
||||
// return Column(
|
||||
// children: [
|
||||
// headerBuilder(items),
|
||||
// Expanded(
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// title,
|
||||
// style: TextStyle(
|
||||
// fontFamily: 'Nunito',
|
||||
// fontSize: headerFontSize,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
// Widget buildLoadingIndicator(BuildContext context) {
|
||||
// return Container(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
// child: Center(
|
||||
// child: CircularProgressIndicator(
|
||||
// valueColor: AlwaysStoppedAnimation<Color>(
|
||||
// FlutterFlowTheme.of(context).primary,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,70 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||
|
||||
mixin Template {
|
||||
PreferredSizeWidget buildAppBar(
|
||||
String title,
|
||||
BuildContext context, [
|
||||
dynamic Function()? backAction,
|
||||
dynamic Function()? frontAction,
|
||||
]) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
return AppBar(
|
||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||
automaticallyImplyLeading: false,
|
||||
title: Text(
|
||||
title,
|
||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||
fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
letterSpacing: 0.0,
|
||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||
FlutterFlowTheme.of(context).headlineMediumFamily),
|
||||
),
|
||||
),
|
||||
leading: _backButton(context, theme, backAction),
|
||||
centerTitle: true,
|
||||
elevation: 0.0,
|
||||
actions: _frontButton(context, theme, frontAction),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _frontButton(BuildContext context, FlutterFlowTheme theme,
|
||||
dynamic Function()? action) {
|
||||
if (action == null) return [];
|
||||
return [
|
||||
IconButton(
|
||||
onPressed: () async => await showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => action(),
|
||||
),
|
||||
icon: Icon(
|
||||
Symbols.info_i_rounded,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
),
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
Widget? _backButton(BuildContext context, FlutterFlowTheme theme,
|
||||
dynamic Function()? onPressed) {
|
||||
if (onPressed == null) return null;
|
||||
return FlutterFlowIconButton(
|
||||
key: ValueKey<String>('BackNavigationAppBar'),
|
||||
borderColor: Colors.transparent,
|
||||
borderRadius: 30.0,
|
||||
borderWidth: 1.0,
|
||||
buttonSize: 60.0,
|
||||
icon: Icon(
|
||||
Icons.keyboard_arrow_left,
|
||||
color: theme.primaryText,
|
||||
size: 30.0,
|
||||
),
|
||||
onPressed: onPressed,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
export 'utils/biometric_util.dart';
|
||||
export 'utils/device_util.dart';
|
||||
export 'utils/dialog_util.dart';
|
||||
export 'utils/image_util.dart';
|
||||
export 'utils/limited_text_size.dart';
|
||||
export 'utils/loading_util.dart';
|
||||
export 'utils/log_util.dart';
|
||||
export 'utils/path_util.dart';
|
||||
export 'utils/share_util.dart';
|
||||
export 'utils/snackbar_util.dart';
|
||||
export 'utils/string_util.dart';
|
||||
export 'utils/text_util.dart';
|
||||
export 'utils/validator_util.dart';
|
||||
export 'utils/webview_util.dart';
|
||||
export 'utils/color_util.dart';
|
|
@ -0,0 +1,48 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ColorUtil {
|
||||
static Color getContrastColor(Color a, Color b) {
|
||||
double luminance(Color color) {
|
||||
return (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) / 255;
|
||||
}
|
||||
|
||||
double contrastRatio(Color a, Color b) {
|
||||
final lumA = luminance(a) + 0.05;
|
||||
final lumB = luminance(b) + 0.05;
|
||||
return lumA > lumB ? lumA / lumB : lumB / lumA;
|
||||
}
|
||||
|
||||
if (contrastRatio(a, b) < 4.5) {
|
||||
// Find a color with higher contrast within the same hue
|
||||
final hsv = HSVColor.fromColor(a);
|
||||
double hue = hsv.hue;
|
||||
double saturation = hsv.saturation;
|
||||
double brightness = hsv.value;
|
||||
|
||||
// Increase brightness to ensure higher contrast
|
||||
brightness = brightness > 0.5 ? brightness - 0.5 : brightness + 0.5;
|
||||
|
||||
return HSVColor.fromAHSV(1.0, hue, saturation, brightness).toColor();
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static Color getSelfContrastColor(Color color) {
|
||||
final hsv = HSVColor.fromColor(color);
|
||||
double hue = hsv.hue;
|
||||
double saturation = hsv.saturation;
|
||||
double brightness = hsv.value;
|
||||
|
||||
// Increase brightness to ensure higher contrast
|
||||
brightness = brightness > 0.5 ? brightness - 0.5 : brightness + 0.5;
|
||||
|
||||
return HSVColor.fromAHSV(1.0, hue, saturation, brightness).toColor();
|
||||
}
|
||||
}
|
||||
|
||||
extension ColorUtilExtension on Color {
|
||||
Color get highlight => ColorUtil.getSelfContrastColor(this);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
export 'biometric_util.dart';
|
||||
export 'device_util.dart';
|
||||
export 'dialog_util.dart';
|
||||
export 'image_util.dart';
|
||||
export 'limited_text_size.dart';
|
||||
export 'loading_util.dart';
|
||||
export 'log_util.dart';
|
||||
export 'path_util.dart';
|
||||
export 'share_util.dart';
|
||||
export 'snackbar_util.dart';
|
||||
export 'string_util.dart';
|
||||
export 'text_util.dart';
|
||||
export 'validator_util.dart';
|
||||
export 'webview_util.dart';
|
|
@ -6,7 +6,7 @@ import 'package:hub/features/backend/index.dart';
|
|||
class LogUtil {
|
||||
static void requestAPIFailed(String url, String body, String reason,
|
||||
dynamic error, StackTrace stack) async {
|
||||
final fullUrl = "${PhpGroup.getBaseUrl()}/$url";
|
||||
final fullUrl = "${FreAccessWSGlobal.getBaseUrl()}/$url";
|
||||
log("URL: $fullUrl");
|
||||
log("Body: $body");
|
||||
log("Reason: $reason");
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ValidatorUtil {
|
||||
|
@ -34,10 +36,16 @@ class ValidatorUtil {
|
|||
}
|
||||
|
||||
static String toLocalDateTime(String format, String value) {
|
||||
try {
|
||||
if (value.isEmpty) return '';
|
||||
DateFormat dateFormat = DateFormat(format);
|
||||
DateTime dateTime = dateFormat.parse(value);
|
||||
|
||||
return DateFormat('dd/MM/yyyy HH:mm:ss').format(dateTime);
|
||||
DateTime? dateTime = dateFormat.tryParse(value);
|
||||
if (dateTime == null) return '';
|
||||
return dateFormat.format(dateTime);
|
||||
} catch (e, s) {
|
||||
log(e.toString(), stackTrace: s);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static String formatDateTimePicker(String dateTime) {
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/// [Base]
|
||||
library;
|
||||
|
||||
export 'widgets/page.dart';
|
||||
export 'widgets/component.dart';
|
||||
export 'widgets/screen.dart';
|
||||
export 'widgets/model.dart';
|
||||
export 'widgets/entity.dart';
|
||||
|
||||
/// [View]'s
|
||||
export 'widgets/list_view.dart';
|
||||
export 'widgets/read_view.dart';
|
||||
export 'widgets/enhanced_carousel_view.dart';
|
||||
export 'widgets/enhanced_list_view.dart';
|
||||
export 'widgets/enhanced_search_view.dart';
|
||||
|
||||
/// [Component]'s
|
||||
export 'widgets/text.dart';
|
|
@ -0,0 +1,25 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
|
||||
/// [ComponentWidget]
|
||||
|
||||
abstract class ComponentWidget<T> extends Widget {
|
||||
const ComponentWidget({super.key});
|
||||
}
|
||||
|
||||
abstract class ModelComponent<T> extends ModelWidget
|
||||
implements ComponentWidget<T> {
|
||||
const ModelComponent({super.key});
|
||||
}
|
||||
|
||||
abstract class StatelessComponent<T> extends StatelessWidget
|
||||
implements ComponentWidget<T> {
|
||||
const StatelessComponent({super.key});
|
||||
}
|
||||
|
||||
abstract class StatefulComponent<T> extends StatefulWidget
|
||||
implements ComponentWidget<T> {
|
||||
const StatefulComponent({super.key});
|
||||
}
|
||||
|
||||
abstract class ComponentState<T extends StatefulComponent> extends State<T> {}
|
|
@ -0,0 +1,124 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/shared/utils.dart';
|
||||
|
||||
typedef EnhancedCarouselViewKey<T> = GlobalKey<_EnhancedCarouselViewState<T>>;
|
||||
|
||||
class EnhancedCarouselView<T> extends StatefulWidget {
|
||||
final Future<List<T?>> Function() dataProvider;
|
||||
final void Function(T?, BuildContext) filter;
|
||||
final Widget Function<T>(T? item, bool isSelected) itemBuilder;
|
||||
final bool showIndicator;
|
||||
|
||||
const EnhancedCarouselView({
|
||||
super.key,
|
||||
required this.dataProvider,
|
||||
required this.filter,
|
||||
required this.itemBuilder,
|
||||
this.showIndicator = false,
|
||||
});
|
||||
|
||||
@override
|
||||
_EnhancedCarouselViewState<T> createState() =>
|
||||
_EnhancedCarouselViewState<T>();
|
||||
}
|
||||
|
||||
class _EnhancedCarouselViewState<T> extends State<EnhancedCarouselView<T>> {
|
||||
T? selectedCategory;
|
||||
|
||||
bool itemIsSelected(T item) {
|
||||
return selectedCategory == item;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final backgroundColor = theme.primary;
|
||||
final overlayColor = WidgetStateProperty.all(Colors.transparent);
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 0, 50, 0),
|
||||
child: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Suas Categorias',
|
||||
enText: 'Your Categories',
|
||||
),
|
||||
style: TextStyle(
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
fontSize: LimitedFontSizeUtil.getHeaderFontSize(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
FutureBuilder<List<T?>>(
|
||||
future: widget.dataProvider(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) return SizedBox();
|
||||
final items = snapshot.data!
|
||||
.map((item) =>
|
||||
widget.itemBuilder(item, itemIsSelected(item as T)))
|
||||
.toList();
|
||||
return SizedBox(
|
||||
height: 130, // Set a specific height
|
||||
child: CarouselView(
|
||||
itemExtent: 140,
|
||||
enableSplash: true,
|
||||
itemSnapping: true,
|
||||
controller: CarouselController(initialItem: 1),
|
||||
backgroundColor: backgroundColor,
|
||||
overlayColor: overlayColor,
|
||||
padding: EdgeInsets.zero,
|
||||
elevation: 0,
|
||||
reverse: true,
|
||||
shrinkExtent: 10,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
onTap: (index) async {
|
||||
log('Selected: ${snapshot.data![index]}');
|
||||
log('Selected Category: $selectedCategory');
|
||||
final bool isSame =
|
||||
itemIsSelected(snapshot.data![index]!);
|
||||
setState(() {
|
||||
if (isSame) {
|
||||
selectedCategory = null;
|
||||
} else {
|
||||
selectedCategory = snapshot.data![index] as T;
|
||||
}
|
||||
});
|
||||
if (isSame)
|
||||
widget.filter(null, context);
|
||||
else
|
||||
widget.filter(snapshot.data![index] as T, context);
|
||||
},
|
||||
children: items,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
if (widget.showIndicator)
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 50,
|
||||
child: Icon(Icons.arrow_left, size: 30, color: Colors.grey),
|
||||
),
|
||||
if (widget.showIndicator)
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 50,
|
||||
child: Icon(Icons.arrow_right, size: 30, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,616 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:rx_bloc/rx_bloc.dart';
|
||||
import 'package:rx_bloc_list/rx_bloc_list.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
/// [TypeDefs] ----------------------------------------------------
|
||||
|
||||
typedef EnhancedListViewKey<BodyType, HeaderType, FooterType, QueryType>
|
||||
= GlobalKey<
|
||||
EnhancedListViewState<BodyType, HeaderType, FooterType, QueryType>>;
|
||||
typedef HeaderTileBuilder<HeaderType> = Widget Function(
|
||||
Future<List<HeaderType?>> Function() headerItems);
|
||||
typedef BodyTileBuilder<BodyType> = Widget Function(
|
||||
BuildContext context, BodyType item, int index);
|
||||
typedef FooterTileBuilder<FooterType> = Widget Function(
|
||||
Future<List<FooterType?>> Function() footerItems);
|
||||
typedef Query<QueryType> = QueryType?;
|
||||
typedef BodyRetrievalUseCase<BodyType, QueryType> = Future<List<BodyType?>>
|
||||
Function(int page, int pageSize, QueryType query);
|
||||
typedef HeaderRetrievalUseCase<HeaderType> = Future<List<HeaderType?>>
|
||||
Function();
|
||||
typedef FooterRetrievalUseCase<FooterType> = Future<List<FooterType?>>
|
||||
Function();
|
||||
|
||||
/// [Extensions] ----------------------------------------------------
|
||||
///
|
||||
extension PaginatedListMergeExtensions<T>
|
||||
on Stream<Result<EnhancedPaginatedList<T>>> {
|
||||
Stream<EnhancedPaginatedList<T>> mergeWithPaginatedList(
|
||||
BehaviorSubject<EnhancedPaginatedList<T>> currentList) {
|
||||
return map(
|
||||
(result) {
|
||||
final current = currentList.value;
|
||||
if (result is ResultSuccess<EnhancedPaginatedList<T>>) {
|
||||
final newPaginated = result.data;
|
||||
return current.items.isEmpty
|
||||
? newPaginated
|
||||
: current.copyWith(
|
||||
list: [...current.items, ...newPaginated.items],
|
||||
currentPage: newPaginated.currentPage,
|
||||
totalCount: newPaginated.totalCount,
|
||||
error: newPaginated.error,
|
||||
);
|
||||
} else if (result is ResultError<EnhancedPaginatedList<T>>) {
|
||||
return current.copyWith(error: result.error);
|
||||
} else {
|
||||
return current;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension PublishSubjectExtensions<T> on PublishSubject<T> {
|
||||
Stream<T> startWith(T initial) => Rx.concat([Stream.value(initial), this]);
|
||||
}
|
||||
|
||||
extension StreamStartWithExtension<T> on Stream<T> {
|
||||
Stream<T> startWith(T initial) => Rx.concat([Stream.value(initial), this]);
|
||||
}
|
||||
|
||||
extension QueryBlocStreamExtensions<T> on Stream<bool> {
|
||||
// Stream<Result<EnhancedPaginatedList<T>>> fetchData(
|
||||
// EnhancedListViewRepository<T> repository,
|
||||
// PaginatedListViewBodyBuilder<T> builder,
|
||||
// BehaviorSubject<EnhancedPaginatedList<T>> paginatedList,
|
||||
// ) =>
|
||||
// switchMap((reset) {
|
||||
// if (reset) {
|
||||
// paginatedList.add(paginatedList.value.resetAll());
|
||||
// }
|
||||
// final nextPage = paginatedList.value.currentPage + 1;
|
||||
// return repository
|
||||
// .fetchPage(nextPage, paginatedList.value.pageSize, builder)
|
||||
// .asResultStream();
|
||||
// });
|
||||
}
|
||||
|
||||
/// [Interfaces] ----------------------------------------------------
|
||||
|
||||
interface class EnhancedPaginatedList<T> extends PaginatedList<T> {
|
||||
@override
|
||||
final Exception? error;
|
||||
final bool isInitialized;
|
||||
@override
|
||||
final bool isLoading;
|
||||
final List<T> items;
|
||||
@override
|
||||
final int pageSize;
|
||||
@override
|
||||
final int? totalCount;
|
||||
final int currentPage;
|
||||
|
||||
EnhancedPaginatedList({
|
||||
required this.items,
|
||||
required this.pageSize,
|
||||
this.currentPage = 0,
|
||||
this.totalCount,
|
||||
required this.error,
|
||||
required this.isInitialized,
|
||||
required this.isLoading,
|
||||
}) : super(
|
||||
error: error,
|
||||
isInitialized: isInitialized,
|
||||
isLoading: isLoading,
|
||||
list: items,
|
||||
pageSize: pageSize,
|
||||
totalCount: totalCount,
|
||||
);
|
||||
|
||||
EnhancedPaginatedList<T> resetAll() => EnhancedPaginatedList<T>(
|
||||
error: null,
|
||||
isInitialized: false,
|
||||
isLoading: false,
|
||||
items: const [],
|
||||
pageSize: pageSize,
|
||||
totalCount: null,
|
||||
currentPage: 0,
|
||||
);
|
||||
|
||||
@override
|
||||
EnhancedPaginatedList<T> copyWith({
|
||||
List<T>? list,
|
||||
bool? isLoading,
|
||||
int? totalCount,
|
||||
Exception? error,
|
||||
int? pageSize,
|
||||
bool? isInitialized,
|
||||
int? currentPage,
|
||||
}) =>
|
||||
EnhancedPaginatedList<T>(
|
||||
error: error ?? this.error,
|
||||
isInitialized: isInitialized ?? this.isInitialized,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
items: list ?? this.items,
|
||||
pageSize: pageSize ?? this.pageSize,
|
||||
totalCount: totalCount ?? this.totalCount,
|
||||
currentPage: currentPage ?? this.currentPage,
|
||||
);
|
||||
|
||||
@override
|
||||
int get itemCount => items.length;
|
||||
|
||||
@override
|
||||
T? getItem(int index) => index < items.length ? items[index] : null;
|
||||
|
||||
Future<void> awaitLoad() async => Future.value();
|
||||
}
|
||||
|
||||
abstract interface class EnhancedListViewBase<BodyType, HeaderType, FooterType,
|
||||
QueryType> extends StatefulWidget {
|
||||
const EnhancedListViewBase({super.key});
|
||||
}
|
||||
|
||||
abstract interface class EnhancedListViewBaseState<BodyType, HeaderType,
|
||||
FooterType, QueryType>
|
||||
extends State<
|
||||
EnhancedListViewBase<BodyType, HeaderType, FooterType, QueryType>> {}
|
||||
|
||||
/// [Mixins] ----------------------------------------------------
|
||||
|
||||
mixin EnhancedListViewMixin<BodyType, HeaderType, FooterType, QueryType> {
|
||||
late EnhancedListViewBloc<BodyType, HeaderType, FooterType, QueryType> bloc;
|
||||
|
||||
void filterBodyItems(QueryType query) => bloc.filterBodyItems(query);
|
||||
|
||||
void filterHeaderItems(QueryType query) => bloc.filterHeaderItems(query);
|
||||
|
||||
void filterFooterItems(QueryType query) => bloc.filterFooterItems(query);
|
||||
}
|
||||
|
||||
/// [Widgets] ----------------------------------------------------
|
||||
|
||||
class EnhancedListView<BodyType, HeaderType, FooterType, QueryType>
|
||||
extends EnhancedListViewBase<BodyType, HeaderType, FooterType, QueryType> {
|
||||
final EnhancedListViewRepository<BodyType, HeaderType, FooterType, QueryType>
|
||||
repository;
|
||||
final EnhancedListViewController<BodyType, HeaderType, FooterType, QueryType>
|
||||
controller;
|
||||
|
||||
const EnhancedListView({
|
||||
Key? key,
|
||||
required this.repository,
|
||||
required this.controller,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
EnhancedListViewState<BodyType, HeaderType, FooterType, QueryType>
|
||||
createState() =>
|
||||
EnhancedListViewState<BodyType, HeaderType, FooterType, QueryType>();
|
||||
}
|
||||
|
||||
class EnhancedListViewState<ItemType, HeaderType, FooterType, QueryType>
|
||||
extends State<EnhancedListView<ItemType, HeaderType, FooterType, QueryType>>
|
||||
with EnhancedListViewMixin<ItemType, HeaderType, FooterType, QueryType> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
bloc = EnhancedListViewBloc<ItemType, HeaderType, FooterType, QueryType>(
|
||||
bodyItemsBuilder: widget.repository.fetchBody,
|
||||
headerItemsBuilder: widget.repository.fetchHeader ?? () async => [],
|
||||
footerItemsBuilder: widget.repository.fetchFooter ?? () async => [],
|
||||
);
|
||||
bloc.events.loadBodyItems();
|
||||
bloc.events.loadHeaderItems();
|
||||
bloc.events.loadFooterItems();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String defaultMessage = FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Nenhum item encontrado',
|
||||
enText: 'No items found',
|
||||
);
|
||||
final header = StreamBuilder<List<HeaderType>>(
|
||||
stream: bloc.states.headerItems.cast<List<HeaderType>>(),
|
||||
builder: (context, headerSnapshot) {
|
||||
if (headerSnapshot.connectionState == ConnectionState.waiting) {
|
||||
return const EnhancedProgressIndicator();
|
||||
} else if (headerSnapshot.hasError) {
|
||||
return EnhancedErrorWidget(error: headerSnapshot.error);
|
||||
} else if (!headerSnapshot.hasData || headerSnapshot.data!.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return widget
|
||||
.controller.headerBuilder!(() async => headerSnapshot.data!);
|
||||
}
|
||||
},
|
||||
);
|
||||
final footer = StreamBuilder<List<FooterType>>(
|
||||
stream: bloc.states.footerItems.cast<List<FooterType>>(),
|
||||
builder: (context, footerSnapshot) {
|
||||
if (footerSnapshot.connectionState == ConnectionState.waiting) {
|
||||
return const EnhancedProgressIndicator();
|
||||
} else if (footerSnapshot.hasError) {
|
||||
return EnhancedErrorWidget(error: footerSnapshot.error);
|
||||
} else if (!footerSnapshot.hasData || footerSnapshot.data!.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
} else {
|
||||
return widget
|
||||
.controller.footerBuilder!(() async => footerSnapshot.data!);
|
||||
}
|
||||
},
|
||||
);
|
||||
final body = Expanded(
|
||||
child: StreamBuilder<List<ItemType>>(
|
||||
stream: bloc.states.bodyItems.cast<List<ItemType>>(),
|
||||
builder: (context, bodySnapshot) {
|
||||
if (bodySnapshot.connectionState == ConnectionState.waiting) {
|
||||
return const EnhancedProgressIndicator();
|
||||
} else if (bodySnapshot.hasError) {
|
||||
return EnhancedErrorWidget(error: bodySnapshot.error);
|
||||
} else if (!bodySnapshot.hasData || bodySnapshot.data!.isEmpty) {
|
||||
return Center(
|
||||
child: Text(defaultMessage),
|
||||
);
|
||||
} else {
|
||||
return ListView.builder(
|
||||
itemCount: bodySnapshot.data?.length ?? 0,
|
||||
itemBuilder: (context, index) {
|
||||
return widget.controller
|
||||
.bodyBuilder(context, bodySnapshot.data![index], index);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
if (widget.controller.headerBuilder != null) header,
|
||||
body,
|
||||
if (widget.controller.footerBuilder != null) footer,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
bloc.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// [Utils] ----------------------------------------------------
|
||||
|
||||
class EnhancedListTile<T extends Widget> extends StatelessWidget {
|
||||
const EnhancedListTile(
|
||||
{required this.leading, required this.title, super.key});
|
||||
|
||||
final T leading;
|
||||
final T title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: leading,
|
||||
title: title,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EnhancedErrorWidget extends StatelessWidget {
|
||||
final Object? error;
|
||||
const EnhancedErrorWidget({required this.error, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
log('error: $error');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
error.toString(),
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EnhancedProgressIndicator extends StatelessWidget {
|
||||
const EnhancedProgressIndicator({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class NetworkError implements Exception {
|
||||
final String message;
|
||||
NetworkError(this.message);
|
||||
}
|
||||
|
||||
class ParsingError implements Exception {
|
||||
final String message;
|
||||
ParsingError(this.message);
|
||||
}
|
||||
|
||||
class AuthorizationError implements Exception {
|
||||
final String message;
|
||||
AuthorizationError(this.message);
|
||||
}
|
||||
|
||||
/// [Repositories] ----------------------------------------------------
|
||||
|
||||
class EnhancedListViewRepository<BodyType, HeaderType, FooterType, QueryType> {
|
||||
final BodyRetrievalUseCase<BodyType, QueryType?> fetchBody;
|
||||
final HeaderRetrievalUseCase<HeaderType>? fetchHeader;
|
||||
final FooterRetrievalUseCase<FooterType>? fetchFooter;
|
||||
|
||||
const EnhancedListViewRepository({
|
||||
required this.fetchBody,
|
||||
this.fetchHeader,
|
||||
this.fetchFooter,
|
||||
});
|
||||
}
|
||||
|
||||
// class HeaderRepository<HeaderType, QueryType> {}
|
||||
// class BodyRepository<BodyType, QueryType> {}
|
||||
// class FooterRepository<FooterType, QueryType> {}
|
||||
|
||||
/// [Controllers] ----------------------------------------------------
|
||||
|
||||
class EnhancedListViewController<BodyType, HeaderType, FooterType, QueryType> {
|
||||
final BodyTileBuilder<BodyType> bodyBuilder;
|
||||
final HeaderTileBuilder<HeaderType>? headerBuilder;
|
||||
final FooterTileBuilder<FooterType>? footerBuilder;
|
||||
|
||||
const EnhancedListViewController({
|
||||
required this.bodyBuilder,
|
||||
this.headerBuilder,
|
||||
this.footerBuilder,
|
||||
});
|
||||
}
|
||||
|
||||
// class HeaderController<HeaderType, QueryType> {}
|
||||
// class BodyController<BodyType, QueryType> {}
|
||||
// class FooterController<FooterType, QueryType> {}
|
||||
|
||||
/// [Blocs] ----------------------------------------------------
|
||||
|
||||
Stream<bool> get loadingState => Stream<bool>.empty();
|
||||
Stream<Exception> get errorState => Stream<Exception>.empty();
|
||||
|
||||
abstract class EnhancedListViewEvents<BodyType, HeaderType, FooterType,
|
||||
QueryType> {
|
||||
void loadBodyItems({bool reset = false, dynamic query = null});
|
||||
void loadHeaderItems();
|
||||
void loadFooterItems();
|
||||
}
|
||||
|
||||
abstract class EnhancedListViewStates<BodyType, HeaderType, FooterType,
|
||||
QueryType> {
|
||||
Stream<List<BodyType>> get bodyItems;
|
||||
Stream<List<HeaderType>> get headerItems;
|
||||
Stream<List<FooterType>> get footerItems;
|
||||
Stream<bool> get isLoading;
|
||||
Stream<String> get errors;
|
||||
}
|
||||
|
||||
class EnhancedListViewBloc<BodyType, HeaderType, FooterType, QueryType>
|
||||
extends $EnhancedListViewBloc<BodyType, HeaderType, FooterType,
|
||||
QueryType?> {
|
||||
EnhancedListViewBloc({
|
||||
required this.bodyItemsBuilder,
|
||||
required this.headerItemsBuilder,
|
||||
required this.footerItemsBuilder,
|
||||
}) {
|
||||
_$loadBodyItemsEvent
|
||||
.startWith((query: null, reset: true))
|
||||
.switchMap((item) => _fetchBodyItems(item.reset, item.query))
|
||||
.bind(_bodyItems)
|
||||
.addTo(_compositeSubscription);
|
||||
|
||||
_$loadHeaderItemsEvent
|
||||
.switchMap((_) => _fetchHeaderItems())
|
||||
.bind(_headerItems)
|
||||
.addTo(_compositeSubscription);
|
||||
|
||||
_$loadFooterItemsEvent
|
||||
.switchMap((_) => _fetchFooterItems())
|
||||
.bind(_footerItems)
|
||||
.addTo(_compositeSubscription);
|
||||
}
|
||||
|
||||
final BodyRetrievalUseCase<BodyType, QueryType?> bodyItemsBuilder;
|
||||
final HeaderRetrievalUseCase<HeaderType> headerItemsBuilder;
|
||||
final FooterRetrievalUseCase<FooterType> footerItemsBuilder;
|
||||
|
||||
final _bodyItems = BehaviorSubject<List<BodyType>>.seeded([]);
|
||||
|
||||
final _headerItems = BehaviorSubject<List<HeaderType>>.seeded([]);
|
||||
|
||||
final _footerItems = BehaviorSubject<List<FooterType>>.seeded([]);
|
||||
|
||||
final _isLoading = BehaviorSubject<bool>.seeded(false);
|
||||
final _errors = BehaviorSubject<String>();
|
||||
|
||||
Stream<List<BodyType>> _fetchBodyItems(bool reset, QueryType? query) async* {
|
||||
try {
|
||||
_isLoading.add(true);
|
||||
final items = await bodyItemsBuilder(1, 10, query);
|
||||
yield items.whereType<BodyType>().toList();
|
||||
} catch (e) {
|
||||
_errors.add(e.toString());
|
||||
} finally {
|
||||
_isLoading.add(false);
|
||||
}
|
||||
}
|
||||
|
||||
Stream<List<HeaderType>> _fetchHeaderItems() async* {
|
||||
try {
|
||||
_isLoading.add(true);
|
||||
final items = await headerItemsBuilder();
|
||||
yield items.whereType<HeaderType>().toList();
|
||||
} catch (e) {
|
||||
_errors.add(e.toString());
|
||||
} finally {
|
||||
_isLoading.add(false);
|
||||
}
|
||||
}
|
||||
|
||||
Stream<List<FooterType>> _fetchFooterItems() async* {
|
||||
try {
|
||||
_isLoading.add(true);
|
||||
final items = await footerItemsBuilder();
|
||||
yield items.whereType<FooterType>().toList();
|
||||
} catch (e) {
|
||||
_errors.add(e.toString());
|
||||
} finally {
|
||||
_isLoading.add(false);
|
||||
}
|
||||
}
|
||||
|
||||
void filterBodyItems(QueryType query) {
|
||||
_$loadBodyItemsEvent.add((query: query, reset: true));
|
||||
}
|
||||
|
||||
void filterHeaderItems(QueryType query) {
|
||||
_$loadHeaderItemsEvent.add(null);
|
||||
}
|
||||
|
||||
void filterFooterItems(QueryType query) {
|
||||
_$loadFooterItemsEvent.add(null);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_bodyItems.close();
|
||||
_headerItems.close();
|
||||
_footerItems.close();
|
||||
_isLoading.close();
|
||||
_errors.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<List<BodyType>> _mapToBodyItemsState() => _bodyItems.stream;
|
||||
@override
|
||||
Stream<String> _mapToErrorsState() => _errors.stream;
|
||||
@override
|
||||
Stream<List<FooterType>> _mapToFooterItemsState() => _footerItems.stream;
|
||||
@override
|
||||
Stream<List<HeaderType>> _mapToHeaderItemsState() => _headerItems.stream;
|
||||
@override
|
||||
Stream<bool> _mapToIsLoadingState() => _isLoading.stream;
|
||||
}
|
||||
|
||||
abstract class EnhancedListViewBlocType extends RxBlocTypeBase {
|
||||
EnhancedListViewEvents get events;
|
||||
EnhancedListViewStates get states;
|
||||
}
|
||||
|
||||
abstract class $EnhancedListViewBloc<BodyType, HeaderType, FooterType,
|
||||
QueryType> extends RxBlocBase
|
||||
implements
|
||||
EnhancedListViewEvents,
|
||||
EnhancedListViewStates,
|
||||
EnhancedListViewBlocType {
|
||||
final _compositeSubscription = CompositeSubscription();
|
||||
|
||||
/// Тhe [Subject] where events sink to by calling [loadBodyItems]
|
||||
final _$loadBodyItemsEvent = PublishSubject<({bool reset, dynamic query})>();
|
||||
|
||||
/// Тhe [Subject] where events sink to by calling [loadHeaderItems]
|
||||
final _$loadHeaderItemsEvent = PublishSubject<void>();
|
||||
|
||||
/// Тhe [Subject] where events sink to by calling [loadFooterItems]
|
||||
final _$loadFooterItemsEvent = PublishSubject<void>();
|
||||
|
||||
/// The state of [bodyItems] implemented in [_mapToBodyItemsState]
|
||||
late final Stream<List<BodyType>> _bodyItemsState = _mapToBodyItemsState();
|
||||
|
||||
/// The state of [headerItems] implemented in [_mapToHeaderItemsState]
|
||||
late final Stream<List<HeaderType>> _headerItemsState =
|
||||
_mapToHeaderItemsState();
|
||||
|
||||
/// The state of [footerItems] implemented in [_mapToFooterItemsState]
|
||||
late final Stream<List<FooterType>> _footerItemsState =
|
||||
_mapToFooterItemsState();
|
||||
|
||||
/// The state of [isLoading] implemented in [_mapToIsLoadingState]
|
||||
late final Stream<bool> _isLoadingState = _mapToIsLoadingState();
|
||||
|
||||
/// The state of [errors] implemented in [_mapToErrorsState]
|
||||
late final Stream<String> _errorsState = _mapToErrorsState();
|
||||
|
||||
@override
|
||||
void loadBodyItems({
|
||||
bool reset = false,
|
||||
dynamic query = null,
|
||||
}) =>
|
||||
_$loadBodyItemsEvent.add((
|
||||
reset: reset,
|
||||
query: query,
|
||||
));
|
||||
|
||||
@override
|
||||
void loadHeaderItems() => _$loadHeaderItemsEvent.add(null);
|
||||
|
||||
@override
|
||||
void loadFooterItems() => _$loadFooterItemsEvent.add(null);
|
||||
|
||||
@override
|
||||
Stream<List<BodyType>> get bodyItems => _bodyItemsState;
|
||||
|
||||
@override
|
||||
Stream<List<HeaderType>> get headerItems => _headerItemsState;
|
||||
|
||||
@override
|
||||
Stream<List<FooterType>> get footerItems => _footerItemsState;
|
||||
|
||||
@override
|
||||
Stream<bool> get isLoading => _isLoadingState;
|
||||
|
||||
@override
|
||||
Stream<String> get errors => _errorsState;
|
||||
|
||||
Stream<List<BodyType>> _mapToBodyItemsState();
|
||||
|
||||
Stream<List<HeaderType>> _mapToHeaderItemsState();
|
||||
|
||||
Stream<List<FooterType>> _mapToFooterItemsState();
|
||||
|
||||
Stream<bool> _mapToIsLoadingState();
|
||||
|
||||
Stream<String> _mapToErrorsState();
|
||||
|
||||
@override
|
||||
EnhancedListViewEvents get events => this;
|
||||
|
||||
@override
|
||||
EnhancedListViewStates get states => this;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_$loadBodyItemsEvent.close();
|
||||
_$loadHeaderItemsEvent.close();
|
||||
_$loadFooterItemsEvent.close();
|
||||
_compositeSubscription.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
typedef _LoadBodyItemsEventArgs = ({bool reset, dynamic query});
|
|
@ -0,0 +1,81 @@
|
|||
// class EnhancedSearchView<QueryType> extends StatelessWidget {
|
||||
// const EnhancedSearchView({
|
||||
// super.key,
|
||||
// required this.filter,
|
||||
// required this.cast,
|
||||
// });
|
||||
|
||||
// final void Function(QueryType query) filter;
|
||||
// final QueryType Function(String query) cast;
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// final theme = FlutterFlowTheme.of(context);
|
||||
// final locale = FFLocalizations.of(context);
|
||||
// TextEditingController controller = TextEditingController();
|
||||
// return TextFormField(
|
||||
// controller: controller,
|
||||
// onChanged: (value) => EasyDebounce.debounce(
|
||||
// '_model.keyTextFieldTextController',
|
||||
// const Duration(milliseconds: 500),
|
||||
// () => filter.call(cast.call(value)),
|
||||
// ),
|
||||
// cursorColor: theme.primaryText,
|
||||
// showCursor: false,
|
||||
// cursorWidth: 2.0,
|
||||
// cursorRadius: Radius.circular(100),
|
||||
// style: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// fontSize: 16.0,
|
||||
// decorationColor: Colors.amber,
|
||||
// ),
|
||||
// keyboardType: TextInputType.text,
|
||||
// textInputAction: TextInputAction.search,
|
||||
// autocorrect: true,
|
||||
// textCapitalization: TextCapitalization.sentences,
|
||||
// decoration: InputDecoration(
|
||||
// prefixIcon: Icon(Icons.search, color: theme.primary),
|
||||
// labelText: locale.getVariableText(
|
||||
// ptText: 'Pesquisar',
|
||||
// enText: 'Search',
|
||||
// ),
|
||||
// labelStyle: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// fontSize: 16.0,
|
||||
// ),
|
||||
// hintText: locale.getVariableText(
|
||||
// ptText: 'Digite sua pesquisa',
|
||||
// enText: 'Enter your search',
|
||||
// ),
|
||||
// hintStyle: TextStyle(
|
||||
// color: theme.accent2,
|
||||
// fontSize: 14.0,
|
||||
// ),
|
||||
// filled: true,
|
||||
// fillColor: Colors.transparent,
|
||||
// helperStyle: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// decorationColor: theme.primaryText,
|
||||
// ),
|
||||
// focusColor: theme.primaryText,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
// enabledBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// focusedBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// errorBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// focusedErrorBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText, width: 2.0),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1 @@
|
|||
abstract class Entity<T> {}
|
|
@ -0,0 +1,322 @@
|
|||
// typedef SearchKey = GlobalKey<EnhancedRemoteListViewState>;
|
||||
|
||||
// typedef Query<X extends Archive> = X?;
|
||||
|
||||
// /// -----------------------------------------------
|
||||
// /// [EnhancedListView]
|
||||
// /// -----------------------------------------------
|
||||
|
||||
// abstract interface class EnhancedListView<T> extends StatefulWidget {
|
||||
// const EnhancedListView({super.key});
|
||||
// }
|
||||
|
||||
// abstract interface class EnhancedListViewState<T>
|
||||
// extends State<EnhancedListView> {}
|
||||
|
||||
// /// -----------------------------------------------
|
||||
// /// [EnhancedLocalListView]
|
||||
// /// -----------------------------------------------
|
||||
|
||||
// class EnhancedLocalListView<T> extends EnhancedListView<T> {
|
||||
// final List<T> list;
|
||||
// final Widget Function(T) itemBuilder;
|
||||
// final bool Function(T, String) filter;
|
||||
// final Widget header;
|
||||
// final List<T> Function(String)? onSearch;
|
||||
|
||||
// EnhancedLocalListView({
|
||||
// Key? key,
|
||||
// required this.list,
|
||||
// required this.itemBuilder,
|
||||
// required this.filter,
|
||||
// List<T> Function(String)? onSearch,
|
||||
// Widget? header,
|
||||
// }) : header = header ?? const SizedBox.shrink(),
|
||||
// onSearch = onSearch ??
|
||||
// ((String query) =>
|
||||
// list.where((documents) => filter(documents, query)).toList()),
|
||||
// super(key: key);
|
||||
|
||||
// // return documents.where((documents) => filter(documents, query)).toList();
|
||||
|
||||
// @override
|
||||
// EnhancedLocalListViewState<T> createState() =>
|
||||
// EnhancedLocalListViewState<T>();
|
||||
// }
|
||||
|
||||
// class EnhancedLocalListViewState<T> extends State<EnhancedLocalListView<T>> {
|
||||
// TextEditingController editingController = TextEditingController();
|
||||
// late List<T> filteredItems;
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// filteredItems = widget.list;
|
||||
// super.initState();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// void filter(value) {
|
||||
// safeSetState(() {
|
||||
// filteredItems = widget.onSearch!(value);
|
||||
// });
|
||||
// }
|
||||
|
||||
// return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: <Widget>[
|
||||
// Expanded(
|
||||
// child: ListView.builder(
|
||||
// shrinkWrap: true,
|
||||
// itemCount: filteredItems.length + 1,
|
||||
// itemBuilder: (context, index) {
|
||||
// if (index == 0) return widget.header;
|
||||
// return widget.itemBuilder(filteredItems[index - 1]);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(30.0),
|
||||
// child: TextFormField(
|
||||
// controller: editingController,
|
||||
// onChanged: filter,
|
||||
// cursorColor: Colors.black,
|
||||
// cursorWidth: 2.0,
|
||||
// cursorRadius: Radius.circular(2.0),
|
||||
// style: TextStyle(
|
||||
// color: Colors.black,
|
||||
// fontSize: 16.0,
|
||||
// ),
|
||||
// keyboardType: TextInputType.text,
|
||||
// textInputAction: TextInputAction.search,
|
||||
// autocorrect: true,
|
||||
// textCapitalization: TextCapitalization.sentences,
|
||||
// decoration: InputDecoration(
|
||||
// prefixIcon: Icon(Icons.search, color: Colors.black),
|
||||
// labelText: 'Pesquisar',
|
||||
// labelStyle: TextStyle(
|
||||
// color: Colors.black,
|
||||
// fontSize: 16.0,
|
||||
// ),
|
||||
// hintText: 'Digite sua pesquisa',
|
||||
// hintStyle: TextStyle(
|
||||
// color: Colors.grey,
|
||||
// fontSize: 14.0,
|
||||
// ),
|
||||
// filled: true,
|
||||
// fillColor: Colors.white,
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
// enabledBorder: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: Colors.black),
|
||||
// ),
|
||||
// focusedBorder: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: Colors.blue),
|
||||
// ),
|
||||
// errorBorder: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: Colors.red),
|
||||
// ),
|
||||
// focusedErrorBorder: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: Colors.red, width: 2.0),
|
||||
// ),
|
||||
// ),
|
||||
// )),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// -----------------------------------------------
|
||||
// /// [EnhancedRemoteListView]
|
||||
// /// -----------------------------------------------
|
||||
|
||||
// // ignore: must_be_immutable
|
||||
// class EnhancedRemoteListView<T, Y> extends EnhancedListView<T> {
|
||||
// final Widget Function(BuildContext, T, int) bodyBuilder;
|
||||
// final Future<List<Y?>> Function() headerItems;
|
||||
// Widget Function<T>(Future<List<T?>> Function() gen) headerBuilder;
|
||||
// final PagingController<int, T> pagingController;
|
||||
// final Future<(bool, List<T?>?)> Function(int pageKey, Query query)
|
||||
// dataProvider;
|
||||
|
||||
// final void Function(Object, StackTrace) onFetchError;
|
||||
|
||||
// EnhancedRemoteListView({
|
||||
// Key? key,
|
||||
// // required this.fetchItems,
|
||||
// required this.bodyBuilder,
|
||||
// required this.headerItems,
|
||||
// required this.headerBuilder,
|
||||
// required this.pagingController,
|
||||
// required this.dataProvider,
|
||||
// required this.onFetchError,
|
||||
// }) : super(key: key);
|
||||
|
||||
// @override
|
||||
// EnhancedRemoteListViewState<T, Y> createState() =>
|
||||
// EnhancedRemoteListViewState<T, Y>();
|
||||
// }
|
||||
|
||||
// class EnhancedRemoteListViewState<T, Y>
|
||||
// extends State<EnhancedRemoteListView<T, Y>> with Pageable {
|
||||
// TextEditingController editingController = TextEditingController();
|
||||
// bool isLoading = false;
|
||||
// Query query = Document.fromDesc('');
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// widget.pagingController.addPageRequestListener(
|
||||
// (page) => fetchPage(
|
||||
// dataProvider: () async => await widget.dataProvider(page, query),
|
||||
// onDataUnavailable: () => showNoMoreDataSnackBar(context),
|
||||
// onDataAvailable: (data) =>
|
||||
// widget.pagingController.appendLastPage(data),
|
||||
// onFetchError: (e, s) => widget.onFetchError),
|
||||
// );
|
||||
// widget.pagingController.addStatusListener(_showError);
|
||||
|
||||
// super.initState();
|
||||
// }
|
||||
|
||||
// Future<void> _showError(PagingStatus status) async {
|
||||
// if (status == PagingStatus.subsequentPageError) {
|
||||
// final message = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Something went wrong while fetching a new page.',
|
||||
// ptText: 'Algo deu errado ao buscar uma nova página.',
|
||||
// );
|
||||
// final retry = FFLocalizations.of(context).getVariableText(
|
||||
// enText: 'Retry',
|
||||
// ptText: 'Recarregar',
|
||||
// );
|
||||
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text(message),
|
||||
// action: SnackBarAction(
|
||||
// label: retry,
|
||||
// onPressed: () => widget.pagingController.retryLastFailedRequest(),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// void filter(Query data) async {
|
||||
// if (data is Category) {
|
||||
// safeSetState(() => query = Category(
|
||||
// id: data.id,
|
||||
// color: data.color,
|
||||
// title: data.title,
|
||||
// ));
|
||||
// widget.pagingController.refresh();
|
||||
// } else if (data is Document) {
|
||||
|
||||
// safeSetState(() => query = data);
|
||||
// widget.pagingController.refresh();
|
||||
// } else {
|
||||
// safeSetState(() {
|
||||
// query = Document.fromDesc('');
|
||||
// });
|
||||
// widget.pagingController.refresh();
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// final noDataFound = FFLocalizations.of(context).getVariableText(
|
||||
// ptText: "Nenhum item encontrado!",
|
||||
// enText: "No item found",
|
||||
// );
|
||||
// final theme = FlutterFlowTheme.of(context);
|
||||
// final locale = FFLocalizations.of(context);
|
||||
|
||||
// return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: <Widget>[
|
||||
// buildPaginatedListView<int, T, Y>(
|
||||
// noDataFound,
|
||||
// widget.pagingController,
|
||||
// widget.headerItems,
|
||||
// widget.headerBuilder,
|
||||
// widget.bodyBuilder,
|
||||
// ),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(8.0),
|
||||
// child: TextFormField(
|
||||
// controller: editingController,
|
||||
// onChanged: (value) => EasyDebounce.debounce(
|
||||
// '_model.keyTextFieldTextController',
|
||||
// const Duration(milliseconds: 500),
|
||||
// () => filter(Document.fromDesc(value)),
|
||||
// ),
|
||||
// cursorColor: theme.primaryText,
|
||||
// showCursor: false,
|
||||
// cursorWidth: 2.0,
|
||||
// cursorRadius: Radius.circular(100),
|
||||
// style: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// fontSize: 16.0,
|
||||
// decorationColor: Colors.amber,
|
||||
// ),
|
||||
// keyboardType: TextInputType.text,
|
||||
// textInputAction: TextInputAction.search,
|
||||
// autocorrect: true,
|
||||
// textCapitalization: TextCapitalization.sentences,
|
||||
// decoration: InputDecoration(
|
||||
// prefixIcon: Icon(Icons.search, color: theme.primary),
|
||||
// labelText: locale.getVariableText(
|
||||
// ptText: 'Pesquisar',
|
||||
// enText: 'Search',
|
||||
// ),
|
||||
// labelStyle: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// fontSize: 16.0,
|
||||
// ),
|
||||
// hintText: locale.getVariableText(
|
||||
// ptText: 'Digite sua pesquisa',
|
||||
// enText: 'Enter your search',
|
||||
// ),
|
||||
// hintStyle: TextStyle(
|
||||
// color: theme.accent2,
|
||||
// fontSize: 14.0,
|
||||
// ),
|
||||
// filled: true,
|
||||
// fillColor: Colors.transparent,
|
||||
// helperStyle: TextStyle(
|
||||
// color: theme.primaryText,
|
||||
// decorationColor: theme.primaryText,
|
||||
// ),
|
||||
// focusColor: theme.primaryText,
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
// enabledBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// focusedBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// errorBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText),
|
||||
// ),
|
||||
// focusedErrorBorder: UnderlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
// borderSide: BorderSide(color: theme.primaryText, width: 2.0),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class ModelWidget extends Widget {
|
||||
const ModelWidget({super.key});
|
||||
|
||||
@override
|
||||
Element createElement() {
|
||||
// TODO: implement createElement
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hub/shared/mixins/template_mixin.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
|
||||
/// [PageWidget]
|
||||
|
||||
abstract class PageWidget<T> extends Widget {
|
||||
const PageWidget({super.key});
|
||||
}
|
||||
|
||||
abstract class ModelPage<T> extends ModelWidget implements PageWidget<T> {
|
||||
const ModelPage({super.key});
|
||||
}
|
||||
|
||||
abstract class StatelessPage<T> extends StatelessWidget
|
||||
with Template
|
||||
implements PageWidget<T> {
|
||||
const StatelessPage({super.key});
|
||||
}
|
||||
|
||||
abstract class StatefulPage<T> extends StatefulWidget implements PageWidget<T> {
|
||||
const StatefulPage({super.key});
|
||||
}
|
||||
|
||||
abstract class PageState<T extends StatefulPage> extends State<T>
|
||||
with Template {}
|
|
@ -0,0 +1,183 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
// Removed unnecessary import
|
||||
import 'package:hub/flutter_flow/index.dart';
|
||||
import 'package:hub/shared/utils/dialog_util.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:pdfx/pdfx.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
typedef ReadViewController = PdfController;
|
||||
typedef DocumentType = PdfDocument;
|
||||
|
||||
abstract interface class Viewer extends StatelessComponent {
|
||||
final String src;
|
||||
|
||||
const Viewer({
|
||||
super.key,
|
||||
required this.src,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return buildViewer(context);
|
||||
}
|
||||
|
||||
Widget buildViewer(BuildContext context);
|
||||
}
|
||||
|
||||
class ReadView extends StatefulWidget {
|
||||
final String url;
|
||||
final String title;
|
||||
final VoidCallback onError;
|
||||
|
||||
const ReadView({
|
||||
super.key,
|
||||
required this.onError,
|
||||
required this.url,
|
||||
required this.title,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ReadView> createState() => ReadViewState();
|
||||
}
|
||||
|
||||
class ReadViewState extends State<ReadView> {
|
||||
Future<ReadViewController> _initializePdf() async {
|
||||
try {
|
||||
final file = await downloadPdf(widget.url);
|
||||
final Future<DocumentType> document = DocumentType.openFile(file.path);
|
||||
return ReadViewController(document: document);
|
||||
} catch (e) {
|
||||
final message = FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Erro ao baixar o PDF',
|
||||
enText: 'Error downloading PDF',
|
||||
);
|
||||
|
||||
return Future.error(message);
|
||||
}
|
||||
}
|
||||
|
||||
Future<File> downloadPdf(String url) async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(url));
|
||||
if (response.statusCode == 200) {
|
||||
final bytes = response.bodyBytes;
|
||||
final dir = await getTemporaryDirectory();
|
||||
final file = File('${dir.path}/downloaded.pdf');
|
||||
await file.writeAsBytes(bytes);
|
||||
return file;
|
||||
} else {
|
||||
throw Exception('Falha ao baixar o PDF');
|
||||
}
|
||||
} catch (e) {
|
||||
final message = FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Erro ao baixar o PDF',
|
||||
enText: 'Error downloading PDF',
|
||||
);
|
||||
await throwError(message, e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> throwError(String message, dynamic error) async {
|
||||
log('$message: $error');
|
||||
await DialogUtil.error(context, message)
|
||||
.whenComplete(() => widget.onError());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
_buildPDFViewer(context),
|
||||
buildShareButton(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Positioned buildShareButton(BuildContext context) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
return Positioned(
|
||||
bottom: 10,
|
||||
right: 10,
|
||||
child: IconButton(
|
||||
icon: Icon(
|
||||
Icons.share,
|
||||
color: theme.primaryText,
|
||||
),
|
||||
color: theme.primaryText,
|
||||
onPressed: onShare,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onShare() async {
|
||||
try {
|
||||
final Uri uri = Uri.parse(widget.url);
|
||||
final response = await http.get(uri);
|
||||
if (response.statusCode == 200) {
|
||||
final XFile xfile = XFile.fromData(response.bodyBytes,
|
||||
name: '${widget.title}.pdf', mimeType: 'application/pdf');
|
||||
await Share.shareXFiles([xfile],
|
||||
text: 'Confira este PDF!',
|
||||
fileNameOverrides: ['${widget.title}.pdf']);
|
||||
} else {
|
||||
throw Exception(
|
||||
'Erro ao compartilhar o arquivo: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
final message = FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Erro ao compartilhar o arquivo',
|
||||
enText: 'Error sharing file',
|
||||
);
|
||||
await throwError(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildLoadingIndicator(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
FlutterFlowTheme.of(context).primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPDFViewer(BuildContext context) => Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: FutureBuilder<ReadViewController>(
|
||||
future: _initializePdf(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) return buildLoadingIndicator(context);
|
||||
if (snapshot.error != null) {
|
||||
return buildLoadingIndicator(context);
|
||||
}
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return buildLoadingIndicator(context);
|
||||
}
|
||||
|
||||
return PdfView(
|
||||
controller: snapshot.data!,
|
||||
renderer: (PdfPage page) => page.render(
|
||||
width: page.width * 2,
|
||||
height: page.height * 2,
|
||||
cropRect: Rect.fromLTWH(
|
||||
10.0, 10.0, page.width * 2, page.height * 2),
|
||||
forPrint: false,
|
||||
quality: 100,
|
||||
format: PdfPageImageFormat.jpeg,
|
||||
backgroundColor: '#ffffff',
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:hub/shared/mixins/template_mixin.dart';
|
||||
import 'package:hub/shared/widgets.dart';
|
||||
|
||||
abstract class ScreenWidget<T> extends Widget {
|
||||
const ScreenWidget({super.key});
|
||||
}
|
||||
|
||||
abstract class ModelScreen<T> extends ModelWidget implements ScreenWidget<T> {
|
||||
const ModelScreen({super.key});
|
||||
}
|
||||
|
||||
abstract class StatelessScreen<T> extends StatelessWidget
|
||||
with Template
|
||||
implements ScreenWidget<T> {
|
||||
const StatelessScreen({super.key});
|
||||
}
|
||||
|
||||
abstract class StatefulScreen<T> extends StatefulWidget
|
||||
implements ScreenWidget<T> {
|
||||
const StatefulScreen({super.key});
|
||||
}
|
||||
|
||||
abstract class ScreenState<T extends StatefulScreen> extends State<T>
|
||||
with Template {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue