Group push notifications

Clear notifications when opening MainActivity
Use lowest privacy setting when replying
This commit is contained in:
Eugen Rochko 2017-03-14 14:31:52 +01:00
parent 4db1d54d79
commit 2e50c547ce
4 changed files with 139 additions and 58 deletions

View File

@ -399,11 +399,18 @@ public class ComposeActivity extends BaseActivity {
if (intent != null) { if (intent != null) {
inReplyToId = intent.getStringExtra("in_reply_to_id"); inReplyToId = intent.getStringExtra("in_reply_to_id");
String replyVisibility = intent.getStringExtra("reply_visibility"); String replyVisibility = intent.getStringExtra("reply_visibility");
if (replyVisibility != null) { if (replyVisibility != null) {
/* Override any remembered visibilty and instead adopt the visibility of the status // Lowest possible visibility setting in response
* to which this replies. */ if (statusVisibility.equals("private") || replyVisibility.equals("private")) {
statusVisibility = "private";
} else if (statusVisibility.equals("unlisted") || replyVisibility.equals("unlisted")) {
statusVisibility = "unlisted";
} else {
statusVisibility = replyVisibility; statusVisibility = replyVisibility;
} }
}
mentionedUsernames = intent.getStringArrayExtra("mentioned_usernames"); mentionedUsernames = intent.getStringArrayExtra("mentioned_usernames");
} }

View File

@ -15,6 +15,7 @@
package com.keylesspalace.tusky; package com.keylesspalace.tusky;
import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -22,12 +23,12 @@ import android.graphics.PorterDuff;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
@ -187,6 +188,18 @@ public class MainActivity extends BaseActivity {
}); });
} }
@Override
protected void onResume() {
super.onResume();
SharedPreferences notificationPreferences = getApplicationContext().getSharedPreferences("Notifications", MODE_PRIVATE);
SharedPreferences.Editor editor = notificationPreferences.edit();
editor.putString("current", "[]");
editor.apply();
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).cancel(MyFirebaseMessagingService.NOTIFY_ID);
}
@Override @Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
ArrayList<Integer> pageHistoryList = new ArrayList<>(); ArrayList<Integer> pageHistoryList = new ArrayList<>();

View File

@ -22,6 +22,9 @@ import com.keylesspalace.tusky.entity.Notification;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target; import com.squareup.picasso.Target;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.IOException; import java.io.IOException;
import okhttp3.Interceptor; import okhttp3.Interceptor;
@ -36,6 +39,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class MyFirebaseMessagingService extends FirebaseMessagingService { public class MyFirebaseMessagingService extends FirebaseMessagingService {
private MastodonAPI mastodonAPI; private MastodonAPI mastodonAPI;
private static final String TAG = "MyFirebaseMessagingService"; private static final String TAG = "MyFirebaseMessagingService";
public static final int NOTIFY_ID = 666;
@Override @Override
public void onMessageReceived(RemoteMessage remoteMessage) { public void onMessageReceived(RemoteMessage remoteMessage) {
@ -112,6 +116,34 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
private void buildNotification(Notification body) { private void buildNotification(Notification body) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences notificationPreferences = getApplicationContext().getSharedPreferences("Notifications", MODE_PRIVATE);
String rawCurrentNotifications = notificationPreferences.getString("current", "[]");
JSONArray currentNotifications;
try {
currentNotifications = new JSONArray(rawCurrentNotifications);
} catch (JSONException e) {
currentNotifications = new JSONArray();
}
boolean alreadyContains = false;
for(int i = 0; i < currentNotifications.length(); i++) {
try {
if (currentNotifications.getString(i).equals(body.account.displayName)) {
alreadyContains = true;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
if (!alreadyContains) currentNotifications.put(body.account.displayName);
SharedPreferences.Editor editor = notificationPreferences.edit();
editor.putString("current", currentNotifications.toString());
editor.commit();
Intent resultIntent = new Intent(this, MainActivity.class); Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("tab_position", 1); resultIntent.putExtra("tab_position", 1);
@ -122,11 +154,12 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this) final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notify) .setSmallIcon(R.drawable.ic_notify)
.setAutoCancel(true)
.setContentIntent(resultPendingIntent) .setContentIntent(resultPendingIntent)
.setDefaults(0); // So it doesn't ring twice, notify only in Target callback .setDefaults(0); // So it doesn't ring twice, notify only in Target callback
final Integer mId = (int)(System.currentTimeMillis() / 1000); if (currentNotifications.length() == 1) {
builder.setContentTitle(titleForType(body))
.setContentText(truncateWithEllipses(bodyForType(body), 40));
Target mTarget = new Target() { Target mTarget = new Target() {
@Override @Override
@ -145,7 +178,7 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
builder.setLights(0xFF00FF8F, 300, 1000); builder.setLights(0xFF00FF8F, 300, 1000);
} }
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).notify(mId, builder.build()); ((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).notify(NOTIFY_ID, builder.build());
} }
@Override @Override
@ -164,31 +197,60 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
.placeholder(R.drawable.avatar_default) .placeholder(R.drawable.avatar_default)
.transform(new RoundedTransformation(7, 0)) .transform(new RoundedTransformation(7, 0))
.into(mTarget); .into(mTarget);
} else {
try {
builder.setContentTitle(String.format(getString(R.string.notification_title_summary), currentNotifications.length()))
.setContentText(truncateWithEllipses(joinNames(currentNotifications), 40));
} catch (JSONException e) {
e.printStackTrace();
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setVisibility(android.app.Notification.VISIBILITY_PRIVATE); builder.setVisibility(android.app.Notification.VISIBILITY_PRIVATE);
builder.setCategory(android.app.Notification.CATEGORY_SOCIAL); builder.setCategory(android.app.Notification.CATEGORY_SOCIAL);
} }
switch (body.type) { ((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).notify(NOTIFY_ID, builder.build());
case MENTION:
builder.setContentTitle(String.format(getString(R.string.notification_mention_format), body.account.getDisplayName()))
.setContentText(truncateWithEllipses(body.status.content.toString(), 40));
break;
case FOLLOW:
builder.setContentTitle(String.format(getString(R.string.notification_follow_format), body.account.getDisplayName()))
.setContentText(truncateWithEllipses(body.account.username, 40));
break;
case FAVOURITE:
builder.setContentTitle(String.format(getString(R.string.notification_favourite_format), body.account.getDisplayName()))
.setContentText(truncateWithEllipses(body.status.content.toString(), 40));
break;
case REBLOG:
builder.setContentTitle(String.format(getString(R.string.notification_reblog_format), body.account.getDisplayName()))
.setContentText(truncateWithEllipses(body.status.content.toString(), 40));
break;
} }
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).notify(mId, builder.build()); private String joinNames(JSONArray array) throws JSONException {
if (array.length() > 3) {
return String.format(getString(R.string.notification_summary_large), array.get(0), array.get(1), array.get(2), array.length() - 3);
} else if (array.length() == 3) {
return String.format(getString(R.string.notification_summary_medium), array.get(0), array.get(1), array.get(2));
} else if (array.length() == 2) {
return String.format(getString(R.string.notification_summary_small), array.get(0), array.get(1));
}
return null;
}
private String titleForType(Notification notification) {
switch (notification.type) {
case MENTION:
return String.format(getString(R.string.notification_mention_format), notification.account.getDisplayName());
case FOLLOW:
return String.format(getString(R.string.notification_follow_format), notification.account.getDisplayName());
case FAVOURITE:
return String.format(getString(R.string.notification_favourite_format), notification.account.getDisplayName());
case REBLOG:
return String.format(getString(R.string.notification_reblog_format), notification.account.getDisplayName());
}
return null;
}
private String bodyForType(Notification notification) {
switch (notification.type) {
case FOLLOW:
return notification.account.username;
case MENTION:
case FAVOURITE:
case REBLOG:
return notification.status.content.toString();
}
return null;
} }
} }

View File

@ -102,12 +102,8 @@
<string name="visibility_unlisted">Everyone can see, but not on public timelines</string> <string name="visibility_unlisted">Everyone can see, but not on public timelines</string>
<string name="visibility_private">Only followers and mentions can see</string> <string name="visibility_private">Only followers and mentions can see</string>
<string name="notification_service_description">Allows Tusky to check for Mastodon notifications.</string>
<string name="notification_service_several_mentions">%d new mentions</string>
<string name="notification_service_one_mention">Mention from %s</string>
<string name="pref_title_notification_settings">Notifications</string> <string name="pref_title_notification_settings">Notifications</string>
<string name="pref_title_pull_notifications">Enable pull notifcations</string> <string name="pref_title_pull_notifications">Enable pull notifications</string>
<string name="pref_summary_pull_notifications">Check for notifications periodically</string> <string name="pref_summary_pull_notifications">Check for notifications periodically</string>
<string name="pref_title_pull_notification_check_interval">Check interval</string> <string name="pref_title_pull_notification_check_interval">Check interval</string>
<string name="pref_summary_pull_notification_check_interval">How often to pull</string> <string name="pref_summary_pull_notification_check_interval">How often to pull</string>
@ -133,5 +129,8 @@
<string name="notification_mention_format">%s mentioned you</string> <string name="notification_mention_format">%s mentioned you</string>
<string name="error_invalid_domain">Invalid domain entered</string> <string name="error_invalid_domain">Invalid domain entered</string>
<string name="error_failed_app_registration">This app could not obtain authentication from that server instance.</string> <string name="error_failed_app_registration">This app could not obtain authentication from that server instance.</string>
<string name="notification_summary_large">%1$s, %2$s, %3$s and %4$d others</string>
<string name="notification_summary_medium">%1$s, %2$s, and %3$s</string>
<string name="notification_summary_small">%1$s and %2$s</string>
<string name="notification_title_summary">%d new interactions</string>
</resources> </resources>