@@ -6,15 +6,17 @@ import androidx.compose.animation.fadeIn
66import androidx.compose.animation.fadeOut
77import androidx.compose.animation.shrinkVertically
88import androidx.compose.foundation.background
9+ import androidx.compose.foundation.border
910import androidx.compose.foundation.clickable
1011import androidx.compose.foundation.layout.Arrangement
1112import androidx.compose.foundation.layout.Box
1213import androidx.compose.foundation.layout.Column
1314import androidx.compose.foundation.layout.Row
14- import androidx.compose.foundation.layout.Spacer
1515import androidx.compose.foundation.layout.fillMaxWidth
1616import androidx.compose.foundation.layout.height
1717import androidx.compose.foundation.layout.padding
18+ import androidx.compose.foundation.layout.size
19+ import androidx.compose.foundation.shape.CircleShape
1820import androidx.compose.material3.ExperimentalMaterial3Api
1921import androidx.compose.material3.SnackbarDuration
2022import androidx.compose.material3.SnackbarHostState
@@ -54,6 +56,7 @@ import net.primal.android.core.compose.AvatarOverlap
5456import net.primal.android.core.compose.AvatarThumbnailsRow
5557import net.primal.android.core.compose.IconText
5658import net.primal.android.core.compose.NostrUserText
59+ import net.primal.android.core.compose.PulsingListItemPlaceholder
5760import net.primal.android.core.compose.preview.PrimalPreview
5861import net.primal.android.core.compose.profile.model.ProfileDetailsUi
5962import net.primal.android.core.compose.profile.model.ProfileStatsUi
@@ -259,11 +262,8 @@ private fun ProfileHeaderDetails(
259262 onProfileClick = onProfileClick,
260263 )
261264 } else {
262- Spacer (
263- modifier = Modifier
264- .padding(vertical = 8 .dp)
265- .fillMaxWidth()
266- .height(36 .dp),
265+ UserFollowedByIndicatorPlaceholder (
266+ modifier = Modifier .padding(horizontal = 14 .dp, vertical = 8 .dp),
267267 )
268268 }
269269 }
@@ -291,7 +291,7 @@ private fun UserFollowedByIndicator(
291291 avatarOverlap = AvatarOverlap .Start ,
292292 avatarBorderSize = 1 .dp,
293293 avatarSize = 36 .dp,
294- maxAvatarsToShow = 5 ,
294+ maxAvatarsToShow = FOLLOWED_BY_AVATAR_COUNT ,
295295 displayAvatarOverflowIndicator = false ,
296296 )
297297 val text =
@@ -306,6 +306,51 @@ private fun UserFollowedByIndicator(
306306 }
307307}
308308
309+ @Composable
310+ private fun UserFollowedByIndicatorPlaceholder (modifier : Modifier = Modifier ) {
311+ Row (
312+ horizontalArrangement = Arrangement .spacedBy(8 .dp),
313+ verticalAlignment = Alignment .CenterVertically ,
314+ modifier = modifier,
315+ ) {
316+ val avatarSize = 36 .dp
317+ val avatarSpacing = avatarSize * (1f - FOLLOWED_BY_AVATAR_OVERLAP )
318+ Box (
319+ modifier = Modifier .size(
320+ width = avatarSpacing * (FOLLOWED_BY_AVATAR_COUNT - 1 ) + avatarSize,
321+ height = avatarSize,
322+ ),
323+ ) {
324+ for (index in FOLLOWED_BY_AVATAR_COUNT - 1 downTo 0 ) {
325+ Box (
326+ modifier = Modifier
327+ .padding(start = avatarSpacing * index)
328+ .size(avatarSize)
329+ .border(
330+ width = 1 .dp,
331+ color = AppTheme .colorScheme.background,
332+ shape = CircleShape ,
333+ ),
334+ ) {
335+ PulsingListItemPlaceholder (
336+ height = avatarSize,
337+ width = avatarSize,
338+ shape = CircleShape ,
339+ )
340+ }
341+ }
342+ }
343+ PulsingListItemPlaceholder (
344+ modifier = Modifier .weight(1f ),
345+ height = 32 .dp,
346+ shape = AppTheme .shapes.small,
347+ )
348+ }
349+ }
350+
351+ private const val FOLLOWED_BY_AVATAR_COUNT = 5
352+ private const val FOLLOWED_BY_AVATAR_OVERLAP = 0.25f
353+
309354@Composable
310355private fun ProfileFollowIndicators (
311356 modifier : Modifier = Modifier ,
0 commit comments