A cheap attempt at a native Bluesky client for Android

Notifications: Stack and label avatar lists

- Reverse the order of avatars in the like/repost notification row so they stack correctly, with the front-most avatar on the right.
- Move the "liked/reposted this" text to be below the avatar stack, so that it gets hidden when the avatar stack is shown

+71 -67
+71 -67
app/src/main/java/industries/geesawra/monarch/LikeRepostRowView.kt
··· 82 82 .animateContentSize() 83 83 ) { 84 84 85 + val authors = data.authors 86 + val firstAuthor = authors.first() 87 + val firstAuthorName = name(firstAuthor.author) 88 + val remainingCount = authors.size - 1 89 + val reasonLine = when { 90 + remainingCount > 1 -> "$firstAuthorName and $remainingCount others ${ 91 + when (data.kind) { 92 + RepeatableNotification.Like -> "liked" 93 + RepeatableNotification.Repost -> "reposted" 94 + } 95 + } this" 96 + 97 + remainingCount == 1 -> "$firstAuthorName and 1 other ${ 98 + when (data.kind) { 99 + RepeatableNotification.Like -> "liked" 100 + RepeatableNotification.Repost -> "reposted" 101 + } 102 + } this" 103 + 104 + else -> "$firstAuthorName ${ 105 + when (data.kind) { 106 + RepeatableNotification.Like -> "liked" 107 + RepeatableNotification.Repost -> "reposted" 108 + } 109 + } this" 110 + } 111 + 85 112 Column( 86 113 verticalArrangement = Arrangement.spacedBy(4.dp) 87 114 ) { ··· 166 193 } 167 194 } 168 195 169 - false -> Box( 170 - modifier = Modifier 171 - .clickable { 172 - if (data.authors.count() > 1) { 173 - showAvatars.value = !showAvatars.value 196 + false -> Column { 197 + Box( 198 + modifier = Modifier 199 + .clickable { 200 + if (data.authors.count() > 1) { 201 + showAvatars.value = !showAvatars.value 202 + } 174 203 } 204 + .fillMaxWidth() 205 + ) { 206 + data.authors.take(8).reversed().forEachIndexed { idx, it -> 207 + AsyncImage( 208 + model = ImageRequest.Builder(LocalContext.current) 209 + .data(it.author.avatar?.uri) 210 + .crossfade(true) 211 + .build(), 212 + contentDescription = "Avatar", 213 + modifier = Modifier 214 + .size( 215 + when (data.kind) { 216 + RepeatableNotification.Like -> minSize + 8.dp 217 + RepeatableNotification.Repost -> minSize 218 + } 219 + ) 220 + .offset( 221 + x = when (idx) { 222 + 0 -> 0.dp 223 + else -> (idx * 16).dp 224 + } 225 + ) 226 + .border( 227 + width = 1.dp, 228 + color = MaterialTheme.colorScheme.surface, 229 + shape = CircleShape 230 + ) 231 + .clip(CircleShape) 232 + ) 175 233 } 176 - .fillMaxWidth() 177 - ) { 178 - data.authors.take(8).forEachIndexed { idx, it -> 179 - AsyncImage( 180 - model = ImageRequest.Builder(LocalContext.current) 181 - .data(it.author.avatar?.uri) 182 - .crossfade(true) 183 - .build(), 184 - contentDescription = "Avatar", 185 - modifier = Modifier 186 - .size( 187 - when (data.kind) { 188 - RepeatableNotification.Like -> minSize + 8.dp 189 - RepeatableNotification.Repost -> minSize 190 - } 191 - ) 192 - .offset( 193 - x = when (idx) { 194 - 0 -> 0.dp 195 - else -> (idx * 16).dp 196 - } 197 - ) 198 - .border( 199 - width = 1.dp, 200 - color = MaterialTheme.colorScheme.surface, 201 - shape = CircleShape 202 - ) 203 - .clip(CircleShape) 204 - ) 205 234 } 235 + 236 + Text( 237 + modifier = Modifier.fillMaxWidth(), 238 + text = reasonLine, 239 + style = MaterialTheme.typography.bodyMedium, 240 + fontWeight = FontWeight.Bold, 241 + ) 242 + 206 243 } 207 244 } 208 245 } ··· 240 277 .size(minSize) 241 278 ) 242 279 243 - val authors = data.authors 244 - val firstAuthor = authors.first() 245 - val firstAuthorName = name(firstAuthor.author) 246 - val remainingCount = authors.size - 1 247 - val text = when { 248 - remainingCount > 1 -> "$firstAuthorName and $remainingCount others ${ 249 - when (data.kind) { 250 - RepeatableNotification.Like -> "liked" 251 - RepeatableNotification.Repost -> "reposted" 252 - } 253 - } this" 254 - 255 - remainingCount == 1 -> "$firstAuthorName and 1 other ${ 256 - when (data.kind) { 257 - RepeatableNotification.Like -> "liked" 258 - RepeatableNotification.Repost -> "reposted" 259 - } 260 - } this" 261 - 262 - else -> "$firstAuthorName ${ 263 - when (data.kind) { 264 - RepeatableNotification.Like -> "liked" 265 - RepeatableNotification.Repost -> "reposted" 266 - } 267 - } this" 268 - } 269 - 270 280 Column( 271 281 modifier = Modifier 272 282 .weight(1f) 273 283 .padding(start = 16.dp) 274 284 ) { 275 - Text( 276 - modifier = Modifier.fillMaxWidth(), 277 - text = text, 278 - style = MaterialTheme.typography.bodyMedium, 279 - fontWeight = FontWeight.Bold, 280 - ) 281 285 Text( 282 286 text = HumanReadable.timeAgo(data.timestamp), 283 287 color = MaterialTheme.colorScheme.onSurfaceVariant,