Using FlowRow to display relay icons.

This commit is contained in:
Vitor Pamplona
2023-04-20 17:19:34 -04:00
parent c40c7bc62b
commit c7a9bd1226

View File

@@ -5,8 +5,6 @@ import android.graphics.Bitmap
import android.util.Log import android.util.Log
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CutCornerShape import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
@@ -61,7 +59,6 @@ import com.vitorpamplona.amethyst.ui.theme.Following
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.math.BigDecimal import java.math.BigDecimal
import kotlin.math.ceil
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue import kotlin.time.measureTimedValue
@@ -299,7 +296,7 @@ fun NoteComposeInner(
} }
if (noteEvent is RepostEvent) { if (noteEvent is RepostEvent) {
note.replyTo?.lastOrNull()?.let { baseNote.replyTo?.lastOrNull()?.let {
RelayBadges(it) RelayBadges(it)
} }
} else { } else {
@@ -871,68 +868,102 @@ private fun LongFormHeader(noteEvent: LongTextNoteEvent, note: Note, loggedIn: U
@Composable @Composable
private fun RelayBadges(baseNote: Note) { private fun RelayBadges(baseNote: Note) {
val noteRelaysState by baseNote.live().relays.observeAsState() val noteRelaysState by baseNote.live().relays.observeAsState()
val noteRelays = noteRelaysState?.note?.relays ?: emptySet() val noteRelays = noteRelaysState?.note ?: return
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
var showShowMore by remember { mutableStateOf(false) }
var lazyRelayList by remember { mutableStateOf(emptyList<String>()) }
val relaysToDisplay = (if (expanded) noteRelays else noteRelays.take(3)).toList() LaunchedEffect(key1 = noteRelaysState, key2 = expanded) {
val height = (ceil(relaysToDisplay.size / 3.0f) * 17).dp withContext(Dispatchers.IO) {
val relayList = noteRelays.relays.map {
it.removePrefix("wss://").removePrefix("ws://")
}
val uri = LocalUriHandler.current val relaysToDisplay = if (expanded) relayList else relayList.take(3)
val shouldListChange = lazyRelayList.size < 3 || lazyRelayList.size != relayList.size
Spacer(Modifier.height(10.dp)) if (shouldListChange) {
lazyRelayList = relaysToDisplay
}
LazyVerticalGrid( val nextShowMore = relayList.size > 3 && !expanded
columns = GridCells.Fixed(3), if (nextShowMore != showShowMore) {
contentPadding = PaddingValues(start = 4.dp, end = 4.dp), // only triggers recomposition when actually different
modifier = Modifier.height(height), showShowMore = nextShowMore
userScrollEnabled = false
) {
items(relaysToDisplay.size) {
val url = relaysToDisplay[it].removePrefix("wss://").removePrefix("ws://")
Box(
Modifier
.padding(1.dp)
.size(15.dp)
) {
RobohashFallbackAsyncImage(
robot = "https://$url/favicon.ico",
robotSize = 15.dp,
model = "https://$url/favicon.ico",
contentDescription = stringResource(R.string.relay_icon),
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
modifier = Modifier
.width(13.dp)
.height(13.dp)
.clip(shape = CircleShape)
// .border(1.dp, Color.Red)
.background(MaterialTheme.colors.background)
.clickable(onClick = { uri.openUri("https://$url") })
)
} }
} }
} }
if (noteRelays.size > 3 && !expanded) { Spacer(Modifier.height(10.dp))
Row(
Modifier VerticalRelayPanelWithFlow(lazyRelayList)
.fillMaxWidth()
.height(25.dp), if (showShowMore) {
horizontalArrangement = Arrangement.Center, ShowMoreRelaysButton {
verticalAlignment = Alignment.Top expanded = true
}
}
}
@Composable
@Stable
private fun VerticalRelayPanelWithFlow(
relays: List<String>
) {
// FlowRow Seems to be a lot faster than LazyVerticalGrid
FlowRow() {
relays.forEach { url ->
RelayIconCompose(url)
}
}
}
@Composable
@Stable
private fun RelayIconCompose(url: String) {
val uri = LocalUriHandler.current
Box(
Modifier
.padding(1.dp)
.size(15.dp)
) {
RobohashFallbackAsyncImage(
robot = "https://$url/favicon.ico",
robotSize = 15.dp,
model = "https://$url/favicon.ico",
contentDescription = stringResource(R.string.relay_icon),
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
modifier = Modifier
.width(13.dp)
.height(13.dp)
.clip(shape = CircleShape)
.background(MaterialTheme.colors.background)
.clickable(onClick = { uri.openUri("https://$url") })
)
}
}
@Composable
private fun ShowMoreRelaysButton(onClick: () -> Unit) {
Row(
Modifier
.fillMaxWidth()
.height(25.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.Top
) {
IconButton(
modifier = Modifier.then(Modifier.size(24.dp)),
onClick = onClick
) { ) {
IconButton( Icon(
modifier = Modifier.then(Modifier.size(24.dp)), imageVector = Icons.Default.ExpandMore,
onClick = { expanded = true } null,
) { modifier = Modifier.size(15.dp),
Icon( tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
imageVector = Icons.Default.ExpandMore, )
null,
modifier = Modifier.size(15.dp),
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
)
}
} }
} }
} }