mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-23 05:25:31 +03:00
Refactor - extracted common method to load avatars for notifications
Signed-off-by: Dariusz Olszewski <starypatyk@users.noreply.github.com>
This commit is contained in:
parent
3b7ca4a31a
commit
d4bdd88588
3 changed files with 43 additions and 72 deletions
|
@ -37,14 +37,6 @@ import android.util.Base64;
|
|||
import android.util.Log;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.facebook.common.executors.UiThreadImmediateExecutorService;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.datasource.DataSource;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.nextcloud.talk.R;
|
||||
import com.nextcloud.talk.activities.CallActivity;
|
||||
import com.nextcloud.talk.activities.MainActivity;
|
||||
|
@ -61,7 +53,6 @@ import com.nextcloud.talk.models.json.push.DecryptedPushMessage;
|
|||
import com.nextcloud.talk.models.json.push.NotificationUser;
|
||||
import com.nextcloud.talk.receivers.DirectReplyReceiver;
|
||||
import com.nextcloud.talk.utils.ApiUtils;
|
||||
import com.nextcloud.talk.utils.DisplayUtils;
|
||||
import com.nextcloud.talk.utils.DoNotDisturbUtils;
|
||||
import com.nextcloud.talk.utils.NotificationUtils;
|
||||
import com.nextcloud.talk.utils.PushUtils;
|
||||
|
@ -93,7 +84,6 @@ import androidx.core.app.NotificationCompat.MessagingStyle;
|
|||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.app.Person;
|
||||
import androidx.core.app.RemoteInput;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.emoji.text.EmojiCompat;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.Worker;
|
||||
|
@ -395,9 +385,10 @@ public class NotificationWorker extends Worker {
|
|||
final NotificationUser notificationUser = decryptedPushMessage.getNotificationUser();
|
||||
final String userType = notificationUser.getType();
|
||||
|
||||
MessagingStyle style = activeStatusBarNotification != null ?
|
||||
MessagingStyle.extractMessagingStyleFromNotification(activeStatusBarNotification.getNotification()) :
|
||||
null;
|
||||
MessagingStyle style = null;
|
||||
if (activeStatusBarNotification != null) {
|
||||
style = MessagingStyle.extractMessagingStyleFromNotification(activeStatusBarNotification.getNotification());
|
||||
}
|
||||
|
||||
Person.Builder person =
|
||||
new Person.Builder()
|
||||
|
@ -413,31 +404,11 @@ public class NotificationWorker extends Worker {
|
|||
String avatarUrl = "user".equals(userType) ?
|
||||
ApiUtils.getUrlForAvatar(baseUrl, notificationUser.getId(), false) :
|
||||
ApiUtils.getUrlForGuestAvatar(baseUrl, notificationUser.getName(), false);
|
||||
|
||||
ImageRequest imageRequest = DisplayUtils.getImageRequestForUrl(avatarUrl, null);
|
||||
Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context).subscribe(
|
||||
new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
protected void onNewResultImpl(Bitmap bitmap) {
|
||||
if (bitmap != null) {
|
||||
new RoundAsCirclePostprocessor(true).process(bitmap);
|
||||
person.setIcon(IconCompat.createWithBitmap(bitmap));
|
||||
notificationBuilder.setStyle(getStyle(person.build(), style));
|
||||
sendNotificationWithId(notificationId, notificationBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
|
||||
notificationBuilder.setStyle(getStyle(person.build(), style));
|
||||
sendNotificationWithId(notificationId, notificationBuilder.build());
|
||||
}
|
||||
},
|
||||
UiThreadImmediateExecutorService.getInstance());
|
||||
} else {
|
||||
notificationBuilder.setStyle(getStyle(person.build(), style));
|
||||
sendNotificationWithId(notificationId, notificationBuilder.build());
|
||||
person.setIcon(NotificationUtils.INSTANCE.loadAvatarSync(avatarUrl));
|
||||
}
|
||||
|
||||
notificationBuilder.setStyle(getStyle(person.build(), style));
|
||||
sendNotificationWithId(notificationId, notificationBuilder.build());
|
||||
}
|
||||
|
||||
private void addReplyAction(NotificationCompat.Builder notificationBuilder, int notificationId) {
|
||||
|
|
|
@ -25,28 +25,18 @@ import android.app.NotificationManager
|
|||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.app.RemoteInput
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import autodagger.AutoInjector
|
||||
import com.facebook.common.executors.UiThreadImmediateExecutorService
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.datasource.DataSource
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.CloseableImage
|
||||
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor
|
||||
import com.nextcloud.talk.api.NcApi
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||
import com.nextcloud.talk.models.database.UserEntity
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.NotificationUtils
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
|
@ -110,7 +100,7 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun onNext(genericOverall: GenericOverall) {
|
||||
loadAvatar(::confirmReplySent)
|
||||
confirmReplySent()
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
|
@ -124,27 +114,6 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
})
|
||||
}
|
||||
|
||||
private fun loadAvatar(callback: (avatarIcon: IconCompat) -> Unit) {
|
||||
val avatarUrl = ApiUtils.getUrlForAvatar(currentUser.baseUrl, currentUser.userId, false)
|
||||
val imageRequest = DisplayUtils.getImageRequestForUrl(avatarUrl, currentUser)
|
||||
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, null)
|
||||
dataSource.subscribe(
|
||||
object : BaseBitmapDataSubscriber() {
|
||||
override fun onNewResultImpl(bitmap: Bitmap?) {
|
||||
if (bitmap != null) {
|
||||
RoundAsCirclePostprocessor(true).process(bitmap)
|
||||
callback(IconCompat.createWithBitmap(bitmap))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage?>>) {
|
||||
// unused atm
|
||||
}
|
||||
},
|
||||
UiThreadImmediateExecutorService.getInstance()
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
private fun findActiveNotification(notificationId: Int): Notification? {
|
||||
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
@ -152,7 +121,7 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
private fun confirmReplySent(avatarIcon: IconCompat) {
|
||||
private fun confirmReplySent() {
|
||||
// Implementation inspired by the SO question and article below:
|
||||
// https://stackoverflow.com/questions/51549456/android-o-notification-for-direct-reply-message
|
||||
// https://medium.com/@sidorovroman3/android-how-to-use-messagingstyle-for-notifications-without-caching-messages-c414ef2b816c
|
||||
|
@ -171,10 +140,10 @@ class DirectReplyReceiver : BroadcastReceiver() {
|
|||
.extractMessagingStyleFromNotification(previousNotification)
|
||||
|
||||
// Add reply
|
||||
val avatarUrl = ApiUtils.getUrlForAvatar(currentUser.baseUrl, currentUser.userId, false)
|
||||
val me = Person.Builder()
|
||||
.setName(currentUser.displayName)
|
||||
// .setIcon(IconCompat.createWithResource(context, R.drawable.ic_user))
|
||||
.setIcon(avatarIcon)
|
||||
.setIcon(NotificationUtils.loadAvatarSync(avatarUrl))
|
||||
.build()
|
||||
val message = NotificationCompat.MessagingStyle.Message(replyMessage, System.currentTimeMillis(), me)
|
||||
previousStyle?.addMessage(message)
|
||||
|
|
|
@ -32,7 +32,13 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.text.TextUtils
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.bluelinelabs.logansquare.LoganSquare
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.datasource.DataSources
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.image.CloseableBitmap
|
||||
import com.facebook.imagepipeline.postprocessors.RoundAsCirclePostprocessor
|
||||
import com.nextcloud.talk.BuildConfig
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.models.RingtoneSettings
|
||||
|
@ -297,6 +303,31 @@ object NotificationUtils {
|
|||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* Load user avatar synchronously.
|
||||
* Inspired by:
|
||||
* https://frescolib.org/docs/using-image-pipeline.html
|
||||
* https://github.com/facebook/fresco/issues/830
|
||||
* https://localcoder.org/using-facebooks-fresco-to-load-a-bitmap
|
||||
*/
|
||||
fun loadAvatarSync(avatarUrl: String): IconCompat? {
|
||||
// TODO - how to handle errors here?
|
||||
var avatarIcon: IconCompat? = null
|
||||
val imageRequest = DisplayUtils.getImageRequestForUrl(avatarUrl, null)
|
||||
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, null)
|
||||
val closeableImageRef = DataSources.waitForFinalResult(dataSource) as CloseableReference<CloseableBitmap>?
|
||||
val bitmap = closeableImageRef?.get()?.underlyingBitmap
|
||||
if (bitmap != null) {
|
||||
// According to Fresco documentation a copy of the bitmap should be made before closing the references.
|
||||
// However, it seems to work without making a copy... ;-)
|
||||
RoundAsCirclePostprocessor(true).process(bitmap)
|
||||
avatarIcon = IconCompat.createWithBitmap(bitmap)
|
||||
}
|
||||
CloseableReference.closeSafely(closeableImageRef)
|
||||
dataSource.close()
|
||||
return avatarIcon
|
||||
}
|
||||
|
||||
private data class Channel(
|
||||
val id: String,
|
||||
val name: String,
|
||||
|
|
Loading…
Reference in a new issue