fix: prevent inbox and profile unlogged contents from being visible if logged

This commit is contained in:
Diego Beraldin 2023-09-21 13:49:46 +02:00
parent 1eff763bbf
commit 31d784d645
6 changed files with 86 additions and 79 deletions

View File

@ -7,8 +7,6 @@ import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.main.InboxViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions.InboxMentionsViewModel
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages.list.InboxMessagesViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies.InboxRepliesMviModel
@ -24,7 +22,6 @@ val inboxTabModule = module {
mvi = DefaultMviModel(InboxMviModel.UiState()),
identityRepository = get(),
userRepository = get(),
siteRepository = get(),
coordinator = get(),
)
}

View File

@ -12,7 +12,7 @@ interface InboxMviModel :
}
data class UiState(
val currentUserId: Int? = null,
val isLogged: Boolean? = null,
val section: InboxSection = InboxSection.REPLIES,
val unreadOnly: Boolean = true,
)

View File

@ -110,7 +110,7 @@ object InboxScreen : Tab {
}
},
actions = {
if (uiState.currentUserId != null) {
if (uiState.isLogged == true) {
Image(
modifier = Modifier.onClick {
model.reduce(InboxMviModel.Intent.ReadAll)
@ -124,64 +124,70 @@ object InboxScreen : Tab {
)
},
) { paddingValues ->
if (uiState.currentUserId == null) {
Column(
modifier = Modifier.padding(paddingValues).padding(horizontal = Spacing.m)
) {
Text(
text = stringResource(MR.strings.inbox_not_logged_message),
)
}
} else {
Column(
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
SectionSelector(
modifier = Modifier.padding(vertical = Spacing.s),
titles = listOf(
stringResource(MR.strings.inbox_section_replies),
stringResource(MR.strings.inbox_section_mentions),
stringResource(MR.strings.inbox_section_messages),
),
currentSection = when (uiState.section) {
InboxSection.MENTIONS -> 1
InboxSection.MESSAGES -> 2
else -> 0
},
onSectionSelected = {
val section = when (it) {
1 -> InboxSection.MENTIONS
2 -> InboxSection.MESSAGES
else -> InboxSection.REPLIES
}
model.reduce(InboxMviModel.Intent.ChangeSection(section))
},
)
val screens = remember {
listOf(
InboxRepliesScreen(),
InboxMentionsScreen(),
InboxMessagesScreen(),
when (uiState.isLogged) {
false -> {
Column(
modifier = Modifier.padding(paddingValues).padding(horizontal = Spacing.m)
) {
Text(
text = stringResource(MR.strings.inbox_not_logged_message),
)
}
TabNavigator(screens.first()) {
CurrentScreen()
val navigator = LocalTabNavigator.current
LaunchedEffect(model) {
model.uiState.map { it.section }.onEach { section ->
val index = when (section) {
InboxSection.REPLIES -> 0
InboxSection.MENTIONS -> 1
InboxSection.MESSAGES -> 2
}
true -> {
Column(
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
) {
SectionSelector(
modifier = Modifier.padding(vertical = Spacing.s),
titles = listOf(
stringResource(MR.strings.inbox_section_replies),
stringResource(MR.strings.inbox_section_mentions),
stringResource(MR.strings.inbox_section_messages),
),
currentSection = when (uiState.section) {
InboxSection.MENTIONS -> 1
InboxSection.MESSAGES -> 2
else -> 0
},
onSectionSelected = {
val section = when (it) {
1 -> InboxSection.MENTIONS
2 -> InboxSection.MESSAGES
else -> InboxSection.REPLIES
}
navigator.current = screens[index]
}.launchIn(this)
model.reduce(InboxMviModel.Intent.ChangeSection(section))
},
)
val screens = remember {
listOf(
InboxRepliesScreen(),
InboxMentionsScreen(),
InboxMessagesScreen(),
)
}
TabNavigator(screens.first()) {
CurrentScreen()
val navigator = LocalTabNavigator.current
LaunchedEffect(model) {
model.uiState.map { it.section }.onEach { section ->
val index = when (section) {
InboxSection.REPLIES -> 0
InboxSection.MENTIONS -> 1
InboxSection.MESSAGES -> 2
}
navigator.current = screens[index]
}.launchIn(this)
}
}
}
}
else -> Unit
}
}
}

View File

@ -4,17 +4,18 @@ 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.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.InboxCoordinator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
class InboxViewModel(
private val mvi: DefaultMviModel<InboxMviModel.Intent, InboxMviModel.UiState, InboxMviModel.Effect>,
private val identityRepository: IdentityRepository,
private val siteRepository: SiteRepository,
private val userRepository: UserRepository,
private val coordinator: InboxCoordinator,
) : ScreenModel,
@ -22,11 +23,10 @@ class InboxViewModel(
override fun onStarted() {
mvi.onStarted()
mvi.scope?.launch(Dispatchers.IO) {
val auth = identityRepository.authToken.value.orEmpty()
siteRepository.getCurrentUser(auth)?.also { user ->
mvi.updateState { it.copy(currentUserId = user.id) }
}
mvi.scope?.launch {
identityRepository.authToken.debounce(250).onEach { auth ->
mvi.updateState { it.copy(isLogged = !auth.isNullOrEmpty()) }
}.launchIn(this)
}
}

View File

@ -98,19 +98,21 @@ internal object ProfileContentScreen : Tab {
ProfileNotLoggedScreen,
ProfileLoggedScreen,
)
TabNavigator(ProfileNotLoggedScreen) {
CurrentScreen()
val navigator = LocalTabNavigator.current
LaunchedEffect(model) {
model.uiState.map { s -> s.logged }.distinctUntilChanged()
.onEach { logged ->
val index = when (logged) {
true -> 1
else -> 0
}
navigator.current = screens[index]
}.launchIn(this)
// wait until logging status is determined
if (uiState.logged != null) {
TabNavigator(ProfileNotLoggedScreen) {
CurrentScreen()
val navigator = LocalTabNavigator.current
LaunchedEffect(model) {
model.uiState.map { s -> s.logged }.distinctUntilChanged()
.onEach { logged ->
val index = when (logged) {
true -> 1
else -> 0
}
navigator.current = screens[index]
}.launchIn(this)
}
}
}
}

View File

@ -8,8 +8,10 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationC
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
class ProfileContentViewModel(
private val mvi: DefaultMviModel<ProfileContentMviModel.Intent, ProfileContentMviModel.UiState, ProfileContentMviModel.Effect>,
@ -22,8 +24,8 @@ class ProfileContentViewModel(
override fun onStarted() {
mvi.onStarted()
mvi.scope?.apply {
identityRepository.authToken.onEach { token ->
mvi.scope?.launch {
identityRepository.authToken.debounce(250).onEach { token ->
mvi.updateState { it.copy(logged = !token.isNullOrEmpty()) }
}.launchIn(this)
}