fix(posts, search, inbox, settings): reset defaults after logout

This commit is contained in:
Diego Beraldin 2023-09-10 22:14:47 +02:00
parent cc8e26f33f
commit 1b8d8828e6
17 changed files with 133 additions and 23 deletions

View File

@ -15,6 +15,7 @@ interface NotificationCenter {
sealed interface Event {
data class PostUpdate(val post: PostModel) : Event
data class CommentUpdate(val comment: CommentModel) : Event
object Logout : Event
}
/**

View File

@ -17,7 +17,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toSortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostsRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@ -84,21 +83,50 @@ class PostListViewModel(
it.copy(isLogged = isLogged)
}
}.launchIn(this)
notificationCenter.events.filterIsInstance<NotificationCenter.Event.PostUpdate>()
notificationCenter.events
.onEach { evt ->
val newPost = evt.post
mvi.updateState {
it.copy(
posts = it.posts.map { p ->
if (p.id == newPost.id) {
newPost
} else {
p
}
},
)
when (evt) {
is NotificationCenter.Event.PostUpdate -> {
val newPost = evt.post
mvi.updateState {
it.copy(
posts = it.posts.map { p ->
if (p.id == newPost.id) {
newPost
} else {
p
}
},
)
}
}
else -> Unit
}
}.launchIn(this)
notificationCenter.events
.onEach { evt ->
when (evt) {
NotificationCenter.Event.Logout -> {
currentPage = 1
val listingType =
keyStore[KeyStoreKeys.DefaultListingType, 0].toListingType()
val sortType =
keyStore[KeyStoreKeys.DefaultPostSortType, 0].toSortType()
mvi.updateState {
it.copy(
listingType = listingType,
sortType = sortType,
posts = emptyList(),
isLogged = false,
)
}
}
else -> Unit
}
}.launchIn(this)
}
if (mvi.uiState.value.posts.isEmpty()) {

View File

@ -53,6 +53,7 @@ kotlin {
implementation(projects.coreAppearance)
implementation(projects.coreCommonui)
implementation(projects.coreUtils)
implementation(projects.coreNotifications)
implementation(projects.domainLemmy.data)
implementation(projects.domainLemmy.repository)

View File

@ -31,6 +31,7 @@ val inboxTabModule = module {
siteRepository = get(),
hapticFeedback = get(),
coordinator = get(),
notificationCenter = get(),
)
}
factory {
@ -40,6 +41,7 @@ val inboxTabModule = module {
identityRepository = get(),
hapticFeedback = get(),
coordinator = get(),
notificationCenter = get(),
)
}
}

View File

@ -4,6 +4,7 @@ import cafe.adriel.voyager.core.model.ScreenModel
import com.github.diegoberaldin.racconforlemmy.core.utils.HapticFeedback
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
@ -23,6 +24,7 @@ class InboxMentionsViewModel(
private val userRepository: UserRepository,
private val hapticFeedback: HapticFeedback,
private val coordinator: InboxCoordinator,
private val notificationCenter: NotificationCenter,
) : ScreenModel,
MviModel<InboxMentionsMviModel.Intent, InboxMentionsMviModel.UiState, InboxMentionsMviModel.Effect> by mvi {
@ -41,6 +43,15 @@ class InboxMentionsViewModel(
changeUnreadOnly(it)
}
}.launchIn(this)
notificationCenter.events.onEach { evt ->
when (evt) {
NotificationCenter.Event.Logout -> {
mvi.updateState { it.copy(mentions = emptyList()) }
}
else -> Unit
}
}.launchIn(this)
}
}

View File

@ -19,7 +19,7 @@ interface InboxRepliesMviModel :
val loading: Boolean = false,
val canFetchMore: Boolean = true,
val unreadOnly: Boolean = true,
val mentions: List<PersonMentionModel> = emptyList(),
val replies: List<PersonMentionModel> = emptyList(),
)
sealed interface Effect

View File

@ -25,7 +25,6 @@ import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -45,10 +44,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCo
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailScreen
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
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.launchIn
import kotlinx.coroutines.flow.onEach
class InboxRepliesScreen : Tab {
override val options: TabOptions
@ -74,7 +69,7 @@ class InboxRepliesScreen : Tab {
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
) {
items(uiState.mentions) { mention ->
items(uiState.replies) { mention ->
SwipeableCard(
modifier = Modifier.fillMaxWidth(),
backgroundColor = {

View File

@ -4,6 +4,7 @@ import cafe.adriel.voyager.core.model.ScreenModel
import com.github.diegoberaldin.racconforlemmy.core.utils.HapticFeedback
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
@ -26,6 +27,7 @@ class InboxRepliesViewModel(
private val siteRepository: SiteRepository,
private val hapticFeedback: HapticFeedback,
private val coordinator: InboxCoordinator,
private val notificationCenter: NotificationCenter,
) : ScreenModel,
MviModel<InboxRepliesMviModel.Intent, InboxRepliesMviModel.UiState, InboxRepliesMviModel.Effect> by mvi {
@ -44,6 +46,15 @@ class InboxRepliesViewModel(
changeUnreadOnly(it)
}
}.launchIn(this)
notificationCenter.events.onEach { evt ->
when (evt) {
NotificationCenter.Event.Logout -> {
mvi.updateState { it.copy(replies = emptyList()) }
}
else -> Unit
}
}.launchIn(this)
}
}
@ -103,10 +114,10 @@ class InboxRepliesViewModel(
val newItems = if (refreshing) {
itemList
} else {
it.mentions + itemList
it.replies + itemList
}
it.copy(
mentions = newItems,
replies = newItems,
loading = false,
canFetchMore = canFetchMore,
refreshing = false,

View File

@ -56,6 +56,8 @@ kotlin {
implementation(projects.coreUtils)
implementation(projects.coreMd)
implementation(projects.coreCommonui)
implementation(projects.corePreferences)
implementation(projects.coreNotifications)
implementation(projects.domainIdentity)
implementation(projects.domainLemmy.data)
implementation(projects.domainLemmy.repository)

View File

@ -3,6 +3,9 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.profile.content
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.notifications.NotificationCenter
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.launchIn
import kotlinx.coroutines.flow.onEach
@ -10,6 +13,8 @@ import kotlinx.coroutines.flow.onEach
class ProfileContentViewModel(
private val mvi: DefaultMviModel<ProfileContentMviModel.Intent, ProfileContentMviModel.UiState, ProfileContentMviModel.Effect>,
private val identityRepository: IdentityRepository,
private val keyStore: TemporaryKeyStore,
private val notificationCenter: NotificationCenter,
) : ScreenModel,
MviModel<ProfileContentMviModel.Intent, ProfileContentMviModel.UiState, ProfileContentMviModel.Effect> by mvi {
@ -23,7 +28,15 @@ class ProfileContentViewModel(
override fun reduce(intent: ProfileContentMviModel.Intent) {
when (intent) {
ProfileContentMviModel.Intent.Logout -> identityRepository.clearToken()
ProfileContentMviModel.Intent.Logout -> logout()
}
}
private fun logout() {
keyStore.save(KeyStoreKeys.DefaultListingType, 0)
keyStore.save(KeyStoreKeys.DefaultCommentSortType, 13)
keyStore.save(KeyStoreKeys.DefaultPostSortType, 0)
identityRepository.clearToken()
notificationCenter.send(NotificationCenter.Event.Logout)
}
}

View File

@ -18,6 +18,8 @@ val profileTabModule = module {
ProfileContentViewModel(
mvi = DefaultMviModel(ProfileContentMviModel.UiState()),
identityRepository = get(),
keyStore = get(),
notificationCenter = get(),
)
}
factory {

View File

@ -53,6 +53,7 @@ kotlin {
implementation(projects.coreUtils)
implementation(projects.corePreferences)
implementation(projects.coreCommonui)
implementation(projects.coreNotifications)
implementation(projects.domainIdentity)
implementation(projects.domainLemmy.data)

View File

@ -3,6 +3,7 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.search.communitylist
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.notifications.NotificationCenter
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
@ -26,6 +27,7 @@ class CommunityListViewModel(
private val identityRepository: IdentityRepository,
private val communityRepository: CommunityRepository,
private val keyStore: TemporaryKeyStore,
private val notificationCenter: NotificationCenter,
) : ScreenModel,
MviModel<CommunityListMviModel.Intent, CommunityListMviModel.UiState, CommunityListMviModel.Effect> by mvi {
@ -45,6 +47,21 @@ class CommunityListViewModel(
it.copy(isLogged = isLogged)
}
}.launchIn(this)
notificationCenter.events.onEach { evt ->
when (evt) {
NotificationCenter.Event.Logout -> {
currentPage = 1
mvi.updateState {
it.copy(
listingType = ListingType.Local,
communities = emptyList(),
)
}
}
else -> Unit
}
}.launchIn(this)
}
if (mvi.uiState.value.communities.isEmpty()) {

View File

@ -13,6 +13,7 @@ val searchTabModule = module {
identityRepository = get(),
communityRepository = get(),
keyStore = get(),
notificationCenter = get(),
)
}
}

View File

@ -51,6 +51,7 @@ kotlin {
implementation(projects.coreArchitecture)
implementation(projects.coreUtils)
implementation(projects.coreCommonui)
implementation(projects.coreNotifications)
implementation(projects.resources)
implementation(projects.domainLemmy.data)
implementation(projects.domainIdentity)

View File

@ -9,6 +9,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.Theme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ColorSchemeProvider
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
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
@ -30,6 +31,7 @@ class SettingsScreenViewModel(
private val languageRepository: LanguageRepository,
private val identityRepository: IdentityRepository,
private val keyStore: TemporaryKeyStore,
private val notificationCenter: NotificationCenter,
) : ScreenModel,
MviModel<SettingsScreenMviModel.Intent, SettingsScreenMviModel.UiState, SettingsScreenMviModel.Effect> by mvi {
@ -54,6 +56,27 @@ class SettingsScreenViewModel(
identityRepository.authToken.onEach { auth ->
mvi.updateState { it.copy(isLogged = !auth.isNullOrEmpty()) }
}.launchIn(this)
notificationCenter.events.onEach { evt ->
when (evt) {
NotificationCenter.Event.Logout -> {
val listingType =
keyStore[KeyStoreKeys.DefaultListingType, 0].toListingType()
val postSortType =
keyStore[KeyStoreKeys.DefaultPostSortType, 0].toSortType()
val commentSortType =
keyStore[KeyStoreKeys.DefaultCommentSortType, 3].toSortType()
mvi.updateState {
it.copy(
defaultListingType = listingType,
defaultPostSortType = postSortType,
defaultCommentSortType = commentSortType,
)
}
}
else -> Unit
}
}.launchIn(this)
}
val listingType = keyStore[KeyStoreKeys.DefaultListingType, 0].toListingType()

View File

@ -16,6 +16,7 @@ val settingsTabModule = module {
languageRepository = get(),
identityRepository = get(),
colorSchemeProvider = get(),
notificationCenter = get(),
)
}
}