feat(explore): add pull to refresh to manage subscriptions screen

This commit is contained in:
Diego Beraldin 2023-09-28 18:00:21 +02:00
parent 9110b86b62
commit 8080aa54ef
3 changed files with 36 additions and 11 deletions

View File

@ -6,13 +6,14 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
interface ManageSubscriptionsMviModel :
MviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect> {
sealed interface Intent {
data object Refresh : Intent
data object HapticIndication : Intent
data class Unsubscribe(val index: Int) : Intent
}
data class UiState(
val loading: Boolean = false,
val refreshing: Boolean = false,
val communities: List<CommunityModel> = emptyList(),
)

View File

@ -2,7 +2,9 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscripti
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@ -10,10 +12,14 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.DismissDirection
import androidx.compose.material.DismissValue
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Unsubscribe
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@ -24,6 +30,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
@ -34,7 +41,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityItem
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
@ -43,7 +49,7 @@ import com.github.diegoberaldin.raccoonforlemmy.resources.MR
import dev.icerock.moko.resources.compose.stringResource
class ManageSubscriptionsScreen : Screen {
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
@Composable
override fun Content() {
val model = rememberScreenModel { getManageSubscriptionsViewModel() }
@ -75,12 +81,21 @@ class ManageSubscriptionsScreen : Screen {
)
},
) { paddingValues ->
val pullRefreshState = rememberPullRefreshState(
uiState.refreshing,
{
model.reduce(ManageSubscriptionsMviModel.Intent.Refresh)
}
)
Box(
modifier = Modifier.padding(paddingValues),
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection)
.pullRefresh(pullRefreshState),
) {
LazyColumn(
modifier = Modifier
.nestedScroll(scrollBehavior.nestedScrollConnection)
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
itemsIndexed(uiState.communities) { idx, community ->
SwipeableCard(
@ -127,9 +142,14 @@ class ManageSubscriptionsScreen : Screen {
)
}
}
if (uiState.loading) {
ProgressHud()
}
PullRefreshIndicator(
refreshing = uiState.refreshing,
state = pullRefreshState,
modifier = Modifier.align(Alignment.TopCenter),
backgroundColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
)
}
}
}

View File

@ -29,6 +29,7 @@ class ManageSubscriptionsViewModel(
override fun reduce(intent: ManageSubscriptionsMviModel.Intent) {
when (intent) {
ManageSubscriptionsMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
ManageSubscriptionsMviModel.Intent.Refresh -> refresh()
is ManageSubscriptionsMviModel.Intent.Unsubscribe -> handleUnsubscription(
community = uiState.value.communities[intent.index]
)
@ -36,13 +37,16 @@ class ManageSubscriptionsViewModel(
}
private fun refresh() {
mvi.updateState { it.copy(loading = true) }
if (uiState.value.refreshing) {
return
}
mvi.updateState { it.copy(refreshing = true) }
mvi.scope?.launch(Dispatchers.IO) {
val auth = identityRepository.authToken.value
val items = communityRepository.getSubscribed(auth).sortedBy { it.name }
mvi.updateState {
it.copy(
loading = false,
refreshing = false,
communities = items,
)
}