Commit cfdf6017 authored by Carey Metcalfe's avatar Carey Metcalfe

Add delete button to notifications

This commit adds a delete buttons to new message notifications. The
option is available in both single and multi-recipient notifications.

It also changes the size of the button icons (for Android versions that
support them) to a more standard size (24dp).
parent 7f91d89f
......@@ -331,6 +331,14 @@
</intent-filter>
</receiver>
<receiver android:name=".notifications.DeleteMessageReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="org.smssecure.smssecure.notifications.DELETE_MSGS"/>
</intent-filter>
</receiver>
<receiver android:name=".notifications.RemoteReplyReceiver"
android:enabled="true"
android:exported="false">
......
......@@ -426,6 +426,7 @@
<string name="MessageNotifier_failed_to_deliver_message">Failed to deliver message.</string>
<string name="MessageNotifier_error_delivering_message">Error delivering message.</string>
<string name="MessageNotifier_mark_all_as_read">Mark all as read</string>
<string name="MessageNotifier_delete_all">Delete all</string>
<string name="MessageNotifier_mark_read">Mark read</string>
<string name="MessageNotifier_media_message">Media message</string>
<string name="MessageNotifier_message_received">Message received by %s.</string>
......
package org.smssecure.smssecure.notifications;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import org.smssecure.smssecure.crypto.MasterSecret;
import org.smssecure.smssecure.database.DatabaseFactory;
public class DeleteMessageReceiver extends MasterSecretBroadcastReceiver {
private static final String TAG = DeleteMessageReceiver.class.getSimpleName();
public static final String DELETE_ACTION = "org.smssecure.smssecure.notifications.DELETE_MSGS";
public static final String MSG_IDS_EXTRA = "msg_ids";
public static final String MSG_IS_MMS_EXTRA = "msg_is_mms";
public static final String THREAD_IDS_EXTRA = "thread_ids";
public static final String NOTIFICATION_ID_EXTRA = "notification_id";
@Override
protected void onReceive(final Context context, Intent intent,
@Nullable final MasterSecret masterSecret)
{
if (!DELETE_ACTION.equals(intent.getAction()))
return;
final long[] messageIds = intent.getLongArrayExtra(MSG_IDS_EXTRA);
final boolean[] messageIsMms = intent.getBooleanArrayExtra(MSG_IS_MMS_EXTRA);
final long[] threadIds = intent.getLongArrayExtra(THREAD_IDS_EXTRA);
if (messageIds == null || messageIsMms == null || threadIds == null ||
messageIds.length != messageIsMms.length){
Log.e(TAG, "Bad extras received");
return;
}
NotificationManagerCompat.from(context).cancel(intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1));
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < messageIds.length; i++) {
if (messageIsMms[i]) {
DatabaseFactory.getMmsDatabase(context).delete(messageIds[i]);
} else {
DatabaseFactory.getSmsDatabase(context).deleteMessage(messageIds[i]);
}
}
for (long threadId : threadIds) {
DatabaseFactory.getThreadDatabase(context).setRead(threadId);
}
MessageNotifier.updateNotification(context, masterSecret);
return null;
}
}.execute();
}
}
......@@ -295,7 +295,8 @@ public class MessageNotifier {
builder.addActions(masterSecret,
notificationState.getMarkAsReadIntent(context, notificationId),
notificationState.getQuickReplyIntent(context, notifications.get(0).getRecipients()),
notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients()));
notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients()),
notificationState.getDeleteMessageIntent(context, notificationId));
ListIterator<NotificationItem> iterator = notifications.listIterator(notifications.size());
......@@ -333,7 +334,8 @@ public class MessageNotifier {
long timestamp = notifications.get(0).getTimestamp();
if (timestamp != 0) builder.setWhen(timestamp);
builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID));
builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID),
notificationState.getDeleteMessageIntent(context, SUMMARY_NOTIFICATION_ID));
ListIterator<NotificationItem> iterator = notifications.listIterator(0);
......
......@@ -47,12 +47,17 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu
}
}
public void addActions(PendingIntent markAsReadIntent) {
NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.check,
public void addActions(PendingIntent markAsReadIntent, PendingIntent deleteAllIntent) {
NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.ic_check_white_24dp,
context.getString(R.string.MessageNotifier_mark_all_as_read),
markAsReadIntent);
NotificationCompat.Action deleteAllAction = new NotificationCompat.Action(R.drawable.ic_delete_white_24dp,
context.getString(R.string.MessageNotifier_delete_all),
deleteAllIntent);
addAction(markAllAsReadAction);
extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction));
addAction(deleteAllAction);
extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction)
.addAction(deleteAllAction));
}
public void addMessageBody(@NonNull Recipient sender, @Nullable CharSequence body) {
......
......@@ -102,7 +102,6 @@ public class NotificationState {
int index = 0;
for (long thread : threads) {
Log.w("NotificationState", "Added thread: " + thread);
threadArray[index++] = thread;
}
......@@ -115,6 +114,33 @@ public class NotificationState {
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public PendingIntent getDeleteMessageIntent(Context context, int notificationId){
long[] idArray = new long[notificationCount];
boolean[] isMmsArray = new boolean[notificationCount];
long[] threadArray = new long[threads.size()];
int index = 0;
for (NotificationItem notificationItem : notifications) {
isMmsArray[index] = notificationItem.isMms();
idArray[index++] = notificationItem.getId();
}
index = 0;
for (long thread : threads) {
threadArray[index++] = thread;
}
Intent intent = new Intent(DeleteMessageReceiver.DELETE_ACTION);
intent.setClass(context, DeleteMessageReceiver.class);
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
intent.putExtra(DeleteMessageReceiver.MSG_IDS_EXTRA, idArray);
intent.putExtra(DeleteMessageReceiver.MSG_IS_MMS_EXTRA, isMmsArray);
intent.putExtra(DeleteMessageReceiver.THREAD_IDS_EXTRA, threadArray);
intent.putExtra(DeleteMessageReceiver.NOTIFICATION_ID_EXTRA, notificationId);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public PendingIntent getRemoteReplyIntent(Context context, Recipients recipients) {
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!");
......@@ -130,7 +156,7 @@ public class NotificationState {
public PendingIntent getQuickReplyIntent(Context context, Recipients recipients) {
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications! " + threads.size());
Intent intent = new Intent(context, ConversationPopupActivity.class);
Intent intent = new Intent(context, ConversationPopupActivity.class);
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, (long)threads.toArray()[0]);
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
......
......@@ -102,19 +102,23 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
public void addActions(@Nullable MasterSecret masterSecret,
@NonNull PendingIntent markReadIntent,
@NonNull PendingIntent quickReplyIntent,
@NonNull PendingIntent wearableReplyIntent)
@NonNull PendingIntent wearableReplyIntent,
@NonNull PendingIntent deleteIntent)
{
Action markAsReadAction = new Action(R.drawable.check,
Action markAsReadAction = new Action(R.drawable.ic_check_white_24dp,
context.getString(R.string.MessageNotifier_mark_read),
markReadIntent);
Action deleteAction = new Action(R.drawable.ic_delete_white_24dp,
context.getString(R.string.delete),
deleteIntent);
if (masterSecret != null) {
Action replyAction = new Action(R.drawable.ic_reply_white_36dp,
Action replyAction = new Action(R.drawable.ic_reply_white_24dp,
context.getString(R.string.MessageNotifier_reply),
quickReplyIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
replyAction = new Action.Builder(R.drawable.ic_reply_white_36dp,
replyAction = new Action.Builder(R.drawable.ic_reply_white_24dp,
context.getString(R.string.MessageNotifier_reply),
wearableReplyIntent)
.addRemoteInput(new RemoteInput.Builder(MessageNotifier.EXTRA_REMOTE_REPLY)
......@@ -131,13 +135,17 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
addAction(markAsReadAction);
addAction(replyAction);
addAction(deleteAction);
extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction)
.addAction(wearableReplyAction));
.addAction(wearableReplyAction)
.addAction(deleteAction));
} else {
addAction(markAsReadAction);
addAction(deleteAction);
extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction));
extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction)
.addAction(deleteAction));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment