Migrates Desktop App to the new metadata cache.
This commit is contained in:
+3
-3
@@ -54,7 +54,7 @@ class ThreadAssembler(
|
|||||||
// Check to see if there is an error in the tag and the root has replies
|
// Check to see if there is an error in the tag and the root has replies
|
||||||
val rootNote = cache.getNoteIfExists(markedAsRoot) as? Note
|
val rootNote = cache.getNoteIfExists(markedAsRoot) as? Note
|
||||||
if (rootNote?.replyTo?.isEmpty() == true) {
|
if (rootNote?.replyTo?.isEmpty() == true) {
|
||||||
return cache.checkGetOrCreateNote(markedAsRoot) as? Note
|
return cache.checkGetOrCreateNote(markedAsRoot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ class ThreadAssembler(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun findRoot(noteId: String): Note? {
|
fun findRoot(noteId: String): Note? {
|
||||||
val note = cache.checkGetOrCreateNote(noteId) as? Note ?: return null
|
val note = cache.checkGetOrCreateNote(noteId) ?: return null
|
||||||
|
|
||||||
return if (note.event != null) {
|
return if (note.event != null) {
|
||||||
val thread = OnlyLatestVersionSet()
|
val thread = OnlyLatestVersionSet()
|
||||||
@@ -102,7 +102,7 @@ class ThreadAssembler(
|
|||||||
fun findThreadFor(noteId: String): ThreadInfo? {
|
fun findThreadFor(noteId: String): ThreadInfo? {
|
||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
|
|
||||||
val note = cache.checkGetOrCreateNote(noteId) as? Note ?: return null
|
val note = cache.checkGetOrCreateNote(noteId) ?: return null
|
||||||
|
|
||||||
return if (note.event != null) {
|
return if (note.event != null) {
|
||||||
val thread = OnlyLatestVersionSet()
|
val thread = OnlyLatestVersionSet()
|
||||||
|
|||||||
+12
-4
@@ -41,7 +41,11 @@ class MetadataPreloader(
|
|||||||
*/
|
*/
|
||||||
fun preloadForUsers(users: Collection<User>) {
|
fun preloadForUsers(users: Collection<User>) {
|
||||||
users.forEach { user ->
|
users.forEach { user ->
|
||||||
val metadata = user.info
|
val metadata =
|
||||||
|
user
|
||||||
|
.metadata()
|
||||||
|
.flow.value
|
||||||
|
?.info
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
// Already have metadata, prefetch avatar
|
// Already have metadata, prefetch avatar
|
||||||
metadata.picture?.let { avatarUrl ->
|
metadata.picture?.let { avatarUrl ->
|
||||||
@@ -58,7 +62,11 @@ class MetadataPreloader(
|
|||||||
* Queue a single user for metadata preloading.
|
* Queue a single user for metadata preloading.
|
||||||
*/
|
*/
|
||||||
fun preloadForUser(user: User) {
|
fun preloadForUser(user: User) {
|
||||||
val metadata = user.info
|
val metadata =
|
||||||
|
user
|
||||||
|
.metadata()
|
||||||
|
.flow.value
|
||||||
|
?.info
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
metadata.picture?.let { avatarUrl ->
|
metadata.picture?.let { avatarUrl ->
|
||||||
imagePrefetcher?.prefetch(avatarUrl)
|
imagePrefetcher?.prefetch(avatarUrl)
|
||||||
@@ -73,7 +81,7 @@ class MetadataPreloader(
|
|||||||
* Triggers avatar image prefetch.
|
* Triggers avatar image prefetch.
|
||||||
*/
|
*/
|
||||||
fun onMetadataReceived(user: User) {
|
fun onMetadataReceived(user: User) {
|
||||||
user.info?.picture?.let { avatarUrl ->
|
user.metadata().flow.value?.info?.picture?.let { avatarUrl ->
|
||||||
imagePrefetcher?.prefetch(avatarUrl)
|
imagePrefetcher?.prefetch(avatarUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +91,7 @@ class MetadataPreloader(
|
|||||||
*/
|
*/
|
||||||
fun prefetchAvatars(users: Collection<User>) {
|
fun prefetchAvatars(users: Collection<User>) {
|
||||||
users.forEach { user ->
|
users.forEach { user ->
|
||||||
user.info?.picture?.let { avatarUrl ->
|
user.metadata().flow.value?.info?.picture?.let { avatarUrl ->
|
||||||
imagePrefetcher?.prefetch(avatarUrl)
|
imagePrefetcher?.prefetch(avatarUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+5
-5
@@ -107,11 +107,11 @@ class DesktopLocalCache : ICacheProvider {
|
|||||||
fun consumeMetadata(event: MetadataEvent) {
|
fun consumeMetadata(event: MetadataEvent) {
|
||||||
val user = getOrCreateUser(event.pubKey)
|
val user = getOrCreateUser(event.pubKey)
|
||||||
|
|
||||||
// Only update if newer
|
if (user.metadata().shouldUpdateWith(event)) {
|
||||||
val currentMetadata = user.latestMetadata
|
val newUserMetadata = event.contactMetaData()
|
||||||
if (currentMetadata == null || event.createdAt > currentMetadata.createdAt) {
|
if (newUserMetadata != null) {
|
||||||
user.latestMetadata = event
|
user.updateUserInfo(newUserMetadata, event, null)
|
||||||
user.info = event.contactMetaData()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -333,7 +333,11 @@ fun FeedScreen(
|
|||||||
// Only fetch metadata for users we don't have yet
|
// Only fetch metadata for users we don't have yet
|
||||||
val missingPubkeys =
|
val missingPubkeys =
|
||||||
zapSenderPubkeys.filter { pubkey ->
|
zapSenderPubkeys.filter { pubkey ->
|
||||||
localCache.getUserIfExists(pubkey)?.info == null
|
localCache
|
||||||
|
.getUserIfExists(pubkey)
|
||||||
|
?.metadataOrNull()
|
||||||
|
?.flow
|
||||||
|
?.value == null
|
||||||
}
|
}
|
||||||
if (missingPubkeys.isEmpty()) {
|
if (missingPubkeys.isEmpty()) {
|
||||||
return@rememberSubscription null
|
return@rememberSubscription null
|
||||||
@@ -449,7 +453,11 @@ fun FeedScreen(
|
|||||||
// Only fetch metadata for users we don't have yet
|
// Only fetch metadata for users we don't have yet
|
||||||
val missingPubkeys =
|
val missingPubkeys =
|
||||||
authorPubkeys.filter { pubkey ->
|
authorPubkeys.filter { pubkey ->
|
||||||
localCache.getUserIfExists(pubkey)?.info == null
|
localCache
|
||||||
|
.getUserIfExists(pubkey)
|
||||||
|
?.metadataOrNull()
|
||||||
|
?.flow
|
||||||
|
?.value == null
|
||||||
}
|
}
|
||||||
if (missingPubkeys.isEmpty()) {
|
if (missingPubkeys.isEmpty()) {
|
||||||
return@rememberSubscription null
|
return@rememberSubscription null
|
||||||
|
|||||||
@@ -70,14 +70,12 @@ import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache
|
|||||||
import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
|
import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager
|
||||||
import com.vitorpamplona.amethyst.desktop.nwc.NwcPaymentHandler
|
import com.vitorpamplona.amethyst.desktop.nwc.NwcPaymentHandler
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArrayOrNull
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
|
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NNote
|
import com.vitorpamplona.quartz.nip19Bech32.entities.NNote
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
|
||||||
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
|
||||||
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
@@ -149,12 +147,8 @@ fun getDisplayName(
|
|||||||
pubKey: String,
|
pubKey: String,
|
||||||
localCache: DesktopLocalCache,
|
localCache: DesktopLocalCache,
|
||||||
): String {
|
): String {
|
||||||
val user = localCache.getUserIfExists(pubKey)
|
val user = localCache.getUserIfExists(pubKey) ?: return pubKey.take(12)
|
||||||
return user?.info?.bestName()
|
return user.toBestDisplayName()
|
||||||
?: pubKey.hexToByteArrayOrNull()?.toNpub()?.let { npub ->
|
|
||||||
npub.take(12) + "..." + npub.takeLast(6)
|
|
||||||
}
|
|
||||||
?: pubKey.take(12) + "..."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -308,7 +302,7 @@ fun ZapReceiptsDialog(
|
|||||||
.distinct()
|
.distinct()
|
||||||
.filter { pubKey ->
|
.filter { pubKey ->
|
||||||
val user = localCache.getUserIfExists(pubKey)
|
val user = localCache.getUserIfExists(pubKey)
|
||||||
user?.info == null
|
user?.metadataOrNull()?.flow?.value == null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pubKeysNeedingMetadata.isNotEmpty()) {
|
if (pubKeysNeedingMetadata.isNotEmpty()) {
|
||||||
@@ -925,7 +919,7 @@ private suspend fun zapNote(
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
// Get author's lightning address from cache
|
// Get author's lightning address from cache
|
||||||
var user = localCache.getUserIfExists(event.pubKey)
|
var user = localCache.getUserIfExists(event.pubKey)
|
||||||
var lnAddress = user?.info?.lud16 ?: user?.info?.lud06
|
var lnAddress = user?.lnAddress()
|
||||||
|
|
||||||
// TODO: Use UserFinderFilterAssemblerSubscription pattern from Amethyst
|
// TODO: Use UserFinderFilterAssemblerSubscription pattern from Amethyst
|
||||||
// to proactively load metadata when zap button is displayed.
|
// to proactively load metadata when zap button is displayed.
|
||||||
@@ -1068,7 +1062,7 @@ private suspend fun fetchUserLightningAddress(
|
|||||||
if (event is MetadataEvent && !resumed) {
|
if (event is MetadataEvent && !resumed) {
|
||||||
localCache.consumeMetadata(event)
|
localCache.consumeMetadata(event)
|
||||||
val user = localCache.getUserIfExists(pubKey)
|
val user = localCache.getUserIfExists(pubKey)
|
||||||
val lnAddress = user?.info?.lud16 ?: user?.info?.lud06
|
val lnAddress = user?.lnAddress()
|
||||||
if (lnAddress != null && !resumed) {
|
if (lnAddress != null && !resumed) {
|
||||||
resumed = true
|
resumed = true
|
||||||
timeoutJob.cancel()
|
timeoutJob.cancel()
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ fun LongFormCard(
|
|||||||
onAuthorClick: (String) -> Unit = {},
|
onAuthorClick: (String) -> Unit = {},
|
||||||
onClick: () -> Unit = {},
|
onClick: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val author = localCache.getUserIfExists(event.pubKey)
|
val author = localCache.getOrCreateUser(event.pubKey)
|
||||||
val authorName = author?.info?.bestName() ?: event.pubKey.take(8)
|
val authorName = author.toBestDisplayName()
|
||||||
val publishedAt = event.publishedAt() ?: event.createdAt
|
val publishedAt = event.publishedAt() ?: event.createdAt
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
|
|||||||
Reference in New Issue
Block a user