From 248483be4e2f569a74a43cd499d5d229a6954dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sat, 16 Sep 2023 16:15:16 +0200 Subject: [PATCH] Added home-screen app-icon Notification badge --- .../userIndex/update/updateUserindex.dart | 2 +- lib/app.dart | 6 ++-- lib/model/chatList/chatListProps.dart | 3 ++ lib/notification/notificationController.dart | 33 ++++++++++++++----- lib/notification/notificationTasks.dart | 22 +++++++++++++ lib/view/pages/talk/joinChat.dart | 2 +- lib/widget/debug/debugTile.dart | 9 ++++- macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ pubspec.yaml | 1 + 9 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 lib/notification/notificationTasks.dart diff --git a/lib/api/mhsl/server/userIndex/update/updateUserindex.dart b/lib/api/mhsl/server/userIndex/update/updateUserindex.dart index 152bb69..f18a056 100644 --- a/lib/api/mhsl/server/userIndex/update/updateUserindex.dart +++ b/lib/api/mhsl/server/userIndex/update/updateUserindex.dart @@ -5,11 +5,11 @@ import 'package:crypto/crypto.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:http/http.dart' as http; -import 'package:marianum_mobile/api/mhsl/server/userIndex/update/updateUserIndexParams.dart'; import 'package:package_info/package_info.dart'; import '../../../../../model/accountData.dart'; import '../../../mhslApi.dart'; +import 'updateUserIndexParams.dart'; class UpdateUserIndex extends MhslApi { UpdateUserIndexParams params; diff --git a/lib/app.dart b/lib/app.dart index 75c6af7..90abe0b 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -56,11 +56,13 @@ class _AppState extends State { NotifyUpdater.registerToServer(); }); } - + FirebaseMessaging.onMessage.listen((message) => NotificationController.onForegroundMessageHandler(message, context)); - FirebaseMessaging.onMessageOpenedApp.listen((message) => NotificationController.onForegroundMessageHandler(message, context)); FirebaseMessaging.onBackgroundMessage(NotificationController.onBackgroundMessageHandler); + FirebaseMessaging.onMessageOpenedApp.listen((message) => NotificationController.onAppOpenedByNotification(message, context)); + FirebaseMessaging.instance.getInitialMessage().then((message) => message == null ? null : NotificationController.onAppOpenedByNotification(message, context)); + super.initState(); } diff --git a/lib/model/chatList/chatListProps.dart b/lib/model/chatList/chatListProps.dart index 876d235..5ba1793 100644 --- a/lib/model/chatList/chatListProps.dart +++ b/lib/model/chatList/chatListProps.dart @@ -1,4 +1,6 @@ +import 'package:flutter_app_badger/flutter_app_badger.dart'; + import '../../api/apiResponse.dart'; import '../../api/marianumcloud/talk/room/getRoomCache.dart'; import '../../api/marianumcloud/talk/room/getRoomResponse.dart'; @@ -20,6 +22,7 @@ class ChatListProps extends DataHolder { onUpdate: (GetRoomResponse data) => { _getRoomResponse = data, notifyListeners(), + FlutterAppBadger.updateBadgeCount(data.data.map((e) => e.unreadMessages).reduce((a, b) => a+b)) } ); } diff --git a/lib/notification/notificationController.dart b/lib/notification/notificationController.dart index 205af1c..43b92fb 100644 --- a/lib/notification/notificationController.dart +++ b/lib/notification/notificationController.dart @@ -1,15 +1,16 @@ import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:provider/provider.dart'; +import 'package:flutter/material.dart'; -import '../model/chatList/chatListProps.dart'; -import '../model/message/messageProps.dart'; +import '../widget/debug/debugTile.dart'; +import '../widget/debug/jsonViewer.dart'; +import 'notificationTasks.dart'; class NotificationController { @pragma('vm:entry-point') static Future onBackgroundMessageHandler(RemoteMessage message) async { + NotificationTasks.updateBadgeCount(message); return; // Displaying the notification is curently done via the Firebase SDK itself. The Message is server-generated. - // log("Handling a background notification: ${message.messageId}"); + // // await Firebase.initializeApp(); // AccountData().waitForPopulation().then((value) { @@ -38,8 +39,24 @@ class NotificationController { } static Future onForegroundMessageHandler(RemoteMessage message, BuildContext context) async { - //NotificationService().showToast(message: "Du hast eine neue Talk Nachricht!", context: context); - Provider.of(context, listen: false).run(renew: true); - Provider.of(context, listen: false).run(renew: true); + NotificationTasks.updateProviders(context); + NotificationTasks.updateBadgeCount(message); + } + + static Future onAppOpenedByNotification(RemoteMessage message, BuildContext context) async { + NotificationTasks.updateProviders(context); + + DebugTile(context).run(() { + showDialog(context: context, builder: (context) => AlertDialog( + title: const Text("Notification report"), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text("Dieser Bericht wird angezeigt, da du den Entwicklermodus aktiviert hast und die App über eine Benachrichtigung geöffnet wurde."), + Text(JsonViewer.format(message.data)), + ], + ), + )); + }); } } \ No newline at end of file diff --git a/lib/notification/notificationTasks.dart b/lib/notification/notificationTasks.dart new file mode 100644 index 0000000..282c380 --- /dev/null +++ b/lib/notification/notificationTasks.dart @@ -0,0 +1,22 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_app_badger/flutter_app_badger.dart'; +import 'package:provider/provider.dart'; + +import '../model/chatList/chatListProps.dart'; +import '../model/chatList/chatProps.dart'; + +class NotificationTasks { + static void updateBadgeCount(RemoteMessage notification) { + FlutterAppBadger.updateBadgeCount(int.parse(notification.data['unreadCount'] ?? 0)); + } + + static void updateProviders(BuildContext context) { + Provider.of(context, listen: false).run(renew: true); + Provider.of(context, listen: false).run(); + } + + static void navigateToTalk() { + // TODO Navigate + } +} \ No newline at end of file diff --git a/lib/view/pages/talk/joinChat.dart b/lib/view/pages/talk/joinChat.dart index a121889..94a6bc0 100644 --- a/lib/view/pages/talk/joinChat.dart +++ b/lib/view/pages/talk/joinChat.dart @@ -80,7 +80,7 @@ class JoinChat extends SearchDelegate { } ); } else if(snapshot.hasError) { - return PlaceholderView(icon: Icons.search_off, text: snapshot.error.toString()); + return const PlaceholderView(icon: Icons.search_off, text: "Ein fehler ist aufgetreten. Bist du mit dem Internet verbunden?"); } return const Center(child: CircularProgressIndicator()); diff --git a/lib/widget/debug/debugTile.dart b/lib/widget/debug/debugTile.dart index 8853d8b..1839758 100644 --- a/lib/widget/debug/debugTile.dart +++ b/lib/widget/debug/debugTile.dart @@ -11,6 +11,8 @@ class DebugTile { bool onlyInDebug; DebugTile(this.context, {this.onlyInDebug = false}); + bool devConditionFulfilled() => Provider.of(context, listen: false).val().devToolsEnabled && (onlyInDebug ? kDebugMode : true); + Widget jsonData(Map data, {bool ignoreConfig = false}) { return callback( title: "JSON daten anzeigen", @@ -31,8 +33,13 @@ class DebugTile { Widget child(Widget child) { return Visibility( - visible: Provider.of(context).val().devToolsEnabled && (onlyInDebug ? kDebugMode : true), + visible: devConditionFulfilled(), child: child, ); } + + void run(void Function() callback) { + if(!devConditionFulfilled()) return; + callback(); + } } \ No newline at end of file diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 7e74013..162c289 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import fast_rsa import file_selector_macos import firebase_core import firebase_messaging +import flutter_app_badger import flutter_local_notifications import package_info import path_provider_foundation @@ -25,6 +26,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) + FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/pubspec.yaml b/pubspec.yaml index 488d5b5..b0b07b9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,6 +91,7 @@ dependencies: flutter_split_view: ^0.1.2 bottom_sheet: ^4.0.0 device_info_plus: ^9.0.3 + flutter_app_badger: ^1.5.0 dev_dependencies: flutter_test: