Commit 901b6289 authored by Yusuke Iwaki's avatar Yusuke Iwaki

modify notification to show user avatar.

parent 54da7fb2
package chat.rocket.android.helper;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;
import bolts.Task;
import bolts.TaskCompletionSource;
import com.amulyakhare.textdrawable.TextDrawable;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import timber.log.Timber;
import static android.R.attr.bitmap;
/**
* Helper for rendering user avatar image.
*/
......@@ -85,4 +95,58 @@ public class Avatar {
.endConfig()
.buildRoundRect(getInitialsForUser(username), getColorForUser(username), round);
}
public Task<Bitmap> getBitmap(Context context, int size) {
TaskCompletionSource<Bitmap> task = new TaskCompletionSource<>();
// Picasso can be triggered only on Main Thread.
if (Looper.myLooper() != Looper.getMainLooper()) {
new Handler(Looper.getMainLooper()).post(() -> {
getBitmap(context, size).continueWith(_task -> {
if (_task.isFaulted()) {
task.setError(_task.getError());
} else {
task.setResult(_task.getResult());
}
return null;
});
});
return task.getTask();
}
Picasso.with(context)
.load(getImageUrl())
.error(getTextDrawable(context))
.into(new Target() {
@Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
if (bitmap != null) {
task.trySetResult(bitmap);
}
}
@Override public void onBitmapFailed(Drawable errorDrawable) {
task.trySetResult(drawableToBitmap(errorDrawable, size));
}
@Override public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
return task.getTask();
}
private static Bitmap drawableToBitmap (Drawable drawable, int size) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
......@@ -11,7 +11,6 @@ public class ViewDataCache {
/**
* stores str if not stored. returns true if already stored.
*/
@DebugLog
public static boolean isStored(String str, View view) {
if (view.getTag() != null && view.getTag() instanceof String
&& ((String) view.getTag()).equals(str)) {
......
......@@ -2,9 +2,13 @@ package chat.rocket.android.notification;
import android.app.Notification;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import bolts.Task;
import chat.rocket.android.R;
import chat.rocket.android.helper.Avatar;
import org.json.JSONObject;
/**
......@@ -12,12 +16,15 @@ import org.json.JSONObject;
*/
public class StreamNotifyUserNotifier implements Notifier {
private final Context context;
private final String hostname;
private final String title;
private final String text;
private final JSONObject payload;
public StreamNotifyUserNotifier(Context context, String title, String text, JSONObject payload) {
public StreamNotifyUserNotifier(Context context, String hostname,
String title, String text, JSONObject payload) {
this.context = context;
this.hostname = hostname;
this.title = title;
this.text = text;
this.payload = payload;
......@@ -28,8 +35,11 @@ public class StreamNotifyUserNotifier implements Notifier {
return;
}
generateNotificationAsync().onSuccess(task -> {
NotificationManagerCompat.from(context)
.notify(generateNotificationId(), generateNotification());
.notify(generateNotificationId(), task.getResult());
return null;
});
}
private boolean shouldNotify() {
......@@ -42,12 +52,34 @@ public class StreamNotifyUserNotifier implements Notifier {
return (int) (System.currentTimeMillis() % Integer.MAX_VALUE);
}
private Notification generateNotification() {
private Task<Notification> generateNotificationAsync() {
int size = context.getResources().getDimensionPixelSize(R.dimen.notification_avatar_size);
return getUsername()
.onSuccessTask(task -> new Avatar(hostname, task.getResult()).getBitmap(context, size))
.continueWithTask(task -> {
Bitmap icon = task.isFaulted() ? null : task.getResult();
return Task.forResult(generateNotification(icon));
});
}
private Task<String> getUsername() {
try {
return Task.forResult(payload.getJSONObject("sender").getString("username"));
} catch (Exception exception) {
return Task.forError(exception);
}
}
private Notification generateNotification(Bitmap largeIcon) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setSmallIcon(R.drawable.rocket_chat_notification_24dp);
if (largeIcon != null) {
builder.setLargeIcon(largeIcon);
}
if (text.length() > 20) {
return new NotificationCompat.BigTextStyle(builder)
.bigText(text)
......@@ -56,5 +88,4 @@ public class StreamNotifyUserNotifier implements Notifier {
return builder.build();
}
}
}
......@@ -209,11 +209,15 @@ public class RocketChatWebSocketThread extends HandlerThread {
}
listenersRegistered = true;
final ServerConfig config = defaultRealm.executeTransactionForRead(realm ->
realm.where(ServerConfig.class).equalTo("serverConfigId", serverConfigId).findFirst());
final String hostname = config.getHostname();
for (Class clazz : REGISTERABLE_CLASSES) {
try {
Constructor ctor = clazz.getConstructor(Context.class, RealmHelper.class,
Constructor ctor = clazz.getConstructor(Context.class, String.class, RealmHelper.class,
DDPClientWraper.class);
Object obj = ctor.newInstance(appContext, serverConfigRealm, ddpClient);
Object obj = ctor.newInstance(appContext, hostname, serverConfigRealm, ddpClient);
if (obj instanceof Registerable) {
Registerable registerable = (Registerable) obj;
......
......@@ -18,14 +18,16 @@ import timber.log.Timber;
public abstract class AbstractDDPDocEventSubscriber implements Registerable {
protected final Context context;
protected final String hostname;
protected final RealmHelper realmHelper;
protected final DDPClientWraper ddpClient;
private String subscriptionId;
private Subscription rxSubscription;
protected AbstractDDPDocEventSubscriber(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
protected AbstractDDPDocEventSubscriber(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
this.context = context;
this.hostname = hostname;
this.realmHelper = realmHelper;
this.ddpClient = ddpClient;
}
......
......@@ -7,9 +7,9 @@ import chat.rocket.android.service.ddp.AbstractDDPDocEventSubscriber;
import org.json.JSONArray;
abstract class AbstractBaseSubscriber extends AbstractDDPDocEventSubscriber {
protected AbstractBaseSubscriber(Context context, RealmHelper realmHelper,
protected AbstractBaseSubscriber(Context context, String hostname, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
super(context, hostname, realmHelper, ddpClient);
}
@Override protected final JSONArray getSubscriptionParams() {
......
......@@ -10,9 +10,9 @@ import io.realm.RealmObject;
* "activeUsers" subscriber.
*/
public class ActiveUsersSubscriber extends AbstractBaseSubscriber {
public ActiveUsersSubscriber(Context context, RealmHelper realmHelper,
public ActiveUsersSubscriber(Context context, String hostname, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
super(context, hostname, realmHelper, ddpClient);
}
@Override protected String getSubscriptionName() {
......
......@@ -10,9 +10,9 @@ import io.realm.RealmObject;
* meteor.loginServiceConfiguration subscriber
*/
public class LoginServiceConfigurationSubscriber extends AbstractBaseSubscriber {
public LoginServiceConfigurationSubscriber(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public LoginServiceConfigurationSubscriber(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
}
@Override protected String getSubscriptionName() {
......
......@@ -10,9 +10,9 @@ import io.realm.RealmObject;
* "userData" subscriber.
*/
public class UserDataSubscriber extends AbstractBaseSubscriber {
public UserDataSubscriber(Context context, RealmHelper realmHelper,
public UserDataSubscriber(Context context, String hostname, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
super(context, hostname, realmHelper, ddpClient);
}
@Override protected String getSubscriptionName() {
......
......@@ -12,9 +12,9 @@ import org.json.JSONObject;
import timber.log.Timber;
abstract class AbstractStreamNotifyEventSubscriber extends AbstractDDPDocEventSubscriber {
protected AbstractStreamNotifyEventSubscriber(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
protected AbstractStreamNotifyEventSubscriber(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
}
@Override protected final boolean shouldTruncateTableOnInitialize() {
......
......@@ -6,9 +6,9 @@ import chat.rocket.android.realm_helper.RealmHelper;
abstract class AbstractStreamNotifyUserEventSubscriber extends AbstractStreamNotifyEventSubscriber {
protected final String userId;
protected AbstractStreamNotifyUserEventSubscriber(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient, String userId) {
super(context, realmHelper, ddpClient);
protected AbstractStreamNotifyUserEventSubscriber(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient, String userId) {
super(context, hostname, realmHelper, ddpClient);
this.userId = userId;
}
......
......@@ -11,9 +11,9 @@ import org.json.JSONException;
import org.json.JSONObject;
public class StreamNotifyUserNotification extends AbstractStreamNotifyUserEventSubscriber {
public StreamNotifyUserNotification(Context context, RealmHelper realmHelper,
public StreamNotifyUserNotification(Context context, String hostname, RealmHelper realmHelper,
DDPClientWraper ddpClient, String userId) {
super(context, realmHelper, ddpClient, userId);
super(context, hostname, realmHelper, ddpClient, userId);
}
@Override protected String getSubscriptionSubParam() {
......@@ -22,7 +22,7 @@ public class StreamNotifyUserNotification extends AbstractStreamNotifyUserEventS
@Override protected void handleArgs(JSONArray args) throws JSONException {
JSONObject target = args.getJSONObject(args.length() - 1);
Notifier notifier = new StreamNotifyUserNotifier(context,
Notifier notifier = new StreamNotifyUserNotifier(context, hostname,
target.getString("title"),
target.getString("text"),
target.getJSONObject("payload"));
......
......@@ -7,9 +7,9 @@ import chat.rocket.android.realm_helper.RealmHelper;
import io.realm.RealmObject;
public class StreamNotifyUserSubscriptionsChanged extends AbstractStreamNotifyUserEventSubscriber {
public StreamNotifyUserSubscriptionsChanged(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient, String userId) {
super(context, realmHelper, ddpClient, userId);
public StreamNotifyUserSubscriptionsChanged(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient, String userId) {
super(context, hostname, realmHelper, ddpClient, userId);
}
@Override protected String getSubscriptionSubParam() {
......
......@@ -14,9 +14,9 @@ import org.json.JSONObject;
public class StreamRoomMessage extends AbstractStreamNotifyEventSubscriber {
private String roomId;
public StreamRoomMessage(Context context, RealmHelper realmHelper, DDPClientWraper ddpClient,
String roomId) {
super(context, realmHelper, ddpClient);
public StreamRoomMessage(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient, String roomId) {
super(context, hostname, realmHelper, ddpClient);
this.roomId = roomId;
}
......
......@@ -15,14 +15,16 @@ public class StreamRoomMessageManager implements Registerable {
private StreamRoomMessage streamRoomMessage;
private final Context context;
private final String hostname;
private final RealmHelper realmHelper;
private final DDPClientWraper ddpClient;
private final AbstractRocketChatCacheObserver cacheObserver;
private final Handler handler;
public StreamRoomMessageManager(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
public StreamRoomMessageManager(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
this.context = context;
this.hostname = hostname;
this.realmHelper = realmHelper;
this.ddpClient = ddpClient;
......@@ -37,7 +39,7 @@ public class StreamRoomMessageManager implements Registerable {
private void registerStreamNotifyMessage(String roomId) {
handler.post(() -> {
streamRoomMessage = new StreamRoomMessage(context, realmHelper, ddpClient, roomId);
streamRoomMessage = new StreamRoomMessage(context, hostname, realmHelper, ddpClient, roomId);
streamRoomMessage.register();
});
}
......
......@@ -11,13 +11,15 @@ abstract class AbstractModelObserver<T extends RealmObject>
implements Registerable, RealmListObserver.Query<T>, RealmListObserver.OnUpdateListener<T> {
protected final Context context;
protected final String hostname;
protected final RealmHelper realmHelper;
protected final DDPClientWraper ddpClient;
private final RealmListObserver observer;
protected AbstractModelObserver(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
protected AbstractModelObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
this.context = context;
this.hostname = hostname;
this.realmHelper = realmHelper;
this.ddpClient = ddpClient;
observer = realmHelper.createListObserver(this).setOnUpdateListener(this);
......
......@@ -24,9 +24,9 @@ public class CurrentUserObserver extends AbstractModelObserver<User> {
private ArrayList<Registerable> listeners;
public CurrentUserObserver(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public CurrentUserObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
methodCall = new MethodCallHelper(realmHelper, ddpClient);
currentUserExists = false;
}
......@@ -60,14 +60,14 @@ public class CurrentUserObserver extends AbstractModelObserver<User> {
// get and observe Room subscriptions.
methodCall.getRoomSubscriptions().onSuccess(task -> {
Registerable listener = new StreamNotifyUserSubscriptionsChanged(
context, realmHelper, ddpClient, userId);
context, hostname, realmHelper, ddpClient, userId);
listener.register();
listeners.add(listener);
return null;
});
Registerable listener = new StreamNotifyUserNotification(
context, realmHelper, ddpClient, userId);
context, hostname, realmHelper, ddpClient, userId);
listener.register();
listeners.add(listener);
}
......
......@@ -21,9 +21,9 @@ public class GetUsersOfRoomsProcedureObserver
private final MethodCallHelper methodCall;
public GetUsersOfRoomsProcedureObserver(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public GetUsersOfRoomsProcedureObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
methodCall = new MethodCallHelper(realmHelper, ddpClient);
}
......
......@@ -22,9 +22,9 @@ public class LoadMessageProcedureObserver extends AbstractModelObserver<LoadMess
private final MethodCallHelper methodCall;
public LoadMessageProcedureObserver(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public LoadMessageProcedureObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
methodCall = new MethodCallHelper(realmHelper, ddpClient);
}
......
......@@ -23,8 +23,9 @@ public class MethodCallObserver extends AbstractModelObserver<MethodCall> {
/**
* constructor.
*/
public MethodCallObserver(Context context, RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public MethodCallObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
realmHelper.executeTransaction(realm -> {
// resume pending operations.
RealmResults<MethodCall> pendingMethodCalls = realm.where(MethodCall.class)
......
......@@ -20,9 +20,9 @@ public class NewMessageObserver extends AbstractModelObserver<Message> {
private final MethodCallHelper methodCall;
public NewMessageObserver(Context context, RealmHelper realmHelper,
DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public NewMessageObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
methodCall = new MethodCallHelper(realmHelper, ddpClient);
realmHelper.executeTransaction(realm -> {
......
......@@ -25,11 +25,12 @@ public class SessionObserver extends AbstractModelObserver<Session> {
/**
* constructor.
*/
public SessionObserver(Context context, RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public SessionObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
count = 0;
streamNotifyMessage = new StreamRoomMessageManager(context, realmHelper, ddpClient);
streamNotifyMessage = new StreamRoomMessageManager(context, hostname, realmHelper, ddpClient);
}
@Override public RealmResults<Session> queryItems(Realm realm) {
......
......@@ -14,8 +14,9 @@ public class TokenLoginObserver extends AbstractModelObserver<Session> {
private final MethodCallHelper methodCall;
public TokenLoginObserver(Context context, RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, realmHelper, ddpClient);
public TokenLoginObserver(Context context, String hostname,
RealmHelper realmHelper, DDPClientWraper ddpClient) {
super(context, hostname, realmHelper, ddpClient);
methodCall = new MethodCallHelper(realmHelper, ddpClient);
}
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="avatar_image_size_normal">24dp</dimen>
<dimen name="avatar_image_size_large">48dp</dimen>
<dimen name="avatar_text_size_normal">11sp</dimen>
<dimen name="avatar_text_size_large">28sp</dimen>
<dimen name="notification_avatar_size">48dp</dimen>
</resources>
\ No newline at end of file
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