forked from GitHub-Mirror/riotX-android
Notification: display room avatar
This commit is contained in:
parent
b388be93c8
commit
9fa3a75fb6
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.notifications
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.HandlerThread
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DecodeFormat
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME It works, but it does not refresh the notification, when it's already displayed
|
||||||
|
*/
|
||||||
|
class BitmapLoader(val context: Context,
|
||||||
|
val listener: BitmapLoaderListener) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar Url -> Icon
|
||||||
|
*/
|
||||||
|
private val cache = HashMap<String, Bitmap>()
|
||||||
|
|
||||||
|
// URLs to load
|
||||||
|
private val toLoad = HashSet<String>()
|
||||||
|
|
||||||
|
// Black list of URLs (broken URL, etc.)
|
||||||
|
private val blacklist = HashSet<String>()
|
||||||
|
|
||||||
|
private var uiHandler = Handler()
|
||||||
|
|
||||||
|
private val handlerThread: HandlerThread = HandlerThread("BitmapLoader", Thread.MIN_PRIORITY)
|
||||||
|
private var backgroundHandler: Handler
|
||||||
|
|
||||||
|
init {
|
||||||
|
handlerThread.start()
|
||||||
|
backgroundHandler = Handler(handlerThread.looper)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get icon of a room.
|
||||||
|
* If already in cache, use it, else load it and call BitmapLoaderListener.onBitmapsLoaded() when ready
|
||||||
|
*/
|
||||||
|
fun getRoomBitmap(path: String?): Bitmap? {
|
||||||
|
if (path == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized(cache) {
|
||||||
|
if (cache[path] != null) {
|
||||||
|
return cache[path]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the queue, if not blacklisted
|
||||||
|
if (!blacklist.contains(path)) {
|
||||||
|
if (toLoad.contains(path)) {
|
||||||
|
// Wait
|
||||||
|
} else {
|
||||||
|
toLoad.add(path)
|
||||||
|
|
||||||
|
backgroundHandler.post {
|
||||||
|
loadRoomBitmap(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
private fun loadRoomBitmap(path: String) {
|
||||||
|
val bitmap = path.let {
|
||||||
|
try {
|
||||||
|
Glide.with(context)
|
||||||
|
.asBitmap()
|
||||||
|
.load(path)
|
||||||
|
.format(DecodeFormat.PREFER_ARGB_8888)
|
||||||
|
.submit()
|
||||||
|
.get()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e, "decodeFile failed")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized(cache) {
|
||||||
|
if (bitmap == null) {
|
||||||
|
// Add to the blacklist
|
||||||
|
blacklist.add(path)
|
||||||
|
} else {
|
||||||
|
cache[path] = bitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
toLoad.remove(path)
|
||||||
|
|
||||||
|
if (toLoad.isEmpty()) {
|
||||||
|
uiHandler.post {
|
||||||
|
listener.onBitmapsLoaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface BitmapLoaderListener {
|
||||||
|
fun onBitmapsLoaded()
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,6 @@ package im.vector.riotredesign.features.notifications
|
|||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.text.TextUtils
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.Person
|
import androidx.core.app.Person
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
@ -59,6 +57,14 @@ class NotificationDrawerManager(val context: Context,
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
private var bitmapLoader = BitmapLoader(context,
|
||||||
|
object : BitmapLoader.BitmapLoaderListener {
|
||||||
|
override fun onBitmapsLoaded() {
|
||||||
|
// Force refresh
|
||||||
|
refreshNotificationDrawer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Should be called as soon as a new event is ready to be displayed.
|
Should be called as soon as a new event is ready to be displayed.
|
||||||
The notification corresponding to this event will not be displayed until
|
The notification corresponding to this event will not be displayed until
|
||||||
@ -372,19 +378,10 @@ class NotificationDrawerManager(val context: Context,
|
|||||||
if (events.isEmpty()) return null
|
if (events.isEmpty()) return null
|
||||||
|
|
||||||
//Use the last event (most recent?)
|
//Use the last event (most recent?)
|
||||||
val roomAvatarPath = events[events.size - 1].roomAvatarPath
|
val roomAvatarPath = events.last().roomAvatarPath
|
||||||
?: events[events.size - 1].senderAvatarPath
|
?: events.last().senderAvatarPath
|
||||||
if (!TextUtils.isEmpty(roomAvatarPath)) {
|
|
||||||
val options = BitmapFactory.Options()
|
|
||||||
options.inPreferredConfig = Bitmap.Config.ARGB_8888
|
|
||||||
try {
|
|
||||||
return BitmapFactory.decodeFile(roomAvatarPath, options)
|
|
||||||
} catch (oom: OutOfMemoryError) {
|
|
||||||
Timber.e(oom, "decodeFile failed with an oom")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
return bitmapLoader.getRoomBitmap(roomAvatarPath)
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldIgnoreMessageEventInRoom(roomId: String?): Boolean {
|
private fun shouldIgnoreMessageEventInRoom(roomId: String?): Boolean {
|
||||||
|
@ -22,7 +22,6 @@ package im.vector.riotredesign.features.notifications
|
|||||||
data class RoomEventGroupInfo(
|
data class RoomEventGroupInfo(
|
||||||
val roomId: String,
|
val roomId: String,
|
||||||
val roomDisplayName: String = "",
|
val roomDisplayName: String = "",
|
||||||
val roomAvatarPath: String? = null,
|
|
||||||
val isDirect: Boolean = false
|
val isDirect: Boolean = false
|
||||||
) {
|
) {
|
||||||
// An event in the list has not yet been display
|
// An event in the list has not yet been display
|
||||||
|
Loading…
Reference in New Issue
Block a user