Using a local version of RoboHash
This commit is contained in:
@@ -93,6 +93,9 @@ dependencies {
|
|||||||
// Json Serialization
|
// Json Serialization
|
||||||
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2'
|
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2'
|
||||||
|
|
||||||
|
// Robohash for Avatars
|
||||||
|
implementation group: 'com.github.vitorpamplona', name: 'android-robohash', version: 'master-SNAPSHOT', ext: 'aar'
|
||||||
|
|
||||||
// link preview
|
// link preview
|
||||||
implementation 'tw.com.oneup.www:Baha-UrlPreview:1.0.1'
|
implementation 'tw.com.oneup.www:Baha-UrlPreview:1.0.1'
|
||||||
implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha04'
|
implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha04'
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.vitorpamplona.amethyst
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.util.LruCache
|
||||||
|
import java.util.UUID
|
||||||
|
import name.neuhalfen.projects.android.robohash.RoboHash
|
||||||
|
|
||||||
|
object RoboHashCache {
|
||||||
|
|
||||||
|
lateinit var robots: RoboHash
|
||||||
|
|
||||||
|
fun get(context: Context, hash: String): Bitmap {
|
||||||
|
if (!this::robots.isInitialized) {
|
||||||
|
robots = RoboHash(context)
|
||||||
|
robots.useCache(LruCache(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
return robots.imageForHandle(robots.calculateHandleFromUUID(UUID.nameUUIDFromBytes(hash.toByteArray())))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ import coil.Coil
|
|||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.compose.rememberAsyncImagePainter
|
import coil.compose.rememberAsyncImagePainter
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.RoboHashCache
|
||||||
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource
|
||||||
@@ -82,7 +83,7 @@ fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel)
|
|||||||
val account = accountState?.account ?: return
|
val account = accountState?.account ?: return
|
||||||
|
|
||||||
val accountUserState by account.userProfile().liveMetadata.observeAsState()
|
val accountUserState by account.userProfile().liveMetadata.observeAsState()
|
||||||
val accountUser = accountUserState?.user
|
val accountUser = accountUserState?.user ?: return
|
||||||
|
|
||||||
val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() }
|
val relayViewModel: RelayPoolViewModel = viewModel { RelayPoolViewModel() }
|
||||||
val connectedRelaysLiveData by relayViewModel.connectedRelaysLiveData.observeAsState()
|
val connectedRelaysLiveData by relayViewModel.connectedRelaysLiveData.observeAsState()
|
||||||
@@ -91,6 +92,7 @@ fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel)
|
|||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
var wantsToEditRelays by remember {
|
var wantsToEditRelays by remember {
|
||||||
mutableStateOf(false)
|
mutableStateOf(false)
|
||||||
@@ -196,8 +198,10 @@ fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel)
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = accountUser?.profilePicture() ?: "https://robohash.org/ohno.png",
|
model = accountUser.profilePicture(),
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${accountUser?.pubkeyHex}.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(34.dp)
|
.width(34.dp)
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ import com.google.zxing.qrcode.encoder.ByteMatrix
|
|||||||
|
|
||||||
import androidx.compose.ui.graphics.Path
|
import androidx.compose.ui.graphics.Path
|
||||||
import androidx.compose.ui.graphics.PathFillType
|
import androidx.compose.ui.graphics.PathFillType
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import com.vitorpamplona.amethyst.RoboHashCache
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerContent(navController: NavHostController,
|
fun DrawerContent(navController: NavHostController,
|
||||||
@@ -124,6 +126,8 @@ fun ProfileContent(baseAccountUser: User, modifier: Modifier = Modifier, scaffol
|
|||||||
val accountUserFollowsState by baseAccountUser.liveFollows.observeAsState()
|
val accountUserFollowsState by baseAccountUser.liveFollows.observeAsState()
|
||||||
val accountUserFollows = accountUserFollowsState?.user ?: return
|
val accountUserFollows = accountUserFollowsState?.user ?: return
|
||||||
|
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
val banner = accountUser.info.banner
|
val banner = accountUser.info.banner
|
||||||
if (banner != null && banner.isNotBlank()) {
|
if (banner != null && banner.isNotBlank()) {
|
||||||
@@ -150,7 +154,9 @@ fun ProfileContent(baseAccountUser: User, modifier: Modifier = Modifier, scaffol
|
|||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = accountUser.profilePicture(),
|
model = accountUser.profilePicture(),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${accountUser.pubkeyHex}.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, accountUser.pubkeyHex)),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(100.dp)
|
.width(100.dp)
|
||||||
.height(100.dp)
|
.height(100.dp)
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ fun ChannelName(
|
|||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = channelPicture,
|
model = channelPicture,
|
||||||
placeholder = channelPicturePlaceholder,
|
placeholder = channelPicturePlaceholder,
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Channel Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(55.dp)
|
.width(55.dp)
|
||||||
.height(55.dp)
|
.height(55.dp)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import coil.compose.AsyncImage
|
|||||||
import coil.compose.rememberAsyncImagePainter
|
import coil.compose.rememberAsyncImagePainter
|
||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
import com.vitorpamplona.amethyst.NotificationCache
|
import com.vitorpamplona.amethyst.NotificationCache
|
||||||
|
import com.vitorpamplona.amethyst.RoboHashCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
|
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||||
@@ -151,7 +152,7 @@ fun ChatroomMessageCompose(baseNote: Note, routeForLastRead: String?, innerQuote
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
val authorState by note.author!!.liveMetadata.observeAsState()
|
val authorState by note.author!!.liveMetadata.observeAsState()
|
||||||
val author = authorState?.user
|
val author = authorState?.user!!
|
||||||
|
|
||||||
if (innerQuote || author != accountUser && note.event is ChannelMessageEvent) {
|
if (innerQuote || author != accountUser && note.event is ChannelMessageEvent) {
|
||||||
Row(
|
Row(
|
||||||
@@ -160,8 +161,10 @@ fun ChatroomMessageCompose(baseNote: Note, routeForLastRead: String?, innerQuote
|
|||||||
modifier = Modifier.padding(top = 5.dp)
|
modifier = Modifier.padding(top = 5.dp)
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = author?.profilePicture(),
|
model = author.profilePicture(),
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${author?.pubkeyHex}.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
|
error = rememberAsyncImagePainter(RoboHashCache.get(context, author.pubkeyHex)),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(25.dp)
|
.width(25.dp)
|
||||||
@@ -277,6 +280,7 @@ private fun RelayBadges(baseNote: Note) {
|
|||||||
val relaysToDisplay = if (expanded) noteRelays else noteRelays.take(3)
|
val relaysToDisplay = if (expanded) noteRelays else noteRelays.take(3)
|
||||||
|
|
||||||
val uri = LocalUriHandler.current
|
val uri = LocalUriHandler.current
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
FlowRow(Modifier.padding(start = 10.dp)) {
|
FlowRow(Modifier.padding(start = 10.dp)) {
|
||||||
relaysToDisplay.forEach {
|
relaysToDisplay.forEach {
|
||||||
@@ -284,9 +288,9 @@ private fun RelayBadges(baseNote: Note) {
|
|||||||
Box(Modifier.size(15.dp).padding(1.dp)) {
|
Box(Modifier.size(15.dp).padding(1.dp)) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = "https://${url}/favicon.ico",
|
model = "https://${url}/favicon.ico",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
fallback = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
error = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
contentDescription = "Relay Icon",
|
contentDescription = "Relay Icon",
|
||||||
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
|
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import coil.compose.rememberAsyncImagePainter
|
|||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
import com.vitorpamplona.amethyst.NotificationCache
|
import com.vitorpamplona.amethyst.NotificationCache
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.RoboHashCache
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
@@ -306,6 +307,7 @@ private fun RelayBadges(baseNote: Note) {
|
|||||||
val relaysToDisplay = if (expanded) noteRelays else noteRelays.take(3)
|
val relaysToDisplay = if (expanded) noteRelays else noteRelays.take(3)
|
||||||
|
|
||||||
val uri = LocalUriHandler.current
|
val uri = LocalUriHandler.current
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
FlowRow(Modifier.padding(top = 10.dp, start = 5.dp, end = 4.dp)) {
|
FlowRow(Modifier.padding(top = 10.dp, start = 5.dp, end = 4.dp)) {
|
||||||
relaysToDisplay.forEach {
|
relaysToDisplay.forEach {
|
||||||
@@ -313,9 +315,9 @@ private fun RelayBadges(baseNote: Note) {
|
|||||||
Box(Modifier.size(15.dp).padding(1.dp)) {
|
Box(Modifier.size(15.dp).padding(1.dp)) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = "https://${url}/favicon.ico",
|
model = "https://${url}/favicon.ico",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
fallback = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
error = rememberAsyncImagePainter("https://robohash.org/$url.png"),
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, url)),
|
||||||
contentDescription = "Relay Icon",
|
contentDescription = "Relay Icon",
|
||||||
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
|
colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -373,15 +375,16 @@ fun NoteAuthorPicture(
|
|||||||
|
|
||||||
val author = note.author
|
val author = note.author
|
||||||
|
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.width(size)
|
.width(size)
|
||||||
.height(size)) {
|
.height(size)) {
|
||||||
if (author == null) {
|
if (author == null) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = "https://robohash.org/ohno.png",
|
model = rememberAsyncImagePainter(RoboHashCache.get(ctx, "ohno")),
|
||||||
contentDescription = "Unknown Author",
|
contentDescription = "Unknown Author",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/ohno.png"),
|
|
||||||
modifier = pictureModifier
|
modifier = pictureModifier
|
||||||
.fillMaxSize(1f)
|
.fillMaxSize(1f)
|
||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
@@ -417,6 +420,8 @@ fun UserPicture(
|
|||||||
val userState by baseUser.liveMetadata.observeAsState()
|
val userState by baseUser.liveMetadata.observeAsState()
|
||||||
val user = userState?.user ?: return
|
val user = userState?.user ?: return
|
||||||
|
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.width(size)
|
.width(size)
|
||||||
@@ -425,9 +430,9 @@ fun UserPicture(
|
|||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = user.profilePicture(),
|
model = user.profilePicture(),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
fallback = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
error = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
modifier = pictureModifier
|
modifier = pictureModifier
|
||||||
.fillMaxSize(1f)
|
.fillMaxSize(1f)
|
||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@@ -34,6 +35,7 @@ import androidx.compose.ui.window.Dialog
|
|||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.compose.rememberAsyncImagePainter
|
import coil.compose.rememberAsyncImagePainter
|
||||||
|
import com.vitorpamplona.amethyst.RoboHashCache
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.qrcode.QrCodeScanner
|
import com.vitorpamplona.amethyst.ui.qrcode.QrCodeScanner
|
||||||
@@ -43,6 +45,8 @@ import nostr.postr.toNpub
|
|||||||
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
||||||
var presenting by remember { mutableStateOf(true) }
|
var presenting by remember { mutableStateOf(true) }
|
||||||
|
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
Dialog(
|
Dialog(
|
||||||
onDismissRequest = onClose,
|
onDismissRequest = onClose,
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
properties = DialogProperties(usePlatformDefaultWidth = false)
|
||||||
@@ -76,9 +80,11 @@ fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
|
|||||||
Column(modifier = Modifier.fillMaxWidth()) {
|
Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth()) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = user.profilePicture() ?: "https://robohash.org/ohno.png",
|
model = user.profilePicture(),
|
||||||
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, user.pubkeyHex)),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${user.pubkeyHex}.png"),
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(100.dp)
|
.width(100.dp)
|
||||||
.height(100.dp)
|
.height(100.dp)
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navController: NavController) {
|
fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navController: NavController) {
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
Column(modifier = Modifier.clickable(
|
Column(modifier = Modifier.clickable(
|
||||||
onClick = { navController.navigate("User/${baseUser.pubkeyHex}") }
|
onClick = { navController.navigate("User/${baseUser.pubkeyHex}") }
|
||||||
)
|
)
|
||||||
@@ -132,11 +134,13 @@ fun ChatroomHeader(baseUser: User, accountViewModel: AccountViewModel, navContro
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
|
||||||
val authorState by baseUser.liveMetadata.observeAsState()
|
val authorState by baseUser.liveMetadata.observeAsState()
|
||||||
val author = authorState?.user
|
val author = authorState?.user!!
|
||||||
|
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = author?.profilePicture(),
|
model = author.profilePicture(),
|
||||||
placeholder = rememberAsyncImagePainter("https://robohash.org/${author?.pubkeyHex}.png"),
|
placeholder = rememberAsyncImagePainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
|
fallback = rememberAsyncImagePainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
|
error = rememberAsyncImagePainter(RoboHashCache.get(ctx, author.pubkeyHex)),
|
||||||
contentDescription = "Profile Image",
|
contentDescription = "Profile Image",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(35.dp)
|
.width(35.dp)
|
||||||
|
|||||||
Reference in New Issue
Block a user