mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-09 20:39:24 +02:00
Adds a new observable system to local cache.
This commit is contained in:
parent
4a6ea550d6
commit
8b052567c4
@ -26,6 +26,7 @@ import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.amethyst.Amethyst
|
||||
import com.vitorpamplona.amethyst.commons.data.DeletionIndex
|
||||
import com.vitorpamplona.amethyst.commons.data.LargeCache
|
||||
import com.vitorpamplona.amethyst.model.observables.LatestByKindWithETag
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.service.relays.Relay
|
||||
import com.vitorpamplona.amethyst.ui.components.BundledInsert
|
||||
@ -142,6 +143,38 @@ object LocalCache {
|
||||
|
||||
val deletionIndex = DeletionIndex()
|
||||
|
||||
val observablesByKindAndETag = ConcurrentHashMap<Int, ConcurrentHashMap<HexKey, LatestByKindWithETag>>(10)
|
||||
|
||||
fun observeETag(
|
||||
kind: Int,
|
||||
eventId: HexKey,
|
||||
onCreate: () -> LatestByKindWithETag,
|
||||
): LatestByKindWithETag {
|
||||
var eTagList = observablesByKindAndETag.get(kind)
|
||||
|
||||
if (eTagList == null) {
|
||||
eTagList = ConcurrentHashMap<HexKey, LatestByKindWithETag>(1)
|
||||
observablesByKindAndETag.put(kind, eTagList)
|
||||
}
|
||||
|
||||
val value = eTagList.get(eventId)
|
||||
|
||||
return if (value != null) {
|
||||
value
|
||||
} else {
|
||||
val newObject = onCreate()
|
||||
val obj = eTagList.putIfAbsent(eventId, newObject) ?: newObject
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
fun updateObservables(event: Event) {
|
||||
val observablesOfKind = observablesByKindAndETag[event.kind()] ?: return
|
||||
event.forEachTaggedEvent {
|
||||
observablesOfKind[it]?.updateIfMatches(event)
|
||||
}
|
||||
}
|
||||
|
||||
fun checkGetOrCreateUser(key: String): User? {
|
||||
// checkNotInMainThread()
|
||||
|
||||
@ -2239,6 +2272,7 @@ object LocalCache {
|
||||
val live: LocalCacheLiveData = LocalCacheLiveData()
|
||||
|
||||
private fun refreshObservers(newNote: Note) {
|
||||
updateObservables(newNote.event as Event)
|
||||
live.invalidateData(newNote)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.model.observables
|
||||
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.quartz.events.Event
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class LatestByKindWithETag(private val kind: Int, private val eTag: String) {
|
||||
private val _latest = MutableStateFlow<Event?>(null)
|
||||
val latest = _latest.asStateFlow()
|
||||
|
||||
fun updateIfMatches(event: Event) {
|
||||
if (event.kind == kind && event.isTaggedEvent(eTag)) {
|
||||
if (event.createdAt > (_latest.value?.createdAt ?: 0)) {
|
||||
_latest.tryEmit(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun canDelete(): Boolean {
|
||||
return _latest.subscriptionCount.value == 0
|
||||
}
|
||||
|
||||
suspend fun init() {
|
||||
val latestNote =
|
||||
LocalCache.notes.maxOrNullOf(
|
||||
filter = { idHex: String, note: Note ->
|
||||
note.event?.let {
|
||||
it.kind() == kind && it.isTaggedEvent(eTag)
|
||||
} == true
|
||||
},
|
||||
comparator = { first: Note?, second: Note? ->
|
||||
println("Comparator $first $second")
|
||||
val firstEvent = first?.event
|
||||
val secondEvent = second?.event
|
||||
|
||||
if (firstEvent == null && secondEvent == null) {
|
||||
0
|
||||
} else if (firstEvent == null) {
|
||||
1
|
||||
} else if (secondEvent == null) {
|
||||
-1
|
||||
} else {
|
||||
firstEvent.createdAt().compareTo(secondEvent.createdAt())
|
||||
}
|
||||
},
|
||||
)?.event as? Event
|
||||
|
||||
_latest.tryEmit(latestNote)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user