This commit is contained in:
jantunesmesias 2024-08-15 15:07:19 -03:00
parent 9ffb3270e6
commit 460ad3bbbd
47 changed files with 2429 additions and 14725 deletions

View File

@ -112,23 +112,23 @@ Future singInLoginAction(
await Future.wait([
Future(() async {
FFAppState().email = emailAdress!;
AppState().email = emailAdress!;
}),
Future(() async {
FFAppState().passwd = password!;
AppState().passwd = password!;
}),
]);
if ((FFAppState().email != '') && (FFAppState().passwd != '')) {
if ((AppState().email != '') && (AppState().passwd != '')) {
devUUID = await getDevUUID();
FFAppState().devUUID = devUUID!;
AppState().devUUID = devUUID!;
loginCall = await PhpGroup.loginCall.call(
email: FFAppState().email,
password: FFAppState().passwd,
uuid: FFAppState().devUUID,
type: FFAppState().device,
email: AppState().email,
password: AppState().passwd,
uuid: AppState().devUUID,
type: AppState().device,
description: randomString(
10,
10,
@ -139,30 +139,30 @@ Future singInLoginAction(
);
if (PhpGroup.loginCall.error((loginCall.jsonBody ?? '')) == false) {
FFAppState().userUUID = PhpGroup.loginCall.userUUID(
AppState().userUUID = PhpGroup.loginCall.userUUID(
(loginCall.jsonBody ?? ''),
)!;
FFAppState().createdAt = dateTimeFormat(
AppState().createdAt = dateTimeFormat(
'd/M/y H:mm:ss',
getCurrentTimestamp,
locale: FFLocalizations.of(context).languageCode,
);
FFAppState().updatedAt = '00/00/0000 00:00:00';
AppState().updatedAt = '00/00/0000 00:00:00';
FFAppState().status =
AppState().status =
PhpGroup.loginCall.userStatus((loginCall.jsonBody ?? ''))!;
FFAppState().userDevUUID =
AppState().userDevUUID =
PhpGroup.loginCall.userDeviceId((loginCall.jsonBody ?? ''))!;
FFAppState().name =
AppState().name =
PhpGroup.loginCall.userName((loginCall.jsonBody ?? ''))!;
FFAppState().serialNumber = await getSerialNumber() ?? '';
AppState().serialNumber = await getSerialNumber() ?? '';
FFAppState().isLogged = true;
AppState().isLogged = true;
await toggleHomePage(context);
} else {
@ -173,13 +173,13 @@ Future singInLoginAction(
PhpGroup.loginCall.msg((loginCall?.jsonBody ?? '')).toString());
}
FFAppState().deleteEmail();
FFAppState().email = '';
AppState().deleteEmail();
AppState().email = '';
FFAppState().deletePasswd();
FFAppState().passwd = '';
AppState().deletePasswd();
AppState().passwd = '';
FFAppState().update(() {});
AppState().update(() {});
}
}
@ -271,15 +271,15 @@ Future forgotPasswdAction(
}
Future cachingLoginActionApp(BuildContext context) async {
if (FFAppState().isLogged == true) {
if (AppState().isLogged == true) {
context.pushNamed('homePage');
} else {
if (isAndroid == true) {
FFAppState().device = 'Android';
AppState().device = 'Android';
} else if (isiOS == true) {
FFAppState().device = 'iOS';
AppState().device = 'iOS';
} else {
FFAppState().device = 'Web';
AppState().device = 'Web';
}
}
}
@ -328,9 +328,9 @@ Future<bool> visitCancelAction(BuildContext context,
ApiCallResponse? apiCallResponse;
apiCallResponse = await PhpGroup.cancelaVisita.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliID: AppState().cliUUID,
atividade: 'cancelaVisita',
idDestino: idDestino,
idVisita: idVisita,
@ -381,8 +381,8 @@ Future<bool> checkLocals({
}) async {
// A chamada para a API permanece a mesma, assumindo que é necessária sempre.
final response = await PhpGroup.getLocalsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
);
// Verificação rápida de erro para evitar processamento desnecessário.
@ -391,7 +391,7 @@ Future<bool> checkLocals({
}
// Uso eficiente de coleções para verificar a condição desejada.
final String uuid = cliUUID ?? FFAppState().cliUUID;
final String uuid = cliUUID ?? AppState().cliUUID;
final bool itemFound = response.jsonBody['locais'].any(
(local) => local['CLI_ID'] == uuid && local['CLU_STATUS'] == "A",
);
@ -427,9 +427,9 @@ Future answersRequest(BuildContext context, String? ref, String? task,
ApiCallResponse? respondeSolicitacaoCall;
respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliUUID: AppState().cliUUID,
atividade: 'respondeSolicitacao',
referencia: ref,
tarefa: task,

View File

@ -1,12 +1,12 @@
// import 'dart:ffi';
import 'package:csv/csv.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:csv/csv.dart';
import 'package:local_auth/local_auth.dart';
import 'package:synchronized/synchronized.dart';
class FFAppState extends ChangeNotifier {
class AppState extends ChangeNotifier {
// Adiciona a variável para controle de autenticação biométrica
bool _isBiometricAuthenticated = false;
bool get isBiometricAuthenticated => _isBiometricAuthenticated;
@ -57,16 +57,16 @@ class FFAppState extends ChangeNotifier {
// Limpar a informação salva, se necessário
}
static FFAppState _instance = FFAppState._internal();
static AppState _instance = AppState._internal();
factory FFAppState() {
factory AppState() {
return _instance;
}
FFAppState._internal();
AppState._internal();
static void reset() {
_instance = FFAppState._internal();
_instance = AppState._internal();
}
Future initializePersistedState() async {
@ -150,6 +150,9 @@ class FFAppState extends ChangeNotifier {
_fingerprintPass =
await secureStorage.getString('fingerprintPass') ?? _fingerprintPass;
});
await _safeInitAsync(() async {
_context = await secureStorage.getObject('ff_context') ?? _context;
});
}
void update(VoidCallback callback) {
@ -159,6 +162,17 @@ class FFAppState extends ChangeNotifier {
late FlutterSecureStorage secureStorage;
BuildContext? _context;
BuildContext? get context => _context;
set context(BuildContext? value) {
_context = value;
secureStorage.setString('ff_context', value.toString());
}
void deleteContext() {
secureStorage.delete(key: 'ff_context');
}
bool _panicOPT = false;
bool get panic => _panicOPT;
set panic(bool value) {
@ -481,6 +495,14 @@ extension FlutterSecureStorageExtensions on FlutterSecureStorage {
Future<void> setDouble(String key, double value) async =>
await writeSync(key: key, value: value.toString());
Future<BuildContext?> getObject(String key) async {
final value = await read(key: key);
if (value == null || value.isEmpty) {
return null;
}
return value as BuildContext;
}
Future<List<String>?> getStringList(String key) async =>
await read(key: key).then((result) {
if (result == null || result.isEmpty) {

View File

@ -0,0 +1,351 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'package:hub/backend/notification/message.dart';
import 'package:hub/backend/notification/message_list.dart';
import 'package:hub/backend/notification/permissions.dart';
import 'package:hub/backend/notification/token_monitor.dart';
import 'package:hub/firebase_options.dart';
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
showFlutterNotification(message);
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
print('Handling a background message ${message.messageId}');
}
/// Create a [AndroidNotificationChannel] for heads up notifications
late AndroidNotificationChannel channel;
bool isFlutterLocalNotificationsInitialized = false;
Future<void> setupFlutterNotifications() async {
if (isFlutterLocalNotificationsInitialized) {
return;
}
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.high,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
isFlutterLocalNotificationsInitialized = true;
}
void showFlutterNotification(RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'launch_background',
),
),
);
}
}
/// Initialize the [FlutterLocalNotificationsPlugin] package.
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// Set the background messaging handler early on, as a named top-level function
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
await setupFlutterNotifications();
}
runApp(MessagingExampleApp());
}
/// Entry point for the example application.
class MessagingExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Messaging Example App',
theme: ThemeData.dark(),
routes: {
'/': (context) => Application(),
'/message': (context) => MessageView(),
},
);
}
}
// Crude counter to make messages unique
int _messageCount = 0;
/// The API endpoint here accepts a raw FCM payload for demonstration purposes.
String constructFCMPayload(String? token) {
_messageCount++;
return jsonEncode({
'token': token,
'data': {
'via': 'FlutterFire Cloud Messaging!!!',
'count': _messageCount.toString(),
},
'notification': {
'title': 'Hello FlutterFire!',
'body': 'This notification (#$_messageCount) was created via FCM!',
},
});
}
/// Renders the example application.
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
String? _token;
String? initialMessage;
bool _resolved = false;
@override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then(
(value) => setState(
() {
_resolved = true;
initialMessage = value?.data.toString();
},
),
);
FirebaseMessaging.onMessage.listen(showFlutterNotification);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
});
}
Future<void> sendPushMessage() async {
if (_token == null) {
print('Unable to send FCM message, no token exists.');
return;
}
try {
await http.post(
Uri.parse('https://api.rnfirebase.io/messaging/send'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: constructFCMPayload(_token),
);
print('FCM request for device sent!');
} catch (e) {
print(e);
}
}
Future<void> onActionSelected(String value) async {
switch (value) {
case 'subscribe':
{
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test".',
);
await FirebaseMessaging.instance.subscribeToTopic('fcm_test');
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test" successful.',
);
}
break;
case 'unsubscribe':
{
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test".',
);
await FirebaseMessaging.instance.unsubscribeFromTopic('fcm_test');
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test" successful.',
);
}
break;
case 'get_apns_token':
{
if (defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS) {
print('FlutterFire Messaging Example: Getting APNs token...');
String? token = await FirebaseMessaging.instance.getAPNSToken();
print('FlutterFire Messaging Example: Got APNs token: $token');
} else {
print(
'FlutterFire Messaging Example: Getting an APNs token is only supported on iOS and macOS platforms.',
);
}
}
break;
default:
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cloud Messaging'),
actions: <Widget>[
PopupMenuButton(
onSelected: onActionSelected,
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem(
value: 'subscribe',
child: Text('Subscribe to topic'),
),
const PopupMenuItem(
value: 'unsubscribe',
child: Text('Unsubscribe to topic'),
),
const PopupMenuItem(
value: 'get_apns_token',
child: Text('Get APNs token (Apple only)'),
),
];
},
),
],
),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: sendPushMessage,
backgroundColor: Colors.white,
child: const Icon(Icons.send),
),
),
body: SingleChildScrollView(
child: Column(
children: [
MetaCard('Permissions', Permissions()),
MetaCard(
'Initial Message',
Column(
children: [
Text(_resolved ? 'Resolved' : 'Resolving'),
Text(initialMessage ?? 'None'),
],
),
),
MetaCard(
'FCM Token',
TokenMonitor((token) {
_token = token;
return token == null
? const CircularProgressIndicator()
: SelectableText(
token,
style: const TextStyle(fontSize: 12),
);
}),
),
ElevatedButton(
onPressed: () {
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
}
});
},
child: const Text('getInitialMessage()'),
),
MetaCard('Message Stream', MessageList()),
],
),
),
);
}
}
/// UI Widget for displaying metadata.
class MetaCard extends StatelessWidget {
final String _title;
final Widget _children;
// ignore: public_member_api_docs
MetaCard(this._title, this._children);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.only(left: 8, right: 8, top: 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 16),
child: Text(_title, style: const TextStyle(fontSize: 18)),
),
_children,
],
),
),
),
);
}
}

View File

@ -0,0 +1,101 @@
// Copyright 2022, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyB7wZb2tO1-Fs6GbDADUSTs2Qs3w08Hovw',
appId: '1:406099696497:web:87e25e51afe982cd3574d0',
messagingSenderId: '406099696497',
projectId: 'flutterfire-e2e-tests',
authDomain: 'flutterfire-e2e-tests.firebaseapp.com',
databaseURL:
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
storageBucket: 'flutterfire-e2e-tests.appspot.com',
measurementId: 'G-JN95N1JV2E',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw',
appId: '1:406099696497:android:74ebb073d7727cd43574d0',
messagingSenderId: '406099696497',
projectId: 'flutterfire-e2e-tests',
databaseURL:
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
storageBucket: 'flutterfire-e2e-tests.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
appId: '1:406099696497:ios:1b423b89c63b82053574d0',
messagingSenderId: '406099696497',
projectId: 'flutterfire-e2e-tests',
databaseURL:
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
storageBucket: 'flutterfire-e2e-tests.appspot.com',
androidClientId:
'406099696497-17qn06u8a0dc717u8ul7s49ampk13lul.apps.googleusercontent.com',
iosClientId:
'406099696497-irb7edfevfkhi6t5s9kbuq1mt1og95rg.apps.googleusercontent.com',
iosBundleId: 'io.flutter.plugins.firebase.messaging',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
appId: '1:406099696497:ios:1b423b89c63b82053574d0',
messagingSenderId: '406099696497',
projectId: 'flutterfire-e2e-tests',
databaseURL:
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
storageBucket: 'flutterfire-e2e-tests.appspot.com',
androidClientId:
'406099696497-17qn06u8a0dc717u8ul7s49ampk13lul.apps.googleusercontent.com',
iosClientId:
'406099696497-irb7edfevfkhi6t5s9kbuq1mt1og95rg.apps.googleusercontent.com',
iosBundleId: 'io.flutter.plugins.firebase.messaging',
);
}

