Restructures Stable elements for minor performance gains.

This commit is contained in:
Vitor Pamplona
2023-06-18 18:57:02 -04:00
parent a3efd15b95
commit be8848fb1b
5 changed files with 121 additions and 102 deletions
@@ -13,8 +13,6 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
class Nip05Verifier() { class Nip05Verifier() {
val client = HttpClient.getHttpClient()
fun assembleUrl(nip05address: String): String? { fun assembleUrl(nip05address: String): String? {
val parts = nip05address.trim().split("@") val parts = nip05address.trim().split("@")
@@ -49,7 +47,7 @@ class Nip05Verifier() {
.url(url) .url(url)
.build() .build()
client.newCall(request).enqueue(object : Callback { HttpClient.getHttpClient().newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
response.use { response.use {
if (it.isSuccessful) { if (it.isSuccessful) {
@@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.components package com.vitorpamplona.amethyst.ui.components
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.checkNotInMainThread
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -15,6 +16,7 @@ import java.util.concurrent.atomic.AtomicBoolean
/** /**
* This class is designed to have a waiting time between two calls of invalidate * This class is designed to have a waiting time between two calls of invalidate
*/ */
@Stable
class BundledUpdate( class BundledUpdate(
val delay: Long, val delay: Long,
val dispatcher: CoroutineDispatcher = Dispatchers.Default val dispatcher: CoroutineDispatcher = Dispatchers.Default
@@ -51,6 +53,7 @@ class BundledUpdate(
/** /**
* This class is designed to have a waiting time between two calls of invalidate * This class is designed to have a waiting time between two calls of invalidate
*/ */
@Stable
class BundledInsert<T>( class BundledInsert<T>(
val delay: Long, val delay: Long,
val dispatcher: CoroutineDispatcher = Dispatchers.Default val dispatcher: CoroutineDispatcher = Dispatchers.Default
@@ -222,7 +222,15 @@ fun RenderZapGallery(
nav: (String) -> Unit, nav: (String) -> Unit,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
Row(remember { Modifier.fillMaxWidth() }) { Row(Modifier.fillMaxWidth()) {
ZapIcon()
AuthorGalleryZaps(zapEvents, backgroundColor, nav, accountViewModel)
}
}
@Composable
private fun ZapIcon() {
Box( Box(
modifier = remember { modifier = remember {
Modifier Modifier
@@ -241,9 +249,6 @@ fun RenderZapGallery(
} }
) )
} }
AuthorGalleryZaps(zapEvents, backgroundColor, nav, accountViewModel)
}
} }
@Composable @Composable
@@ -313,7 +318,7 @@ private fun AuthorPictureAndComment(
nav: (String) -> Unit, nav: (String) -> Unit,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
var content by remember { val content = remember {
mutableStateOf( mutableStateOf(
ZapAmountCommentNotification( ZapAmountCommentNotification(
user = zapRequest.author, user = zapRequest.author,
@@ -330,28 +335,24 @@ private fun AuthorPictureAndComment(
val amount = (zapEvent?.event as? LnZapEvent)?.amount val amount = (zapEvent?.event as? LnZapEvent)?.amount
if (decryptedContent != null) { if (decryptedContent != null) {
val newAuthor = LocalCache.getOrCreateUser(decryptedContent.pubKey) val newAuthor = LocalCache.getOrCreateUser(decryptedContent.pubKey)
content = ZapAmountCommentNotification(newAuthor, decryptedContent.content.ifBlank { null }, showAmountAxis(amount)) content.value = ZapAmountCommentNotification(newAuthor, decryptedContent.content.ifBlank { null }, showAmountAxis(amount))
} else { } else {
if (!zapRequest.event?.content().isNullOrBlank() || amount != null) { if (!zapRequest.event?.content().isNullOrBlank() || amount != null) {
content = ZapAmountCommentNotification(zapRequest.author, zapRequest.event?.content()?.ifBlank { null }, showAmountAxis(amount)) content.value = ZapAmountCommentNotification(zapRequest.author, zapRequest.event?.content()?.ifBlank { null }, showAmountAxis(amount))
} }
} }
} }
} }
} }
val route by remember { Row(
derivedStateOf { modifier = Modifier.clickable {
"User/${content.user?.pubkeyHex}" nav("User/${content.value.user?.pubkeyHex}")
} },
} verticalAlignment = Alignment.CenterVertically
) {
content.user?.let { user ->
AuthorPictureAndComment( AuthorPictureAndComment(
author = user, authorComment = content,
comment = content.comment,
amount = content.amount,
route = route,
backgroundColor = backgroundColor, backgroundColor = backgroundColor,
nav = nav, nav = nav,
accountViewModel = accountViewModel accountViewModel = accountViewModel
@@ -375,33 +376,34 @@ val commentTextSize = 12.sp
@Composable @Composable
private fun AuthorPictureAndComment( private fun AuthorPictureAndComment(
author: User, authorComment: MutableState<ZapAmountCommentNotification>,
comment: String?,
amount: String?,
route: String,
backgroundColor: MutableState<Color>, backgroundColor: MutableState<Color>,
nav: (String) -> Unit, nav: (String) -> Unit,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
val modifier = remember { Box(modifier = sizedModifier, contentAlignment = Alignment.BottomCenter) {
Modifier.clickable { DisplayPicture(authorComment, accountViewModel)
nav(route) DisplayAmount(authorComment)
}
} }
Row( DisplayComment(authorComment, backgroundColor, nav, accountViewModel)
modifier = modifier, }
verticalAlignment = Alignment.CenterVertically
) { @Composable
Box(modifier = sizedModifier, contentAlignment = Alignment.BottomCenter) { fun DisplayPicture(authorComment: MutableState<ZapAmountCommentNotification>, accountViewModel: AccountViewModel) {
authorComment.value.user?.let {
FastNoteAuthorPicture( FastNoteAuthorPicture(
author = author, author = it,
size = Size35dp, size = Size35dp,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
pictureModifier = simpleModifier pictureModifier = simpleModifier
) )
}
}
amount?.let { @Composable
fun DisplayAmount(authorComment: MutableState<ZapAmountCommentNotification>) {
authorComment.value.amount?.let {
Box( Box(
modifier = amountBoxModifier, modifier = amountBoxModifier,
contentAlignment = Alignment.BottomCenter contentAlignment = Alignment.BottomCenter
@@ -427,7 +429,14 @@ private fun AuthorPictureAndComment(
} }
} }
comment?.let { @Composable
fun DisplayComment(
authorComment: MutableState<ZapAmountCommentNotification>,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
authorComment.value.comment?.let {
TranslatableRichTextViewer( TranslatableRichTextViewer(
content = it, content = it,
canPreview = true, canPreview = true,
@@ -439,7 +448,6 @@ private fun AuthorPictureAndComment(
) )
} }
} }
}
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
@@ -477,21 +485,30 @@ private fun NotePictureAndComment(
nav: (String) -> Unit, nav: (String) -> Unit,
accountViewModel: AccountViewModel accountViewModel: AccountViewModel
) { ) {
val author by remember(baseNote) { val author = remember(baseNote) {
derivedStateOf { mutableStateOf(
baseNote.author ZapAmountCommentNotification(
user = baseNote.author,
comment = null,
amount = null
)
)
}
val modifier = remember(baseNote) {
Modifier.clickable {
nav("User/${baseNote.author?.pubkeyHex}")
} }
} }
val route by remember(baseNote) { Row(
derivedStateOf { modifier = modifier,
"User/${baseNote.author?.pubkeyHex}" verticalAlignment = Alignment.CenterVertically
) {
AuthorPictureAndComment(authorComment = author, backgroundColor, nav, accountViewModel)
} }
} }
author?.let { AuthorPictureAndComment(it, null, null, route, backgroundColor, nav, accountViewModel) }
}
@Composable @Composable
fun FastNoteAuthorPicture( fun FastNoteAuthorPicture(
author: User, author: User,
@@ -2706,9 +2706,7 @@ private fun VerticalRelayPanelWithFlow(
val showMoreRelaysButtonIconButtonModifier = Modifier.size(24.dp) val showMoreRelaysButtonIconButtonModifier = Modifier.size(24.dp)
val showMoreRelaysButtonIconModifier = Modifier.size(15.dp) val showMoreRelaysButtonIconModifier = Modifier.size(15.dp)
val showMoreRelaysButtonBoxModifer = Modifier val showMoreRelaysButtonBoxModifer = Modifier.fillMaxWidth().height(25.dp)
.fillMaxWidth()
.height(25.dp)
@Composable @Composable
private fun ShowMoreRelaysButton(onClick: () -> Unit) { private fun ShowMoreRelaysButton(onClick: () -> Unit) {
@@ -2879,7 +2877,7 @@ fun UserPicture(
@Composable @Composable
private fun ObserveAndDisplayFollowingMark(userHex: String, iconSize: Dp, accountViewModel: AccountViewModel) { private fun ObserveAndDisplayFollowingMark(userHex: String, iconSize: Dp, accountViewModel: AccountViewModel) {
val accountFollowsState by accountViewModel.account.userProfile().live().follows.observeAsState() val accountFollowsState by accountViewModel.userFollows.observeAsState()
var showFollowingMark by remember { mutableStateOf(false) } var showFollowingMark by remember { mutableStateOf(false) }
@@ -15,6 +15,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AccountState import com.vitorpamplona.amethyst.model.AccountState
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.model.UserState
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.model.Event
import com.vitorpamplona.amethyst.service.model.LnZapEvent import com.vitorpamplona.amethyst.service.model.LnZapEvent
@@ -32,6 +33,8 @@ class AccountViewModel(val account: Account) : ViewModel() {
val accountLanguagesLiveData: LiveData<AccountState> = account.liveLanguages.map { it } val accountLanguagesLiveData: LiveData<AccountState> = account.liveLanguages.map { it }
val accountLastReadLiveData: LiveData<AccountState> = account.liveLastRead.map { it } val accountLastReadLiveData: LiveData<AccountState> = account.liveLastRead.map { it }
val userFollows: LiveData<UserState> = account.userProfile().live().follows.map { it }
fun isWriteable(): Boolean { fun isWriteable(): Boolean {
return account.isWriteable() return account.isWriteable()
} }