mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 14:07:05 +05:30
feat: load link metadata lazily
This commit is contained in:
parent
4337a19abc
commit
79aba9a187
7 changed files with 50 additions and 61 deletions
|
@ -206,6 +206,7 @@ fun LobstersApp(
|
|||
CommentsPage(
|
||||
postId = postId,
|
||||
getDetails = viewModel::getPostComments,
|
||||
getLinkMetadata = viewModel::getLinkMetadata,
|
||||
postActions = postActions,
|
||||
htmlConverter = htmlConverter,
|
||||
)
|
||||
|
|
|
@ -27,7 +27,7 @@ class ClawViewModel
|
|||
constructor(
|
||||
private val api: LobstersApi,
|
||||
private val savedPostsRepository: SavedPostsRepository,
|
||||
private val postDetailsRepository: PostDetailsRepository,
|
||||
private val linkMetadataRepository: LinkMetadataRepository,
|
||||
private val pagingSourceFactory: LobstersPagingSource.Factory,
|
||||
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||
) : ViewModel() {
|
||||
|
@ -76,18 +76,18 @@ constructor(
|
|||
|
||||
suspend fun getPostComments(postId: String) =
|
||||
withContext(ioDispatcher) {
|
||||
val details =
|
||||
when (val result = api.getPostDetails(postId)) {
|
||||
is Success -> result.value
|
||||
is Failure.NetworkFailure -> throw result.error
|
||||
is Failure.UnknownFailure -> throw result.error
|
||||
is Failure.HttpFailure,
|
||||
is Failure.ApiFailure -> throw IOException("API returned an invalid response")
|
||||
}
|
||||
val extendedDetails = postDetailsRepository.getExtendedDetails(details)
|
||||
extendedDetails
|
||||
when (val result = api.getPostDetails(postId)) {
|
||||
is Success -> result.value
|
||||
is Failure.NetworkFailure -> throw result.error
|
||||
is Failure.UnknownFailure -> throw result.error
|
||||
is Failure.HttpFailure,
|
||||
is Failure.ApiFailure -> throw IOException("API returned an invalid response")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getLinkMetadata(url: String) =
|
||||
withContext(ioDispatcher) { linkMetadataRepository.getLinkMetadata(url) }
|
||||
|
||||
suspend fun getUserProfile(username: String) =
|
||||
withContext(ioDispatcher) {
|
||||
when (val result = api.getUser(username)) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package dev.msfjarvis.claw.android.viewmodel
|
||||
|
||||
import dev.msfjarvis.claw.metadata.MetadataExtractor
|
||||
import dev.msfjarvis.claw.model.LinkMetadata
|
||||
import javax.inject.Inject
|
||||
|
||||
class LinkMetadataRepository
|
||||
@Inject
|
||||
constructor(
|
||||
private val metadataExtractor: MetadataExtractor,
|
||||
) {
|
||||
suspend fun getLinkMetadata(url: String): LinkMetadata {
|
||||
return metadataExtractor.getExtractedMetadata(url)
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package dev.msfjarvis.claw.android.viewmodel
|
||||
|
||||
import dev.msfjarvis.claw.metadata.MetadataExtractor
|
||||
import dev.msfjarvis.claw.model.ExtendedPostDetails
|
||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||
import javax.inject.Inject
|
||||
|
||||
class PostDetailsRepository
|
||||
@Inject
|
||||
constructor(
|
||||
private val metadataExtractor: MetadataExtractor,
|
||||
) {
|
||||
suspend fun getExtendedDetails(details: LobstersPostDetails): ExtendedPostDetails {
|
||||
val metadata = metadataExtractor.getExtractedMetadata(details.url)
|
||||
return ExtendedPostDetails(
|
||||
title = details.title,
|
||||
linkMetadata = metadata,
|
||||
description = details.description,
|
||||
submitter = details.submitter,
|
||||
tags = details.tags,
|
||||
comments = details.comments,
|
||||
commentsUrl = details.commentsUrl,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -40,19 +41,26 @@ import dev.msfjarvis.claw.common.res.ClawIcons
|
|||
import dev.msfjarvis.claw.common.ui.NetworkImage
|
||||
import dev.msfjarvis.claw.common.ui.ThemedRichText
|
||||
import dev.msfjarvis.claw.model.Comment
|
||||
import dev.msfjarvis.claw.model.ExtendedPostDetails
|
||||
import dev.msfjarvis.claw.model.LinkMetadata
|
||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||
import java.time.Instant
|
||||
import java.time.temporal.TemporalAccessor
|
||||
|
||||
@Composable
|
||||
fun CommentsHeader(
|
||||
postDetails: ExtendedPostDetails,
|
||||
postDetails: LobstersPostDetails,
|
||||
getLinkMetadata: suspend (String) -> LinkMetadata,
|
||||
postActions: PostActions,
|
||||
htmlConverter: HTMLConverter,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val linkMetadata by
|
||||
produceState(
|
||||
initialValue = LinkMetadata(postDetails.url, null, null),
|
||||
) {
|
||||
value = getLinkMetadata(postDetails.url)
|
||||
}
|
||||
|
||||
Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) {
|
||||
Column(
|
||||
|
@ -63,13 +71,11 @@ fun CommentsHeader(
|
|||
TagRow(tags = postDetails.tags)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
|
||||
if (postDetails.linkMetadata.url.isNotBlank()) {
|
||||
if (linkMetadata.url.isNotBlank()) {
|
||||
PostLink(
|
||||
linkMetadata = postDetails.linkMetadata,
|
||||
linkMetadata = linkMetadata,
|
||||
modifier =
|
||||
Modifier.clickable {
|
||||
postActions.viewPost(postDetails.linkMetadata.url, postDetails.commentsUrl)
|
||||
},
|
||||
Modifier.clickable { postActions.viewPost(linkMetadata.url, postDetails.commentsUrl) },
|
||||
)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@ import dev.msfjarvis.claw.common.NetworkState.Success
|
|||
import dev.msfjarvis.claw.common.posts.PostActions
|
||||
import dev.msfjarvis.claw.common.ui.NetworkError
|
||||
import dev.msfjarvis.claw.common.ui.ProgressBar
|
||||
import dev.msfjarvis.claw.model.ExtendedPostDetails
|
||||
import dev.msfjarvis.claw.model.LinkMetadata
|
||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||
|
||||
@Composable
|
||||
private fun CommentsPageInternal(
|
||||
details: ExtendedPostDetails,
|
||||
details: LobstersPostDetails,
|
||||
getLinkMetadata: suspend (String) -> LinkMetadata,
|
||||
postActions: PostActions,
|
||||
htmlConverter: HTMLConverter,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -38,6 +40,7 @@ private fun CommentsPageInternal(
|
|||
item {
|
||||
CommentsHeader(
|
||||
postDetails = details,
|
||||
getLinkMetadata = getLinkMetadata,
|
||||
postActions = postActions,
|
||||
htmlConverter = htmlConverter,
|
||||
)
|
||||
|
@ -73,11 +76,12 @@ private fun CommentsPageInternal(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@Suppress("UNCHECKED_CAST", "LongParameterList")
|
||||
@Composable
|
||||
fun CommentsPage(
|
||||
postId: String,
|
||||
getDetails: suspend (String) -> ExtendedPostDetails,
|
||||
getDetails: suspend (String) -> LobstersPostDetails,
|
||||
getLinkMetadata: suspend (String) -> LinkMetadata,
|
||||
postActions: PostActions,
|
||||
htmlConverter: HTMLConverter,
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -94,7 +98,8 @@ fun CommentsPage(
|
|||
when (postDetails) {
|
||||
is Success<*> -> {
|
||||
CommentsPageInternal(
|
||||
details = (postDetails as Success<ExtendedPostDetails>).data,
|
||||
details = (postDetails as Success<LobstersPostDetails>).data,
|
||||
getLinkMetadata = getLinkMetadata,
|
||||
postActions = postActions,
|
||||
htmlConverter = htmlConverter,
|
||||
modifier = modifier.fillMaxSize(),
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
@file:Suppress("LongParameterList")
|
||||
|
||||
package dev.msfjarvis.claw.model
|
||||
|
||||
class ExtendedPostDetails(
|
||||
val title: String,
|
||||
val linkMetadata: LinkMetadata,
|
||||
val description: String,
|
||||
val submitter: User,
|
||||
val tags: List<String>,
|
||||
val comments: List<Comment>,
|
||||
val commentsUrl: String,
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue