From 67dd1b9f920334747396e305727bc661da2926c7 Mon Sep 17 00:00:00 2001 From: jantunesmesias Date: Thu, 11 Jul 2024 09:28:06 -0300 Subject: [PATCH] messages --- .flutter-plugins-dependencies | 2 +- .tool-versions | 1 + lib/backend/api_requests/api_calls.dart | 40 ++ .../pushNotificationService.dart | 60 ++- .../option_selection_modal_widget.dart | 2 +- .../menu_component/menu_component_model.dart | 7 + .../menu_list_view_component_widget.dart | 1 + .../menu_staggered_view_component_widget.dart | 2 + .../message_well_component_model.dart | 36 +- .../message_well_component_widget.dart | 395 ++++++++++++++---- .../message_notification_model.dart | 77 ++++ .../message_notification_widget.dart | 288 +++++++++++++ lib/flutter_flow/nav/nav.dart | 2 + lib/main.dart | 2 + lib/pages/home_page/home_page_model.dart | 2 + lib/pages/home_page/home_page_widget.dart | 17 +- .../message_history_page_model.dart | 50 +++ .../message_history_page_widget.dart | 288 +++++++++++++ pubspec.lock | 48 +++ pubspec.yaml | 3 + 20 files changed, 1216 insertions(+), 107 deletions(-) create mode 100644 .tool-versions create mode 100644 lib/components/templates_components/message_notificaion_modal_template_component/message_notification_model.dart create mode 100644 lib/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart create mode 100644 lib/pages/message_history_page/message_history_page_model.dart create mode 100644 lib/pages/message_history_page/message_history_page_widget.dart diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 3e960510..d5d16702 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","native_build":true,"dependencies":[]},{"name":"file_picker","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_picker-8.0.5\\\\","native_build":true,"dependencies":[]},{"name":"firebase_analytics","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_analytics-11.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_core-3.1.0\\\\","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_messaging-15.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_ios","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_inappwebview_ios-1.0.13\\\\","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_local_notifications-17.1.2\\\\","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage-9.2.2\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_ios","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_ios-0.8.12\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_ios-6.3.0\\\\","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\video_player_avfoundation-2.6.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"webview_flutter_wkwebview","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\webview_flutter_wkwebview-3.13.1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","native_build":true,"dependencies":[]},{"name":"file_picker","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_picker-8.0.5\\\\","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"firebase_analytics","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_analytics-11.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_core-3.1.0\\\\","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_messaging-15.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_inappwebview_android-1.0.13\\\\","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_local_notifications-17.1.2\\\\","native_build":true,"dependencies":[]},{"name":"flutter_plugin_android_lifecycle","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_plugin_android_lifecycle-2.0.20\\\\","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage-9.2.2\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_android-0.8.12+3\\\\","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.5\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.3\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_android-6.3.3\\\\","native_build":true,"dependencies":[]},{"name":"video_player_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\video_player_android-2.5.0\\\\","native_build":true,"dependencies":[]},{"name":"webview_flutter_android","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\webview_flutter_android-3.16.4\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","native_build":true,"dependencies":[]},{"name":"file_selector_macos","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_selector_macos-0.9.4\\\\","native_build":true,"dependencies":[]},{"name":"firebase_analytics","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_analytics-11.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_core-3.1.0\\\\","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_messaging-15.0.1\\\\","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_macos","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_inappwebview_macos-1.0.11\\\\","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_local_notifications-17.1.2\\\\","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_macos","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage_macos-3.1.2\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_macos","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_macos-0.2.1+1\\\\","native_build":false,"dependencies":["file_selector_macos"]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_macos","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_macos-3.2.0\\\\","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\video_player_avfoundation-2.6.1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","native_build":false,"dependencies":[]},{"name":"file_selector_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_selector_linux-0.9.2+1\\\\","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage_linux-1.2.1\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_linux-0.2.1+1\\\\","native_build":false,"dependencies":["file_selector_linux"]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.2\\\\","native_build":false,"dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_linux-3.1.1\\\\","native_build":true,"dependencies":[]}],"windows":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","native_build":false,"dependencies":[]},{"name":"file_selector_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_selector_windows-0.9.3+1\\\\","native_build":true,"dependencies":[]},{"name":"firebase_core","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_core-3.1.0\\\\","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage_windows-3.1.2\\\\","native_build":true,"dependencies":[]},{"name":"image_picker_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_windows-0.2.1+1\\\\","native_build":false,"dependencies":["file_selector_windows"]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.2\\\\","native_build":false,"dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_windows-3.1.1\\\\","native_build":true,"dependencies":[]}],"web":[{"name":"device_info_plus","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-10.1.0\\\\","dependencies":[]},{"name":"file_picker","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\file_picker-8.0.5\\\\","dependencies":[]},{"name":"firebase_analytics_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_analytics_web-0.5.7+9\\\\","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_core_web-2.17.2\\\\","dependencies":[]},{"name":"firebase_messaging_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\firebase_messaging_web-3.8.9\\\\","dependencies":["firebase_core_web"]},{"name":"flutter_inappwebview_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_inappwebview_web-1.0.8\\\\","dependencies":[]},{"name":"flutter_secure_storage_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\flutter_secure_storage_web-1.2.1\\\\","dependencies":[]},{"name":"image_picker_for_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\image_picker_for_web-3.0.4\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.3.0\\\\","dependencies":[]},{"name":"url_launcher_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\url_launcher_web-2.3.1\\\\","dependencies":[]},{"name":"video_player_web","path":"C:\\\\Users\\\\jantu\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\video_player_web-2.3.1\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"device_info_plus","dependencies":[]},{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"file_selector_linux","dependencies":[]},{"name":"file_selector_macos","dependencies":[]},{"name":"file_selector_windows","dependencies":[]},{"name":"firebase_analytics","dependencies":["firebase_analytics_web","firebase_core"]},{"name":"firebase_analytics_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":["firebase_core","firebase_messaging_web"]},{"name":"firebase_messaging_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_inappwebview","dependencies":["flutter_inappwebview_android","flutter_inappwebview_ios","flutter_inappwebview_macos","flutter_inappwebview_web"]},{"name":"flutter_inappwebview_android","dependencies":[]},{"name":"flutter_inappwebview_ios","dependencies":[]},{"name":"flutter_inappwebview_macos","dependencies":[]},{"name":"flutter_inappwebview_web","dependencies":[]},{"name":"flutter_local_notifications","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"image_picker","dependencies":["image_picker_android","image_picker_for_web","image_picker_ios","image_picker_linux","image_picker_macos","image_picker_windows"]},{"name":"image_picker_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"image_picker_ios","dependencies":[]},{"name":"image_picker_linux","dependencies":["file_selector_linux"]},{"name":"image_picker_macos","dependencies":["file_selector_macos"]},{"name":"image_picker_windows","dependencies":["file_selector_windows"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]},{"name":"video_player","dependencies":["video_player_android","video_player_avfoundation","video_player_web"]},{"name":"video_player_android","dependencies":[]},{"name":"video_player_avfoundation","dependencies":[]},{"name":"video_player_web","dependencies":[]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2024-07-04 15:26:15.581529","version":"3.22.2"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","native_build":true,"dependencies":[]},{"name":"file_picker","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_picker-8.0.5/","native_build":true,"dependencies":[]},{"name":"firebase_analytics","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_analytics-11.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_core-3.1.0/","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_messaging-15.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_ios","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_inappwebview_ios-1.0.13/","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_local_notifications-17.1.2/","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.2/","native_build":true,"dependencies":[]},{"name":"image_picker_ios","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_ios-0.8.12/","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/home/wsl/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_ios","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_ios-6.3.0/","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/video_player_avfoundation-2.6.1/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"webview_flutter_wkwebview","path":"/home/wsl/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.13.1/","native_build":true,"dependencies":[]}],"android":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","native_build":true,"dependencies":[]},{"name":"file_picker","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_picker-8.0.5/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"firebase_analytics","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_analytics-11.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_core-3.1.0/","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_messaging-15.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_inappwebview_android-1.0.13/","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_local_notifications-17.1.2/","native_build":true,"dependencies":[]},{"name":"flutter_plugin_android_lifecycle","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.20/","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.2/","native_build":true,"dependencies":[]},{"name":"image_picker_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_android-0.8.12+3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/path_provider_android-2.2.5/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.3/","native_build":true,"dependencies":[]},{"name":"sqflite","path":"/home/wsl/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","native_build":true,"dependencies":[]},{"name":"url_launcher_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.3/","native_build":true,"dependencies":[]},{"name":"video_player_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/video_player_android-2.5.0/","native_build":true,"dependencies":[]},{"name":"webview_flutter_android","path":"/home/wsl/.pub-cache/hosted/pub.dev/webview_flutter_android-3.16.4/","native_build":true,"dependencies":[]}],"macos":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","native_build":true,"dependencies":[]},{"name":"file_selector_macos","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_selector_macos-0.9.4/","native_build":true,"dependencies":[]},{"name":"firebase_analytics","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_analytics-11.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_core-3.1.0/","native_build":true,"dependencies":[]},{"name":"firebase_messaging","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_messaging-15.0.1/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_inappwebview_macos","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_inappwebview_macos-1.0.11/","native_build":true,"dependencies":[]},{"name":"flutter_local_notifications","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_local_notifications-17.1.2/","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_macos","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.2/","native_build":true,"dependencies":[]},{"name":"image_picker_macos","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1+1/","native_build":false,"dependencies":["file_selector_macos"]},{"name":"path_provider_foundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"/home/wsl/.pub-cache/hosted/pub.dev/sqflite-2.3.3+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"url_launcher_macos","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.0/","native_build":true,"dependencies":[]},{"name":"video_player_avfoundation","path":"/home/wsl/.pub-cache/hosted/pub.dev/video_player_avfoundation-2.6.1/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","native_build":false,"dependencies":[]},{"name":"file_selector_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_selector_linux-0.9.2+1/","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.1/","native_build":true,"dependencies":[]},{"name":"image_picker_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_linux-0.2.1+1/","native_build":false,"dependencies":["file_selector_linux"]},{"name":"path_provider_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/","native_build":false,"dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_linux-3.1.1/","native_build":true,"dependencies":[]}],"windows":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","native_build":false,"dependencies":[]},{"name":"file_selector_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3+1/","native_build":true,"dependencies":[]},{"name":"firebase_core","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_core-3.1.0/","native_build":true,"dependencies":[]},{"name":"flutter_secure_storage_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[]},{"name":"image_picker_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1+1/","native_build":false,"dependencies":["file_selector_windows"]},{"name":"path_provider_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/","native_build":false,"dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.1/","native_build":true,"dependencies":[]}],"web":[{"name":"device_info_plus","path":"/home/wsl/.pub-cache/hosted/pub.dev/device_info_plus-10.1.0/","dependencies":[]},{"name":"file_picker","path":"/home/wsl/.pub-cache/hosted/pub.dev/file_picker-8.0.5/","dependencies":[]},{"name":"firebase_analytics_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_analytics_web-0.5.7+9/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_core_web-2.17.2/","dependencies":[]},{"name":"firebase_messaging_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.8.9/","dependencies":["firebase_core_web"]},{"name":"flutter_inappwebview_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_inappwebview_web-1.0.8/","dependencies":[]},{"name":"flutter_secure_storage_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[]},{"name":"image_picker_for_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/image_picker_for_web-3.0.4/","dependencies":[]},{"name":"shared_preferences_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/shared_preferences_web-2.3.0/","dependencies":[]},{"name":"url_launcher_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/url_launcher_web-2.3.1/","dependencies":[]},{"name":"video_player_web","path":"/home/wsl/.pub-cache/hosted/pub.dev/video_player_web-2.3.1/","dependencies":[]}]},"dependencyGraph":[{"name":"device_info_plus","dependencies":[]},{"name":"file_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"file_selector_linux","dependencies":[]},{"name":"file_selector_macos","dependencies":[]},{"name":"file_selector_windows","dependencies":[]},{"name":"firebase_analytics","dependencies":["firebase_analytics_web","firebase_core"]},{"name":"firebase_analytics_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":["firebase_core","firebase_messaging_web"]},{"name":"firebase_messaging_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_inappwebview","dependencies":["flutter_inappwebview_android","flutter_inappwebview_ios","flutter_inappwebview_macos","flutter_inappwebview_web"]},{"name":"flutter_inappwebview_android","dependencies":[]},{"name":"flutter_inappwebview_ios","dependencies":[]},{"name":"flutter_inappwebview_macos","dependencies":[]},{"name":"flutter_inappwebview_web","dependencies":[]},{"name":"flutter_local_notifications","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"image_picker","dependencies":["image_picker_android","image_picker_for_web","image_picker_ios","image_picker_linux","image_picker_macos","image_picker_windows"]},{"name":"image_picker_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"image_picker_ios","dependencies":[]},{"name":"image_picker_linux","dependencies":["file_selector_linux"]},{"name":"image_picker_macos","dependencies":["file_selector_macos"]},{"name":"image_picker_windows","dependencies":["file_selector_windows"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]},{"name":"video_player","dependencies":["video_player_android","video_player_avfoundation","video_player_web"]},{"name":"video_player_android","dependencies":[]},{"name":"video_player_avfoundation","dependencies":[]},{"name":"video_player_web","dependencies":[]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2024-07-11 08:49:55.747362","version":"3.22.2"} \ No newline at end of file diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..a487aa36 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +gradle 7.5 diff --git a/lib/backend/api_requests/api_calls.dart b/lib/backend/api_requests/api_calls.dart index 1823160e..704423d6 100644 --- a/lib/backend/api_requests/api_calls.dart +++ b/lib/backend/api_requests/api_calls.dart @@ -39,6 +39,7 @@ class PhpGroup { static GetLiberationsCall getLiberationsCall = GetLiberationsCall(); static GetLiberationsCopyCall getLiberationsCopyCall = GetLiberationsCopyCall(); + static GetMessagesCall getMessagesCall = GetMessagesCall(); } class UpdToken { @@ -2045,6 +2046,45 @@ class GetLiberationsCall { .toList(); } +class GetMessagesCall { + Future call({ + String? devUUID = '', + String? userUUID = '', + String? cliID = '', + String? atividade = '', + String? pageSize = '', + String? pageNumber = '', + String? tipoDestino = '', + }) async { + final baseUrl = PhpGroup.getBaseUrl(); + + return ApiManager.instance.makeApiCall( + callName: 'getMessages', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'pageSize': pageSize, + 'pageNumber': pageNumber, + 'tipoDestino': tipoDestino, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } +} + class GetLiberationsCopyCall { Future call({ String? devUUID = '', diff --git a/lib/backend/push_notification/pushNotificationService.dart b/lib/backend/push_notification/pushNotificationService.dart index 3c819528..ddfe887c 100644 --- a/lib/backend/push_notification/pushNotificationService.dart +++ b/lib/backend/push_notification/pushNotificationService.dart @@ -7,6 +7,7 @@ import 'package:f_r_e_hub/actions/actions.dart'; import 'package:f_r_e_hub/app_state.dart'; import 'package:f_r_e_hub/backend/api_requests/api_calls.dart'; import 'package:f_r_e_hub/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_widget.dart'; +import 'package:f_r_e_hub/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart'; import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; @@ -20,6 +21,8 @@ class PushNotificationService { final Subject _onMessage = BehaviorSubject(); final BehaviorSubject _context = BehaviorSubject(); + final BehaviorSubject> _notificationDetails = + BehaviorSubject>(); PushNotificationService() { _initializeLocalNotifications(_context); @@ -93,6 +96,8 @@ class PushNotificationService { } } + + void _initializeLocalNotifications( BehaviorSubject context) async { while (context.valueOrNull == null) { @@ -119,7 +124,9 @@ class PushNotificationService { Map message = validJsonFromString(response.payload!); debugPrint('Notification payload: $message'); - _handleNotificationClick(message); + var data = _notificationDetails; // Assuming getOnMessage() now returns the latest RemoteMessage + debugPrint('Extra: ${data.value}'); + _handleNotificationClick(message, extra: data.value ?? {'extra': 'extra'}); } catch (e) { debugPrint('Error decoding notification payload: $e'); } @@ -161,6 +168,7 @@ class PushNotificationService { debugPrint('Got a message whilst in the foreground!'); debugPrint('Message data: ${message.toMap()}'); _onMessage.add(message); + _notificationDetails.add(message.toMap()['notification']); _showNotification(message); }); } @@ -174,8 +182,8 @@ class PushNotificationService { debugPrint('Notification clicked!'); _onMessage.add(message); - NotificationHandler().handleMessage(message.data, context); - }); + debugPrint('Extra: ${message.notification?.body}'); + NotificationHandler().handleMessage(message.data, context); }); } void configureTokenRefresh() { @@ -276,13 +284,14 @@ class PushNotificationService { ); } - _handleNotificationClick(Map payload) { + _handleNotificationClick(Map payload, {Map extra = const {}}) { switch (payload.isNotEmpty) { case true: // Print the 'data' property debugPrint('Notification payload: $payload'); + debugPrint('Extra: $extra'); // Handle the message data as needed - NotificationHandler().handleMessage(payload, _context.value); + NotificationHandler().handleMessage(payload, _context.value, extra: extra.isEmpty ? {} : extra); // Access the 'data' property of 'RemoteMessage' case false: debugPrint('Notification payload is empty'); @@ -298,7 +307,7 @@ class PushNotificationService { } class NotificationHandler { - void handleMessage(Map message, BuildContext context) { + void handleMessage(Map message, BuildContext context, {Map extra = const {}}) { debugPrint('Notification Received!'); message.forEach((key, value) { debugPrint('$key: $value'); @@ -312,10 +321,10 @@ class NotificationHandler { case '': break; case 'access': - _showAcessNotificationModal(message, context); + _showAcessNotificationModal(message, context, extra); break; - case 'mensagem': - debugPrint('mensagem'); + case 'mensagem': + _showMessageNotificationDialog(message, context, extra); break; case 'enroll_cond': debugPrint('enroll_cond'); @@ -326,7 +335,6 @@ class NotificationHandler { } String _getIdBasedOnUserType(Map message) { - // Verifica o tipo de usuário 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 @@ -341,7 +349,7 @@ class NotificationHandler { } void _showAcessNotificationModal( - Map message, BuildContext context) { + Map message, BuildContext context, Map extra) { debugPrint('Showing access notification dialog'); debugPrint('USR_TIPO: ${message['USR_TIPO']}'); debugPrint('USR_ID: ${message['USR_ID']}'); @@ -369,6 +377,26 @@ class NotificationHandler { ); } + void _showMessageNotificationDialog( + Map message, BuildContext context, Map extra) { + debugPrint('Showing message notification dialog'); + showDialog( + context: context, + builder: (BuildContext context) { + return Dialog( + backgroundColor: Colors.transparent, + child: MessageNotificationModalTemplateComponentWidget( + id: message['local']['CLI_ID'].toString(), + from: message['remetente'].toString(), + to: message['destinatario'].toString() == 'O' ? 'Morador' : 'Visitante', + message: extra['body'].toString(), + ), + ); + }, + ); + } + + void _showVisitRequestDialog( Map message, BuildContext context) { debugPrint('Showing visit request notification dialog'); @@ -379,12 +407,12 @@ class NotificationHandler { return Dialog( backgroundColor: Colors.transparent, child: VisitRequestTemplateComponentWidget( - vteName: message['VTE_NOME'] ?? 'Unknown', + vteName: message['mensagem'] ?? 'Unknown', vteReason: message['motivo'] ?? 'Unknown', vteMsg: message['mensagem'] ?? 'Unknown', - vteDocument: message['documento'], - vteUUID: message['idVisitante'].toString(), - vawRef: message['referencia'].toString(), + vteDocument: message['documento'] ?? '', + vteUUID: message['idVisitante'].toString() ?? '0', + vawRef: message['referencia'].toString() ?? '0', vawStatus: 'S', changeStatusAction: changeStatusAction, ), @@ -410,4 +438,6 @@ class PushNotificationManager { void dispose() { _onMessageReceivedController.close(); } + + } diff --git a/lib/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart b/lib/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart index 710ad2eb..2233fc5f 100644 --- a/lib/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart +++ b/lib/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart @@ -81,7 +81,7 @@ class _OptionSelectionModalWidgetState extends State gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 10.0, - mainAxisSpacing: 100.0, + mainAxisSpacing: 10.0, mainAxisExtent: 120.0, childAspectRatio: 10, ), diff --git a/lib/components/organism_components/menu_component/menu_component_model.dart b/lib/components/organism_components/menu_component/menu_component_model.dart index 0115a49f..3db649cc 100644 --- a/lib/components/organism_components/menu_component/menu_component_model.dart +++ b/lib/components/organism_components/menu_component/menu_component_model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import '/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart'; import '/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart'; @@ -130,11 +131,13 @@ class MenuComponentModel extends FlutterFlowModel { 'liberationHistory', 'acessHistoryPage', 'scheduleCompleteVisitPage', + // 'messageHistoryPage', ], iconsListIcon: [ Icons.history_rounded, Icons.history_rounded, Icons.history_rounded, + // Icons.history_rounded, ], nameListStr: [ FFLocalizations.of(context).getVariableText( @@ -149,6 +152,10 @@ class MenuComponentModel extends FlutterFlowModel { ptText: 'Histórico\nde Visita', enText: 'Visit\nHistory', ), + // FFLocalizations.of(context).getVariableText( + // ptText: 'Histórico\nde Mensagens', + // enText: 'Message\nHistory', + // ), ], ), ); diff --git a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart index 60458b48..3ecbeee8 100644 --- a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart +++ b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:google_fonts/google_fonts.dart'; import '/flutter_flow/flutter_flow_icon_button.dart'; diff --git a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart index 7271a6c9..96c065f9 100644 --- a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart +++ b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:google_fonts/google_fonts.dart'; diff --git a/lib/components/organism_components/message_well_component/message_well_component_model.dart b/lib/components/organism_components/message_well_component/message_well_component_model.dart index 3da2a723..89ce0d76 100644 --- a/lib/components/organism_components/message_well_component/message_well_component_model.dart +++ b/lib/components/organism_components/message_well_component/message_well_component_model.dart @@ -1,12 +1,46 @@ +import 'package:f_r_e_hub/backend/api_requests/api_manager.dart'; +import 'package:f_r_e_hub/flutter_flow/request_manager.dart'; + import '/flutter_flow/flutter_flow_util.dart'; import 'message_well_component_widget.dart' show MessageWellComponentWidget; import 'package:flutter/material.dart'; class MessageWellComponentModel extends FlutterFlowModel { + final unfocusNode = FocusNode(); + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode; + TextEditingController? textController; + String? Function(BuildContext, String?)? textControllerValidator; + + /// Query cache managers for this widget. + + final _getLiberationsManager = StreamRequestManager(); + Stream getLiberations({ + String? uniqueQueryKey, + bool? overrideCache, + required Stream Function() requestFn, + }) => + _getLiberationsManager.performRequest( + uniqueQueryKey: uniqueQueryKey, + overrideCache: overrideCache, + requestFn: requestFn, + ); + void clearGetLiberationsCache() => _getLiberationsManager.clear(); + void clearGetLiberationsCacheKey(String? uniqueKey) => + _getLiberationsManager.clearRequest(uniqueKey); + @override void initState(BuildContext context) {} @override - void dispose() {} + void dispose() { + unfocusNode.dispose(); + textFieldFocusNode?.dispose(); + textController?.dispose(); + + /// Dispose query cache managers for this widget. + + clearGetLiberationsCache(); + } } diff --git a/lib/components/organism_components/message_well_component/message_well_component_widget.dart b/lib/components/organism_components/message_well_component/message_well_component_widget.dart index d8a5b8b8..c28173b5 100644 --- a/lib/components/organism_components/message_well_component/message_well_component_widget.dart +++ b/lib/components/organism_components/message_well_component/message_well_component_widget.dart @@ -1,10 +1,12 @@ -import '/flutter_flow/flutter_flow_theme.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import '/flutter_flow/flutter_flow_widgets.dart'; +import 'package:f_r_e_hub/app_state.dart'; +import 'package:f_r_e_hub/backend/api_requests/api_calls.dart'; +import 'package:f_r_e_hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:f_r_e_hub/flutter_flow/internationalization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'message_well_component_model.dart'; -export 'message_well_component_model.dart'; +import 'package:provider/provider.dart'; + class MessageWellComponentWidget extends StatefulWidget { const MessageWellComponentWidget({super.key}); @@ -14,105 +16,57 @@ class MessageWellComponentWidget extends StatefulWidget { _MessageWellComponentWidgetState(); } -class _MessageWellComponentWidgetState - extends State { - late MessageWellComponentModel _model; +class _MessageWellComponentWidgetState extends State { + late ScrollController _listViewController; + bool _allowScrollInSingleChildScrollView = true; + + VoidCallback get _scrollListener => MessageWellNotifier()._scrollListener; + final dropdownValueNotifier = ValueNotifier('All'); // Using ValueNotifier for state management - @override - void setState(VoidCallback callback) { - super.setState(callback); - _model.onUpdate(); - } @override void initState() { super.initState(); - _model = createModel(context, () => MessageWellComponentModel()); + _listViewController = ScrollController(); + _listViewController.addListener(_scrollListener); // Adicione esta linha + // WidgetsBinding.instance?.addPostFrameCallback((_) { + // context.read().fetchMessages(); + // }); } @override void dispose() { - _model.maybeDispose(); - + _listViewController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { + final state = context.watch(); + final messages = state.getMessages(); + final theme = FlutterFlowTheme.of(context); return Align( - alignment: const AlignmentDirectional(0.0, 0.0), + alignment: Alignment.center, child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 40.0, 0.0, 0.0), - child: Container( - width: double.infinity, - height: 167.0, - decoration: const BoxDecoration(), + padding: const EdgeInsets.symmetric(vertical: 40.0), + child: SizedBox( + height: MediaQuery.of(context).size.height * 0.8, child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, children: [ - Text( - FFLocalizations.of(context).getText( - '8fworxmb' /* Mural de Mensagens */, - ), - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: 'Nunito Sans', - letterSpacing: 0.0, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Nunito Sans'), - ), - ), - Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 5.0, 0.0, 0.0), - child: FFButtonWidget( - onPressed: () { - print('Button pressed ...'); - }, - text: FFLocalizations.of(context).getText( - 'yikill36' /* Todos */, - ), - options: FFButtonOptions( - width: 260.0, - height: 20.0, - padding: - const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), - iconPadding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), - color: const Color(0xFF1AAB5F), - textStyle: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: - FlutterFlowTheme.of(context).labelMediumFamily, - color: FlutterFlowTheme.of(context).customColor4, - letterSpacing: 0.0, - fontWeight: FontWeight.normal, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).labelMediumFamily), - ), - elevation: 3.0, - borderSide: const BorderSide( - color: Colors.transparent, - width: 1.0, - ), - borderRadius: BorderRadius.circular(8.0), - ), - ), - ), + _buildHandleMessageWell(context, theme), + _buildMenuMessageWell(context, theme, dropdownValueNotifier), Expanded( - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 10.0, 0.0, 0.0), - child: Container( - width: 464.0, - height: 127.0, - decoration: const BoxDecoration( - shape: BoxShape.rectangle, - ), - child: ListView( - padding: EdgeInsets.zero, - scrollDirection: Axis.vertical, - children: const [], - ), + child: NotificationListener( + onNotification: _buildScrollMessageListManager, + child: ListView.builder( + controller: _listViewController, + itemCount: messages.length, + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + itemBuilder: (context, index) { + var message = messages[index]; + return _buildMessageItem(context, message, index); + }, ), ), ), @@ -122,4 +76,275 @@ class _MessageWellComponentWidgetState ), ); } + + +bool _buildScrollMessageListManager(ScrollNotification notification) { + final notifier = context.read(); + if (notification is ScrollUpdateNotification) { + debugPrint('Scrolling ...'); + if (_listViewController.offset <= 0 && notification.scrollDelta! < 0) { + debugPrint('Scrolling up ...'); + setState(() { + _allowScrollInSingleChildScrollView = true; + }); + } else { + debugPrint('Scrolling down ...'); + if (_listViewController.position.extentAfter == 0) { + debugPrint('Reached end of list. Incrementing pageNumber...'); + notifier.incrementPageNumber(); + } + setState(() { + _allowScrollInSingleChildScrollView = false; + // MessageWellNotifier().fetchMessages(); + }); + } + } + return true; } + +Widget _buildMenuMessageWell(BuildContext context, FlutterFlowTheme theme, ValueNotifier dropdownValueNotifier) { + + final locations = FFLocalizations.of(context); + late String all = locations.getVariableText(enText: 'All', ptText: 'All'); + late String personal = locations.getVariableText(enText: 'Personal', ptText: 'Pessoal'); + late String global = locations.getVariableText(enText: 'Global', ptText: 'Global'); + + return SizedBox( + key: UniqueKey(), + width: 200, + height: 40, + child: ValueListenableBuilder( + valueListenable: dropdownValueNotifier, + builder: (context, value, child) { + return DropdownButtonFormField( + value: value, + decoration: InputDecoration( + contentPadding: EdgeInsets.symmetric(horizontal: 10.0), + border: OutlineInputBorder( + borderSide: BorderSide( + color: theme.primary, // Assuming FlutterFlowTheme.of(context).primary is the correct usage + width: 2, // Adjusted width to a reasonable value + ), + borderRadius: BorderRadius.circular(10), + ), + filled: true, + fillColor: theme.primary, + ), + onChanged: (String? newValue) { + if (newValue != null) { + // logger.log('DropDown value: $newValue'); // Assuming logger is correctly initialized elsewhere + dropdownValueNotifier.value = newValue; // Update the ValueNotifier value + } + }, + items: [ + DropdownMenuItem(value: all, child: Text(all)), + DropdownMenuItem(value: personal, child: Text(personal)), + DropdownMenuItem(value: global, child: Text(global)), + ], + style: theme.labelMedium.override( + fontFamily: theme.labelMediumFamily, + color: theme.primaryText, + useGoogleFonts: GoogleFonts.asMap().containsKey(theme.labelMediumFamily), + ), + ); + }, + ), + ); +} + + Text _buildHandleMessageWell(BuildContext context, FlutterFlowTheme theme) { + return Text( + FFLocalizations.of(context).getText('8fworxmb'), // Mural de Mensagens + style: theme.bodyMedium.override( + fontFamily: 'Nunito Sans', + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito Sans'), + ), + ); + } + + Widget _buildMessageItem(BuildContext context, dynamic message, int index) { + final theme = Theme.of(context); + String formatMessageOrigin(String messageOrigin) { + final words = messageOrigin.split(' '); + final formattedWords = words.map((word) { + final firstLetter = word.substring(0, 1).toUpperCase(); + final remainingLetters = word.substring(1).toLowerCase(); + return '$firstLetter$remainingLetters'; + }); + return formattedWords.join(' '); + } + return GestureDetector( + onTap: () => print('Message tapped ...\nmessage[$index]: $message'), + child: Padding( + padding: const EdgeInsets.fromLTRB(20, 5, 20, 5), + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + height: 127.0, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + width: 64.0, + height: 64.0, + decoration: const BoxDecoration(shape: BoxShape.circle), + ), + ), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 8.0), + Center( + child: Text( + '~ ${formatMessageOrigin(message['MSG_ORIGEM_DESC'].toString())}', + style: theme.textTheme.headlineMedium!.copyWith( + fontFamily: 'Nunito Sans', + color: FlutterFlowTheme.of(context).primary, + fontSize: 14.0, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 8.0), + Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Text( + formatMessageOrigin(message['MSG_TEXTO'].toString()), + style: theme.textTheme.bodyMedium!.copyWith( + fontFamily: 'Nunito Sans', + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 14.0, + ), + softWrap: true, + maxLines: 10, + ), + ), + ), + ], + ), + ) + ], + ), + ), + ), + ); +} +} + +class MessageWellState { + final List messages; + int pageNumber; + final bool allowScrollInSingleChildScrollView; + final ScrollController listViewController; + + MessageWellState({ + required this.messages, + this.pageNumber = 1, + required this.allowScrollInSingleChildScrollView, + required this.listViewController, + }); + + MessageWellState copyWith({ + List? messages, + int? pageNumber, + bool? allowScrollInSingleChildScrollView, + ScrollController? listViewController, + }) { + return MessageWellState( + messages: messages ?? this.messages, + pageNumber: pageNumber ?? this.pageNumber, + allowScrollInSingleChildScrollView: allowScrollInSingleChildScrollView ?? this.allowScrollInSingleChildScrollView, + listViewController: listViewController ?? this.listViewController, + ); + } +} + +class MessageWellNotifier extends StateNotifier { + var totalPageNumber = 1; + + MessageWellNotifier() + : super(MessageWellState(messages: [], allowScrollInSingleChildScrollView: true, listViewController: ScrollController())) { + state.listViewController.addListener(_scrollListener); + fetchMessages(); + } + + void fetchMessages() async { + if (state.pageNumber <= totalPageNumber) { + var apiCall = GetMessagesCall(); + var response = await apiCall.call( + devUUID: FFAppState().devUUID.toString(), + userUUID: FFAppState().userUUID.toString(), + cliID: FFAppState().cliUUID.toString(), + atividade: 'getMensagens', + pageSize: '10', + pageNumber: state.pageNumber.toString(), + tipoDestino: 'A', + ); + if (response.statusCode == 200) { + var messagesData = response.jsonBody['mensagens']; + debugPrint('inputs: ${FFAppState().devUUID}, ${FFAppState().userUUID}, ${FFAppState().cliUUID}'); + debugPrint('response: ${response.jsonBody}'); + debugPrint('response[mensagens]: $messagesData'); + debugPrint('response[mensagens][0][MSG_TEXTO]: ${messagesData[0]['MSG_TEXTO']}'); + var newMessages = [...state.messages, ...messagesData]; + var rExp = RegExp(r'\d+').allMatches(newMessages.toString()).map((e) => e.group(0)).toList(); + debugPrint('rExp: $rExp'); + debugPrint('newMessages: $newMessages'); + state = state.copyWith(messages: newMessages); + totalPageNumber = int.parse(response.jsonBody['total_pages']); + debugPrint('totalPageNumber: $totalPageNumber'); + } else { + debugPrint('Error fetching messages: ${response.statusCode}'); + } + } else { + debugPrint('No more messages to fetch ...'); + } + } + + List getMessages() { + return state.messages; + } + + void _scrollListener() { + if (!state.allowScrollInSingleChildScrollView) { + if (state.pageNumber <= totalPageNumber) { + state = state.copyWith(pageNumber: state.pageNumber + 1); + debugPrint('state.pageNumber: ${state.pageNumber}'); + fetchMessages(); + } + } + } + + @override + void dispose() { + state.listViewController.removeListener(_scrollListener); + super.dispose(); + } + + void incrementPageNumber() { + if (state.pageNumber <= totalPageNumber) { + state = state.copyWith(pageNumber: state.pageNumber + 1); + debugPrint('state.pageNumber: ${state.pageNumber}'); + } + } +} + + +mixin Logger { + static void log(String message) { + debugPrint('Logger: $message'); + } +} + +final messageWellProvider = StateNotifierProvider((ref) { + return MessageWellNotifier(); +}); diff --git a/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_model.dart b/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_model.dart new file mode 100644 index 00000000..2e5bc0c6 --- /dev/null +++ b/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_model.dart @@ -0,0 +1,77 @@ +import '/backend/api_requests/api_calls.dart'; +import '/flutter_flow/flutter_flow_util.dart'; +import 'message_notification_widget.dart' + show MessageNotificationModalTemplateComponentWidget; +import 'package:flutter/material.dart'; + +class MessageNotificationModalTemplateComponentModel + extends FlutterFlowModel { + /// State fields for stateful widgets in this component. + + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode1; + TextEditingController? textController1; + String? Function(BuildContext, String?)? textController1Validator; + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode2; + TextEditingController? textController2; + String? Function(BuildContext, String?)? textController2Validator; + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode3; + TextEditingController? textController3; + String? Function(BuildContext, String?)? textController3Validator; + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode4; + TextEditingController? textController4; + String? Function(BuildContext, String?)? textController4Validator; + + @override + void initState(BuildContext context) {} + + @override + void dispose() { + textFieldFocusNode1?.dispose(); + textController1?.dispose(); + + textFieldFocusNode2?.dispose(); + textController2?.dispose(); + + textFieldFocusNode3?.dispose(); + textController3?.dispose(); + + textFieldFocusNode4?.dispose(); + textController4?.dispose(); + } + + /// Action blocks. + Future visitRequestComponentAction( + BuildContext context, { + required String? actionValue, + required String? refUUID, + required String? responseValue, + required String? vteUUID, + }) async { + ApiCallResponse? visitRequest; + + visitRequest = await PhpGroup.respondeSolicitacaoCall.call( + userUUID: FFAppState().userUUID, + devUUID: FFAppState().devUUID, + cliUUID: FFAppState().cliUUID, + atividade: 'respondeSolicitacao', + referencia: refUUID, + tarefa: actionValue, + resposta: responseValue, + idVisitante: vteUUID, + ); + + if (PhpGroup.respondeSolicitacaoCall.error( + (visitRequest.jsonBody ?? ''), + ) == + false) { + Navigator.pop(context); + return true; + } else { + return false; + } + } +} diff --git a/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart b/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart new file mode 100644 index 00000000..3a67f3dd --- /dev/null +++ b/lib/components/templates_components/message_notificaion_modal_template_component/message_notification_widget.dart @@ -0,0 +1,288 @@ +import '/flutter_flow/flutter_flow_theme.dart'; +import '/flutter_flow/flutter_flow_util.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; +import 'message_notification_model.dart'; + +class MessageNotificationModalTemplateComponentWidget extends StatefulWidget { + const MessageNotificationModalTemplateComponentWidget({ + super.key, + required this.message, + required this.from, + required this.to, + required this.id, + }); + + final String? message; + final String? from; + final String? to; + final String? id; + + @override + State createState() => + _MessageNotificationModalTemplateComponentWidgetState(); +} + +class _MessageNotificationModalTemplateComponentWidgetState + extends State { + late MessageNotificationModalTemplateComponentModel _model; + + @override + void setState(VoidCallback callback) { + super.setState(callback); + _model.onUpdate(); + } + + @override + void initState() { + super.initState(); + _model = createModel( + context, () => MessageNotificationModalTemplateComponentModel()); + + _model.textController1 ??= TextEditingController(text: widget.message); + _model.textFieldFocusNode1 ??= FocusNode(); + + _model.textController2 ??= TextEditingController(text: widget.from); + _model.textFieldFocusNode2 ??= FocusNode(); + + _model.textController3 ??= TextEditingController(text: widget.to); + _model.textFieldFocusNode3 ??= FocusNode(); + + } + + @override + void dispose() { + _model.maybeDispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + context.watch(); + + return Align( + alignment: const AlignmentDirectional(0.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(10.0, 0.0, 10.0, 0.0), + child: Container( + width: MediaQuery.sizeOf(context).width * 0.9, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).primaryBackground, + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(25.0), + bottomRight: Radius.circular(25.0), + topLeft: Radius.circular(25.0), + topRight: Radius.circular(25.0), + ), + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 24.0, 0.0, 24.0, 0.0), + child: TextFormField( + controller: _model.textController1, + focusNode: _model.textFieldFocusNode1, + autofocus: false, + textInputAction: TextInputAction.next, + readOnly: true, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelText: FFLocalizations.of(context).getVariableText( + ptText: 'Mensagem', + enText: 'Message', + ), + + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: + FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).labelMediumFamily), + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: + FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).labelMediumFamily), + ), + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, + suffixIcon: Icon( + Icons.message, + color: FlutterFlowTheme.of(context).accent1, + ), + ), + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + FlutterFlowTheme.of(context).bodyMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + ), + textAlign: TextAlign.start, + maxLines: null, + keyboardType: TextInputType.name, + validator: + _model.textController1Validator.asValidator(context), + ), + ), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: TextFormField( + controller: _model.textController2, + focusNode: _model.textFieldFocusNode2, + autofocus: false, + textInputAction: TextInputAction.next, + readOnly: true, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelText: FFLocalizations.of(context).getVariableText( + ptText: 'De', + enText: 'From', + ), + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: FlutterFlowTheme.of(context) + .labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .labelMediumFamily), + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: FlutterFlowTheme.of(context) + .labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .labelMediumFamily), + ), + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, + suffixIcon: Icon( + Icons.person, + color: FlutterFlowTheme.of(context).accent1, + ), + ), + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + FlutterFlowTheme.of(context).bodyMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .bodyMediumFamily), + ), + textAlign: TextAlign.start, + maxLines: null, + keyboardType: TextInputType.name, + validator: _model.textController2Validator + .asValidator(context), + ), + ), + ] + .addToStart(const SizedBox(width: 24.0)) + .addToEnd(const SizedBox(width: 24.0)), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 24.0, 0.0, 24.0, 0.0), + child: TextFormField( + controller: _model.textController3, + focusNode: _model.textFieldFocusNode3, + autofocus: false, + textInputAction: TextInputAction.next, + readOnly: true, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelText: FFLocalizations.of(context).getVariableText( + ptText: 'Para', + enText: 'To', + ), + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: + FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).labelMediumFamily), + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: + FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).labelMediumFamily), + ), + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, + suffixIcon: Icon( + Icons.person, + color: FlutterFlowTheme.of(context).accent1, + ), + ), + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + FlutterFlowTheme.of(context).bodyMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + ), + textAlign: TextAlign.start, + maxLines: null, + keyboardType: TextInputType.name, + validator: + _model.textController3Validator.asValidator(context), + ), + ), + + + ] + .divide(const SizedBox(height: 10.0)) + .addToStart(const SizedBox(height: 20.0)) + .addToEnd(const SizedBox(height: 20.0)), + ), + ), + ), + ), + ); + } +} diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 104b4c75..adde80eb 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:f_r_e_hub/pages/fast_pass_page/fast_pass_page_widget.dart'; +import 'package:f_r_e_hub/pages/message_history_page/message_history_page_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -77,6 +78,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter( path: '/visitHistoryPage', builder: (context, params) => const VisitHistoryPageWidget(), ), + FFRoute(name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => const MessageHistoryPageWidget()), FFRoute( name: 'registerVisitorPage', path: '/registerVisitorPage', diff --git a/lib/main.dart b/lib/main.dart index c9614d60..e9e8d587 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,8 @@ // import 'package:firebase_messaging/firebase_messaging.dart'; // import 'package:flutter_local_notifications/flutter_local_notifications.dart'; // import 'package:firebase_analytics/firebase_analytics.dart'; + + import 'package:firebase_core/firebase_core.dart'; import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; diff --git a/lib/pages/home_page/home_page_model.dart b/lib/pages/home_page/home_page_model.dart index 01e742ae..d938eebc 100644 --- a/lib/pages/home_page/home_page_model.dart +++ b/lib/pages/home_page/home_page_model.dart @@ -1,3 +1,5 @@ +import 'package:f_r_e_hub/components/organism_components/message_well_component/message_well_component_model.dart'; + import '/components/organism_components/local_profile_component/local_profile_component_widget.dart'; import '/components/organism_components/menu_component/menu_component_widget.dart'; import '/components/organism_components/message_well_component/message_well_component_widget.dart'; diff --git a/lib/pages/home_page/home_page_widget.dart b/lib/pages/home_page/home_page_widget.dart index 6e3573c1..2fb8f6c8 100644 --- a/lib/pages/home_page/home_page_widget.dart +++ b/lib/pages/home_page/home_page_widget.dart @@ -1098,6 +1098,7 @@ class _HomePageWidgetState extends State { Wrap( spacing: 0.0, runSpacing: 0.0, + alignment: WrapAlignment.start, crossAxisAlignment: WrapCrossAlignment.start, direction: Axis.horizontal, @@ -1112,12 +1113,20 @@ class _HomePageWidgetState extends State { ), Align( alignment: const AlignmentDirectional(0.0, 0.0), - child: wrapWithModel( - model: _model.messageWellComponentModel, - updateCallback: () => setState(() {}), - child: const MessageWellComponentWidget(), + child: Provider( + create: (_) => MessageWellNotifier(), + child: wrapWithModel( + model: _model.messageWellComponentModel, + updateCallback: () => setState(() {}), + child: const MessageWellComponentWidget(), + ), ), ), + //footer + const SizedBox( + height: 100, + width: double.infinity, + ) ], ), ], diff --git a/lib/pages/message_history_page/message_history_page_model.dart b/lib/pages/message_history_page/message_history_page_model.dart new file mode 100644 index 00000000..1bfa4793 --- /dev/null +++ b/lib/pages/message_history_page/message_history_page_model.dart @@ -0,0 +1,50 @@ +import '/backend/api_requests/api_calls.dart'; +import '/flutter_flow/flutter_flow_util.dart'; +import '/flutter_flow/request_manager.dart'; + +import 'message_history_page_widget.dart' show MessageHistoryPageWidget; +import 'package:flutter/material.dart'; + +class MessageHistoryPageModel extends FlutterFlowModel { + /// State fields for stateful widgets in this page. + /// + + //copyWith + + final unfocusNode = FocusNode(); + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode; + TextEditingController? textController; + String? Function(BuildContext, String?)? textControllerValidator; + + /// Query cache managers for this widget. + + final _getLiberationsManager = StreamRequestManager(); + Stream getLiberations({ + String? uniqueQueryKey, + bool? overrideCache, + required Stream Function() requestFn, + }) => + _getLiberationsManager.performRequest( + uniqueQueryKey: uniqueQueryKey, + overrideCache: overrideCache, + requestFn: requestFn, + ); + void clearGetLiberationsCache() => _getLiberationsManager.clear(); + void clearGetLiberationsCacheKey(String? uniqueKey) => + _getLiberationsManager.clearRequest(uniqueKey); + + @override + void initState(BuildContext context) {} + + @override + void dispose() { + unfocusNode.dispose(); + textFieldFocusNode?.dispose(); + textController?.dispose(); + + /// Dispose query cache managers for this widget. + + clearGetLiberationsCache(); + } +} diff --git a/lib/pages/message_history_page/message_history_page_widget.dart b/lib/pages/message_history_page/message_history_page_widget.dart new file mode 100644 index 00000000..4bf6991f --- /dev/null +++ b/lib/pages/message_history_page/message_history_page_widget.dart @@ -0,0 +1,288 @@ +// import 'dart:js_interop'; + +import 'package:f_r_e_hub/actions/actions.dart'; +import 'package:f_r_e_hub/backend/push_notification/pushNotificationService.dart'; +import 'package:f_r_e_hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:f_r_e_hub/components/templates_components/visit_request_template_component/visit_request_template_component_widget.dart'; + +import '/backend/api_requests/api_calls.dart'; +import '/flutter_flow/flutter_flow_icon_button.dart'; +import '/flutter_flow/flutter_flow_theme.dart'; +import '/flutter_flow/flutter_flow_util.dart'; +import '/flutter_flow/custom_functions.dart' as functions; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:provider/provider.dart'; +import 'message_history_page_model.dart'; + +class MessageHistoryPageWidget extends StatefulWidget { + const MessageHistoryPageWidget({super.key}); + + @override + State createState() => + _MessageHistoryPageWidgetState(); +} + +class _MessageHistoryPageWidgetState extends State { + late MessageHistoryPageModel _model; + + final scaffoldKey = GlobalKey(); + + @override + void initState() { + super.initState(); + _model = createModel(context, () => MessageHistoryPageModel()); + + _model.textController ??= TextEditingController(); + _model.textFieldFocusNode ??= FocusNode(); + } + + @override + void dispose() { + _model.dispose(); + + super.dispose(); + } + + void onUpdate(BuildContext context) { + _model.clearGetLiberationsCache(); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + context.watch(); + return GestureDetector( + onTap: () => _model.unfocusNode.canRequestFocus + ? FocusScope.of(context).requestFocus(_model.unfocusNode) + : FocusScope.of(context).unfocus(), + child: Scaffold( + key: scaffoldKey, + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + appBar: appBarLiberationHistoryPage(context), + body: bodyLiberationHistoryPage(context, _model), + ), + ); + } +} + +PreferredSizeWidget appBarLiberationHistoryPage(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + leading: FlutterFlowIconButton( + borderColor: Colors.transparent, + borderRadius: 30.0, + borderWidth: 1.0, + buttonSize: 60.0, + icon: Icon( + Icons.keyboard_arrow_left, + color: FlutterFlowTheme.of(context).primaryText, + size: 30.0, + ), + onPressed: () async { + context.pop(); + }, + ), + title: Text( + FFLocalizations.of(context).getText( + '784f83pc' /* Histórico de Liberação */, + ), + style: FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: 'Nunito', + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 17.0, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + ), + ), + actions: const [], + centerTitle: true, + ); +} + +Widget bodyLiberationHistoryPage( + BuildContext context, MessageHistoryPageModel _model) { + return SafeArea( + top: true, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded(child: liberationDynamicListView(context, _model)), + ].addToStart(const SizedBox(height: 0)), + ), + ); +} + + + + +Widget liberationDynamicListView( + BuildContext context, + MessageHistoryPageModel _model, +) { + return Container( + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration(), + child: StreamBuilder( + stream: _model.getLiberations( + requestFn: () => PhpGroup.getLiberationsCall.call( + devUUID: FFAppState().devUUID, + userUUID: FFAppState().userUUID, + cliID: FFAppState().cliUUID, + atividade: 'getSolicitacoes', + ), + ), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return Center( + child: SizedBox( + width: 50.0, + height: 50.0, + child: SpinKitCircle( + color: FlutterFlowTheme.of(context).primary, + size: 50.0, + ), + ), + ); + } + final columnGetLiberationsResponse = snapshot.data!; + final liberationHistory = PhpGroup.getLiberationsCall + .rqList( + columnGetLiberationsResponse.jsonBody, + ) + ?.toList() ?? + []; + final filteredLiberationHistory = _model.textController.text.isNotEmpty + ? liberationHistory + .where((item) => functions + .jsonToStr(getJsonField( + item, + r'''$.VTE_NOME''', + )) + .toLowerCase() + .contains( + _model.textController.text.toLowerCase(), + )) + .toList() + : liberationHistory; + + return ListView.builder( + itemCount: filteredLiberationHistory.length, + addAutomaticKeepAlives: false, + addRepaintBoundaries: true, + cacheExtent: 1000.0, + itemBuilder: (BuildContext context, int index) { + final liberationHistoryItem = filteredLiberationHistory[index]; + return Padding( + padding: EdgeInsets.only( + top: index == 0 + ? MediaQuery.of(context).size.height * 0.075 + : 8.0, + left: 8.0, + right: 8.0, + bottom: 8.0, + ), + child: Align( + alignment: AlignmentDirectional(0.0, 0.0), + child: liberationHistoryItemCard( + context, + liberationHistoryItem, + ), + ), + ); + }, + ); + }, + ), + ); +} + +Widget liberationHistoryItemCard( + BuildContext context, dynamic liberationHistoryItem) { + return CardItemTemplateComponentWidget( + imageHashMap: Map.from({ + 'key': liberationHistoryItem['VTE_ID'], + 'value': 'E', + }), + labelsHashMap: Map.from({ + 'Nome:': liberationHistoryItem['VTE_NOME'], + 'Data:': liberationHistoryItem['NOT_DTENVIO'], + 'Motivo:': liberationHistoryItem['NOT_MOTIVO'], + }), + statusHashMap: liberationHistoryItem['NOT_STATUS'] == 'L' + ? Map.from({ + FFLocalizations.of(context).getVariableText( + ptText: 'Ativo', + enText: 'Active', + ): FlutterFlowTheme.of(context).success, + }) + : liberationHistoryItem['NOT_STATUS'] == 'B' + ? Map.from({ + FFLocalizations.of(context).getVariableText( + ptText: 'Bloqueado', + enText: 'Blocked', + ): FlutterFlowTheme.of(context).error, + }) + : Map.from({ + FFLocalizations.of(context).getVariableText( + ptText: 'Pendente', + enText: 'Pending', + ): FlutterFlowTheme.of(context).warning, + }), + onTapCardItemAction: () async { + showModalBottomSheet( + isScrollControlled: true, + isDismissible: true, + backgroundColor: Colors.transparent, + useSafeArea: true, + context: context, + builder: (context) { + return VisitRequestTemplateComponentWidget( + vteName: liberationHistoryItem['VTE_NOME'], + vteReason: liberationHistoryItem['NOT_MOTIVO'], + vawDate: liberationHistoryItem['NOT_STATUS'] == 'S' + ? liberationHistoryItem['NOT_DTENVIO'] + : liberationHistoryItem['NOT_DTRESPOSTA'], + vawStatus: liberationHistoryItem['NOT_STATUS'], + vteMsg: liberationHistoryItem['NOT_MSGENVIO'], + vteUUID: liberationHistoryItem['VTE_ID'], + cliUUID: FFAppState().cliUUID, + msgUUID: liberationHistoryItem['NOT_ID'], + vawDestino: liberationHistoryItem['NOT_DESTINO'], + vawUUID: liberationHistoryItem['NOT_ID'], + vawName: liberationHistoryItem['NOT_NOME'], + vawRef: liberationHistoryItem['NOT_ID'], + changeStatusAction: changeStatusAction, + // vteDocument: liberationHistoryItem['VTE_DOCUMENTO'], + ); + }, + ).then((_) { + PushNotificationManager _pushNotificationService = + PushNotificationManager(); + + _pushNotificationService.onMessageReceived.listen((received) { + if (received.data['click_action'] == 'cancel_request') { + debugPrint('Aprovado'); + _pushNotificationService.dispose(); + snackbar(context, opt: true); + context.pushReplacementNamed( + 'liberationHistory', + extra: { + kTransitionInfoKey: const TransitionInfo( + hasTransition: true, + transitionType: PageTransitionType.scale, + alignment: Alignment.bottomCenter, + ), + }, + ); + } + }); + }); + }, + ); +} diff --git a/pubspec.lock b/pubspec.lock index 8104211b..8cfc5a20 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + bloc: + dependency: transitive + description: + name: bloc + sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" + url: "https://pub.dev" + source: hosted + version: "8.1.4" boolean_selector: dependency: transitive description: @@ -366,6 +374,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.5.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a + url: "https://pub.dev" + source: hosted + version: "8.1.6" flutter_cache_manager: dependency: "direct main" description: @@ -374,6 +390,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.2" + flutter_expandable_fab: + dependency: "direct main" + description: + name: flutter_expandable_fab + sha256: "85eee55657e747814007d9d09bfc713dc961ede4240e82fae6c1ade8eb5bb4d3" + url: "https://pub.dev" + source: hosted + version: "2.1.0" flutter_inappwebview: dependency: "direct main" description: @@ -483,6 +507,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.20" + flutter_riverpod: + dependency: "direct main" + description: + name: flutter_riverpod + sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" + url: "https://pub.dev" + source: hosted + version: "2.5.1" flutter_secure_storage: dependency: "direct main" description: @@ -965,6 +997,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" + riverpod: + dependency: transitive + description: + name: riverpod + sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d + url: "https://pub.dev" + source: hosted + version: "2.5.1" rxdart: dependency: "direct main" description: @@ -1074,6 +1114,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.1" + state_notifier: + dependency: transitive + description: + name: state_notifier + sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb + url: "https://pub.dev" + source: hosted + version: "1.0.0" stream_channel: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ccc4d6bc..47cca160 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: easy_debounce: 2.0.3 equatable: 2.0.5 file_picker: 8.0.5 + flutter_expandable_fab: ^2.1.0 firebase_analytics: 11.0.1 flutter_animate: 4.5.0 flutter_cache_manager: 3.3.2 @@ -97,6 +98,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.0 + flutter_bloc: ^8.1.6 + flutter_riverpod: ^2.5.1 dependency_overrides: http: 1.2.1