diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 1ba4651..3e7a40e 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -1,69 +1,73 @@
-
- CADisableMinimumFrameDurationOnPhone
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- didvan
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(FLUTTER_BUILD_NAME)
- CFBundleSignature
- ????
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- FirebaseAppDelegateProxyEnabled
-
- LSRequiresIPhoneOS
-
- NSCameraUsageDescription
- We need to access to the user gallery to add user profile photo
- NSMicrophoneUsageDescription
- Some message to describe why you need this permission
- NSPhotoLibraryUsageDescription
- We need to access to the user gallery to add user profile photo
- UIApplicationSupportsIndirectInputEvents
-
- UIBackgroundModes
-
- audio
- fetch
- remote-notification
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
- UIInterfaceOrientationPortrait
-
- UIViewControllerBasedStatusBarAppearance
-
- UNNotificationServiceExtension
-
- $(PRODUCT_BUNDLE_IDENTIFIER).MyNotificationServiceExtension
-
- NSAppleMusicUsageDescription
- This app requires access to Apple Music to [explain specific reason].
- NSMicrophoneUsageDescription
- ... explain why the app uses the microphone here ...
- NSAppTransportSecurity
- NSAllowsArbitraryLoads
-
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ didvan
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ FirebaseAppDelegateProxyEnabled
+
+ LSRequiresIPhoneOS
+
+ NSCameraUsageDescription
+ We need to access to the user gallery to add user profile photo
+ NSMicrophoneUsageDescription
+ Some message to describe why you need this permission
+ NSPhotoLibraryUsageDescription
+ We need to access to the user gallery to add user profile photo
+ UIApplicationSupportsIndirectInputEvents
+
+ UIBackgroundModes
+
+ audio
+ fetch
+ remote-notification
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+
+ UIViewControllerBasedStatusBarAppearance
+
+ UNNotificationServiceExtension
+
+ $(PRODUCT_BUNDLE_IDENTIFIER).MyNotificationServiceExtension
+
+ NSAppleMusicUsageDescription
+ This app requires access to Apple Music to [explain specific reason].
+ NSMicrophoneUsageDescription
+ ... explain why the app uses the microphone here ...
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+ BGTaskSchedulerPermittedIdentifiers
+
+ dev.flutter.background.refresh
+
-
-
+
\ No newline at end of file
diff --git a/lib/main.dart b/lib/main.dart
index 011224a..3ffdb74 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -15,6 +15,7 @@ import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/route_generator.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
+import 'package:didvan/services/back_services.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/notification/notification_service.dart';
@@ -32,24 +33,23 @@ import 'package:provider/provider.dart';
final GlobalKey navigatorKey = GlobalKey();
-@pragma('vm:entry-point')
-Future _initPushNotification(RemoteMessage message) async {
- if (!kIsWeb) {
- await NotificationService.initializeNotification();
- }
- await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
- // if (kDebugMode) {
- print("background: ${NotificationData.fromJson(message.data).toJson()}");
- // }
- try {
- NotificationService.showFirebaseNotification(message);
- NotificationService.startListeningNotificationEvents();
- } catch (e) {
- // if (kDebugMode) {
- print(e);
- // }
- }
-}
+// @pragma('vm:entry-point')
+// Future _initPushNotification(RemoteMessage message) async {
+// if (!kIsWeb) {
+// await NotificationService.startListeningNotificationEvents();
+// }
+// await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
+// // if (kDebugMode) {
+// print("background: ${NotificationData.fromJson(message.data).toJson()}");
+// // }
+// try {
+// NotificationService.showFirebaseNotification(message);
+// } catch (e) {
+// // if (kDebugMode) {
+// print(e);
+// // }
+// }
+// }
@pragma('vm:entry-point')
Future _backgroundCallbackHomeWidget(Uri? uri) async {
@@ -65,7 +65,6 @@ Future _backgroundCallbackHomeWidget(Uri? uri) async {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
-
try {
if (!kIsWeb) {
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
@@ -73,7 +72,7 @@ void main() async {
await NotificationService.initializeNotification();
}
- FirebaseMessaging.onBackgroundMessage(_initPushNotification);
+ // FirebaseMessaging.onBackgroundMessage(_initPushNotification);
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform);
await FirebaseApi().initNotification();
diff --git a/lib/providers/user.dart b/lib/providers/user.dart
index 08d329f..77fd775 100644
--- a/lib/providers/user.dart
+++ b/lib/providers/user.dart
@@ -65,9 +65,7 @@ class UserProvider extends CoreProvier {
value: service.result['user']['end'],
);
- FirebaseApi()
- .initNotification()
- .then((value) => _registerFirebaseToken());
+ await _registerFirebaseToken();
return true;
} catch (e) {
diff --git a/lib/services/back_services.dart b/lib/services/back_services.dart
new file mode 100644
index 0000000..6a6b552
--- /dev/null
+++ b/lib/services/back_services.dart
@@ -0,0 +1,57 @@
+import 'dart:async';
+import 'dart:ui';
+
+import 'package:didvan/firebase_options.dart';
+import 'package:didvan/models/notification_data.dart';
+import 'package:didvan/services/notification/notification_service.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter_background_service/flutter_background_service.dart';
+import 'package:get/get.dart';
+
+Future initializeService() async {
+ final service = FlutterBackgroundService();
+ await service.configure(
+ iosConfiguration: IosConfiguration(
+ autoStart: true,
+ onForeground: onStart,
+ onBackground: onIosBackground),
+ androidConfiguration: AndroidConfiguration(
+ onStart: onStart,
+ isForegroundMode: true,
+ autoStart: true,
+ autoStartOnBoot: true));
+}
+
+@pragma('vm:entry-point')
+Future onIosBackground(ServiceInstance service) async {
+ WidgetsFlutterBinding.ensureInitialized();
+ DartPluginRegistrant.ensureInitialized();
+ return true;
+}
+
+@pragma('vm:entry-point')
+void onStart(ServiceInstance service) {
+ DartPluginRegistrant.ensureInitialized();
+ if (service is AndroidServiceInstance) {
+ service.on('setAsForeground').listen((event) {
+ service.setAsForegroundService();
+ });
+ service.on('setAsBackground').listen((event) {
+ service.setAsBackgroundService();
+ });
+ }
+ service.on('stopService').listen((event) {
+ service.stopSelf();
+ });
+ Timer.periodic(const Duration(seconds: 1), (timer) async {
+ if (service is AndroidServiceInstance) {
+ if (await service.isForegroundService()) {}
+ }
+
+ NotificationService.startListeningNotificationEvents();
+ print('background service running');
+ service.invoke('update');
+ });
+}
diff --git a/lib/services/notification/firebase_api.dart b/lib/services/notification/firebase_api.dart
index dc2448a..7eaeb6d 100644
--- a/lib/services/notification/firebase_api.dart
+++ b/lib/services/notification/firebase_api.dart
@@ -7,6 +7,7 @@ import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
import 'package:get/get.dart';
class FirebaseApi {
@@ -33,11 +34,34 @@ class FirebaseApi {
sound: true,
);
- FirebaseMessaging.instance
- .getInitialMessage()
- .asStream()
- .listen((event) async {});
- FirebaseMessaging.onMessageOpenedApp.listen((event) {});
+ final initMsg = await FirebaseMessaging.instance.getInitialMessage();
+
+ if (initMsg != null) {
+ try {
+ NotificationMessage data = NotificationMessage.fromJson(initMsg.data);
+ HomeWidgetRepository.data = data;
+ print("data: ${HomeWidgetRepository.data}");
+ await HomeWidgetRepository.decideWhereToGoNotif();
+ await StorageService.delete(
+ key: 'notification${AppInitializer.createNotificationId(data)}');
+ } catch (e) {
+ e.printError();
+ }
+ }
+
+ FirebaseMessaging.onMessageOpenedApp.listen((initMsg) async {
+ try {
+ NotificationMessage data = NotificationMessage.fromJson(initMsg.data);
+ HomeWidgetRepository.data = data;
+ print("data: ${HomeWidgetRepository.data}");
+ await HomeWidgetRepository.decideWhereToGoNotif();
+ await StorageService.delete(
+ key: 'notification${AppInitializer.createNotificationId(data)}');
+ } catch (e) {
+ e.printError();
+ }
+ });
+
FirebaseMessaging.onMessage.listen((event) => handleMessage(event));
}
@@ -46,6 +70,13 @@ class FirebaseApi {
//do ever you want with message
// if (kDebugMode) {
print("forground: ${NotificationData.fromJson(message.data).toJson()}");
+ const platform = MethodChannel('com.didvan.didvanapp/notification');
+
+ await platform.invokeMethod('showNotification', {
+ 'title': message.notification!.title,
+ 'message': message.notification!.body
+ });
+
// }
try {
await NotificationService.showFirebaseNotification(message);
diff --git a/lib/services/notification/notification_service.dart b/lib/services/notification/notification_service.dart
index 46ceb8b..410c552 100644
--- a/lib/services/notification/notification_service.dart
+++ b/lib/services/notification/notification_service.dart
@@ -5,6 +5,7 @@ import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
class NotificationService {
@@ -163,3 +164,47 @@ class NotificationService {
}
}
}
+
+class NotificationHelper {
+ static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
+ FlutterLocalNotificationsPlugin();
+
+ static Future initialized() async {
+ const AndroidInitializationSettings initializationSettingsAndroid =
+ AndroidInitializationSettings('@mipmap/ic_launcher');
+ final initializationSettingsIos = DarwinInitializationSettings(
+ requestAlertPermission: true,
+ requestBadgePermission: true,
+ requestSoundPermission: true,
+ onDidReceiveLocalNotification: (id, title, body, payload) async {},
+ );
+
+ await flutterLocalNotificationsPlugin.initialize(
+ InitializationSettings(
+ android: initializationSettingsAndroid,
+ iOS: initializationSettingsIos),
+ onDidReceiveNotificationResponse: (details) {
+ print("onDidReceiveNotificationResponse: ${details}");
+ }, onDidReceiveBackgroundNotificationResponse: localBackgroundHandler);
+ }
+
+ static void displayNotification(RemoteMessage message) async {
+ try {
+ final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
+ const notifDetails = NotificationDetails(
+ android: AndroidNotificationDetails(
+ 'push_notificatiion', 'push_notificatiion_channel',
+ importance: Importance.max, priority: Priority.high));
+
+ await flutterLocalNotificationsPlugin.show(
+ id, message.data['title'], message.data['body'], notifDetails);
+ } on Exception catch (e) {
+ e.printError();
+ }
+ }
+}
+
+@pragma('vm:entry-point')
+Future localBackgroundHandler(NotificationResponse data) async {
+ print("onDidReceiveBackgroundNotificationResponse: ${data}");
+}
diff --git a/lib/views/webview/web_view.dart b/lib/views/webview/web_view.dart
index 3a5ca60..962eea6 100644
--- a/lib/views/webview/web_view.dart
+++ b/lib/views/webview/web_view.dart
@@ -22,7 +22,6 @@ class _WebViewState extends State {
void initState() {
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
- ..setBackgroundColor(Theme.of(context).colorScheme.background)
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
diff --git a/lib/views/widgets/didvan/page_view.dart b/lib/views/widgets/didvan/page_view.dart
index b3bcb25..1ef8447 100644
--- a/lib/views/widgets/didvan/page_view.dart
+++ b/lib/views/widgets/didvan/page_view.dart
@@ -311,7 +311,7 @@ class _DidvanPageViewState extends State {
),
);
} else {
- AppInitializer.openWebLink(content, href,
+ AppInitializer.openWebLink(context, href,
mode: LaunchMode.inAppWebView);
}
},
diff --git a/pubspec.lock b/pubspec.lock
index d578c26..a282de3 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -358,6 +358,38 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_background_service:
+ dependency: "direct main"
+ description:
+ name: flutter_background_service
+ sha256: d32f078ec57647c9cfd6e1a8da9297f7d8f021d4dcc204a35aaad2cdbfe255f0
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.10"
+ flutter_background_service_android:
+ dependency: transitive
+ description:
+ name: flutter_background_service_android
+ sha256: "39da42dddf877beeef82bc2583130d8bedb4d0765e99ca9e7b4a32e8c6abd239"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.7"
+ flutter_background_service_ios:
+ dependency: transitive
+ description:
+ name: flutter_background_service_ios
+ sha256: "6037ffd45c4d019dab0975c7feb1d31012dd697e25edc05505a4a9b0c7dc9fba"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.3"
+ flutter_background_service_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_background_service_platform_interface
+ sha256: ca74aa95789a8304f4d3f57f07ba404faa86bed6e415f83e8edea6ad8b904a41
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.2"
flutter_cache_manager:
dependency: "direct main"
description:
@@ -382,6 +414,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
+ flutter_local_notifications:
+ dependency: "direct main"
+ description:
+ name: flutter_local_notifications
+ sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f
+ url: "https://pub.dev"
+ source: hosted
+ version: "17.2.2"
+ flutter_local_notifications_linux:
+ dependency: transitive
+ description:
+ name: flutter_local_notifications_linux
+ sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.1"
+ flutter_local_notifications_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_local_notifications_platform_interface
+ sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66"
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.2.0"
flutter_localizations:
dependency: "direct main"
description: flutter
@@ -1098,6 +1154,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.1"
+ timezone:
+ dependency: transitive
+ description:
+ name: timezone
+ sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.4"
toggle_switch:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 238d458..dde99d1 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -92,6 +92,8 @@ dependencies:
mime: ^1.0.2
path: any
flutter_cache_manager: any
+ flutter_local_notifications: ^17.2.2
+ flutter_background_service: ^5.0.10
# url_launcher: ^6.3.0
dev_dependencies:
diff --git a/web/index.html b/web/index.html
index 5761fa8..bf5f328 100644
--- a/web/index.html
+++ b/web/index.html
@@ -28,12 +28,16 @@
-
+
Didvan