From 1b8d8828e6fce98ce95fe0d3e4ab6185b8b699c9 Mon Sep 17 00:00:00 2001 From: Diego Beraldin Date: Sun, 10 Sep 2023 22:14:47 +0200 Subject: [PATCH] fix(posts, search, inbox, settings): reset defaults after logout --- .../core/notifications/NotificationCenter.kt | 1 + .../home/postlist/PostListViewModel.kt | 54 ++++++++++++++----- feature-inbox/build.gradle.kts | 1 + .../feature/inbox/di/InboxModule.kt | 2 + .../inbox/mentions/InboxMentionsViewModel.kt | 11 ++++ .../inbox/replies/InboxRepliesMviModel.kt | 2 +- .../inbox/replies/InboxRepliesScreen.kt | 7 +-- .../inbox/replies/InboxRepliesViewModel.kt | 15 +++++- feature-profile/build.gradle.kts | 2 + .../content/ProfileContentViewModel.kt | 15 +++++- .../feature/profile/di/ProfileModule.kt | 2 + feature-search/build.gradle.kts | 1 + .../communitylist/CommunityListViewModel.kt | 17 ++++++ .../feature/search/di/SearchModule.kt | 1 + feature-settings/build.gradle.kts | 1 + .../content/SettingsScreenViewModel.kt | 23 ++++++++ .../feature/settings/di/SettingsModule.kt | 1 + 17 files changed, 133 insertions(+), 23 deletions(-) diff --git a/core-notifications/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/notifications/NotificationCenter.kt b/core-notifications/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/notifications/NotificationCenter.kt index b6e2ce87d..be0c6fda0 100644 --- a/core-notifications/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/notifications/NotificationCenter.kt +++ b/core-notifications/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/core/notifications/NotificationCenter.kt @@ -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 } /** diff --git a/feature-home/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/home/postlist/PostListViewModel.kt b/feature-home/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/home/postlist/PostListViewModel.kt index 1866eaede..52b5529ce 100644 --- a/feature-home/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/home/postlist/PostListViewModel.kt +++ b/feature-home/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/home/postlist/PostListViewModel.kt @@ -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.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()) { diff --git a/feature-inbox/build.gradle.kts b/feature-inbox/build.gradle.kts index 1185d8824..26cb96a25 100644 --- a/feature-inbox/build.gradle.kts +++ b/feature-inbox/build.gradle.kts @@ -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) diff --git a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/di/InboxModule.kt b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/di/InboxModule.kt index 412e17d16..350855fbe 100644 --- a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/di/InboxModule.kt +++ b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/di/InboxModule.kt @@ -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(), ) } } diff --git a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/mentions/InboxMentionsViewModel.kt b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/mentions/InboxMentionsViewModel.kt index 9e4bf8856..deeaf341a 100644 --- a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/mentions/InboxMentionsViewModel.kt +++ b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/mentions/InboxMentionsViewModel.kt @@ -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 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) } } diff --git a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesMviModel.kt b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesMviModel.kt index a6307b122..15c88f559 100644 --- a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesMviModel.kt +++ b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesMviModel.kt @@ -19,7 +19,7 @@ interface InboxRepliesMviModel : val loading: Boolean = false, val canFetchMore: Boolean = true, val unreadOnly: Boolean = true, - val mentions: List = emptyList(), + val replies: List = emptyList(), ) sealed interface Effect diff --git a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesScreen.kt b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesScreen.kt index 53bdafc41..0b1deff37 100644 --- a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesScreen.kt +++ b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesScreen.kt @@ -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 = { diff --git a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesViewModel.kt b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesViewModel.kt index fde669713..bbfc09642 100644 --- a/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesViewModel.kt +++ b/feature-inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/replies/InboxRepliesViewModel.kt @@ -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 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, diff --git a/feature-profile/build.gradle.kts b/feature-profile/build.gradle.kts index 95d812c71..e4bc53903 100644 --- a/feature-profile/build.gradle.kts +++ b/feature-profile/build.gradle.kts @@ -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) diff --git a/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/content/ProfileContentViewModel.kt b/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/content/ProfileContentViewModel.kt index 98031a53c..0753aecda 100644 --- a/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/content/ProfileContentViewModel.kt +++ b/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/content/ProfileContentViewModel.kt @@ -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, private val identityRepository: IdentityRepository, + private val keyStore: TemporaryKeyStore, + private val notificationCenter: NotificationCenter, ) : ScreenModel, MviModel 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) + } } diff --git a/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/di/ProfileModule.kt b/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/di/ProfileModule.kt index e28b47806..c1071a18a 100644 --- a/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/di/ProfileModule.kt +++ b/feature-profile/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/profile/di/ProfileModule.kt @@ -18,6 +18,8 @@ val profileTabModule = module { ProfileContentViewModel( mvi = DefaultMviModel(ProfileContentMviModel.UiState()), identityRepository = get(), + keyStore = get(), + notificationCenter = get(), ) } factory { diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts index 9533afb1b..2d3652b6d 100644 --- a/feature-search/build.gradle.kts +++ b/feature-search/build.gradle.kts @@ -53,6 +53,7 @@ kotlin { implementation(projects.coreUtils) implementation(projects.corePreferences) implementation(projects.coreCommonui) + implementation(projects.coreNotifications) implementation(projects.domainIdentity) implementation(projects.domainLemmy.data) diff --git a/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/communitylist/CommunityListViewModel.kt b/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/communitylist/CommunityListViewModel.kt index 9c361ff9e..1cd2cf9f8 100644 --- a/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/communitylist/CommunityListViewModel.kt +++ b/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/communitylist/CommunityListViewModel.kt @@ -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 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()) { diff --git a/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/di/SearchModule.kt b/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/di/SearchModule.kt index 8406abdf8..58d4ccbee 100644 --- a/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/di/SearchModule.kt +++ b/feature-search/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/search/di/SearchModule.kt @@ -13,6 +13,7 @@ val searchTabModule = module { identityRepository = get(), communityRepository = get(), keyStore = get(), + notificationCenter = get(), ) } } diff --git a/feature-settings/build.gradle.kts b/feature-settings/build.gradle.kts index 66189ccce..bcfebb024 100644 --- a/feature-settings/build.gradle.kts +++ b/feature-settings/build.gradle.kts @@ -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) diff --git a/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/content/SettingsScreenViewModel.kt b/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/content/SettingsScreenViewModel.kt index d30bee9c6..cb3ad1be5 100644 --- a/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/content/SettingsScreenViewModel.kt +++ b/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/content/SettingsScreenViewModel.kt @@ -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 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() diff --git a/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/di/SettingsModule.kt b/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/di/SettingsModule.kt index 41095204e..b83c9d0af 100644 --- a/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/di/SettingsModule.kt +++ b/feature-settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/di/SettingsModule.kt @@ -16,6 +16,7 @@ val settingsTabModule = module { languageRepository = get(), identityRepository = get(), colorSchemeProvider = get(), + notificationCenter = get(), ) } }