mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-08 19:08:46 +01:00
chore: remove unnecessary dispatcher switch (#852)
This commit is contained in:
parent
9ebf3f7b9e
commit
cae9fd4da3
@ -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<InboxMviModel.Intent, InboxMviModel.UiState, InboxMviModel.Effect>(
|
||||
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)
|
||||
|
@ -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<AdvancedSettingsMviModel.Intent, AdvancedSettingsMviModel.UiState, AdvancedSettingsMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
|
@ -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<SettingsColorAndFontMviModel.Intent, SettingsColorAndFontMviModel.UiState, SettingsColorAndFontMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<SettingsMviModel.Intent, SettingsMviModel.UiState, SettingsMviModel.Effect>(
|
||||
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(
|
||||
|
@ -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<MainScreenMviModel.Intent, MainScreenMviModel.UiState, MainScreenMviModel.Effect>(
|
||||
initialState = MainScreenMviModel.UiState(),
|
||||
) {
|
||||
|
||||
init {
|
||||
screenModelScope.launch(Dispatchers.IO) {
|
||||
screenModelScope.launch {
|
||||
identityRepository.startup()
|
||||
|
||||
inboxCoordinator.totalUnread.onEach { unreadCount ->
|
||||
|
@ -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<InboxChatMviModel.Intent, InboxChatMviModel.UiState, InboxChatMviModel.Effect>(
|
||||
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,
|
||||
|
@ -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<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect>(
|
||||
initialState = CommunityDetailMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private var hideReadPosts = false
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
@ -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) {
|
||||
|
@ -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<ConfigureContentViewMviModel.Intent, ConfigureContentViewMviModel.State, ConfigureContentViewMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ConfigureSwipeActionsMviModel.Intent, ConfigureSwipeActionsMviModel.UiState, ConfigureSwipeActionsMviModel.Effect>(
|
||||
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<ActionOnSwipe> = 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<ActionOnSwipe> =
|
||||
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<ActionOnSwipe> = 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<ActionOnSwipe> =
|
||||
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<ActionOnSwipe> = 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<ActionOnSwipe> =
|
||||
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(),
|
||||
|
@ -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<ModalDrawerMviModel.Intent, ModalDrawerMviModel.UiState, ModalDrawerMviModel.Effect>(
|
||||
initialState = ModalDrawerMviModel.UiState()
|
||||
initialState = ModalDrawerMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
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(),
|
||||
|
@ -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<ExploreMviModel.Intent, ExploreMviModel.UiState, ExploreMviModel.Effect>(
|
||||
initialState = ExploreMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
private var searchEventChannel = Channel<Unit>()
|
||||
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<SearchResult.Post>()
|
||||
.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<SearchResult.Post>()
|
||||
.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()
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
@ -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<ManageBanMviModel.Intent, ManageBanMviModel.UiState, ManageBanMviModel.Effect>(
|
||||
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(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect>(
|
||||
initialState = ManageSubscriptionsMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
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
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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<InboxMentionsMviModel.Intent, InboxMentionsMviModel.UiState, InboxMentionsMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<InboxMessagesMviModel.Intent, InboxMessagesMviModel.UiState, InboxMessagesMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<MultiCommunityMviModel.Intent, MultiCommunityMviModel.UiState, MultiCommunityMviModel.Effect>(
|
||||
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
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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<MultiCommunityEditorMviModel.Intent, MultiCommunityEditorMviModel.UiState, MultiCommunityEditorMviModel.Effect>(
|
||||
initialState = MultiCommunityEditorMviModel.UiState()
|
||||
initialState = MultiCommunityEditorMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private var communities: List<Pair<CommunityModel, Boolean>> = emptyList()
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
@ -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<Pair<CommunityModel, Boolean>> {
|
||||
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)
|
||||
|
@ -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<ProfileLoggedMviModel.Intent, ProfileLoggedMviModel.UiState, ProfileLoggedMviModel.Effect>(
|
||||
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()
|
||||
|
@ -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<PostListMviModel.Intent, PostListMviModel.UiState, PostListMviModel.Effect>(
|
||||
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)
|
||||
|
@ -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<InboxRepliesMviModel.Intent, InboxRepliesMviModel.UiState, InboxRepliesMviModel.Effect>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<ReportListMviModel.Intent, ReportListMviModel.UiState, ReportListMviModel.Effect>(
|
||||
initialState = ReportListMviModel.UiState(),
|
||||
) {
|
||||
|
||||
private val currentPage = mutableMapOf<ReportListSection, Int>()
|
||||
|
||||
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 },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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<SelectInstanceMviModel.Intent, SelectInstanceMviModel.State, SelectInstanceMviModel.Effect>(
|
||||
initialState = SelectInstanceMviModel.State(),
|
||||
) {
|
||||
|
||||
private val saveOperationChannel = Channel<List<String>>()
|
||||
|
||||
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 {
|
||||
|
@ -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<UserDetailMviModel.Intent, UserDetailMviModel.UiState, UserDetailMviModel.Effect>(
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user