2024-06-04 08:20:28 +02:00
import ' dart:io ' ;
2024-05-31 15:22:27 +02:00
import ' package:firebase_messaging/firebase_messaging.dart ' ;
2024-02-10 18:29:41 +01:00
import ' package:flutter/material.dart ' ;
2024-07-13 01:05:32 +02:00
import ' package:flutter/scheduler.dart ' ;
2024-06-15 21:29:51 +02:00
import ' package:flutter_local_notifications/flutter_local_notifications.dart ' ;
2024-02-11 01:08:51 +01:00
import ' package:provider/provider.dart ' ;
2024-05-25 18:09:39 +02:00
import ' package:hive_flutter/hive_flutter.dart ' ;
2024-05-31 15:22:27 +02:00
import ' package:simplecloudnotifier/api/api_client.dart ' ;
2024-06-15 15:56:50 +02:00
import ' package:simplecloudnotifier/models/channel.dart ' ;
2024-06-02 17:09:57 +02:00
import ' package:simplecloudnotifier/models/client.dart ' ;
2024-06-15 21:29:51 +02:00
import ' package:simplecloudnotifier/models/scn_message.dart ' ;
2024-05-23 20:05:55 +02:00
import ' package:simplecloudnotifier/nav_layout.dart ' ;
2024-07-13 01:05:32 +02:00
import ' package:simplecloudnotifier/pages/channel_view/channel_view.dart ' ;
import ' package:simplecloudnotifier/pages/message_view/message_view.dart ' ;
2024-06-15 21:29:51 +02:00
import ' package:simplecloudnotifier/settings/app_settings.dart ' ;
2024-06-13 17:00:08 +02:00
import ' package:simplecloudnotifier/state/app_bar_state.dart ' ;
2024-06-17 23:23:35 +02:00
import ' package:simplecloudnotifier/state/app_events.dart ' ;
2024-05-23 20:05:55 +02:00
import ' package:simplecloudnotifier/state/app_theme.dart ' ;
2024-05-25 18:09:39 +02:00
import ' package:simplecloudnotifier/state/application_log.dart ' ;
2024-06-15 18:24:18 +02:00
import ' package:simplecloudnotifier/state/fb_message.dart ' ;
2024-05-25 18:09:39 +02:00
import ' package:simplecloudnotifier/state/globals.dart ' ;
import ' package:simplecloudnotifier/state/request_log.dart ' ;
2024-06-02 17:09:57 +02:00
import ' package:simplecloudnotifier/state/app_auth.dart ' ;
2024-05-31 15:22:27 +02:00
import ' package:firebase_core/firebase_core.dart ' ;
2024-06-17 23:23:35 +02:00
import ' package:simplecloudnotifier/state/scn_data_cache.dart ' ;
2024-06-13 17:00:08 +02:00
import ' package:simplecloudnotifier/utils/navi.dart ' ;
2024-06-15 21:29:51 +02:00
import ' package:simplecloudnotifier/utils/notifier.dart ' ;
2024-05-31 23:21:24 +02:00
import ' package:toastification/toastification.dart ' ;
2024-05-31 15:22:27 +02:00
import ' firebase_options.dart ' ;
2024-05-23 20:05:55 +02:00
void main ( ) async {
2024-06-01 03:06:02 +02:00
print ( ' [INIT] Application starting... ' ) ;
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Ensure WidgetsFlutterBinding... ' ) ;
2024-05-25 18:09:39 +02:00
WidgetsFlutterBinding . ensureInitialized ( ) ;
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Init Globals... ' ) ;
2024-05-25 18:09:39 +02:00
await Globals ( ) . init ( ) ;
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Init Hive... ' ) ;
await Hive . initFlutter ( ) ;
2024-05-25 18:09:39 +02:00
Hive . registerAdapter ( SCNRequestAdapter ( ) ) ;
Hive . registerAdapter ( SCNLogAdapter ( ) ) ;
2024-05-26 00:20:25 +02:00
Hive . registerAdapter ( SCNLogLevelAdapter ( ) ) ;
2024-06-15 21:29:51 +02:00
Hive . registerAdapter ( SCNMessageAdapter ( ) ) ;
2024-06-15 15:56:50 +02:00
Hive . registerAdapter ( ChannelAdapter ( ) ) ;
2024-06-15 18:24:18 +02:00
Hive . registerAdapter ( FBMessageAdapter ( ) ) ;
2024-05-25 18:09:39 +02:00
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Load Hive<scn-logs>... ' ) ;
2024-05-26 00:20:25 +02:00
try {
2024-05-25 18:09:39 +02:00
await Hive . openBox < SCNLog > ( ' scn-logs ' ) ;
2024-05-26 00:20:25 +02:00
} catch ( exc , trace ) {
Hive . deleteBoxFromDisk ( ' scn-logs ' ) ;
await Hive . openBox < SCNLog > ( ' scn-logs ' ) ;
ApplicationLog . error ( ' Failed to open Hive-Box: scn-logs: ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to open Hive-Box: scn-logs ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-05-25 18:09:39 +02:00
}
2024-02-10 19:57:17 +01:00
2024-06-15 21:29:51 +02:00
print ( ' [INIT] Load Hive<scn-requests>... ' ) ;
try {
await Hive . openBox < SCNRequest > ( ' scn-requests ' ) ;
} catch ( exc , trace ) {
Hive . deleteBoxFromDisk ( ' scn-requests ' ) ;
await Hive . openBox < SCNRequest > ( ' scn-requests ' ) ;
ApplicationLog . error ( ' Failed to open Hive-Box: scn-requests: ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to open Hive-Box: scn-requests ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-15 21:29:51 +02:00
}
2024-06-15 15:56:50 +02:00
print ( ' [INIT] Load Hive<scn-message-cache>... ' ) ;
try {
2024-06-15 21:29:51 +02:00
await Hive . openBox < SCNMessage > ( ' scn-message-cache ' ) ;
2024-06-15 15:56:50 +02:00
} catch ( exc , trace ) {
Hive . deleteBoxFromDisk ( ' scn-message-cache ' ) ;
2024-06-15 21:29:51 +02:00
await Hive . openBox < SCNMessage > ( ' scn-message-cache ' ) ;
2024-06-15 15:56:50 +02:00
ApplicationLog . error ( ' Failed to open Hive-Box: scn-message-cache ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to open Hive-Box: scn-message-cache ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-15 15:56:50 +02:00
}
print ( ' [INIT] Load Hive<scn-channel-cache>... ' ) ;
try {
await Hive . openBox < Channel > ( ' scn-channel-cache ' ) ;
} catch ( exc , trace ) {
Hive . deleteBoxFromDisk ( ' scn-channel-cache ' ) ;
await Hive . openBox < Channel > ( ' scn-channel-cache ' ) ;
ApplicationLog . error ( ' Failed to open Hive-Box: scn-channel-cache ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to open Hive-Box: scn-channel-cache ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-15 15:56:50 +02:00
}
2024-06-15 18:24:18 +02:00
print ( ' [INIT] Load Hive<scn-fb-messages>... ' ) ;
try {
await Hive . openBox < FBMessage > ( ' scn-fb-messages ' ) ;
} catch ( exc , trace ) {
Hive . deleteBoxFromDisk ( ' scn-fb-messages ' ) ;
await Hive . openBox < FBMessage > ( ' scn-fb-messages ' ) ;
ApplicationLog . error ( ' Failed to open Hive-Box: scn-fb-messages ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to open Hive-Box: scn-fb-messages ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-15 18:24:18 +02:00
}
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Load AppAuth... ' ) ;
2024-06-02 17:09:57 +02:00
final appAuth = AppAuth ( ) ; // ensure UserAccount is loaded
if ( appAuth . isAuth ( ) ) {
2024-06-17 22:53:03 +02:00
// load user+client in background
( ) async {
try {
await appAuth . loadUser ( ) ;
} catch ( exc , trace ) {
ApplicationLog . error ( ' Failed to load user (background load on startup): ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to load user (background load on startup) ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-17 22:53:03 +02:00
}
try {
await appAuth . loadClient ( ) ;
} catch ( exc , trace ) {
ApplicationLog . error ( ' Failed to load user (background load on startup): ' + exc . toString ( ) , trace: trace ) ;
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to load user (background load on startup) ' , { ' error ' : exc . toString ( ) , ' trace ' : trace } ) ;
2024-06-17 22:53:03 +02:00
}
} ( ) ;
2024-06-02 17:09:57 +02:00
}
2024-05-31 15:22:27 +02:00
2024-06-04 08:20:28 +02:00
if ( ! Platform . isLinux ) {
print ( ' [INIT] Init Firebase... ' ) ;
await Firebase . initializeApp ( options: DefaultFirebaseOptions . currentPlatform ) ;
2024-05-31 15:22:27 +02:00
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Request Notification permissions... ' ) ;
await FirebaseMessaging . instance . requestPermission ( provisional: true ) ;
FirebaseMessaging . instance . onTokenRefresh . listen ( ( fcmToken ) {
try {
setFirebaseToken ( fcmToken ) ;
} catch ( exc , trace ) {
ApplicationLog . error ( ' Failed to set firebase token: ' + exc . toString ( ) , trace: trace ) ;
}
} ) . onError ( ( dynamic err ) {
ApplicationLog . error ( ' Failed to listen to token refresh events: ' + ( err ? . toString ( ) ? ? ' ' ) ) ;
} ) ;
2024-05-31 15:22:27 +02:00
try {
2024-06-04 08:20:28 +02:00
print ( ' [INIT] Query firebase token... ' ) ;
final fcmToken = await FirebaseMessaging . instance . getToken ( ) ;
if ( fcmToken ! = null ) {
setFirebaseToken ( fcmToken ) ;
}
2024-05-31 15:22:27 +02:00
} catch ( exc , trace ) {
2024-06-04 08:20:28 +02:00
ApplicationLog . error ( ' Failed to get+set firebase token: ' + exc . toString ( ) , trace: trace ) ;
2024-05-31 15:22:27 +02:00
}
2024-06-15 18:24:18 +02:00
FirebaseMessaging . onBackgroundMessage ( _onBackgroundMessage ) ;
FirebaseMessaging . onMessage . listen ( _onForegroundMessage ) ;
2024-06-04 08:20:28 +02:00
} else {
print ( ' [INIT] Skip Firebase init (Platform == Linux)... ' ) ;
2024-06-01 03:06:02 +02:00
}
2024-06-15 21:29:51 +02:00
print ( ' [INIT] Load Notifications... ' ) ;
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin ( ) ;
final flutterLocalNotificationsPluginImpl = flutterLocalNotificationsPlugin . resolvePlatformSpecificImplementation < AndroidFlutterLocalNotificationsPlugin > ( ) ;
if ( flutterLocalNotificationsPluginImpl = = null ) {
ApplicationLog . error ( ' Failed to get AndroidFlutterLocalNotificationsPlugin ' , trace: StackTrace . current ) ;
} else {
flutterLocalNotificationsPluginImpl . requestNotificationsPermission ( ) ;
final initializationSettingsAndroid = AndroidInitializationSettings ( ' ic_notification_white ' ) ;
final initializationSettingsDarwin = DarwinInitializationSettings (
requestAlertPermission: true ,
requestBadgePermission: true ,
requestSoundPermission: true ,
onDidReceiveLocalNotification: _receiveLocalDarwinNotification ,
notificationCategories: getDarwinNotificationCategories ( ) ,
) ;
final initializationSettingsLinux = LinuxInitializationSettings ( defaultActionName: ' Open notification ' ) ;
final initializationSettings = InitializationSettings (
android: initializationSettingsAndroid ,
iOS: initializationSettingsDarwin ,
linux: initializationSettingsLinux ,
) ;
2024-07-13 01:05:32 +02:00
flutterLocalNotificationsPlugin . initialize (
initializationSettings ,
onDidReceiveNotificationResponse: _receiveLocalNotification ,
onDidReceiveBackgroundNotificationResponse: _notificationTapBackground ,
) ;
2024-06-15 21:29:51 +02:00
final appLaunchNotification = await flutterLocalNotificationsPlugin . getNotificationAppLaunchDetails ( ) ;
if ( appLaunchNotification ! = null ) {
2024-07-13 01:05:32 +02:00
// Use has launched SCN by clicking on a loca notifiaction, if it was a summary or message notifiaction open the corresponding screen
// This is android only
//TODO same on iOS, somehow??
2024-06-15 21:29:51 +02:00
ApplicationLog . info ( ' App launched by notification: ${ appLaunchNotification . notificationResponse ? . id } ' ) ;
2024-07-13 01:05:32 +02:00
_handleNotificationClickAction ( appLaunchNotification . notificationResponse ? . payload , Duration ( milliseconds: 600 ) ) ;
2024-06-15 21:29:51 +02:00
}
}
2024-06-04 08:20:28 +02:00
ApplicationLog . debug ( ' [INIT] Application started ' ) ;
2024-05-26 00:20:25 +02:00
2024-02-11 01:08:51 +01:00
runApp (
MultiProvider (
providers: [
2024-06-02 17:09:57 +02:00
ChangeNotifierProvider ( create: ( context ) = > AppAuth ( ) , lazy: false ) ,
2024-05-26 00:20:25 +02:00
ChangeNotifierProvider ( create: ( context ) = > AppTheme ( ) , lazy: false ) ,
2024-06-13 17:00:08 +02:00
ChangeNotifierProvider ( create: ( context ) = > AppBarState ( ) , lazy: false ) ,
2024-06-15 21:29:51 +02:00
ChangeNotifierProvider ( create: ( context ) = > AppSettings ( ) , lazy: false ) ,
2024-02-11 01:08:51 +01:00
] ,
2024-06-13 17:00:08 +02:00
child: SCNApp ( ) ,
2024-02-11 01:08:51 +01:00
) ,
) ;
2024-02-10 18:29:41 +01:00
}
2024-06-15 18:24:18 +02:00
class SCNApp extends StatelessWidget {
SCNApp ( { super . key } ) ;
2024-07-13 01:05:32 +02:00
static var materialKey = GlobalKey < NavigatorState > ( ) ;
2024-06-15 18:24:18 +02:00
@ override
Widget build ( BuildContext context ) {
return ToastificationWrapper (
config: ToastificationConfig (
itemWidth: 440 ,
2024-10-19 17:52:27 +02:00
marginBuilder: ( context , alignment ) = > EdgeInsets . symmetric ( vertical: 64 ) ,
2024-06-15 18:24:18 +02:00
animationDuration: Duration ( milliseconds: 200 ) ,
) ,
child: Consumer < AppTheme > (
builder: ( context , appTheme , child ) = > MaterialApp (
2024-07-13 01:05:32 +02:00
navigatorKey: SCNApp . materialKey ,
2024-06-15 18:24:18 +02:00
title: ' SimpleCloudNotifier ' ,
navigatorObservers: [ Navi . routeObserver , Navi . modalRouteObserver ] ,
theme: ThemeData (
//TODO color settings
colorScheme: ColorScheme . fromSeed ( seedColor: Colors . blue , brightness: appTheme . darkMode ? Brightness . dark : Brightness . light ) ,
useMaterial3: true ,
) ,
home: SCNNavLayout ( ) ,
) ,
) ,
) ;
}
}
2024-06-15 21:29:51 +02:00
@ pragma ( ' vm:entry-point ' )
2024-07-13 01:05:32 +02:00
void _notificationTapBackground ( NotificationResponse notificationResponse ) {
// I think only iOS triggers this, TODO
2024-06-15 21:29:51 +02:00
ApplicationLog . info ( ' Received local notification<vm:entry-point>: ${ notificationResponse . id } ' ) ;
}
2024-05-31 15:22:27 +02:00
void setFirebaseToken ( String fcmToken ) async {
2024-06-02 17:09:57 +02:00
final acc = AppAuth ( ) ;
2024-06-01 03:06:02 +02:00
final oldToken = Globals ( ) . getPrefFCMToken ( ) ;
2024-06-02 17:09:57 +02:00
await Globals ( ) . setPrefFCMToken ( fcmToken ) ;
2024-06-01 03:06:02 +02:00
ApplicationLog . info ( ' New firebase token received ' , additional: ' Token: $ fcmToken (old: $ oldToken ) ' ) ;
2024-06-02 17:09:57 +02:00
if ( ! acc . isAuth ( ) ) return ;
2024-06-01 03:06:02 +02:00
2024-06-02 17:09:57 +02:00
Client ? client ;
try {
2024-06-15 15:56:50 +02:00
client = await acc . loadClient ( forceIfOlder: Duration ( seconds: 60 ) ) ;
2024-06-02 17:09:57 +02:00
} catch ( exc , trace ) {
ApplicationLog . error ( ' Failed to get client: ' + exc . toString ( ) , trace: trace ) ;
return ;
}
2024-06-08 14:16:07 +02:00
if ( oldToken ! = null & & oldToken = = fcmToken & & client ! = null & & client . fcmToken = = fcmToken ) {
2024-06-02 17:09:57 +02:00
ApplicationLog . info ( ' Firebase token unchanged - do nothing ' , additional: ' Token: $ fcmToken ' ) ;
return ;
}
if ( client = = null ) {
// should not really happen - perhaps someone externally deleted the client?
final newClient = await APIClient . addClient ( acc , fcmToken , Globals ( ) . deviceModel , Globals ( ) . version , Globals ( ) . hostname , Globals ( ) . clientType ) ;
acc . setClientAndClientID ( newClient ) ;
await acc . save ( ) ;
} else {
final newClient = await APIClient . updateClient ( acc , client . clientID , fcmToken , Globals ( ) . deviceModel , Globals ( ) . hostname , Globals ( ) . version ) ;
acc . setClientAndClientID ( newClient ) ;
await acc . save ( ) ;
2024-05-31 15:22:27 +02:00
}
}
2024-06-17 22:26:48 +02:00
@ pragma ( ' vm:entry-point ' )
2024-06-15 18:24:18 +02:00
Future < void > _onBackgroundMessage ( RemoteMessage message ) async {
2024-07-13 01:05:32 +02:00
// a firebase message was received while the app was in the background or terminated
2024-06-15 18:24:18 +02:00
await _receiveMessage ( message , false ) ;
}
2024-02-10 18:29:41 +01:00
2024-06-17 22:26:48 +02:00
@ pragma ( ' vm:entry-point ' )
2024-06-15 18:24:18 +02:00
void _onForegroundMessage ( RemoteMessage message ) {
2024-07-13 01:05:32 +02:00
// a firebase message was received while the app was in the foreground
2024-06-15 18:24:18 +02:00
_receiveMessage ( message , true ) ;
}
Future < void > _receiveMessage ( RemoteMessage message , bool foreground ) async {
2024-06-15 21:29:51 +02:00
try {
// ensure globals init
if ( ! Globals ( ) . isInitialized ) {
print ( ' [LATE-INIT] Init Globals() - to ensure working _receiveMessage( $ foreground )... ' ) ;
await Globals ( ) . init ( ) ;
}
// ensure hive init
if ( ! Hive . isBoxOpen ( ' scn-logs ' ) ) {
print ( ' [LATE-INIT] Init Hive - to ensure working _receiveMessage( $ foreground )... ' ) ;
await Hive . initFlutter ( ) ;
Hive . registerAdapter ( SCNRequestAdapter ( ) ) ;
Hive . registerAdapter ( SCNLogAdapter ( ) ) ;
Hive . registerAdapter ( SCNLogLevelAdapter ( ) ) ;
Hive . registerAdapter ( SCNMessageAdapter ( ) ) ;
Hive . registerAdapter ( ChannelAdapter ( ) ) ;
Hive . registerAdapter ( FBMessageAdapter ( ) ) ;
}
print ( ' [LATE-INIT] Ensure hive boxes are open for _receiveMessage( $ foreground )... ' ) ;
await Hive . openBox < SCNLog > ( ' scn-logs ' ) ;
await Hive . openBox < FBMessage > ( ' scn-fb-messages ' ) ;
await Hive . openBox < SCNMessage > ( ' scn-message-cache ' ) ;
2024-07-13 00:16:01 +02:00
await Hive . openBox < SCNRequest > ( ' scn-requests ' ) ;
2024-06-15 21:29:51 +02:00
} catch ( exc , trace ) {
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to init hive ' , { ' exception ' : exc . toString ( ) , ' trace ' : trace . toString ( ) , ' data ' : message , ' foreground ' : foreground } ) ;
2024-06-15 21:29:51 +02:00
ApplicationLog . error ( ' Failed to init hive: ' + exc . toString ( ) , trace: trace ) ;
2024-07-13 01:05:32 +02:00
Notifier . showLocalNotification ( " " , " @ERROR " , " @ERROR " , ' Error Channel ' , " Error " , " Failed to receive SCN message (init failed) " , null ) ;
2024-06-15 21:29:51 +02:00
return ;
}
2024-06-15 18:24:18 +02:00
ApplicationLog . info ( ' Received FB message ( ${ foreground ? ' foreground ' : ' background ' } ): ${ message . messageId ? ? ' NULL ' } ' ) ;
2024-06-15 21:29:51 +02:00
2024-06-17 23:23:35 +02:00
String scn_msg_id ;
2024-06-15 21:29:51 +02:00
try {
2024-06-17 23:23:35 +02:00
scn_msg_id = message . data [ ' scn_msg_id ' ] as String ;
2024-06-15 21:29:51 +02:00
final timestamp = DateTime . fromMillisecondsSinceEpoch ( int . parse ( message . data [ ' timestamp ' ] as String ) * 1000 ) ;
final title = message . data [ ' title ' ] as String ;
final channel = message . data [ ' channel ' ] as String ;
final channel_id = message . data [ ' channel_id ' ] as String ;
final body = message . data [ ' body ' ] as String ;
2024-07-13 01:05:32 +02:00
Notifier . showLocalNotification ( scn_msg_id , channel_id , channel , ' Channel: ${ channel } ' , title , body , timestamp ) ;
2024-06-15 21:29:51 +02:00
} catch ( exc , trace ) {
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to decode received FB message ' , { ' exception ' : exc . toString ( ) , ' trace ' : trace . toString ( ) , ' data ' : message , ' foreground ' : foreground } ) ;
2024-06-15 21:29:51 +02:00
ApplicationLog . error ( ' Failed to decode received FB message ' + exc . toString ( ) , trace: trace ) ;
2024-07-13 01:05:32 +02:00
Notifier . showLocalNotification ( " " , " @ERROR " , " @ERROR " , ' Error Channel ' , " Error " , " Failed to receive SCN message (decode failed) " , null ) ;
2024-06-15 21:29:51 +02:00
return ;
}
try {
FBMessageLog . insert ( message ) ;
} catch ( exc , trace ) {
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to persist received FB message ' , { ' exception ' : exc . toString ( ) , ' trace ' : trace . toString ( ) , ' data ' : message , ' foreground ' : foreground } ) ;
2024-06-15 21:29:51 +02:00
ApplicationLog . error ( ' Failed to persist received FB message ' + exc . toString ( ) , trace: trace ) ;
2024-07-13 01:05:32 +02:00
Notifier . showLocalNotification ( " " , " @ERROR " , " @ERROR " , ' Error Channel ' , " Error " , " Failed to receive SCN message (persist failed) " , null ) ;
2024-06-15 21:29:51 +02:00
return ;
}
2024-06-17 23:23:35 +02:00
try {
final msg = await APIClient . getMessage ( AppAuth ( ) , scn_msg_id ) ;
SCNDataCache ( ) . addToMessageCache ( [ msg ] ) ;
if ( foreground ) AppEvents ( ) . notifyMessageReceivedListeners ( msg ) ;
} catch ( exc , trace ) {
2024-10-19 17:16:34 +02:00
ApplicationLog . writeRawFailure ( ' Failed to query+persist message ' , { ' exception ' : exc . toString ( ) , ' trace ' : trace . toString ( ) , ' data ' : message , ' foreground ' : foreground } ) ;
2024-09-19 19:46:46 +02:00
ApplicationLog . error ( ' Failed to query+persist message: ' + exc . toString ( ) , trace: trace ) ;
2024-06-17 23:23:35 +02:00
return ;
}
2024-06-15 21:29:51 +02:00
}
void _receiveLocalDarwinNotification ( int id , String ? title , String ? body , String ? payload ) {
2024-07-13 01:05:32 +02:00
//TODO iOS?
2024-06-15 21:29:51 +02:00
ApplicationLog . info ( ' Received local notification<darwin>: $ id -> [ $ title ] ' ) ;
}
void _receiveLocalNotification ( NotificationResponse details ) {
2024-07-13 01:05:32 +02:00
// User has tapped a flutter_local notification, while the app was running
ApplicationLog . info ( ' Tapped local notification: [[ ${ details . id } | ${ details . actionId } | ${ details . input } | ${ details . notificationResponseType } | ${ details . payload } ]] ' ) ;
_handleNotificationClickAction ( details . payload , Duration . zero ) ;
}
void _handleNotificationClickAction ( String ? payload , Duration delay ) {
final parts = payload ? . split ( ' \n ' ) ? ? [ ] ;
if ( parts . length = = 4 & & parts [ 0 ] = = ' @SCN_MESSAGE ' ) {
final messageID = parts [ 1 ] ;
( ) async {
2024-10-19 17:52:27 +02:00
await Future . delayed ( delay , ( ) { } ) ;
2024-07-13 01:05:32 +02:00
SchedulerBinding . instance . addPostFrameCallback ( ( _ ) {
ApplicationLog . info ( ' Handle notification action @SCN_MESSAGE --> ${ messageID } ' ) ;
Navi . push ( SCNApp . materialKey . currentContext ! , ( ) = > MessageViewPage ( messageID: messageID , preloadedData: null ) ) ;
} ) ;
} ( ) ;
} else if ( parts . length = = 3 & & parts [ 0 ] = = ' @SCN_MESSAGE_SUMMARY ' ) {
final channelID = parts [ 1 ] ;
( ) async {
2024-10-19 17:52:27 +02:00
await Future . delayed ( delay , ( ) { } ) ;
2024-07-13 01:05:32 +02:00
SchedulerBinding . instance . addPostFrameCallback ( ( _ ) {
ApplicationLog . info ( ' Handle notification action @SCN_MESSAGE_SUMMARY --> ${ channelID } ' ) ;
Navi . push ( SCNApp . materialKey . currentContext ! , ( ) = > ChannelViewPage ( channelID: channelID , preloadedData: null , needsReload: null ) ) ;
} ) ;
} ( ) ;
}
2024-06-15 21:29:51 +02:00
}
List < DarwinNotificationCategory > getDarwinNotificationCategories ( ) {
return < DarwinNotificationCategory > [
//TODO ?!?
] ;
2024-02-10 18:29:41 +01:00
}