From 1a172d3d860b00144ce7a87dd96a17e342aeabaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com> Date: Sat, 19 Aug 2023 17:04:45 +0200 Subject: [PATCH] Implemented structure for push Notifications --- .idea/libraries/Dart_Packages.xml | 144 ++++++++++++++++-- .idea/libraries/Flutter_Plugins.xml | 35 +++-- android/app/build.gradle | 3 +- android/app/google-services.json | 39 +++++ .../app/FlutterMultiDexApplication.java | 25 +++ android/build.gradle | 1 + client.iml | 1 + lib/api/mhsl/mhslApi.dart | 5 + .../mhsl/notify/register/notifyRegister.dart | 26 ++++ .../notify/register/notifyRegisterParams.dart | 19 +++ .../register/notifyRegisterParams.g.dart | 23 +++ lib/app.dart | 11 ++ lib/main.dart | 6 + lib/notification/notificationController.dart | 45 ++++++ lib/notification/notificationService.dart | 75 +++++++++ lib/notification/notifyUpdater.dart | 22 +++ lib/storage/base/settings.dart | 3 + lib/storage/base/settings.g.dart | 3 + .../notification/notificationSettings.dart | 14 ++ .../notification/notificationSettings.g.dart | 21 +++ lib/view/pages/more/overhang.dart | 1 - lib/view/pages/talk/chatList.dart | 3 + lib/view/settings/defaultSettings.dart | 5 + lib/view/settings/settings.dart | 68 ++++++--- macos/Flutter/GeneratedPluginRegistrant.swift | 6 + pubspec.yaml | 5 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 28 files changed, 567 insertions(+), 46 deletions(-) create mode 100644 android/app/google-services.json create mode 100644 android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java create mode 100644 lib/api/mhsl/notify/register/notifyRegister.dart create mode 100644 lib/api/mhsl/notify/register/notifyRegisterParams.dart create mode 100644 lib/api/mhsl/notify/register/notifyRegisterParams.g.dart create mode 100644 lib/notification/notificationController.dart create mode 100644 lib/notification/notificationService.dart create mode 100644 lib/notification/notifyUpdater.dart create mode 100644 lib/storage/notification/notificationSettings.dart create mode 100644 lib/storage/notification/notificationSettings.g.dart diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 1503a2d..326de58 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -9,6 +9,13 @@ </list> </value> </entry> + <entry key="_flutterfire_internals"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/_flutterfire_internals-1.3.4/lib" /> + </list> + </value> + </entry> <entry key="analyzer"> <value> <list> @@ -215,7 +222,7 @@ <entry key="collection"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.1/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.2/lib" /> </list> </value> </entry> @@ -282,6 +289,13 @@ </list> </value> </entry> + <entry key="dbus"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dbus-0.7.8/lib" /> + </list> + </value> + </entry> <entry key="device_info_plus"> <value> <list> @@ -380,6 +394,62 @@ </list> </value> </entry> + <entry key="firebase_core"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0/lib" /> + </list> + </value> + </entry> + <entry key="firebase_core_platform_interface"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_platform_interface-4.8.0/lib" /> + </list> + </value> + </entry> + <entry key="firebase_core_web"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0/lib" /> + </list> + </value> + </entry> + <entry key="firebase_in_app_messaging"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4/lib" /> + </list> + </value> + </entry> + <entry key="firebase_in_app_messaging_platform_interface"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging_platform_interface-0.2.4+4/lib" /> + </list> + </value> + </entry> + <entry key="firebase_messaging"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5/lib" /> + </list> + </value> + </entry> + <entry key="firebase_messaging_platform_interface"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_platform_interface-4.5.4/lib" /> + </list> + </value> + </entry> + <entry key="firebase_messaging_web"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4/lib" /> + </list> + </value> + </entry> <entry key="fixnum"> <value> <list> @@ -436,6 +506,27 @@ </list> </value> </entry> + <entry key="flutter_local_notifications"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1/lib" /> + </list> + </value> + </entry> + <entry key="flutter_local_notifications_linux"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-4.0.0+1/lib" /> + </list> + </value> + </entry> + <entry key="flutter_local_notifications_platform_interface"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_platform_interface-7.0.0+1/lib" /> + </list> + </value> + </entry> <entry key="flutter_localizations"> <value> <list> @@ -478,6 +569,13 @@ </list> </value> </entry> + <entry key="fluttertoast"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/lib" /> + </list> + </value> + </entry> <entry key="font_awesome_flutter"> <value> <list> @@ -600,7 +698,7 @@ <entry key="intl"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.0/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.1/lib" /> </list> </value> </entry> @@ -705,14 +803,14 @@ <entry key="matcher"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.16/lib" /> </list> </value> </entry> <entry key="material_color_utilities"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.5.0/lib" /> </list> </value> </entry> @@ -1006,7 +1104,7 @@ <entry key="source_span"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib" /> </list> </value> </entry> @@ -1132,7 +1230,7 @@ <entry key="test_api"> <value> <list> - <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib" /> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.6.0/lib" /> </list> </value> </entry> @@ -1248,6 +1346,13 @@ </list> </value> </entry> + <entry key="web"> + <value> + <list> + <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/web-0.1.4-beta/lib" /> + </list> + </value> + </entry> <entry key="web_socket_channel"> <value> <list> @@ -1297,6 +1402,7 @@ <root url="file://$USER_HOME$/.pub-cache/git/nextcloud-neon-50d607e278061992659e4fdbc03a9d9fe0f04a77/packages/dynamite/dynamite_runtime/lib" /> <root url="file://$USER_HOME$/.pub-cache/git/nextcloud-neon-9a42bdb3a0ef1e3dbd62f746fb0fe75856be66a3/packages/nextcloud/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-62.0.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_flutterfire_internals-1.3.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-6.0.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/animated_digit-3.2.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/another_flushbar-1.12.30/lib" /> @@ -1326,7 +1432,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cli_util-0.4.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/clock-1.1.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/code_builder-4.5.0/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.2/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/convert-3.1.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cookie_jar-4.0.8/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cross_file-0.3.3+4/lib" /> @@ -1336,6 +1442,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_internal-0.2.9/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_style-2.3.2/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dbus-0.7.8/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus_platform_interface-7.0.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-4.0.6/lib" /> @@ -1349,15 +1456,27 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_platform_interface-2.6.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/filesize-2.0.1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_platform_interface-4.8.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging_platform_interface-0.2.4+4/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_platform_interface-4.5.4/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_cache_manager-3.3.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_launcher_icons-0.13.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_linkify-6.0.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_lints-2.0.2/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-4.0.0+1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_platform_interface-7.0.0+1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_login-4.2.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_native_splash-2.3.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.15/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.5.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/frontend_server_client-3.2.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/glob-2.1.2/lib" /> @@ -1375,7 +1494,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.9.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl_phone_number_input-0.7.3+1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/io-1.0.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/jiffy-6.2.1/lib" /> @@ -1390,8 +1509,8 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/loader_overlay-2.3.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.3.5/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logging-1.2.0/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.16/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.5.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/meta-1.9.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/mime-1.0.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/nested-1.0.0/lib" /> @@ -1431,7 +1550,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sign_in_button-3.2.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_gen-1.4.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_helper-1.3.4/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.3.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite_common-2.5.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib" /> @@ -1449,7 +1568,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_windows-21.2.10/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/synchronized-3.1.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.6.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timezone-0.9.2/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timing-1.0.1/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/typed_data-1.3.2/lib" /> @@ -1466,6 +1585,7 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/version-3.0.2/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/watcher-1.1.0/lib" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/web-0.1.4-beta/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/web_socket_channel-2.4.0/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/win32-4.1.4/lib" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xdg_directories-1.0.1/lib" /> diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index e848caa..e5ebdb8 100644 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,24 +1,18 @@ <component name="libraryTable"> <library name="Flutter Plugins" type="FlutterPluginsLibraryType"> <CLASSES> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/better_open_file-3.6.4" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/package_info-2.0.2" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider-2.0.15" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_linux-3.0.5" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.4" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_linux-0.9.2" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_linux-0.2.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_web-21.2.10" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_web-2.0.18" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/libphonenumber_plugin-0.3.2" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_android-6.0.37" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_macos-3.0.6" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_ios-0.8.8" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/better_open_file-3.6.4" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/package_info-2.0.2" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher-6.1.12" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/libphonenumber_web-0.3.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker-1.0.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.0" /> @@ -26,19 +20,32 @@ <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_macos-0.9.3+1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_web-2.2.0" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.4" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider-2.0.15" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_for_web-2.2.0" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.0" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_linux-0.9.2" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_linux-3.0.5" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_android-0.8.7+4" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_windows-3.0.7" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.4" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_native_splash-2.3.1" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.7" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.0" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences-2.2.0" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_linux-0.2.1" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.2" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.11" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_picker-5.3.1" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_android-6.0.37" /> - <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_android-0.8.7+4" /> <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.3.0" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1" /> + <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2" /> </CLASSES> <JAVADOC /> <SOURCES /> diff --git a/android/app/build.gradle b/android/app/build.gradle index 361edbd..0c2fde7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -23,6 +23,7 @@ if (flutterVersionName == null) { apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +apply plugin: 'com.google.gms.google-services' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { @@ -39,7 +40,7 @@ android { applicationId "eu.mhsl.marianum.mobile.client" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 19 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..adab10f --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "522850592536", + "project_id": "marmobile-33b10", + "storage_bucket": "marmobile-33b10.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:522850592536:android:9a355c61e6f1b0f0c2606d", + "android_client_info": { + "package_name": "eu.mhsl.marianum.mobile.client" + } + }, + "oauth_client": [ + { + "client_id": "522850592536-5urolovocke0fmr7kpd0hqvfd3gft6qo.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAXo66A3jSBxnAYKgpUIfucidELoHw5W3M" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "522850592536-5urolovocke0fmr7kpd0hqvfd3gft6qo.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java new file mode 100644 index 0000000..752fc18 --- /dev/null +++ b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java @@ -0,0 +1,25 @@ +// Generated file. +// +// If you wish to remove Flutter's multidex support, delete this entire file. +// +// Modifications to this file should be done in a copy under a different name +// as this file may be regenerated. + +package io.flutter.app; + +import android.app.Application; +import android.content.Context; +import androidx.annotation.CallSuper; +import androidx.multidex.MultiDex; + +/** + * Extension of {@link android.app.Application}, adding multidex support. + */ +public class FlutterMultiDexApplication extends Application { + @Override + @CallSuper + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + MultiDex.install(this); + } +} diff --git a/android/build.gradle b/android/build.gradle index 3efffaf..db9efaf 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.15' } } diff --git a/client.iml b/client.iml index fa043b4..2fa4042 100644 --- a/client.iml +++ b/client.iml @@ -3,6 +3,7 @@ <component name="NewModuleRootManager" inherit-compiler-output="true"> <exclude-output /> <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" /> <excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/.pub" /> <excludeFolder url="file://$MODULE_DIR$/.dart_tool" /> diff --git a/lib/api/mhsl/mhslApi.dart b/lib/api/mhsl/mhslApi.dart index fa9ec02..64f6270 100644 --- a/lib/api/mhsl/mhslApi.dart +++ b/lib/api/mhsl/mhslApi.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:http/http.dart' as http; import '../apiError.dart'; @@ -21,6 +22,10 @@ abstract class MhslApi<T> extends ApiRequest { throw ApiError("Request could not be dispatched!"); } + if(data.statusCode > 299) { + log("Non 200 Status code from mhsl services: $subpath: ${data.statusCode}"); + } + return assemble(utf8.decode(data.bodyBytes)); } } \ No newline at end of file diff --git a/lib/api/mhsl/notify/register/notifyRegister.dart b/lib/api/mhsl/notify/register/notifyRegister.dart new file mode 100644 index 0000000..c614520 --- /dev/null +++ b/lib/api/mhsl/notify/register/notifyRegister.dart @@ -0,0 +1,26 @@ + +import 'dart:convert'; +import 'dart:developer'; + +import 'package:http/http.dart' as http; + +import '../../mhslApi.dart'; +import 'notifyRegisterParams.dart'; + +class NotifyRegister extends MhslApi<void> { + NotifyRegisterParams params; + NotifyRegister(this.params) : super("notify/register/"); + + + @override + void assemble(String raw) { + + } + + @override + Future<http.Response> request(Uri uri) { + String requestString = jsonEncode(params.toJson()); + log(requestString); + return http.post(uri, body: requestString); + } +} \ No newline at end of file diff --git a/lib/api/mhsl/notify/register/notifyRegisterParams.dart b/lib/api/mhsl/notify/register/notifyRegisterParams.dart new file mode 100644 index 0000000..75c7a95 --- /dev/null +++ b/lib/api/mhsl/notify/register/notifyRegisterParams.dart @@ -0,0 +1,19 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'notifyRegisterParams.g.dart'; + +@JsonSerializable() +class NotifyRegisterParams { + String username; + String password; + String fcmToken; + + NotifyRegisterParams({ + required this.username, + required this.password, + required this.fcmToken + }); + + factory NotifyRegisterParams.fromJson(Map<String, dynamic> json) => _$NotifyRegisterParamsFromJson(json); + Map<String, dynamic> toJson() => _$NotifyRegisterParamsToJson(this); +} \ No newline at end of file diff --git a/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart b/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart new file mode 100644 index 0000000..0b26d8d --- /dev/null +++ b/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'notifyRegisterParams.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +NotifyRegisterParams _$NotifyRegisterParamsFromJson( + Map<String, dynamic> json) => + NotifyRegisterParams( + username: json['username'] as String, + password: json['password'] as String, + fcmToken: json['fcmToken'] as String, + ); + +Map<String, dynamic> _$NotifyRegisterParamsToJson( + NotifyRegisterParams instance) => + <String, dynamic>{ + 'username': instance.username, + 'password': instance.password, + 'fcmToken': instance.fcmToken, + }; diff --git a/lib/app.dart b/lib/app.dart index 391296b..f77ea5c 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,6 +1,7 @@ import 'dart:async'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; import 'package:provider/provider.dart'; @@ -10,6 +11,9 @@ import 'api/mhsl/breaker/getBreakers/getBreakersResponse.dart'; import 'model/breakers/Breaker.dart'; import 'model/breakers/BreakerProps.dart'; import 'model/chatList/chatListProps.dart'; +import 'notification/notificationController.dart'; +import 'notification/notifyUpdater.dart'; +import 'storage/base/settingsProvider.dart'; import 'view/pages/files/files.dart'; import 'view/pages/more/overhang.dart'; import 'view/pages/talk/chatList.dart'; @@ -42,6 +46,13 @@ class _AppState extends State<App> { }); }); + if(Provider.of<SettingsProvider>(context, listen: false).val().notificationSettings.enabled) { + NotifyUpdater.registerToServer(); + } + + FirebaseMessaging.onMessage.listen((message) => NotificationController.onForegroundMessageHandler(message, context)); + FirebaseMessaging.onBackgroundMessage(NotificationController.onBackgroundMessageHandler); + super.initState(); } diff --git a/lib/main.dart b/lib/main.dart index d0af28b..6268f3c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,10 @@ import 'dart:async'; +import 'dart:developer'; import 'dart:io'; +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/services.dart'; import 'package:jiffy/jiffy.dart'; @@ -27,6 +31,8 @@ import 'widget/placeholderView.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + log("Firebase token: ${await FirebaseMessaging.instance.getToken() ?? "Error: no Firebase token!"}"); ByteData data = await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem'); SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List()); diff --git a/lib/notification/notificationController.dart b/lib/notification/notificationController.dart new file mode 100644 index 0000000..22a6b13 --- /dev/null +++ b/lib/notification/notificationController.dart @@ -0,0 +1,45 @@ +import 'dart:developer'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/cupertino.dart'; + +import '../api/marianumcloud/talk/room/getRoom.dart'; +import '../api/marianumcloud/talk/room/getRoomParams.dart'; +import '../model/accountData.dart'; +import 'notificationService.dart'; + +class NotificationController { + @pragma('vm:entry-point') + static Future<void> onBackgroundMessageHandler(RemoteMessage message) async { + log("Handling a background notification: ${message.messageId}"); + + await Firebase.initializeApp(); + AccountData().waitForPopulation().then((value) { + log("User account status: $value"); + if(value) { + GetRoom( + GetRoomParams( + includeStatus: false, + ), + ).run().then((value) { + var messageCount = value.data.map((e) => e.unreadMessages).reduce((a, b) => a + b); + var chatCount = value.data.map((e) => e.unreadMessages).length; + var people = value.data.where((e) => e.unreadMessages > 0).map((e) => e.displayName.split(" ")[0]); + + final NotificationService service = NotificationService(); + service.initializeNotifications().then((value) { + service.showNotification( + title: "Du hast $messageCount ungelesene Nachrichten!", + body: "In $chatCount Chats, von ${people.join(", ")}" + ); + }); + }); + } + }); + } + + static Future<void> onForegroundMessageHandler(RemoteMessage message, BuildContext context) async { + NotificationService().showToast(message: "Du hast eine neue Talk Nachricht!", context: context); + } +} \ No newline at end of file diff --git a/lib/notification/notificationService.dart b/lib/notification/notificationService.dart new file mode 100644 index 0000000..77fdc8c --- /dev/null +++ b/lib/notification/notificationService.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; + +import '../model/chatList/chatListProps.dart'; +import '../model/message/messageProps.dart'; + +class NotificationService { + static final NotificationService _instance = NotificationService._internal(); + + factory NotificationService() { + return _instance; + } + + NotificationService._internal(); + + FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); + + Future<void> initializeNotifications() async { + const AndroidInitializationSettings androidSettings = AndroidInitializationSettings( + '@mipmap/ic_launcher' + ); + + final DarwinInitializationSettings iosSettings = DarwinInitializationSettings( + onDidReceiveLocalNotification: (id, title, body, payload) { + // TODO Navigate to Talk section (This runs when an Notification is tapped) + }, + ); + + + final InitializationSettings initializationSettings = InitializationSettings( + android: androidSettings, + iOS: iosSettings, + ); + + await flutterLocalNotificationsPlugin.initialize( + initializationSettings, + ); + } + + Future<void> showNotification({required String title, required String body}) async { + const AndroidNotificationDetails androidPlatformChannelSpecifics = + AndroidNotificationDetails( + 'your_channel_id', + 'Your Channel Name', + importance: Importance.defaultImportance, + priority: Priority.defaultPriority, + ticker: 'ticker', + ); + + const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); + + await flutterLocalNotificationsPlugin.show( + 0, + title, + body, + platformChannelSpecifics, + ); + } + + void showToast({required String message, required BuildContext context, ToastGravity gravity = ToastGravity.BOTTOM}) { + Fluttertoast.showToast( + msg: message, + gravity: gravity, + toastLength: Toast.LENGTH_SHORT, + backgroundColor: Theme.of(context).primaryColor, + textColor: Colors.white, + fontSize: 13.0, + ); + + Provider.of<ChatListProps>(context, listen: false).run(renew: true); + Provider.of<MessageProps>(context, listen: false).run(renew: true); + } +} \ No newline at end of file diff --git a/lib/notification/notifyUpdater.dart b/lib/notification/notifyUpdater.dart new file mode 100644 index 0000000..72688de --- /dev/null +++ b/lib/notification/notifyUpdater.dart @@ -0,0 +1,22 @@ + +import 'package:firebase_messaging/firebase_messaging.dart'; + +import '../api/mhsl/notify/register/notifyRegister.dart'; +import '../api/mhsl/notify/register/notifyRegisterParams.dart'; +import '../model/accountData.dart'; + +class NotifyUpdater { + static void registerToServer() async { + String? fcmToken = await FirebaseMessaging.instance.getToken(); + + if(fcmToken == null) throw Exception("Failed to register push notification because there is no FBC token!"); + + NotifyRegister( + NotifyRegisterParams( + username: AccountData().getUsername(), + password: AccountData().getPassword(), + fcmToken: fcmToken, + ), + ).run(); + } +} \ No newline at end of file diff --git a/lib/storage/base/settings.dart b/lib/storage/base/settings.dart index 59aca1c..5f96084 100644 --- a/lib/storage/base/settings.dart +++ b/lib/storage/base/settings.dart @@ -5,6 +5,7 @@ import '../file/fileSettings.dart'; import '../fileView/fileViewSettings.dart'; import '../gradeAverages/gradeAveragesSettings.dart'; import '../holidays/holidaysSettings.dart'; +import '../notification/notificationSettings.dart'; import '../talk/talkSettings.dart'; import '../timetable/timetableSettings.dart'; @@ -25,6 +26,7 @@ class Settings { FileSettings fileSettings; HolidaysSettings holidaysSettings; FileViewSettings fileViewSettings; + NotificationSettings notificationSettings; Settings({ required this.appTheme, @@ -35,6 +37,7 @@ class Settings { required this.fileSettings, required this.holidaysSettings, required this.fileViewSettings, + required this.notificationSettings, }); static String _themeToJson(ThemeMode m) => m.name; diff --git a/lib/storage/base/settings.g.dart b/lib/storage/base/settings.g.dart index 5d04e65..b8ca058 100644 --- a/lib/storage/base/settings.g.dart +++ b/lib/storage/base/settings.g.dart @@ -21,6 +21,8 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) => Settings( json['holidaysSettings'] as Map<String, dynamic>), fileViewSettings: FileViewSettings.fromJson( json['fileViewSettings'] as Map<String, dynamic>), + notificationSettings: NotificationSettings.fromJson( + json['notificationSettings'] as Map<String, dynamic>), ); Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{ @@ -32,4 +34,5 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{ 'fileSettings': instance.fileSettings.toJson(), 'holidaysSettings': instance.holidaysSettings.toJson(), 'fileViewSettings': instance.fileViewSettings.toJson(), + 'notificationSettings': instance.notificationSettings.toJson(), }; diff --git a/lib/storage/notification/notificationSettings.dart b/lib/storage/notification/notificationSettings.dart new file mode 100644 index 0000000..81607ba --- /dev/null +++ b/lib/storage/notification/notificationSettings.dart @@ -0,0 +1,14 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'notificationSettings.g.dart'; + +@JsonSerializable() +class NotificationSettings { + bool askUsageDismissed; + bool enabled; + + NotificationSettings({required this.askUsageDismissed, required this.enabled}); + + factory NotificationSettings.fromJson(Map<String, dynamic> json) => _$NotificationSettingsFromJson(json); + Map<String, dynamic> toJson() => _$NotificationSettingsToJson(this); +} \ No newline at end of file diff --git a/lib/storage/notification/notificationSettings.g.dart b/lib/storage/notification/notificationSettings.g.dart new file mode 100644 index 0000000..d46c15d --- /dev/null +++ b/lib/storage/notification/notificationSettings.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'notificationSettings.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +NotificationSettings _$NotificationSettingsFromJson( + Map<String, dynamic> json) => + NotificationSettings( + askUsageDismissed: json['askUsageDismissed'] as bool, + enabled: json['enabled'] as bool, + ); + +Map<String, dynamic> _$NotificationSettingsToJson( + NotificationSettings instance) => + <String, dynamic>{ + 'askUsageDismissed': instance.askUsageDismissed, + 'enabled': instance.enabled, + }; diff --git a/lib/view/pages/more/overhang.dart b/lib/view/pages/more/overhang.dart index 5f9be9d..7b501a6 100644 --- a/lib/view/pages/more/overhang.dart +++ b/lib/view/pages/more/overhang.dart @@ -1,5 +1,4 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; diff --git a/lib/view/pages/talk/chatList.dart b/lib/view/pages/talk/chatList.dart index 0760f9f..acd879d 100644 --- a/lib/view/pages/talk/chatList.dart +++ b/lib/view/pages/talk/chatList.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -26,6 +27,8 @@ class _ChatListState extends State<ChatList> { void initState() { super.initState(); + FirebaseMessaging.instance.requestPermission(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { _query(); }); diff --git a/lib/view/settings/defaultSettings.dart b/lib/view/settings/defaultSettings.dart index 44d9494..1c6bc88 100644 --- a/lib/view/settings/defaultSettings.dart +++ b/lib/view/settings/defaultSettings.dart @@ -7,6 +7,7 @@ import '../../storage/file/fileSettings.dart'; import '../../storage/fileView/fileViewSettings.dart'; import '../../storage/gradeAverages/gradeAveragesSettings.dart'; import '../../storage/holidays/holidaysSettings.dart'; +import '../../storage/notification/notificationSettings.dart'; import '../../storage/talk/talkSettings.dart'; import '../../storage/timetable/timetableSettings.dart'; import '../pages/files/files.dart'; @@ -39,6 +40,10 @@ class DefaultSettings { fileViewSettings: FileViewSettings( alwaysOpenExternally: Platform.isIOS, ), + notificationSettings: NotificationSettings( + askUsageDismissed: false, + enabled: false, + ) ); } } \ No newline at end of file diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart index 6c221ae..f106da4 100644 --- a/lib/view/settings/settings.dart +++ b/lib/view/settings/settings.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../model/accountData.dart'; +import '../../notification/notifyUpdater.dart'; import '../../storage/base/settingsProvider.dart'; import '../../theming/appTheme.dart'; import '../../widget/centeredLeading.dart'; @@ -87,9 +88,7 @@ class _SettingsState extends State<Settings> { ), )).toList(), onChanged: (e) { - setState(() { - settings.val(write: true).appTheme = e!; - }); + settings.val(write: true).appTheme = e!; }, ), ), @@ -102,9 +101,7 @@ class _SettingsState extends State<Settings> { trailing: Checkbox( value: settings.val().talkSettings.sortFavoritesToTop, onChanged: (e) { - setState(() { - settings.val(write: true).talkSettings.sortFavoritesToTop = e!; - }); + settings.val(write: true).talkSettings.sortFavoritesToTop = e!; }, ), ), @@ -115,9 +112,7 @@ class _SettingsState extends State<Settings> { trailing: Checkbox( value: settings.val().talkSettings.sortUnreadToTop, onChanged: (e) { - setState(() { - settings.val(write: true).talkSettings.sortUnreadToTop = e!; - }); + settings.val(write: true).talkSettings.sortUnreadToTop = e!; }, ), ), @@ -130,9 +125,7 @@ class _SettingsState extends State<Settings> { trailing: Checkbox( value: settings.val().fileSettings.sortFoldersToTop, onChanged: (e) { - setState(() { - settings.val(write: true).fileSettings.sortFoldersToTop = e!; - }); + settings.val(write: true).fileSettings.sortFoldersToTop = e!; }, ), ), @@ -152,6 +145,49 @@ class _SettingsState extends State<Settings> { const Divider(), + ListTile( + leading: const CenteredLeading(Icon(Icons.notifications_active_outlined)), + title: const Text("Push-Benachrichtigungen aktivieren"), + subtitle: const Text("Lange tippen für mehr Informationen"), + trailing: Checkbox( + value: settings.val().notificationSettings.enabled, + onChanged: (e) { + if(e!) { + ConfirmDialog( + title: "Warnung", + icon: Icons.warning_amber, + content: "" + "Die Push-Benachrichtigungen werden durch mhsl.eu versendet.\n\n" + "Durch das aktivieren dieser Funktion wird dein Nutzername, dein Password und eine Geräte-ID von mhsl dauerhaft gespeichert und verarbeitet.\n\n" + "Für mehr Informationen drücke lange auf die Einstellungsoption!", + confirmButton: "Aktivieren", + onConfirm: () { + settings.val(write: true).notificationSettings.enabled = e; + NotifyUpdater.registerToServer(); + }, + ).asDialog(context); + } else { + settings.val(write: true).notificationSettings.enabled = e; + } + }, + ), + onLongPress: () => showDialog(context: context, builder: (context) => AlertDialog( + title: const Text("Info über Push"), + content: const SingleChildScrollView(child: Text("" + "Aufgrund technischer Limitationen müssen Push-nachrichten über einen Externen Server - hier 'mhsl.eu' (Author dieser App) - erfolgen.\n\n" + "Wenn Push aktiviert wird, werden deine Zugangsdaten und ein Token verschlüsselt an den Betreiber gesendet und von ihm unverschlüsselt gespeichert.\n\n" + "Der extene Server verwendet die Zugangsdaten um sich maschinell in Nextcloud Talk anzumelden und via Websockets auf neue Nachrichten zu warten.\n\n" + "Wenn eine neue Nachricht eintrifft wird dein Telefon via FBC-Messaging (Google Firebase Push) vom Externen Server benachrichtigt.\n\n" + "Behalte im Hinterkopf, dass deine Zugangsdaten auf einem Externen Server gespeichert werden und dies trots bester Absichten ein Sicherheitsrisiko sein kann!" + )), + actions: [ + TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Zurück")) + ], + )), + ), + + const Divider(), + ListTile( leading: const Icon(Icons.live_help_outlined), title: const Text("Informationen und Lizenzen"), @@ -215,9 +251,7 @@ class _SettingsState extends State<Settings> { trailing: Checkbox( value: settings.val().devToolsEnabled, onChanged: (state) { - changeView() => setState(() { - settings.val(write: true).devToolsEnabled = state ?? false; - }); + changeView() => settings.val(write: true).devToolsEnabled = state ?? false; if(!state!) { changeView(); @@ -284,9 +318,7 @@ class _SettingsState extends State<Settings> { content: "Alle Einstellungen gehen verloren! Accountdaten sowie App-Daten sind nicht betroffen.", confirmButton: "Unwiederruflich Löschen", onConfirm: () { - setState(() { - Provider.of<SettingsProvider>(context, listen: false).reset(); - }); + Provider.of<SettingsProvider>(context, listen: false).reset(); }, ).asDialog(context); }, diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 9d5f78f..f9e6582 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,6 +7,9 @@ import Foundation import device_info_plus import file_selector_macos +import firebase_core +import firebase_messaging +import flutter_local_notifications import package_info import path_provider_foundation import shared_preferences_foundation @@ -17,6 +20,9 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) + FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.yaml b/pubspec.yaml index d124148..ca0a645 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -81,6 +81,11 @@ dependencies: syncfusion_flutter_pdfviewer: ^21.2.8 photo_view: ^0.14.0 uuid: ^3.0.7 + firebase_messaging: ^14.6.5 + firebase_core: ^2.15.0 + firebase_in_app_messaging: ^0.7.3+4 + flutter_local_notifications: ^15.1.0+1 + fluttertoast: ^8.2.2 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 779f0ee..9f7d909 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,12 +7,15 @@ #include "generated_plugin_registrant.h" #include <file_selector_windows/file_selector_windows.h> +#include <firebase_core/firebase_core_plugin_c_api.h> #include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h> #include <url_launcher_windows/url_launcher_windows.h> void RegisterPlugins(flutter::PluginRegistry* registry) { FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 3757972..d9d5615 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_windows + firebase_core syncfusion_pdfviewer_windows url_launcher_windows )