mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 19:28:25 +00:00
Merge pull request #3994 from greenart7c3/fix/deleted-list-uuid-in-top-bar
fix(lists): stop deleted lists showing their UUID in the feed filter picker
This commit is contained in:
@@ -788,6 +788,62 @@ class AccountSettings(
|
|||||||
// list names
|
// list names
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All per-screen persisted feed filters paired with their factory default.
|
||||||
|
* Deleting a list (NIP-51 people list / follow pack) must reset any screen whose
|
||||||
|
* filter still points at the deleted address — otherwise the screen keeps a
|
||||||
|
* dangling [TopFilter.PeopleList] that re-creates an empty AddressableNote shell
|
||||||
|
* on every start and shows the list's dTag/UUID in the top bar instead of a name.
|
||||||
|
*/
|
||||||
|
private val feedFiltersWithDefaults: List<Pair<MutableStateFlow<TopFilter>, TopFilter>> =
|
||||||
|
listOf(
|
||||||
|
defaultHomeFollowList to TopFilter.AllFollows,
|
||||||
|
defaultStoriesFollowList to TopFilter.Global,
|
||||||
|
defaultNotificationFollowList to TopFilter.Selected,
|
||||||
|
defaultDiscoveryFollowList to TopFilter.Global,
|
||||||
|
defaultPollsFollowList to TopFilter.Global,
|
||||||
|
defaultPicturesFollowList to TopFilter.Global,
|
||||||
|
defaultNappletsFollowList to TopFilter.Global,
|
||||||
|
defaultNsitesFollowList to TopFilter.Global,
|
||||||
|
defaultWorkoutsFollowList to TopFilter.Global,
|
||||||
|
defaultGitRepositoriesFollowList to TopFilter.Global,
|
||||||
|
defaultHighlightsFollowList to TopFilter.Global,
|
||||||
|
defaultCalendarsFollowList to TopFilter.Global,
|
||||||
|
defaultProductsFollowList to TopFilter.AroundMe,
|
||||||
|
defaultShortsFollowList to TopFilter.Global,
|
||||||
|
defaultPublicChatsFollowList to TopFilter.Global,
|
||||||
|
defaultLiveStreamsFollowList to TopFilter.Global,
|
||||||
|
defaultNestsFollowList to TopFilter.Global,
|
||||||
|
defaultLongsFollowList to TopFilter.Global,
|
||||||
|
defaultArticlesFollowList to TopFilter.AllFollows,
|
||||||
|
defaultMusicTracksFollowList to TopFilter.Global,
|
||||||
|
defaultMusicPlaylistsFollowList to TopFilter.Global,
|
||||||
|
defaultPodcastEpisodesFollowList to TopFilter.Global,
|
||||||
|
defaultPodcastsFollowList to TopFilter.Global,
|
||||||
|
defaultSoftwareAppsFollowList to TopFilter.Global,
|
||||||
|
defaultBadgesFollowList to TopFilter.Mine,
|
||||||
|
defaultBrowseEmojiSetsFollowList to TopFilter.Global,
|
||||||
|
defaultCommunitiesFollowList to TopFilter.AllFollows,
|
||||||
|
defaultFollowPacksFollowList to TopFilter.Global,
|
||||||
|
defaultAppRecommendationsFollowList to TopFilter.Global,
|
||||||
|
defaultRelayGroupsDiscoveryFollowList to TopFilter.Mine,
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Resets every persisted feed filter that points at the deleted list's address. */
|
||||||
|
fun resetFeedFiltersPointingTo(address: Address) {
|
||||||
|
var changed = false
|
||||||
|
|
||||||
|
feedFiltersWithDefaults.forEach { (flow, default) ->
|
||||||
|
val current = flow.value
|
||||||
|
if (current is TopFilter.AddressableTopFilter && current.address == address) {
|
||||||
|
flow.tryEmit(default)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) saveAccountSettings()
|
||||||
|
}
|
||||||
|
|
||||||
fun changeDefaultHomeFollowList(name: FeedDefinition) {
|
fun changeDefaultHomeFollowList(name: FeedDefinition) {
|
||||||
changeDefaultHomeFollowList(name.code)
|
changeDefaultHomeFollowList(name.code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -825,6 +825,12 @@ object LocalCache : ILocalCache, ICacheProvider, Dao {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a kind-5 event from the addressable's own author has deleted this
|
||||||
|
* address. Works for empty addressable shells whose event is not loaded yet.
|
||||||
|
*/
|
||||||
|
fun hasBeenDeleted(address: Address): Boolean = deletionIndex.hasBeenDeleted(address, address.pubKeyHex)
|
||||||
|
|
||||||
fun getOrAddAliasNote(
|
fun getOrAddAliasNote(
|
||||||
idHex: String,
|
idHex: String,
|
||||||
note: Note,
|
note: Note,
|
||||||
|
|||||||
+13
-1
@@ -71,7 +71,15 @@ class FollowListsState(
|
|||||||
) {
|
) {
|
||||||
val user = cache.getOrCreateUser(signer.pubKey)
|
val user = cache.getOrCreateUser(signer.pubKey)
|
||||||
|
|
||||||
fun existingPeopleListNotes() = cache.addressables.filter(FollowListEvent.KIND, user.pubkeyHex)
|
// Hides shells that a kind-5 deletion event from the list's author has already
|
||||||
|
// deleted (e.g. a persisted TopFilter re-creates an empty shell for the deleted
|
||||||
|
// address after a restart, and its name falls back to the dTag/UUID). Shells that
|
||||||
|
// are merely not loaded yet stay in the list so the UI can subscribe and fetch
|
||||||
|
// them from relays.
|
||||||
|
fun existingPeopleListNotes() =
|
||||||
|
cache.addressables
|
||||||
|
.filter(FollowListEvent.KIND, user.pubkeyHex)
|
||||||
|
.filter { it.event != null || !cache.hasBeenDeleted(it.address) }
|
||||||
|
|
||||||
val followListVersions = MutableStateFlow(0)
|
val followListVersions = MutableStateFlow(0)
|
||||||
|
|
||||||
@@ -255,6 +263,10 @@ class FollowListsState(
|
|||||||
val followListEvent = getPeopleList(identifierTag)
|
val followListEvent = getPeopleList(identifierTag)
|
||||||
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
||||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||||
|
// Any screen whose persisted feed filter still points at this follow pack would
|
||||||
|
// keep re-creating an empty shell for its address (and render the dTag/UUID in
|
||||||
|
// the top bar) — reset those filters to their default.
|
||||||
|
account.settings.resetFeedFiltersPointingTo(followListEvent.address())
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun addUserToSet(
|
suspend fun addUserToSet(
|
||||||
|
|||||||
+11
@@ -69,10 +69,17 @@ class PeopleListsState(
|
|||||||
) {
|
) {
|
||||||
val user = cache.getOrCreateUser(signer.pubKey)
|
val user = cache.getOrCreateUser(signer.pubKey)
|
||||||
|
|
||||||
|
// Hides the fixed-dTag block-list shell when it is not loaded (it has no
|
||||||
|
// meaningful name until it exists) and shells that a kind-5 deletion event from
|
||||||
|
// the list's author has already deleted (e.g. a persisted TopFilter re-creates an
|
||||||
|
// empty shell for the deleted address after a restart, and its name falls back to
|
||||||
|
// the dTag/UUID). Shells that are merely not loaded yet stay in the list so the UI
|
||||||
|
// can subscribe and fetch them from relays.
|
||||||
fun existingPeopleListNotes() =
|
fun existingPeopleListNotes() =
|
||||||
cache.addressables
|
cache.addressables
|
||||||
.filter(PeopleListEvent.KIND, user.pubkeyHex)
|
.filter(PeopleListEvent.KIND, user.pubkeyHex)
|
||||||
.filter { it.dTag() != PeopleListEvent.BLOCK_LIST_D_TAG || it.event != null }
|
.filter { it.dTag() != PeopleListEvent.BLOCK_LIST_D_TAG || it.event != null }
|
||||||
|
.filter { it.event != null || !cache.hasBeenDeleted(it.address) }
|
||||||
|
|
||||||
val peopleListVersions = MutableStateFlow(0)
|
val peopleListVersions = MutableStateFlow(0)
|
||||||
|
|
||||||
@@ -262,6 +269,10 @@ class PeopleListsState(
|
|||||||
val followListEvent = getPeopleList(identifierTag)
|
val followListEvent = getPeopleList(identifierTag)
|
||||||
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
val deletionEvent = account.signer.sign(DeletionEvent.build(listOf(followListEvent)))
|
||||||
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
account.sendMyPublicAndPrivateOutbox(deletionEvent)
|
||||||
|
// Any screen whose persisted feed filter still points at this list would keep
|
||||||
|
// re-creating an empty shell for its address (and render the dTag/UUID in the
|
||||||
|
// top bar) — reset those filters to their default.
|
||||||
|
account.settings.resetFeedFiltersPointingTo(followListEvent.address())
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun addUserToSet(
|
suspend fun addUserToSet(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip09Deletions
|
package com.vitorpamplona.quartz.nip09Deletions
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
@@ -115,6 +116,18 @@ class DeletionIndex {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a kind-5 event signed by [pubKey] deleted the addressable at [address].
|
||||||
|
* Used when the addressable's event is not loaded yet (e.g. an empty shell
|
||||||
|
* re-created after a restart), so there is no event id or createdAt to compare
|
||||||
|
* against. A re-published version would arrive as a loaded event and is checked
|
||||||
|
* by [hasBeenDeleted] instead.
|
||||||
|
*/
|
||||||
|
fun hasBeenDeleted(
|
||||||
|
address: Address,
|
||||||
|
pubKey: HexKey,
|
||||||
|
): Boolean = hasBeenDeleted(DeletionRequest(address.toValue(), pubKey))
|
||||||
|
|
||||||
private fun hasBeenDeleted(key: DeletionRequest) = deletedReferencesBefore.containsKey(key)
|
private fun hasBeenDeleted(key: DeletionRequest) = deletedReferencesBefore.containsKey(key)
|
||||||
|
|
||||||
private fun hasBeenDeleted(
|
private fun hasBeenDeleted(
|
||||||
|
|||||||
Reference in New Issue
Block a user