View File

@ -0,0 +1,163 @@
// Copyright 2022, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// ignore_for_file: require_trailing_commas
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
/// Message route arguments.
class MessageArguments {
/// The RemoteMessage
final RemoteMessage message;
/// Whether this message caused the application to open.
final bool openedApplication;
// ignore: public_member_api_docs
MessageArguments(this.message, this.openedApplication);
}
/// Displays information about a [RemoteMessage].
class MessageView extends StatelessWidget {
/// A single data row.
Widget row(String title, String? value) {
return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, top: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('$title: '),
Expanded(child: Text(value ?? 'N/A')),
],
),
);
}
@override
Widget build(BuildContext context) {
final MessageArguments args =
ModalRoute.of(context)!.settings.arguments! as MessageArguments;
RemoteMessage message = args.message;
RemoteNotification? notification = message.notification;
return Scaffold(
appBar: AppBar(
title: Text(message.messageId ?? 'N/A'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: [
row('Triggered application open',
args.openedApplication.toString()),
row('Message ID', message.messageId),
row('Sender ID', message.senderId),
row('Category', message.category),
row('Collapse Key', message.collapseKey),
row('Content Available', message.contentAvailable.toString()),
row('Data', message.data.toString()),
row('From', message.from),
row('Message ID', message.messageId),
row('Sent Time', message.sentTime?.toString()),
row('Thread ID', message.threadId),
row('Time to Live (TTL)', message.ttl?.toString()),
if (notification != null) ...[
Padding(
padding: const EdgeInsets.only(top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Remote Notification',
style: TextStyle(fontSize: 18),
),
row(
'Title',
notification.title,
),
row(
'Body',
notification.body,
),
if (notification.android != null) ...[
const SizedBox(height: 16),
const Text(
'Android Properties',
style: TextStyle(fontSize: 18),
),
row(
'Channel ID',
notification.android!.channelId,
),
row(
'Click Action',
notification.android!.clickAction,
),
row(
'Color',
notification.android!.color,
),
row(
'Count',
notification.android!.count?.toString(),
),
row(
'Image URL',
notification.android!.imageUrl,
),
row(
'Link',
notification.android!.link,
),
row(
'Priority',
notification.android!.priority.toString(),
),
row(
'Small Icon',
notification.android!.smallIcon,
),
row(
'Sound',
notification.android!.sound,
),
row(
'Ticker',
notification.android!.ticker,
),
row(
'Visibility',
notification.android!.visibility.toString(),
),
],
if (notification.apple != null) ...[
const Text(
'Apple Properties',
style: TextStyle(fontSize: 18),
),
row(
'Subtitle',
notification.apple!.subtitle,
),
row(
'Badge',
notification.apple!.badge,
),
row(
'Sound',
notification.apple!.sound?.name,
),
]
],
),
)
]
],
),
)),
);
}
}

View File

@ -0,0 +1,53 @@
// Copyright 2022, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// ignore_for_file: require_trailing_commas
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'message.dart';
/// Listens for incoming foreground messages and displays them in a list.
class MessageList extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MessageList();
}
class _MessageList extends State<MessageList> {
List<RemoteMessage> _messages = [];
@override
void initState() {
super.initState();
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
setState(() {
_messages = [..._messages, message];
});
});
}
@override
Widget build(BuildContext context) {
if (_messages.isEmpty) {
return const Text('No messages received');
}
return ListView.builder(
shrinkWrap: true,
itemCount: _messages.length,
itemBuilder: (context, index) {
RemoteMessage message = _messages[index];
return ListTile(
title: Text(
message.messageId ?? 'no RemoteMessage.messageId available'),
subtitle:
Text(message.sentTime?.toString() ?? DateTime.now().toString()),
onTap: () => Navigator.pushNamed(context, '/message',
arguments: MessageArguments(message, false)),
);
});
}
}

View File

@ -0,0 +1,383 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'package:hub/backend/notification/message.dart';
import 'package:hub/backend/notification/message_list.dart';
import 'package:hub/backend/notification/permissions.dart';
import 'package:hub/backend/notification/token_monitor.dart';
import 'package:hub/firebase_options.dart';
// import 'firebase_options.dart';
// import 'message.dart';
// import 'message_list.dart';
// import 'permissions.dart';
// import 'token_monitor.dart';
/// Working example of FirebaseMessaging.
/// Please use this in order to verify messages are working in foreground, background & terminated state.
/// Setup your app following this guide:
/// https://firebase.google.com/docs/cloud-messaging/flutter/client#platform-specific_setup_and_requirements):
///
/// Once you've completed platform specific requirements, follow these instructions:
/// 1. Install melos tool by running `flutter pub global activate melos`.
/// 2. Run `melos bootstrap` in FlutterFire project.
/// 3. In your terminal, root to ./packages/firebase_messaging/firebase_messaging/example directory.
/// 4. Run `flutterfire configure` in the example/ directory to setup your app with your Firebase project.
/// 5. Open `token_monitor.dart` and change `vapidKey` to yours.
/// 6. Run the app on an actual device for iOS, android is fine to run on an emulator.
/// 7. Use the following script to send a message to your device: scripts/send-message.js. To run this script,
/// you will need nodejs installed on your computer. Then the following:
/// a. Download a service account key (JSON file) from your Firebase console, rename it to "google-services.json" and add to the example/scripts directory.
/// b. Ensure your device/emulator is running, and run the FirebaseMessaging example app using `flutter run`.
/// c. Copy the token that is printed in the console and paste it here: https://github.com/firebase/flutterfire/blob/01b4d357e1/packages/firebase_messaging/firebase_messaging/example/lib/main.dart#L32
/// c. From your terminal, root to example/scripts directory & run `npm install`.
/// d. Run `npm run send-message` in the example/scripts directory and your app will receive messages in any state; foreground, background, terminated.
/// Note: Flutter API documentation for receiving messages: https://firebase.google.com/docs/cloud-messaging/flutter/receive
/// Note: If you find your messages have stopped arriving, it is extremely likely they are being throttled by the platform. iOS in particular
/// are aggressive with their throttling policy.
///
/// To verify that your messages are being received, you ought to see a notification appearon your device/emulator via the flutter_local_notifications plugin.
/// Define a top-level named handler which background/terminated messages will
/// call. Be sure to annotate the handler with `@pragma('vm:entry-point')` above the function declaration.
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
showFlutterNotification(message);
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
print('Handling a background message ${message.messageId}');
}
/// Create a [AndroidNotificationChannel] for heads up notifications
late AndroidNotificationChannel channel;
bool isFlutterLocalNotificationsInitialized = false;
Future<void> setupFlutterNotifications() async {
if (isFlutterLocalNotificationsInitialized) {
return;
}
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.high,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
isFlutterLocalNotificationsInitialized = true;
}
void showFlutterNotification(RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'launch_background',
),
),
);
}
}
/// Initialize the [FlutterLocalNotificationsPlugin] package.
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// Set the background messaging handler early on, as a named top-level function
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
await setupFlutterNotifications();
}
runApp(MessagingExampleApp());
}
/// Entry point for the example application.
class MessagingExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Messaging Example App',
theme: ThemeData.dark(),
routes: {
'/': (context) => Application(),
'/message': (context) => MessageView(),
},
);
}
}
// Crude counter to make messages unique
int _messageCount = 0;
/// The API endpoint here accepts a raw FCM payload for demonstration purposes.
String constructFCMPayload(String? token) {
_messageCount++;
return jsonEncode({
'token': token,
'data': {
'via': 'FlutterFire Cloud Messaging!!!',
'count': _messageCount.toString(),
},
'notification': {
'title': 'Hello FlutterFire!',
'body': 'This notification (#$_messageCount) was created via FCM!',
},
});
}
/// Renders the example application.
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
String? _token;
String? initialMessage;
bool _resolved = false;
@override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then(
(value) => setState(
() {
_resolved = true;
initialMessage = value?.data.toString();
},
),
);
FirebaseMessaging.onMessage.listen(showFlutterNotification);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
});
}
Future<void> sendPushMessage() async {
if (_token == null) {
print('Unable to send FCM message, no token exists.');
return;
}
try {
await http.post(
Uri.parse('https://api.rnfirebase.io/messaging/send'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: constructFCMPayload(_token),
);
print('FCM request for device sent!');
} catch (e) {
print(e);
}
}
Future<void> onActionSelected(String value) async {
switch (value) {
case 'subscribe':
{
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test".',
);
await FirebaseMessaging.instance.subscribeToTopic('fcm_test');
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test" successful.',
);
}
break;
case 'unsubscribe':
{
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test".',
);
await FirebaseMessaging.instance.unsubscribeFromTopic('fcm_test');
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test" successful.',
);
}
break;
case 'get_apns_token':
{
if (defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS) {
print('FlutterFire Messaging Example: Getting APNs token...');
String? token = await FirebaseMessaging.instance.getAPNSToken();
print('FlutterFire Messaging Example: Got APNs token: $token');
} else {
print(
'FlutterFire Messaging Example: Getting an APNs token is only supported on iOS and macOS platforms.',
);
}
}
break;
default:
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cloud Messaging'),
actions: <Widget>[
PopupMenuButton(
onSelected: onActionSelected,
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem(
value: 'subscribe',
child: Text('Subscribe to topic'),
),
const PopupMenuItem(
value: 'unsubscribe',
child: Text('Unsubscribe to topic'),
),
const PopupMenuItem(
value: 'get_apns_token',
child: Text('Get APNs token (Apple only)'),
),
];
},
),
],
),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: sendPushMessage,
backgroundColor: Colors.white,
child: const Icon(Icons.send),
),
),
body: SingleChildScrollView(
child: Column(
children: [
MetaCard('Permissions', Permissions()),
MetaCard(
'Initial Message',
Column(
children: [
Text(_resolved ? 'Resolved' : 'Resolving'),
Text(initialMessage ?? 'None'),
],
),
),
MetaCard(
'FCM Token',
TokenMonitor((token) {
_token = token;
return token == null
? const CircularProgressIndicator()
: SelectableText(
token,
style: const TextStyle(fontSize: 12),
);
}),
),
ElevatedButton(
onPressed: () {
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
}
});
},
child: const Text('getInitialMessage()'),
),
MetaCard('Message Stream', MessageList()),
],
),
),
);
}
}
/// UI Widget for displaying metadata.
class MetaCard extends StatelessWidget {
final String _title;
final Widget _children;
// ignore: public_member_api_docs
MetaCard(this._title, this._children);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.only(left: 8, right: 8, top: 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 16),
child: Text(_title, style: const TextStyle(fontSize: 18)),
),
_children,
],
),
),
),
);
}
}

View File

@ -0,0 +1,120 @@
// Copyright 2022, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// ignore_for_file: require_trailing_commas
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
/// Requests & displays the current user permissions for this device.
class Permissions extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Permissions();
}
class _Permissions extends State<Permissions> {
bool _requested = false;
bool _fetching = false;
late NotificationSettings _settings;
Future<void> requestPermissions() async {
setState(() {
_fetching = true;
});
NotificationSettings settings =
await FirebaseMessaging.instance.requestPermission(
announcement: true,
carPlay: true,
criticalAlert: true,
);
setState(() {
_requested = true;
_fetching = false;
_settings = settings;
});
}
Future<void> checkPermissions() async {
setState(() {
_fetching = true;
});
NotificationSettings settings =
await FirebaseMessaging.instance.getNotificationSettings();
setState(() {
_requested = true;
_fetching = false;
_settings = settings;
});
}
Widget row(String title, String value) {
return Container(
margin: const EdgeInsets.only(bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)),
Text(value),
],
),
);
}
@override
Widget build(BuildContext context) {
if (_fetching) {
return const CircularProgressIndicator();
}
if (!_requested) {
return ElevatedButton(
onPressed: requestPermissions,
child: const Text('Request Permissions'));
}
return Column(children: [
row('Authorization Status', statusMap[_settings.authorizationStatus]!),
if (defaultTargetPlatform == TargetPlatform.iOS) ...[
row('Alert', settingsMap[_settings.alert]!),
row('Announcement', settingsMap[_settings.announcement]!),
row('Badge', settingsMap[_settings.badge]!),
row('Car Play', settingsMap[_settings.carPlay]!),
row('Lock Screen', settingsMap[_settings.lockScreen]!),
row('Notification Center', settingsMap[_settings.notificationCenter]!),
row('Show Previews', previewMap[_settings.showPreviews]!),
row('Sound', settingsMap[_settings.sound]!),
],
ElevatedButton(
onPressed: checkPermissions, child: const Text('Reload Permissions')),
]);
}
}
/// Maps a [AuthorizationStatus] to a string value.
const statusMap = {
AuthorizationStatus.authorized: 'Authorized',
AuthorizationStatus.denied: 'Denied',
AuthorizationStatus.notDetermined: 'Not Determined',
AuthorizationStatus.provisional: 'Provisional',
};
/// Maps a [AppleNotificationSetting] to a string value.
const settingsMap = {
AppleNotificationSetting.disabled: 'Disabled',
AppleNotificationSetting.enabled: 'Enabled',
AppleNotificationSetting.notSupported: 'Not Supported',
};
/// Maps a [AppleShowPreviewSetting] to a string value.
const previewMap = {
AppleShowPreviewSetting.always: 'Always',
AppleShowPreviewSetting.never: 'Never',
AppleShowPreviewSetting.notSupported: 'Not Supported',
AppleShowPreviewSetting.whenAuthenticated: 'Only When Authenticated',
};

