From adb8ee88d1ff09b0e4c7e9338c52748119c21dd0 Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Fri, 28 Jul 2023 17:32:14 +0200 Subject: [PATCH] feat: Take care of i18n --- example/lib/main.dart | 11 +- .../me/polynom/moxplatform_android/Api.java | 116 +++++++++++++++++- .../moxplatform_android/BootReceiver.java | 10 +- .../polynom/moxplatform_android/Constants.kt | 10 +- .../MoxplatformAndroidPlugin.java | 7 +- .../NotificationReceiver.kt | 70 +++++++++-- .../moxplatform_android/Notifications.kt | 34 ++--- .../lib/src/notifications_android.dart | 3 +- .../lib/src/api.g.dart | 49 +++++++- .../lib/src/notifications.dart | 2 +- .../lib/src/notifications_stub.dart | 2 +- pigeons/api.dart | 15 ++- 12 files changed, 277 insertions(+), 52 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index ada36f7..0ad4575 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -41,7 +41,16 @@ class MyAppState extends State { Future initStateAsync() async { await Permission.notification.request(); - await MoxplatformPlugin.notifications.createNotificationChannel("Test notification channel", channelId, false); + await MoxplatformPlugin.notifications.createNotificationChannel( + "Test notification channel", + channelId, + false, + NotificationI18nData( + reply: "答える", + markAsRead: "読みた", + you: "あなた", + ), + ); MoxplatformPlugin.notifications.getEventStream().listen((event) { print('NotificationEvent(type: ${event.type}, jid: ${event.jid}, payload: ${event.payload})'); diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Api.java b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Api.java index f500f94..db3ce05 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Api.java +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Api.java @@ -554,6 +554,106 @@ public class Api { } } + /** Generated class from Pigeon that represents data sent in messages. */ + public static final class NotificationI18nData { + /** The content of the reply button. */ + private @NonNull String reply; + + public @NonNull String getReply() { + return reply; + } + + public void setReply(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"reply\" is null."); + } + this.reply = setterArg; + } + + /** The content of the "mark as read" button. */ + private @NonNull String markAsRead; + + public @NonNull String getMarkAsRead() { + return markAsRead; + } + + public void setMarkAsRead(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"markAsRead\" is null."); + } + this.markAsRead = setterArg; + } + + /** The text to show when *you* reply. */ + private @NonNull String you; + + public @NonNull String getYou() { + return you; + } + + public void setYou(@NonNull String setterArg) { + if (setterArg == null) { + throw new IllegalStateException("Nonnull field \"you\" is null."); + } + this.you = setterArg; + } + + /** Constructor is non-public to enforce null safety; use Builder. */ + NotificationI18nData() {} + + public static final class Builder { + + private @Nullable String reply; + + public @NonNull Builder setReply(@NonNull String setterArg) { + this.reply = setterArg; + return this; + } + + private @Nullable String markAsRead; + + public @NonNull Builder setMarkAsRead(@NonNull String setterArg) { + this.markAsRead = setterArg; + return this; + } + + private @Nullable String you; + + public @NonNull Builder setYou(@NonNull String setterArg) { + this.you = setterArg; + return this; + } + + public @NonNull NotificationI18nData build() { + NotificationI18nData pigeonReturn = new NotificationI18nData(); + pigeonReturn.setReply(reply); + pigeonReturn.setMarkAsRead(markAsRead); + pigeonReturn.setYou(you); + return pigeonReturn; + } + } + + @NonNull + ArrayList toList() { + ArrayList toListResult = new ArrayList(3); + toListResult.add(reply); + toListResult.add(markAsRead); + toListResult.add(you); + return toListResult; + } + + static @NonNull NotificationI18nData fromList(@NonNull ArrayList list) { + NotificationI18nData pigeonResult = new NotificationI18nData(); + Object reply = list.get(0); + pigeonResult.setReply((String) reply); + Object markAsRead = list.get(1); + pigeonResult.setMarkAsRead((String) markAsRead); + Object you = list.get(2); + pigeonResult.setYou((String) you); + return pigeonResult; + } + } + private static class MoxplatformApiCodec extends StandardMessageCodec { public static final MoxplatformApiCodec INSTANCE = new MoxplatformApiCodec(); @@ -567,8 +667,10 @@ public class Api { case (byte) 129: return NotificationEvent.fromList((ArrayList) readValue(buffer)); case (byte) 130: - return NotificationMessage.fromList((ArrayList) readValue(buffer)); + return NotificationI18nData.fromList((ArrayList) readValue(buffer)); case (byte) 131: + return NotificationMessage.fromList((ArrayList) readValue(buffer)); + case (byte) 132: return NotificationMessageContent.fromList((ArrayList) readValue(buffer)); default: return super.readValueOfType(type, buffer); @@ -583,11 +685,14 @@ public class Api { } else if (value instanceof NotificationEvent) { stream.write(129); writeValue(stream, ((NotificationEvent) value).toList()); - } else if (value instanceof NotificationMessage) { + } else if (value instanceof NotificationI18nData) { stream.write(130); + writeValue(stream, ((NotificationI18nData) value).toList()); + } else if (value instanceof NotificationMessage) { + stream.write(131); writeValue(stream, ((NotificationMessage) value).toList()); } else if (value instanceof NotificationMessageContent) { - stream.write(131); + stream.write(132); writeValue(stream, ((NotificationMessageContent) value).toList()); } else { super.writeValue(stream, value); @@ -598,7 +703,7 @@ public class Api { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface MoxplatformApi { - void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent); + void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent, @NonNull NotificationI18nData i18n); void showMessagingNotification(@NonNull MessagingNotification notification); @@ -628,8 +733,9 @@ public class Api { String titleArg = (String) args.get(0); String idArg = (String) args.get(1); Boolean urgentArg = (Boolean) args.get(2); + NotificationI18nData i18nArg = (NotificationI18nData) args.get(3); try { - api.createNotificationChannel(titleArg, idArg, urgentArg); + api.createNotificationChannel(titleArg, idArg, urgentArg, i18nArg); wrapped.add(0, null); } catch (Throwable exception) { diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/BootReceiver.java b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/BootReceiver.java index 372d141..6603649 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/BootReceiver.java +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/BootReceiver.java @@ -16,11 +16,11 @@ public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (MoxplatformAndroidPlugin.getStartAtBoot(context)) { - if (BackgroundService.wakeLock == null) { - Log.d(TAG, "Wakelock is null. Acquiring it..."); - BackgroundService.getLock(context).acquire(MoxplatformConstants.WAKE_LOCK_DURATION); - Log.d(TAG, "Wakelock acquired..."); - } + if (BackgroundService.wakeLock == null) { + Log.d(TAG, "Wakelock is null. Acquiring it..."); + BackgroundService.getLock(context).acquire(MoxplatformConstants.WAKE_LOCK_DURATION); + Log.d(TAG, "Wakelock acquired..."); + } ContextCompat.startForegroundService(context, new Intent(context, BackgroundService.class)); } diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Constants.kt b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Constants.kt index 31b9696..78b8798 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Constants.kt +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Constants.kt @@ -6,17 +6,21 @@ const val TAG = "Moxplatform" // The size of the buffer to hashing, encryption, and decryption in bytes. const val BUFFER_SIZE = 8096 -const val REPLY_ACTION = "reply"; // The data key for text entered in the notification's reply field const val REPLY_TEXT_KEY = "key_reply_text" -// The action for pressing the "Mark as read" button on a notification -const val MARK_AS_READ_ACTION = "mark_as_read" // The key for the notification id to mark as read const val MARK_AS_READ_ID_KEY = "notification_id" +// Values for actions performed through the notification +const val REPLY_ACTION = "reply"; +const val MARK_AS_READ_ACTION = "mark_as_read" const val TAP_ACTION = "tap"; +// Extra data keys for the intents that reach the NotificationReceiver +const val NOTIFICATION_EXTRA_JID_KEY = "jid"; +const val NOTIFICATION_EXTRA_ID_KEY = "notification_id"; + // TODO: Maybe try again to rewrite the entire plugin in Kotlin //const val METHOD_CHANNEL_KEY = "me.polynom.moxplatform_android" //const val BACKGROUND_METHOD_CHANNEL_KEY = METHOD_CHANNEL_KEY + "_bg" diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/MoxplatformAndroidPlugin.java b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/MoxplatformAndroidPlugin.java index e9d06ea..55d5342 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/MoxplatformAndroidPlugin.java +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/MoxplatformAndroidPlugin.java @@ -288,7 +288,7 @@ import kotlin.jvm.functions.Function1; } @Override - public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent) { + public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent, @NonNull NotificationI18nData i18n) { final NotificationChannel channel = new NotificationChannel( id, title, @@ -298,6 +298,11 @@ import kotlin.jvm.functions.Function1; channel.enableLights(true); final NotificationManager manager = getSystemService(context, NotificationManager.class); manager.createNotificationChannel(channel); + + // Configure i18n + NotificationI18nManager.INSTANCE.setYou(i18n.getYou()); + NotificationI18nManager.INSTANCE.setReply(i18n.getReply()); + NotificationI18nManager.INSTANCE.setMarkAsRead(i18n.getMarkAsRead()); } @Override diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/NotificationReceiver.kt b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/NotificationReceiver.kt index 5a9946e..7e7c03b 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/NotificationReceiver.kt +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/NotificationReceiver.kt @@ -1,19 +1,27 @@ package me.polynom.moxplatform_android +import android.app.Notification import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.os.Build import android.util.Log +import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import androidx.core.app.Person import androidx.core.app.RemoteInput import me.polynom.moxplatform_android.Api.NotificationEvent +import java.time.Instant class NotificationReceiver : BroadcastReceiver() { + /* + * Dismisses the notification through which we received @intent. + * */ private fun dismissNotification(context: Context, intent: Intent) { // Dismiss the notification - val notificationId = intent.getLongExtra("notification_id", -1).toInt() + val notificationId = intent.getLongExtra(NOTIFICATION_EXTRA_ID_KEY, -1).toInt() if (notificationId != -1) { NotificationManagerCompat.from(context).cancel( notificationId, @@ -23,15 +31,19 @@ class NotificationReceiver : BroadcastReceiver() { } } + private fun findActiveNotification(context: Context, id: Int): Notification? { + return (context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) + .activeNotifications + .find { it.id == id }?.notification + } + private fun handleMarkAsRead(context: Context, intent: Intent) { - Log.d("NotificationReceiver", "Marking ${intent.getStringExtra("jid")} as read") - val jidWrapper = intent.getStringExtra("jid") ?: "" NotificationManagerCompat.from(context).cancel(intent.getLongExtra(MARK_AS_READ_ID_KEY, -1).toInt()) MoxplatformAndroidPlugin.notificationSink?.success( NotificationEvent().apply { // TODO: Use constant for key // TODO: Fix - jid = jidWrapper + jid = intent.getStringExtra(NOTIFICATION_EXTRA_JID_KEY)!! type = Api.NotificationEventType.MARK_AS_READ payload = null }.toList() @@ -41,28 +53,60 @@ class NotificationReceiver : BroadcastReceiver() { } private fun handleReply(context: Context, intent: Intent) { - val jidWrapper = intent.getStringExtra("jid") ?: "" val remoteInput = RemoteInput.getResultsFromIntent(intent) ?: return - Log.d("NotificationReceiver", "Got a reply for ${jidWrapper}") - // TODO: Notify app + val replyPayload = remoteInput.getCharSequence(REPLY_TEXT_KEY) MoxplatformAndroidPlugin.notificationSink?.success( NotificationEvent().apply { // TODO: Use constant for key - jid = jidWrapper + jid = intent.getStringExtra(NOTIFICATION_EXTRA_JID_KEY)!! type = Api.NotificationEventType.REPLY - payload = remoteInput.getCharSequence(REPLY_TEXT_KEY).toString() + payload = replyPayload.toString() }.toList() ) - // TODO: Update the notification to prevent showing the spinner + val id = intent.getLongExtra(NOTIFICATION_EXTRA_ID_KEY, -1).toInt() + if (id == -1) { + Log.e(TAG, "Failed to find notification id for reply") + return; + } + + val notification = findActiveNotification(context, id) + if (notification == null) { + Log.e(TAG, "Failed to find notification for id ${id}") + return + } + + // Thanks https://medium.com/@sidorovroman3/android-how-to-use-messagingstyle-for-notifications-without-caching-messages-c414ef2b816c + val recoveredStyle = NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(notification)!! + // TODO: Use a person and cache this data somewhere + val newStyle = Notification.MessagingStyle(NotificationI18nManager.you).apply { + conversationTitle = recoveredStyle.conversationTitle + // TODO: Use person + recoveredStyle.messages.forEach { + addMessage(Notification.MessagingStyle.Message(it.text, it.timestamp, it.sender)) + } + } + + // TODO: Images get lost here? Do we have to request a new content URI? + newStyle.addMessage( + Notification.MessagingStyle.Message( + replyPayload!!, + Instant.now().toEpochMilli(), + null as CharSequence? + ) + ) + + val recoveredBuilder = Notification.Builder.recoverBuilder(context, notification).apply { + style = newStyle + setOnlyAlertOnce(true) + } + NotificationManagerCompat.from(context).notify(id, recoveredBuilder.build()) } private fun handleTap(context: Context, intent: Intent) { - Log.d("NotificationReceiver", "Received a tap") - MoxplatformAndroidPlugin.notificationSink?.success( NotificationEvent().apply { - jid = intent.getStringExtra("jid")!! + jid = intent.getStringExtra(NOTIFICATION_EXTRA_JID_KEY)!! type = Api.NotificationEventType.OPEN payload = null }.toList() diff --git a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.kt b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.kt index 899c78e..ecaa52a 100644 --- a/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.kt +++ b/packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.kt @@ -12,18 +12,23 @@ import androidx.core.content.FileProvider import androidx.core.graphics.drawable.IconCompat import java.io.File +object NotificationI18nManager { + var you: String = "You" + var markAsRead: String = "Mark as read" + var reply: String = "Reply" +} + /// Show a messaging style notification described by @notification. fun showMessagingNotification(context: Context, notification: Api.MessagingNotification) { // Build the actions // -> Reply action val remoteInput = RemoteInput.Builder(REPLY_TEXT_KEY).apply { - // TODO: i18n - setLabel("Reply") + setLabel(NotificationI18nManager.reply) }.build() val replyIntent = Intent(context, NotificationReceiver::class.java).apply { action = REPLY_ACTION - // TODO: Use a constant - putExtra("jid", notification.jid) + putExtra(NOTIFICATION_EXTRA_JID_KEY, notification.jid) + putExtra(NOTIFICATION_EXTRA_ID_KEY, notification.id) } val replyPendingIntent = PendingIntent.getBroadcast( context.applicationContext, @@ -34,8 +39,7 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif val replyAction = NotificationCompat.Action.Builder( // TODO: Wrong icon? R.drawable.ic_service_icon, - // TODO: i18n - "Reply", + NotificationI18nManager.reply, replyPendingIntent, ).apply { addRemoteInput(remoteInput) @@ -45,9 +49,8 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif // -> Mark as read action val markAsReadIntent = Intent(context, NotificationReceiver::class.java).apply { action = MARK_AS_READ_ACTION - // TODO: Use a constant - putExtra("jid", notification.jid) - putExtra("notification_id", notification.id) + putExtra(NOTIFICATION_EXTRA_JID_KEY, notification.jid) + putExtra(NOTIFICATION_EXTRA_ID_KEY, notification.id) } val markAsReadPendingIntent = PendingIntent.getBroadcast( context.applicationContext, @@ -59,7 +62,7 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif // TODO: Wrong icon R.drawable.ic_service_icon, // TODO: i18n - "Mark as read", + NotificationI18nManager.markAsRead, markAsReadPendingIntent, ).build() @@ -67,9 +70,8 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif // Thanks https://github.com/MaikuB/flutter_local_notifications/blob/master/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java#L246 val tapIntent = Intent(context, NotificationReceiver::class.java).apply { action = TAP_ACTION - // TODO: Use constants - putExtra("jid", notification.jid) - putExtra("notification_id", notification.id) + putExtra(NOTIFICATION_EXTRA_JID_KEY, notification.jid) + putExtra(NOTIFICATION_EXTRA_ID_KEY, notification.id) } val tapPendingIntent = PendingIntent.getBroadcast( context, @@ -80,8 +82,7 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif // Build the notification // TODO: Use a person - // TODO: i18n - val style = NotificationCompat.MessagingStyle("Me"); + val style = NotificationCompat.MessagingStyle(NotificationI18nManager.you); for (message in notification.messages) { // Build the sender val sender = Person.Builder().apply { @@ -131,6 +132,9 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif // Notification actions addAction(replyAction) addAction(markAsReadAction) + + // Prevent no notification when we replied before + setOnlyAlertOnce(false) }.build() // Post the notification diff --git a/packages/moxplatform_android/lib/src/notifications_android.dart b/packages/moxplatform_android/lib/src/notifications_android.dart index 2a2243e..ff14296 100644 --- a/packages/moxplatform_android/lib/src/notifications_android.dart +++ b/packages/moxplatform_android/lib/src/notifications_android.dart @@ -13,8 +13,9 @@ class AndroidNotificationsImplementation extends NotificationsImplementation { String title, String id, bool urgent, + NotificationI18nData i18n, ) async { - return _api.createNotificationChannel(title, id, urgent); + return _api.createNotificationChannel(title, id, urgent, i18n); } @override diff --git a/packages/moxplatform_platform_interface/lib/src/api.g.dart b/packages/moxplatform_platform_interface/lib/src/api.g.dart index 96ea483..42f8a0f 100644 --- a/packages/moxplatform_platform_interface/lib/src/api.g.dart +++ b/packages/moxplatform_platform_interface/lib/src/api.g.dart @@ -175,6 +175,40 @@ class NotificationEvent { } } +class NotificationI18nData { + NotificationI18nData({ + required this.reply, + required this.markAsRead, + required this.you, + }); + + /// The content of the reply button. + String reply; + + /// The content of the "mark as read" button. + String markAsRead; + + /// The text to show when *you* reply. + String you; + + Object encode() { + return [ + reply, + markAsRead, + you, + ]; + } + + static NotificationI18nData decode(Object result) { + result as List; + return NotificationI18nData( + reply: result[0]! as String, + markAsRead: result[1]! as String, + you: result[2]! as String, + ); + } +} + class _MoxplatformApiCodec extends StandardMessageCodec { const _MoxplatformApiCodec(); @override @@ -185,12 +219,15 @@ class _MoxplatformApiCodec extends StandardMessageCodec { } else if (value is NotificationEvent) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is NotificationMessage) { + } else if (value is NotificationI18nData) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is NotificationMessageContent) { + } else if (value is NotificationMessage) { buffer.putUint8(131); writeValue(buffer, value.encode()); + } else if (value is NotificationMessageContent) { + buffer.putUint8(132); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -204,8 +241,10 @@ class _MoxplatformApiCodec extends StandardMessageCodec { case 129: return NotificationEvent.decode(readValue(buffer)!); case 130: - return NotificationMessage.decode(readValue(buffer)!); + return NotificationI18nData.decode(readValue(buffer)!); case 131: + return NotificationMessage.decode(readValue(buffer)!); + case 132: return NotificationMessageContent.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -223,12 +262,12 @@ class MoxplatformApi { static const MessageCodec codec = _MoxplatformApiCodec(); - Future createNotificationChannel(String arg_title, String arg_id, bool arg_urgent) async { + Future createNotificationChannel(String arg_title, String arg_id, bool arg_urgent, NotificationI18nData arg_i18n) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannel', codec, binaryMessenger: _binaryMessenger); final List? replyList = - await channel.send([arg_title, arg_id, arg_urgent]) as List?; + await channel.send([arg_title, arg_id, arg_urgent, arg_i18n]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', diff --git a/packages/moxplatform_platform_interface/lib/src/notifications.dart b/packages/moxplatform_platform_interface/lib/src/notifications.dart index 8b5ff48..bcf9fc5 100644 --- a/packages/moxplatform_platform_interface/lib/src/notifications.dart +++ b/packages/moxplatform_platform_interface/lib/src/notifications.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:moxplatform_platform_interface/src/api.g.dart'; abstract class NotificationsImplementation { - Future createNotificationChannel(String title, String id, bool urgent); + Future createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n); Future showMessagingNotification(MessagingNotification notification); diff --git a/packages/moxplatform_platform_interface/lib/src/notifications_stub.dart b/packages/moxplatform_platform_interface/lib/src/notifications_stub.dart index c6dd341..40e2f71 100644 --- a/packages/moxplatform_platform_interface/lib/src/notifications_stub.dart +++ b/packages/moxplatform_platform_interface/lib/src/notifications_stub.dart @@ -4,7 +4,7 @@ import 'package:moxplatform_platform_interface/src/notifications.dart'; class StubNotificationsImplementation extends NotificationsImplementation { @override - Future createNotificationChannel(String title, String id, bool urgent) async {} + Future createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n) async {} @override Future showMessagingNotification(MessagingNotification notification) async {} diff --git a/pigeons/api.dart b/pigeons/api.dart index 7634510..d8471cd 100644 --- a/pigeons/api.dart +++ b/pigeons/api.dart @@ -97,9 +97,22 @@ class NotificationEvent { final String? payload; } +class NotificationI18nData { + const NotificationI18nData(this.reply, this.markAsRead, this.you); + + /// The content of the reply button. + final String reply; + + /// The content of the "mark as read" button. + final String markAsRead; + + /// The text to show when *you* reply. + final String you; +} + @HostApi() abstract class MoxplatformApi { - void createNotificationChannel(String title, String id, bool urgent); + void createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n); void showMessagingNotification(MessagingNotification notification);