fix(inbox): navigation between screens

This commit is contained in:
Diego Beraldin 2023-09-09 14:53:28 +02:00
parent 5bd81e529b
commit a2f6ea97a4
5 changed files with 73 additions and 29 deletions

View File

@ -13,6 +13,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -22,6 +23,8 @@ 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 cafe.adriel.voyager.navigator.CurrentScreen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
import com.github.diegoberaldin.racconforlemmy.core.utils.onClick
@ -31,12 +34,16 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.InboxTypeSheet
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsScreen
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.InboxMessagesScreen
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesScreen
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository
import com.github.diegoberaldin.raccoonforlemmy.resources.di.staticString
import dev.icerock.moko.resources.compose.stringResource
import dev.icerock.moko.resources.desc.desc
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
class InboxScreen : Screen {
@OptIn(ExperimentalMaterial3Api::class)
@ -133,19 +140,28 @@ class InboxScreen : Screen {
model.reduce(InboxMviModel.Intent.ChangeSection(section))
},
)
val screen = when (uiState.section) {
InboxSection.REPLIES -> InboxRepliesScreen(
parentModel = model,
)
InboxSection.MENTIONS -> InboxMentionsScreen(
parentModel = model,
)
InboxSection.MESSAGES -> null
}
if (screen != null) {
Navigator(screen)
val screens = listOf(
InboxRepliesScreen().apply {
parentModel = model
},
InboxMentionsScreen().apply {
parentModel = model
},
InboxMessagesScreen()
)
Navigator(screens) {
CurrentScreen()
val navigator = LocalNavigator.current
LaunchedEffect(model) {
model.uiState.map { it.section }.onEach { section ->
val index = when (section) {
InboxSection.REPLIES -> 0
InboxSection.MENTIONS -> 1
InboxSection.MESSAGES -> 2
}
navigator?.replace(screens[index])
}.launchIn(this)
}
}
}
}

View File

@ -46,39 +46,42 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDet
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxMentionsViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
class InboxMentionsScreen(
private val parentModel: InboxViewModel,
) : Screen {
class InboxMentionsScreen : Screen {
var parentModel: InboxViewModel? = null
@OptIn(ExperimentalMaterialApi::class)
@Composable
override fun Content() {
val model = rememberScreenModel { getInboxMentionsViewModel() }
model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState()
val parentUiState by parentModel.uiState.collectAsState()
val parentUiState by (parentModel?.uiState
?: MutableStateFlow(InboxMviModel.UiState())).collectAsState()
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
LaunchedEffect(parentModel) {
parentModel.uiState.map { it.unreadOnly }.distinctUntilChanged().onEach {
parentModel?.uiState?.map { it.unreadOnly }?.distinctUntilChanged()?.onEach {
model.reduce(InboxMentionsMviModel.Intent.ChangeUnreadOnly(unread = it))
}.launchIn(this)
}?.launchIn(this)
if (uiState.unreadOnly != parentUiState.unreadOnly) {
model.reduce(InboxMentionsMviModel.Intent.ChangeUnreadOnly(parentUiState.unreadOnly))
}
parentModel.effects.onEach {
parentModel?.effects?.onEach {
when (it) {
InboxMviModel.Effect.Refresh -> {
model.reduce(InboxMentionsMviModel.Intent.Refresh)
}
}
}.launchIn(this)
}?.launchIn(this)
}
val pullRefreshState = rememberPullRefreshState(uiState.refreshing, {

View File

@ -0,0 +1,22 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import cafe.adriel.voyager.core.screen.Screen
class InboxMessagesScreen : Screen {
@Composable
override fun Content() {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "\uD83D\uDEA7 Work in progress! \uD83D\uDEA7",
style = MaterialTheme.typography.titleLarge,
)
}
}
}

View File

@ -46,39 +46,42 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDet
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxRepliesViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
class InboxRepliesScreen(
private val parentModel: InboxViewModel,
) : Screen {
class InboxRepliesScreen : Screen {
var parentModel: InboxViewModel? = null
@OptIn(ExperimentalMaterialApi::class)
@Composable
override fun Content() {
val model = rememberScreenModel { getInboxRepliesViewModel() }
model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState()
val parentUiState by parentModel.uiState.collectAsState()
val parentUiState by (parentModel?.uiState
?: MutableStateFlow(InboxMviModel.UiState())).collectAsState()
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
LaunchedEffect(parentModel) {
parentModel.uiState.map { it.unreadOnly }.distinctUntilChanged().onEach {
parentModel?.uiState?.map { it.unreadOnly }?.distinctUntilChanged()?.onEach {
model.reduce(InboxRepliesMviModel.Intent.ChangeUnreadOnly(unread = it))
}.launchIn(this)
}?.launchIn(this)
if (uiState.unreadOnly != parentUiState.unreadOnly) {
model.reduce(InboxRepliesMviModel.Intent.ChangeUnreadOnly(parentUiState.unreadOnly))
}
parentModel.effects.onEach {
parentModel?.effects?.onEach {
when (it) {
InboxMviModel.Effect.Refresh -> {
model.reduce(InboxRepliesMviModel.Intent.Refresh)
}
}
}.launchIn(this)
}?.launchIn(this)
}
val pullRefreshState = rememberPullRefreshState(uiState.refreshing, {