View File

@ -0,0 +1,50 @@
// Copyright 2022, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// ignore_for_file: require_trailing_commas
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
/// Manages & returns the users FCM token.
///
/// Also monitors token refreshes and updates state.
class TokenMonitor extends StatefulWidget {
// ignore: public_member_api_docs
const TokenMonitor(this._builder, {super.key});
final Widget Function(String? token) _builder;
@override
State<StatefulWidget> createState() => _TokenMonitor();
}
class _TokenMonitor extends State<TokenMonitor> {
String? _token;
late Stream<String> _tokenStream;
void setToken(String? token) {
print('FCM Token: $token');
setState(() {
_token = token;
});
}
@override
void initState() {
super.initState();
FirebaseMessaging.instance
.getToken(
vapidKey:
'BNKkaUWxyP_yC_lki1kYazgca0TNhuzt2drsOrL6WrgGbqnMnr8ZMLzg_rSPDm6HKphABS0KzjPfSqCXHXEd06Y')
.then(setToken);
_tokenStream = FirebaseMessaging.instance.onTokenRefresh;
_tokenStream.listen(setToken);
}
@override
Widget build(BuildContext context) {
return widget._builder(_token);
}
}

View File

@ -1,42 +1,36 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'dart:math' as math;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hub/actions/actions.dart';
import 'package:hub/app_state.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/backend/api_requests/api_manager.dart';
import 'package:hub/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
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/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:rxdart/rxdart.dart';
//
class PushNotificationService {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final Subject<RemoteMessage> _onMessage = BehaviorSubject<RemoteMessage>();
final BehaviorSubject<BuildContext> _context =
BehaviorSubject<BuildContext>();
final BehaviorSubject<RemoteMessage> _onMessage =
BehaviorSubject<RemoteMessage>();
final BehaviorSubject<Map<String, dynamic>> _notificationDetails =
BehaviorSubject<Map<String, dynamic>>();
PushNotificationService() {
_initializeLocalNotifications(_context);
_initializeFirebase();
_initializeLocalNotifications();
_createNotificationChannels();
}
@ -44,12 +38,21 @@ class PushNotificationService {
return _onMessage;
}
Future<void> initialize(BuildContext context) async {
_context.add(context);
Future<void> _initializeFirebase() async {
// await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform);
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) =>
_firebaseMessagingBackgroundHandler(
message, _flutterLocalNotificationsPlugin));
}
Future<void> initialize() async {
await _requestPermissions();
_listenToForegroundMessages(context);
_listenToBackgroundMessages();
_listenToNotificationClicks(context);
WidgetsBinding.instance.addPostFrameCallback((_) {
_listenToForegroundMessages();
_listenToBackgroundMessages();
_listenToNotificationClicks();
});
await updateDeviceToken();
}
@ -60,21 +63,22 @@ class PushNotificationService {
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
} else {}
log('Notification permissions granted');
} else {
log('Notification permissions denied');
}
}
Map<String, dynamic> validJsonFromString(String? jsonString) {
static Map<String, dynamic> validJsonFromString(String? jsonString) {
if (jsonString == null || jsonString.isEmpty) {
return {};
}
// Passo 1 e 2: Adiciona aspas duplas em torno das chaves e valores que não estão corretamente delimitados
String correctedJson = jsonString.replaceAllMapped(
RegExp(r'([a-zA-Z0-9_]+)\s*:\s*([^",\}\]]+)'), (match) {
var key = '"${match[1]!}"'; // Chaves sempre recebem aspas
var key = '"${match[1]!}"';
var value = match[2]!.trim();
// Verifica se o valor é uma string (não numérica, booleana, nula ou objeto JSON)
bool isStringValue = !RegExp(r'^-?\d+(\.\d+)?$').hasMatch(value) &&
value != 'true' &&
value != 'false' &&
@ -82,56 +86,68 @@ class PushNotificationService {
!value.startsWith('{') &&
!value.endsWith('}');
// Adiciona aspas duplas em torno do valor se for uma string
String quotedValue = isStringValue ? '"$value"' : value;
return '$key: $quotedValue';
});
// Passo 3: Tratar corretamente strings JSON aninhadas
correctedJson =
correctedJson.replaceAllMapped(RegExp(r'"{([^"]+)}"'), (match) {
// Remove as aspas duplas extras em torno de objetos JSON aninhados
return '{${match[1]!}}';
});
try {
// Passo 4: Decodificar o JSON corrigido
return jsonDecode(correctedJson);
} catch (e) {
return {};
}
}
void _initializeLocalNotifications(
BehaviorSubject<BuildContext> context) async {
while (context.valueOrNull == null) {
await Future.delayed(Duration(milliseconds: 100));
}
void _initializeLocalNotifications() async {
try {
while (AppState().context == null) {
await Future.delayed(const Duration(milliseconds: 100));
}
log("Context: ${AppState().context}");
var initializationSettingsAndroid =
const AndroidInitializationSettings('mipmap/ic_fre_black');
var initializationSettingsAndroid =
AndroidInitializationSettings('mipmap/ic_fre_black');
var initializationSettingsIOS = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
_flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) async {
if (response.payload != null) {
try {
Map<String, dynamic> message = validJsonFromString(response.payload!);
var data = _notificationDetails; // Assuming getOnMessage() now returns the latest RemoteMessage
_handleNotificationClick(message, extra: data.value);
} catch (e) {}
}
},
);
var initializationSettingsIOS = const DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
_flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveBackgroundNotificationResponse: (response) =>
notificationTapBackground(response, _notificationDetails),
onDidReceiveNotificationResponse: (response) =>
notificationTapBackground(response, _notificationDetails),
);
} on Exception catch (e, s) {
log("Error initializing local notifications: $e");
log(s.toString());
}
}
@pragma('vm:entry-point')
static void notificationTapBackground(
NotificationResponse response, _notificationDetails) async {
log("Notification: ${response.payload}");
if (response.payload != null) {
try {
Map<String, dynamic> message =
validJsonFromString(response.payload ?? '');
var data = _notificationDetails.value;
_handleNotificationClick(message, extra: data);
} catch (e) {
log('Error handling background notification: $e');
}
}
}
void _createNotificationChannels() {
@ -144,41 +160,48 @@ class PushNotificationService {
'miscellaneous'
];
for (String action in actions) {
_createNotificationChannel(action, "Channel for $action");
_createNotificationChannel('channel_$action', "channel_$action");
}
}
void _createNotificationChannel(String channelId, String channelName) {
_flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(
AndroidNotificationChannel(
channelId, // Use o click_action como ID do canal
channelName, // Nome descritivo baseado no click_action
description: 'Channel for $channelName notifications',
importance: Importance.max,
),
);
final androidNotificationChannel = AndroidNotificationChannel(
channelId,
channelName,
description: 'Channel for $channelName notifications',
importance: Importance.max,
);
AndroidFlutterLocalNotificationsPlugin()
.createNotificationChannel(androidNotificationChannel)
.catchError((error, stackTrace) {
log('Error creating notification channel: $error');
log(stackTrace.toString());
});
}
void _listenToForegroundMessages(BuildContext context) {
void _listenToForegroundMessages() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
log("Message Foregroud: ${message.data}");
log("Message Foreground: ${message.data}");
_onMessage.add(message);
_notificationDetails.add(message.toMap()['notification']);
_showNotification(message);
}).onError((error) {
log("Error listening to foreground messages: $error");
});
}
void _listenToBackgroundMessages() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) =>
_firebaseMessagingBackgroundHandler(
message, _flutterLocalNotificationsPlugin));
}
void _listenToNotificationClicks(BuildContext context) {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
_onMessage.add(message);
NotificationHandler().handleMessage(message.data, context);
void _listenToNotificationClicks() {
FirebaseMessaging.onMessageOpenedApp
.listen((RemoteMessage message) => _firebaseMessagingBackgroundHandler)
.onError((err) {
log("Error listening to notification clicks: $err");
});
}
@ -189,10 +212,13 @@ class PushNotificationService {
}
Future<void> _updateToken(String token) async {
FFAppState().token = token;
AppState().token = token;
final ApiCallResponse? response = await _updateTokenOnServer(token);
if (_isTokenUpdateSuccessful(response)) {
} else {}
log('Token update successful');
} else {
log('Token update failed');
}
}
Future<void> _handleTokenUpdate(String newToken) async {
@ -209,7 +235,9 @@ class PushNotificationService {
final String? deviceToken = await _firebaseMessaging.getToken();
if (deviceToken != null) {
await _updateToken(deviceToken);
} else {}
} else {
log('Failed to get device token');
}
}
Future<NotificationSettings> _requestNotificationPermission() async {
@ -233,8 +261,8 @@ class PushNotificationService {
Future<ApiCallResponse?> _updateTokenOnServer(String deviceToken) async {
return await PhpGroup.updToken.call(
token: deviceToken,
devid: FFAppState().devUUID,
useruuid: FFAppState().userUUID,
devid: AppState().devUUID,
useruuid: AppState().userUUID,
);
}
@ -247,80 +275,107 @@ class PushNotificationService {
return 'channel_$baseId';
}
void _showNotification(RemoteMessage message) async {
String channelId =
_getChannelIdBasedOnClickAction(message.data['click_action']);
var androidDetails = AndroidNotificationDetails(
Future<void> _showNotification(RemoteMessage message) async {
final String channelId = 'high_importance_channel';
final AndroidNotificationDetails androidDetails =
AndroidNotificationDetails(
channelId,
'Channel Name for $channelId',
channelDescription: 'Channel Description for $channelId',
importance: Importance.max,
'High Importance Notifications',
channelDescription: 'This channel is used for important notifications.',
importance: Importance.high,
priority: Priority.high,
);
var iOSDetails = DarwinNotificationDetails();
var generalNotificationDetails = NotificationDetails(android: androidDetails, iOS: iOSDetails);
final NotificationDetails generalNotificationDetails =
NotificationDetails(android: androidDetails);
await _flutterLocalNotificationsPlugin.show(
// DateTime.now().millisecondsSinceEpoch % (1 << 31),
math.Random().nextInt(1 << 30),
message.notification?.title,
message.notification?.body,
generalNotificationDetails,
payload: message.data.toString(),
payload: jsonEncode(message.data),
);
}
_handleNotificationClick(Map<String, dynamic> payload,
static _handleNotificationClick(Map<String, dynamic> payload,
{Map<String, dynamic> extra = const {}}) {
log("Payload _handleNotificationClick: $payload");
switch (payload.isNotEmpty) {
case true:
// Print the 'data' property
// Handle the message data as needed
NotificationHandler().handleMessage(payload, _context.value, extra: extra.isEmpty ? {} : extra);
// Access the 'data' property of 'RemoteMessage'
NotificationHandler().handleMessage(payload, AppState().context,
extra: extra.isEmpty ? {} : extra);
break;
case false:
// Handle the message notification as needed
break;
}
}
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Mensagem firebase: $message");
@pragma('vm:entry-point')
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message,
FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) async {
await Firebase.initializeApp();
showFlutterNotification(message, _flutterLocalNotificationsPlugin);
log('Handling a background message ${message.messageId}');
}
static void showFlutterNotification(RemoteMessage message,
FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin) {
final RemoteNotification? notification = message.notification;
final AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
_flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
'high_importance_channel',
'High Importance Notifications',
channelDescription:
'This channel is used for important notifications.',
icon: 'launch_background',
),
),
);
}
}
}
class NotificationHandler {
void handleMessage(Map<String, dynamic> message, BuildContext context, {Map<String, dynamic> extra = const {}}) {
void handleMessage(Map<String, dynamic> message, BuildContext? context,
{Map<String, dynamic> extra = const {}}) {
message.forEach((key, value) {});
switch (message['click_action']) {
case 'visit_request':
_showVisitRequestDialog(message, context);
break;
case '':
break;
case 'access':
_showAcessNotificationModal(message, context);
break;
case 'mensagem':
log("Extra Handle Message: $extra");
_showMessageNotificationDialog(message, context, extra);
break;
case 'enroll_cond':
break;
default:
log("Message: $message");
log("Extra: $extra");
if (context != null) {
switch (message['click_action']) {
case 'visit_request':
_showVisitRequestDialog(message, context);
break;
case '':
break;
case 'access':
_showAcessNotificationModal(message, context);
break;
case 'mensagem':
log("Extra Handle Message: $extra");
_showMessageNotificationDialog(message, context, extra);
break;
case 'enroll_cond':
break;
default:
}
}
}
String _getIdBasedOnUserType(Map<String, dynamic> message) {
if (message['USR_TIPO'].toString() == 'O') {
// Retorna USR_ID se não estiver vazio/nulo, caso contrário retorna '0'
return message['USR_ID'].toString().isEmpty
? '0'
: message['USR_ID'].toString();
} else {
// Retorna USR_DOCUMENTO se não estiver vazio/nulo, caso contrário retorna '0'
return message['USR_DOCUMENTO'].toString().isEmpty
? '0'
: message['USR_DOCUMENTO'].toString();
@ -334,25 +389,27 @@ class NotificationHandler {
builder: (BuildContext context) {
_getIdBasedOnUserType(message);
return Dialog(
backgroundColor: Colors.transparent,
child: AccessNotificationModalTemplateComponentWidget(
datetime: message['ACE_DATAHORA'].toString(),
drive: message['ACI_DESCRICAO'].toString(),
id: message['USR_TIPO'].toString() == 'O'
? message['USR_ID'].toString() == ''
? '0'
: message['USR_ID'].toString()
: message['USR_DOCUMENTO'].toString() == ''
? '0'
: message['USR_DOCUMENTO'].toString(),
name: message['PES_NOME'].toString(),
type: message['USR_TIPO'],
));
backgroundColor: Colors.transparent,
child: AccessNotificationModalTemplateComponentWidget(
datetime: message['ACE_DATAHORA'].toString(),
drive: message['ACI_DESCRICAO'].toString(),
id: message['USR_TIPO'].toString() == 'O'
? message['USR_ID'].toString() == ''
? '0'
: message['USR_ID'].toString()
: message['USR_DOCUMENTO'].toString() == ''
? '0'
: message['USR_DOCUMENTO'].toString(),
name: message['PES_NOME'].toString(),
type: message['USR_TIPO'],
),
);
},
);
}
void _showMessageNotificationDialog(Map<String, dynamic> message, BuildContext context, Map<String, dynamic> extra) {
void _showMessageNotificationDialog(Map<String, dynamic> message,
BuildContext context, Map<String, dynamic> extra) {
showDialog(
useSafeArea: true,
barrierDismissible: true,
@ -361,7 +418,7 @@ class NotificationHandler {
String localId = '';
try {
localId = jsonDecode(message['local'])['CLI_ID'];
} catch(e, s) {
} catch (e) {
localId = message['local']['CLI_ID'].toString();
}
@ -404,7 +461,6 @@ class NotificationHandler {
showDialog(
context: context,
barrierDismissible: true,
// barrierColor: Colors.green,
builder: (BuildContext context) {
_getIdBasedOnUserType(message);
return Dialog(
@ -535,7 +591,7 @@ class NotificationHandler {
): message['mensagem'],
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${message['documento'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${message['documento'] ?? ''}&tipo=E',
statusHashMap: [
{
FFLocalizations.of(context).getVariableText(
@ -544,7 +600,6 @@ class NotificationHandler {
): FlutterFlowTheme.of(context).warning,
},
],
// changeStatusAction: answersRequest,
),
);
},

View File

@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_model.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:provider/provider.dart';
import '/backend/api_requests/api_calls.dart';
import '/flutter_flow/flutter_flow_icon_button.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:provider/provider.dart';
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
const BottomArrowLinkedLocalsComponentWidget({super.key});
@ -44,7 +43,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Align(
alignment: const AlignmentDirectional(0.0, 1.0),
@ -105,8 +104,8 @@ class _BottomArrowLinkedLocalsComponentWidgetState
Expanded(
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getLocalsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
@ -156,17 +155,17 @@ class _BottomArrowLinkedLocalsComponentWidgetState
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
FFAppState().cliUUID = getJsonField(
AppState().cliUUID = getJsonField(
eachLocalsItem,
r'''$.CLI_ID''',
).toString();
setState(() {});
FFAppState().local = getJsonField(
AppState().local = getJsonField(
eachLocalsItem,
r'''$.CLI_NOME''',
).toString();
setState(() {});
FFAppState().ownerUUID = getJsonField(
AppState().ownerUUID = getJsonField(
eachLocalsItem,
r'''$.CLU_OWNER_ID''',
).toString();

View File

@ -43,7 +43,7 @@ class _LocalProfileComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Container(
decoration: const BoxDecoration(),
@ -92,7 +92,7 @@ class _LocalProfileComponentWidgetState
child: ClipRRect(
borderRadius: BorderRadius.circular(200.0),
child: Image.network(
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
'https://freaccess.com.br/freaccess/Images/Clients/${AppState().cliUUID}.png',
width: 80.0,
height: 80.0,
fit: BoxFit.cover,
@ -117,7 +117,7 @@ class _LocalProfileComponentWidgetState
children: [
Text(
valueOrDefault<String>(
functions.convertToUppercase(FFAppState().local),
functions.convertToUppercase(AppState().local),
'NOME DO LOCAL',
),
style: FlutterFlowTheme.of(context).labelMedium.override(

View File

@ -355,9 +355,9 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
if (state.pageNumber <= totalPageNumber) {
var apiCall = GetMessagesCall();
var response = await apiCall.call(
devUUID: FFAppState().devUUID.toString(),
userUUID: FFAppState().userUUID.toString(),
cliID: FFAppState().cliUUID.toString(),
devUUID: AppState().devUUID.toString(),
userUUID: AppState().userUUID.toString(),
cliID: AppState().cliUUID.toString(),
atividade: 'getMensagens',
pageSize: '100',
pageNumber: state.pageNumber.toString(),

View File

@ -99,7 +99,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
final visitorsData = widget.visitorJsonList!.toList().take(2).toList();
final visitorsDataItem = visitorsData[0];
@ -178,7 +178,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
imageUrl: valueOrDefault<String>(
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
visitorsDataItem,
r'''$.VTE_DOCUMENTO''',
).toString()}&tipo=E",
@ -789,8 +789,8 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
onPressed: () async {
_model.postScheduleVisit =
await PhpGroup.postScheduleVisitCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
atividade: 'putVisita',
devDesc: widget.visitObsStr,
idVisitante: widget.visitorStrList,
@ -801,7 +801,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
idMotivo: extractIdToStr(widget.visitResonStr!),
idNAC: extractIdToStr(widget.visitLevelStr!),
obs: widget.visitObsStr,
cliID: FFAppState().cliUUID,
cliID: AppState().cliUUID,
);
if (PhpGroup.postScheduleVisitCall.error(

View File

@ -5,13 +5,11 @@ import 'package:hub/components/organism_components/up_arrow_linked_locals_compon
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
class UpArrowLinkedLocalsComponentWidget extends StatefulWidget {
const UpArrowLinkedLocalsComponentWidget({super.key});
@ -45,7 +43,7 @@ class _UpArrowLinkedLocalsComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Align(
alignment: const AlignmentDirectional(0.0, -1.0),
@ -82,8 +80,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
),
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getLocalsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
@ -134,12 +132,12 @@ class _UpArrowLinkedLocalsComponentWidgetState
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
FFAppState().cliUUID = getJsonField(
AppState().cliUUID = getJsonField(
eachLocalsItem,
r'''$.CLI_ID''',
).toString();
setState(() {});
FFAppState().local = getJsonField(
AppState().local = getJsonField(
eachLocalsItem,
r'''$.CLI_NOME''',
).toString();
@ -150,7 +148,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
width: 50.0,
height: double.infinity,
decoration: const BoxDecoration(),
alignment: const AlignmentDirectional(0.0, 0.0),
alignment:
const AlignmentDirectional(0.0, 0.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
@ -162,7 +161,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.primaryText,
borderRadius: const BorderRadius.only(
borderRadius:
const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight:
Radius.circular(25.0),
@ -177,7 +177,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
),
),
child: ClipRRect(
borderRadius: const BorderRadius.only(
borderRadius:
const BorderRadius.only(
bottomLeft: Radius.circular(25.0),
bottomRight:
Radius.circular(25.0),
@ -192,14 +193,14 @@ class _UpArrowLinkedLocalsComponentWidgetState
width: double.infinity,
height: double.infinity,
fit: BoxFit.fill,
alignment: const Alignment(0.0, 0.0),
alignment:
const Alignment(0.0, 0.0),
),
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
0.0, 10.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional
.fromSTEB(0.0, 10.0, 0.0, 0.0),
child: Text(
getJsonField(
eachLocalsItem,

View File

@ -4,7 +4,6 @@ import 'access_notification_modal_template_component_widget.dart'
show AccessNotificationModalTemplateComponentWidget;
import 'package:flutter/material.dart';
class AccessNotificationModalTemplateComponentModel
extends FlutterFlowModel<AccessNotificationModalTemplateComponentWidget> {
/// State fields for stateful widgets in this component.
@ -55,9 +54,9 @@ class AccessNotificationModalTemplateComponentModel
ApiCallResponse? visitRequest;
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliUUID: AppState().cliUUID,
atividade: 'respondeSolicitacao',
referencia: refUUID,
tarefa: actionValue,

View File

@ -7,9 +7,6 @@ import 'package:provider/provider.dart';
import 'access_notification_modal_template_component_model.dart';
export 'access_notification_modal_template_component_model.dart';
class AccessNotificationModalTemplateComponentWidget extends StatefulWidget {
const AccessNotificationModalTemplateComponentWidget({
super.key,
@ -70,17 +67,13 @@ class _AccessNotificationModalTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
String labelTypeResident = FFLocalizations.of(context).getVariableText(
enText: 'Resident',
ptText: 'Morador'
);
String labelTypeResident = FFLocalizations.of(context)
.getVariableText(enText: 'Resident', ptText: 'Morador');
String labelTypeVisitor = FFLocalizations.of(context).getVariableText(
enText: 'Visitor',
ptText: 'Visitante'
);
String labelTypeVisitor = FFLocalizations.of(context)
.getVariableText(enText: 'Visitor', ptText: 'Visitante');
return Align(
alignment: const AlignmentDirectional(0.0, 0.0),
@ -120,7 +113,7 @@ class _AccessNotificationModalTemplateComponentWidgetState
// widget.type == 'O'
// ? 'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=O'
// : 'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=${widget.type}',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=${widget.type}',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
fit: BoxFit.cover,
@ -194,7 +187,10 @@ class _AccessNotificationModalTemplateComponentWidgetState
children: [
Expanded(
child: TextFormField(
controller: TextEditingController(text: widget.type == 'O' ? labelTypeResident : labelTypeVisitor),
controller: TextEditingController(
text: widget.type == 'O'
? labelTypeResident
: labelTypeVisitor),
focusNode: _model.textFieldFocusNode2,
autofocus: false,
textInputAction: TextInputAction.next,
@ -329,7 +325,7 @@ class _AccessNotificationModalTemplateComponentWidgetState
decoration: InputDecoration(
isDense: true,
labelText: FFLocalizations.of(context).getVariableText(
enText: 'Access Sector',
enText: 'Access Sector',
ptText: 'Setor de Acesso',
),
labelStyle: FlutterFlowTheme.of(context)

View File

@ -83,7 +83,7 @@ class _CardItemTemplateComponentWidgetState
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
context.watch<FFAppState>();
context.watch<AppState>();
return InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,

View File

@ -10,7 +10,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'change_pass_model.dart';
export 'change_pass_model.dart';
class PassKeyTemplateWidget extends StatefulWidget {
const PassKeyTemplateWidget({
super.key,
@ -20,12 +19,10 @@ class PassKeyTemplateWidget extends StatefulWidget {
final Future Function(String key)? toggleActionStatus;
@override
State<PassKeyTemplateWidget> createState() =>
_PassKeyTemplateWidgetState();
State<PassKeyTemplateWidget> createState() => _PassKeyTemplateWidgetState();
}
class _PassKeyTemplateWidgetState
extends State<PassKeyTemplateWidget> {
class _PassKeyTemplateWidgetState extends State<PassKeyTemplateWidget> {
late PassKeyTemplateComponentModel _model;
@override
@ -82,7 +79,8 @@ class _PassKeyTemplateWidgetState
tablet: false,
))
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 16.0, 8.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 16.0, 8.0),
child: InkWell(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
@ -104,8 +102,8 @@ class _PassKeyTemplateWidgetState
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(12.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
12.0, 0.0, 0.0, 0.0),
child: Text(
'',
style:
@ -125,11 +123,14 @@ class _PassKeyTemplateWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getVariableText(
enText: 'INSERT PASSWORD',
ptText: FFAppState().accessPass != '' ? 'ALTERAR SENHA' : 'ADICIONAR SENHA',
ptText: AppState().accessPass != ''
? 'ALTERAR SENHA'
: 'ADICIONAR SENHA',
),
style: FlutterFlowTheme.of(context).headlineMedium.override(
fontFamily: 'Outfit',
@ -142,12 +143,12 @@ class _PassKeyTemplateWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 4.0, 16.0, 4.0),
padding:
const EdgeInsetsDirectional.fromSTEB(16.0, 4.0, 16.0, 4.0),
child: Text(
FFLocalizations.of(context).getVariableText(
enText: 'Enter your password to continue',
ptText: 'Digite sua senha para continuar'
),
enText: 'Enter your password to continue',
ptText: 'Digite sua senha para continuar'),
style: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
@ -165,7 +166,8 @@ class _PassKeyTemplateWidgetState
child: Column(
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(16.0, 12.0, 16.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
16.0, 12.0, 16.0, 0.0),
child: SizedBox(
width: double.infinity,
child: TextFormField(
@ -175,7 +177,7 @@ class _PassKeyTemplateWidgetState
'_model.keyTextFieldTextController',
const Duration(milliseconds: 2000),
() {
if (mounted) setState(() {});
if (mounted) setState(() {});
},
),
autofillHints: const [AutofillHints.password],
@ -184,120 +186,120 @@ class _PassKeyTemplateWidgetState
obscureText: !_model.keyTextFieldVisibility1,
decoration: InputDecoration(
isDense: true,
labelText: FFLocalizations.of(context).getVariableText(
ptText: 'Senha',
enText: 'Password',
labelText:
FFLocalizations.of(context).getVariableText(
ptText: 'Senha',
enText: 'Password',
),
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
.labelMedium
.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
hintText: FFLocalizations.of(context).getVariableText(
ptText: 'Digite a sua senha.....',
enText: 'Enter your password.....',
ptText: 'Digite a sua senha.....',
enText: 'Enter your password.....',
),
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
.labelMedium
.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).primary,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 2.0,
),
borderRadius: BorderRadius.circular(12.0),
),
filled: true,
fillColor:
FlutterFlowTheme.of(context).primaryBackground,
contentPadding:
const EdgeInsetsDirectional.fromSTEB(
FlutterFlowTheme.of(context).primaryBackground,
contentPadding: const EdgeInsetsDirectional.fromSTEB(
24.0, 24.0, 20.0, 24.0),
suffixIcon: InkWell(
onTap: () => setState(
() => _model.keyTextFieldVisibility1 =
!_model.keyTextFieldVisibility1,
),
focusNode: FocusNode(skipTraversal: true),
child: Icon(
_model.keyTextFieldVisibility1
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
color: FlutterFlowTheme.of(context).accent1,
size: 22.0,
),
onTap: () => setState(
() => _model.keyTextFieldVisibility1 =
!_model.keyTextFieldVisibility1,
),
focusNode: FocusNode(skipTraversal: true),
child: Icon(
_model.keyTextFieldVisibility1
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
color: FlutterFlowTheme.of(context).accent1,
size: 22.0,
),
),
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
fontFamily: 'Plus Jakarta Sans',
color: FlutterFlowTheme.of(context).primaryText,
fontSize: 14.0,
letterSpacing: 0.0,
fontWeight: FontWeight.w500,
useGoogleFonts: GoogleFonts.asMap()
.containsKey('Plus Jakarta Sans'),
),
maxLength: 4,
maxLengthEnforcement: MaxLengthEnforcement.enforced,
buildCounter: (context,
{required currentLength,
required isFocused,
maxLength}) =>
null,
{required currentLength,
required isFocused,
maxLength}) =>
null,
keyboardType: TextInputType.number,
cursorColor: FlutterFlowTheme.of(context).primary,
validator: _model.keyTextFieldTextControllerValidator1
.asValidator(context),
.asValidator(context),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
LengthLimitingTextInputFormatter(4),
],
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
LengthLimitingTextInputFormatter(4),
],
),
),
),
),
],
),
),
Align(
alignment: const AlignmentDirectional(0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 24.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(0.0, 24.0, 0.0, 0.0),
child: FFButtonWidget(
onPressed: () async {
if (_model.formKey.currentState == null ||
@ -305,20 +307,24 @@ class _PassKeyTemplateWidgetState
return;
}
await widget.toggleActionStatus?.call(
_model.keyTextFieldTextController1.text.isEmpty ? _model.keyTextFieldTextController2.text : _model.keyTextFieldTextController1.text,
_model.keyTextFieldTextController1.text.isEmpty
? _model.keyTextFieldTextController2.text
: _model.keyTextFieldTextController1.text,
);
Navigator.pop(context, true);
},
text: FFLocalizations.of(context).getVariableText(
ptText: FFAppState().accessPass != '' ? 'Alterar' : 'Adicionar',
enText: FFAppState().accessPass != '' ? 'Change' : 'Add',
ptText:
AppState().accessPass != '' ? 'Alterar' : 'Adicionar',
enText: AppState().accessPass != '' ? 'Change' : 'Add',
),
options: FFButtonOptions(
width: 270.0,
height: 50.0,
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
iconPadding:
const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0.0, 0.0, 0.0, 0.0),
color: const Color(0xFF1AAB5F),
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
fontFamily: 'Plus Jakarta Sans',

View File

@ -113,12 +113,11 @@ Widget buildDetails(
context,
MaterialPageRoute(
builder: (context) => ScheduleCompleteVisitPageWidget(
dropdownValue1: visitaWrapItem['MOT_DESCRICAO'],
dropdownValue1: visitaWrapItem['MOT_DESCRICAO'],
dropdownValue2: visitaWrapItem['NAC_DESCRICAO'],
visitorJsonList: [visitaWrapItem],
visitorStrList: visitaWrapItem['VTE_DOCUMENTO'],
)
),
)),
);
},
options: FFButtonOptions(
@ -177,7 +176,7 @@ URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${vi
'Fim': visitaWrapItem['VAW_DTFIM'] ?? '',
}),
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
statusHashMap: [
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
Map<String, Color>.from({

View File

@ -28,12 +28,10 @@ class DetailsComponentWidget extends StatefulWidget {
final List<Widget> buttons;
@override
State<DetailsComponentWidget> createState() =>
_DetailsComponentWidgetState();
State<DetailsComponentWidget> createState() => _DetailsComponentWidgetState();
}
class _DetailsComponentWidgetState
extends State<DetailsComponentWidget> {
class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
late DetailsComponentModel _model;
LinkedHashMap<String, String> get labelsLinkedHashMap =>
@ -66,7 +64,7 @@ class _DetailsComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Container(
constraints: BoxConstraints(

View File

@ -58,9 +58,9 @@ class LiberationHistoryItemDetailsTemplateComponentModel
ApiCallResponse? visitRequest;
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliUUID: AppState().cliUUID,
atividade: 'respondeSolicitacao',
referencia: refUUID,
tarefa: actionValue,

View File

@ -1,4 +1,3 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
@ -69,7 +68,7 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Align(
alignment: const AlignmentDirectional(0.0, 0.0),
@ -106,7 +105,7 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
fadeInDuration: const Duration(milliseconds: 100),
fadeOutDuration: const Duration(milliseconds: 100),
imageUrl: valueOrDefault<String>(
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${widget.id}&tipo=E',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
fit: BoxFit.cover,
@ -117,7 +116,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
.addToEnd(const SizedBox(width: 10.0)),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model.textController1,
focusNode: _model.textFieldFocusNode1,
@ -242,7 +242,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
.addToEnd(const SizedBox(width: 24.0)),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model.textController3,
focusNode: _model.textFieldFocusNode3,
@ -300,7 +301,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0),
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model.textController4,
focusNode: _model.textFieldFocusNode4,

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'package:hub/app_state.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
@ -56,9 +55,9 @@ class MessageNotificationModalTemplateComponentModel
ApiCallResponse? visitRequest;
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliUUID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliUUID: AppState().cliUUID,
atividade: 'respondeSolicitacao',
referencia: refUUID,
tarefa: actionValue,

View File

@ -64,7 +64,7 @@ class _MessageNotificationModalTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Align(
alignment: const AlignmentDirectional(0.0, 0.0),

View File

@ -47,9 +47,9 @@ class RegisiterVistorTemplateComponentModel
Future<bool> getVisitanteByDocument(
String document, BuildContext context) async {
final response = await PhpGroup.getVisitorByDocCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getVisitante',
documento: document,
);

View File

@ -112,7 +112,7 @@ class _RegisiterVistorTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Align(
alignment: const AlignmentDirectional(0.0, 1.0),
child: Container(
@ -809,9 +809,9 @@ class _RegisiterVistorTemplateComponentWidgetState
_model.scheduleVisitor =
await PhpGroup.postScheduleVisitorCall
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'putVisitante',
documento: _model.textController2.text,
nome: _model.textController1.text,

View File

@ -123,7 +123,7 @@ class _SignUpTemplateComponentWidgetState
return false;
}
context.watch<FFAppState>();
context.watch<AppState>();
return Row(
mainAxisSize: MainAxisSize.max,
@ -701,7 +701,7 @@ class _SignUpTemplateComponentWidgetState
email: _model
.emailRegisterFormTextController
.text,
device: FFAppState().device,
device: AppState().device,
);
shouldSetState = true;
if (_model.signUp == true) {

View File

@ -128,7 +128,7 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
var filteredVisitorJsonList =
findVisitorById(widget.visitorJsonList, widget.visitIdStr) ?? 'null';
context.watch<FFAppState>();
context.watch<AppState>();
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 200.0, 0.0, 0.0),
@ -829,9 +829,9 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
onPressed: () async {
_model.deleteVisit =
await PhpGroup.deleteVisitCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'cancelaVisita',
idVisita: widget.visitIdStr,
);

View File

@ -61,7 +61,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 50.0, 0.0, 0.0),
@ -291,7 +291,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
fadeOutDuration: const Duration(
milliseconds: 500),
imageUrl:
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
visitorItem,
r'''$.VTE_DOCUMENTO''',
).toString()}&tipo=E",
@ -462,9 +462,9 @@ class _VisitorSearchModalTemplateComponentWidgetState
TextSelection.collapsed(offset: _model.textController!.text.length);
});
_model.getVisitorByDoc = await PhpGroup.getVisitorByDocCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getVisitante',
documento: _model.textController.text,
);

View File

@ -69,7 +69,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
FFRoute(
name: '_initialize',
path: '/',
builder: (context, _) => FFAppState().isLogged
builder: (context, _) => AppState().isLogged
? const HomePageWidget()
: const WelcomePageWidget(),
),

View File

@ -1,41 +1,157 @@
import 'dart:developer';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:hub/app_state.dart';
import 'package:hub/firebase_options.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'firebase_options.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:flutter/services.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
showFlutterNotification(message);
log('Handling a background message ${message.messageId}');
}
late AndroidNotificationChannel channel;
late DarwinInitializationSettings iosSettings;
late InitializationSettings initializationSettings;
late AndroidInitializationSettings initializationSettingsAndroid;
bool isFlutterLocalNotificationsInitialized = false;
@pragma('vm:entry-point')
Future<void> setupFlutterNotifications() async {
if (isFlutterLocalNotificationsInitialized) {
return;
}
channel = const AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.high,
);
initializationSettingsAndroid =
const AndroidInitializationSettings('mipmap/ic_fre_black');
iosSettings = const DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: iosSettings,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel)
.then((_) async => await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (response) async {
log('Notification: ${response.payload}');
},
onDidReceiveBackgroundNotificationResponse: (response) async {
log('Notification: ${response.payload}');
},
));
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
isFlutterLocalNotificationsInitialized = true;
}
void showFlutterNotification(RemoteMessage message) {
log('Handling a background message ${message.messageId}');
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: 'launch_background',
),
),
);
}
}
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
await setupFlutterNotifications();
}
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
await init();
runApp(ChangeNotifierProvider(
create: (context) => FFAppState(),
child: const MyApp(),
));
await init().then((_) {
runApp(ChangeNotifierProvider(
create: (context) => AppState(),
child: const MyApp(),
));
});
}
Future<void> init() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
log('Setting up Crashlytics...');
final crashlyticsInstance = FirebaseCrashlytics.instance;
if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
FlutterError.onError = crashlyticsInstance.recordFlutterError;
} else {
log('Crashlytics instance is null');
}
log('Crashlytics set up.');
log('Initializing FlutterFlowTheme...');
await FlutterFlowTheme.initialize();
log('FlutterFlowTheme initialized.');
log('Initializing FFLocalizations...');
await FFLocalizations.initialize();
final appState = FFAppState();
log('FFLocalizations initialized.');
log('Initializing app state...');
final appState = AppState();
await appState.initializePersistedState();
log('App state initialized.');
log('Initializing GoRouter...');
GoRouter.optionURLReflectsImperativeAPIs = true;
usePathUrlStrategy();
log('GoRouter initialized.');
}
class MyApp extends StatefulWidget {

View File

@ -209,9 +209,9 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
try {
setState(() => _loading = true);
var response = await PhpGroup.getAccessCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getAcessos',
pageSize: _pageSize.toString(),
pageNumber: _pageNumber.toString(),
@ -355,7 +355,7 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
BuildContext context, dynamic accessHistoryItem) {
return CardItemTemplateComponentWidget(
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${accessHistoryItem['PES_ID'] ?? ''}&tipo=${accessHistoryItem['PES_TIPO'] ?? ''}',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${accessHistoryItem['PES_ID'] ?? ''}&tipo=${accessHistoryItem['PES_TIPO'] ?? ''}',
labelsHashMap: Map<String, String>.from({
'Nome:': accessHistoryItem['PES_NOME'] ?? '',
'Acesso:': accessHistoryItem['ACE_DATAHORA'] ?? '',
@ -409,7 +409,7 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
String imageUrlAtomWidget(String document, String type) {
return valueOrDefault<String>(
"https://freaccess.com.br/freaccess/getImage.php?&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=$document&tipo=$type",
"https://freaccess.com.br/freaccess/getImage.php?&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=$document&tipo=$type",
"https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg",
);
}

View File

@ -9,15 +9,15 @@ import 'package:webview_flutter/webview_flutter.dart';
import 'dart:io' show Platform;
class FastPassPageWidget extends StatefulWidget {
final String freToken = FFAppState().userUUID;
final String freUserData = "{\"name\": \"${FFAppState().name}\", " +
"\"email\": \"${FFAppState().email}\"," +
"\"dev_id\": \"${FFAppState().devUUID}\"," +
"\"created_at\": \"${FFAppState().createdAt}\"," +
final String freToken = AppState().userUUID;
final String freUserData = "{\"name\": \"${AppState().name}\", " +
"\"email\": \"${AppState().email}\"," +
"\"dev_id\": \"${AppState().devUUID}\"," +
"\"created_at\": \"${AppState().createdAt}\"," +
"\"updated_at\": \"0000-00-00 00:00:00\"," +
"\"status\": \"A\" }";
final String clientId = FFAppState().cliUUID;
final String clientId = AppState().cliUUID;
@override
_FastPassPageWidgetState createState() => _FastPassPageWidgetState();
@ -35,63 +35,69 @@ class _FastPassPageWidgetState extends State<FastPassPageWidget> {
@override
void initState() {
super.initState();
name = FFAppState().name;
email = FFAppState().email;
userUUID = FFAppState().userUUID;
created_at = FFAppState().createdAt;
name = AppState().name;
email = AppState().email;
userUUID = AppState().userUUID;
created_at = AppState().createdAt;
url = 'https://hub.freaccess.com.br/hub/fast-pass/${widget.clientId}';
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Platform.isIOS ? InAppWebView(
initialUrlRequest: URLRequest(url: WebUri(url)),
initialSettings: InAppWebViewSettings(
allowsBackForwardNavigationGestures: true,
javaScriptEnabled: true,
),
onWebViewCreated: (controller) async {
_controllerIOS = controller;
},
onLoadStop: (controller, url) async {
await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')");
await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')");
},
) : WebViewWidget(
controller: _controllerAll = WebViewController()
..clearCache()
..clearLocalStorage()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {},
onPageStarted: (String url) {
final String token = "localStorage.setItem('fre-token', '\"${widget.freToken}\"');";
final String data = "localStorage.setItem('fre-user-data', '${widget.freUserData}');";
body: Platform.isIOS
? InAppWebView(
initialUrlRequest: URLRequest(url: WebUri(url)),
initialSettings: InAppWebViewSettings(
allowsBackForwardNavigationGestures: true,
javaScriptEnabled: true,
),
onWebViewCreated: (controller) async {
_controllerIOS = controller;
},
onLoadStop: (controller, url) async {
await controller.evaluateJavascript(
source:
"window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')");
await controller.evaluateJavascript(
source:
"window.localStorage.setItem('fre-user-data', '${widget.freUserData}')");
},
)
: WebViewWidget(
controller: _controllerAll = WebViewController()
..clearCache()
..clearLocalStorage()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {},
onPageStarted: (String url) {
final String token =
"localStorage.setItem('fre-token', '\"${widget.freToken}\"');";
final String data =
"localStorage.setItem('fre-user-data', '${widget.freUserData}');";
_controllerAll.runJavaScript(token);
_controllerAll.runJavaScript(data);
},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('http') ||
request.url.startsWith('https://api.whatsapp.com/send') ||
request.url.startsWith('https://wa.me')) {
launchUrlString(request.url);
return NavigationDecision.prevent;
}
return NavigationDecision.prevent;
},
_controllerAll.runJavaScript(token);
_controllerAll.runJavaScript(data);
},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('http') ||
request.url
.startsWith('https://api.whatsapp.com/send') ||
request.url.startsWith('https://wa.me')) {
launchUrlString(request.url);
return NavigationDecision.prevent;
}
return NavigationDecision.prevent;
},
),
)
..loadRequest(Uri.parse(url)),
),
)
..loadRequest(Uri.parse(url)),
),
),
);
}
}

View File

@ -1,13 +1,13 @@
// import 'package:hub/backend/push_notification/pushNotification.dart';
import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart';
import 'package:hub/actions/actions.dart';
import 'package:hub/backend/push_notification/pushNotificationService.dart';
import 'package:hub/backend/schema/enums/enums.dart';
import 'package:hub/components/atomic_components/menu_button_item/menu_button_item_widget.dart';
import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart';
import 'package:hub/components/organism_components/local_profile_component/local_profile_component_widget.dart';
import 'package:hub/components/organism_components/menu_component/menu_component_widget.dart';
@ -15,15 +15,32 @@ import 'package:hub/components/organism_components/message_well_component/messag
import 'package:hub/flutter_flow/custom_functions.dart';
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/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/main.dart';
import 'package:hub/pages/home_page/home_page_model.dart';
import 'package:provider/provider.dart';
// Crude counter to make messages unique
int _messageCount = 0;
/// The API endpoint here accepts a raw FCM payload for demonstration purposes.
String constructFCMPayload(String? token) {
_messageCount++;
return jsonEncode({
'token': token,
'data': {
'via': 'FlutterFire Cloud Messaging!!!',
'count': _messageCount.toString(),
},
'notification': {
'title': 'Hello FlutterFire!',
'body': 'This notification (#$_messageCount) was created via FCM!',
},
});
}
class HomePageWidget extends StatefulWidget {
const HomePageWidget({super.key});
@ -35,6 +52,9 @@ class _HomePageWidgetState extends State<HomePageWidget> {
late HomePageModel _model;
bool localStatus = false;
final scaffoldKey = GlobalKey<ScaffoldState>();
String? _token;
String? initialMessage;
bool _resolved = false;
Future<void> checkLocalStatus() async {
localStatus = await checkLocals(
@ -48,9 +68,29 @@ class _HomePageWidgetState extends State<HomePageWidget> {
void initState() {
super.initState();
_model = createModel(context, () => HomePageModel());
SchedulerBinding.instance.addPostFrameCallback((_) async {
await PushNotificationService().initialize(context);
FirebaseMessaging.instance
.getInitialMessage()
.then(
(value) => setState(
() {
_resolved = true;
initialMessage = value?.data.toString();
log('getInitialMessage resolved');
},
),
)
.whenComplete(() => log('getInitialMessage completed'));
FirebaseMessaging.onMessage.listen(showFlutterNotification).onDone(() {
log('onMessage completed');
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
log('A new onMessageOpenedApp event was published!');
});
AppState().context = context;
WidgetsBinding.instance.addPostFrameCallback((_) async {
@override
void initState() {
super.initState();
@ -58,7 +98,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
}
// Rest of your code...
if (FFAppState().cliUUID == null || FFAppState().cliUUID.isEmpty) {
if (AppState().cliUUID == null || AppState().cliUUID.isEmpty) {
showModalBottomSheet(
isScrollControlled: false,
backgroundColor: Colors.transparent,
@ -93,9 +133,72 @@ class _HomePageWidgetState extends State<HomePageWidget> {
super.dispose();
}
Future<void> sendPushMessage() async {
if (_token == null) {
log('Unable to send FCM message, no token exists.');
return;
}
try {
await post(
Uri.parse('https://api.rnfirebase.io/messaging/send'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: constructFCMPayload(_token),
);
log('FCM request for device sent!');
} catch (e) {
log(e.toString());
}
}
Future<void> onActionSelected(String value) async {
switch (value) {
case 'subscribe':
{
log(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test".',
);
await FirebaseMessaging.instance.subscribeToTopic('fcm_test');
log(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test" successful.',
);
}
break;
case 'unsubscribe':
{
log(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test".',
);
await FirebaseMessaging.instance.unsubscribeFromTopic('fcm_test');
log(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test" successful.',
);
}
break;
case 'get_apns_token':
{
if (defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS) {
log('FlutterFire Messaging Example: Getting APNs token...');
String? token = await FirebaseMessaging.instance.getAPNSToken();
log('FlutterFire Messaging Example: Got APNs token: $token');
} else {
log(
'FlutterFire Messaging Example: Getting an APNs token is only supported on iOS and macOS platforms.',
);
}
}
break;
default:
break;
}
}
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return GestureDetector(
onTap: () => _model.unfocusNode.canRequestFocus
? FocusScope.of(context).requestFocus(_model.unfocusNode)
@ -363,7 +466,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
),
child: Image.network(
valueOrDefault<String>(
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
'https://freaccess.com.br/freaccess/Images/Clients/${AppState().cliUUID}.png',
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
),
fit: BoxFit.cover,
@ -373,7 +476,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
width: 150.0,
child: Text(
valueOrDefault<String>(
convertToUppercase(FFAppState().local),
convertToUppercase(AppState().local),
'NOME DO LOCAL',
),
style: FlutterFlowTheme.of(context)
@ -543,7 +646,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
),
FFButtonWidget(
onPressed: () async {
FFAppState().deleteAll();
AppState().deleteAll();
setState(() {});
context.goNamed(
@ -787,3 +890,34 @@ class _HomePageWidgetState extends State<HomePageWidget> {
// );
}
}
/// UI Widget for displaying metadata.
class MetaCard extends StatelessWidget {
final String _title;
final Widget _children;
// ignore: public_member_api_docs
MetaCard(this._title, this._children);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.only(left: 8, right: 8, top: 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 16),
child: Text(_title, style: const TextStyle(fontSize: 18)),
),
_children,
],
),
),
),
);
}
}

View File

@ -4,7 +4,7 @@ import 'dart:developer';
import 'package:hub/actions/actions.dart';
import 'package:hub/backend/api_requests/api_calls.dart';
import 'package:hub/backend/push_notification/pushNotificationService.dart';
import 'package:hub/backend/push_notification/push_notification_service.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
@ -58,7 +58,7 @@ class _LiberationHistoryWidgetState extends State<LiberationHistoryWidget> {
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return GestureDetector(
onTap: () => _model.unfocusNode.canRequestFocus
? FocusScope.of(context).requestFocus(_model.unfocusNode)
@ -227,9 +227,9 @@ Widget liberationDynamicListView(
child: StreamBuilder<ApiCallResponse>(
stream: _model.getLiberations(
requestFn: () => PhpGroup.getLiberationsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getSolicitacoes',
),
),
@ -299,7 +299,7 @@ Widget liberationHistoryItemCard(
BuildContext context, dynamic liberationHistoryItem) {
return CardItemTemplateComponentWidget(
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
labelsHashMap: Map<String, String>.from({
'Nome:': liberationHistoryItem['VTE_NOME'],
'Data:': liberationHistoryItem['NOT_DTENVIO'],
@ -416,7 +416,7 @@ Widget liberationHistoryItemCard(
})
],
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${liberationHistoryItem['VTE_ID'] ?? ''}&tipo=E',
),
);
},

View File

@ -91,7 +91,7 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
@ -105,9 +105,9 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
setState(() => _loading = true);
var response = await PhpGroup.getMessagesCall.call(
devUUID: FFAppState().devUUID.toString(),
userUUID: FFAppState().userUUID.toString(),
cliID: FFAppState().cliUUID.toString(),
devUUID: AppState().devUUID.toString(),
userUUID: AppState().userUUID.toString(),
cliID: AppState().cliUUID.toString(),
atividade: 'getMensagens',
pageSize: _pageSize.toString(),
pageNumber: _pageNumber.toString(),

View File

@ -9,7 +9,6 @@ import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/people_on_the_property_page/people_on_the_property_page_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
@ -19,7 +18,6 @@ import 'package:provider/provider.dart';
import '../../shared/utils/dialog_util.dart';
import '../../shared/utils/log_util.dart';
class PeopleOnThePropertyPageWidget extends StatefulWidget {
const PeopleOnThePropertyPageWidget({super.key});
@ -49,7 +47,7 @@ class _PeopleOnThePropertyPageWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Scaffold(
key: scaffoldKey,
@ -93,10 +91,10 @@ class _PeopleOnThePropertyPageWidgetState
top: true,
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getPessoasLocalCall.call(
cliID: FFAppState().cliUUID,
ownID: FFAppState().ownerUUID,
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: AppState().cliUUID,
ownID: AppState().ownerUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
@ -115,7 +113,12 @@ class _PeopleOnThePropertyPageWidgetState
if (snapshot.hasError || snapshot.data?.exception != null) {
if (snapshot.error != null && snapshot.stackTrace != null) {
LogUtil.requestAPIFailed('getPessoasLocal.php', "", 'Busca Pessoas no Local', snapshot.error, snapshot.stackTrace!);
LogUtil.requestAPIFailed(
'getPessoasLocal.php',
"",
'Busca Pessoas no Local',
snapshot.error,
snapshot.stackTrace!);
}
return Center(
@ -124,9 +127,8 @@ class _PeopleOnThePropertyPageWidgetState
height: 100,
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: "Pessoas não encontradas",
enText: "Persons not found"
),
ptText: "Pessoas não encontradas",
enText: "Persons not found"),
textAlign: TextAlign.center,
),
),
@ -134,7 +136,12 @@ class _PeopleOnThePropertyPageWidgetState
}
final columnGetPessoasLocalResponse = snapshot.data!;
final getPoepleProperty = PhpGroup.getPessoasLocalCall.pessoas(columnGetPessoasLocalResponse.jsonBody,)?.toList() ?? [];
final getPoepleProperty = PhpGroup.getPessoasLocalCall
.pessoas(
columnGetPessoasLocalResponse.jsonBody,
)
?.toList() ??
[];
return ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
@ -170,7 +177,8 @@ class _PeopleOnThePropertyPageWidgetState
r'''$.USU_NOME''',
).toString(),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
fontFamily:
FlutterFlowTheme.of(context).bodyMediumFamily,
fontSize: 14.0,
letterSpacing: 0.0,
useGoogleFonts: GoogleFonts.asMap().containsKey(

View File

@ -24,9 +24,9 @@ class PreferencesPageModel with ChangeNotifier {
// })
// .whenComplete(() => notifyListeners()));
if (FFAppState().fingerprint) {
FFAppState().fingerprint = false;
FFAppState().deleteFingerprintPass();
if (AppState().fingerprint) {
AppState().fingerprint = false;
AppState().deleteFingerprintPass();
notifyListeners();
} else {
await showModalBottomSheet(
@ -39,8 +39,8 @@ class PreferencesPageModel with ChangeNotifier {
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().fingerprintPass = key;
FFAppState().fingerprint = true;
AppState().fingerprintPass = key;
AppState().fingerprint = true;
},
),
);
@ -88,8 +88,8 @@ class PreferencesPageModel with ChangeNotifier {
Share.share(
FFLocalizations.of(context).getVariableText(
ptText:
'Este é o meu identificador de acesso: ${FFAppState().userDevUUID}',
enText: 'This is my access identifier: ${FFAppState().userDevUUID}',
'Este é o meu identificador de acesso: ${AppState().userDevUUID}',
enText: 'This is my access identifier: ${AppState().userDevUUID}',
),
);
}
@ -102,19 +102,19 @@ class PreferencesPageModel with ChangeNotifier {
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
title: Text(
FFLocalizations.of(context).getVariableText(
enText: FFAppState().notify
enText: AppState().notify
? 'Disable Access Notification'
: 'Access Notification',
ptText: FFAppState().notify
ptText: AppState().notify
? 'Desativar notificação de acesso'
: 'Notificação de acesso'),
),
content: Text(
FFLocalizations.of(context).getVariableText(
ptText: FFAppState().notify
ptText: AppState().notify
? 'Tem certeza que deseja desativar as suas notificações de acesso?'
: 'Tem certeza que deseja receber as suas notificações de acesso?',
enText: FFAppState().notify
enText: AppState().notify
? 'Are you sure you want to disable your access notifications?'
: 'Are you sure you want to receive your access notifications?'),
),
@ -150,17 +150,17 @@ class PreferencesPageModel with ChangeNotifier {
try {
PhpGroup.changeNotifica
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliID: AppState().cliUUID,
atividade: 'updVisitado',
notifica: FFAppState().notify ? 'S' : 'N',
notifica: AppState().notify ? 'S' : 'N',
)
.then((value) {
if (value.jsonBody['error'] == false) {
Navigator.pop(context);
FFAppState().notify = !FFAppState().notify;
AppState().notify = !AppState().notify;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
@ -306,16 +306,16 @@ class PreferencesPageModel with ChangeNotifier {
try {
await PhpGroup.resopndeVinculo
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliID: AppState().cliUUID,
tarefa: 'I',
)
.then((value) {
if (value.jsonBody['error'] == false) {
FFAppState().deleteCliUUID();
FFAppState().deleteLocal();
FFAppState().deleteOwnerUUID();
AppState().deleteCliUUID();
AppState().deleteLocal();
AppState().deleteOwnerUUID();
Navigator.pop(context);
Navigator.pop(context);
@ -460,13 +460,13 @@ class PreferencesPageModel with ChangeNotifier {
try {
await PhpGroup.deleteAccount
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
)
.then((value) {
if (value.jsonBody['error'] == false) {
FFAppState().deleteAll();
FFAppState().isLogged = false;
AppState().deleteAll();
AppState().isLogged = false;
context.goNamed(
'welcomePage',
extra: <String, dynamic>{
@ -565,20 +565,20 @@ class PreferencesPageModel with ChangeNotifier {
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().accessPass = key;
AppState().accessPass = key;
notifyListeners();
await PhpGroup.changePass
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliID: AppState().cliUUID,
atividade: 'updVisitado',
newSenha: FFAppState().accessPass,
newSenha: AppState().accessPass,
)
.then((value) {
// var error = jsonDecode(value.jsonBody['error'].toString());
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().pass = true;
AppState().pass = true;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
@ -655,20 +655,20 @@ class PreferencesPageModel with ChangeNotifier {
padding: MediaQuery.viewInsetsOf(context),
child: PassKeyTemplateWidget(
toggleActionStatus: (key) async {
FFAppState().panicPass = key;
AppState().panicPass = key;
notifyListeners();
await PhpGroup.changePanic
.call(
userUUID: FFAppState().userUUID,
devUUID: FFAppState().devUUID,
cliID: FFAppState().cliUUID,
userUUID: AppState().userUUID,
devUUID: AppState().devUUID,
cliID: AppState().cliUUID,
atividade: 'updVisitado',
newSenhaPanico: FFAppState().panicPass,
newSenhaPanico: AppState().panicPass,
)
.then((value) {
FFAppState().panic = true;
AppState().panic = true;
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
FFAppState().panic = true;
AppState().panic = true;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(

View File

@ -101,7 +101,7 @@ class PreferencesPageWidget extends StatelessWidget {
icon = Icons.fingerprint;
onPressed = () =>
model.toggleFingerprint(context); // Disable if fingerprint is false
isEnabled = FFAppState().fingerprint;
isEnabled = AppState().fingerprint;
content = FFLocalizations.of(context).getVariableText(
ptText:
'Ative a autenticação por impressão digital para login seguro.',
@ -111,7 +111,7 @@ class PreferencesPageWidget extends StatelessWidget {
case 1:
icon = Icons.person;
onPressed = () => model.enablePerson(context);
isEnabled = FFAppState().person;
isEnabled = AppState().person;
content = FFLocalizations.of(context).getVariableText(
ptText: 'Compartilhe o código de identificação remota',
enText: 'Share the remote identification code',
@ -120,7 +120,7 @@ class PreferencesPageWidget extends StatelessWidget {
case 2:
icon = Icons.notifications;
onPressed = () => model.toggleNotify(context);
isEnabled = FFAppState().notify;
isEnabled = AppState().notify;
content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para receber sua notificação de acesso',
enText: 'Enable to receive your access notification',
@ -129,7 +129,7 @@ class PreferencesPageWidget extends StatelessWidget {
case 3:
icon = Icons.lock;
// onLongPress = model.togglePass(context, model);
isEnabled = FFAppState().pass;
isEnabled = AppState().pass;
content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para inserir uma credencial de acesso para o QRCode',
enText: 'Enable to enter an access credential for the QRCode',
@ -138,7 +138,7 @@ class PreferencesPageWidget extends StatelessWidget {
case 4:
icon = Icons.lock_clock_sharp;
// onLongPress = model.togglePass(context, model);
isEnabled = FFAppState().panic;
isEnabled = AppState().panic;
content = FFLocalizations.of(context).getVariableText(
ptText: 'Ative para inserir uma credencial de pânico para o QRCode',
enText: 'Enable to enter an panic credential for the QRCode',

View File

@ -145,14 +145,14 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
safeSetState(() async {
_resetAnimationAndToggleAccess();
});
FFAppState().fingerprint
AppState().fingerprint
? await _showBiometricsAuth(context)
: await _showQrCodeBottomSheet(context);
},
child: buildQrCode(
dimension: dimension,
errorCorrectLevel: QrErrorCorrectLevel.M,
identifier: FFAppState().userDevUUID,
identifier: AppState().userDevUUID,
pass: _model.key!,
direction: 5,
),
@ -200,7 +200,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
alignment: const AlignmentDirectional(0.0, 0.0),
child: FFButtonWidget(
onPressed: () async {
FFAppState().fingerprint
AppState().fingerprint
? await _showBiometricsAuth(context)
: await _showQrCodeBottomSheet(context);
},
@ -362,9 +362,9 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
}
Future<void> _showBiometricsAuth(BuildContext context) async {
FFAppState()
AppState()
.checkBiometrics()
.then((value) => FFAppState().authenticateBiometric().then((value) {
.then((value) => AppState().authenticateBiometric().then((value) {
safeSetState(() {
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
animationsMap['barcodeOnActionTriggerAnimation']!
@ -375,7 +375,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
.reverse();
}
_model.isAccess = !_model.isAccess;
_model.key = FFAppState().fingerprintPass;
_model.key = AppState().fingerprintPass;
});
}))
.onError((error, StackTrace) {

View File

@ -37,7 +37,7 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return Scaffold(
appBar: AppBar(
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,

View File

@ -64,7 +64,10 @@ class _ScheduleCompleteVisitPageWidgetState
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if ((widget.visitorStrList != null && widget.visitorStrList != '') && ((widget.visitorJsonList != null && (widget.visitorJsonList)!.isNotEmpty) != null)) {
if ((widget.visitorStrList != null && widget.visitorStrList != '') &&
((widget.visitorJsonList != null &&
(widget.visitorJsonList)!.isNotEmpty) !=
null)) {
_model.visitorJsonList = widget.visitorJsonList!
.where((e) =>
widget.visitorStrList ==
@ -82,7 +85,8 @@ class _ScheduleCompleteVisitPageWidgetState
return;
}
if ((widget.dropdownValue1 != null && widget.dropdownValue1 != '') && (widget.dropdownValue2 != null && widget.dropdownValue2 != '')) {
if ((widget.dropdownValue1 != null && widget.dropdownValue1 != '') &&
(widget.dropdownValue2 != null && widget.dropdownValue2 != '')) {
_model.dropDownValue1 = widget.dropdownValue1!;
_model.dropDownValue2 = widget.dropdownValue2!;
safeSetState(() {});
@ -145,7 +149,7 @@ class _ScheduleCompleteVisitPageWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return GestureDetector(
onTap: () => _model.unfocusNode.canRequestFocus
@ -864,7 +868,7 @@ Widget scheduleVisit(BuildContext context,
fadeOutDuration:
const Duration(milliseconds: 500),
imageUrl:
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(visitorListViewItem, r'''$.VTE_DOCUMENTO''').toString()}&tipo=E",
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(visitorListViewItem, r'''$.VTE_DOCUMENTO''').toString()}&tipo=E",
fit: BoxFit.cover,
),
),
@ -1078,9 +1082,9 @@ Widget scheduleVisit(BuildContext context,
decoration: const BoxDecoration(),
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getDadosCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliUUID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliUUID: AppState().cliUUID,
atividade: 'getDados',
),
builder: (context, snapshot) {
@ -1098,29 +1102,58 @@ Widget scheduleVisit(BuildContext context,
);
}
final dropDownGetDadosResponse = snapshot.data!;
final reasonsJsonList = PhpGroup.getDadosCall.reasonsJsonList(dropDownGetDadosResponse.jsonBody);
final dropDownGetDadosResponse =
snapshot.data!;
final reasonsJsonList =
PhpGroup.getDadosCall.reasonsJsonList(
dropDownGetDadosResponse.jsonBody);
if (_model.dropDownValue1 != '' && _model.dropDownValue1 != null) {
String value = _model.dropDownValue1.toString() ?? '';
if (_model.dropDownValue1 != '' &&
_model.dropDownValue1 != null) {
String value =
_model.dropDownValue1.toString() ??
'';
if (value.contains('{') && value.contains('}') && value.contains(':')) {
if (value.contains('{') &&
value.contains('}') &&
value.contains(':')) {
// log("Valor e um Objeto | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
} else {
// log("Valor e uma String | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
if (reasonsJsonList != null && reasonsJsonList.isNotEmpty) {
var item = reasonsJsonList.where((reason) => reason['MOT_DESCRICAO'].toString().contains(_model.dropDownValue1 ?? ''));
_model.dropDownValue1 = item.firstOrNull.toString() ?? '';
if (reasonsJsonList != null &&
reasonsJsonList.isNotEmpty) {
var item = reasonsJsonList.where(
(reason) =>
reason['MOT_DESCRICAO']
.toString()
.contains(_model
.dropDownValue1 ??
''));
_model.dropDownValue1 =
item.firstOrNull.toString() ?? '';
}
}
}
return FlutterFlowDropDown<String>(
fillColor: FlutterFlowTheme.of(context).primaryBackground,
controller: _model.dropDownValueController1 ??= FormFieldController<String>(_model.dropDownValue1 ??= ''),
options: reasonsJsonList != null && reasonsJsonList != [] ? reasonsJsonList.map((e) => e.toString()).toList() : [],
optionLabels: PhpGroup.getDadosCall.reasonsMotDescStrList(dropDownGetDadosResponse.jsonBody),
onChanged: (val) => safeSetState(() => _model.dropDownValue1 = val),
fillColor: FlutterFlowTheme.of(context)
.primaryBackground,
controller:
_model.dropDownValueController1 ??=
FormFieldController<String>(
_model.dropDownValue1 ??= ''),
options: reasonsJsonList != null &&
reasonsJsonList != []
? reasonsJsonList
.map((e) => e.toString())
.toList()
: [],
optionLabels: PhpGroup.getDadosCall
.reasonsMotDescStrList(
dropDownGetDadosResponse
.jsonBody),
onChanged: (val) => safeSetState(
() => _model.dropDownValue1 = val),
width: double.infinity,
height: double.infinity,
textStyle: FlutterFlowTheme.of(context)
@ -1202,9 +1235,9 @@ Widget scheduleVisit(BuildContext context,
decoration: const BoxDecoration(),
child: FutureBuilder<ApiCallResponse>(
future: PhpGroup.getDadosCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliUUID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliUUID: AppState().cliUUID,
atividade: 'getDados',
),
builder: (context, snapshot) {
@ -1223,28 +1256,55 @@ Widget scheduleVisit(BuildContext context,
);
}
final dropDownGetDadosResponse = snapshot.data!;
final lavelList = PhpGroup.getDadosCall.levelJsonList(dropDownGetDadosResponse.jsonBody);
final dropDownGetDadosResponse =
snapshot.data!;
final lavelList = PhpGroup.getDadosCall
.levelJsonList(
dropDownGetDadosResponse.jsonBody);
if (_model.dropDownValue2 != '' && _model.dropDownValue2 != null) {
String value = _model.dropDownValue2.toString() ?? '';
if (_model.dropDownValue2 != '' &&
_model.dropDownValue2 != null) {
String value =
_model.dropDownValue2.toString() ??
'';
if (value.contains('{') && value.contains('}') && value.contains(':')) {
if (value.contains('{') &&
value.contains('}') &&
value.contains(':')) {
// log("Valor e um Objeto | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
} else {
// log("Valor e uma String | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
if (lavelList != null && lavelList.isNotEmpty) {
var item = lavelList.where((level) => level['NAC_DESCRICAO'].toString().contains(_model.dropDownValue2 ?? ''));
_model.dropDownValue2 = item.firstOrNull.toString() ?? '';
if (lavelList != null &&
lavelList.isNotEmpty) {
var item = lavelList.where((level) =>
level['NAC_DESCRICAO']
.toString()
.contains(
_model.dropDownValue2 ??
''));
_model.dropDownValue2 =
item.firstOrNull.toString() ?? '';
}
}
}
return FlutterFlowDropDown<String>(
controller: _model.dropDownValueController2 ??= FormFieldController<String>(_model.dropDownValue2 ??= ''),
options: lavelList != null && lavelList != [] ? lavelList.map((e) => e.toString()).toList() : [],
optionLabels: PhpGroup.getDadosCall.levelNACDescricaoStrList(dropDownGetDadosResponse.jsonBody),
onChanged: (val) => safeSetState(() => _model.dropDownValue2 = val),
controller:
_model.dropDownValueController2 ??=
FormFieldController<String>(
_model.dropDownValue2 ??= ''),
options:
lavelList != null && lavelList != []
? lavelList
.map((e) => e.toString())
.toList()
: [],
optionLabels: PhpGroup.getDadosCall
.levelNACDescricaoStrList(
dropDownGetDadosResponse
.jsonBody),
onChanged: (val) => safeSetState(
() => _model.dropDownValue2 = val),
width: double.infinity,
height: double.infinity,
textStyle: FlutterFlowTheme.of(context)
@ -1552,7 +1612,6 @@ Widget scheduleVisit(BuildContext context,
),
onPressed: _model.isValid()
? () async {
await showDialog(
context: context,
builder: (context) {
@ -1605,8 +1664,8 @@ Widget scheduleVisit(BuildContext context,
), () async {
await PhpGroup.postScheduleVisitCall
.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
atividade: 'putVisita',
devDesc: _model.textController3.text,
idVisitante: _model.visitorStrList,
@ -1622,7 +1681,7 @@ Widget scheduleVisit(BuildContext context,
idNAC: extractIdToStr(
_model.dropDownValue2!),
obs: _model.textController3.text,
cliID: FFAppState().cliUUID,
cliID: AppState().cliUUID,
)
.catchError((e) async {
await DialogUtil.errorDefault(context);
@ -1676,7 +1735,7 @@ Widget scheduleVisit(BuildContext context,
),
],
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${_model.visitorJsonList[0]['VTE_DOCUMENTO'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${_model.visitorJsonList[0]['VTE_DOCUMENTO'] ?? ''}&tipo=E',
labelsHashMap: {
'Nome': _model.visitorJsonList[0]['VTE_NOME'],
'Start': _model.textController1.text,

View File

@ -17,7 +17,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:hub/pages/schedule_provisional_visit_page/schedule_provisional_visit_page_model.dart';
import 'package:provider/provider.dart';
class ScheduleProvisionalVisitPageWidget extends StatefulWidget {
const ScheduleProvisionalVisitPageWidget({super.key});
@ -55,7 +54,8 @@ class _ScheduleProvisionalVisitPageWidgetState
}
bool _isFormValid() {
if (_model.personNameTextController.text == '' || _model.personNameTextController.text.length > 80) {
if (_model.personNameTextController.text == '' ||
_model.personNameTextController.text.length > 80) {
return false;
}
@ -68,7 +68,7 @@ class _ScheduleProvisionalVisitPageWidgetState
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
@ -161,10 +161,12 @@ class _ScheduleProvisionalVisitPageWidgetState
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Align(
alignment: const AlignmentDirectional(-1.0, 0.0),
alignment:
const AlignmentDirectional(-1.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 0.0, 0.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 0.0, 0.0),
child: Text(
FFLocalizations.of(context).getText(
'8d3679lf' /* Propriedade */,
@ -210,7 +212,8 @@ class _ScheduleProvisionalVisitPageWidgetState
MainAxisAlignment.start,
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
borderRadius:
const BorderRadius.only(
bottomLeft: Radius.circular(50.0),
bottomRight:
Radius.circular(50.0),
@ -218,12 +221,12 @@ class _ScheduleProvisionalVisitPageWidgetState
topRight: Radius.circular(50.0),
),
child: CachedNetworkImage(
fadeInDuration:
const Duration(milliseconds: 200),
fadeOutDuration:
const Duration(milliseconds: 200),
fadeInDuration: const Duration(
milliseconds: 200),
fadeOutDuration: const Duration(
milliseconds: 200),
imageUrl:
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
'https://freaccess.com.br/freaccess/Images/Clients/${AppState().cliUUID}.png',
width: 35.0,
height: 35.0,
fit: BoxFit.contain,
@ -232,11 +235,10 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
15.0, 0.0, 0.0, 0.0),
padding: const EdgeInsetsDirectional
.fromSTEB(15.0, 0.0, 0.0, 0.0),
child: Text(
FFAppState().local,
AppState().local,
style:
FlutterFlowTheme.of(context)
.bodyMedium
@ -272,10 +274,12 @@ class _ScheduleProvisionalVisitPageWidgetState
MainAxisAlignment.spaceEvenly,
children: [
Align(
alignment: const AlignmentDirectional(-1.0, 0.0),
alignment:
const AlignmentDirectional(-1.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
24.0, 10.0, 0.0, 10.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 10.0, 0.0, 10.0),
child: Text(
FFLocalizations.of(context).getText(
'z6aawgqa' /* Dados da Visita */,
@ -303,12 +307,11 @@ class _ScheduleProvisionalVisitPageWidgetState
Container(
height: 80.0,
decoration: const BoxDecoration(),
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
24.0, 0.0, 24.0, 0.0),
padding: const EdgeInsetsDirectional
.fromSTEB(24.0, 0.0, 24.0, 0.0),
child: SizedBox(
width: double.infinity,
child: TextFormField(
@ -319,7 +322,8 @@ class _ScheduleProvisionalVisitPageWidgetState
onChanged: (_) =>
EasyDebounce.debounce(
'_model.personNameTextController',
const Duration(milliseconds: 500),
const Duration(
milliseconds: 500),
() => setState(() {}),
),
autofocus: false,
@ -463,12 +467,13 @@ class _ScheduleProvisionalVisitPageWidgetState
SizedBox(
height: 80.0,
child: Stack(
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
children: [
Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: TextFormField(
controller: _model
@ -478,7 +483,8 @@ class _ScheduleProvisionalVisitPageWidgetState
onChanged: (_) =>
EasyDebounce.debounce(
'_model.dateTimeTextController',
const Duration(milliseconds: 500),
const Duration(
milliseconds: 500),
() => setState(() {}),
),
readOnly: true,
@ -590,8 +596,9 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: InkWell(
splashColor: Colors.transparent,
@ -787,24 +794,28 @@ class _ScheduleProvisionalVisitPageWidgetState
],
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0.0, 10.0, 0.0, 10.0),
padding:
const EdgeInsetsDirectional.fromSTEB(
0.0, 10.0, 0.0, 10.0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment:
const AlignmentDirectional(0.0, 0.0),
alignment: const AlignmentDirectional(
0.0, 0.0),
child: Container(
decoration: const BoxDecoration(),
alignment:
const AlignmentDirectional(0.0, 0.0),
const AlignmentDirectional(
0.0, 0.0),
child: Align(
alignment: const AlignmentDirectional(
0.0, 0.0),
alignment:
const AlignmentDirectional(
0.0, 0.0),
child: Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(
padding:
const EdgeInsetsDirectional
.fromSTEB(
24.0, 0.0, 24.0, 0.0),
child: SizedBox(
width: double.infinity,
@ -961,51 +972,71 @@ class _ScheduleProvisionalVisitPageWidgetState
),
),
FFButtonWidget(
onPressed: !_isFormValid() ? null : () async {
onPressed: !_isFormValid()
? null
: () async {
try {
_model.provVisitSchedule = await PhpGroup
.postProvVisitSchedulingCall
.call(
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'putAgendamentoProv',
data:
_model.dateTimeTextController.text,
motivo: _model.notesTextController.text,
nome: _model
.personNameTextController.text,
proID: AppState().ownerUUID,
);
try {
_model.provVisitSchedule = await PhpGroup.postProvVisitSchedulingCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
atividade: 'putAgendamentoProv',
data: _model.dateTimeTextController.text,
motivo: _model.notesTextController.text,
nome: _model.personNameTextController.text,
proID: FFAppState().ownerUUID,
);
if (PhpGroup.postProvVisitSchedulingCall
.error((_model.provVisitSchedule
?.jsonBody ??
'')) ==
false) {
DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
ptText:
"Agendamento Provisório Realizado com Sucesso!",
enText:
"Provisional Scheduling Successfully Completed"));
setState(() {
_model.dateTimeTextController
?.clear();
_model.personNameTextController
?.clear();
_model.notesTextController?.clear();
});
} else {
var message = PhpGroup
.postProvVisitSchedulingCall
.msg((_model.provVisitSchedule
?.jsonBody ??
''));
if (message != null) {
DialogUtil.error(context, message);
} else {
DialogUtil.errorDefault(context);
}
}
if (PhpGroup.postProvVisitSchedulingCall.error((_model.provVisitSchedule?.jsonBody ?? '')) == false) {
DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
ptText: "Agendamento Provisório Realizado com Sucesso!",
enText: "Provisional Scheduling Successfully Completed"
)
);
setState(() {
_model.dateTimeTextController?.clear();
_model.personNameTextController?.clear();
_model.notesTextController?.clear();
});
} else {
var message = PhpGroup.postProvVisitSchedulingCall.msg((_model.provVisitSchedule?.jsonBody ?? ''));
if (message != null) {
DialogUtil.error(context, message);
} else {
DialogUtil.errorDefault(context);
}
}
setState(() {});
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed("processRequest.php", "", "Cadastrar Visita Provisória", e, s);
}
},
setState(() {});
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed(
"processRequest.php",
"",
"Cadastrar Visita Provisória",
e,
s);
}
},
showLoadingIndicator: true,
text: FFLocalizations.of(context).getText('bv5fg9sv' /* Enviar */),
text: FFLocalizations.of(context)
.getText('bv5fg9sv' /* Enviar */),
options: FFButtonOptions(
width: 150.0,
height: 50.0,

View File

@ -36,9 +36,9 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget> {
try {
var response = await ScheduleCompleteVisitPageModel().visitHistory(
requestFn: () => PhpGroup.getVisitsCall.call(
devUUID: FFAppState().devUUID,
userUUID: FFAppState().userUUID,
cliID: FFAppState().cliUUID,
devUUID: AppState().devUUID,
userUUID: AppState().userUUID,
cliID: AppState().cliUUID,
atividade: 'getVisitas',
pageSize: 10,
pageNumber: pageNumber,
@ -113,7 +113,7 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget> {
return CardItemTemplateComponentWidget(
imagePath:
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
labelsHashMap: {
'Nome:': visitaWrapItem['VTE_NOME'] ?? '',
'Inicio:': visitaWrapItem['VAW_DTINICIO'] ?? '',

View File

@ -28,13 +28,13 @@ class _WelcomePageWidgetState extends State<WelcomePageWidget> {
// On page load action.
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (isAndroid == true) {
FFAppState().device = 'Android';
AppState().device = 'Android';
setState(() {});
} else if (isiOS == true) {
FFAppState().device = 'iOS';
AppState().device = 'iOS';
setState(() {});
} else {
FFAppState().device = 'Web';
AppState().device = 'Web';
setState(() {});
}
});
@ -49,7 +49,7 @@ class _WelcomePageWidgetState extends State<WelcomePageWidget> {
@override
Widget build(BuildContext context) {
context.watch<FFAppState>();
context.watch<AppState>();
return GestureDetector(
onTap: () => _model.unfocusNode.canRequestFocus

14151
log

File diff suppressed because one or more lines are too long