feat: load link metadata lazily

This commit is contained in:
Harsh Shandilya 2022-10-16 12:21:19 +05:30
parent 4337a19abc
commit 79aba9a187
No known key found for this signature in database
7 changed files with 50 additions and 61 deletions

View file

@ -206,6 +206,7 @@ fun LobstersApp(
CommentsPage(
postId = postId,
getDetails = viewModel::getPostComments,
getLinkMetadata = viewModel::getLinkMetadata,
postActions = postActions,
htmlConverter = htmlConverter,
)

View file

@ -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)) {

View file

@ -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)
}
}

View file

@ -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,
)
}
}

View file

@ -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))
}

View file

@ -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(),

View file

@ -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,
)