Skip to content

Commit

Permalink
WIP Start using UI state from ReaderTagsFeed in ReaderTagsFeedViewModel
Browse files Browse the repository at this point in the history
  • Loading branch information
RenanLukas committed Apr 26, 2024
1 parent e598244 commit 45be2f2
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@ class ReaderUtilsWrapper @Inject constructor(
fun isSelfHosted(authorBlogId: Long) = ReaderUtils.isSelfHosted(authorBlogId)

fun getTagFromTagUrl(url: String): String = ReaderUtils.getTagFromTagUrl(url)

fun getShortLikeLabelText(numLikes: Int): String =
ReaderUtils.getShortLikeLabelText(contextProvider.getContext(), numLikes)

fun getShortCommentLabelText(numComments: Int): String =
ReaderUtils.getShortCommentLabelText(contextProvider.getContext(), numComments)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import org.wordpress.android.models.ReaderPostList
import org.wordpress.android.models.ReaderTag
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.ui.reader.exceptions.ReaderPostFetchException
import org.wordpress.android.ui.reader.repository.ReaderPostRepository
import org.wordpress.android.ui.reader.utils.ReaderUtilsWrapper
import org.wordpress.android.ui.reader.views.compose.tagsfeed.TagsFeedPostItem
import org.wordpress.android.viewmodel.ScopedViewModel
import javax.inject.Inject
Expand All @@ -19,8 +19,9 @@ import javax.inject.Named
class ReaderTagsFeedViewModel @Inject constructor(
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
private val readerPostRepository: ReaderPostRepository,
private val readerUtilsWrapper: ReaderUtilsWrapper,
) : ScopedViewModel(bgDispatcher) {
private val _uiStateFlow = MutableStateFlow(UiState.Initial)
private val _uiStateFlow: MutableStateFlow<UiState> = MutableStateFlow(UiState.Initial)
val uiStateFlow: StateFlow<UiState> = _uiStateFlow

/**
Expand All @@ -29,6 +30,10 @@ class ReaderTagsFeedViewModel @Inject constructor(
* [FetchState]s: [FetchState.Loading], [FetchState.Success], [FetchState.Error].
*/
fun fetchAll(tags: List<ReaderTag>) {
if (tags.isEmpty()) {
_uiStateFlow.value = UiState.Empty(::onOpenTagsListClick)
return
}
tags.forEach {
fetchTag(it)
}
Expand All @@ -42,23 +47,109 @@ class ReaderTagsFeedViewModel @Inject constructor(
*/
fun fetchTag(tag: ReaderTag) {
launch {
// _uiStateFlow.update {
// it.copy(tagStates = it.tagStates + (tag to FetchState.Loading))
// }
//
// try {
// val posts = readerPostRepository.fetchNewerPostsForTag(tag)
// _uiStateFlow.update {
// it.copy(tagStates = it.tagStates + (tag to FetchState.Success(posts)))
// }
// } catch (e: ReaderPostFetchException) {
// _uiStateFlow.update {
// it.copy(tagStates = it.tagStates + (tag to FetchState.Error(e)))
// }
// }
_uiStateFlow.update { UiState.Loading }

val loadedData = mutableListOf<TagFeedItem>()
val currentValue = _uiStateFlow.value
if (currentValue is UiState.Loaded) {
loadedData.addAll(currentValue.data)
}
try {
val posts = readerPostRepository.fetchNewerPostsForTag(tag)
if (posts.isNotEmpty()) {
loadedData.add(
TagFeedItem(
tagChip = TagChip(
tag = tag,
onTagClick = ::onTagClick,
),
postList = PostList.Loaded(
posts.map {
TagsFeedPostItem(
siteName = it.blogName,
postDateLine = "1H",
postTitle = it.title,
postExcerpt = it.excerpt,
postImageUrl = it.blogImageUrl,
postNumberOfLikesText = readerUtilsWrapper.getShortLikeLabelText(
numLikes = it.numLikes
),
postNumberOfCommentsText = readerUtilsWrapper.getShortCommentLabelText(
numComments = it.numReplies
),
isPostLiked = it.isLikedByCurrentUser,
onSiteClick = ::onSiteClick,
onPostImageClick = ::onPostImageClick,
onPostLikeClick = ::onPostLikeClick,
onPostMoreMenuClick = ::onPostMoreMenuClick,
)
}
),
)
)
} else {
loadedData.add(
errorTagFeedItem(
tag = tag,
errorType = ErrorType.NoContent,
)
)
}
} catch (e: ReaderPostFetchException) {
loadedData.add(
errorTagFeedItem(
tag = tag,
errorType = ErrorType.Default,
)
)
}
_uiStateFlow.update { UiState.Loaded(loadedData) }
}
}

private fun errorTagFeedItem(
tag: ReaderTag,
errorType: ErrorType,
): TagFeedItem =
TagFeedItem(
tagChip = TagChip(
tag = tag,
onTagClick = ::onTagClick
),
postList = PostList.Error(
type = errorType,
onRetryClick = ::onRetryClick
),
)

private fun onOpenTagsListClick() {
// TODO
}

private fun onTagClick() {
// TODO
}

private fun onRetryClick() {
// TODO
}

private fun onSiteClick() {
// TODO
}

private fun onPostImageClick() {
// TODO
}

private fun onPostLikeClick() {
// TODO
}

private fun onPostMoreMenuClick() {
// TODO
}

sealed class UiState {
object Initial : UiState()
data class Loaded(val data: List<TagFeedItem>) : UiState()
Expand All @@ -75,7 +166,7 @@ class ReaderTagsFeedViewModel @Inject constructor(

data class TagChip(
val tag: ReaderTag,
val onTagClicked: () -> Unit,
val onTagClick: () -> Unit,
)

sealed class PostList {
Expand All @@ -90,7 +181,7 @@ class ReaderTagsFeedViewModel @Inject constructor(
}

sealed interface ErrorType {
data object Loading : ErrorType
data object Default : ErrorType

data object NoContent : ErrorType
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private fun Loaded(uiState: UiState.Loaded) {
start = Margin.Large.value,
),
text = UiString.UiStringText(tagChip.tag.tagTitle),
onClick = tagChip.onTagClicked,
onClick = tagChip.onTagClick,
height = 36.dp,
)
Spacer(modifier = Modifier.height(Margin.Large.value))
Expand Down Expand Up @@ -300,7 +300,7 @@ private fun PostListLoaded(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false),
onClick = {
tagChip.onTagClicked()
tagChip.onTagClick()
AppLog.e(AppLog.T.READER, "RL-> Tag clicked")
}
),
Expand Down Expand Up @@ -374,7 +374,7 @@ private fun PostListError(
)
Spacer(modifier = Modifier.height(Margin.Medium.value))
val errorMessage = when (postList.type) {
is ErrorType.Loading -> stringResource(R.string.reader_tags_feed_loading_error_description)
is ErrorType.Default -> stringResource(R.string.reader_tags_feed_loading_error_description)
is ErrorType.NoContent -> stringResource(R.string.reader_tags_feed_no_content_error_description, tagName)
}
Text(
Expand Down Expand Up @@ -529,7 +529,7 @@ fun ReaderTagsFeedLoaded() {
),
TagFeedItem(
tagChip = TagChip(readerTag, {}),
postList = PostList.Error(ErrorType.Loading, {}),
postList = PostList.Error(ErrorType.Default, {}),
),
TagFeedItem(
tagChip = TagChip(readerTag, {}),
Expand Down

0 comments on commit 45be2f2

Please sign in to comment.