feat: Color in the notification silhouette
This commit is contained in:
parent
daf40aed0b
commit
8f93821617
@ -45,6 +45,8 @@ class MyAppState extends State<MyApp> {
|
|||||||
"Test notification channel",
|
"Test notification channel",
|
||||||
channelId,
|
channelId,
|
||||||
false,
|
false,
|
||||||
|
);
|
||||||
|
await MoxplatformPlugin.notifications.setI18n(
|
||||||
NotificationI18nData(
|
NotificationI18nData(
|
||||||
reply: "答える",
|
reply: "答える",
|
||||||
markAsRead: "読みた",
|
markAsRead: "読みた",
|
||||||
@ -128,9 +130,8 @@ class MyHomePage extends StatelessWidget {
|
|||||||
title: const Text('Moxplatform Demo'),
|
title: const Text('Moxplatform Demo'),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: ListView(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
children: <Widget>[
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _cryptoTest,
|
onPressed: _cryptoTest,
|
||||||
child: const Text('Test cryptography'),
|
child: const Text('Test cryptography'),
|
||||||
|
@ -703,12 +703,14 @@ public class Api {
|
|||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
public interface MoxplatformApi {
|
public interface MoxplatformApi {
|
||||||
|
|
||||||
void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent, @NonNull NotificationI18nData i18n);
|
void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent);
|
||||||
|
|
||||||
void showMessagingNotification(@NonNull MessagingNotification notification);
|
void showMessagingNotification(@NonNull MessagingNotification notification);
|
||||||
|
|
||||||
void setNotificationSelfAvatar(@NonNull String path);
|
void setNotificationSelfAvatar(@NonNull String path);
|
||||||
|
|
||||||
|
void setNotificationI18n(@NonNull NotificationI18nData data);
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
String getPersistentDataPath();
|
String getPersistentDataPath();
|
||||||
|
|
||||||
@ -735,9 +737,8 @@ public class Api {
|
|||||||
String titleArg = (String) args.get(0);
|
String titleArg = (String) args.get(0);
|
||||||
String idArg = (String) args.get(1);
|
String idArg = (String) args.get(1);
|
||||||
Boolean urgentArg = (Boolean) args.get(2);
|
Boolean urgentArg = (Boolean) args.get(2);
|
||||||
NotificationI18nData i18nArg = (NotificationI18nData) args.get(3);
|
|
||||||
try {
|
try {
|
||||||
api.createNotificationChannel(titleArg, idArg, urgentArg, i18nArg);
|
api.createNotificationChannel(titleArg, idArg, urgentArg);
|
||||||
wrapped.add(0, null);
|
wrapped.add(0, null);
|
||||||
}
|
}
|
||||||
catch (Throwable exception) {
|
catch (Throwable exception) {
|
||||||
@ -788,6 +789,30 @@ public class Api {
|
|||||||
api.setNotificationSelfAvatar(pathArg);
|
api.setNotificationSelfAvatar(pathArg);
|
||||||
wrapped.add(0, null);
|
wrapped.add(0, null);
|
||||||
}
|
}
|
||||||
|
catch (Throwable exception) {
|
||||||
|
ArrayList<Object> wrappedError = wrapError(exception);
|
||||||
|
wrapped = wrappedError;
|
||||||
|
}
|
||||||
|
reply.reply(wrapped);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
BasicMessageChannel<Object> channel =
|
||||||
|
new BasicMessageChannel<>(
|
||||||
|
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.setNotificationI18n", getCodec());
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler(
|
||||||
|
(message, reply) -> {
|
||||||
|
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||||
|
ArrayList<Object> args = (ArrayList<Object>) message;
|
||||||
|
NotificationI18nData dataArg = (NotificationI18nData) args.get(0);
|
||||||
|
try {
|
||||||
|
api.setNotificationI18n(dataArg);
|
||||||
|
wrapped.add(0, null);
|
||||||
|
}
|
||||||
catch (Throwable exception) {
|
catch (Throwable exception) {
|
||||||
ArrayList<Object> wrappedError = wrapError(exception);
|
ArrayList<Object> wrappedError = wrapError(exception);
|
||||||
wrapped = wrappedError;
|
wrapped = wrappedError;
|
||||||
|
@ -288,7 +288,7 @@ import kotlin.jvm.functions.Function1;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent, @NonNull NotificationI18nData i18n) {
|
public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent) {
|
||||||
final NotificationChannel channel = new NotificationChannel(
|
final NotificationChannel channel = new NotificationChannel(
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
@ -298,11 +298,6 @@ import kotlin.jvm.functions.Function1;
|
|||||||
channel.enableLights(true);
|
channel.enableLights(true);
|
||||||
final NotificationManager manager = getSystemService(context, NotificationManager.class);
|
final NotificationManager manager = getSystemService(context, NotificationManager.class);
|
||||||
manager.createNotificationChannel(channel);
|
manager.createNotificationChannel(channel);
|
||||||
|
|
||||||
// Configure i18n
|
|
||||||
NotificationDataManager.INSTANCE.setYou(i18n.getYou());
|
|
||||||
NotificationDataManager.INSTANCE.setReply(i18n.getReply());
|
|
||||||
NotificationDataManager.INSTANCE.setMarkAsRead(i18n.getMarkAsRead());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -315,6 +310,14 @@ import kotlin.jvm.functions.Function1;
|
|||||||
NotificationDataManager.INSTANCE.setAvatarPath(path);
|
NotificationDataManager.INSTANCE.setAvatarPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNotificationI18n(@NonNull NotificationI18nData data) {
|
||||||
|
// Configure i18n
|
||||||
|
NotificationDataManager.INSTANCE.setYou(data.getYou());
|
||||||
|
NotificationDataManager.INSTANCE.setReply(data.getReply());
|
||||||
|
NotificationDataManager.INSTANCE.setMarkAsRead(data.getMarkAsRead());
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String getPersistentDataPath() {
|
public String getPersistentDataPath() {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package me.polynom.moxplatform_android
|
package me.polynom.moxplatform_android
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Color
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.app.Person
|
import androidx.core.app.Person
|
||||||
@ -38,8 +40,7 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT,
|
PendingIntent.FLAG_UPDATE_CURRENT,
|
||||||
)
|
)
|
||||||
val replyAction = NotificationCompat.Action.Builder(
|
val replyAction = NotificationCompat.Action.Builder(
|
||||||
// TODO: Wrong icon?
|
R.drawable.reply,
|
||||||
R.drawable.ic_service_icon,
|
|
||||||
NotificationDataManager.reply,
|
NotificationDataManager.reply,
|
||||||
replyPendingIntent,
|
replyPendingIntent,
|
||||||
).apply {
|
).apply {
|
||||||
@ -60,8 +61,7 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT,
|
PendingIntent.FLAG_UPDATE_CURRENT,
|
||||||
)
|
)
|
||||||
val markAsReadAction = NotificationCompat.Action.Builder(
|
val markAsReadAction = NotificationCompat.Action.Builder(
|
||||||
// TODO: Wrong icon
|
R.drawable.mark_as_read,
|
||||||
R.drawable.ic_service_icon,
|
|
||||||
NotificationDataManager.markAsRead,
|
NotificationDataManager.markAsRead,
|
||||||
markAsReadPendingIntent,
|
markAsReadPendingIntent,
|
||||||
).build()
|
).build()
|
||||||
@ -141,8 +141,11 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
|
|||||||
// Assemble the notification
|
// Assemble the notification
|
||||||
val finalNotification = NotificationCompat.Builder(context, notification.channelId).apply {
|
val finalNotification = NotificationCompat.Builder(context, notification.channelId).apply {
|
||||||
setStyle(style)
|
setStyle(style)
|
||||||
// TODO: I think this is wrong
|
// NOTE: It's okay to use the service icon here as I cannot get Android to display the
|
||||||
|
// actual logo. So we'll have to make do with the silhouette and the color purple.
|
||||||
setSmallIcon(R.drawable.ic_service_icon)
|
setSmallIcon(R.drawable.ic_service_icon)
|
||||||
|
color = Color.argb(255, 207, 74, 255)
|
||||||
|
setColorized(true)
|
||||||
|
|
||||||
// Tap action
|
// Tap action
|
||||||
setContentIntent(tapPendingIntent)
|
setContentIntent(tapPendingIntent)
|
||||||
@ -151,6 +154,9 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
|
|||||||
addAction(replyAction)
|
addAction(replyAction)
|
||||||
addAction(markAsReadAction)
|
addAction(markAsReadAction)
|
||||||
|
|
||||||
|
setAllowSystemGeneratedContextualActions(true)
|
||||||
|
setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
|
|
||||||
// Prevent no notification when we replied before
|
// Prevent no notification when we replied before
|
||||||
setOnlyAlertOnce(false)
|
setOnlyAlertOnce(false)
|
||||||
}.build()
|
}.build()
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M17.34,20l-3.54,-3.54l1.41,-1.41l2.12,2.12l4.24,-4.24L23,14.34L17.34,20zM12,17c0,-3.87 3.13,-7 7,-7c1.08,0 2.09,0.25 3,0.68V4c0,-1.1 -0.9,-2 -2,-2H4C2.9,2 2,2.9 2,4v18l4,-4h6v0c0,-0.17 0.01,-0.33 0.03,-0.5C12.01,17.34 12,17.17 12,17z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
|
android:tint="#FFFFFF" android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z"/>
|
||||||
|
</vector>
|
@ -13,9 +13,8 @@ class AndroidNotificationsImplementation extends NotificationsImplementation {
|
|||||||
String title,
|
String title,
|
||||||
String id,
|
String id,
|
||||||
bool urgent,
|
bool urgent,
|
||||||
NotificationI18nData i18n,
|
|
||||||
) async {
|
) async {
|
||||||
return _api.createNotificationChannel(title, id, urgent, i18n);
|
return _api.createNotificationChannel(title, id, urgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -30,6 +29,11 @@ class AndroidNotificationsImplementation extends NotificationsImplementation {
|
|||||||
return _api.setNotificationSelfAvatar(path);
|
return _api.setNotificationSelfAvatar(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setI18n(NotificationI18nData data) {
|
||||||
|
return _api.setNotificationI18n(data);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<NotificationEvent> getEventStream() => _channel
|
Stream<NotificationEvent> getEventStream() => _channel
|
||||||
.receiveBroadcastStream()
|
.receiveBroadcastStream()
|
||||||
|
@ -262,12 +262,12 @@ class MoxplatformApi {
|
|||||||
|
|
||||||
static const MessageCodec<Object?> codec = _MoxplatformApiCodec();
|
static const MessageCodec<Object?> codec = _MoxplatformApiCodec();
|
||||||
|
|
||||||
Future<void> createNotificationChannel(String arg_title, String arg_id, bool arg_urgent, NotificationI18nData arg_i18n) async {
|
Future<void> createNotificationChannel(String arg_title, String arg_id, bool arg_urgent) async {
|
||||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannel', codec,
|
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.createNotificationChannel', codec,
|
||||||
binaryMessenger: _binaryMessenger);
|
binaryMessenger: _binaryMessenger);
|
||||||
final List<Object?>? replyList =
|
final List<Object?>? replyList =
|
||||||
await channel.send(<Object?>[arg_title, arg_id, arg_urgent, arg_i18n]) as List<Object?>?;
|
await channel.send(<Object?>[arg_title, arg_id, arg_urgent]) as List<Object?>?;
|
||||||
if (replyList == null) {
|
if (replyList == null) {
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'channel-error',
|
code: 'channel-error',
|
||||||
@ -328,6 +328,28 @@ class MoxplatformApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> setNotificationI18n(NotificationI18nData arg_data) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.setNotificationI18n', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_data]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> getPersistentDataPath() async {
|
Future<String> getPersistentDataPath() async {
|
||||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.getPersistentDataPath', codec,
|
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.getPersistentDataPath', codec,
|
||||||
|
@ -2,11 +2,18 @@ import 'dart:async';
|
|||||||
import 'package:moxplatform_platform_interface/src/api.g.dart';
|
import 'package:moxplatform_platform_interface/src/api.g.dart';
|
||||||
|
|
||||||
abstract class NotificationsImplementation {
|
abstract class NotificationsImplementation {
|
||||||
Future<void> createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n);
|
/// Creates a notification channel with the name [title] and id [id]. If [urgent] is true, then
|
||||||
|
/// it configures the channel as carrying urgent information.
|
||||||
|
Future<void> createNotificationChannel(String title, String id, bool urgent);
|
||||||
|
|
||||||
|
/// Shows a notification [notification] in the messaging style with everyting it needs.
|
||||||
Future<void> showMessagingNotification(MessagingNotification notification);
|
Future<void> showMessagingNotification(MessagingNotification notification);
|
||||||
|
|
||||||
|
/// Sets the path to the self-avatar for in-notification replies.
|
||||||
Future<void> setNotificationSelfAvatar(String path);
|
Future<void> setNotificationSelfAvatar(String path);
|
||||||
|
|
||||||
|
/// Configures the i18n data for usage in notifications.
|
||||||
|
Future<void> setI18n(NotificationI18nData data);
|
||||||
|
|
||||||
Stream<NotificationEvent> getEventStream();
|
Stream<NotificationEvent> getEventStream();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import 'package:moxplatform_platform_interface/src/notifications.dart';
|
|||||||
|
|
||||||
class StubNotificationsImplementation extends NotificationsImplementation {
|
class StubNotificationsImplementation extends NotificationsImplementation {
|
||||||
@override
|
@override
|
||||||
Future<void> createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n) async {}
|
Future<void> createNotificationChannel(String title, String id, bool urgent) async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> showMessagingNotification(MessagingNotification notification) async {}
|
Future<void> showMessagingNotification(MessagingNotification notification) async {}
|
||||||
@ -12,6 +12,9 @@ class StubNotificationsImplementation extends NotificationsImplementation {
|
|||||||
@override
|
@override
|
||||||
Future<void> setNotificationSelfAvatar(String path) async {}
|
Future<void> setNotificationSelfAvatar(String path) async {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setI18n(NotificationI18nData data) async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<NotificationEvent> getEventStream() {
|
Stream<NotificationEvent> getEventStream() {
|
||||||
return StreamController<NotificationEvent>().stream;
|
return StreamController<NotificationEvent>().stream;
|
||||||
|
@ -112,15 +112,11 @@ class NotificationI18nData {
|
|||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class MoxplatformApi {
|
abstract class MoxplatformApi {
|
||||||
void createNotificationChannel(String title, String id, bool urgent, NotificationI18nData i18n);
|
void createNotificationChannel(String title, String id, bool urgent);
|
||||||
|
|
||||||
void showMessagingNotification(MessagingNotification notification);
|
void showMessagingNotification(MessagingNotification notification);
|
||||||
|
|
||||||
void setNotificationSelfAvatar(String path);
|
void setNotificationSelfAvatar(String path);
|
||||||
|
void setNotificationI18n(NotificationI18nData data);
|
||||||
String getPersistentDataPath();
|
String getPersistentDataPath();
|
||||||
|
|
||||||
String getCacheDataPath();
|
String getCacheDataPath();
|
||||||
|
|
||||||
void eventStub(NotificationEvent event);
|
void eventStub(NotificationEvent event);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user