From b6e48e3763d2006e890e8207b51a2e0312be4ee2 Mon Sep 17 00:00:00 2001 From: Djorkaeff Alexandre Date: Fri, 31 Jan 2020 10:56:48 -0300 Subject: [PATCH] [IMPROVEMENT] Use MessagingStyle on Android Notification (#1575) --- .../reactnative/CustomPushNotification.java | 121 +++++++++++++----- .../java/chat/rocket/reactnative/Ejson.java | 5 +- 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java b/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java index c888391b5..a27a20028 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java +++ b/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java @@ -10,8 +10,10 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.drawable.Icon; import android.os.Build; import android.os.Bundle; +import android.app.Person; import com.google.gson.*; import com.bumptech.glide.Glide; @@ -30,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ArrayList; +import java.util.Date; import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME; @@ -41,7 +44,7 @@ public class CustomPushNotification extends PushNotification { reactApplicationContext = new ReactApplicationContext(context); } - private static Map> notificationMessages = new HashMap>(); + private static Map> notificationMessages = new HashMap>(); public static String KEY_REPLY = "KEY_REPLY"; public static String NOTIFICATION_ID = "NOTIFICATION_ID"; @@ -53,15 +56,26 @@ public class CustomPushNotification extends PushNotification { public void onReceived() throws InvalidNotificationException { final Bundle bundle = mNotificationProps.asBundle(); - String notId = bundle.getString("notId"); - String message = bundle.getString("message"); + String notId = bundle.getString("notId", "1"); + String title = bundle.getString("title"); if (notificationMessages.get(notId) == null) { - notificationMessages.put(notId, new ArrayList()); + notificationMessages.put(notId, new ArrayList()); } - notificationMessages.get(notId).add(message); - super.postNotification(notId != null ? Integer.parseInt(notId) : 1); + Gson gson = new Gson(); + Ejson ejson = gson.fromJson(bundle.getString("ejson", "{}"), Ejson.class); + + boolean hasSender = ejson.sender != null; + + bundle.putLong("time", new Date().getTime()); + bundle.putString("username", hasSender ? ejson.sender.username : title); + bundle.putString("senderId", hasSender ? ejson.sender._id : "1"); + bundle.putString("avatarUri", ejson.getAvatarUri()); + + notificationMessages.get(notId).add(bundle); + + super.postNotification(Integer.parseInt(notId)); notifyReceivedToJS(); } @@ -69,7 +83,7 @@ public class CustomPushNotification extends PushNotification { @Override public void onOpened() { Bundle bundle = mNotificationProps.asBundle(); - final String notId = bundle.getString("notId"); + final String notId = bundle.getString("notId", "1"); notificationMessages.remove(notId); digestNotification(); } @@ -79,19 +93,16 @@ public class CustomPushNotification extends PushNotification { final Notification.Builder notification = new Notification.Builder(mContext); Bundle bundle = mNotificationProps.asBundle(); - String title = bundle.getString("title"); - String message = bundle.getString("message"); - String notId = bundle.getString("notId"); + String notId = bundle.getString("notId", "1"); notification .setContentIntent(intent) - .setContentTitle(title) - .setContentText(message) .setPriority(Notification.PRIORITY_HIGH) .setDefaults(Notification.DEFAULT_ALL) .setAutoCancel(true); - Integer notificationId = notId != null ? Integer.parseInt(notId) : 1; + Integer notificationId = Integer.parseInt(notId); + notificationColor(notification); notificationChannel(notification); notificationIcons(notification, bundle); notificationStyle(notification, notificationId, bundle); @@ -114,22 +125,26 @@ public class CustomPushNotification extends PushNotification { .submit(100, 100) .get(); } catch (final ExecutionException | InterruptedException e) { - return null; + return largeIcon(); } } + private Bitmap largeIcon() { + final Resources res = mContext.getResources(); + String packageName = mContext.getPackageName(); + int largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); + Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId); + return largeIconBitmap; + } + private void notificationIcons(Notification.Builder notification, Bundle bundle) { final Resources res = mContext.getResources(); String packageName = mContext.getPackageName(); int smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName); - Gson gson = new Gson(); - Ejson ejson = gson.fromJson(bundle.getString("ejson", "{}"), Ejson.class); - notification - .setSmallIcon(smallIconResId) - .setLargeIcon(getAvatar(ejson.getAvatarUri())); + .setSmallIcon(smallIconResId); } private void notificationChannel(Notification.Builder notification) { @@ -148,21 +163,69 @@ public class CustomPushNotification extends PushNotification { } } - private void notificationStyle(Notification.Builder notification, int notId, Bundle bundle) { - Notification.InboxStyle messageStyle = new Notification.InboxStyle(); - List messages = notificationMessages.get(Integer.toString(notId)); - if (messages != null) { - for (int i = 0; i < messages.size(); i++) { - messageStyle.addLine(messages.get(i)); - } - String summary = bundle.getString("summaryText"); - messageStyle.setSummaryText(summary.replace("%n%", Integer.toString(messages.size()))); - notification.setNumber(messages.size()); + private String extractMessage(String message, Ejson ejson) { + if (ejson.type != null && !ejson.type.equals("d")) { + int pos = message.indexOf(":"); + int start = pos == -1 ? 0 : pos + 2; + return message.substring(start, message.length()); } + return message; + } + private void notificationColor(Notification.Builder notification) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { notification.setColor(mContext.getColor(R.color.notification_text)); } + } + + private void notificationStyle(Notification.Builder notification, int notId, Bundle bundle) { + Notification.MessagingStyle messageStyle; + String title = bundle.getString("title"); + + Gson gson = new Gson(); + Ejson ejson = gson.fromJson(bundle.getString("ejson", "{}"), Ejson.class); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + messageStyle = new Notification.MessagingStyle(""); + } else { + Person sender = new Person.Builder() + .setKey("") + .setName("") + .build(); + messageStyle = new Notification.MessagingStyle(sender); + } + + messageStyle.setConversationTitle(title); + if (ejson.type != null && !ejson.type.equals("d")) { + messageStyle.setGroupConversation(true); + } + + List bundles = notificationMessages.get(Integer.toString(notId)); + + if (bundles != null) { + for (int i = 0; i < bundles.size(); i++) { + Bundle data = bundles.get(i); + + long timestamp = data.getLong("time"); + String message = data.getString("message"); + String username = data.getString("username"); + String senderId = data.getString("senderId"); + String avatarUri = data.getString("avatarUri"); + + String m = extractMessage(message, ejson); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + messageStyle.addMessage(m, timestamp, username); + } else { + Person sender = new Person.Builder() + .setKey(senderId) + .setName(username) + .setIcon(Icon.createWithBitmap(getAvatar(avatarUri))) + .build(); + messageStyle.addMessage(m, timestamp, sender); + } + } + } notification.setStyle(messageStyle); } diff --git a/android/app/src/main/java/chat/rocket/reactnative/Ejson.java b/android/app/src/main/java/chat/rocket/reactnative/Ejson.java index 591fda93a..cd18a292a 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/Ejson.java +++ b/android/app/src/main/java/chat/rocket/reactnative/Ejson.java @@ -14,7 +14,7 @@ public class Ejson { private SharedPreferences sharedPreferences = RNUserDefaultsModule.getPreferences(CustomPushNotification.reactApplicationContext); public String getAvatarUri() { - if (type == null || !type.equals("d")) { + if (type == null) { return null; } return serverURL() + "/avatar/" + this.sender.username + "?rc_token=" + token() + "&rc_uid=" + userId(); @@ -36,7 +36,8 @@ public class Ejson { return url; } - private class Sender { + public class Sender { String username; + String _id; } } \ No newline at end of file