Fixes the index after deletions
This commit is contained in:
@@ -200,9 +200,6 @@ import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
interface ILocalCache {
|
||||
@@ -520,12 +517,6 @@ object LocalCache : ILocalCache {
|
||||
wasVerified: Boolean,
|
||||
) = consumeBaseReplaceable(event, relay, wasVerified)
|
||||
|
||||
fun formattedDateTime(timestamp: Long): String =
|
||||
Instant
|
||||
.ofEpochSecond(timestamp)
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.format(DateTimeFormatter.ofPattern("uuuu MMM d hh:mm a"))
|
||||
|
||||
fun consume(
|
||||
event: TextNoteEvent,
|
||||
relay: NormalizedRelayUrl? = null,
|
||||
@@ -831,7 +822,7 @@ object LocalCache : ILocalCache {
|
||||
event.mapTaggedEventId { checkGetOrCreateNote(it) } + event.mapTaggedAddress { checkGetOrCreateAddressableNote(it) }
|
||||
}
|
||||
|
||||
else -> emptyList<Note>()
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
fun consume(
|
||||
@@ -1339,6 +1330,9 @@ object LocalCache : ILocalCache {
|
||||
masterNote.removeReport(deleteNote)
|
||||
}
|
||||
|
||||
deleteNote.inChatroom?.removeMessageSync(deleteNote)
|
||||
deleteNote.inChannel?.removeNote(deleteNote)
|
||||
|
||||
getAnyChannel(deleteNote)?.removeNote(deleteNote)
|
||||
|
||||
(deletedEvent as? TorrentCommentEvent)?.torrentIds()?.let {
|
||||
@@ -1357,18 +1351,18 @@ object LocalCache : ILocalCache {
|
||||
}
|
||||
|
||||
fun deleteWraps(event: WrappedEvent) {
|
||||
event.host?.let {
|
||||
event.host?.let { hostStub ->
|
||||
// seal
|
||||
getNoteIfExists(it.id)?.let {
|
||||
val noteEvent = it.event
|
||||
getNoteIfExists(hostStub.id)?.let { hostNote ->
|
||||
val noteEvent = hostNote.event
|
||||
if (noteEvent is WrappedEvent) {
|
||||
deleteWraps(noteEvent)
|
||||
}
|
||||
it.clearFlow()
|
||||
refreshDeletedNoteObservers(it)
|
||||
hostNote.clearFlow()
|
||||
refreshDeletedNoteObservers(hostNote)
|
||||
}
|
||||
|
||||
notes.remove(it.id)
|
||||
notes.remove(hostStub.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1590,7 +1584,7 @@ object LocalCache : ILocalCache {
|
||||
oldChannel.updateChannelInfo(author, event)
|
||||
true
|
||||
} else {
|
||||
wasVerified
|
||||
false
|
||||
}
|
||||
} else {
|
||||
wasVerified
|
||||
@@ -2055,11 +2049,7 @@ object LocalCache : ILocalCache {
|
||||
if (note.event?.tags?.tagValueContains(text, true) == true ||
|
||||
note.idHex.startsWith(text, true)
|
||||
) {
|
||||
if (!note.isHiddenFor(hiddenUsers.flow.value)) {
|
||||
return@filter true
|
||||
} else {
|
||||
return@filter false
|
||||
}
|
||||
return@filter !note.isHiddenFor(hiddenUsers.flow.value)
|
||||
}
|
||||
|
||||
if (note.event?.isContentEncoded() == false) {
|
||||
@@ -2080,11 +2070,7 @@ object LocalCache : ILocalCache {
|
||||
if (addressable.event?.tags?.tagValueContains(text, true) == true ||
|
||||
addressable.idHex.startsWith(text, true)
|
||||
) {
|
||||
if (!addressable.isHiddenFor(hiddenUsers.flow.value)) {
|
||||
return@filter true
|
||||
} else {
|
||||
return@filter false
|
||||
}
|
||||
return@filter !addressable.isHiddenFor(hiddenUsers.flow.value)
|
||||
}
|
||||
|
||||
if (addressable.event?.isContentEncoded() == false) {
|
||||
@@ -2187,7 +2173,7 @@ object LocalCache : ILocalCache {
|
||||
suspend fun findLatestModificationForNote(note: Note): List<Note> {
|
||||
checkNotInMainThread()
|
||||
|
||||
val originalAuthor = note.author?.pubkeyHex ?: return emptyList()
|
||||
val noteAuthor = note.author ?: return emptyList()
|
||||
|
||||
modificationCache[note.idHex]?.let {
|
||||
return it
|
||||
@@ -2200,7 +2186,7 @@ object LocalCache : ILocalCache {
|
||||
.filter { _, item ->
|
||||
val noteEvent = item.event
|
||||
|
||||
noteEvent is TextNoteModificationEvent && note.author == item.author && noteEvent.isTaggedEvent(note.idHex) && !noteEvent.isExpirationBefore(time)
|
||||
noteEvent is TextNoteModificationEvent && noteAuthor == item.author && noteEvent.isTaggedEvent(note.idHex) && !noteEvent.isExpirationBefore(time)
|
||||
}.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
||||
|
||||
modificationCache.put(note.idHex, newNotes)
|
||||
@@ -2315,8 +2301,7 @@ object LocalCache : ILocalCache {
|
||||
val childrenToBeRemoved = mutableListOf<Note>()
|
||||
|
||||
toBeRemoved.forEach {
|
||||
// TODO: NEED TO TEST IF WRAPS COME BACK WHEN NEEDED BEFORE ACTIVATING
|
||||
// childrenToBeRemoved.addAll(removeIfWrap(it))
|
||||
childrenToBeRemoved.addAll(removeIfWrap(it))
|
||||
removeFromCache(it)
|
||||
|
||||
childrenToBeRemoved.addAll(it.removeAllChildNotes())
|
||||
@@ -2428,6 +2413,9 @@ object LocalCache : ILocalCache {
|
||||
masterNote.removeReport(note)
|
||||
}
|
||||
|
||||
note.inChatroom?.removeMessageSync(note)
|
||||
note.inChannel?.removeNote(note)
|
||||
|
||||
val noteEvent = note.event
|
||||
|
||||
if (noteEvent is LnZapEvent) {
|
||||
@@ -2896,6 +2884,9 @@ class LocalCacheFlow {
|
||||
// Refreshes observers in batches.
|
||||
private val bundler = BundledInsert<Note>(1000, Dispatchers.Default)
|
||||
|
||||
// Refreshes observers in batches.
|
||||
private val bundler2 = BundledInsert<Note>(1000, Dispatchers.Default)
|
||||
|
||||
fun newNote(newNote: Note) {
|
||||
bundler.invalidateList(newNote) { bundledNewNotes ->
|
||||
_newEventBundles.emit(bundledNewNotes)
|
||||
@@ -2903,7 +2894,7 @@ class LocalCacheFlow {
|
||||
}
|
||||
|
||||
fun removedNote(newNote: Note) {
|
||||
bundler.invalidateList(newNote) { bundledNewNotes ->
|
||||
bundler2.invalidateList(newNote) { bundledNewNotes ->
|
||||
_deletedEventBundles.emit(bundledNewNotes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,13 @@ class FeedContentState(
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteFromFeed(deletedNotes: Set<Note>) {
|
||||
val feed = _feedContent.value
|
||||
if (feed is FeedState.Loaded) {
|
||||
updateFeed((feed.feed.value.list - deletedNotes).toImmutableList())
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshFromOldState(newItems: Set<Note>) {
|
||||
val oldNotesState = _feedContent.value
|
||||
if (localFilter is AdditiveFeedFilter && lastFeedKey == localFilter.feedKey()) {
|
||||
|
||||
+10
@@ -46,7 +46,10 @@ import com.vitorpamplona.amethyst.ui.note.AboutDisplay
|
||||
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.AnimateOnNewSearch
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ShowUserSuggestionList(
|
||||
@@ -62,10 +65,17 @@ fun ShowUserSuggestionList(
|
||||
AnimateOnNewSearch(userSuggestions, listState)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.Default) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
userSuggestions.invalidateData()
|
||||
}
|
||||
}
|
||||
launch(Dispatchers.Default) {
|
||||
LocalCache.live.deletedEventBundles.collect {
|
||||
userSuggestions.invalidateData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchResponses(userSuggestions, listState, onSelect, accountViewModel, modifier)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,13 @@ abstract class FeedViewModel(
|
||||
feedState.updateFeedWith(newNotes)
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Delete from feeds: ${this@FeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
feedState.deleteFromFeed(newNotes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
||||
@@ -106,6 +106,13 @@ open class UserFeedViewModel(
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Delete from feeds: ${this@UserFeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
||||
+2
-9
@@ -198,7 +198,8 @@ class DecryptAndIndexProcessor(
|
||||
is DraftEvent -> {
|
||||
// Avoid decrypting over and over again if the event already exist.
|
||||
if (event.pubKey == account.signer.pubKey) {
|
||||
deindexDraftAsRealEvent(eventNote)
|
||||
// already deindexed by LocalCache
|
||||
// deindexDraftAsRealEvent(eventNote)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,14 +304,6 @@ class DecryptAndIndexProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
fun deindexDraftAsRealEvent(draftEventWrap: Note) {
|
||||
draftEventWrap.replyTo?.forEach { it.removeReply(draftEventWrap) }
|
||||
draftEventWrap.replyTo = null
|
||||
|
||||
draftEventWrap.inChatroom?.removeMessageSync(draftEventWrap)
|
||||
draftEventWrap.inChannel?.removeNote(draftEventWrap)
|
||||
}
|
||||
|
||||
suspend fun runNew(newNotes: Set<Note>) {
|
||||
try {
|
||||
newNotes.forEach {
|
||||
|
||||
+5
-4
@@ -87,11 +87,12 @@ open class LnZapFeedViewModel(
|
||||
init {
|
||||
Log.d("Init", "${this.javaClass.simpleName}")
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
checkNotInMainThread()
|
||||
|
||||
LocalCache.live.newEventBundles.collect { newNotes ->
|
||||
checkNotInMainThread()
|
||||
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -77,7 +77,9 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdTopPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun SearchScreen(
|
||||
@@ -142,6 +144,7 @@ private fun SearchBar(
|
||||
TextSearchDataSourceSubscription(searchBarViewModel, accountViewModel)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
launch(Dispatchers.Default) {
|
||||
LocalCache.live.newEventBundles.collect {
|
||||
if (searchBarViewModel.isSearchingFun()) {
|
||||
searchBarViewModel.invalidateData()
|
||||
@@ -149,6 +152,15 @@ private fun SearchBar(
|
||||
}
|
||||
}
|
||||
|
||||
launch(Dispatchers.Default) {
|
||||
LocalCache.live.deletedEventBundles.collect {
|
||||
if (searchBarViewModel.isSearchingFun()) {
|
||||
searchBarViewModel.invalidateData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimateOnNewSearch(searchBarViewModel, listState)
|
||||
|
||||
SearchTextField(searchBarViewModel, Modifier.statusBarsPadding())
|
||||
|
||||
+6
@@ -105,6 +105,12 @@ open class StringFeedViewModel(
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
LocalCache.live.deletedEventBundles.collect { newNotes ->
|
||||
Log.d("Rendering Metrics", "Update feeds: ${this@StringFeedViewModel.javaClass.simpleName} with ${newNotes.size}")
|
||||
invalidateData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
||||
Reference in New Issue
Block a user