kopia lustrzana https://github.com/vitorpamplona/amethyst
69 wiersze
2.0 KiB
Kotlin
69 wiersze
2.0 KiB
Kotlin
package com.vitorpamplona.amethyst
|
|
|
|
import androidx.lifecycle.LiveData
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.NonCancellable
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
|
|
object NotificationCache {
|
|
val lastReadByRoute = mutableMapOf<String, Long>()
|
|
|
|
fun markAsRead(route: String, timestampInSecs: Long) {
|
|
val lastTime = lastReadByRoute[route]
|
|
if (lastTime == null || timestampInSecs > lastTime) {
|
|
lastReadByRoute.put(route, timestampInSecs)
|
|
|
|
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
|
scope.launch {
|
|
LocalPreferences.saveLastRead(route, timestampInSecs)
|
|
live.invalidateData()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun load(route: String): Long {
|
|
var lastTime = lastReadByRoute[route]
|
|
if (lastTime == null) {
|
|
lastTime = LocalPreferences.loadLastRead(route)
|
|
lastReadByRoute[route] = lastTime
|
|
}
|
|
return lastTime
|
|
}
|
|
|
|
// Observers line up here.
|
|
val live: NotificationLiveData = NotificationLiveData(this)
|
|
}
|
|
|
|
class NotificationLiveData(val cache: NotificationCache) : LiveData<NotificationState>(NotificationState(cache)) {
|
|
// Refreshes observers in batches.
|
|
var handlerWaiting = AtomicBoolean()
|
|
|
|
fun invalidateData() {
|
|
if (!hasActiveObservers()) return
|
|
if (handlerWaiting.getAndSet(true)) return
|
|
|
|
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
|
scope.launch {
|
|
try {
|
|
delay(100)
|
|
refresh()
|
|
} finally {
|
|
withContext(NonCancellable) {
|
|
handlerWaiting.set(false)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun refresh() {
|
|
postValue(NotificationState(cache))
|
|
}
|
|
}
|
|
|
|
class NotificationState(val cache: NotificationCache)
|