twonly-app/lib/src/services/notification_service.dart
2025-03-25 00:11:07 +01:00

195 lines
6.5 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logging/logging.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/database/tables/contacts_table.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/json_models/message.dart' as my;
/// Streams are created so that app can respond to notification-related events
/// since the plugin is initialized in the `main` function
final StreamController<NotificationResponse> selectNotificationStream =
StreamController<NotificationResponse>.broadcast();
const MethodChannel platform = MethodChannel('twonly.eu/notifications');
const String portName = 'notification_send_port';
class ReceivedNotification {
ReceivedNotification({
required this.id,
required this.title,
required this.body,
required this.payload,
this.data,
});
final int id;
final String? title;
final String? body;
final String? payload;
final Map<String, dynamic>? data;
}
String? selectedNotificationPayload;
/// A notification action which triggers a url launch event
const String urlLaunchActionId = 'id_1';
/// A notification action which triggers a App navigation event
const String navigationActionId = 'id_3';
/// Defines a iOS/MacOS notification category for text input actions.
const String darwinNotificationCategoryText = 'textCategory';
/// Defines a iOS/MacOS notification category for plain actions.
const String darwinNotificationCategoryPlain = 'plainCategory';
@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
// ignore: avoid_print
print('notification(${notificationResponse.id}) action tapped: '
'${notificationResponse.actionId} with'
' payload: ${notificationResponse.payload}');
if (notificationResponse.input?.isNotEmpty ?? false) {
// ignore: avoid_print
print(
'notification action tapped with input: ${notificationResponse.input}');
}
}
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
int id = 0;
Future<void> setupPushNotification() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings("ic_launcher_foreground");
final List<DarwinNotificationCategory> darwinNotificationCategories =
<DarwinNotificationCategory>[];
/// Note: permissions aren't requested here just to demonstrate that can be
/// done later
final DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
requestProvisionalPermission: false,
notificationCategories: darwinNotificationCategories,
);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: selectNotificationStream.add,
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
}
String getPushNotificationText(String key, String userName) {
String systemLanguage = Platform.localeName;
Map<String, String> pushNotificationText;
if (systemLanguage.contains("de")) {
pushNotificationText = {
"newTextMessage": "%userName% hat dir eine Nachricht gesendet.",
"newTwonly": "%userName% hat dir ein twonly gesendet.",
"newVideo": "%userName% hat dir ein Video gesendet.",
"newImage": "%userName% hat dir ein Bild gesendet.",
"contactRequest": "%userName% möchte sich mir dir vernetzen.",
"acceptRequest": "%userName% ist jetzt mit dir vernetzt.",
"storedMediaFile": "%userName% hat dein Bild gespeichert."
};
} else {
pushNotificationText = {
"newTextMessage": "%userName% has sent you a message.",
"newTwonly": "%userName% has sent you a twonly.",
"newVideo": "%userName% has sent you a video.",
"newImage": "%userName% has sent you an image.",
"contactRequest": "%userName% wants to connect with you.",
"acceptRequest": "%userName% is now connected with you.",
"storedMediaFile": "%userName% has stored your image."
};
}
// Replace %userName% with the actual user name
return pushNotificationText[key]?.replaceAll("%userName%", userName) ?? "";
}
Future localPushNotificationNewMessage(
int fromUserId, my.MessageJson message, int messageId) async {
Contact? user = await twonlyDatabase.contactsDao
.getContactByUserId(fromUserId)
.getSingleOrNull();
if (user == null) return;
String msg = "";
final content = message.content;
if (content is my.TextMessageContent) {
msg =
getPushNotificationText("newTextMessage", getContactDisplayName(user));
} else if (content is my.MediaMessageContent) {
if (content.isRealTwonly) {
msg = getPushNotificationText("newTwonly", getContactDisplayName(user));
} else if (content.isVideo) {
msg = getPushNotificationText("newVideo", getContactDisplayName(user));
} else {
msg = getPushNotificationText("newImage", getContactDisplayName(user));
}
}
if (message.kind == my.MessageKind.contactRequest) {
msg =
getPushNotificationText("contactRequest", getContactDisplayName(user));
}
if (message.kind == my.MessageKind.acceptRequest) {
msg = getPushNotificationText("acceptRequest", getContactDisplayName(user));
}
if (message.kind == my.MessageKind.storedMediaFile) {
msg =
getPushNotificationText("storedMediaFile", getContactDisplayName(user));
}
if (msg == "") {
Logger("localPushNotificationNewMessage")
.shout("No push notification type defined!");
}
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'0',
'Messages',
channelDescription: 'Messages from other users.',
importance: Importance.max,
priority: Priority.max,
ticker: 'You got a new message.',
);
const DarwinNotificationDetails darwinNotificationDetails =
DarwinNotificationDetails();
const NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails, iOS: darwinNotificationDetails);
await flutterLocalNotificationsPlugin.show(
messageId,
getContactDisplayName(user),
msg,
notificationDetails,
payload: message.kind.index.toString(),
);
}