diff --git a/feature/inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/main/InboxViewModel.kt b/feature/inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/main/InboxViewModel.kt index e49970f77..0418c2673 100644 --- a/feature/inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/main/InboxViewModel.kt +++ b/feature/inbox/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/inbox/main/InboxViewModel.kt @@ -9,8 +9,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.toInboxUnreadOnly import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository import com.github.diegoberaldin.raccoonforlemmy.domain.inbox.InboxCoordinator import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -25,7 +23,6 @@ class InboxViewModel( DefaultMviModel( initialState = InboxMviModel.UiState(), ) { - init { screenModelScope.launch { identityRepository.isLogged.onEach { logged -> @@ -62,9 +59,10 @@ class InboxViewModel( override fun reduce(intent: InboxMviModel.Intent) { when (intent) { - is InboxMviModel.Intent.ChangeSection -> updateState { - it.copy(section = intent.value) - } + is InboxMviModel.Intent.ChangeSection -> + updateState { + it.copy(section = intent.value) + } InboxMviModel.Intent.ReadAll -> markAllRead() } @@ -78,7 +76,7 @@ class InboxViewModel( } private fun markAllRead() { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value userRepository.readAll(auth) emitEffect(InboxMviModel.Effect.Refresh) diff --git a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/advanced/AdvancedSettingsViewModel.kt b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/advanced/AdvancedSettingsViewModel.kt index 7fa99789b..cc5edaa22 100644 --- a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/advanced/AdvancedSettingsViewModel.kt +++ b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/advanced/AdvancedSettingsViewModel.kt @@ -23,8 +23,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toInt import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toListingType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -46,7 +44,6 @@ class AdvancedSettingsViewModel( DefaultMviModel( initialState = AdvancedSettingsMviModel.UiState(), ) { - init { screenModelScope.launch { themeRepository.navItemTitles.onEach { value -> @@ -155,7 +152,7 @@ class AdvancedSettingsViewModel( private fun changeNavBarTitlesVisible(value: Boolean) { themeRepository.changeNavItemTitles(value) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(navigationTitlesVisible = value) saveSettings(settings) } @@ -163,7 +160,7 @@ class AdvancedSettingsViewModel( private fun changeEnableDoubleTapAction(value: Boolean) { updateState { it.copy(enableDoubleTapAction = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(enableDoubleTapAction = value) saveSettings(settings) } @@ -171,7 +168,7 @@ class AdvancedSettingsViewModel( private fun changeAutoLoadImages(value: Boolean) { updateState { it.copy(autoLoadImages = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(autoLoadImages = value) saveSettings(settings) } @@ -179,7 +176,7 @@ class AdvancedSettingsViewModel( private fun changeAutoExpandComments(value: Boolean) { updateState { it.copy(autoExpandComments = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(autoExpandComments = value) saveSettings(settings) } @@ -187,7 +184,7 @@ class AdvancedSettingsViewModel( private fun changeHideNavigationBarWhileScrolling(value: Boolean) { updateState { it.copy(hideNavigationBarWhileScrolling = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(hideNavigationBarWhileScrolling = value) saveSettings(settings) } @@ -195,7 +192,7 @@ class AdvancedSettingsViewModel( private fun changeMarkAsReadWhileScrolling(value: Boolean) { updateState { it.copy(markAsReadWhileScrolling = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(markAsReadWhileScrolling = value) saveSettings(settings) } @@ -203,7 +200,7 @@ class AdvancedSettingsViewModel( private fun changeZombieModeInterval(value: Duration) { updateState { it.copy(zombieModeInterval = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(zombieModeInterval = value) saveSettings(settings) } @@ -211,7 +208,7 @@ class AdvancedSettingsViewModel( private fun changeZombieModeScrollAmount(value: Float) { updateState { it.copy(zombieModeScrollAmount = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(zombieModeScrollAmount = value) saveSettings(settings) } @@ -219,7 +216,7 @@ class AdvancedSettingsViewModel( private fun changeDefaultInboxUnreadOnly(value: Boolean) { updateState { it.copy(defaultInboxUnreadOnly = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(defaultInboxType = value.toInboxDefaultType()) saveSettings(settings) notificationCenter.send(NotificationCenterEvent.ResetInbox) @@ -228,7 +225,7 @@ class AdvancedSettingsViewModel( private fun changeSearchPostTitleOnly(value: Boolean) { updateState { it.copy(searchPostTitleOnly = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(searchPostTitleOnly = value) saveSettings(settings) } @@ -236,16 +233,15 @@ class AdvancedSettingsViewModel( private fun changeExploreType(value: ListingType) { updateState { it.copy(defaultExploreType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(defaultExploreType = value.toInt()) saveSettings(settings) } - } private fun changeEdgeToEdge(value: Boolean) { updateState { it.copy(edgeToEdge = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(edgeToEdge = value) saveSettings(settings) } @@ -253,19 +249,20 @@ class AdvancedSettingsViewModel( private fun changeInfiniteScrollDisabled(value: Boolean) { updateState { it.copy(infiniteScrollDisabled = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(infiniteScrollEnabled = !value) saveSettings(settings) } } private fun changeSystemBarTheme(value: UiBarTheme) { - val opaque = when (value) { - UiBarTheme.Opaque -> true - else -> false - } + val opaque = + when (value) { + UiBarTheme.Opaque -> true + else -> false + } updateState { it.copy(opaqueSystemBars = opaque) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(opaqueSystemBars = opaque) saveSettings(settings) } @@ -273,7 +270,7 @@ class AdvancedSettingsViewModel( private fun changeImageSourcePath(value: Boolean) { updateState { it.copy(imageSourcePath = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(imageSourcePath = value) saveSettings(settings) } @@ -289,7 +286,7 @@ class AdvancedSettingsViewModel( private fun changeDefaultLanguageId(value: Long?) { updateState { it.copy(defaultLanguageId = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(defaultLanguageId = value) saveSettings(settings) } @@ -297,7 +294,7 @@ class AdvancedSettingsViewModel( private fun changeInboxBackgroundCheckPeriod(value: Duration) { updateState { it.copy(inboxBackgroundCheckPeriod = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(inboxBackgroundCheckPeriod = value) saveSettings(settings) } @@ -305,7 +302,7 @@ class AdvancedSettingsViewModel( private fun changeFadeReadPosts(value: Boolean) { updateState { it.copy(fadeReadPosts = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(fadeReadPosts = value) saveSettings(settings) } @@ -313,7 +310,7 @@ class AdvancedSettingsViewModel( private fun changeShowUnreadPosts(value: Boolean) { updateState { it.copy(showUnreadComments = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(showUnreadComments = value) saveSettings(settings) } @@ -321,7 +318,7 @@ class AdvancedSettingsViewModel( private fun changeEnableButtonsToScrollBetweenComments(value: Boolean) { updateState { it.copy(enableButtonsToScrollBetweenComments = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value.copy(enableButtonsToScrollBetweenComments = value) saveSettings(settings) } diff --git a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/colors/SettingsColorAndFontViewModel.kt b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/colors/SettingsColorAndFontViewModel.kt index e6ba29fa8..13e489e2a 100644 --- a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/colors/SettingsColorAndFontViewModel.kt +++ b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/colors/SettingsColorAndFontViewModel.kt @@ -15,8 +15,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.SettingsMo import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -32,7 +30,6 @@ class SettingsColorAndFontViewModel( DefaultMviModel( initialState = SettingsColorAndFontMviModel.UiState(), ) { - init { screenModelScope.launch { themeRepository.uiTheme.onEach { value -> @@ -112,92 +109,99 @@ class SettingsColorAndFontViewModel( private fun changeFontFamily(value: UiFontFamily) { themeRepository.changeUiFontFamily(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - uiFontFamily = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + uiFontFamily = value.toInt(), + ) saveSettings(settings) } } private fun changeUiFontScale(value: Float) { themeRepository.changeUiFontScale(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - uiFontScale = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + uiFontScale = value, + ) saveSettings(settings) } } - - private fun changeDynamicColors(value: Boolean) { themeRepository.changeDynamicColors(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - dynamicColors = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + dynamicColors = value, + ) saveSettings(settings) } } private fun changeCustomSeedColor(value: Color?) { themeRepository.changeCustomSeedColor(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - customSeedColor = value?.toArgb() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + customSeedColor = value?.toArgb(), + ) saveSettings(settings) } } private fun changeUpVoteColor(value: Color?) { themeRepository.changeUpVoteColor(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - upVoteColor = value?.toArgb() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + upVoteColor = value?.toArgb(), + ) saveSettings(settings) } } private fun changeDownVoteColor(value: Color?) { themeRepository.changeDownVoteColor(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - downVoteColor = value?.toArgb() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + downVoteColor = value?.toArgb(), + ) saveSettings(settings) } } private fun changeReplyColor(value: Color?) { themeRepository.changeReplyColor(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - replyColor = value?.toArgb() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + replyColor = value?.toArgb(), + ) saveSettings(settings) } } private fun changeSaveColor(value: Color?) { themeRepository.changeSaveColor(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - saveColor = value?.toArgb() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + saveColor = value?.toArgb(), + ) saveSettings(settings) } } private fun changeCommentBarTheme(value: CommentBarTheme) { themeRepository.changeCommentBarTheme(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - commentBarTheme = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + commentBarTheme = value.toInt(), + ) saveSettings(settings) } } diff --git a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/main/SettingsViewModel.kt b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/main/SettingsViewModel.kt index 06cf86649..4dc547c58 100644 --- a/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/main/SettingsViewModel.kt +++ b/feature/settings/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/feature/settings/main/SettingsViewModel.kt @@ -23,8 +23,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toInt import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toListingType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toSortType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortTypesUseCase -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -43,7 +41,6 @@ class SettingsViewModel( DefaultMviModel( initialState = SettingsMviModel.UiState(), ) { - init { screenModelScope.launch { themeRepository.uiTheme.onEach { value -> @@ -130,30 +127,33 @@ class SettingsViewModel( private fun changeTheme(value: UiTheme?) { themeRepository.changeUiTheme(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - theme = value?.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + theme = value?.toInt(), + ) saveSettings(settings) } } private fun changeLanguage(value: String) { l10nManager.changeLanguage(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - locale = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + locale = value, + ) saveSettings(settings) } } private fun changeDefaultListingType(value: ListingType) { updateState { it.copy(defaultListingType = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - defaultListingType = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + defaultListingType = value.toInt(), + ) saveSettings(settings) notificationCenter.send(NotificationCenterEvent.ResetHome) } @@ -161,10 +161,11 @@ class SettingsViewModel( private fun changeDefaultPostSortType(value: SortType) { updateState { it.copy(defaultPostSortType = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - defaultPostSortType = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + defaultPostSortType = value.toInt(), + ) saveSettings(settings) notificationCenter.send(NotificationCenterEvent.ResetHome) } @@ -172,20 +173,22 @@ class SettingsViewModel( private fun changeDefaultCommentSortType(value: SortType) { updateState { it.copy(defaultCommentSortType = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - defaultCommentSortType = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + defaultCommentSortType = value.toInt(), + ) saveSettings(settings) } } private fun changeIncludeNsfw(value: Boolean) { updateState { it.copy(includeNsfw = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - includeNsfw = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + includeNsfw = value, + ) saveSettings(settings) notificationCenter.send(NotificationCenterEvent.ResetHome) notificationCenter.send(NotificationCenterEvent.ResetExplore) @@ -194,30 +197,33 @@ class SettingsViewModel( private fun changeBlurNsfw(value: Boolean) { updateState { it.copy(blurNsfw = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - blurNsfw = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + blurNsfw = value, + ) saveSettings(settings) } } private fun changeUrlOpeningMode(value: UrlOpeningMode) { updateState { it.copy(urlOpeningMode = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - urlOpeningMode = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + urlOpeningMode = value.toInt(), + ) saveSettings(settings) } } private fun changeEnableSwipeActions(value: Boolean) { updateState { it.copy(enableSwipeActions = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - enableSwipeActions = value - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + enableSwipeActions = value, + ) saveSettings(settings) } } @@ -234,7 +240,7 @@ class SettingsViewModel( } private fun handleLogout() { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val settings = settingsRepository.getSettings(null) updateState { it.copy( diff --git a/shared/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/MainViewModel.kt b/shared/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/MainViewModel.kt index 221048343..0bb1ae308 100644 --- a/shared/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/MainViewModel.kt +++ b/shared/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/MainViewModel.kt @@ -6,8 +6,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.Sett import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository import com.github.diegoberaldin.raccoonforlemmy.domain.inbox.InboxCoordinator import com.github.diegoberaldin.raccoonforlemmy.domain.inbox.notification.InboxNotificationChecker -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map @@ -23,9 +21,8 @@ class MainViewModel( DefaultMviModel( initialState = MainScreenMviModel.UiState(), ) { - init { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { identityRepository.startup() inboxCoordinator.totalUnread.onEach { unreadCount -> diff --git a/unit/chat/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/chat/InboxChatViewModel.kt b/unit/chat/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/chat/InboxChatViewModel.kt index a757f86ef..b97382b70 100644 --- a/unit/chat/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/chat/InboxChatViewModel.kt +++ b/unit/chat/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/chat/InboxChatViewModel.kt @@ -11,12 +11,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepo import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PrivateMessageRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class InboxChatViewModel( private val otherUserId: Long, @@ -31,7 +28,6 @@ class InboxChatViewModel( DefaultMviModel( initialState = InboxChatMviModel.UiState(), ) { - private var currentPage: Int = 1 init { @@ -51,24 +47,23 @@ class InboxChatViewModel( handleLogout() }.launchIn(this) - withContext(Dispatchers.IO) { - val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0 - updateState { it.copy(currentUserId = currentUserId) } + val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0 + updateState { it.copy(currentUserId = currentUserId) } - val user = userRepository.get( + val user = + userRepository.get( id = otherUserId, auth = auth, ) - updateState { - it.copy( - otherUserName = user?.name.orEmpty(), - otherUserAvatar = user?.avatar, - ) - } + updateState { + it.copy( + otherUserName = user?.name.orEmpty(), + otherUserAvatar = user?.avatar, + ) + } - if (uiState.value.messages.isEmpty()) { - refresh(initial = true) - } + if (uiState.value.messages.isEmpty()) { + refresh(initial = true) } } } @@ -127,30 +122,33 @@ class InboxChatViewModel( updateState { it.copy(loading = true) } val auth = identityRepository.authToken.value val refreshing = currentState.refreshing - val itemList = messageRepository.getAll( - creatorId = otherUserId, - auth = auth, - page = currentPage, - unreadOnly = false, - )?.onEach { - if (!it.read) { - markAsRead(true, it.id) + val itemList = + messageRepository.getAll( + creatorId = otherUserId, + auth = auth, + page = currentPage, + unreadOnly = false, + )?.onEach { + if (!it.read) { + markAsRead(true, it.id) + } } - } if (!itemList.isNullOrEmpty()) { currentPage++ } - val itemsToAdd = itemList.orEmpty().filter { - it.creator?.id == otherUserId || it.recipient?.id == otherUserId - } + val itemsToAdd = + itemList.orEmpty().filter { + it.creator?.id == otherUserId || it.recipient?.id == otherUserId + } val shouldTryNextPage = itemsToAdd.isEmpty() && tryCount < 10 updateState { - val newItems = if (refreshing) { - itemsToAdd - } else { - it.messages + itemsToAdd - } + val newItems = + if (refreshing) { + itemsToAdd + } else { + it.messages + itemsToAdd + } it.copy( messages = newItems, loading = false, @@ -164,14 +162,18 @@ class InboxChatViewModel( } } - private fun markAsRead(read: Boolean, messageId: Long) { + private fun markAsRead( + read: Boolean, + messageId: Long, + ) { val auth = identityRepository.authToken.value screenModelScope.launch { - val newMessage = messageRepository.markAsRead( - read = read, - messageId = messageId, - auth = auth, - ) + val newMessage = + messageRepository.markAsRead( + read = read, + messageId = messageId, + auth = auth, + ) if (newMessage != null) { handleMessageUpdate(newMessage) } @@ -181,13 +183,14 @@ class InboxChatViewModel( private fun handleMessageUpdate(newMessage: PrivateMessageModel) { updateState { it.copy( - messages = it.messages.map { msg -> - if (msg.id == newMessage.id) { - newMessage - } else { - msg - } - } + messages = + it.messages.map { msg -> + if (msg.id == newMessage.id) { + newMessage + } else { + msg + } + }, ) } } @@ -225,30 +228,32 @@ class InboxChatViewModel( if (text.isNotEmpty()) { screenModelScope.launch { val auth = identityRepository.authToken.value - val newMessage = if (isEditing) { - messageRepository.edit( - messageId = editedMessageId ?: 0, - message = text, - auth = auth, - ) - } else { - messageRepository.create( - message = text, - recipientId = otherUserId, - auth = auth, - ) - } - val newMessages = if (isEditing) { - uiState.value.messages.map { msg -> - if (msg.id == newMessage?.id) { - newMessage - } else { - msg - } + val newMessage = + if (isEditing) { + messageRepository.edit( + messageId = editedMessageId ?: 0, + message = text, + auth = auth, + ) + } else { + messageRepository.create( + message = text, + recipientId = otherUserId, + auth = auth, + ) + } + val newMessages = + if (isEditing) { + uiState.value.messages.map { msg -> + if (msg.id == newMessage?.id) { + newMessage + } else { + msg + } + } + } else { + (newMessage?.let { listOf(it) } ?: emptyList()) + uiState.value.messages } - } else { - (newMessage?.let { listOf(it) } ?: emptyList()) + uiState.value.messages - } updateState { it.copy( messages = newMessages, diff --git a/unit/communitydetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/communitydetail/CommunityDetailViewModel.kt b/unit/communitydetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/communitydetail/CommunityDetailViewModel.kt index 86ffcc164..4034170f6 100644 --- a/unit/communitydetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/communitydetail/CommunityDetailViewModel.kt +++ b/unit/communitydetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/communitydetail/CommunityDetailViewModel.kt @@ -32,9 +32,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortT import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.LemmyItemCache import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.debounce @@ -70,7 +68,6 @@ class CommunityDetailViewModel( DefaultMviModel( initialState = CommunityDetailMviModel.UiState(), ) { - private var hideReadPosts = false private val searchEventChannel = Channel() @@ -81,8 +78,9 @@ class CommunityDetailViewModel( updateState { it.copy( community = community, - instance = otherInstance.takeIf { n -> n.isNotEmpty() } - ?: apiConfigurationRepository.instance.value, + instance = + otherInstance.takeIf { n -> n.isNotEmpty() } + ?: apiConfigurationRepository.instance.value, ) } } @@ -133,16 +131,17 @@ class CommunityDetailViewModel( val newUser = evt.user updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == postId) { - p.copy( - creator = newUser, - updateDate = newUser.updateDate, - ) - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == postId) { + p.copy( + creator = newUser, + updateDate = newUser.updateDate, + ) + } else { + p + } + }, ) } }.launchIn(this) @@ -204,13 +203,15 @@ class CommunityDetailViewModel( override fun reduce(intent: CommunityDetailMviModel.Intent) { when (intent) { - CommunityDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch(Dispatchers.IO) { - loadNextPage() - } + CommunityDetailMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - CommunityDetailMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) { - refresh() - } + CommunityDetailMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + } is CommunityDetailMviModel.Intent.DownVotePost -> { if (intent.feedback) { @@ -274,15 +275,17 @@ class CommunityDetailViewModel( ) } - is CommunityDetailMviModel.Intent.ModFeaturePost -> uiState.value.posts.firstOrNull { it.id == intent.id } - ?.also { post -> - feature(post = post) - } + is CommunityDetailMviModel.Intent.ModFeaturePost -> + uiState.value.posts.firstOrNull { it.id == intent.id } + ?.also { post -> + feature(post = post) + } - is CommunityDetailMviModel.Intent.ModLockPost -> uiState.value.posts.firstOrNull { it.id == intent.id } - ?.also { post -> - lock(post = post) - } + is CommunityDetailMviModel.Intent.ModLockPost -> + uiState.value.posts.firstOrNull { it.id == intent.id } + ?.also { post -> + lock(post = post) + } is CommunityDetailMviModel.Intent.ModToggleModUser -> { toggleModeratorStatus(intent.id) @@ -300,9 +303,10 @@ class CommunityDetailViewModel( } is CommunityDetailMviModel.Intent.SetSearch -> updateSearchText(intent.value) - is CommunityDetailMviModel.Intent.Copy -> screenModelScope.launch { - emitEffect(CommunityDetailMviModel.Effect.TriggerCopy(intent.value)) - } + is CommunityDetailMviModel.Intent.Copy -> + screenModelScope.launch { + emitEffect(CommunityDetailMviModel.Effect.TriggerCopy(intent.value)) + } CommunityDetailMviModel.Intent.WillOpenDetail -> { val state = postPaginationManager.extractState() @@ -327,22 +331,24 @@ class CommunityDetailViewModel( otherInstance = otherInstance, query = currentState.searchText.takeIf { currentState.searching }, includeNsfw = settingsRepository.currentSettings.value.includeNsfw, - ) + ), ) updateState { it.copy(canFetchMore = true, refreshing = true) } val auth = identityRepository.authToken.value val accountId = accountRepository.getActive()?.id val isFavorite = favoriteCommunityRepository.getBy(accountId, currentState.community.id) != null - val refreshedCommunity = communityRepository.get( - auth = auth, - name = currentState.community.name, - id = currentState.community.id, - instance = otherInstance, - )?.copy(favorite = isFavorite) - val moderators = communityRepository.getModerators( - auth = auth, - id = currentState.community.id, - ) + val refreshedCommunity = + communityRepository.get( + auth = auth, + name = currentState.community.name, + id = currentState.community.id, + instance = otherInstance, + )?.copy(favorite = isFavorite) + val moderators = + communityRepository.getModerators( + auth = auth, + id = currentState.community.id, + ) if (refreshedCommunity != null) { updateState { it.copy( @@ -362,7 +368,7 @@ class CommunityDetailViewModel( return } updateState { it.copy(sortType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(CommunityDetailMviModel.Effect.BackToTop) delay(50) refresh() @@ -376,26 +382,27 @@ class CommunityDetailViewModel( return } updateState { it.copy(loading = true) } - val posts = postPaginationManager.loadNextPage().let { - if (!hideReadPosts) { - it - } else { - it.filter { post -> !post.read } - } - }.let { - if (currentState.searching) { - it.filter { post -> - listOf(post.title, post.text).any { s -> - s.contains( - other = currentState.searchText, - ignoreCase = true, - ) - } + val posts = + postPaginationManager.loadNextPage().let { + if (!hideReadPosts) { + it + } else { + it.filter { post -> !post.read } + } + }.let { + if (currentState.searching) { + it.filter { post -> + listOf(post.title, post.text).any { s -> + s.contains( + other = currentState.searchText, + ignoreCase = true, + ) + } + } + } else { + it } - } else { - it } - } if (uiState.value.autoLoadImages) { posts.forEach { post -> post.imageUrl.takeIf { i -> i.isNotEmpty() }?.also { url -> @@ -415,12 +422,13 @@ class CommunityDetailViewModel( private fun toggleUpVotePost(post: PostModel) { val newValue = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newValue, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.upVote( @@ -444,7 +452,7 @@ class CommunityDetailViewModel( return } val newPost = post.copy(read = true) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.setRead( @@ -462,12 +470,13 @@ class CommunityDetailViewModel( private fun toggleDownVotePost(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.downVote( @@ -488,12 +497,13 @@ class CommunityDetailViewModel( private fun toggleSavePost(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.save( @@ -514,11 +524,12 @@ class CommunityDetailViewModel( private fun subscribe() { hapticFeedback.vibrate() - screenModelScope.launch(Dispatchers.IO) { - val community = communityRepository.subscribe( - auth = identityRepository.authToken.value, - id = communityId, - ) + screenModelScope.launch { + val community = + communityRepository.subscribe( + auth = identityRepository.authToken.value, + id = communityId, + ) if (community != null) { updateState { it.copy(community = community) } notificationCenter.send(NotificationCenterEvent.CommunitySubscriptionChanged(community)) @@ -528,11 +539,12 @@ class CommunityDetailViewModel( private fun unsubscribe() { hapticFeedback.vibrate() - screenModelScope.launch(Dispatchers.IO) { - val community = communityRepository.unsubscribe( - auth = identityRepository.authToken.value, - id = communityId, - ) + screenModelScope.launch { + val community = + communityRepository.unsubscribe( + auth = identityRepository.authToken.value, + id = communityId, + ) if (community != null) { updateState { it.copy(community = community) } notificationCenter.send(NotificationCenterEvent.CommunitySubscriptionChanged(community)) @@ -543,13 +555,14 @@ class CommunityDetailViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == post.id) { - post - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == post.id) { + post + } else { + p + } + }, ) } } @@ -560,7 +573,7 @@ class CommunityDetailViewModel( private fun blockCommunity() { updateState { it.copy(asyncInProgress = true) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value communityRepository.block(communityId, true, auth).getOrThrow() @@ -575,7 +588,7 @@ class CommunityDetailViewModel( private fun blockInstance() { updateState { it.copy(asyncInProgress = true) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val community = uiState.value.community val instanceId = community.instanceId @@ -611,13 +624,14 @@ class CommunityDetailViewModel( } private fun feature(post: PostModel) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value.orEmpty() - val newPost = postRepository.featureInCommunity( - postId = post.id, - auth = auth, - featured = !post.featuredCommunity - ) + val newPost = + postRepository.featureInCommunity( + postId = post.id, + auth = auth, + featured = !post.featuredCommunity, + ) if (newPost != null) { handlePostUpdate(newPost) } @@ -625,13 +639,14 @@ class CommunityDetailViewModel( } private fun lock(post: PostModel) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value.orEmpty() - val newPost = postRepository.lock( - postId = post.id, - auth = auth, - locked = !post.locked, - ) + val newPost = + postRepository.lock( + postId = post.id, + auth = auth, + locked = !post.locked, + ) if (newPost != null) { handlePostUpdate(newPost) } @@ -639,15 +654,16 @@ class CommunityDetailViewModel( } private fun toggleModeratorStatus(userId: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val isModerator = uiState.value.moderators.containsId(userId) val auth = identityRepository.authToken.value.orEmpty() - val newModerators = communityRepository.addModerator( - auth = auth, - communityId = communityId, - added = !isModerator, - userId = userId, - ) + val newModerators = + communityRepository.addModerator( + auth = auth, + communityId = communityId, + added = !isModerator, + userId = userId, + ) updateState { it.copy(moderators = newModerators) } @@ -655,7 +671,7 @@ class CommunityDetailViewModel( } private fun toggleFavorite() { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val accountId = accountRepository.getActive()?.id ?: 0L val newValue = !uiState.value.community.favorite if (newValue) { diff --git a/unit/configurecontentview/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configurecontentview/ConfigureContentViewViewModel.kt b/unit/configurecontentview/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configurecontentview/ConfigureContentViewViewModel.kt index e8fe18761..bc053f5f2 100644 --- a/unit/configurecontentview/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configurecontentview/ConfigureContentViewViewModel.kt +++ b/unit/configurecontentview/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configurecontentview/ConfigureContentViewViewModel.kt @@ -13,8 +13,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationC import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.SettingsModel import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -29,9 +27,8 @@ class ConfigureContentViewViewModel( private val notificationCenter: NotificationCenter, ) : ConfigureContentViewMviModel, DefaultMviModel( - initialState = ConfigureContentViewMviModel.State() + initialState = ConfigureContentViewMviModel.State(), ) { - init { screenModelScope.launch { themeRepository.postLayout.onEach { value -> @@ -124,114 +121,128 @@ class ConfigureContentViewViewModel( private fun changePostLayout(value: PostLayout) { themeRepository.changePostLayout(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - postLayout = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + postLayout = value.toInt(), + ) saveSettings(settings) } } private fun changeVoteFormat(value: VoteFormat) { updateState { it.copy(voteFormat = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.let { - if (value == VoteFormat.Hidden) { - it.copy(showScores = false) - } else { - it.copy( - voteFormat = value, - showScores = true, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.let { + if (value == VoteFormat.Hidden) { + it.copy(showScores = false) + } else { + it.copy( + voteFormat = value, + showScores = true, + ) + } } - } saveSettings(settings) } } private fun changeFullHeightImages(value: Boolean) { updateState { it.copy(fullHeightImages = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - fullHeightImages = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + fullHeightImages = value, + ) saveSettings(settings) } } private fun changeFullWidthImages(value: Boolean) { updateState { it.copy(fullWidthImages = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - fullWidthImages = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + fullWidthImages = value, + ) saveSettings(settings) } } private fun changePreferUserNicknames(value: Boolean) { updateState { it.copy(preferUserNicknames = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - preferUserNicknames = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + preferUserNicknames = value, + ) saveSettings(settings) } } private fun changePostBodyMaxLines(value: Int?) { updateState { it.copy(postBodyMaxLines = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - postBodyMaxLines = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + postBodyMaxLines = value, + ) saveSettings(settings) } } - private fun changeContentFontScale(value: Float, contentClass: ContentFontClass) { - val contentFontScale = themeRepository.contentFontScale.value.let { - when (contentClass) { - ContentFontClass.Title -> it.copy(title = value) - ContentFontClass.Body -> it.copy(body = value) - ContentFontClass.Comment -> it.copy(comment = value) - ContentFontClass.AncillaryText -> it.copy(ancillary = value) + private fun changeContentFontScale( + value: Float, + contentClass: ContentFontClass, + ) { + val contentFontScale = + themeRepository.contentFontScale.value.let { + when (contentClass) { + ContentFontClass.Title -> it.copy(title = value) + ContentFontClass.Body -> it.copy(body = value) + ContentFontClass.Comment -> it.copy(comment = value) + ContentFontClass.AncillaryText -> it.copy(ancillary = value) + } } - } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - contentFontScale = contentFontScale, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + contentFontScale = contentFontScale, + ) saveSettings(settings) } } private fun changeContentFontFamily(value: UiFontFamily) { themeRepository.changeContentFontFamily(value) - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - contentFontFamily = value.toInt() - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + contentFontFamily = value.toInt(), + ) saveSettings(settings) } } private fun changeCommentBarThickness(value: Int) { updateState { it.copy(commentBarThickness = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - commentBarThickness = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + commentBarThickness = value, + ) saveSettings(settings) } } private fun changeCommentIndentAmount(value: Int) { updateState { it.copy(commentIndentAmount = value) } - screenModelScope.launch(Dispatchers.IO) { - val settings = settingsRepository.currentSettings.value.copy( - commentIndentAmount = value, - ) + screenModelScope.launch { + val settings = + settingsRepository.currentSettings.value.copy( + commentIndentAmount = value, + ) saveSettings(settings) } } @@ -241,4 +252,4 @@ class ConfigureContentViewViewModel( settingsRepository.updateSettings(settings, accountId) settingsRepository.changeCurrentSettings(settings) } -} \ No newline at end of file +} diff --git a/unit/configureswipeactions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configureswipeactions/ConfigureSwipeActionsViewModel.kt b/unit/configureswipeactions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configureswipeactions/ConfigureSwipeActionsViewModel.kt index 9daa6f5ad..48b24e492 100644 --- a/unit/configureswipeactions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configureswipeactions/ConfigureSwipeActionsViewModel.kt +++ b/unit/configureswipeactions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/configureswipeactions/ConfigureSwipeActionsViewModel.kt @@ -9,8 +9,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.ActionOnSw import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.ActionOnSwipeTarget import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -23,26 +21,28 @@ class ConfigureSwipeActionsViewModel( DefaultMviModel( initialState = ConfigureSwipeActionsMviModel.UiState(), ) { - init { screenModelScope.launch { notificationCenter.subscribe(NotificationCenterEvent.ActionsOnSwipeSelected::class) .onEach { evt -> when (evt.target) { - ActionOnSwipeTarget.Posts -> addActionPosts( - action = evt.value, - direction = evt.direction, - ) + ActionOnSwipeTarget.Posts -> + addActionPosts( + action = evt.value, + direction = evt.direction, + ) - ActionOnSwipeTarget.Comments -> addActionComments( - action = evt.value, - direction = evt.direction, - ) + ActionOnSwipeTarget.Comments -> + addActionComments( + action = evt.value, + direction = evt.direction, + ) - ActionOnSwipeTarget.Inbox -> addActionInbox( - action = evt.value, - direction = evt.direction, - ) + ActionOnSwipeTarget.Inbox -> + addActionInbox( + action = evt.value, + direction = evt.direction, + ) } }.launchIn(this) } @@ -51,20 +51,23 @@ class ConfigureSwipeActionsViewModel( override fun reduce(intent: ConfigureSwipeActionsMviModel.Intent) { when (intent) { - is ConfigureSwipeActionsMviModel.Intent.DeleteActionComments -> removeActionComments( - action = intent.value, - direction = intent.direction, - ) + is ConfigureSwipeActionsMviModel.Intent.DeleteActionComments -> + removeActionComments( + action = intent.value, + direction = intent.direction, + ) - is ConfigureSwipeActionsMviModel.Intent.DeleteActionInbox -> removeActionInbox( - action = intent.value, - direction = intent.direction, - ) + is ConfigureSwipeActionsMviModel.Intent.DeleteActionInbox -> + removeActionInbox( + action = intent.value, + direction = intent.direction, + ) - is ConfigureSwipeActionsMviModel.Intent.DeleteActionPosts -> removeActionPosts( - action = intent.value, - direction = intent.direction, - ) + is ConfigureSwipeActionsMviModel.Intent.DeleteActionPosts -> + removeActionPosts( + action = intent.value, + direction = intent.direction, + ) ConfigureSwipeActionsMviModel.Intent.ResetActionsComments -> resetActionsComments() ConfigureSwipeActionsMviModel.Intent.ResetActionsInbox -> resetActionsInbox() @@ -87,28 +90,35 @@ class ConfigureSwipeActionsViewModel( updateAvailableOptions() } - private fun addActionPosts(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun addActionPosts( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartPosts + action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartPosts + action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndPosts + action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndPosts + action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartPosts = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartPosts = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndPosts = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndPosts = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -130,28 +140,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun removeActionPosts(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun removeActionPosts( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartPosts - action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartPosts - action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndPosts - action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndPosts - action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartPosts = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartPosts = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndPosts = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndPosts = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -173,28 +190,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun addActionComments(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun addActionComments( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartComments + action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartComments + action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndComments + action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndComments + action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartComments = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartComments = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndComments = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndComments = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -216,28 +240,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun removeActionComments(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun removeActionComments( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartComments - action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartComments - action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndComments - action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndComments - action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartComments = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartComments = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndComments = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndComments = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -259,28 +290,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun addActionInbox(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun addActionInbox( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartInbox + action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartInbox + action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndInbox + action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndInbox + action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartInbox = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartInbox = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndInbox = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndInbox = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -302,28 +340,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun removeActionInbox(action: ActionOnSwipe, direction: ActionOnSwipeDirection) { - screenModelScope.launch(Dispatchers.IO) { + private fun removeActionInbox( + action: ActionOnSwipe, + direction: ActionOnSwipeDirection, + ) { + screenModelScope.launch { val settings = settingsRepository.currentSettings.value val accountId = accountRepository.getActive()?.id ?: return@launch - val newActions = when (direction) { - ActionOnSwipeDirection.ToStart -> { - (settings.actionsOnSwipeToStartInbox - action).toSet().toList() - } + val newActions = + when (direction) { + ActionOnSwipeDirection.ToStart -> { + (settings.actionsOnSwipeToStartInbox - action).toSet().toList() + } - ActionOnSwipeDirection.ToEnd -> { - (settings.actionsOnSwipeToEndInbox - action).toSet().toList() + ActionOnSwipeDirection.ToEnd -> { + (settings.actionsOnSwipeToEndInbox - action).toSet().toList() + } } - } - val newSettings = when (direction) { - ActionOnSwipeDirection.ToStart -> settings.copy( - actionsOnSwipeToStartInbox = newActions - ) + val newSettings = + when (direction) { + ActionOnSwipeDirection.ToStart -> + settings.copy( + actionsOnSwipeToStartInbox = newActions, + ) - ActionOnSwipeDirection.ToEnd -> settings.copy( - actionsOnSwipeToEndInbox = newActions - ) - } + ActionOnSwipeDirection.ToEnd -> + settings.copy( + actionsOnSwipeToEndInbox = newActions, + ) + } settingsRepository.updateSettings(settings = newSettings, accountId = accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -347,11 +392,12 @@ class ConfigureSwipeActionsViewModel( private fun resetActionsPosts() { val settings = settingsRepository.currentSettings.value - val newSettings = settings.copy( - actionsOnSwipeToStartPosts = ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS, - actionsOnSwipeToEndPosts = ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS, - ) - screenModelScope.launch(Dispatchers.IO) { + val newSettings = + settings.copy( + actionsOnSwipeToStartPosts = ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS, + actionsOnSwipeToEndPosts = ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS, + ) + screenModelScope.launch { val accountId = accountRepository.getActive()?.id ?: return@launch settingsRepository.updateSettings(newSettings, accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -362,11 +408,12 @@ class ConfigureSwipeActionsViewModel( private fun resetActionsComments() { val settings = settingsRepository.currentSettings.value - val newSettings = settings.copy( - actionsOnSwipeToStartComments = ActionOnSwipe.DEFAULT_SWIPE_TO_START_COMMENTS, - actionsOnSwipeToEndComments = ActionOnSwipe.DEFAULT_SWIPE_TO_END_COMMENTS, - ) - screenModelScope.launch(Dispatchers.IO) { + val newSettings = + settings.copy( + actionsOnSwipeToStartComments = ActionOnSwipe.DEFAULT_SWIPE_TO_START_COMMENTS, + actionsOnSwipeToEndComments = ActionOnSwipe.DEFAULT_SWIPE_TO_END_COMMENTS, + ) + screenModelScope.launch { val accountId = accountRepository.getActive()?.id ?: return@launch settingsRepository.updateSettings(newSettings, accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -377,11 +424,12 @@ class ConfigureSwipeActionsViewModel( private fun resetActionsInbox() { val settings = settingsRepository.currentSettings.value - val newSettings = settings.copy( - actionsOnSwipeToStartInbox = ActionOnSwipe.DEFAULT_SWIPE_TO_START_INBOX, - actionsOnSwipeToEndInbox = ActionOnSwipe.DEFAULT_SWIPE_TO_END_INBOX, - ) - screenModelScope.launch(Dispatchers.IO) { + val newSettings = + settings.copy( + actionsOnSwipeToStartInbox = ActionOnSwipe.DEFAULT_SWIPE_TO_START_INBOX, + actionsOnSwipeToEndInbox = ActionOnSwipe.DEFAULT_SWIPE_TO_END_INBOX, + ) + screenModelScope.launch { val accountId = accountRepository.getActive()?.id ?: return@launch settingsRepository.updateSettings(newSettings, accountId) settingsRepository.changeCurrentSettings(newSettings) @@ -390,34 +438,35 @@ class ConfigureSwipeActionsViewModel( } } - private fun updateAvailableOptions( - preventActionsOnBothSides: Boolean = false, - ) { + private fun updateAvailableOptions(preventActionsOnBothSides: Boolean = false) { val currentState = uiState.value - val actionsPosts: Set = buildSet { - this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS - this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_POSTS - if (preventActionsOnBothSides) { - this -= currentState.actionsOnSwipeToStartPosts.toSet() - this -= currentState.actionsOnSwipeToEndPosts.toSet() + val actionsPosts: Set = + buildSet { + this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS + this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_POSTS + if (preventActionsOnBothSides) { + this -= currentState.actionsOnSwipeToStartPosts.toSet() + this -= currentState.actionsOnSwipeToEndPosts.toSet() + } } - } - val actionsComments: Set = buildSet { - this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_COMMENTS - this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_COMMENTS - if (preventActionsOnBothSides) { - this -= currentState.actionsOnSwipeToStartComments.toSet() - this -= currentState.actionsOnSwipeToEndComments.toSet() + val actionsComments: Set = + buildSet { + this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_COMMENTS + this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_COMMENTS + if (preventActionsOnBothSides) { + this -= currentState.actionsOnSwipeToStartComments.toSet() + this -= currentState.actionsOnSwipeToEndComments.toSet() + } } - } - val actionsInbox: Set = buildSet { - this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_INBOX - this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_INBOX - if (preventActionsOnBothSides) { - this -= currentState.actionsOnSwipeToStartInbox.toSet() - this -= currentState.actionsOnSwipeToEndInbox.toSet() + val actionsInbox: Set = + buildSet { + this += ActionOnSwipe.DEFAULT_SWIPE_TO_START_INBOX + this += ActionOnSwipe.DEFAULT_SWIPE_TO_END_INBOX + if (preventActionsOnBothSides) { + this -= currentState.actionsOnSwipeToStartInbox.toSet() + this -= currentState.actionsOnSwipeToEndInbox.toSet() + } } - } updateState { it.copy( availableOptionsPosts = actionsPosts.toList(), diff --git a/unit/drawer/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/drawer/ModalDrawerViewModel.kt b/unit/drawer/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/drawer/ModalDrawerViewModel.kt index 3742f6f66..ee36f7a71 100644 --- a/unit/drawer/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/drawer/ModalDrawerViewModel.kt +++ b/unit/drawer/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/drawer/ModalDrawerViewModel.kt @@ -13,10 +13,8 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.Ident import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.channelFlow @@ -28,7 +26,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import kotlinx.coroutines.yield @@ -44,9 +41,8 @@ class ModalDrawerViewModel( private val notificationCenter: NotificationCenter, ) : ModalDrawerMviModel, DefaultMviModel( - initialState = ModalDrawerMviModel.UiState() + initialState = ModalDrawerMviModel.UiState(), ) { - private val searchEventChannel = Channel() init { @@ -85,11 +81,9 @@ class ModalDrawerViewModel( observeChangesInFavoriteCommunities() - withContext(Dispatchers.IO) { - delay(250) - refreshUser() - refresh() - } + delay(250) + refreshUser() + refresh() } } @@ -111,20 +105,22 @@ class ModalDrawerViewModel( } }.distinctUntilChanged() }.onEach { favoriteCommunityIds -> - val newCommunities = uiState.value.communities.map { community -> - community.copy(favorite = community.id in favoriteCommunityIds) - } - .sortedBy { it.name } - .sortedByDescending { it.favorite } + val newCommunities = + uiState.value.communities.map { community -> + community.copy(favorite = community.id in favoriteCommunityIds) + } + .sortedBy { it.name } + .sortedByDescending { it.favorite } updateState { it.copy(communities = newCommunities) } }.launchIn(this) } override fun reduce(intent: ModalDrawerMviModel.Intent) { when (intent) { - ModalDrawerMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - } + ModalDrawerMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + } is ModalDrawerMviModel.Intent.SetSearch -> { updateState { it.copy(searchText = intent.value) } @@ -166,35 +162,37 @@ class ModalDrawerViewModel( val favoriteCommunityIds = favoriteCommunityRepository.getAll(accountId).map { it.communityId } val searchText = uiState.value.searchText - val communities = communityRepository.getSubscribed(auth) - .let { - if (searchText.isEmpty()) { - it - } else { - it.filter { e -> - listOf(e.name, e.title).any { s -> s.contains(other = searchText, ignoreCase = true) } - } - } - }.map { community -> - community.copy(favorite = community.id in favoriteCommunityIds) - } - .sortedBy { it.name } - .let { - val favorites = it.filter { e -> e.favorite } - val res = it - favorites.toSet() - favorites + res - } - val multiCommunitites = accountId?.let { - multiCommunityRepository.getAll(it) - .let { communities -> + val communities = + communityRepository.getSubscribed(auth) + .let { if (searchText.isEmpty()) { - communities + it } else { - communities.filter { c -> c.name.contains(other = searchText, ignoreCase = true) } + it.filter { e -> + listOf(e.name, e.title).any { s -> s.contains(other = searchText, ignoreCase = true) } + } } + }.map { community -> + community.copy(favorite = community.id in favoriteCommunityIds) } - .sortedBy { e -> e.name } - }.orEmpty() + .sortedBy { it.name } + .let { + val favorites = it.filter { e -> e.favorite } + val res = it - favorites.toSet() + favorites + res + } + val multiCommunitites = + accountId?.let { + multiCommunityRepository.getAll(it) + .let { communities -> + if (searchText.isEmpty()) { + communities + } else { + communities.filter { c -> c.name.contains(other = searchText, ignoreCase = true) } + } + } + .sortedBy { e -> e.name } + }.orEmpty() updateState { it.copy( isFiltering = searchText.isNotEmpty(), diff --git a/unit/explore/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/explore/ExploreViewModel.kt b/unit/explore/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/explore/ExploreViewModel.kt index 54b1527d2..cfcea369b 100644 --- a/unit/explore/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/explore/ExploreViewModel.kt +++ b/unit/explore/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/explore/ExploreViewModel.kt @@ -23,9 +23,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.Communit import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortTypesUseCase import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn @@ -51,18 +49,18 @@ class ExploreViewModel( DefaultMviModel( initialState = ExploreMviModel.UiState(), ) { - private var currentPage: Int = 1 private var searchEventChannel = Channel() private val isOnOtherInstance: Boolean get() = otherInstance.isNotEmpty() private val notificationEventKey: String - get() = buildString { - append("explore") - if (isOnOtherInstance) { - append("-") - append(otherInstance) + get() = + buildString { + append("explore") + if (isOnOtherInstance) { + append("-") + append(otherInstance) + } } - } init { updateState { @@ -152,7 +150,7 @@ class ExploreViewModel( sortType = sortType, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { refresh() emitEffect(ExploreMviModel.Effect.BackToTop) } @@ -166,13 +164,13 @@ class ExploreViewModel( override fun reduce(intent: ExploreMviModel.Intent) { when (intent) { ExploreMviModel.Intent.LoadNextPage -> { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { loadNextPage() } } ExploreMviModel.Intent.Refresh -> { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { refresh() } } @@ -270,7 +268,7 @@ class ExploreViewModel( private fun changeListingType(value: ListingType) { updateState { it.copy(listingType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(ExploreMviModel.Effect.BackToTop) refresh() } @@ -278,7 +276,7 @@ class ExploreViewModel( private fun changeSortType(value: SortType) { updateState { it.copy(sortType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(ExploreMviModel.Effect.BackToTop) refresh() } @@ -286,7 +284,7 @@ class ExploreViewModel( private fun changeResultType(value: SearchResultType) { updateState { it.copy(resultType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(ExploreMviModel.Effect.BackToTop) refresh() } @@ -318,15 +316,16 @@ class ExploreViewModel( val sortType = currentState.sortType val resultType = currentState.resultType val settings = settingsRepository.currentSettings.value - val itemList = communityRepository.search( - query = searchText, - auth = auth, - resultType = resultType, - page = currentPage, - listingType = listingType, - sortType = sortType, - instance = otherInstance, - ) + val itemList = + communityRepository.search( + query = searchText, + auth = auth, + resultType = resultType, + page = currentPage, + listingType = listingType, + sortType = sortType, + instance = otherInstance, + ) val additionalResolvedCommunity = if (resultType == SearchResultType.All || resultType == SearchResultType.Communities && currentPage == 1) { communityRepository.getResolved( @@ -348,56 +347,68 @@ class ExploreViewModel( if (itemList.isNotEmpty()) { currentPage++ } - val itemsToAdd = itemList.filter { item -> - if (settings.includeNsfw) { - true - } else { - isSafeForWork(item) - } - }.let { - when (resultType) { - SearchResultType.Communities -> { - if (additionalResolvedCommunity != null && it.none { r -> r is SearchResult.Community && r.model.id == additionalResolvedCommunity.id }) { - it + SearchResult.Community(additionalResolvedCommunity) - } else { - it - } + val itemsToAdd = + itemList.filter { item -> + if (settings.includeNsfw) { + true + } else { + isSafeForWork(item) } - - SearchResultType.Users -> { - if (additionalResolvedUser != null && it.none { r -> r is SearchResult.User && r.model.id == additionalResolvedUser.id }) { - it + SearchResult.User(additionalResolvedUser) - } else { - it + }.let { + when (resultType) { + SearchResultType.Communities -> { + if (additionalResolvedCommunity != null && + it.none { + r -> + r is SearchResult.Community && r.model.id == additionalResolvedCommunity.id + } + ) { + it + SearchResult.Community(additionalResolvedCommunity) + } else { + it + } } - } - SearchResultType.Posts -> { - if (settings.searchPostTitleOnly && searchText.isNotEmpty()) { - // apply the more restrictive title-only search - it.filterIsInstance() - .filter { r -> r.model.title.contains(other = searchText, ignoreCase = true) } - } else { - it + SearchResultType.Users -> { + if (additionalResolvedUser != null && + it.none { + r -> + r is SearchResult.User && r.model.id == additionalResolvedUser.id + } + ) { + it + SearchResult.User(additionalResolvedUser) + } else { + it + } } - } - else -> it + SearchResultType.Posts -> { + if (settings.searchPostTitleOnly && searchText.isNotEmpty()) { + // apply the more restrictive title-only search + it.filterIsInstance() + .filter { r -> r.model.title.contains(other = searchText, ignoreCase = true) } + } else { + it + } + } + + else -> it + } + }.filter { item -> + if (refreshing) { + true + } else { + // prevents accidental duplication + currentState.results.none { other -> getItemKey(item) == getItemKey(other) } + } } - }.filter { item -> - if (refreshing) { - true - } else { - // prevents accidental duplication - currentState.results.none { other -> getItemKey(item) == getItemKey(other) } - } - } updateState { - val newItems = if (refreshing) { - itemsToAdd - } else { - it.results + itemsToAdd - } + val newItems = + if (refreshing) { + itemsToAdd + } else { + it.results + itemsToAdd + } it.copy( results = newItems, loading = false, @@ -407,13 +418,14 @@ class ExploreViewModel( } } - private fun isSafeForWork(element: SearchResult): Boolean = when (element) { - is SearchResult.Community -> !element.model.nsfw - is SearchResult.Post -> !element.model.nsfw - is SearchResult.Comment -> true - is SearchResult.User -> true - else -> false - } + private fun isSafeForWork(element: SearchResult): Boolean = + when (element) { + is SearchResult.Community -> !element.model.nsfw + is SearchResult.Post -> !element.model.nsfw + is SearchResult.Comment -> true + is SearchResult.User -> true + else -> false + } private fun handleLogout() { currentPage = 1 @@ -429,13 +441,14 @@ class ExploreViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - results = it.results.map { r -> - if (r is SearchResult.Post && r.model.id == post.id) { - r.copy(model = post) - } else { - r - } - }, + results = + it.results.map { r -> + if (r is SearchResult.Post && r.model.id == post.id) { + r.copy(model = post) + } else { + r + } + }, ) } } @@ -443,36 +456,39 @@ class ExploreViewModel( private fun handleCommentUpdate(comment: CommentModel) { updateState { it.copy( - results = it.results.map { r -> - if (r is SearchResult.Comment && r.model.id == comment.id) { - r.copy(model = comment) - } else { - r - } - }, + results = + it.results.map { r -> + if (r is SearchResult.Comment && r.model.id == comment.id) { + r.copy(model = comment) + } else { + r + } + }, ) } } private fun toggleUpVote(post: PostModel) { val newVote = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newVote, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newVote, + ) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = newPost) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = newPost) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.upVote( @@ -484,14 +500,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = post) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = post) + } else { + res + } + }, ) } } @@ -500,23 +517,25 @@ class ExploreViewModel( private fun toggleDownVote(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = newPost) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = newPost) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.downVote( @@ -528,14 +547,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = post) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = post) + } else { + res + } + }, ) } } @@ -544,23 +564,25 @@ class ExploreViewModel( private fun toggleSave(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = newPost) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = newPost) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.save( @@ -572,14 +594,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Post) return@map res - if (res.model.id == post.id) { - res.copy(model = post) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Post) return@map res + if (res.model.id == post.id) { + res.copy(model = post) + } else { + res + } + }, ) } } @@ -588,23 +611,25 @@ class ExploreViewModel( private fun toggleUpVoteComment(comment: CommentModel) { val newValue = comment.myVote <= 0 - val newComment = commentRepository.asUpVoted( - comment = comment, - voted = newValue, - ) + val newComment = + commentRepository.asUpVoted( + comment = comment, + voted = newValue, + ) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = newComment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = newComment) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() commentRepository.upVote( @@ -616,14 +641,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = comment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = comment) + } else { + res + } + }, ) } } @@ -635,17 +661,18 @@ class ExploreViewModel( val newComment = commentRepository.asDownVoted(comment, newValue) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = newComment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = newComment) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() commentRepository.downVote( @@ -657,14 +684,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = comment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = comment) + } else { + res + } + }, ) } } @@ -673,23 +701,25 @@ class ExploreViewModel( private fun toggleSaveComment(comment: CommentModel) { val newValue = !comment.saved - val newComment = commentRepository.asSaved( - comment = comment, - saved = newValue, - ) + val newComment = + commentRepository.asSaved( + comment = comment, + saved = newValue, + ) updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = newComment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = newComment) + } else { + res + } + }, ) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() commentRepository.save( @@ -701,14 +731,15 @@ class ExploreViewModel( e.printStackTrace() updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Comment) return@map res - if (res.model.id == comment.id) { - res.copy(model = comment) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Comment) return@map res + if (res.model.id == comment.id) { + res.copy(model = comment) + } else { + res + } + }, ) } } @@ -716,29 +747,31 @@ class ExploreViewModel( } private fun toggleSubscription(communityId: Long) { - val community = uiState.value.results.firstOrNull { - (it as? SearchResult.Community)?.model?.id == communityId - }.let { (it as? SearchResult.Community)?.model } ?: return - screenModelScope.launch(Dispatchers.IO) { - val newValue = when (community.subscribed) { - true -> { - hapticFeedback.vibrate() - communityRepository.unsubscribe( - auth = identityRepository.authToken.value, - id = communityId, - ) - } + val community = + uiState.value.results.firstOrNull { + (it as? SearchResult.Community)?.model?.id == communityId + }.let { (it as? SearchResult.Community)?.model } ?: return + screenModelScope.launch { + val newValue = + when (community.subscribed) { + true -> { + hapticFeedback.vibrate() + communityRepository.unsubscribe( + auth = identityRepository.authToken.value, + id = communityId, + ) + } - false -> { - hapticFeedback.vibrate() - communityRepository.subscribe( - auth = identityRepository.authToken.value, - id = communityId, - ) - } + false -> { + hapticFeedback.vibrate() + communityRepository.subscribe( + auth = identityRepository.authToken.value, + id = communityId, + ) + } - else -> community - } + else -> community + } if (newValue == null) { emitEffect(ExploreMviModel.Effect.OperationFailure) } else { @@ -750,22 +783,24 @@ class ExploreViewModel( private fun handleCommunityUpdate(community: CommunityModel) { updateState { it.copy( - results = it.results.map { res -> - if (res !is SearchResult.Community) return@map res - if (res.model.id == community.id) { - res.copy(model = community) - } else { - res - } - }, + results = + it.results.map { res -> + if (res !is SearchResult.Community) return@map res + if (res.model.id == community.id) { + res.copy(model = community) + } else { + res + } + }, ) } } } -internal fun getItemKey(result: SearchResult): String = when (result) { - is SearchResult.Post -> "post" + result.model.id.toString() + result.model.updateDate - is SearchResult.Comment -> "comment" + result.model.id.toString() + result.model.updateDate - is SearchResult.User -> "user" + result.model.id.toString() - is SearchResult.Community -> "community" + result.model.id.toString() -} \ No newline at end of file +internal fun getItemKey(result: SearchResult): String = + when (result) { + is SearchResult.Post -> "post" + result.model.id.toString() + result.model.updateDate + is SearchResult.Comment -> "comment" + result.model.id.toString() + result.model.updateDate + is SearchResult.User -> "user" + result.model.id.toString() + is SearchResult.Community -> "community" + result.model.id.toString() + } diff --git a/unit/manageban/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/manageban/ManageBanViewModel.kt b/unit/manageban/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/manageban/ManageBanViewModel.kt index ee5ddfb25..7cff2dd1a 100644 --- a/unit/manageban/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/manageban/ManageBanViewModel.kt +++ b/unit/manageban/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/manageban/ManageBanViewModel.kt @@ -7,12 +7,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.Ident import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class ManageBanViewModel( private val identityRepository: IdentityRepository, @@ -24,7 +21,6 @@ class ManageBanViewModel( DefaultMviModel( initialState = ManageBanMviModel.UiState(), ) { - init { screenModelScope.launch { settingsRepository.currentSettings.onEach { settings -> @@ -36,10 +32,8 @@ class ManageBanViewModel( } }.launchIn(this) - withContext(Dispatchers.IO) { - if (uiState.value.initial) { - refresh() - } + if (uiState.value.initial) { + refresh() } } } @@ -82,7 +76,7 @@ class ManageBanViewModel( userRepository.block( id = id, blocked = false, - auth = auth + auth = auth, ) updateState { it.copy(bannedUsers = it.bannedUsers.filter { e -> e.id != id }) @@ -98,7 +92,7 @@ class ManageBanViewModel( communityRepository.block( id = id, blocked = false, - auth = auth + auth = auth, ) updateState { it.copy(bannedCommunities = it.bannedCommunities.filter { e -> e.id != id }) @@ -114,7 +108,7 @@ class ManageBanViewModel( siteRepository.block( id = id, blocked = false, - auth = auth + auth = auth, ) updateState { it.copy(bannedInstances = it.bannedInstances.filter { e -> e.id != id }) @@ -122,4 +116,4 @@ class ManageBanViewModel( } } } -} \ No newline at end of file +} diff --git a/unit/managesubscriptions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/managesubscriptions/ManageSubscriptionsViewModel.kt b/unit/managesubscriptions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/managesubscriptions/ManageSubscriptionsViewModel.kt index e1f249e62..5a67d3058 100644 --- a/unit/managesubscriptions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/managesubscriptions/ManageSubscriptionsViewModel.kt +++ b/unit/managesubscriptions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/managesubscriptions/ManageSubscriptionsViewModel.kt @@ -14,9 +14,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.vibrate.HapticFeedbac 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.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn @@ -38,7 +36,6 @@ class ManageSubscriptionsViewModel( DefaultMviModel( initialState = ManageSubscriptionsMviModel.UiState(), ) { - private val searchEventChannel = Channel() init { @@ -81,7 +78,7 @@ class ManageSubscriptionsViewModel( } is ManageSubscriptionsMviModel.Intent.DeleteMultiCommunity -> { - uiState.value.multiCommunities.firstOrNull() { + uiState.value.multiCommunities.firstOrNull { (it.id ?: 0L) == intent.id }?.also { community -> deleteMultiCommunity(community) @@ -103,37 +100,39 @@ class ManageSubscriptionsViewModel( return } updateState { it.copy(refreshing = true) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value val accountId = accountRepository.getActive()?.id ?: 0L val favoriteCommunityIds = favoriteCommunityRepository.getAll(accountId).map { it.communityId } - val communities = communityRepository.getSubscribed(auth) - .let { - val searchText = uiState.value.searchText - if (searchText.isNotEmpty()) { - it.filter { c -> - c.title.contains(searchText, ignoreCase = true) - || c.name.contains(searchText, ignoreCase = true) + val communities = + communityRepository.getSubscribed(auth) + .let { + val searchText = uiState.value.searchText + if (searchText.isNotEmpty()) { + it.filter { c -> + c.title.contains(searchText, ignoreCase = true) || + c.name.contains(searchText, ignoreCase = true) + } + } else { + it } - } else { - it - } - }.map { community -> - community.copy(favorite = community.id in favoriteCommunityIds) - }.sortedBy { it.name } - val multiCommunitites = multiCommunityRepository.getAll(accountId) - .let { - val searchText = uiState.value.searchText - if (searchText.isNotEmpty()) { - it.filter { c -> - c.name.contains(searchText, ignoreCase = true) + }.map { community -> + community.copy(favorite = community.id in favoriteCommunityIds) + }.sortedBy { it.name } + val multiCommunitites = + multiCommunityRepository.getAll(accountId) + .let { + val searchText = uiState.value.searchText + if (searchText.isNotEmpty()) { + it.filter { c -> + c.name.contains(searchText, ignoreCase = true) + } + } else { + it } - } else { - it } - } - .sortedBy { it.name } + .sortedBy { it.name } updateState { it.copy( @@ -147,10 +146,11 @@ class ManageSubscriptionsViewModel( } private fun unsubscribe(community: CommunityModel) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value communityRepository.unsubscribe( - auth = auth, id = community.id + auth = auth, + id = community.id, ) updateState { it.copy(communities = it.communities.filter { c -> c.id != community.id }) @@ -159,7 +159,7 @@ class ManageSubscriptionsViewModel( } private fun deleteMultiCommunity(community: MultiCommunityModel) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { multiCommunityRepository.delete(community) updateState { val newCommunities = it.multiCommunities.filter { c -> c.id != community.id } @@ -170,23 +170,24 @@ class ManageSubscriptionsViewModel( private fun handleMultiCommunityCreated(community: MultiCommunityModel) { val oldCommunities = uiState.value.multiCommunities - val newCommunities = if (oldCommunities.any { it.id == community.id }) { - oldCommunities.map { - if (it.id == community.id) { - community - } else { - it + val newCommunities = + if (oldCommunities.any { it.id == community.id }) { + oldCommunities.map { + if (it.id == community.id) { + community + } else { + it + } } - } - } else { - oldCommunities + community - }.sortedBy { it.name } + } else { + oldCommunities + community + }.sortedBy { it.name } updateState { it.copy(multiCommunities = newCommunities) } } private fun toggleFavorite(community: CommunityModel) { val communityId = community.id - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val accountId = accountRepository.getActive()?.id ?: 0L val newValue = !community.favorite if (newValue) { @@ -206,13 +207,14 @@ class ManageSubscriptionsViewModel( private fun handleCommunityUpdate(community: CommunityModel) { updateState { it.copy( - communities = it.communities.map { c -> - if (c.id == community.id) { - community - } else { - c - } - }, + communities = + it.communities.map { c -> + if (c.id == community.id) { + community + } else { + c + } + }, ) } } diff --git a/unit/mentions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/mentions/InboxMentionsViewModel.kt b/unit/mentions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/mentions/InboxMentionsViewModel.kt index ebe527ab0..a644ee862 100644 --- a/unit/mentions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/mentions/InboxMentionsViewModel.kt +++ b/unit/mentions/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/mentions/InboxMentionsViewModel.kt @@ -13,8 +13,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionM import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -30,9 +28,8 @@ class InboxMentionsViewModel( private val notificationCenter: NotificationCenter, ) : InboxMentionsMviModel, DefaultMviModel( - initialState = InboxMentionsMviModel.UiState() + initialState = InboxMentionsMviModel.UiState(), ) { - private var currentPage: Int = 1 init { @@ -78,14 +75,16 @@ class InboxMentionsViewModel( override fun reduce(intent: InboxMentionsMviModel.Intent) { when (intent) { - InboxMentionsMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + InboxMentionsMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - InboxMentionsMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - emitEffect(InboxMentionsMviModel.Effect.BackToTop) - } + InboxMentionsMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + emitEffect(InboxMentionsMviModel.Effect.BackToTop) + } is InboxMentionsMviModel.Intent.MarkAsRead -> { markAsRead( @@ -138,28 +137,29 @@ class InboxMentionsViewModel( return } - updateState { it.copy(loading = true) } val auth = identityRepository.authToken.value val refreshing = currentState.refreshing val unreadOnly = currentState.unreadOnly - val itemList = userRepository.getMentions( - auth = auth, - page = currentPage, - unreadOnly = unreadOnly, - sort = SortType.New, - )?.map { - it.copy(isCommentReply = it.comment.depth > 0) - } + val itemList = + userRepository.getMentions( + auth = auth, + page = currentPage, + unreadOnly = unreadOnly, + sort = SortType.New, + )?.map { + it.copy(isCommentReply = it.comment.depth > 0) + } if (!itemList.isNullOrEmpty()) { currentPage++ } updateState { - val newItems = if (refreshing) { - itemList.orEmpty() - } else { - it.mentions + itemList.orEmpty() - } + val newItems = + if (refreshing) { + itemList.orEmpty() + } else { + it.mentions + itemList.orEmpty() + } it.copy( mentions = newItems, loading = false, @@ -173,18 +173,22 @@ class InboxMentionsViewModel( private fun handleItemUpdate(item: PersonMentionModel) { updateState { it.copy( - mentions = it.mentions.map { i -> - if (i.id == item.id) { - item - } else { - i - } - } + mentions = + it.mentions.map { i -> + if (i.id == item.id) { + item + } else { + i + } + }, ) } } - private fun markAsRead(read: Boolean, mention: PersonMentionModel) { + private fun markAsRead( + read: Boolean, + mention: PersonMentionModel, + ) { val auth = identityRepository.authToken.value screenModelScope.launch { userRepository.setMentionRead( @@ -196,9 +200,10 @@ class InboxMentionsViewModel( if (read && currentState.unreadOnly) { updateState { it.copy( - mentions = currentState.mentions.filter { m -> - m.id != mention.id - } + mentions = + currentState.mentions.filter { m -> + m.id != mention.id + }, ) } } else { @@ -211,14 +216,16 @@ class InboxMentionsViewModel( private fun toggleUpVoteComment(mention: PersonMentionModel) { val newValue = mention.myVote <= 0 - val newComment = commentRepository.asUpVoted( - comment = mention.comment, - voted = newValue, - ) - val newMention = mention.copy( - myVote = newComment.myVote, - score = newComment.score, - ) + val newComment = + commentRepository.asUpVoted( + comment = mention.comment, + voted = newValue, + ) + val newMention = + mention.copy( + myVote = newComment.myVote, + score = newComment.score, + ) handleItemUpdate(newMention) screenModelScope.launch { try { @@ -237,10 +244,11 @@ class InboxMentionsViewModel( private fun toggleDownVoteComment(mention: PersonMentionModel) { val newValue = mention.myVote >= 0 val newComment = commentRepository.asDownVoted(mention.comment, newValue) - val newMention = mention.copy( - myVote = newComment.myVote, - score = newComment.score, - ) + val newMention = + mention.copy( + myVote = newComment.myVote, + score = newComment.score, + ) handleItemUpdate(newMention) screenModelScope.launch { try { @@ -265,7 +273,7 @@ class InboxMentionsViewModel( private fun handleLogout() { updateState { it.copy(mentions = emptyList()) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { refresh(initial = true) } } diff --git a/unit/messages/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/messages/InboxMessagesViewModel.kt b/unit/messages/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/messages/InboxMessagesViewModel.kt index 947254f7c..32c0f18de 100644 --- a/unit/messages/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/messages/InboxMessagesViewModel.kt +++ b/unit/messages/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/messages/InboxMessagesViewModel.kt @@ -10,12 +10,9 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.inbox.InboxCoordinator import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.otherUser import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PrivateMessageRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class InboxMessagesViewModel( private val identityRepository: IdentityRepository, @@ -28,7 +25,6 @@ class InboxMessagesViewModel( DefaultMviModel( initialState = InboxMessagesMviModel.UiState(), ) { - private var currentPage: Int = 1 init { @@ -58,32 +54,31 @@ class InboxMessagesViewModel( handleLogout() }.launchIn(this) - withContext(Dispatchers.IO) { - val auth = identityRepository.authToken.value.orEmpty() - val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0 - updateState { it.copy(currentUserId = currentUserId) } + val auth = identityRepository.authToken.value.orEmpty() + val currentUserId = siteRepository.getCurrentUser(auth)?.id ?: 0 + updateState { it.copy(currentUserId = currentUserId) } - if (uiState.value.initial) { - val value = coordinator.unreadOnly.value - changeUnreadOnly(value) - refresh(initial = true) - } - updateUnreadItems() + if (uiState.value.initial) { + val value = coordinator.unreadOnly.value + changeUnreadOnly(value) + refresh(initial = true) } - + updateUnreadItems() } } override fun reduce(intent: InboxMessagesMviModel.Intent) { when (intent) { - InboxMessagesMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + InboxMessagesMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - InboxMessagesMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - emitEffect(InboxMessagesMviModel.Effect.BackToTop) - } + InboxMessagesMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + emitEffect(InboxMessagesMviModel.Effect.BackToTop) + } } } @@ -123,31 +118,34 @@ class InboxMessagesViewModel( val auth = identityRepository.authToken.value val refreshing = currentState.refreshing val unreadOnly = currentState.unreadOnly - val itemList = messageRepository.getAll( - auth = auth, - page = currentPage, - unreadOnly = unreadOnly, - )?.groupBy { - it.otherUser(currentState.currentUserId)?.id ?: 0 - }?.mapNotNull { entry -> - val messages = entry.value.sortedBy { m -> m.publishDate } - messages.lastOrNull() - } + val itemList = + messageRepository.getAll( + auth = auth, + page = currentPage, + unreadOnly = unreadOnly, + )?.groupBy { + it.otherUser(currentState.currentUserId)?.id ?: 0 + }?.mapNotNull { entry -> + val messages = entry.value.sortedBy { m -> m.publishDate } + messages.lastOrNull() + } if (!itemList.isNullOrEmpty()) { currentPage++ } updateState { - val newItems = if (refreshing) { - itemList.orEmpty() - } else { - it.chats + itemList.orEmpty().filter { outerChat -> - val outerOtherUser = outerChat.otherUser(currentState.currentUserId) - currentState.chats.none { chat -> - val otherUser = chat.otherUser(currentState.currentUserId) - outerOtherUser == otherUser - } + val newItems = + if (refreshing) { + itemList.orEmpty() + } else { + it.chats + + itemList.orEmpty().filter { outerChat -> + val outerOtherUser = outerChat.otherUser(currentState.currentUserId) + currentState.chats.none { chat -> + val otherUser = chat.otherUser(currentState.currentUserId) + outerOtherUser == otherUser + } + } } - } it.copy( chats = newItems, loading = false, @@ -167,7 +165,7 @@ class InboxMessagesViewModel( private fun handleLogout() { updateState { it.copy(chats = emptyList()) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { refresh(initial = true) } } diff --git a/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/detail/MultiCommunityViewModel.kt b/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/detail/MultiCommunityViewModel.kt index 1a89c4a71..9a5939999 100644 --- a/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/detail/MultiCommunityViewModel.kt +++ b/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/detail/MultiCommunityViewModel.kt @@ -22,13 +22,10 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toSortType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortTypesUseCase import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class MultiCommunityViewModel( private val communityId: Long, @@ -47,9 +44,8 @@ class MultiCommunityViewModel( private val postNavigationManager: PostNavigationManager, ) : MultiCommunityMviModel, DefaultMviModel( - initialState = MultiCommunityMviModel.UiState() + initialState = MultiCommunityMviModel.UiState(), ) { - private var hideReadPosts = false init { @@ -105,18 +101,16 @@ class MultiCommunityViewModel( val user = siteRepository.getCurrentUser(auth) updateState { it.copy(currentUserId = user?.id ?: 0) } } - withContext(Dispatchers.IO) { - if (uiState.value.posts.isEmpty()) { - val settings = settingsRepository.currentSettings.value - val sortTypes = getSortTypesUseCase.getTypesForPosts() - updateState { - it.copy( - sortType = settings.defaultPostSortType.toSortType(), - availableSortTypes = sortTypes, - ) - } - refresh(initial = true) + if (uiState.value.posts.isEmpty()) { + val settings = settingsRepository.currentSettings.value + val sortTypes = getSortTypesUseCase.getTypesForPosts() + updateState { + it.copy( + sortType = settings.defaultPostSortType.toSortType(), + availableSortTypes = sortTypes, + ) } + refresh(initial = true) } } } @@ -133,13 +127,15 @@ class MultiCommunityViewModel( } MultiCommunityMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() - MultiCommunityMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + MultiCommunityMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - MultiCommunityMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - } + MultiCommunityMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + } is MultiCommunityMviModel.Intent.SavePost -> { if (intent.feedback) { @@ -162,17 +158,20 @@ class MultiCommunityViewModel( } MultiCommunityMviModel.Intent.ClearRead -> clearRead() - is MultiCommunityMviModel.Intent.MarkAsRead -> markAsRead( - post = uiState.value.posts.first { it.id == intent.id }, - ) + is MultiCommunityMviModel.Intent.MarkAsRead -> + markAsRead( + post = uiState.value.posts.first { it.id == intent.id }, + ) - is MultiCommunityMviModel.Intent.Hide -> hide( - post = uiState.value.posts.first { it.id == intent.id }, - ) + is MultiCommunityMviModel.Intent.Hide -> + hide( + post = uiState.value.posts.first { it.id == intent.id }, + ) - is MultiCommunityMviModel.Intent.Copy -> screenModelScope.launch { - emitEffect(MultiCommunityMviModel.Effect.TriggerCopy(intent.value)) - } + is MultiCommunityMviModel.Intent.Copy -> + screenModelScope.launch { + emitEffect(MultiCommunityMviModel.Effect.TriggerCopy(intent.value)) + } MultiCommunityMviModel.Intent.WillOpenDetail -> { val state = postPaginationManager.extractState() @@ -189,7 +188,7 @@ class MultiCommunityViewModel( communityIds = uiState.value.community.communityIds, sortType = sortType, includeNsfw = settingsRepository.currentSettings.value.includeNsfw, - ) + ), ) updateState { it.copy( @@ -211,13 +210,14 @@ class MultiCommunityViewModel( updateState { it.copy(loading = true) } - val posts = postPaginationManager.loadNextPage().let { - if (!hideReadPosts) { - it - } else { - it.filter { post -> !post.read } + val posts = + postPaginationManager.loadNextPage().let { + if (!hideReadPosts) { + it + } else { + it.filter { post -> !post.read } + } } - } val canFetchMore = postPaginationManager.canFetchMore if (uiState.value.autoLoadImages) { posts.forEach { post -> @@ -251,12 +251,13 @@ class MultiCommunityViewModel( private fun toggleUpVote(post: PostModel) { val newVote = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newVote, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newVote, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.upVote( @@ -277,7 +278,7 @@ class MultiCommunityViewModel( return } val newPost = post.copy(read = true) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.setRead( @@ -295,12 +296,13 @@ class MultiCommunityViewModel( private fun toggleDownVote(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.downVote( @@ -318,12 +320,13 @@ class MultiCommunityViewModel( private fun toggleSave(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.save( @@ -342,13 +345,14 @@ class MultiCommunityViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == post.id) { - post - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == post.id) { + post + } else { + p + } + }, ) } } diff --git a/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/editor/MultiCommunityEditorViewModel.kt b/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/editor/MultiCommunityEditorViewModel.kt index fb75a9143..bdf44a4e4 100644 --- a/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/editor/MultiCommunityEditorViewModel.kt +++ b/unit/multicommunity/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/multicommunity/editor/MultiCommunityEditorViewModel.kt @@ -12,9 +12,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.ValidationError 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.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn @@ -33,9 +31,8 @@ class MultiCommunityEditorViewModel( private val notificationCenter: NotificationCenter, ) : MultiCommunityEditorMviModel, DefaultMviModel( - initialState = MultiCommunityEditorMviModel.UiState() + initialState = MultiCommunityEditorMviModel.UiState(), ) { - private var communities: List> = emptyList() private val searchEventChannel = Channel() @@ -73,14 +70,16 @@ class MultiCommunityEditorViewModel( } private fun populate() { - screenModelScope.launch(Dispatchers.IO) { - val editedCommunity = communityId?.toLong()?.let { - multiCommunityRepository.getById(it) - } + screenModelScope.launch { + val editedCommunity = + communityId?.let { + multiCommunityRepository.getById(it) + } val auth = identityRepository.authToken.value - communities = communityRepository.getSubscribed(auth).sortedBy { it.name }.map { c -> - c to (editedCommunity?.communityIds?.contains(c.id) == true) - } + communities = + communityRepository.getSubscribed(auth).sortedBy { it.name }.map { c -> + c to (editedCommunity?.communityIds?.contains(c.id) == true) + } updateState { val newCommunities = communities val availableIcons = newCommunities.filter { i -> i.second }.mapNotNull { i -> i.first.icon } @@ -103,36 +102,40 @@ class MultiCommunityEditorViewModel( private fun filterCommunities(): List> { val searchText = uiState.value.searchText - val res = if (searchText.isNotEmpty()) { - communities.filter { it.first.name.contains(other = searchText, ignoreCase = true) } - } else { - communities - } + val res = + if (searchText.isNotEmpty()) { + communities.filter { it.first.name.contains(other = searchText, ignoreCase = true) } + } else { + communities + } return res } private fun selectImage(index: Int?) { - val image = if (index == null) { - null - } else { - uiState.value.availableIcons[index] - } + val image = + if (index == null) { + null + } else { + uiState.value.availableIcons[index] + } updateState { it.copy(icon = image) } } private fun toggleCommunity(communityId: Long) { - val newCommunities = communities.map { item -> - if (item.first.id == communityId) { - item.first to !item.second - } else { - item + val newCommunities = + communities.map { item -> + if (item.first.id == communityId) { + item.first to !item.second + } else { + item + } + } + val availableIcons = + newCommunities.filter { i -> + i.second + }.mapNotNull { i -> + i.first.icon } - } - val availableIcons = newCommunities.filter { i -> - i.second - }.mapNotNull { i -> - i.first.icon - } communities = newCommunities val filtered = filterCommunities() updateState { state -> @@ -156,26 +159,28 @@ class MultiCommunityEditorViewModel( return } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val icon = currentState.icon val communityIds = currentState.communities.filter { it.second }.map { it.first.id } - val editedCommunity = communityId?.toLong()?.let { - multiCommunityRepository.getById(it) - } - val multiCommunity = editedCommunity?.copy( - name = name, - icon = icon, - communityIds = communityIds, - ) ?: MultiCommunityModel( - name = name, - icon = icon, - communityIds = communityIds, - ) + val editedCommunity = + communityId?.let { + multiCommunityRepository.getById(it) + } + val multiCommunity = + editedCommunity?.copy( + name = name, + icon = icon, + communityIds = communityIds, + ) ?: MultiCommunityModel( + name = name, + icon = icon, + communityIds = communityIds, + ) val accountId = accountRepository.getActive()?.id ?: return@launch if (multiCommunity.id == null) { val id = multiCommunityRepository.create(multiCommunity, accountId) notificationCenter.send( - NotificationCenterEvent.MultiCommunityCreated(multiCommunity.copy(id = id)) + NotificationCenterEvent.MultiCommunityCreated(multiCommunity.copy(id = id)), ) } else { multiCommunityRepository.update(multiCommunity) diff --git a/unit/myaccount/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/myaccount/ProfileLoggedViewModel.kt b/unit/myaccount/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/myaccount/ProfileLoggedViewModel.kt index cfb119e86..8e59ec659 100644 --- a/unit/myaccount/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/myaccount/ProfileLoggedViewModel.kt +++ b/unit/myaccount/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/myaccount/ProfileLoggedViewModel.kt @@ -21,9 +21,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay @@ -32,7 +30,6 @@ import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import kotlinx.coroutines.yield @@ -51,9 +48,8 @@ class ProfileLoggedViewModel( private val postNavigationManager: PostNavigationManager, ) : ProfileLoggedMviModel, DefaultMviModel( - initialState = ProfileLoggedMviModel.UiState() + initialState = ProfileLoggedMviModel.UiState(), ) { - init { updateState { it.copy(instance = apiConfigurationRepository.instance.value) } screenModelScope.launch { @@ -110,14 +106,10 @@ class ProfileLoggedViewModel( initial = false, ) } - withContext(Dispatchers.IO) { - refresh(initial = false) - } + refresh(initial = false) } else { - withContext(Dispatchers.IO) { - refreshUser() - refresh(initial = true) - } + refreshUser() + refresh(initial = true) } } } @@ -128,13 +120,15 @@ class ProfileLoggedViewModel( is ProfileLoggedMviModel.Intent.ChangeSection -> changeSection(intent.section) is ProfileLoggedMviModel.Intent.DeleteComment -> deleteComment(intent.id) is ProfileLoggedMviModel.Intent.DeletePost -> deletePost(intent.id) - ProfileLoggedMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + ProfileLoggedMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - ProfileLoggedMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - } + ProfileLoggedMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + } is ProfileLoggedMviModel.Intent.Share -> { shareHelper.share(intent.url) @@ -228,13 +222,13 @@ class ProfileLoggedViewModel( PostPaginationSpecification.User( id = userId, sortType = SortType.New, - ) + ), ) commentPaginationManager.reset( CommentPaginationSpecification.User( id = userId, sortType = SortType.New, - ) + ), ) updateState { it.copy( @@ -268,18 +262,20 @@ class ProfileLoggedViewModel( val section = currentState.section if (section == ProfileLoggedSection.Posts) { coroutineScope { - val posts = async { - postPaginationManager.loadNextPage() - }.await() - val comments = async { - if (currentState.comments.isEmpty() || refreshing) { - // this is needed because otherwise on first selector change - // the lazy column scrolls back to top (it must have an empty data set) - commentPaginationManager.loadNextPage() - } else { - currentState.comments - } - }.await() + val posts = + async { + postPaginationManager.loadNextPage() + }.await() + val comments = + async { + if (currentState.comments.isEmpty() || refreshing) { + // this is needed because otherwise on first selector change + // the lazy column scrolls back to top (it must have an empty data set) + commentPaginationManager.loadNextPage() + } else { + currentState.comments + } + }.await() updateState { it.copy( posts = posts, @@ -307,10 +303,11 @@ class ProfileLoggedViewModel( private fun toggleUpVotePost(post: PostModel) { val newVote = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newVote, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newVote, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -329,10 +326,11 @@ class ProfileLoggedViewModel( private fun toggleDownVotePost(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -351,10 +349,11 @@ class ProfileLoggedViewModel( private fun toggleSavePost(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -373,10 +372,11 @@ class ProfileLoggedViewModel( private fun toggleUpVoteComment(comment: CommentModel) { val newValue = comment.myVote <= 0 - val newComment = commentRepository.asUpVoted( - comment = comment, - voted = newValue, - ) + val newComment = + commentRepository.asUpVoted( + comment = comment, + voted = newValue, + ) handleCommentUpdate(newComment) screenModelScope.launch { try { @@ -414,10 +414,11 @@ class ProfileLoggedViewModel( private fun toggleSaveComment(comment: CommentModel) { val newValue = !comment.saved - val newComment = commentRepository.asSaved( - comment = comment, - saved = newValue, - ) + val newComment = + commentRepository.asSaved( + comment = comment, + saved = newValue, + ) handleCommentUpdate(newComment) screenModelScope.launch { try { @@ -437,13 +438,14 @@ class ProfileLoggedViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == post.id) { - post - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == post.id) { + post + } else { + p + } + }, ) } } @@ -451,13 +453,14 @@ class ProfileLoggedViewModel( private fun handleCommentUpdate(comment: CommentModel) { updateState { it.copy( - comments = it.comments.map { c -> - if (c.id == comment.id) { - comment - } else { - c - } - }, + comments = + it.comments.map { c -> + if (c.id == comment.id) { + comment + } else { + c + } + }, ) } } @@ -467,7 +470,7 @@ class ProfileLoggedViewModel( } private fun deletePost(id: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value.orEmpty() postRepository.delete(id = id, auth = auth) handlePostDelete(id) @@ -475,7 +478,7 @@ class ProfileLoggedViewModel( } private fun deleteComment(id: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value.orEmpty() commentRepository.delete(id, auth) refresh() diff --git a/unit/postlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/postlist/PostListViewModel.kt b/unit/postlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/postlist/PostListViewModel.kt index 750a52a46..97832e0e7 100644 --- a/unit/postlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/postlist/PostListViewModel.kt +++ b/unit/postlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/postlist/PostListViewModel.kt @@ -26,8 +26,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortT import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -52,9 +50,8 @@ class PostListViewModel( private val postNavigationManager: PostNavigationManager, ) : PostListMviModel, DefaultMviModel( - initialState = PostListMviModel.UiState() + initialState = PostListMviModel.UiState(), ) { - private var hideReadPosts = false init { @@ -184,16 +181,18 @@ class PostListViewModel( override fun reduce(intent: PostListMviModel.Intent) { when (intent) { - PostListMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } - - is PostListMviModel.Intent.Refresh -> screenModelScope.launch { - if (intent.hardReset) { - refreshUser() + PostListMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } + + is PostListMviModel.Intent.Refresh -> + screenModelScope.launch { + if (intent.hardReset) { + refreshUser() + } + refresh() } - refresh() - } is PostListMviModel.Intent.ChangeListing -> applyListingType(intent.value) is PostListMviModel.Intent.DownVotePost -> { @@ -256,9 +255,10 @@ class PostListViewModel( ) } - is PostListMviModel.Intent.Copy -> screenModelScope.launch { - emitEffect(PostListMviModel.Effect.TriggerCopy(intent.value)) - } + is PostListMviModel.Intent.Copy -> + screenModelScope.launch { + emitEffect(PostListMviModel.Effect.TriggerCopy(intent.value)) + } PostListMviModel.Intent.WillOpenDetail -> { val state = postPaginationManager.extractState() @@ -277,7 +277,7 @@ class PostListViewModel( listingType = listingType, sortType = sortType, includeNsfw = settingsRepository.currentSettings.value.includeNsfw, - ) + ), ) updateState { it.copy( @@ -301,13 +301,14 @@ class PostListViewModel( return } updateState { it.copy(loading = true) } - val posts = postPaginationManager.loadNextPage().let { - if (!hideReadPosts) { - it - } else { - it.filter { post -> !post.read } + val posts = + postPaginationManager.loadNextPage().let { + if (!hideReadPosts) { + it + } else { + it.filter { post -> !post.read } + } } - } if (uiState.value.autoLoadImages) { posts.forEach { post -> post.imageUrl.takeIf { i -> i.isNotEmpty() }?.also { url -> @@ -343,7 +344,7 @@ class PostListViewModel( return } updateState { it.copy(listingType = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(PostListMviModel.Effect.BackToTop) delay(50) refresh() @@ -352,12 +353,13 @@ class PostListViewModel( private fun toggleUpVote(post: PostModel) { val newVote = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newVote, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newVote, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.upVote( @@ -378,7 +380,7 @@ class PostListViewModel( return } val newPost = post.copy(read = true) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.setRead( @@ -396,12 +398,13 @@ class PostListViewModel( private fun toggleDownVote(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.downVote( @@ -419,12 +422,13 @@ class PostListViewModel( private fun toggleSave(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) handlePostUpdate(newPost) - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value.orEmpty() postRepository.save( @@ -443,13 +447,14 @@ class PostListViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == post.id) { - post - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == post.id) { + post + } else { + p + } + }, ) } } @@ -465,7 +470,7 @@ class PostListViewModel( } private fun handlePostDelete(id: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value.orEmpty() postRepository.delete(id = id, auth = auth) handlePostDelete(id) @@ -491,21 +496,21 @@ class PostListViewModel( } private fun blockUser(userId: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value userRepository.block(userId, true, auth) } } private fun blockCommunity(communityId: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val auth = identityRepository.authToken.value communityRepository.block(communityId, true, auth) } } private fun blockInstance(instanceId: Long) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value siteRepository.block(instanceId, true, auth) diff --git a/unit/replies/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/replies/InboxRepliesViewModel.kt b/unit/replies/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/replies/InboxRepliesViewModel.kt index 5626ade1e..dcc889111 100644 --- a/unit/replies/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/replies/InboxRepliesViewModel.kt +++ b/unit/replies/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/replies/InboxRepliesViewModel.kt @@ -14,8 +14,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -34,7 +32,6 @@ class InboxRepliesViewModel( DefaultMviModel( initialState = InboxRepliesMviModel.UiState(), ) { - private var currentPage: Int = 1 private var currentUserId: Long? = null @@ -81,14 +78,16 @@ class InboxRepliesViewModel( override fun reduce(intent: InboxRepliesMviModel.Intent) { when (intent) { - InboxRepliesMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + InboxRepliesMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - InboxRepliesMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - emitEffect(InboxRepliesMviModel.Effect.BackToTop) - } + InboxRepliesMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + emitEffect(InboxRepliesMviModel.Effect.BackToTop) + } is InboxRepliesMviModel.Intent.MarkAsRead -> { markAsRead( @@ -97,7 +96,6 @@ class InboxRepliesViewModel( ) } - InboxRepliesMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() is InboxRepliesMviModel.Intent.DownVoteComment -> { toggleDownVoteComment( @@ -149,24 +147,26 @@ class InboxRepliesViewModel( val auth = identityRepository.authToken.value val refreshing = currentState.refreshing val unreadOnly = currentState.unreadOnly - val itemList = userRepository.getReplies( - auth = auth, - page = currentPage, - unreadOnly = unreadOnly, - sort = SortType.New, - )?.map { - it.copy(isCommentReply = it.comment.depth > 0) - } + val itemList = + userRepository.getReplies( + auth = auth, + page = currentPage, + unreadOnly = unreadOnly, + sort = SortType.New, + )?.map { + it.copy(isCommentReply = it.comment.depth > 0) + } if (!itemList.isNullOrEmpty()) { currentPage++ } updateState { - val newItems = if (refreshing) { - itemList.orEmpty() - } else { - it.replies + itemList.orEmpty() - } + val newItems = + if (refreshing) { + itemList.orEmpty() + } else { + it.replies + itemList.orEmpty() + } it.copy( replies = newItems, loading = false, @@ -180,18 +180,22 @@ class InboxRepliesViewModel( private fun handleItemUpdate(item: PersonMentionModel) { updateState { it.copy( - replies = it.replies.map { i -> - if (i.id == item.id) { - item - } else { - i - } - } + replies = + it.replies.map { i -> + if (i.id == item.id) { + item + } else { + i + } + }, ) } } - private fun markAsRead(read: Boolean, reply: PersonMentionModel) { + private fun markAsRead( + read: Boolean, + reply: PersonMentionModel, + ) { val auth = identityRepository.authToken.value screenModelScope.launch { userRepository.setReplyRead( @@ -203,9 +207,10 @@ class InboxRepliesViewModel( if (read && currentState.unreadOnly) { updateState { it.copy( - replies = currentState.replies.filter { r -> - r.id != reply.id - } + replies = + currentState.replies.filter { r -> + r.id != reply.id + }, ) } } else { @@ -218,10 +223,11 @@ class InboxRepliesViewModel( private fun toggleUpVoteComment(mention: PersonMentionModel) { val newValue = mention.myVote <= 0 - val newMention = commentRepository.asUpVoted( - mention = mention, - voted = newValue, - ) + val newMention = + commentRepository.asUpVoted( + mention = mention, + voted = newValue, + ) handleItemUpdate(newMention) screenModelScope.launch { try { @@ -239,10 +245,11 @@ class InboxRepliesViewModel( private fun toggleDownVoteComment(mention: PersonMentionModel) { val newValue = mention.myVote >= 0 - val newMention = commentRepository.asDownVoted( - mention = mention, - downVoted = newValue - ) + val newMention = + commentRepository.asDownVoted( + mention = mention, + downVoted = newValue, + ) handleItemUpdate(newMention) screenModelScope.launch { try { @@ -265,7 +272,7 @@ class InboxRepliesViewModel( private fun handleLogout() { updateState { it.copy(replies = emptyList()) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { refresh(initial = true) } } diff --git a/unit/reportlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/reportlist/ReportListViewModel.kt b/unit/reportlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/reportlist/ReportListViewModel.kt index b07ba7902..7bcd58163 100644 --- a/unit/reportlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/reportlist/ReportListViewModel.kt +++ b/unit/reportlist/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/reportlist/ReportListViewModel.kt @@ -12,8 +12,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentReportM import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostReportModel import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay @@ -34,7 +32,6 @@ class ReportListViewModel( DefaultMviModel( initialState = ReportListMviModel.UiState(), ) { - private val currentPage = mutableMapOf() init { @@ -66,24 +63,28 @@ class ReportListViewModel( when (intent) { is ReportListMviModel.Intent.ChangeSection -> changeSection(intent.value) is ReportListMviModel.Intent.ChangeUnresolvedOnly -> changeUnresolvedOnly(intent.value) - ReportListMviModel.Intent.Refresh -> screenModelScope.launch(Dispatchers.IO) { - refresh() - } - - ReportListMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } - - is ReportListMviModel.Intent.ResolveComment -> uiState.value.commentReports - .firstOrNull { it.id == intent.id }?.also { - resolve(it) + ReportListMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() } - is ReportListMviModel.Intent.ResolvePost -> uiState.value.postReports - .firstOrNull { it.id == intent.id }?.also { - resolve(it) + ReportListMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() } + is ReportListMviModel.Intent.ResolveComment -> + uiState.value.commentReports + .firstOrNull { it.id == intent.id }?.also { + resolve(it) + } + + is ReportListMviModel.Intent.ResolvePost -> + uiState.value.postReports + .firstOrNull { it.id == intent.id }?.also { + resolve(it) + } + ReportListMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() } } @@ -100,7 +101,7 @@ class ReportListViewModel( updateState { it.copy(unresolvedOnly = value) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { emitEffect(ReportListMviModel.Effect.BackToTop) delay(50) refresh(initial = true) @@ -136,34 +137,37 @@ class ReportListViewModel( if (section == ReportListSection.Posts) { val page = currentPage[ReportListSection.Posts] ?: 1 coroutineScope { - val itemList = async { - postRepository.getReports( - auth = auth, - communityId = communityId, - page = page, - unresolvedOnly = unresolvedOnly, - ) - }.await() - val commentReports = async { - if (page == 1 && (currentState.commentReports.isEmpty() || refreshing)) { - // this is needed because otherwise on first selector change - // the lazy column scrolls back to top (it must have an empty data set) - commentRepository.getReports( + val itemList = + async { + postRepository.getReports( auth = auth, communityId = communityId, - page = 1, + page = page, unresolvedOnly = unresolvedOnly, - ).orEmpty() - } else { - currentState.commentReports - } - }.await() + ) + }.await() + val commentReports = + async { + if (page == 1 && (currentState.commentReports.isEmpty() || refreshing)) { + // this is needed because otherwise on first selector change + // the lazy column scrolls back to top (it must have an empty data set) + commentRepository.getReports( + auth = auth, + communityId = communityId, + page = 1, + unresolvedOnly = unresolvedOnly, + ).orEmpty() + } else { + currentState.commentReports + } + }.await() updateState { - val postReports = if (refreshing) { - itemList.orEmpty() - } else { - it.postReports + itemList.orEmpty() - } + val postReports = + if (refreshing) { + itemList.orEmpty() + } else { + it.postReports + itemList.orEmpty() + } it.copy( postReports = postReports, commentReports = commentReports, @@ -179,19 +183,21 @@ class ReportListViewModel( } } else { val page = currentPage[ReportListSection.Comments] ?: 1 - val itemList = commentRepository.getReports( - auth = auth, - communityId = communityId, - page = page, - unresolvedOnly = unresolvedOnly, - ) + val itemList = + commentRepository.getReports( + auth = auth, + communityId = communityId, + page = page, + unresolvedOnly = unresolvedOnly, + ) updateState { - val commentReports = if (refreshing) { - itemList.orEmpty() - } else { - it.commentReports + itemList.orEmpty() - } + val commentReports = + if (refreshing) { + itemList.orEmpty() + } else { + it.commentReports + itemList.orEmpty() + } it.copy( commentReports = commentReports, loading = false, @@ -210,11 +216,12 @@ class ReportListViewModel( screenModelScope.launch { updateState { it.copy(asyncInProgress = true) } val auth = identityRepository.authToken.value.orEmpty() - val newReport = postRepository.resolveReport( - reportId = report.id, - auth = auth, - resolved = !report.resolved - ) + val newReport = + postRepository.resolveReport( + reportId = report.id, + auth = auth, + resolved = !report.resolved, + ) updateState { it.copy(asyncInProgress = false) } if (newReport != null) { if (uiState.value.unresolvedOnly && newReport.resolved) { @@ -230,11 +237,12 @@ class ReportListViewModel( screenModelScope.launch { updateState { it.copy(asyncInProgress = true) } val auth = identityRepository.authToken.value.orEmpty() - val newReport = commentRepository.resolveReport( - reportId = report.id, - auth = auth, - resolved = !report.resolved - ) + val newReport = + commentRepository.resolveReport( + reportId = report.id, + auth = auth, + resolved = !report.resolved, + ) updateState { it.copy(asyncInProgress = false) } if (newReport != null) { if (uiState.value.unresolvedOnly && newReport.resolved) { @@ -249,13 +257,14 @@ class ReportListViewModel( private fun handleReportUpdate(report: PostReportModel) { updateState { it.copy( - postReports = it.postReports.map { r -> - if (r.id == report.id) { - report - } else { - r - } - } + postReports = + it.postReports.map { r -> + if (r.id == report.id) { + report + } else { + r + } + }, ) } } @@ -263,13 +272,14 @@ class ReportListViewModel( private fun handleReportUpdate(report: CommentReportModel) { updateState { it.copy( - commentReports = it.commentReports.map { r -> - if (r.id == report.id) { - report - } else { - r - } - } + commentReports = + it.commentReports.map { r -> + if (r.id == report.id) { + report + } else { + r + } + }, ) } } @@ -277,7 +287,7 @@ class ReportListViewModel( private fun handleReporDelete(report: PostReportModel) { updateState { it.copy( - postReports = it.postReports.filter { r -> r.id != report.id } + postReports = it.postReports.filter { r -> r.id != report.id }, ) } } @@ -285,7 +295,7 @@ class ReportListViewModel( private fun handleReporDelete(report: CommentReportModel) { updateState { it.copy( - commentReports = it.commentReports.filter { r -> r.id != report.id } + commentReports = it.commentReports.filter { r -> r.id != report.id }, ) } } diff --git a/unit/selectinstance/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/selectinstance/SelectInstanceViewModel.kt b/unit/selectinstance/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/selectinstance/SelectInstanceViewModel.kt index d999de1e5..57f15f3c8 100644 --- a/unit/selectinstance/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/selectinstance/SelectInstanceViewModel.kt +++ b/unit/selectinstance/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/selectinstance/SelectInstanceViewModel.kt @@ -6,9 +6,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.Inst import com.github.diegoberaldin.raccoonforlemmy.core.utils.ValidationError import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.IO import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn @@ -24,7 +22,6 @@ class SelectInstanceViewModel( DefaultMviModel( initialState = SelectInstanceMviModel.State(), ) { - private val saveOperationChannel = Channel>() init { @@ -40,7 +37,7 @@ class SelectInstanceViewModel( } if (uiState.value.instances.isEmpty()) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { val instances = instanceRepository.getAll() updateState { it.copy(instances = instances) } } @@ -64,7 +61,7 @@ class SelectInstanceViewModel( } private fun deleteInstance(value: String) { - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { instanceRepository.remove(value) val instances = instanceRepository.getAll() updateState { it.copy(instances = instances) } @@ -83,13 +80,14 @@ class SelectInstanceViewModel( return } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { updateState { it.copy(changeInstanceLoading = true) } - val res = communityRepository.getList( - instance = instanceName, - page = 1, - limit = 1 - ) + val res = + communityRepository.getList( + instance = instanceName, + page = 1, + limit = 1, + ) if (res.isEmpty()) { updateState { it.copy( @@ -115,11 +113,15 @@ class SelectInstanceViewModel( } } - private fun swapInstances(from: Int, to: Int) { - val newInstances = uiState.value.instances.toMutableList().apply { - val element = removeAt(from) - add(to, element) - } + private fun swapInstances( + from: Int, + to: Int, + ) { + val newInstances = + uiState.value.instances.toMutableList().apply { + val element = removeAt(from) + add(to, element) + } screenModelScope.launch { saveOperationChannel.send(newInstances) updateState { diff --git a/unit/userdetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/userdetail/UserDetailViewModel.kt b/unit/userdetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/userdetail/UserDetailViewModel.kt index f5b519a12..e28d0e9d0 100644 --- a/unit/userdetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/userdetail/UserDetailViewModel.kt +++ b/unit/userdetail/src/commonMain/kotlin/com/github/diegoberaldin/raccoonforlemmy/unit/userdetail/UserDetailViewModel.kt @@ -31,14 +31,12 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepo import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class UserDetailViewModel( private val userId: Long, @@ -64,12 +62,12 @@ class UserDetailViewModel( DefaultMviModel( initialState = UserDetailMviModel.UiState(), ) { - init { updateState { it.copy( - instance = otherInstance.takeIf { n -> n.isNotEmpty() } - ?: apiConfigurationRepository.instance.value, + instance = + otherInstance.takeIf { n -> n.isNotEmpty() } + ?: apiConfigurationRepository.instance.value, ) } screenModelScope.launch { @@ -141,9 +139,7 @@ class UserDetailViewModel( settingsRepository.currentSettings.value.defaultPostSortType updateState { it.copy(sortType = defaultPostSortType.toSortType()) } - withContext(Dispatchers.IO) { - refresh(initial = true) - } + refresh(initial = true) } } } @@ -172,13 +168,15 @@ class UserDetailViewModel( } UserDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() - UserDetailMviModel.Intent.LoadNextPage -> screenModelScope.launch { - loadNextPage() - } + UserDetailMviModel.Intent.LoadNextPage -> + screenModelScope.launch { + loadNextPage() + } - UserDetailMviModel.Intent.Refresh -> screenModelScope.launch { - refresh() - } + UserDetailMviModel.Intent.Refresh -> + screenModelScope.launch { + refresh() + } is UserDetailMviModel.Intent.SaveComment -> { if (intent.feedback) { @@ -222,9 +220,10 @@ class UserDetailViewModel( UserDetailMviModel.Intent.Block -> blockUser() UserDetailMviModel.Intent.BlockInstance -> blockInstance() - is UserDetailMviModel.Intent.Copy -> screenModelScope.launch { - emitEffect(UserDetailMviModel.Effect.TriggerCopy(intent.value)) - } + is UserDetailMviModel.Intent.Copy -> + screenModelScope.launch { + emitEffect(UserDetailMviModel.Effect.TriggerCopy(intent.value)) + } UserDetailMviModel.Intent.WillOpenDetail -> { val state = postPaginationManager.extractState() @@ -253,11 +252,12 @@ class UserDetailViewModel( private fun updateAvailableSortTypes() { screenModelScope.launch { - val sortTypes = if (uiState.value.section == UserDetailSection.Posts) { - getSortTypesUseCase.getTypesForPosts(otherInstance = otherInstance) - } else { - getSortTypesUseCase.getTypesForComments(otherInstance = otherInstance) - } + val sortTypes = + if (uiState.value.section == UserDetailSection.Posts) { + getSortTypesUseCase.getTypesForPosts(otherInstance = otherInstance) + } else { + getSortTypesUseCase.getTypesForComments(otherInstance = otherInstance) + } updateState { it.copy(availableSortTypes = sortTypes) } } } @@ -269,7 +269,7 @@ class UserDetailViewModel( name = uiState.value.user.name, sortType = uiState.value.sortType, otherInstance = otherInstance, - ) + ), ) commentPaginationManager.reset( CommentPaginationSpecification.User( @@ -277,7 +277,7 @@ class UserDetailViewModel( name = uiState.value.user.name, sortType = uiState.value.sortType, otherInstance = otherInstance, - ) + ), ) updateState { it.copy( @@ -288,12 +288,13 @@ class UserDetailViewModel( ) } val auth = identityRepository.authToken.value - val refreshedUser = userRepository.get( - id = userId, - auth = auth, - otherInstance = otherInstance, - username = uiState.value.user.name, - ) + val refreshedUser = + userRepository.get( + id = userId, + auth = auth, + otherInstance = otherInstance, + username = uiState.value.user.name, + ) if (refreshedUser != null) { updateState { it.copy(user = refreshedUser) } } @@ -311,18 +312,20 @@ class UserDetailViewModel( val section = currentState.section if (section == UserDetailSection.Posts) { coroutineScope { - val posts = async { - postPaginationManager.loadNextPage() - }.await() - val comments = async { - if (currentState.comments.isEmpty() || refreshing) { - // this is needed because otherwise on first selector change - // the lazy column scrolls back to top (it must have an empty data set) - commentPaginationManager.loadNextPage() - } else { - currentState.comments - } - }.await() + val posts = + async { + postPaginationManager.loadNextPage() + }.await() + val comments = + async { + if (currentState.comments.isEmpty() || refreshing) { + // this is needed because otherwise on first selector change + // the lazy column scrolls back to top (it must have an empty data set) + commentPaginationManager.loadNextPage() + } else { + currentState.comments + } + }.await() updateState { if (uiState.value.autoLoadImages) { posts.forEach { post -> @@ -357,10 +360,11 @@ class UserDetailViewModel( private fun toggleUpVote(post: PostModel) { val newVote = post.myVote <= 0 - val newPost = postRepository.asUpVoted( - post = post, - voted = newVote, - ) + val newPost = + postRepository.asUpVoted( + post = post, + voted = newVote, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -379,10 +383,11 @@ class UserDetailViewModel( private fun toggleDownVote(post: PostModel) { val newValue = post.myVote >= 0 - val newPost = postRepository.asDownVoted( - post = post, - downVoted = newValue, - ) + val newPost = + postRepository.asDownVoted( + post = post, + downVoted = newValue, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -401,10 +406,11 @@ class UserDetailViewModel( private fun toggleSave(post: PostModel) { val newValue = !post.saved - val newPost = postRepository.asSaved( - post = post, - saved = newValue, - ) + val newPost = + postRepository.asSaved( + post = post, + saved = newValue, + ) handlePostUpdate(newPost) screenModelScope.launch { try { @@ -423,10 +429,11 @@ class UserDetailViewModel( private fun toggleUpVoteComment(comment: CommentModel) { val newValue = comment.myVote <= 0 - val newComment = commentRepository.asUpVoted( - comment = comment, - voted = newValue, - ) + val newComment = + commentRepository.asUpVoted( + comment = comment, + voted = newValue, + ) handleCommentUpdate(newComment) screenModelScope.launch { try { @@ -464,10 +471,11 @@ class UserDetailViewModel( private fun toggleSaveComment(comment: CommentModel) { val newValue = !comment.saved - val newComment = commentRepository.asSaved( - comment = comment, - saved = newValue, - ) + val newComment = + commentRepository.asSaved( + comment = comment, + saved = newValue, + ) handleCommentUpdate(newComment) screenModelScope.launch { try { @@ -487,13 +495,14 @@ class UserDetailViewModel( private fun handlePostUpdate(post: PostModel) { updateState { it.copy( - posts = it.posts.map { p -> - if (p.id == post.id) { - post - } else { - p - } - }, + posts = + it.posts.map { p -> + if (p.id == post.id) { + post + } else { + p + } + }, ) } } @@ -501,20 +510,21 @@ class UserDetailViewModel( private fun handleCommentUpdate(comment: CommentModel) { updateState { it.copy( - comments = it.comments.map { c -> - if (c.id == comment.id) { - comment - } else { - c - } - }, + comments = + it.comments.map { c -> + if (c.id == comment.id) { + comment + } else { + c + } + }, ) } } private fun blockUser() { updateState { it.copy(asyncInProgress = true) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val auth = identityRepository.authToken.value userRepository.block(userId, true, auth).getOrThrow() @@ -529,7 +539,7 @@ class UserDetailViewModel( private fun blockInstance() { updateState { it.copy(asyncInProgress = true) } - screenModelScope.launch(Dispatchers.IO) { + screenModelScope.launch { try { val user = uiState.value.user val instanceId = user.instanceId