feat(explore): subscription management screen
This commit is contained in:
parent
d2500372c2
commit
6297ef3b97
@ -42,6 +42,7 @@ kotlin {
|
|||||||
implementation(projects.coreUtils)
|
implementation(projects.coreUtils)
|
||||||
implementation(projects.corePreferences)
|
implementation(projects.corePreferences)
|
||||||
implementation(projects.coreCommonui)
|
implementation(projects.coreCommonui)
|
||||||
|
implementation(projects.coreCommonui.components)
|
||||||
implementation(projects.coreNotifications)
|
implementation(projects.coreNotifications)
|
||||||
|
|
||||||
implementation(projects.domainIdentity)
|
implementation(projects.domainIdentity)
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreViewModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsViewModel
|
||||||
import org.koin.java.KoinJavaComponent.inject
|
import org.koin.java.KoinJavaComponent.inject
|
||||||
|
|
||||||
actual fun getExploreViewModel(): ExploreViewModel {
|
actual fun getExploreViewModel(): ExploreViewModel {
|
||||||
val res: ExploreViewModel by inject(ExploreViewModel::class.java)
|
val res: ExploreViewModel by inject(ExploreViewModel::class.java)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun getManageSubscriptionsViewModel(): ManageSubscriptionsViewModel {
|
||||||
|
val res: ManageSubscriptionsViewModel by inject(ManageSubscriptionsViewModel::class.java)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreMviModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreMviModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreViewModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsMviModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsViewModel
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val searchTabModule = module {
|
val searchTabModule = module {
|
||||||
@ -20,4 +22,12 @@ val searchTabModule = module {
|
|||||||
hapticFeedback = get(),
|
hapticFeedback = get(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
factory {
|
||||||
|
ManageSubscriptionsViewModel(
|
||||||
|
mvi = DefaultMviModel(ManageSubscriptionsMviModel.UiState()),
|
||||||
|
identityRepository = get(),
|
||||||
|
communityRepository = get(),
|
||||||
|
hapticFeedback = get(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreViewModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsViewModel
|
||||||
|
|
||||||
expect fun getExploreViewModel(): ExploreViewModel
|
expect fun getExploreViewModel(): ExploreViewModel
|
||||||
|
|
||||||
|
expect fun getManageSubscriptionsViewModel(): ManageSubscriptionsViewModel
|
@ -1,4 +1,4 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.content
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.main
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
@ -1,4 +1,4 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.content
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.main
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@ -73,6 +73,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResultTy
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.di.getExploreViewModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.di.getExploreViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsScreen
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||||
import dev.icerock.moko.resources.compose.stringResource
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
|
|
||||||
@ -101,6 +102,7 @@ class ExploreScreen : Screen {
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
listingType = uiState.listingType,
|
listingType = uiState.listingType,
|
||||||
sortType = uiState.sortType,
|
sortType = uiState.sortType,
|
||||||
|
isLogged = uiState.isLogged,
|
||||||
onSelectListingType = {
|
onSelectListingType = {
|
||||||
val sheet = ListingTypeBottomSheet(
|
val sheet = ListingTypeBottomSheet(
|
||||||
isLogged = uiState.isLogged,
|
isLogged = uiState.isLogged,
|
||||||
@ -125,6 +127,10 @@ class ExploreScreen : Screen {
|
|||||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||||
bottomSheetNavigator.show(sheet)
|
bottomSheetNavigator.show(sheet)
|
||||||
},
|
},
|
||||||
|
onSettings = {
|
||||||
|
val sheet = ManageSubscriptionsScreen()
|
||||||
|
navigator?.push(sheet)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { padding ->
|
) { padding ->
|
@ -1,10 +1,12 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.content
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.main
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ManageAccounts
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@ -29,8 +31,10 @@ internal fun CommunityTopBar(
|
|||||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||||
listingType: ListingType,
|
listingType: ListingType,
|
||||||
sortType: SortType,
|
sortType: SortType,
|
||||||
onSelectListingType: () -> Unit,
|
isLogged: Boolean = false,
|
||||||
onSelectSortType: () -> Unit,
|
onSelectListingType: (() -> Unit)? = null,
|
||||||
|
onSelectSortType: (() -> Unit)? = null,
|
||||||
|
onSettings: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
@ -40,7 +44,7 @@ internal fun CommunityTopBar(
|
|||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.onClick {
|
modifier = Modifier.onClick {
|
||||||
onSelectListingType()
|
onSelectListingType?.invoke()
|
||||||
},
|
},
|
||||||
imageVector = listingType.toIcon(),
|
imageVector = listingType.toIcon(),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
@ -63,7 +67,9 @@ internal fun CommunityTopBar(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
Row {
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||||
|
) {
|
||||||
val additionalLabel = when (sortType) {
|
val additionalLabel = when (sortType) {
|
||||||
SortType.Top.Day -> stringResource(MR.strings.home_sort_type_top_day_short)
|
SortType.Top.Day -> stringResource(MR.strings.home_sort_type_top_day_short)
|
||||||
SortType.Top.Month -> stringResource(MR.strings.home_sort_type_top_month_short)
|
SortType.Top.Month -> stringResource(MR.strings.home_sort_type_top_month_short)
|
||||||
@ -85,12 +91,23 @@ internal fun CommunityTopBar(
|
|||||||
}
|
}
|
||||||
Image(
|
Image(
|
||||||
modifier = Modifier.onClick {
|
modifier = Modifier.onClick {
|
||||||
onSelectSortType()
|
onSelectSortType?.invoke()
|
||||||
},
|
},
|
||||||
imageVector = sortType.toIcon(),
|
imageVector = sortType.toIcon(),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (isLogged) {
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.onClick {
|
||||||
|
onSettings?.invoke()
|
||||||
|
},
|
||||||
|
imageVector = Icons.Default.ManageAccounts,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
@ -1,7 +1,6 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.content
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.main
|
||||||
|
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.HapticFeedback
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository
|
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||||
@ -9,6 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationC
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
|
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
|
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core.utils.HapticFeedback
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions
|
||||||
|
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||||
|
|
||||||
|
interface ManageSubscriptionsMviModel :
|
||||||
|
MviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect> {
|
||||||
|
sealed interface Intent {
|
||||||
|
data object HapticIndication : Intent
|
||||||
|
|
||||||
|
data class Unsubscribe(val index: Int) : Intent
|
||||||
|
}
|
||||||
|
|
||||||
|
data class UiState(
|
||||||
|
val loading: Boolean = false,
|
||||||
|
val communities: List<CommunityModel> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed interface Effect
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
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.Icon
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Unsubscribe
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
|
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
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.di.getManageSubscriptionsViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||||
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
|
|
||||||
|
class ManageSubscriptionsScreen : Screen {
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
override fun Content() {
|
||||||
|
val model = rememberScreenModel { getManageSubscriptionsViewModel() }
|
||||||
|
model.bindToLifecycle(key)
|
||||||
|
val uiState by model.uiState.collectAsState()
|
||||||
|
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||||
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(MR.strings.explore_title_manage_subscriptions),
|
||||||
|
style = MaterialTheme.typography.titleLarge
|
||||||
|
)
|
||||||
|
},
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
navigationIcon = {
|
||||||
|
Image(
|
||||||
|
modifier = Modifier.onClick {
|
||||||
|
navigator?.pop()
|
||||||
|
},
|
||||||
|
imageVector = Icons.Default.ArrowBack,
|
||||||
|
contentDescription = null,
|
||||||
|
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) { paddingValues ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
|
) {
|
||||||
|
itemsIndexed(uiState.communities) { idx, community ->
|
||||||
|
SwipeableCard(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
directions = setOf(DismissDirection.EndToStart),
|
||||||
|
backgroundColor = {
|
||||||
|
when (it) {
|
||||||
|
DismissValue.DismissedToStart -> MaterialTheme.colorScheme.secondary
|
||||||
|
else -> Color.Transparent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onGestureBegin = {
|
||||||
|
model.reduce(ManageSubscriptionsMviModel.Intent.HapticIndication)
|
||||||
|
},
|
||||||
|
onDismissToStart = {
|
||||||
|
model.reduce(
|
||||||
|
ManageSubscriptionsMviModel.Intent.Unsubscribe(idx),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
swipeContent = { _ ->
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.background(
|
||||||
|
color = MaterialTheme.colorScheme.onSecondary,
|
||||||
|
shape = CircleShape,
|
||||||
|
).padding(Spacing.xs),
|
||||||
|
imageVector = Icons.Default.Unsubscribe,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.secondary,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
CommunityItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.onClick {
|
||||||
|
navigator?.push(
|
||||||
|
CommunityDetailScreen(community),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
community = community,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (uiState.loading) {
|
||||||
|
ProgressHud()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions
|
||||||
|
|
||||||
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.core.utils.HapticFeedback
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.IO
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ManageSubscriptionsViewModel(
|
||||||
|
private val mvi: DefaultMviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect>,
|
||||||
|
private val identityRepository: IdentityRepository,
|
||||||
|
private val communityRepository: CommunityRepository,
|
||||||
|
private val hapticFeedback: HapticFeedback,
|
||||||
|
) : ScreenModel,
|
||||||
|
MviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect> by mvi {
|
||||||
|
|
||||||
|
override fun onStarted() {
|
||||||
|
mvi.onStarted()
|
||||||
|
if (uiState.value.communities.isEmpty()) {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reduce(intent: ManageSubscriptionsMviModel.Intent) {
|
||||||
|
when (intent) {
|
||||||
|
ManageSubscriptionsMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||||
|
is ManageSubscriptionsMviModel.Intent.Unsubscribe -> handleUnsubscription(
|
||||||
|
community = uiState.value.communities[intent.index]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refresh() {
|
||||||
|
mvi.updateState { it.copy(loading = 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,
|
||||||
|
communities = items,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleUnsubscription(community: CommunityModel) {
|
||||||
|
mvi.scope?.launch {
|
||||||
|
val auth = identityRepository.authToken.value
|
||||||
|
communityRepository.unsubscribe(
|
||||||
|
auth = auth, id = community.id
|
||||||
|
)
|
||||||
|
mvi.updateState {
|
||||||
|
it.copy(communities = it.communities.filter { c -> c.id != community.id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
|||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.tab.Tab
|
import cafe.adriel.voyager.navigator.tab.Tab
|
||||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreScreen
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreScreen
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository
|
import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.resources.di.staticString
|
import com.github.diegoberaldin.raccoonforlemmy.resources.di.staticString
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
package com.github.diegoberaldin.raccoonforlemmy.feature.search.di
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.content.ExploreViewModel
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.main.ExploreViewModel
|
||||||
|
import com.github.diegoberaldin.raccoonforlemmy.feature.search.managesubscriptions.ManageSubscriptionsViewModel
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
|
|
||||||
actual fun getExploreViewModel() = SearchScreenModelHelper.model
|
actual fun getExploreViewModel() = SearchScreenModelHelper.model
|
||||||
|
|
||||||
|
actual fun getManageSubscriptionsViewModel() = SearchScreenModelHelper.manageSuscriptionsViewModel
|
||||||
|
|
||||||
object SearchScreenModelHelper : KoinComponent {
|
object SearchScreenModelHelper : KoinComponent {
|
||||||
val model: ExploreViewModel by inject()
|
val model: ExploreViewModel by inject()
|
||||||
|
val manageSuscriptionsViewModel: ManageSubscriptionsViewModel by inject()
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
<string name="explore_result_type_communities">Communities</string>
|
<string name="explore_result_type_communities">Communities</string>
|
||||||
<string name="explore_result_type_users">Users</string>
|
<string name="explore_result_type_users">Users</string>
|
||||||
<string name="explore_search_placeholder">Search text</string>
|
<string name="explore_search_placeholder">Search text</string>
|
||||||
|
<string name="explore_title_manage_subscriptions">Manage subscriptions</string>
|
||||||
|
|
||||||
<string name="profile_not_logged_message">You are currently not logged in.\nPlease add an
|
<string name="profile_not_logged_message">You are currently not logged in.\nPlease add an
|
||||||
account to continue.
|
account to continue.
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="explore_result_type_communities">Comunidades</string>
|
<string name="explore_result_type_communities">Comunidades</string>
|
||||||
<string name="explore_result_type_users">Usuarios</string>
|
<string name="explore_result_type_users">Usuarios</string>
|
||||||
<string name="explore_search_placeholder">Texto de búsqueda</string>
|
<string name="explore_search_placeholder">Texto de búsqueda</string>
|
||||||
|
<string name="explore_title_manage_subscriptions">Gestionar subscripciones</string>
|
||||||
|
|
||||||
<string name="profile_not_logged_message">Acceso no efectuado.\nAñadir una cuenta para
|
<string name="profile_not_logged_message">Acceso no efectuado.\nAñadir una cuenta para
|
||||||
continuar.
|
continuar.
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
<string name="explore_result_type_communities">Comunità</string>
|
<string name="explore_result_type_communities">Comunità</string>
|
||||||
<string name="explore_result_type_users">Utenti</string>
|
<string name="explore_result_type_users">Utenti</string>
|
||||||
<string name="explore_search_placeholder">Testo di ricerca</string>
|
<string name="explore_search_placeholder">Testo di ricerca</string>
|
||||||
|
<string name="explore_title_manage_subscriptions">Gestione iscruzione</string>
|
||||||
|
|
||||||
<string name="profile_not_logged_message">Login non effettuato.\nAggiungi un account per
|
<string name="profile_not_logged_message">Login non effettuato.\nAggiungi un account per
|
||||||
continuare.
|
continuare.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user