From 50601853f589afeab69e341248f464bb191aaaef Mon Sep 17 00:00:00 2001 From: FineFindus <63370021+FineFindus@users.noreply.github.com> Date: Fri, 3 Mar 2023 23:45:07 +0100 Subject: [PATCH] feat(notifications/actions): add reply action Closes https://github.com/LucasGGamerM/moshidon/issues/104 --- .../android/PushNotificationReceiver.java | 67 ++++++++++++++++++- .../android/model/NotificationAction.java | 1 + mastodon/src/main/res/values/strings_sk.xml | 2 + 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java index b876027b3..5752f13c4 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java +++ b/mastodon/src/main/java/org/joinmastodon/android/PushNotificationReceiver.java @@ -5,17 +5,22 @@ import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.RemoteInput; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.RequiresApi; + import org.joinmastodon.android.api.MastodonAPIController; import org.joinmastodon.android.api.requests.notifications.GetNotificationByID; +import org.joinmastodon.android.api.requests.statuses.CreateStatus; import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked; import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited; import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged; @@ -32,6 +37,7 @@ import org.parceler.Parcels; import java.util.Arrays; import java.util.List; import java.util.Random; +import java.util.UUID; import java.util.stream.Collectors; import me.grishka.appkit.api.Callback; @@ -44,6 +50,8 @@ public class PushNotificationReceiver extends BroadcastReceiver{ private static final String TAG="PushNotificationReceive"; public static final int NOTIFICATION_ID=178; + private static final String ACTION_KEY_TEXT_REPLY = "ACTION_KEY_TEXT_REPLY"; + private static final int SUMMARY_ID = 791; private static int notificationId = 0; @@ -122,6 +130,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{ case BOOKMARK -> new SetStatusBookmarked(statusID, true).exec(accountID); case BOOST -> new SetStatusReblogged(notification.status.id, true, preferences.postingDefaultVisibility).exec(accountID); case UNBOOST -> new SetStatusReblogged(notification.status.id, false, preferences.postingDefaultVisibility).exec(accountID); + case REPLY -> handleReplyAction(context, accountID, intent, notification, notificationId, preferences); default -> Log.w(TAG, "onReceive: Failed to get NotificationAction"); } } @@ -208,10 +217,14 @@ public class PushNotificationReceiver extends BroadcastReceiver{ if (notification != null){ switch (pn.notificationType){ case MENTION, STATUS -> { + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){ + builder.addAction(buildReplyAction(context, id, accountID, notification)); + } builder.addAction(buildNotificationAction(context, id, accountID, notification, context.getString(R.string.sk_notification_action_favorite), NotificationAction.FAVORITE)); builder.addAction(buildNotificationAction(context, id, accountID, notification, context.getString(R.string.sk_notification_action_bookmark), NotificationAction.BOOKMARK)); - if(notification.status.visibility != StatusPrivacy.DIRECT) + if(notification.status.visibility != StatusPrivacy.DIRECT) { builder.addAction(buildNotificationAction(context, id, accountID, notification, context.getString(R.string.sk_notification_action_boost), NotificationAction.BOOST)); + } } case UPDATE -> { if(notification.status.reblogged) @@ -234,4 +247,56 @@ public class PushNotificationReceiver extends BroadcastReceiver{ return new Notification.Action.Builder(null, title, actionPendingIntent).build(); } + + private Notification.Action buildReplyAction(Context context, int notificationId, String accountID, org.joinmastodon.android.model.Notification notification){ + String replyLabel = context.getResources().getString(R.string.sk_notification_action_reply); + RemoteInput remoteInput = new RemoteInput.Builder(ACTION_KEY_TEXT_REPLY) + .setLabel(replyLabel) + .build(); + + Intent notificationIntent=new Intent(context, PushNotificationReceiver.class); + notificationIntent.putExtra("notificationId", notificationId); + notificationIntent.putExtra("fromNotificationAction", true); + notificationIntent.putExtra("accountID", accountID); + notificationIntent.putExtra("notificationAction", NotificationAction.REPLY.ordinal()); + notificationIntent.putExtra("notification", Parcels.wrap(notification)); + + int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT : PendingIntent.FLAG_UPDATE_CURRENT; + PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context, new Random().nextInt(), notificationIntent,flags); + return new Notification.Action.Builder(null, replyLabel, replyPendingIntent).addRemoteInput(remoteInput).build(); + } + + private void handleReplyAction(Context context, String accountID, Intent intent, org.joinmastodon.android.model.Notification notification, int notificationId, Preferences preferences) { + Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); + if (remoteInput == null) { + Log.e(TAG, "handleReplyAction: Could not get reply input"); + return; + } + CharSequence input = remoteInput.getCharSequence(ACTION_KEY_TEXT_REPLY); + + CreateStatus.Request req=new CreateStatus.Request(); + req.status = input.toString(); + req.language = preferences.postingDefaultLanguage; + req.visibility = preferences.postingDefaultVisibility; + req.inReplyToId = notification.status.id; + if(!notification.status.spoilerText.isEmpty() && GlobalUserPreferences.prefixRepliesWithRe && !notification.status.spoilerText.startsWith("re: ")){ + req.spoilerText = "re: " + notification.status.spoilerText; + } + +// new CreateStatus(req, UUID.randomUUID().toString()).exec(accountID); + + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + Notification.Builder builder = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ? + new Notification.Builder(context, accountID+"_"+notification.type) : + new Notification.Builder(context) + .setPriority(Notification.PRIORITY_DEFAULT) + .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE); + + Notification repliedNotification = builder.setSmallIcon(R.drawable.ic_ntf_logo) + .setContentText(context.getString(R.string.sk_notification_action_replied, notification.status.account.getDisplayUsername())) + .build(); +// notificationManager.cancel(accountID, notificationId); +// notificationManager.notify(notificationId, repliedNotification); + notificationManager.notify(accountID, notificationId, repliedNotification); + } } \ No newline at end of file diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/NotificationAction.java b/mastodon/src/main/java/org/joinmastodon/android/model/NotificationAction.java index 6fc1259a0..420bb1d1a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/NotificationAction.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/NotificationAction.java @@ -5,4 +5,5 @@ public enum NotificationAction { BOOST, UNBOOST, BOOKMARK, + REPLY, } diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 4c35e8e40..863e5bb0d 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -266,4 +266,6 @@ Bookmark Boost Unboost + Reply + Successfully replied to the post by %s \ No newline at end of file