WIP
This commit is contained in:
parent
9ffb3270e6
commit
460ad3bbbd
|
@ -112,23 +112,23 @@ Future singInLoginAction(
|
||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
Future(() async {
|
Future(() async {
|
||||||
FFAppState().email = emailAdress!;
|
AppState().email = emailAdress!;
|
||||||
}),
|
}),
|
||||||
Future(() async {
|
Future(() async {
|
||||||
FFAppState().passwd = password!;
|
AppState().passwd = password!;
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ((FFAppState().email != '') && (FFAppState().passwd != '')) {
|
if ((AppState().email != '') && (AppState().passwd != '')) {
|
||||||
devUUID = await getDevUUID();
|
devUUID = await getDevUUID();
|
||||||
|
|
||||||
FFAppState().devUUID = devUUID!;
|
AppState().devUUID = devUUID!;
|
||||||
|
|
||||||
loginCall = await PhpGroup.loginCall.call(
|
loginCall = await PhpGroup.loginCall.call(
|
||||||
email: FFAppState().email,
|
email: AppState().email,
|
||||||
password: FFAppState().passwd,
|
password: AppState().passwd,
|
||||||
uuid: FFAppState().devUUID,
|
uuid: AppState().devUUID,
|
||||||
type: FFAppState().device,
|
type: AppState().device,
|
||||||
description: randomString(
|
description: randomString(
|
||||||
10,
|
10,
|
||||||
10,
|
10,
|
||||||
|
@ -139,30 +139,30 @@ Future singInLoginAction(
|
||||||
);
|
);
|
||||||
|
|
||||||
if (PhpGroup.loginCall.error((loginCall.jsonBody ?? '')) == false) {
|
if (PhpGroup.loginCall.error((loginCall.jsonBody ?? '')) == false) {
|
||||||
FFAppState().userUUID = PhpGroup.loginCall.userUUID(
|
AppState().userUUID = PhpGroup.loginCall.userUUID(
|
||||||
(loginCall.jsonBody ?? ''),
|
(loginCall.jsonBody ?? ''),
|
||||||
)!;
|
)!;
|
||||||
|
|
||||||
FFAppState().createdAt = dateTimeFormat(
|
AppState().createdAt = dateTimeFormat(
|
||||||
'd/M/y H:mm:ss',
|
'd/M/y H:mm:ss',
|
||||||
getCurrentTimestamp,
|
getCurrentTimestamp,
|
||||||
locale: FFLocalizations.of(context).languageCode,
|
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 ?? ''))!;
|
PhpGroup.loginCall.userStatus((loginCall.jsonBody ?? ''))!;
|
||||||
|
|
||||||
FFAppState().userDevUUID =
|
AppState().userDevUUID =
|
||||||
PhpGroup.loginCall.userDeviceId((loginCall.jsonBody ?? ''))!;
|
PhpGroup.loginCall.userDeviceId((loginCall.jsonBody ?? ''))!;
|
||||||
|
|
||||||
FFAppState().name =
|
AppState().name =
|
||||||
PhpGroup.loginCall.userName((loginCall.jsonBody ?? ''))!;
|
PhpGroup.loginCall.userName((loginCall.jsonBody ?? ''))!;
|
||||||
|
|
||||||
FFAppState().serialNumber = await getSerialNumber() ?? '';
|
AppState().serialNumber = await getSerialNumber() ?? '';
|
||||||
|
|
||||||
FFAppState().isLogged = true;
|
AppState().isLogged = true;
|
||||||
|
|
||||||
await toggleHomePage(context);
|
await toggleHomePage(context);
|
||||||
} else {
|
} else {
|
||||||
|
@ -173,13 +173,13 @@ Future singInLoginAction(
|
||||||
PhpGroup.loginCall.msg((loginCall?.jsonBody ?? '')).toString());
|
PhpGroup.loginCall.msg((loginCall?.jsonBody ?? '')).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
FFAppState().deleteEmail();
|
AppState().deleteEmail();
|
||||||
FFAppState().email = '';
|
AppState().email = '';
|
||||||
|
|
||||||
FFAppState().deletePasswd();
|
AppState().deletePasswd();
|
||||||
FFAppState().passwd = '';
|
AppState().passwd = '';
|
||||||
|
|
||||||
FFAppState().update(() {});
|
AppState().update(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,15 +271,15 @@ Future forgotPasswdAction(
|
||||||
}
|
}
|
||||||
|
|
||||||
Future cachingLoginActionApp(BuildContext context) async {
|
Future cachingLoginActionApp(BuildContext context) async {
|
||||||
if (FFAppState().isLogged == true) {
|
if (AppState().isLogged == true) {
|
||||||
context.pushNamed('homePage');
|
context.pushNamed('homePage');
|
||||||
} else {
|
} else {
|
||||||
if (isAndroid == true) {
|
if (isAndroid == true) {
|
||||||
FFAppState().device = 'Android';
|
AppState().device = 'Android';
|
||||||
} else if (isiOS == true) {
|
} else if (isiOS == true) {
|
||||||
FFAppState().device = 'iOS';
|
AppState().device = 'iOS';
|
||||||
} else {
|
} else {
|
||||||
FFAppState().device = 'Web';
|
AppState().device = 'Web';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,9 +328,9 @@ Future<bool> visitCancelAction(BuildContext context,
|
||||||
ApiCallResponse? apiCallResponse;
|
ApiCallResponse? apiCallResponse;
|
||||||
|
|
||||||
apiCallResponse = await PhpGroup.cancelaVisita.call(
|
apiCallResponse = await PhpGroup.cancelaVisita.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'cancelaVisita',
|
atividade: 'cancelaVisita',
|
||||||
idDestino: idDestino,
|
idDestino: idDestino,
|
||||||
idVisita: idVisita,
|
idVisita: idVisita,
|
||||||
|
@ -381,8 +381,8 @@ Future<bool> checkLocals({
|
||||||
}) async {
|
}) async {
|
||||||
// A chamada para a API permanece a mesma, assumindo que é necessária sempre.
|
// A chamada para a API permanece a mesma, assumindo que é necessária sempre.
|
||||||
final response = await PhpGroup.getLocalsCall.call(
|
final response = await PhpGroup.getLocalsCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verificação rápida de erro para evitar processamento desnecessário.
|
// 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.
|
// 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(
|
final bool itemFound = response.jsonBody['locais'].any(
|
||||||
(local) => local['CLI_ID'] == uuid && local['CLU_STATUS'] == "A",
|
(local) => local['CLI_ID'] == uuid && local['CLU_STATUS'] == "A",
|
||||||
);
|
);
|
||||||
|
@ -427,9 +427,9 @@ Future answersRequest(BuildContext context, String? ref, String? task,
|
||||||
ApiCallResponse? respondeSolicitacaoCall;
|
ApiCallResponse? respondeSolicitacaoCall;
|
||||||
|
|
||||||
respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call(
|
respondeSolicitacaoCall = await PhpGroup.respondeSolicitacaoCall.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'respondeSolicitacao',
|
atividade: 'respondeSolicitacao',
|
||||||
referencia: ref,
|
referencia: ref,
|
||||||
tarefa: task,
|
tarefa: task,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// import 'dart:ffi';
|
// import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:csv/csv.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:csv/csv.dart';
|
|
||||||
import 'package:local_auth/local_auth.dart';
|
import 'package:local_auth/local_auth.dart';
|
||||||
import 'package:synchronized/synchronized.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
|
// Adiciona a variável para controle de autenticação biométrica
|
||||||
bool _isBiometricAuthenticated = false;
|
bool _isBiometricAuthenticated = false;
|
||||||
bool get isBiometricAuthenticated => _isBiometricAuthenticated;
|
bool get isBiometricAuthenticated => _isBiometricAuthenticated;
|
||||||
|
@ -57,16 +57,16 @@ class FFAppState extends ChangeNotifier {
|
||||||
// Limpar a informação salva, se necessário
|
// Limpar a informação salva, se necessário
|
||||||
}
|
}
|
||||||
|
|
||||||
static FFAppState _instance = FFAppState._internal();
|
static AppState _instance = AppState._internal();
|
||||||
|
|
||||||
factory FFAppState() {
|
factory AppState() {
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
FFAppState._internal();
|
AppState._internal();
|
||||||
|
|
||||||
static void reset() {
|
static void reset() {
|
||||||
_instance = FFAppState._internal();
|
_instance = AppState._internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future initializePersistedState() async {
|
Future initializePersistedState() async {
|
||||||
|
@ -150,6 +150,9 @@ class FFAppState extends ChangeNotifier {
|
||||||
_fingerprintPass =
|
_fingerprintPass =
|
||||||
await secureStorage.getString('fingerprintPass') ?? _fingerprintPass;
|
await secureStorage.getString('fingerprintPass') ?? _fingerprintPass;
|
||||||
});
|
});
|
||||||
|
await _safeInitAsync(() async {
|
||||||
|
_context = await secureStorage.getObject('ff_context') ?? _context;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(VoidCallback callback) {
|
void update(VoidCallback callback) {
|
||||||
|
@ -159,6 +162,17 @@ class FFAppState extends ChangeNotifier {
|
||||||
|
|
||||||
late FlutterSecureStorage secureStorage;
|
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 _panicOPT = false;
|
||||||
bool get panic => _panicOPT;
|
bool get panic => _panicOPT;
|
||||||
set panic(bool value) {
|
set panic(bool value) {
|
||||||
|
@ -481,6 +495,14 @@ extension FlutterSecureStorageExtensions on FlutterSecureStorage {
|
||||||
Future<void> setDouble(String key, double value) async =>
|
Future<void> setDouble(String key, double value) async =>
|
||||||
await writeSync(key: key, value: value.toString());
|
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 =>
|
Future<List<String>?> getStringList(String key) async =>
|
||||||
await read(key: key).then((result) {
|
await read(key: key).then((result) {
|
||||||
if (result == null || result.isEmpty) {
|
if (result == null || result.isEmpty) {
|
||||||
|
|
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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',
|
||||||
|
);
|
||||||
|
}
|
|
@ -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,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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',
|
||||||
|
};
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +1,36 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.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/material.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:hub/actions/actions.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_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/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/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/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_icon_button.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_theme.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_util.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
|
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
|
||||||
import 'package:hub/flutter_flow/internationalization.dart';
|
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
class PushNotificationService {
|
class PushNotificationService {
|
||||||
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
|
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
|
||||||
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
||||||
FlutterLocalNotificationsPlugin();
|
FlutterLocalNotificationsPlugin();
|
||||||
final Subject<RemoteMessage> _onMessage = BehaviorSubject<RemoteMessage>();
|
final BehaviorSubject<RemoteMessage> _onMessage =
|
||||||
final BehaviorSubject<BuildContext> _context =
|
BehaviorSubject<RemoteMessage>();
|
||||||
BehaviorSubject<BuildContext>();
|
|
||||||
final BehaviorSubject<Map<String, dynamic>> _notificationDetails =
|
final BehaviorSubject<Map<String, dynamic>> _notificationDetails =
|
||||||
BehaviorSubject<Map<String, dynamic>>();
|
BehaviorSubject<Map<String, dynamic>>();
|
||||||
|
|
||||||
PushNotificationService() {
|
PushNotificationService() {
|
||||||
_initializeLocalNotifications(_context);
|
_initializeFirebase();
|
||||||
|
_initializeLocalNotifications();
|
||||||
_createNotificationChannels();
|
_createNotificationChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +38,21 @@ class PushNotificationService {
|
||||||
return _onMessage;
|
return _onMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initialize(BuildContext context) async {
|
Future<void> _initializeFirebase() async {
|
||||||
_context.add(context);
|
// await Firebase.initializeApp(
|
||||||
|
// options: DefaultFirebaseOptions.currentPlatform);
|
||||||
|
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) =>
|
||||||
|
_firebaseMessagingBackgroundHandler(
|
||||||
|
message, _flutterLocalNotificationsPlugin));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initialize() async {
|
||||||
await _requestPermissions();
|
await _requestPermissions();
|
||||||
_listenToForegroundMessages(context);
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_listenToForegroundMessages();
|
||||||
_listenToBackgroundMessages();
|
_listenToBackgroundMessages();
|
||||||
_listenToNotificationClicks(context);
|
_listenToNotificationClicks();
|
||||||
|
});
|
||||||
await updateDeviceToken();
|
await updateDeviceToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,21 +63,22 @@ class PushNotificationService {
|
||||||
sound: true,
|
sound: true,
|
||||||
);
|
);
|
||||||
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
|
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) {
|
if (jsonString == null || jsonString.isEmpty) {
|
||||||
return {};
|
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(
|
String correctedJson = jsonString.replaceAllMapped(
|
||||||
RegExp(r'([a-zA-Z0-9_]+)\s*:\s*([^",\}\]]+)'), (match) {
|
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();
|
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) &&
|
bool isStringValue = !RegExp(r'^-?\d+(\.\d+)?$').hasMatch(value) &&
|
||||||
value != 'true' &&
|
value != 'true' &&
|
||||||
value != 'false' &&
|
value != 'false' &&
|
||||||
|
@ -82,36 +86,33 @@ class PushNotificationService {
|
||||||
!value.startsWith('{') &&
|
!value.startsWith('{') &&
|
||||||
!value.endsWith('}');
|
!value.endsWith('}');
|
||||||
|
|
||||||
// Adiciona aspas duplas em torno do valor se for uma string
|
|
||||||
String quotedValue = isStringValue ? '"$value"' : value;
|
String quotedValue = isStringValue ? '"$value"' : value;
|
||||||
|
|
||||||
return '$key: $quotedValue';
|
return '$key: $quotedValue';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Passo 3: Tratar corretamente strings JSON aninhadas
|
|
||||||
correctedJson =
|
correctedJson =
|
||||||
correctedJson.replaceAllMapped(RegExp(r'"{([^"]+)}"'), (match) {
|
correctedJson.replaceAllMapped(RegExp(r'"{([^"]+)}"'), (match) {
|
||||||
// Remove as aspas duplas extras em torno de objetos JSON aninhados
|
|
||||||
return '{${match[1]!}}';
|
return '{${match[1]!}}';
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Passo 4: Decodificar o JSON corrigido
|
|
||||||
return jsonDecode(correctedJson);
|
return jsonDecode(correctedJson);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initializeLocalNotifications(
|
void _initializeLocalNotifications() async {
|
||||||
BehaviorSubject<BuildContext> context) async {
|
try {
|
||||||
while (context.valueOrNull == null) {
|
while (AppState().context == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
}
|
}
|
||||||
|
log("Context: ${AppState().context}");
|
||||||
var initializationSettingsAndroid =
|
var initializationSettingsAndroid =
|
||||||
AndroidInitializationSettings('mipmap/ic_fre_black');
|
const AndroidInitializationSettings('mipmap/ic_fre_black');
|
||||||
var initializationSettingsIOS = DarwinInitializationSettings(
|
|
||||||
|
var initializationSettingsIOS = const DarwinInitializationSettings(
|
||||||
requestAlertPermission: true,
|
requestAlertPermission: true,
|
||||||
requestBadgePermission: true,
|
requestBadgePermission: true,
|
||||||
requestSoundPermission: true,
|
requestSoundPermission: true,
|
||||||
|
@ -122,16 +123,31 @@ class PushNotificationService {
|
||||||
);
|
);
|
||||||
_flutterLocalNotificationsPlugin.initialize(
|
_flutterLocalNotificationsPlugin.initialize(
|
||||||
initializationSettings,
|
initializationSettings,
|
||||||
onDidReceiveNotificationResponse: (NotificationResponse response) async {
|
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) {
|
if (response.payload != null) {
|
||||||
try {
|
try {
|
||||||
Map<String, dynamic> message = validJsonFromString(response.payload!);
|
Map<String, dynamic> message =
|
||||||
var data = _notificationDetails; // Assuming getOnMessage() now returns the latest RemoteMessage
|
validJsonFromString(response.payload ?? '');
|
||||||
_handleNotificationClick(message, extra: data.value);
|
var data = _notificationDetails.value;
|
||||||
} catch (e) {}
|
_handleNotificationClick(message, extra: data);
|
||||||
|
} catch (e) {
|
||||||
|
log('Error handling background notification: $e');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createNotificationChannels() {
|
void _createNotificationChannels() {
|
||||||
|
@ -144,41 +160,48 @@ class PushNotificationService {
|
||||||
'miscellaneous'
|
'miscellaneous'
|
||||||
];
|
];
|
||||||
for (String action in actions) {
|
for (String action in actions) {
|
||||||
_createNotificationChannel(action, "Channel for $action");
|
_createNotificationChannel('channel_$action', "channel_$action");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createNotificationChannel(String channelId, String channelName) {
|
void _createNotificationChannel(String channelId, String channelName) {
|
||||||
_flutterLocalNotificationsPlugin
|
final androidNotificationChannel = AndroidNotificationChannel(
|
||||||
.resolvePlatformSpecificImplementation<
|
channelId,
|
||||||
AndroidFlutterLocalNotificationsPlugin>()
|
channelName,
|
||||||
?.createNotificationChannel(
|
|
||||||
AndroidNotificationChannel(
|
|
||||||
channelId, // Use o click_action como ID do canal
|
|
||||||
channelName, // Nome descritivo baseado no click_action
|
|
||||||
description: 'Channel for $channelName notifications',
|
description: 'Channel for $channelName notifications',
|
||||||
importance: Importance.max,
|
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) {
|
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||||
log("Message Foregroud: ${message.data}");
|
log("Message Foreground: ${message.data}");
|
||||||
_onMessage.add(message);
|
_onMessage.add(message);
|
||||||
_notificationDetails.add(message.toMap()['notification']);
|
_notificationDetails.add(message.toMap()['notification']);
|
||||||
_showNotification(message);
|
_showNotification(message);
|
||||||
|
}).onError((error) {
|
||||||
|
log("Error listening to foreground messages: $error");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenToBackgroundMessages() {
|
void _listenToBackgroundMessages() {
|
||||||
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) =>
|
||||||
|
_firebaseMessagingBackgroundHandler(
|
||||||
|
message, _flutterLocalNotificationsPlugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenToNotificationClicks(BuildContext context) {
|
void _listenToNotificationClicks() {
|
||||||
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
|
FirebaseMessaging.onMessageOpenedApp
|
||||||
_onMessage.add(message);
|
.listen((RemoteMessage message) => _firebaseMessagingBackgroundHandler)
|
||||||
NotificationHandler().handleMessage(message.data, context);
|
.onError((err) {
|
||||||
|
log("Error listening to notification clicks: $err");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +212,13 @@ class PushNotificationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateToken(String token) async {
|
Future<void> _updateToken(String token) async {
|
||||||
FFAppState().token = token;
|
AppState().token = token;
|
||||||
final ApiCallResponse? response = await _updateTokenOnServer(token);
|
final ApiCallResponse? response = await _updateTokenOnServer(token);
|
||||||
if (_isTokenUpdateSuccessful(response)) {
|
if (_isTokenUpdateSuccessful(response)) {
|
||||||
} else {}
|
log('Token update successful');
|
||||||
|
} else {
|
||||||
|
log('Token update failed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleTokenUpdate(String newToken) async {
|
Future<void> _handleTokenUpdate(String newToken) async {
|
||||||
|
@ -209,7 +235,9 @@ class PushNotificationService {
|
||||||
final String? deviceToken = await _firebaseMessaging.getToken();
|
final String? deviceToken = await _firebaseMessaging.getToken();
|
||||||
if (deviceToken != null) {
|
if (deviceToken != null) {
|
||||||
await _updateToken(deviceToken);
|
await _updateToken(deviceToken);
|
||||||
} else {}
|
} else {
|
||||||
|
log('Failed to get device token');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<NotificationSettings> _requestNotificationPermission() async {
|
Future<NotificationSettings> _requestNotificationPermission() async {
|
||||||
|
@ -233,8 +261,8 @@ class PushNotificationService {
|
||||||
Future<ApiCallResponse?> _updateTokenOnServer(String deviceToken) async {
|
Future<ApiCallResponse?> _updateTokenOnServer(String deviceToken) async {
|
||||||
return await PhpGroup.updToken.call(
|
return await PhpGroup.updToken.call(
|
||||||
token: deviceToken,
|
token: deviceToken,
|
||||||
devid: FFAppState().devUUID,
|
devid: AppState().devUUID,
|
||||||
useruuid: FFAppState().userUUID,
|
useruuid: AppState().userUUID,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,53 +275,81 @@ class PushNotificationService {
|
||||||
return 'channel_$baseId';
|
return 'channel_$baseId';
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showNotification(RemoteMessage message) async {
|
Future<void> _showNotification(RemoteMessage message) async {
|
||||||
String channelId =
|
final String channelId = 'high_importance_channel';
|
||||||
_getChannelIdBasedOnClickAction(message.data['click_action']);
|
final AndroidNotificationDetails androidDetails =
|
||||||
|
AndroidNotificationDetails(
|
||||||
var androidDetails = AndroidNotificationDetails(
|
|
||||||
channelId,
|
channelId,
|
||||||
'Channel Name for $channelId',
|
'High Importance Notifications',
|
||||||
channelDescription: 'Channel Description for $channelId',
|
channelDescription: 'This channel is used for important notifications.',
|
||||||
importance: Importance.max,
|
importance: Importance.high,
|
||||||
priority: Priority.high,
|
priority: Priority.high,
|
||||||
);
|
);
|
||||||
var iOSDetails = DarwinNotificationDetails();
|
final NotificationDetails generalNotificationDetails =
|
||||||
var generalNotificationDetails = NotificationDetails(android: androidDetails, iOS: iOSDetails);
|
NotificationDetails(android: androidDetails);
|
||||||
|
|
||||||
await _flutterLocalNotificationsPlugin.show(
|
await _flutterLocalNotificationsPlugin.show(
|
||||||
// DateTime.now().millisecondsSinceEpoch % (1 << 31),
|
|
||||||
math.Random().nextInt(1 << 30),
|
math.Random().nextInt(1 << 30),
|
||||||
message.notification?.title,
|
message.notification?.title,
|
||||||
message.notification?.body,
|
message.notification?.body,
|
||||||
generalNotificationDetails,
|
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 {}}) {
|
{Map<String, dynamic> extra = const {}}) {
|
||||||
|
log("Payload _handleNotificationClick: $payload");
|
||||||
switch (payload.isNotEmpty) {
|
switch (payload.isNotEmpty) {
|
||||||
case true:
|
case true:
|
||||||
// Print the 'data' property
|
NotificationHandler().handleMessage(payload, AppState().context,
|
||||||
// Handle the message data as needed
|
extra: extra.isEmpty ? {} : extra);
|
||||||
NotificationHandler().handleMessage(payload, _context.value, extra: extra.isEmpty ? {} : extra);
|
break;
|
||||||
// Access the 'data' property of 'RemoteMessage'
|
|
||||||
case false:
|
case false:
|
||||||
// Handle the message notification as needed
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
@pragma('vm:entry-point')
|
||||||
log("Mensagem firebase: $message");
|
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 {
|
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) {});
|
message.forEach((key, value) {});
|
||||||
|
|
||||||
|
log("Message: $message");
|
||||||
|
log("Extra: $extra");
|
||||||
|
|
||||||
|
if (context != null) {
|
||||||
switch (message['click_action']) {
|
switch (message['click_action']) {
|
||||||
case 'visit_request':
|
case 'visit_request':
|
||||||
_showVisitRequestDialog(message, context);
|
_showVisitRequestDialog(message, context);
|
||||||
|
@ -312,15 +368,14 @@ class NotificationHandler {
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String _getIdBasedOnUserType(Map<String, dynamic> message) {
|
String _getIdBasedOnUserType(Map<String, dynamic> message) {
|
||||||
if (message['USR_TIPO'].toString() == 'O') {
|
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
|
return message['USR_ID'].toString().isEmpty
|
||||||
? '0'
|
? '0'
|
||||||
: message['USR_ID'].toString();
|
: message['USR_ID'].toString();
|
||||||
} else {
|
} else {
|
||||||
// Retorna USR_DOCUMENTO se não estiver vazio/nulo, caso contrário retorna '0'
|
|
||||||
return message['USR_DOCUMENTO'].toString().isEmpty
|
return message['USR_DOCUMENTO'].toString().isEmpty
|
||||||
? '0'
|
? '0'
|
||||||
: message['USR_DOCUMENTO'].toString();
|
: message['USR_DOCUMENTO'].toString();
|
||||||
|
@ -347,12 +402,14 @@ class NotificationHandler {
|
||||||
: message['USR_DOCUMENTO'].toString(),
|
: message['USR_DOCUMENTO'].toString(),
|
||||||
name: message['PES_NOME'].toString(),
|
name: message['PES_NOME'].toString(),
|
||||||
type: message['USR_TIPO'],
|
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(
|
showDialog(
|
||||||
useSafeArea: true,
|
useSafeArea: true,
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
|
@ -361,7 +418,7 @@ class NotificationHandler {
|
||||||
String localId = '';
|
String localId = '';
|
||||||
try {
|
try {
|
||||||
localId = jsonDecode(message['local'])['CLI_ID'];
|
localId = jsonDecode(message['local'])['CLI_ID'];
|
||||||
} catch(e, s) {
|
} catch (e) {
|
||||||
localId = message['local']['CLI_ID'].toString();
|
localId = message['local']['CLI_ID'].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +461,6 @@ class NotificationHandler {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
// barrierColor: Colors.green,
|
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
_getIdBasedOnUserType(message);
|
_getIdBasedOnUserType(message);
|
||||||
return Dialog(
|
return Dialog(
|
||||||
|
@ -535,7 +591,7 @@ class NotificationHandler {
|
||||||
): message['mensagem'],
|
): message['mensagem'],
|
||||||
}),
|
}),
|
||||||
imagePath:
|
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: [
|
statusHashMap: [
|
||||||
{
|
{
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
@ -544,7 +600,6 @@ class NotificationHandler {
|
||||||
): FlutterFlowTheme.of(context).warning,
|
): FlutterFlowTheme.of(context).warning,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// changeStatusAction: answersRequest,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
|
@ -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/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 '/backend/api_requests/api_calls.dart';
|
||||||
import '/flutter_flow/flutter_flow_icon_button.dart';
|
import '/flutter_flow/flutter_flow_icon_button.dart';
|
||||||
import '/flutter_flow/flutter_flow_theme.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 {
|
class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
||||||
const BottomArrowLinkedLocalsComponentWidget({super.key});
|
const BottomArrowLinkedLocalsComponentWidget({super.key});
|
||||||
|
@ -44,7 +43,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 1.0),
|
alignment: const AlignmentDirectional(0.0, 1.0),
|
||||||
|
@ -105,8 +104,8 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FutureBuilder<ApiCallResponse>(
|
child: FutureBuilder<ApiCallResponse>(
|
||||||
future: PhpGroup.getLocalsCall.call(
|
future: PhpGroup.getLocalsCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
// Customize what your widget looks like when it's loading.
|
// Customize what your widget looks like when it's loading.
|
||||||
|
@ -156,17 +155,17 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
FFAppState().cliUUID = getJsonField(
|
AppState().cliUUID = getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
r'''$.CLI_ID''',
|
r'''$.CLI_ID''',
|
||||||
).toString();
|
).toString();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
FFAppState().local = getJsonField(
|
AppState().local = getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
r'''$.CLI_NOME''',
|
r'''$.CLI_NOME''',
|
||||||
).toString();
|
).toString();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
FFAppState().ownerUUID = getJsonField(
|
AppState().ownerUUID = getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
r'''$.CLU_OWNER_ID''',
|
r'''$.CLU_OWNER_ID''',
|
||||||
).toString();
|
).toString();
|
||||||
|
|
|
@ -43,7 +43,7 @@ class _LocalProfileComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
|
@ -92,7 +92,7 @@ class _LocalProfileComponentWidgetState
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(200.0),
|
borderRadius: BorderRadius.circular(200.0),
|
||||||
child: Image.network(
|
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,
|
width: 80.0,
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -117,7 +117,7 @@ class _LocalProfileComponentWidgetState
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
valueOrDefault<String>(
|
valueOrDefault<String>(
|
||||||
functions.convertToUppercase(FFAppState().local),
|
functions.convertToUppercase(AppState().local),
|
||||||
'NOME DO LOCAL',
|
'NOME DO LOCAL',
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context).labelMedium.override(
|
style: FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
|
|
|
@ -355,9 +355,9 @@ class MessageWellNotifier extends StateNotifier<MessageWellState> {
|
||||||
if (state.pageNumber <= totalPageNumber) {
|
if (state.pageNumber <= totalPageNumber) {
|
||||||
var apiCall = GetMessagesCall();
|
var apiCall = GetMessagesCall();
|
||||||
var response = await apiCall.call(
|
var response = await apiCall.call(
|
||||||
devUUID: FFAppState().devUUID.toString(),
|
devUUID: AppState().devUUID.toString(),
|
||||||
userUUID: FFAppState().userUUID.toString(),
|
userUUID: AppState().userUUID.toString(),
|
||||||
cliID: FFAppState().cliUUID.toString(),
|
cliID: AppState().cliUUID.toString(),
|
||||||
atividade: 'getMensagens',
|
atividade: 'getMensagens',
|
||||||
pageSize: '100',
|
pageSize: '100',
|
||||||
pageNumber: state.pageNumber.toString(),
|
pageNumber: state.pageNumber.toString(),
|
||||||
|
|
|
@ -99,7 +99,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
final visitorsData = widget.visitorJsonList!.toList().take(2).toList();
|
final visitorsData = widget.visitorJsonList!.toList().take(2).toList();
|
||||||
final visitorsDataItem = visitorsData[0];
|
final visitorsDataItem = visitorsData[0];
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
||||||
fadeInDuration: const Duration(milliseconds: 500),
|
fadeInDuration: const Duration(milliseconds: 500),
|
||||||
fadeOutDuration: const Duration(milliseconds: 500),
|
fadeOutDuration: const Duration(milliseconds: 500),
|
||||||
imageUrl: valueOrDefault<String>(
|
imageUrl: valueOrDefault<String>(
|
||||||
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
|
"https://freaccess.com.br/freaccess/getImage.php?devUUID=${AppState().devUUID}&userUUID=${AppState().userUUID}&cliID=${AppState().cliUUID}&atividade=getFoto&Documento=${getJsonField(
|
||||||
visitorsDataItem,
|
visitorsDataItem,
|
||||||
r'''$.VTE_DOCUMENTO''',
|
r'''$.VTE_DOCUMENTO''',
|
||||||
).toString()}&tipo=E",
|
).toString()}&tipo=E",
|
||||||
|
@ -789,8 +789,8 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_model.postScheduleVisit =
|
_model.postScheduleVisit =
|
||||||
await PhpGroup.postScheduleVisitCall.call(
|
await PhpGroup.postScheduleVisitCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
atividade: 'putVisita',
|
atividade: 'putVisita',
|
||||||
devDesc: widget.visitObsStr,
|
devDesc: widget.visitObsStr,
|
||||||
idVisitante: widget.visitorStrList,
|
idVisitante: widget.visitorStrList,
|
||||||
|
@ -801,7 +801,7 @@ class _ScheduleVisitDetailWidgetState extends State<ScheduleVisitDetailWidget> {
|
||||||
idMotivo: extractIdToStr(widget.visitResonStr!),
|
idMotivo: extractIdToStr(widget.visitResonStr!),
|
||||||
idNAC: extractIdToStr(widget.visitLevelStr!),
|
idNAC: extractIdToStr(widget.visitLevelStr!),
|
||||||
obs: widget.visitObsStr,
|
obs: widget.visitObsStr,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (PhpGroup.postScheduleVisitCall.error(
|
if (PhpGroup.postScheduleVisitCall.error(
|
||||||
|
|
|
@ -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_theme.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
||||||
class UpArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
class UpArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
||||||
const UpArrowLinkedLocalsComponentWidget({super.key});
|
const UpArrowLinkedLocalsComponentWidget({super.key});
|
||||||
|
|
||||||
|
@ -45,7 +43,7 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, -1.0),
|
alignment: const AlignmentDirectional(0.0, -1.0),
|
||||||
|
@ -82,8 +80,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
),
|
),
|
||||||
child: FutureBuilder<ApiCallResponse>(
|
child: FutureBuilder<ApiCallResponse>(
|
||||||
future: PhpGroup.getLocalsCall.call(
|
future: PhpGroup.getLocalsCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
// Customize what your widget looks like when it's loading.
|
// Customize what your widget looks like when it's loading.
|
||||||
|
@ -134,12 +132,12 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
FFAppState().cliUUID = getJsonField(
|
AppState().cliUUID = getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
r'''$.CLI_ID''',
|
r'''$.CLI_ID''',
|
||||||
).toString();
|
).toString();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
FFAppState().local = getJsonField(
|
AppState().local = getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
r'''$.CLI_NOME''',
|
r'''$.CLI_NOME''',
|
||||||
).toString();
|
).toString();
|
||||||
|
@ -150,7 +148,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
width: 50.0,
|
width: 50.0,
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment:
|
||||||
|
const AlignmentDirectional(0.0, 0.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
|
@ -162,7 +161,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: FlutterFlowTheme.of(context)
|
color: FlutterFlowTheme.of(context)
|
||||||
.primaryText,
|
.primaryText,
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius:
|
||||||
|
const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(25.0),
|
bottomLeft: Radius.circular(25.0),
|
||||||
bottomRight:
|
bottomRight:
|
||||||
Radius.circular(25.0),
|
Radius.circular(25.0),
|
||||||
|
@ -177,7 +177,8 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius:
|
||||||
|
const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(25.0),
|
bottomLeft: Radius.circular(25.0),
|
||||||
bottomRight:
|
bottomRight:
|
||||||
Radius.circular(25.0),
|
Radius.circular(25.0),
|
||||||
|
@ -192,14 +193,14 @@ class _UpArrowLinkedLocalsComponentWidgetState
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
alignment: const Alignment(0.0, 0.0),
|
alignment:
|
||||||
|
const Alignment(0.0, 0.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsetsDirectional
|
||||||
const EdgeInsetsDirectional.fromSTEB(
|
.fromSTEB(0.0, 10.0, 0.0, 0.0),
|
||||||
0.0, 10.0, 0.0, 0.0),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
getJsonField(
|
getJsonField(
|
||||||
eachLocalsItem,
|
eachLocalsItem,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'access_notification_modal_template_component_widget.dart'
|
||||||
show AccessNotificationModalTemplateComponentWidget;
|
show AccessNotificationModalTemplateComponentWidget;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|
||||||
class AccessNotificationModalTemplateComponentModel
|
class AccessNotificationModalTemplateComponentModel
|
||||||
extends FlutterFlowModel<AccessNotificationModalTemplateComponentWidget> {
|
extends FlutterFlowModel<AccessNotificationModalTemplateComponentWidget> {
|
||||||
/// State fields for stateful widgets in this component.
|
/// State fields for stateful widgets in this component.
|
||||||
|
@ -55,9 +54,9 @@ class AccessNotificationModalTemplateComponentModel
|
||||||
ApiCallResponse? visitRequest;
|
ApiCallResponse? visitRequest;
|
||||||
|
|
||||||
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'respondeSolicitacao',
|
atividade: 'respondeSolicitacao',
|
||||||
referencia: refUUID,
|
referencia: refUUID,
|
||||||
tarefa: actionValue,
|
tarefa: actionValue,
|
||||||
|
|
|
@ -7,9 +7,6 @@ import 'package:provider/provider.dart';
|
||||||
import 'access_notification_modal_template_component_model.dart';
|
import 'access_notification_modal_template_component_model.dart';
|
||||||
export 'access_notification_modal_template_component_model.dart';
|
export 'access_notification_modal_template_component_model.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AccessNotificationModalTemplateComponentWidget extends StatefulWidget {
|
class AccessNotificationModalTemplateComponentWidget extends StatefulWidget {
|
||||||
const AccessNotificationModalTemplateComponentWidget({
|
const AccessNotificationModalTemplateComponentWidget({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -70,17 +67,13 @@ class _AccessNotificationModalTemplateComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
String labelTypeResident = FFLocalizations.of(context).getVariableText(
|
String labelTypeResident = FFLocalizations.of(context)
|
||||||
enText: 'Resident',
|
.getVariableText(enText: 'Resident', ptText: 'Morador');
|
||||||
ptText: 'Morador'
|
|
||||||
);
|
|
||||||
|
|
||||||
String labelTypeVisitor = FFLocalizations.of(context).getVariableText(
|
String labelTypeVisitor = FFLocalizations.of(context)
|
||||||
enText: 'Visitor',
|
.getVariableText(enText: 'Visitor', ptText: 'Visitante');
|
||||||
ptText: 'Visitante'
|
|
||||||
);
|
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
@ -120,7 +113,7 @@ class _AccessNotificationModalTemplateComponentWidgetState
|
||||||
// widget.type == 'O'
|
// 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=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=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',
|
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -194,7 +187,10 @@ class _AccessNotificationModalTemplateComponentWidgetState
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: TextEditingController(text: widget.type == 'O' ? labelTypeResident : labelTypeVisitor),
|
controller: TextEditingController(
|
||||||
|
text: widget.type == 'O'
|
||||||
|
? labelTypeResident
|
||||||
|
: labelTypeVisitor),
|
||||||
focusNode: _model.textFieldFocusNode2,
|
focusNode: _model.textFieldFocusNode2,
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
textInputAction: TextInputAction.next,
|
textInputAction: TextInputAction.next,
|
||||||
|
|
|
@ -83,7 +83,7 @@ class _CardItemTemplateComponentWidgetState
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
double screenWidth = MediaQuery.of(context).size.width;
|
double screenWidth = MediaQuery.of(context).size.width;
|
||||||
double screenHeight = MediaQuery.of(context).size.height;
|
double screenHeight = MediaQuery.of(context).size.height;
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return InkWell(
|
return InkWell(
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
focusColor: Colors.transparent,
|
focusColor: Colors.transparent,
|
||||||
|
|
|
@ -10,7 +10,6 @@ import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'change_pass_model.dart';
|
import 'change_pass_model.dart';
|
||||||
export 'change_pass_model.dart';
|
export 'change_pass_model.dart';
|
||||||
|
|
||||||
|
|
||||||
class PassKeyTemplateWidget extends StatefulWidget {
|
class PassKeyTemplateWidget extends StatefulWidget {
|
||||||
const PassKeyTemplateWidget({
|
const PassKeyTemplateWidget({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -20,12 +19,10 @@ class PassKeyTemplateWidget extends StatefulWidget {
|
||||||
final Future Function(String key)? toggleActionStatus;
|
final Future Function(String key)? toggleActionStatus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PassKeyTemplateWidget> createState() =>
|
State<PassKeyTemplateWidget> createState() => _PassKeyTemplateWidgetState();
|
||||||
_PassKeyTemplateWidgetState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PassKeyTemplateWidgetState
|
class _PassKeyTemplateWidgetState extends State<PassKeyTemplateWidget> {
|
||||||
extends State<PassKeyTemplateWidget> {
|
|
||||||
late PassKeyTemplateComponentModel _model;
|
late PassKeyTemplateComponentModel _model;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -82,7 +79,8 @@ class _PassKeyTemplateWidgetState
|
||||||
tablet: false,
|
tablet: false,
|
||||||
))
|
))
|
||||||
Padding(
|
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(
|
child: InkWell(
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
focusColor: Colors.transparent,
|
focusColor: Colors.transparent,
|
||||||
|
@ -104,8 +102,8 @@ class _PassKeyTemplateWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
const EdgeInsetsDirectional.fromSTEB(12.0, 0.0, 0.0, 0.0),
|
12.0, 0.0, 0.0, 0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
'',
|
'',
|
||||||
style:
|
style:
|
||||||
|
@ -125,11 +123,14 @@ class _PassKeyTemplateWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
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(
|
child: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
enText: 'INSERT PASSWORD',
|
enText: 'INSERT PASSWORD',
|
||||||
ptText: FFAppState().accessPass != '' ? 'ALTERAR SENHA' : 'ADICIONAR SENHA',
|
ptText: AppState().accessPass != ''
|
||||||
|
? 'ALTERAR SENHA'
|
||||||
|
: 'ADICIONAR SENHA',
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
style: FlutterFlowTheme.of(context).headlineMedium.override(
|
||||||
fontFamily: 'Outfit',
|
fontFamily: 'Outfit',
|
||||||
|
@ -142,12 +143,12 @@ class _PassKeyTemplateWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
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(
|
child: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
enText: 'Enter your password to continue',
|
enText: 'Enter your password to continue',
|
||||||
ptText: 'Digite sua senha para continuar'
|
ptText: 'Digite sua senha para continuar'),
|
||||||
),
|
|
||||||
style: FlutterFlowTheme.of(context).labelMedium.override(
|
style: FlutterFlowTheme.of(context).labelMedium.override(
|
||||||
fontFamily: 'Plus Jakarta Sans',
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
color: FlutterFlowTheme.of(context).primaryText,
|
color: FlutterFlowTheme.of(context).primaryText,
|
||||||
|
@ -165,7 +166,8 @@ class _PassKeyTemplateWidgetState
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
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(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
@ -184,7 +186,8 @@ class _PassKeyTemplateWidgetState
|
||||||
obscureText: !_model.keyTextFieldVisibility1,
|
obscureText: !_model.keyTextFieldVisibility1,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
isDense: true,
|
isDense: true,
|
||||||
labelText: FFLocalizations.of(context).getVariableText(
|
labelText:
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Senha',
|
ptText: 'Senha',
|
||||||
enText: 'Password',
|
enText: 'Password',
|
||||||
),
|
),
|
||||||
|
@ -245,8 +248,7 @@ class _PassKeyTemplateWidgetState
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor:
|
fillColor:
|
||||||
FlutterFlowTheme.of(context).primaryBackground,
|
FlutterFlowTheme.of(context).primaryBackground,
|
||||||
contentPadding:
|
contentPadding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
const EdgeInsetsDirectional.fromSTEB(
|
|
||||||
24.0, 24.0, 20.0, 24.0),
|
24.0, 24.0, 20.0, 24.0),
|
||||||
suffixIcon: InkWell(
|
suffixIcon: InkWell(
|
||||||
onTap: () => setState(
|
onTap: () => setState(
|
||||||
|
@ -292,12 +294,12 @@ class _PassKeyTemplateWidgetState
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
),
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
child: Padding(
|
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(
|
child: FFButtonWidget(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_model.formKey.currentState == null ||
|
if (_model.formKey.currentState == null ||
|
||||||
|
@ -305,20 +307,24 @@ class _PassKeyTemplateWidgetState
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await widget.toggleActionStatus?.call(
|
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);
|
Navigator.pop(context, true);
|
||||||
},
|
},
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: FFLocalizations.of(context).getVariableText(
|
||||||
ptText: FFAppState().accessPass != '' ? 'Alterar' : 'Adicionar',
|
ptText:
|
||||||
enText: FFAppState().accessPass != '' ? 'Change' : 'Add',
|
AppState().accessPass != '' ? 'Alterar' : 'Adicionar',
|
||||||
|
enText: AppState().accessPass != '' ? 'Change' : 'Add',
|
||||||
),
|
),
|
||||||
options: FFButtonOptions(
|
options: FFButtonOptions(
|
||||||
width: 270.0,
|
width: 270.0,
|
||||||
height: 50.0,
|
height: 50.0,
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0),
|
padding: const EdgeInsetsDirectional.fromSTEB(
|
||||||
iconPadding:
|
0.0, 0.0, 0.0, 0.0),
|
||||||
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),
|
color: const Color(0xFF1AAB5F),
|
||||||
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
|
textStyle: FlutterFlowTheme.of(context).titleSmall.override(
|
||||||
fontFamily: 'Plus Jakarta Sans',
|
fontFamily: 'Plus Jakarta Sans',
|
||||||
|
|
|
@ -117,8 +117,7 @@ Widget buildDetails(
|
||||||
dropdownValue2: visitaWrapItem['NAC_DESCRICAO'],
|
dropdownValue2: visitaWrapItem['NAC_DESCRICAO'],
|
||||||
visitorJsonList: [visitaWrapItem],
|
visitorJsonList: [visitaWrapItem],
|
||||||
visitorStrList: visitaWrapItem['VTE_DOCUMENTO'],
|
visitorStrList: visitaWrapItem['VTE_DOCUMENTO'],
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
options: FFButtonOptions(
|
options: FFButtonOptions(
|
||||||
|
@ -177,7 +176,7 @@ URL do Convite: https://visita.freaccess.com.br/${visitaWrapItem['VAW_ID']}/${vi
|
||||||
'Fim': visitaWrapItem['VAW_DTFIM'] ?? '',
|
'Fim': visitaWrapItem['VAW_DTFIM'] ?? '',
|
||||||
}),
|
}),
|
||||||
imagePath:
|
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: [
|
statusHashMap: [
|
||||||
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
|
if (getStatus(visitaWrapItem['VAW_STATUS']) == status.active)
|
||||||
Map<String, Color>.from({
|
Map<String, Color>.from({
|
||||||
|
|
|
@ -28,12 +28,10 @@ class DetailsComponentWidget extends StatefulWidget {
|
||||||
final List<Widget> buttons;
|
final List<Widget> buttons;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DetailsComponentWidget> createState() =>
|
State<DetailsComponentWidget> createState() => _DetailsComponentWidgetState();
|
||||||
_DetailsComponentWidgetState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DetailsComponentWidgetState
|
class _DetailsComponentWidgetState extends State<DetailsComponentWidget> {
|
||||||
extends State<DetailsComponentWidget> {
|
|
||||||
late DetailsComponentModel _model;
|
late DetailsComponentModel _model;
|
||||||
|
|
||||||
LinkedHashMap<String, String> get labelsLinkedHashMap =>
|
LinkedHashMap<String, String> get labelsLinkedHashMap =>
|
||||||
|
@ -66,7 +64,7 @@ class _DetailsComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
|
|
|
@ -58,9 +58,9 @@ class LiberationHistoryItemDetailsTemplateComponentModel
|
||||||
ApiCallResponse? visitRequest;
|
ApiCallResponse? visitRequest;
|
||||||
|
|
||||||
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'respondeSolicitacao',
|
atividade: 'respondeSolicitacao',
|
||||||
referencia: refUUID,
|
referencia: refUUID,
|
||||||
tarefa: actionValue,
|
tarefa: actionValue,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
@ -69,7 +68,7 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
@ -106,7 +105,7 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
|
||||||
fadeInDuration: const Duration(milliseconds: 100),
|
fadeInDuration: const Duration(milliseconds: 100),
|
||||||
fadeOutDuration: const Duration(milliseconds: 100),
|
fadeOutDuration: const Duration(milliseconds: 100),
|
||||||
imageUrl: valueOrDefault<String>(
|
imageUrl: valueOrDefault<String>(
|
||||||
'https://freaccess.com.br/freaccess/getImage.php?devUUID=${FFAppState().devUUID}&userUUID=${FFAppState().userUUID}&cliID=${FFAppState().cliUUID}&atividade=getFoto&Documento=${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',
|
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -117,7 +116,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
|
||||||
.addToEnd(const SizedBox(width: 10.0)),
|
.addToEnd(const SizedBox(width: 10.0)),
|
||||||
),
|
),
|
||||||
Padding(
|
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(
|
child: TextFormField(
|
||||||
controller: _model.textController1,
|
controller: _model.textController1,
|
||||||
focusNode: _model.textFieldFocusNode1,
|
focusNode: _model.textFieldFocusNode1,
|
||||||
|
@ -242,7 +242,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
|
||||||
.addToEnd(const SizedBox(width: 24.0)),
|
.addToEnd(const SizedBox(width: 24.0)),
|
||||||
),
|
),
|
||||||
Padding(
|
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(
|
child: TextFormField(
|
||||||
controller: _model.textController3,
|
controller: _model.textController3,
|
||||||
focusNode: _model.textFieldFocusNode3,
|
focusNode: _model.textFieldFocusNode3,
|
||||||
|
@ -300,7 +301,8 @@ class _LiberationHistoryItemDetailsTemplateComponentWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
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(
|
child: TextFormField(
|
||||||
controller: _model.textController4,
|
controller: _model.textController4,
|
||||||
focusNode: _model.textFieldFocusNode4,
|
focusNode: _model.textFieldFocusNode4,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hub/app_state.dart';
|
import 'package:hub/app_state.dart';
|
||||||
import 'package:hub/backend/api_requests/api_calls.dart';
|
import 'package:hub/backend/api_requests/api_calls.dart';
|
||||||
|
@ -56,9 +55,9 @@ class MessageNotificationModalTemplateComponentModel
|
||||||
ApiCallResponse? visitRequest;
|
ApiCallResponse? visitRequest;
|
||||||
|
|
||||||
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
visitRequest = await PhpGroup.respondeSolicitacaoCall.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'respondeSolicitacao',
|
atividade: 'respondeSolicitacao',
|
||||||
referencia: refUUID,
|
referencia: refUUID,
|
||||||
tarefa: actionValue,
|
tarefa: actionValue,
|
||||||
|
|
|
@ -64,7 +64,7 @@ class _MessageNotificationModalTemplateComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
|
|
|
@ -47,9 +47,9 @@ class RegisiterVistorTemplateComponentModel
|
||||||
Future<bool> getVisitanteByDocument(
|
Future<bool> getVisitanteByDocument(
|
||||||
String document, BuildContext context) async {
|
String document, BuildContext context) async {
|
||||||
final response = await PhpGroup.getVisitorByDocCall.call(
|
final response = await PhpGroup.getVisitorByDocCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'getVisitante',
|
atividade: 'getVisitante',
|
||||||
documento: document,
|
documento: document,
|
||||||
);
|
);
|
||||||
|
|
|
@ -112,7 +112,7 @@ class _RegisiterVistorTemplateComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return Align(
|
return Align(
|
||||||
alignment: const AlignmentDirectional(0.0, 1.0),
|
alignment: const AlignmentDirectional(0.0, 1.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -809,9 +809,9 @@ class _RegisiterVistorTemplateComponentWidgetState
|
||||||
_model.scheduleVisitor =
|
_model.scheduleVisitor =
|
||||||
await PhpGroup.postScheduleVisitorCall
|
await PhpGroup.postScheduleVisitorCall
|
||||||
.call(
|
.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'putVisitante',
|
atividade: 'putVisitante',
|
||||||
documento: _model.textController2.text,
|
documento: _model.textController2.text,
|
||||||
nome: _model.textController1.text,
|
nome: _model.textController1.text,
|
||||||
|
|
|
@ -123,7 +123,7 @@ class _SignUpTemplateComponentWidgetState
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
@ -701,7 +701,7 @@ class _SignUpTemplateComponentWidgetState
|
||||||
email: _model
|
email: _model
|
||||||
.emailRegisterFormTextController
|
.emailRegisterFormTextController
|
||||||
.text,
|
.text,
|
||||||
device: FFAppState().device,
|
device: AppState().device,
|
||||||
);
|
);
|
||||||
shouldSetState = true;
|
shouldSetState = true;
|
||||||
if (_model.signUp == true) {
|
if (_model.signUp == true) {
|
||||||
|
|
|
@ -128,7 +128,7 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
|
||||||
var filteredVisitorJsonList =
|
var filteredVisitorJsonList =
|
||||||
findVisitorById(widget.visitorJsonList, widget.visitIdStr) ?? 'null';
|
findVisitorById(widget.visitorJsonList, widget.visitIdStr) ?? 'null';
|
||||||
|
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 200.0, 0.0, 0.0),
|
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 200.0, 0.0, 0.0),
|
||||||
|
@ -829,9 +829,9 @@ class _ViewVisitDetailWidgetState extends State<ViewVisitDetailWidget> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_model.deleteVisit =
|
_model.deleteVisit =
|
||||||
await PhpGroup.deleteVisitCall.call(
|
await PhpGroup.deleteVisitCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'cancelaVisita',
|
atividade: 'cancelaVisita',
|
||||||
idVisita: widget.visitIdStr,
|
idVisita: widget.visitIdStr,
|
||||||
);
|
);
|
||||||
|
|
|
@ -61,7 +61,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 50.0, 0.0, 0.0),
|
padding: const EdgeInsetsDirectional.fromSTEB(0.0, 50.0, 0.0, 0.0),
|
||||||
|
@ -291,7 +291,7 @@ class _VisitorSearchModalTemplateComponentWidgetState
|
||||||
fadeOutDuration: const Duration(
|
fadeOutDuration: const Duration(
|
||||||
milliseconds: 500),
|
milliseconds: 500),
|
||||||
imageUrl:
|
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,
|
visitorItem,
|
||||||
r'''$.VTE_DOCUMENTO''',
|
r'''$.VTE_DOCUMENTO''',
|
||||||
).toString()}&tipo=E",
|
).toString()}&tipo=E",
|
||||||
|
@ -462,9 +462,9 @@ class _VisitorSearchModalTemplateComponentWidgetState
|
||||||
TextSelection.collapsed(offset: _model.textController!.text.length);
|
TextSelection.collapsed(offset: _model.textController!.text.length);
|
||||||
});
|
});
|
||||||
_model.getVisitorByDoc = await PhpGroup.getVisitorByDocCall.call(
|
_model.getVisitorByDoc = await PhpGroup.getVisitorByDocCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'getVisitante',
|
atividade: 'getVisitante',
|
||||||
documento: _model.textController.text,
|
documento: _model.textController.text,
|
||||||
);
|
);
|
||||||
|
|
|
@ -69,7 +69,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter(
|
||||||
FFRoute(
|
FFRoute(
|
||||||
name: '_initialize',
|
name: '_initialize',
|
||||||
path: '/',
|
path: '/',
|
||||||
builder: (context, _) => FFAppState().isLogged
|
builder: (context, _) => AppState().isLogged
|
||||||
? const HomePageWidget()
|
? const HomePageWidget()
|
||||||
: const WelcomePageWidget(),
|
: const WelcomePageWidget(),
|
||||||
),
|
),
|
||||||
|
|
136
lib/main.dart
136
lib/main.dart
|
@ -1,41 +1,157 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_crashlytics/firebase_crashlytics.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/app_state.dart';
|
||||||
|
import 'package:hub/firebase_options.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
|
||||||
import 'package:hub/flutter_flow/internationalization.dart';
|
import 'package:hub/flutter_flow/internationalization.dart';
|
||||||
import 'package:hub/flutter_flow/nav/nav.dart';
|
import 'package:hub/flutter_flow/nav/nav.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:responsive_framework/responsive_framework.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>();
|
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 {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||||
|
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||||||
|
|
||||||
|
if (!kIsWeb) {
|
||||||
|
await setupFlutterNotifications();
|
||||||
|
}
|
||||||
SystemChrome.setPreferredOrientations([
|
SystemChrome.setPreferredOrientations([
|
||||||
DeviceOrientation.portraitUp,
|
DeviceOrientation.portraitUp,
|
||||||
DeviceOrientation.portraitDown,
|
DeviceOrientation.portraitDown,
|
||||||
]);
|
]);
|
||||||
await init();
|
await init().then((_) {
|
||||||
runApp(ChangeNotifierProvider(
|
runApp(ChangeNotifierProvider(
|
||||||
create: (context) => FFAppState(),
|
create: (context) => AppState(),
|
||||||
child: const MyApp(),
|
child: const MyApp(),
|
||||||
));
|
));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
log('Setting up Crashlytics...');
|
||||||
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
|
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();
|
await FlutterFlowTheme.initialize();
|
||||||
|
log('FlutterFlowTheme initialized.');
|
||||||
|
|
||||||
|
log('Initializing FFLocalizations...');
|
||||||
await FFLocalizations.initialize();
|
await FFLocalizations.initialize();
|
||||||
final appState = FFAppState();
|
log('FFLocalizations initialized.');
|
||||||
|
|
||||||
|
log('Initializing app state...');
|
||||||
|
final appState = AppState();
|
||||||
await appState.initializePersistedState();
|
await appState.initializePersistedState();
|
||||||
|
log('App state initialized.');
|
||||||
|
|
||||||
|
log('Initializing GoRouter...');
|
||||||
GoRouter.optionURLReflectsImperativeAPIs = true;
|
GoRouter.optionURLReflectsImperativeAPIs = true;
|
||||||
usePathUrlStrategy();
|
usePathUrlStrategy();
|
||||||
|
log('GoRouter initialized.');
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
class MyApp extends StatefulWidget {
|
||||||
|
|
|
@ -209,9 +209,9 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
|
||||||
try {
|
try {
|
||||||
setState(() => _loading = true);
|
setState(() => _loading = true);
|
||||||
var response = await PhpGroup.getAccessCall.call(
|
var response = await PhpGroup.getAccessCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'getAcessos',
|
atividade: 'getAcessos',
|
||||||
pageSize: _pageSize.toString(),
|
pageSize: _pageSize.toString(),
|
||||||
pageNumber: _pageNumber.toString(),
|
pageNumber: _pageNumber.toString(),
|
||||||
|
@ -355,7 +355,7 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
|
||||||
BuildContext context, dynamic accessHistoryItem) {
|
BuildContext context, dynamic accessHistoryItem) {
|
||||||
return CardItemTemplateComponentWidget(
|
return CardItemTemplateComponentWidget(
|
||||||
imagePath:
|
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({
|
labelsHashMap: Map<String, String>.from({
|
||||||
'Nome:': accessHistoryItem['PES_NOME'] ?? '',
|
'Nome:': accessHistoryItem['PES_NOME'] ?? '',
|
||||||
'Acesso:': accessHistoryItem['ACE_DATAHORA'] ?? '',
|
'Acesso:': accessHistoryItem['ACE_DATAHORA'] ?? '',
|
||||||
|
@ -409,7 +409,7 @@ class _AcessHistoryPageWidgetState extends State<AcessHistoryPageWidget> {
|
||||||
|
|
||||||
String imageUrlAtomWidget(String document, String type) {
|
String imageUrlAtomWidget(String document, String type) {
|
||||||
return valueOrDefault<String>(
|
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",
|
"https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,15 @@ import 'package:webview_flutter/webview_flutter.dart';
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
class FastPassPageWidget extends StatefulWidget {
|
class FastPassPageWidget extends StatefulWidget {
|
||||||
final String freToken = FFAppState().userUUID;
|
final String freToken = AppState().userUUID;
|
||||||
final String freUserData = "{\"name\": \"${FFAppState().name}\", " +
|
final String freUserData = "{\"name\": \"${AppState().name}\", " +
|
||||||
"\"email\": \"${FFAppState().email}\"," +
|
"\"email\": \"${AppState().email}\"," +
|
||||||
"\"dev_id\": \"${FFAppState().devUUID}\"," +
|
"\"dev_id\": \"${AppState().devUUID}\"," +
|
||||||
"\"created_at\": \"${FFAppState().createdAt}\"," +
|
"\"created_at\": \"${AppState().createdAt}\"," +
|
||||||
"\"updated_at\": \"0000-00-00 00:00:00\"," +
|
"\"updated_at\": \"0000-00-00 00:00:00\"," +
|
||||||
"\"status\": \"A\" }";
|
"\"status\": \"A\" }";
|
||||||
|
|
||||||
final String clientId = FFAppState().cliUUID;
|
final String clientId = AppState().cliUUID;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_FastPassPageWidgetState createState() => _FastPassPageWidgetState();
|
_FastPassPageWidgetState createState() => _FastPassPageWidgetState();
|
||||||
|
@ -35,20 +35,19 @@ class _FastPassPageWidgetState extends State<FastPassPageWidget> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
name = FFAppState().name;
|
name = AppState().name;
|
||||||
email = FFAppState().email;
|
email = AppState().email;
|
||||||
userUUID = FFAppState().userUUID;
|
userUUID = AppState().userUUID;
|
||||||
created_at = FFAppState().createdAt;
|
created_at = AppState().createdAt;
|
||||||
url = 'https://hub.freaccess.com.br/hub/fast-pass/${widget.clientId}';
|
url = 'https://hub.freaccess.com.br/hub/fast-pass/${widget.clientId}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
body: Platform.isIOS ? InAppWebView(
|
body: Platform.isIOS
|
||||||
|
? InAppWebView(
|
||||||
initialUrlRequest: URLRequest(url: WebUri(url)),
|
initialUrlRequest: URLRequest(url: WebUri(url)),
|
||||||
initialSettings: InAppWebViewSettings(
|
initialSettings: InAppWebViewSettings(
|
||||||
allowsBackForwardNavigationGestures: true,
|
allowsBackForwardNavigationGestures: true,
|
||||||
|
@ -58,10 +57,15 @@ class _FastPassPageWidgetState extends State<FastPassPageWidget> {
|
||||||
_controllerIOS = controller;
|
_controllerIOS = controller;
|
||||||
},
|
},
|
||||||
onLoadStop: (controller, url) async {
|
onLoadStop: (controller, url) async {
|
||||||
await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')");
|
await controller.evaluateJavascript(
|
||||||
await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')");
|
source:
|
||||||
|
"window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')");
|
||||||
|
await controller.evaluateJavascript(
|
||||||
|
source:
|
||||||
|
"window.localStorage.setItem('fre-user-data', '${widget.freUserData}')");
|
||||||
},
|
},
|
||||||
) : WebViewWidget(
|
)
|
||||||
|
: WebViewWidget(
|
||||||
controller: _controllerAll = WebViewController()
|
controller: _controllerAll = WebViewController()
|
||||||
..clearCache()
|
..clearCache()
|
||||||
..clearLocalStorage()
|
..clearLocalStorage()
|
||||||
|
@ -71,15 +75,18 @@ class _FastPassPageWidgetState extends State<FastPassPageWidget> {
|
||||||
NavigationDelegate(
|
NavigationDelegate(
|
||||||
onProgress: (int progress) {},
|
onProgress: (int progress) {},
|
||||||
onPageStarted: (String url) {
|
onPageStarted: (String url) {
|
||||||
final String token = "localStorage.setItem('fre-token', '\"${widget.freToken}\"');";
|
final String token =
|
||||||
final String data = "localStorage.setItem('fre-user-data', '${widget.freUserData}');";
|
"localStorage.setItem('fre-token', '\"${widget.freToken}\"');";
|
||||||
|
final String data =
|
||||||
|
"localStorage.setItem('fre-user-data', '${widget.freUserData}');";
|
||||||
|
|
||||||
_controllerAll.runJavaScript(token);
|
_controllerAll.runJavaScript(token);
|
||||||
_controllerAll.runJavaScript(data);
|
_controllerAll.runJavaScript(data);
|
||||||
},
|
},
|
||||||
onNavigationRequest: (NavigationRequest request) {
|
onNavigationRequest: (NavigationRequest request) {
|
||||||
if (request.url.startsWith('http') ||
|
if (request.url.startsWith('http') ||
|
||||||
request.url.startsWith('https://api.whatsapp.com/send') ||
|
request.url
|
||||||
|
.startsWith('https://api.whatsapp.com/send') ||
|
||||||
request.url.startsWith('https://wa.me')) {
|
request.url.startsWith('https://wa.me')) {
|
||||||
launchUrlString(request.url);
|
launchUrlString(request.url);
|
||||||
return NavigationDecision.prevent;
|
return NavigationDecision.prevent;
|
||||||
|
@ -92,6 +99,5 @@ class _FastPassPageWidgetState extends State<FastPassPageWidget> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
// import 'package:hub/backend/push_notification/pushNotification.dart';
|
// import 'package:hub/backend/push_notification/pushNotification.dart';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
import 'package:hub/actions/actions.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/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/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/local_profile_component/local_profile_component_widget.dart';
|
||||||
import 'package:hub/components/organism_components/menu_component/menu_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/custom_functions.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_icon_button.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_theme.dart';
|
||||||
|
|
||||||
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
import 'package:hub/flutter_flow/flutter_flow_widgets.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/flutter_flow/nav/nav.dart';
|
||||||
|
import 'package:hub/main.dart';
|
||||||
import 'package:hub/pages/home_page/home_page_model.dart';
|
import 'package:hub/pages/home_page/home_page_model.dart';
|
||||||
|
|
||||||
import 'package:provider/provider.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 {
|
class HomePageWidget extends StatefulWidget {
|
||||||
const HomePageWidget({super.key});
|
const HomePageWidget({super.key});
|
||||||
|
|
||||||
|
@ -35,6 +52,9 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
late HomePageModel _model;
|
late HomePageModel _model;
|
||||||
bool localStatus = false;
|
bool localStatus = false;
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
String? _token;
|
||||||
|
String? initialMessage;
|
||||||
|
bool _resolved = false;
|
||||||
|
|
||||||
Future<void> checkLocalStatus() async {
|
Future<void> checkLocalStatus() async {
|
||||||
localStatus = await checkLocals(
|
localStatus = await checkLocals(
|
||||||
|
@ -48,9 +68,29 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_model = createModel(context, () => HomePageModel());
|
_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
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -58,7 +98,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rest of your code...
|
// Rest of your code...
|
||||||
if (FFAppState().cliUUID == null || FFAppState().cliUUID.isEmpty) {
|
if (AppState().cliUUID == null || AppState().cliUUID.isEmpty) {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
isScrollControlled: false,
|
isScrollControlled: false,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
|
@ -93,9 +133,72 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
super.dispose();
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => _model.unfocusNode.canRequestFocus
|
onTap: () => _model.unfocusNode.canRequestFocus
|
||||||
? FocusScope.of(context).requestFocus(_model.unfocusNode)
|
? FocusScope.of(context).requestFocus(_model.unfocusNode)
|
||||||
|
@ -363,7 +466,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
),
|
),
|
||||||
child: Image.network(
|
child: Image.network(
|
||||||
valueOrDefault<String>(
|
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',
|
'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg',
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -373,7 +476,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
width: 150.0,
|
width: 150.0,
|
||||||
child: Text(
|
child: Text(
|
||||||
valueOrDefault<String>(
|
valueOrDefault<String>(
|
||||||
convertToUppercase(FFAppState().local),
|
convertToUppercase(AppState().local),
|
||||||
'NOME DO LOCAL',
|
'NOME DO LOCAL',
|
||||||
),
|
),
|
||||||
style: FlutterFlowTheme.of(context)
|
style: FlutterFlowTheme.of(context)
|
||||||
|
@ -543,7 +646,7 @@ class _HomePageWidgetState extends State<HomePageWidget> {
|
||||||
),
|
),
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
FFAppState().deleteAll();
|
AppState().deleteAll();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
||||||
context.goNamed(
|
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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:developer';
|
||||||
|
|
||||||
import 'package:hub/actions/actions.dart';
|
import 'package:hub/actions/actions.dart';
|
||||||
import 'package:hub/backend/api_requests/api_calls.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/card_item_template_component/card_item_template_component_widget.dart';
|
||||||
import 'package:hub/components/templates_components/details_component/details_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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => _model.unfocusNode.canRequestFocus
|
onTap: () => _model.unfocusNode.canRequestFocus
|
||||||
? FocusScope.of(context).requestFocus(_model.unfocusNode)
|
? FocusScope.of(context).requestFocus(_model.unfocusNode)
|
||||||
|
@ -227,9 +227,9 @@ Widget liberationDynamicListView(
|
||||||
child: StreamBuilder<ApiCallResponse>(
|
child: StreamBuilder<ApiCallResponse>(
|
||||||
stream: _model.getLiberations(
|
stream: _model.getLiberations(
|
||||||
requestFn: () => PhpGroup.getLiberationsCall.call(
|
requestFn: () => PhpGroup.getLiberationsCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'getSolicitacoes',
|
atividade: 'getSolicitacoes',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -299,7 +299,7 @@ Widget liberationHistoryItemCard(
|
||||||
BuildContext context, dynamic liberationHistoryItem) {
|
BuildContext context, dynamic liberationHistoryItem) {
|
||||||
return CardItemTemplateComponentWidget(
|
return CardItemTemplateComponentWidget(
|
||||||
imagePath:
|
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({
|
labelsHashMap: Map<String, String>.from({
|
||||||
'Nome:': liberationHistoryItem['VTE_NOME'],
|
'Nome:': liberationHistoryItem['VTE_NOME'],
|
||||||
'Data:': liberationHistoryItem['NOT_DTENVIO'],
|
'Data:': liberationHistoryItem['NOT_DTENVIO'],
|
||||||
|
@ -416,7 +416,7 @@ Widget liberationHistoryItemCard(
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
imagePath:
|
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',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -91,7 +91,7 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
@ -105,9 +105,9 @@ class _MessageHistoryPageWidgetState extends State<MessageHistoryPageWidget>
|
||||||
setState(() => _loading = true);
|
setState(() => _loading = true);
|
||||||
|
|
||||||
var response = await PhpGroup.getMessagesCall.call(
|
var response = await PhpGroup.getMessagesCall.call(
|
||||||
devUUID: FFAppState().devUUID.toString(),
|
devUUID: AppState().devUUID.toString(),
|
||||||
userUUID: FFAppState().userUUID.toString(),
|
userUUID: AppState().userUUID.toString(),
|
||||||
cliID: FFAppState().cliUUID.toString(),
|
cliID: AppState().cliUUID.toString(),
|
||||||
atividade: 'getMensagens',
|
atividade: 'getMensagens',
|
||||||
pageSize: _pageSize.toString(),
|
pageSize: _pageSize.toString(),
|
||||||
pageNumber: _pageNumber.toString(),
|
pageNumber: _pageNumber.toString(),
|
||||||
|
|
|
@ -9,7 +9,6 @@ import 'package:hub/flutter_flow/internationalization.dart';
|
||||||
import 'package:hub/flutter_flow/nav/nav.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: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:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.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/dialog_util.dart';
|
||||||
import '../../shared/utils/log_util.dart';
|
import '../../shared/utils/log_util.dart';
|
||||||
|
|
||||||
|
|
||||||
class PeopleOnThePropertyPageWidget extends StatefulWidget {
|
class PeopleOnThePropertyPageWidget extends StatefulWidget {
|
||||||
const PeopleOnThePropertyPageWidget({super.key});
|
const PeopleOnThePropertyPageWidget({super.key});
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: scaffoldKey,
|
key: scaffoldKey,
|
||||||
|
@ -93,10 +91,10 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
top: true,
|
top: true,
|
||||||
child: FutureBuilder<ApiCallResponse>(
|
child: FutureBuilder<ApiCallResponse>(
|
||||||
future: PhpGroup.getPessoasLocalCall.call(
|
future: PhpGroup.getPessoasLocalCall.call(
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
ownID: FFAppState().ownerUUID,
|
ownID: AppState().ownerUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
// Customize what your widget looks like when it's loading.
|
// 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.hasError || snapshot.data?.exception != null) {
|
||||||
if (snapshot.error != null && snapshot.stackTrace != 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(
|
return Center(
|
||||||
|
@ -125,8 +128,7 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: "Pessoas não encontradas",
|
ptText: "Pessoas não encontradas",
|
||||||
enText: "Persons not found"
|
enText: "Persons not found"),
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -134,7 +136,12 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
}
|
}
|
||||||
|
|
||||||
final columnGetPessoasLocalResponse = snapshot.data!;
|
final columnGetPessoasLocalResponse = snapshot.data!;
|
||||||
final getPoepleProperty = PhpGroup.getPessoasLocalCall.pessoas(columnGetPessoasLocalResponse.jsonBody,)?.toList() ?? [];
|
final getPoepleProperty = PhpGroup.getPessoasLocalCall
|
||||||
|
.pessoas(
|
||||||
|
columnGetPessoasLocalResponse.jsonBody,
|
||||||
|
)
|
||||||
|
?.toList() ??
|
||||||
|
[];
|
||||||
|
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
@ -170,7 +177,8 @@ class _PeopleOnThePropertyPageWidgetState
|
||||||
r'''$.USU_NOME''',
|
r'''$.USU_NOME''',
|
||||||
).toString(),
|
).toString(),
|
||||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
fontFamily:
|
||||||
|
FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
letterSpacing: 0.0,
|
letterSpacing: 0.0,
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
useGoogleFonts: GoogleFonts.asMap().containsKey(
|
||||||
|
|
|
@ -24,9 +24,9 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
// })
|
// })
|
||||||
// .whenComplete(() => notifyListeners()));
|
// .whenComplete(() => notifyListeners()));
|
||||||
|
|
||||||
if (FFAppState().fingerprint) {
|
if (AppState().fingerprint) {
|
||||||
FFAppState().fingerprint = false;
|
AppState().fingerprint = false;
|
||||||
FFAppState().deleteFingerprintPass();
|
AppState().deleteFingerprintPass();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
await showModalBottomSheet(
|
await showModalBottomSheet(
|
||||||
|
@ -39,8 +39,8 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
padding: MediaQuery.viewInsetsOf(context),
|
padding: MediaQuery.viewInsetsOf(context),
|
||||||
child: PassKeyTemplateWidget(
|
child: PassKeyTemplateWidget(
|
||||||
toggleActionStatus: (key) async {
|
toggleActionStatus: (key) async {
|
||||||
FFAppState().fingerprintPass = key;
|
AppState().fingerprintPass = key;
|
||||||
FFAppState().fingerprint = true;
|
AppState().fingerprint = true;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -88,8 +88,8 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
Share.share(
|
Share.share(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText:
|
ptText:
|
||||||
'Este é o meu identificador de acesso: ${FFAppState().userDevUUID}',
|
'Este é o meu identificador de acesso: ${AppState().userDevUUID}',
|
||||||
enText: 'This is my access identifier: ${FFAppState().userDevUUID}',
|
enText: 'This is my access identifier: ${AppState().userDevUUID}',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -102,19 +102,19 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
title: Text(
|
title: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
enText: FFAppState().notify
|
enText: AppState().notify
|
||||||
? 'Disable Access Notification'
|
? 'Disable Access Notification'
|
||||||
: 'Access Notification',
|
: 'Access Notification',
|
||||||
ptText: FFAppState().notify
|
ptText: AppState().notify
|
||||||
? 'Desativar notificação de acesso'
|
? 'Desativar notificação de acesso'
|
||||||
: 'Notificação de acesso'),
|
: 'Notificação de acesso'),
|
||||||
),
|
),
|
||||||
content: Text(
|
content: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
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 desativar as suas notificações de acesso?'
|
||||||
: 'Tem certeza que deseja receber 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 disable your access notifications?'
|
||||||
: 'Are you sure you want to receive your access notifications?'),
|
: 'Are you sure you want to receive your access notifications?'),
|
||||||
),
|
),
|
||||||
|
@ -150,17 +150,17 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
try {
|
try {
|
||||||
PhpGroup.changeNotifica
|
PhpGroup.changeNotifica
|
||||||
.call(
|
.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'updVisitado',
|
atividade: 'updVisitado',
|
||||||
notifica: FFAppState().notify ? 'S' : 'N',
|
notifica: AppState().notify ? 'S' : 'N',
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (value.jsonBody['error'] == false) {
|
if (value.jsonBody['error'] == false) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
||||||
FFAppState().notify = !FFAppState().notify;
|
AppState().notify = !AppState().notify;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
|
@ -306,16 +306,16 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
try {
|
try {
|
||||||
await PhpGroup.resopndeVinculo
|
await PhpGroup.resopndeVinculo
|
||||||
.call(
|
.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
tarefa: 'I',
|
tarefa: 'I',
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (value.jsonBody['error'] == false) {
|
if (value.jsonBody['error'] == false) {
|
||||||
FFAppState().deleteCliUUID();
|
AppState().deleteCliUUID();
|
||||||
FFAppState().deleteLocal();
|
AppState().deleteLocal();
|
||||||
FFAppState().deleteOwnerUUID();
|
AppState().deleteOwnerUUID();
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
||||||
|
@ -460,13 +460,13 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
try {
|
try {
|
||||||
await PhpGroup.deleteAccount
|
await PhpGroup.deleteAccount
|
||||||
.call(
|
.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (value.jsonBody['error'] == false) {
|
if (value.jsonBody['error'] == false) {
|
||||||
FFAppState().deleteAll();
|
AppState().deleteAll();
|
||||||
FFAppState().isLogged = false;
|
AppState().isLogged = false;
|
||||||
context.goNamed(
|
context.goNamed(
|
||||||
'welcomePage',
|
'welcomePage',
|
||||||
extra: <String, dynamic>{
|
extra: <String, dynamic>{
|
||||||
|
@ -565,20 +565,20 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
padding: MediaQuery.viewInsetsOf(context),
|
padding: MediaQuery.viewInsetsOf(context),
|
||||||
child: PassKeyTemplateWidget(
|
child: PassKeyTemplateWidget(
|
||||||
toggleActionStatus: (key) async {
|
toggleActionStatus: (key) async {
|
||||||
FFAppState().accessPass = key;
|
AppState().accessPass = key;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
await PhpGroup.changePass
|
await PhpGroup.changePass
|
||||||
.call(
|
.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'updVisitado',
|
atividade: 'updVisitado',
|
||||||
newSenha: FFAppState().accessPass,
|
newSenha: AppState().accessPass,
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
// var error = jsonDecode(value.jsonBody['error'].toString());
|
// var error = jsonDecode(value.jsonBody['error'].toString());
|
||||||
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
|
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
|
||||||
FFAppState().pass = true;
|
AppState().pass = true;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
|
@ -655,20 +655,20 @@ class PreferencesPageModel with ChangeNotifier {
|
||||||
padding: MediaQuery.viewInsetsOf(context),
|
padding: MediaQuery.viewInsetsOf(context),
|
||||||
child: PassKeyTemplateWidget(
|
child: PassKeyTemplateWidget(
|
||||||
toggleActionStatus: (key) async {
|
toggleActionStatus: (key) async {
|
||||||
FFAppState().panicPass = key;
|
AppState().panicPass = key;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
await PhpGroup.changePanic
|
await PhpGroup.changePanic
|
||||||
.call(
|
.call(
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'updVisitado',
|
atividade: 'updVisitado',
|
||||||
newSenhaPanico: FFAppState().panicPass,
|
newSenhaPanico: AppState().panicPass,
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
FFAppState().panic = true;
|
AppState().panic = true;
|
||||||
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
|
if (jsonDecode(value.jsonBody['error'].toString()) == false) {
|
||||||
FFAppState().panic = true;
|
AppState().panic = true;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
|
|
|
@ -101,7 +101,7 @@ class PreferencesPageWidget extends StatelessWidget {
|
||||||
icon = Icons.fingerprint;
|
icon = Icons.fingerprint;
|
||||||
onPressed = () =>
|
onPressed = () =>
|
||||||
model.toggleFingerprint(context); // Disable if fingerprint is false
|
model.toggleFingerprint(context); // Disable if fingerprint is false
|
||||||
isEnabled = FFAppState().fingerprint;
|
isEnabled = AppState().fingerprint;
|
||||||
content = FFLocalizations.of(context).getVariableText(
|
content = FFLocalizations.of(context).getVariableText(
|
||||||
ptText:
|
ptText:
|
||||||
'Ative a autenticação por impressão digital para login seguro.',
|
'Ative a autenticação por impressão digital para login seguro.',
|
||||||
|
@ -111,7 +111,7 @@ class PreferencesPageWidget extends StatelessWidget {
|
||||||
case 1:
|
case 1:
|
||||||
icon = Icons.person;
|
icon = Icons.person;
|
||||||
onPressed = () => model.enablePerson(context);
|
onPressed = () => model.enablePerson(context);
|
||||||
isEnabled = FFAppState().person;
|
isEnabled = AppState().person;
|
||||||
content = FFLocalizations.of(context).getVariableText(
|
content = FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Compartilhe o código de identificação remota',
|
ptText: 'Compartilhe o código de identificação remota',
|
||||||
enText: 'Share the remote identification code',
|
enText: 'Share the remote identification code',
|
||||||
|
@ -120,7 +120,7 @@ class PreferencesPageWidget extends StatelessWidget {
|
||||||
case 2:
|
case 2:
|
||||||
icon = Icons.notifications;
|
icon = Icons.notifications;
|
||||||
onPressed = () => model.toggleNotify(context);
|
onPressed = () => model.toggleNotify(context);
|
||||||
isEnabled = FFAppState().notify;
|
isEnabled = AppState().notify;
|
||||||
content = FFLocalizations.of(context).getVariableText(
|
content = FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Ative para receber sua notificação de acesso',
|
ptText: 'Ative para receber sua notificação de acesso',
|
||||||
enText: 'Enable to receive your access notification',
|
enText: 'Enable to receive your access notification',
|
||||||
|
@ -129,7 +129,7 @@ class PreferencesPageWidget extends StatelessWidget {
|
||||||
case 3:
|
case 3:
|
||||||
icon = Icons.lock;
|
icon = Icons.lock;
|
||||||
// onLongPress = model.togglePass(context, model);
|
// onLongPress = model.togglePass(context, model);
|
||||||
isEnabled = FFAppState().pass;
|
isEnabled = AppState().pass;
|
||||||
content = FFLocalizations.of(context).getVariableText(
|
content = FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Ative para inserir uma credencial de acesso para o QRCode',
|
ptText: 'Ative para inserir uma credencial de acesso para o QRCode',
|
||||||
enText: 'Enable to enter an access credential for the QRCode',
|
enText: 'Enable to enter an access credential for the QRCode',
|
||||||
|
@ -138,7 +138,7 @@ class PreferencesPageWidget extends StatelessWidget {
|
||||||
case 4:
|
case 4:
|
||||||
icon = Icons.lock_clock_sharp;
|
icon = Icons.lock_clock_sharp;
|
||||||
// onLongPress = model.togglePass(context, model);
|
// onLongPress = model.togglePass(context, model);
|
||||||
isEnabled = FFAppState().panic;
|
isEnabled = AppState().panic;
|
||||||
content = FFLocalizations.of(context).getVariableText(
|
content = FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Ative para inserir uma credencial de pânico para o QRCode',
|
ptText: 'Ative para inserir uma credencial de pânico para o QRCode',
|
||||||
enText: 'Enable to enter an panic credential for the QRCode',
|
enText: 'Enable to enter an panic credential for the QRCode',
|
||||||
|
|
|
@ -145,14 +145,14 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
safeSetState(() async {
|
safeSetState(() async {
|
||||||
_resetAnimationAndToggleAccess();
|
_resetAnimationAndToggleAccess();
|
||||||
});
|
});
|
||||||
FFAppState().fingerprint
|
AppState().fingerprint
|
||||||
? await _showBiometricsAuth(context)
|
? await _showBiometricsAuth(context)
|
||||||
: await _showQrCodeBottomSheet(context);
|
: await _showQrCodeBottomSheet(context);
|
||||||
},
|
},
|
||||||
child: buildQrCode(
|
child: buildQrCode(
|
||||||
dimension: dimension,
|
dimension: dimension,
|
||||||
errorCorrectLevel: QrErrorCorrectLevel.M,
|
errorCorrectLevel: QrErrorCorrectLevel.M,
|
||||||
identifier: FFAppState().userDevUUID,
|
identifier: AppState().userDevUUID,
|
||||||
pass: _model.key!,
|
pass: _model.key!,
|
||||||
direction: 5,
|
direction: 5,
|
||||||
),
|
),
|
||||||
|
@ -200,7 +200,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
alignment: const AlignmentDirectional(0.0, 0.0),
|
alignment: const AlignmentDirectional(0.0, 0.0),
|
||||||
child: FFButtonWidget(
|
child: FFButtonWidget(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
FFAppState().fingerprint
|
AppState().fingerprint
|
||||||
? await _showBiometricsAuth(context)
|
? await _showBiometricsAuth(context)
|
||||||
: await _showQrCodeBottomSheet(context);
|
: await _showQrCodeBottomSheet(context);
|
||||||
},
|
},
|
||||||
|
@ -362,9 +362,9 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showBiometricsAuth(BuildContext context) async {
|
Future<void> _showBiometricsAuth(BuildContext context) async {
|
||||||
FFAppState()
|
AppState()
|
||||||
.checkBiometrics()
|
.checkBiometrics()
|
||||||
.then((value) => FFAppState().authenticateBiometric().then((value) {
|
.then((value) => AppState().authenticateBiometric().then((value) {
|
||||||
safeSetState(() {
|
safeSetState(() {
|
||||||
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
if (animationsMap['barcodeOnActionTriggerAnimation'] != null) {
|
||||||
animationsMap['barcodeOnActionTriggerAnimation']!
|
animationsMap['barcodeOnActionTriggerAnimation']!
|
||||||
|
@ -375,7 +375,7 @@ class _QrCodePageWidgetState extends State<QrCodePageWidget>
|
||||||
.reverse();
|
.reverse();
|
||||||
}
|
}
|
||||||
_model.isAccess = !_model.isAccess;
|
_model.isAccess = !_model.isAccess;
|
||||||
_model.key = FFAppState().fingerprintPass;
|
_model.key = AppState().fingerprintPass;
|
||||||
});
|
});
|
||||||
}))
|
}))
|
||||||
.onError((error, StackTrace) {
|
.onError((error, StackTrace) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ class _RegisterVisitorPageWidgetState extends State<RegisterVisitorPageWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
|
|
|
@ -64,7 +64,10 @@ class _ScheduleCompleteVisitPageWidgetState
|
||||||
|
|
||||||
// On page load action.
|
// On page load action.
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
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!
|
_model.visitorJsonList = widget.visitorJsonList!
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
widget.visitorStrList ==
|
widget.visitorStrList ==
|
||||||
|
@ -82,7 +85,8 @@ class _ScheduleCompleteVisitPageWidgetState
|
||||||
return;
|
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.dropDownValue1 = widget.dropdownValue1!;
|
||||||
_model.dropDownValue2 = widget.dropdownValue2!;
|
_model.dropDownValue2 = widget.dropdownValue2!;
|
||||||
safeSetState(() {});
|
safeSetState(() {});
|
||||||
|
@ -145,7 +149,7 @@ class _ScheduleCompleteVisitPageWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => _model.unfocusNode.canRequestFocus
|
onTap: () => _model.unfocusNode.canRequestFocus
|
||||||
|
@ -864,7 +868,7 @@ Widget scheduleVisit(BuildContext context,
|
||||||
fadeOutDuration:
|
fadeOutDuration:
|
||||||
const Duration(milliseconds: 500),
|
const Duration(milliseconds: 500),
|
||||||
imageUrl:
|
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,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1078,9 +1082,9 @@ Widget scheduleVisit(BuildContext context,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
child: FutureBuilder<ApiCallResponse>(
|
child: FutureBuilder<ApiCallResponse>(
|
||||||
future: PhpGroup.getDadosCall.call(
|
future: PhpGroup.getDadosCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'getDados',
|
atividade: 'getDados',
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
@ -1098,29 +1102,58 @@ Widget scheduleVisit(BuildContext context,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final dropDownGetDadosResponse = snapshot.data!;
|
final dropDownGetDadosResponse =
|
||||||
final reasonsJsonList = PhpGroup.getDadosCall.reasonsJsonList(dropDownGetDadosResponse.jsonBody);
|
snapshot.data!;
|
||||||
|
final reasonsJsonList =
|
||||||
|
PhpGroup.getDadosCall.reasonsJsonList(
|
||||||
|
dropDownGetDadosResponse.jsonBody);
|
||||||
|
|
||||||
if (_model.dropDownValue1 != '' && _model.dropDownValue1 != null) {
|
if (_model.dropDownValue1 != '' &&
|
||||||
String value = _model.dropDownValue1.toString() ?? '';
|
_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}");
|
// log("Valor e um Objeto | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
|
||||||
} else {
|
} else {
|
||||||
// log("Valor e uma String | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
|
// log("Valor e uma String | Usuário Escolheu o Motivo ${_model.dropDownValue1}");
|
||||||
if (reasonsJsonList != null && reasonsJsonList.isNotEmpty) {
|
if (reasonsJsonList != null &&
|
||||||
var item = reasonsJsonList.where((reason) => reason['MOT_DESCRICAO'].toString().contains(_model.dropDownValue1 ?? ''));
|
reasonsJsonList.isNotEmpty) {
|
||||||
_model.dropDownValue1 = item.firstOrNull.toString() ?? '';
|
var item = reasonsJsonList.where(
|
||||||
|
(reason) =>
|
||||||
|
reason['MOT_DESCRICAO']
|
||||||
|
.toString()
|
||||||
|
.contains(_model
|
||||||
|
.dropDownValue1 ??
|
||||||
|
''));
|
||||||
|
_model.dropDownValue1 =
|
||||||
|
item.firstOrNull.toString() ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FlutterFlowDropDown<String>(
|
return FlutterFlowDropDown<String>(
|
||||||
fillColor: FlutterFlowTheme.of(context).primaryBackground,
|
fillColor: FlutterFlowTheme.of(context)
|
||||||
controller: _model.dropDownValueController1 ??= FormFieldController<String>(_model.dropDownValue1 ??= ''),
|
.primaryBackground,
|
||||||
options: reasonsJsonList != null && reasonsJsonList != [] ? reasonsJsonList.map((e) => e.toString()).toList() : [],
|
controller:
|
||||||
optionLabels: PhpGroup.getDadosCall.reasonsMotDescStrList(dropDownGetDadosResponse.jsonBody),
|
_model.dropDownValueController1 ??=
|
||||||
onChanged: (val) => safeSetState(() => _model.dropDownValue1 = val),
|
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,
|
width: double.infinity,
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
textStyle: FlutterFlowTheme.of(context)
|
textStyle: FlutterFlowTheme.of(context)
|
||||||
|
@ -1202,9 +1235,9 @@ Widget scheduleVisit(BuildContext context,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
child: FutureBuilder<ApiCallResponse>(
|
child: FutureBuilder<ApiCallResponse>(
|
||||||
future: PhpGroup.getDadosCall.call(
|
future: PhpGroup.getDadosCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliUUID: FFAppState().cliUUID,
|
cliUUID: AppState().cliUUID,
|
||||||
atividade: 'getDados',
|
atividade: 'getDados',
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
@ -1223,28 +1256,55 @@ Widget scheduleVisit(BuildContext context,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final dropDownGetDadosResponse = snapshot.data!;
|
final dropDownGetDadosResponse =
|
||||||
final lavelList = PhpGroup.getDadosCall.levelJsonList(dropDownGetDadosResponse.jsonBody);
|
snapshot.data!;
|
||||||
|
final lavelList = PhpGroup.getDadosCall
|
||||||
|
.levelJsonList(
|
||||||
|
dropDownGetDadosResponse.jsonBody);
|
||||||
|
|
||||||
if (_model.dropDownValue2 != '' && _model.dropDownValue2 != null) {
|
if (_model.dropDownValue2 != '' &&
|
||||||
String value = _model.dropDownValue2.toString() ?? '';
|
_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}");
|
// log("Valor e um Objeto | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
|
||||||
} else {
|
} else {
|
||||||
// log("Valor e uma String | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
|
// log("Valor e uma String | Usuário Escolheu o Nivel ${_model.dropDownValue2}");
|
||||||
if (lavelList != null && lavelList.isNotEmpty) {
|
if (lavelList != null &&
|
||||||
var item = lavelList.where((level) => level['NAC_DESCRICAO'].toString().contains(_model.dropDownValue2 ?? ''));
|
lavelList.isNotEmpty) {
|
||||||
_model.dropDownValue2 = item.firstOrNull.toString() ?? '';
|
var item = lavelList.where((level) =>
|
||||||
|
level['NAC_DESCRICAO']
|
||||||
|
.toString()
|
||||||
|
.contains(
|
||||||
|
_model.dropDownValue2 ??
|
||||||
|
''));
|
||||||
|
_model.dropDownValue2 =
|
||||||
|
item.firstOrNull.toString() ?? '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FlutterFlowDropDown<String>(
|
return FlutterFlowDropDown<String>(
|
||||||
controller: _model.dropDownValueController2 ??= FormFieldController<String>(_model.dropDownValue2 ??= ''),
|
controller:
|
||||||
options: lavelList != null && lavelList != [] ? lavelList.map((e) => e.toString()).toList() : [],
|
_model.dropDownValueController2 ??=
|
||||||
optionLabels: PhpGroup.getDadosCall.levelNACDescricaoStrList(dropDownGetDadosResponse.jsonBody),
|
FormFieldController<String>(
|
||||||
onChanged: (val) => safeSetState(() => _model.dropDownValue2 = val),
|
_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,
|
width: double.infinity,
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
textStyle: FlutterFlowTheme.of(context)
|
textStyle: FlutterFlowTheme.of(context)
|
||||||
|
@ -1552,7 +1612,6 @@ Widget scheduleVisit(BuildContext context,
|
||||||
),
|
),
|
||||||
onPressed: _model.isValid()
|
onPressed: _model.isValid()
|
||||||
? () async {
|
? () async {
|
||||||
|
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -1605,8 +1664,8 @@ Widget scheduleVisit(BuildContext context,
|
||||||
), () async {
|
), () async {
|
||||||
await PhpGroup.postScheduleVisitCall
|
await PhpGroup.postScheduleVisitCall
|
||||||
.call(
|
.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
atividade: 'putVisita',
|
atividade: 'putVisita',
|
||||||
devDesc: _model.textController3.text,
|
devDesc: _model.textController3.text,
|
||||||
idVisitante: _model.visitorStrList,
|
idVisitante: _model.visitorStrList,
|
||||||
|
@ -1622,7 +1681,7 @@ Widget scheduleVisit(BuildContext context,
|
||||||
idNAC: extractIdToStr(
|
idNAC: extractIdToStr(
|
||||||
_model.dropDownValue2!),
|
_model.dropDownValue2!),
|
||||||
obs: _model.textController3.text,
|
obs: _model.textController3.text,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
)
|
)
|
||||||
.catchError((e) async {
|
.catchError((e) async {
|
||||||
await DialogUtil.errorDefault(context);
|
await DialogUtil.errorDefault(context);
|
||||||
|
@ -1676,7 +1735,7 @@ Widget scheduleVisit(BuildContext context,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
imagePath:
|
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: {
|
labelsHashMap: {
|
||||||
'Nome': _model.visitorJsonList[0]['VTE_NOME'],
|
'Nome': _model.visitorJsonList[0]['VTE_NOME'],
|
||||||
'Start': _model.textController1.text,
|
'Start': _model.textController1.text,
|
||||||
|
|
|
@ -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:hub/pages/schedule_provisional_visit_page/schedule_provisional_visit_page_model.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
||||||
class ScheduleProvisionalVisitPageWidget extends StatefulWidget {
|
class ScheduleProvisionalVisitPageWidget extends StatefulWidget {
|
||||||
const ScheduleProvisionalVisitPageWidget({super.key});
|
const ScheduleProvisionalVisitPageWidget({super.key});
|
||||||
|
|
||||||
|
@ -55,7 +54,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isFormValid() {
|
bool _isFormValid() {
|
||||||
if (_model.personNameTextController.text == '' || _model.personNameTextController.text.length > 80) {
|
if (_model.personNameTextController.text == '' ||
|
||||||
|
_model.personNameTextController.text.length > 80) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => FocusScope.of(context).unfocus(),
|
onTap: () => FocusScope.of(context).unfocus(),
|
||||||
|
@ -161,9 +161,11 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment: const AlignmentDirectional(-1.0, 0.0),
|
alignment:
|
||||||
|
const AlignmentDirectional(-1.0, 0.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(
|
||||||
24.0, 0.0, 0.0, 0.0),
|
24.0, 0.0, 0.0, 0.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getText(
|
FFLocalizations.of(context).getText(
|
||||||
|
@ -210,7 +212,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
MainAxisAlignment.start,
|
MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius:
|
||||||
|
const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(50.0),
|
bottomLeft: Radius.circular(50.0),
|
||||||
bottomRight:
|
bottomRight:
|
||||||
Radius.circular(50.0),
|
Radius.circular(50.0),
|
||||||
|
@ -218,12 +221,12 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
topRight: Radius.circular(50.0),
|
topRight: Radius.circular(50.0),
|
||||||
),
|
),
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
fadeInDuration:
|
fadeInDuration: const Duration(
|
||||||
const Duration(milliseconds: 200),
|
milliseconds: 200),
|
||||||
fadeOutDuration:
|
fadeOutDuration: const Duration(
|
||||||
const Duration(milliseconds: 200),
|
milliseconds: 200),
|
||||||
imageUrl:
|
imageUrl:
|
||||||
'https://freaccess.com.br/freaccess/Images/Clients/${FFAppState().cliUUID}.png',
|
'https://freaccess.com.br/freaccess/Images/Clients/${AppState().cliUUID}.png',
|
||||||
width: 35.0,
|
width: 35.0,
|
||||||
height: 35.0,
|
height: 35.0,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
|
@ -232,11 +235,10 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsetsDirectional
|
||||||
const EdgeInsetsDirectional.fromSTEB(
|
.fromSTEB(15.0, 0.0, 0.0, 0.0),
|
||||||
15.0, 0.0, 0.0, 0.0),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
FFAppState().local,
|
AppState().local,
|
||||||
style:
|
style:
|
||||||
FlutterFlowTheme.of(context)
|
FlutterFlowTheme.of(context)
|
||||||
.bodyMedium
|
.bodyMedium
|
||||||
|
@ -272,9 +274,11 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
MainAxisAlignment.spaceEvenly,
|
MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment: const AlignmentDirectional(-1.0, 0.0),
|
alignment:
|
||||||
|
const AlignmentDirectional(-1.0, 0.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(
|
||||||
24.0, 10.0, 0.0, 10.0),
|
24.0, 10.0, 0.0, 10.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getText(
|
FFLocalizations.of(context).getText(
|
||||||
|
@ -303,12 +307,11 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
Container(
|
Container(
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
alignment:
|
alignment: const AlignmentDirectional(
|
||||||
const AlignmentDirectional(0.0, 0.0),
|
0.0, 0.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding: const EdgeInsetsDirectional
|
||||||
const EdgeInsetsDirectional.fromSTEB(
|
.fromSTEB(24.0, 0.0, 24.0, 0.0),
|
||||||
24.0, 0.0, 24.0, 0.0),
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
@ -319,7 +322,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
EasyDebounce.debounce(
|
EasyDebounce.debounce(
|
||||||
'_model.personNameTextController',
|
'_model.personNameTextController',
|
||||||
const Duration(milliseconds: 500),
|
const Duration(
|
||||||
|
milliseconds: 500),
|
||||||
() => setState(() {}),
|
() => setState(() {}),
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
|
@ -463,11 +467,12 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment:
|
alignment: const AlignmentDirectional(
|
||||||
const AlignmentDirectional(0.0, 0.0),
|
0.0, 0.0),
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsetsDirectional
|
padding:
|
||||||
|
const EdgeInsetsDirectional
|
||||||
.fromSTEB(
|
.fromSTEB(
|
||||||
24.0, 0.0, 24.0, 0.0),
|
24.0, 0.0, 24.0, 0.0),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
@ -478,7 +483,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
onChanged: (_) =>
|
onChanged: (_) =>
|
||||||
EasyDebounce.debounce(
|
EasyDebounce.debounce(
|
||||||
'_model.dateTimeTextController',
|
'_model.dateTimeTextController',
|
||||||
const Duration(milliseconds: 500),
|
const Duration(
|
||||||
|
milliseconds: 500),
|
||||||
() => setState(() {}),
|
() => setState(() {}),
|
||||||
),
|
),
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
|
@ -590,7 +596,8 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsetsDirectional
|
padding:
|
||||||
|
const EdgeInsetsDirectional
|
||||||
.fromSTEB(
|
.fromSTEB(
|
||||||
24.0, 0.0, 24.0, 0.0),
|
24.0, 0.0, 24.0, 0.0),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
@ -787,23 +794,27 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(
|
padding:
|
||||||
|
const EdgeInsetsDirectional.fromSTEB(
|
||||||
0.0, 10.0, 0.0, 10.0),
|
0.0, 10.0, 0.0, 10.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment:
|
alignment: const AlignmentDirectional(
|
||||||
const AlignmentDirectional(0.0, 0.0),
|
0.0, 0.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
alignment:
|
alignment:
|
||||||
const AlignmentDirectional(0.0, 0.0),
|
const AlignmentDirectional(
|
||||||
|
0.0, 0.0),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: const AlignmentDirectional(
|
alignment:
|
||||||
|
const AlignmentDirectional(
|
||||||
0.0, 0.0),
|
0.0, 0.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsetsDirectional
|
padding:
|
||||||
|
const EdgeInsetsDirectional
|
||||||
.fromSTEB(
|
.fromSTEB(
|
||||||
24.0, 0.0, 24.0, 0.0),
|
24.0, 0.0, 24.0, 0.0),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
@ -961,35 +972,50 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
onPressed: !_isFormValid() ? null : () async {
|
onPressed: !_isFormValid()
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
try {
|
try {
|
||||||
_model.provVisitSchedule = await PhpGroup.postProvVisitSchedulingCall.call(
|
_model.provVisitSchedule = await PhpGroup
|
||||||
devUUID: FFAppState().devUUID,
|
.postProvVisitSchedulingCall
|
||||||
userUUID: FFAppState().userUUID,
|
.call(
|
||||||
cliID: FFAppState().cliUUID,
|
devUUID: AppState().devUUID,
|
||||||
|
userUUID: AppState().userUUID,
|
||||||
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'putAgendamentoProv',
|
atividade: 'putAgendamentoProv',
|
||||||
data: _model.dateTimeTextController.text,
|
data:
|
||||||
|
_model.dateTimeTextController.text,
|
||||||
motivo: _model.notesTextController.text,
|
motivo: _model.notesTextController.text,
|
||||||
nome: _model.personNameTextController.text,
|
nome: _model
|
||||||
proID: FFAppState().ownerUUID,
|
.personNameTextController.text,
|
||||||
|
proID: AppState().ownerUUID,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (PhpGroup.postProvVisitSchedulingCall.error((_model.provVisitSchedule?.jsonBody ?? '')) == false) {
|
if (PhpGroup.postProvVisitSchedulingCall
|
||||||
|
.error((_model.provVisitSchedule
|
||||||
|
?.jsonBody ??
|
||||||
|
'')) ==
|
||||||
|
false) {
|
||||||
DialogUtil.success(
|
DialogUtil.success(
|
||||||
context,
|
context,
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: "Agendamento Provisório Realizado com Sucesso!",
|
ptText:
|
||||||
enText: "Provisional Scheduling Successfully Completed"
|
"Agendamento Provisório Realizado com Sucesso!",
|
||||||
)
|
enText:
|
||||||
);
|
"Provisional Scheduling Successfully Completed"));
|
||||||
setState(() {
|
setState(() {
|
||||||
_model.dateTimeTextController?.clear();
|
_model.dateTimeTextController
|
||||||
_model.personNameTextController?.clear();
|
?.clear();
|
||||||
|
_model.personNameTextController
|
||||||
|
?.clear();
|
||||||
_model.notesTextController?.clear();
|
_model.notesTextController?.clear();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var message = PhpGroup.postProvVisitSchedulingCall.msg((_model.provVisitSchedule?.jsonBody ?? ''));
|
var message = PhpGroup
|
||||||
|
.postProvVisitSchedulingCall
|
||||||
|
.msg((_model.provVisitSchedule
|
||||||
|
?.jsonBody ??
|
||||||
|
''));
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
DialogUtil.error(context, message);
|
DialogUtil.error(context, message);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1000,12 +1026,17 @@ class _ScheduleProvisionalVisitPageWidgetState
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
DialogUtil.errorDefault(context);
|
DialogUtil.errorDefault(context);
|
||||||
LogUtil.requestAPIFailed("processRequest.php", "", "Cadastrar Visita Provisória", e, s);
|
LogUtil.requestAPIFailed(
|
||||||
|
"processRequest.php",
|
||||||
|
"",
|
||||||
|
"Cadastrar Visita Provisória",
|
||||||
|
e,
|
||||||
|
s);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
showLoadingIndicator: true,
|
showLoadingIndicator: true,
|
||||||
text: FFLocalizations.of(context).getText('bv5fg9sv' /* Enviar */),
|
text: FFLocalizations.of(context)
|
||||||
|
.getText('bv5fg9sv' /* Enviar */),
|
||||||
options: FFButtonOptions(
|
options: FFButtonOptions(
|
||||||
width: 150.0,
|
width: 150.0,
|
||||||
height: 50.0,
|
height: 50.0,
|
||||||
|
|
|
@ -36,9 +36,9 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget> {
|
||||||
try {
|
try {
|
||||||
var response = await ScheduleCompleteVisitPageModel().visitHistory(
|
var response = await ScheduleCompleteVisitPageModel().visitHistory(
|
||||||
requestFn: () => PhpGroup.getVisitsCall.call(
|
requestFn: () => PhpGroup.getVisitsCall.call(
|
||||||
devUUID: FFAppState().devUUID,
|
devUUID: AppState().devUUID,
|
||||||
userUUID: FFAppState().userUUID,
|
userUUID: AppState().userUUID,
|
||||||
cliID: FFAppState().cliUUID,
|
cliID: AppState().cliUUID,
|
||||||
atividade: 'getVisitas',
|
atividade: 'getVisitas',
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
pageNumber: pageNumber,
|
pageNumber: pageNumber,
|
||||||
|
@ -113,7 +113,7 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget> {
|
||||||
|
|
||||||
return CardItemTemplateComponentWidget(
|
return CardItemTemplateComponentWidget(
|
||||||
imagePath:
|
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: {
|
labelsHashMap: {
|
||||||
'Nome:': visitaWrapItem['VTE_NOME'] ?? '',
|
'Nome:': visitaWrapItem['VTE_NOME'] ?? '',
|
||||||
'Inicio:': visitaWrapItem['VAW_DTINICIO'] ?? '',
|
'Inicio:': visitaWrapItem['VAW_DTINICIO'] ?? '',
|
||||||
|
|
|
@ -28,13 +28,13 @@ class _WelcomePageWidgetState extends State<WelcomePageWidget> {
|
||||||
// On page load action.
|
// On page load action.
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
if (isAndroid == true) {
|
if (isAndroid == true) {
|
||||||
FFAppState().device = 'Android';
|
AppState().device = 'Android';
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} else if (isiOS == true) {
|
} else if (isiOS == true) {
|
||||||
FFAppState().device = 'iOS';
|
AppState().device = 'iOS';
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} else {
|
} else {
|
||||||
FFAppState().device = 'Web';
|
AppState().device = 'Web';
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -49,7 +49,7 @@ class _WelcomePageWidgetState extends State<WelcomePageWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
context.watch<FFAppState>();
|
context.watch<AppState>();
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => _model.unfocusNode.canRequestFocus
|
onTap: () => _model.unfocusNode.canRequestFocus
|
||||||
|
|
Loading…
Reference in New Issue