mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 09:57:04 +05:30
refactor: hoist state out of comments page
This commit is contained in:
parent
0d3c08c10a
commit
bcac86d187
2 changed files with 68 additions and 14 deletions
|
@ -10,13 +10,12 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.github.michaelbull.result.coroutines.runSuspendCatching
|
import com.deliveryhero.whetstone.compose.injectedViewModel
|
||||||
import com.github.michaelbull.result.fold
|
|
||||||
import dev.msfjarvis.claw.common.NetworkState
|
|
||||||
import dev.msfjarvis.claw.common.NetworkState.Error
|
import dev.msfjarvis.claw.common.NetworkState.Error
|
||||||
import dev.msfjarvis.claw.common.NetworkState.Loading
|
import dev.msfjarvis.claw.common.NetworkState.Loading
|
||||||
import dev.msfjarvis.claw.common.NetworkState.Success
|
import dev.msfjarvis.claw.common.NetworkState.Success
|
||||||
|
@ -35,23 +34,17 @@ fun CommentsPage(
|
||||||
getSeenComments: suspend (String) -> PostComments?,
|
getSeenComments: suspend (String) -> PostComments?,
|
||||||
markSeenComments: (String, List<Comment>) -> Unit,
|
markSeenComments: (String, List<Comment>) -> Unit,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
openUserProfile: (String) -> Unit,
|
openUserProfile: (String) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
viewModel: CommentsViewModel = injectedViewModel(),
|
||||||
) {
|
) {
|
||||||
val postDetails by
|
LaunchedEffect(postId) { viewModel.loadPostDetails(postId) }
|
||||||
produceState<NetworkState>(Loading, key1 = postId) {
|
|
||||||
runSuspendCatching { postActions.getComments(postId) }
|
|
||||||
.fold(
|
|
||||||
success = { details -> value = Success(details) },
|
|
||||||
failure = { value = Error(error = it, description = "Failed to load comments") },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val commentState by
|
val commentState by
|
||||||
produceState<PostComments?>(initialValue = null, key1 = postId) {
|
produceState<PostComments?>(initialValue = null, key1 = postId) {
|
||||||
value = getSeenComments(postId)
|
value = getSeenComments(postId)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (postDetails) {
|
when (val postDetails = viewModel.postDetails) {
|
||||||
is Success<*> -> {
|
is Success<*> -> {
|
||||||
CommentsPageInternal(
|
CommentsPageInternal(
|
||||||
details = (postDetails as Success<UIPost>).data,
|
details = (postDetails as Success<UIPost>).data,
|
||||||
|
@ -64,7 +57,7 @@ fun CommentsPage(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Error -> {
|
is Error -> {
|
||||||
val error = postDetails as Error
|
val error = postDetails
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
NetworkError(
|
NetworkError(
|
||||||
label = error.description,
|
label = error.description,
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright © Harsh Shandilya.
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
*/
|
||||||
|
package dev.msfjarvis.claw.common.comments
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import com.deliveryhero.whetstone.app.ApplicationScope
|
||||||
|
import com.deliveryhero.whetstone.viewmodel.ContributesViewModel
|
||||||
|
import com.github.michaelbull.result.coroutines.runSuspendCatching
|
||||||
|
import com.github.michaelbull.result.fold
|
||||||
|
import com.slack.eithernet.ApiResult.Failure
|
||||||
|
import com.slack.eithernet.ApiResult.Success
|
||||||
|
import com.squareup.anvil.annotations.optional.ForScope
|
||||||
|
import dev.msfjarvis.claw.api.LobstersApi
|
||||||
|
import dev.msfjarvis.claw.api.toError
|
||||||
|
import dev.msfjarvis.claw.common.NetworkState
|
||||||
|
import dev.msfjarvis.claw.core.injection.IODispatcher
|
||||||
|
import dev.msfjarvis.claw.model.UIPost
|
||||||
|
import dev.msfjarvis.claw.model.toUIPost
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
@ContributesViewModel
|
||||||
|
class CommentsViewModel
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
private val api: LobstersApi,
|
||||||
|
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||||
|
@ForScope(ApplicationScope::class) context: Context,
|
||||||
|
) : AndroidViewModel(context as Application) {
|
||||||
|
var postDetails by mutableStateOf<NetworkState>(NetworkState.Loading)
|
||||||
|
|
||||||
|
suspend fun loadPostDetails(postId: String) {
|
||||||
|
postDetails =
|
||||||
|
runSuspendCatching<UIPost> {
|
||||||
|
withContext(ioDispatcher) {
|
||||||
|
when (val result = api.getPostDetails(postId)) {
|
||||||
|
is Success -> result.value.toUIPost()
|
||||||
|
is Failure.NetworkFailure -> throw result.error
|
||||||
|
is Failure.UnknownFailure -> throw result.error
|
||||||
|
is Failure.HttpFailure -> throw result.toError()
|
||||||
|
is Failure.ApiFailure -> throw IOException("API returned an invalid response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fold(
|
||||||
|
success = { details -> NetworkState.Success(details) },
|
||||||
|
failure = { NetworkState.Error(error = it, description = "Failed to load comments") },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue