A cheap attempt at a native Bluesky client for Android

Notifications: fetch posts in bulk

Instead of fetching the subject of each "like" or "repost" notification individually, fetch all of them in a single bulk request. This reduces network IO and improves performance when loading notifications.

+24 -3
+24 -3
app/src/main/java/industries/geesawra/monarch/datalayer/TimelineViewModel.kt
··· 211 211 ) 212 212 213 213 val repeatable = mutableListOf<Notification>() 214 + val postsToFetch = rawNotifs.notifications.mapNotNull { 215 + when (it.reason) { 216 + ListNotificationsReason.Like -> { 217 + val l: Like = it.record.decodeAs() 218 + l.subject.uri 219 + } 220 + 221 + ListNotificationsReason.Repost -> { 222 + val l: Repost = it.record.decodeAs() 223 + l.subject.uri 224 + } 225 + 226 + else -> null 227 + } 228 + } 229 + 230 + val posts = postsToFetch.chunked(25).fold(mapOf<AtUri, Post>()) { acc, chunk -> 231 + acc + bskyConn.getPosts(chunk).getOrThrow() 232 + .associate { it.uri to it.record.decodeAs<Post>() } 233 + } 214 234 215 235 // we could bulk request posts here and avoid much of the network IO 216 236 var notifs = rawNotifs.notifications.mapNotNull { ··· 222 242 223 243 ListNotificationsReason.Like -> { 224 244 val l: Like = it.record.decodeAs() 225 - val lp = fetchRecord(l.subject.uri).getOrThrow() 245 + val lp = posts[l.subject.uri]!! 246 + 226 247 227 248 repeatable += Notification.RawLike( 228 - lp.decodeAs(), 249 + lp, 229 250 it.author, 230 251 l.createdAt.toStdlibInstant() 231 252 ) ··· 265 286 266 287 ListNotificationsReason.Repost -> { 267 288 val p: Repost = it.record.decodeAs() 268 - val rpp: Post = fetchRecord(p.subject.uri).getOrThrow().decodeAs() 289 + val rpp = posts[p.subject.uri]!! 269 290 270 291 val pp = when (rpp.embed) { 271 292 is PostEmbedUnion.Record -> {