Use AccountError in FeedTab

This commit is contained in:
Shinokuni 2024-11-12 18:40:50 +01:00
parent 903f6c5427
commit a96bf18a18
9 changed files with 41 additions and 33 deletions

View File

@ -40,15 +40,15 @@ import org.koin.dsl.module
val appModule = module { val appModule = module {
factory { TimelineScreenModel(get(), get(), get()) } factory { TimelineScreenModel(get(), get(), get(), androidContext()) }
factory { FeedScreenModel(get(), get(), get(), androidContext()) } factory { FeedScreenModel(get(), get(), androidContext()) }
factory { (url: String?) -> NewFeedScreenModel(get(), get(), androidContext(), url) } factory { (url: String?) -> NewFeedScreenModel(get(), get(), androidContext(), url) }
factory { AccountSelectionScreenModel(get()) } factory { AccountSelectionScreenModel(get()) }
factory { AccountScreenModel(get()) } factory { AccountScreenModel(get(), androidContext()) }
factory { (itemId: Int) -> ItemScreenModel(get(), itemId, get()) } factory { (itemId: Int) -> ItemScreenModel(get(), itemId, get()) }

View File

@ -29,8 +29,9 @@ import org.koin.core.component.get
class AccountScreenModel( class AccountScreenModel(
private val database: Database, private val database: Database,
context: Context,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : TabScreenModel(database) { ) : TabScreenModel(database, context) {
private val _closeHome = MutableStateFlow(false) private val _closeHome = MutableStateFlow(false)
val closeHome = _closeHome.asStateFlow() val closeHome = _closeHome.asStateFlow()

View File

@ -3,7 +3,6 @@ package com.readrops.app.feeds
import android.content.Context import android.content.Context
import android.util.Patterns import android.util.Patterns
import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.core.model.screenModelScope
import com.readrops.api.localfeed.LocalRSSDataSource
import com.readrops.app.R import com.readrops.app.R
import com.readrops.app.home.TabScreenModel import com.readrops.app.home.TabScreenModel
import com.readrops.app.repositories.GetFoldersWithFeeds import com.readrops.app.repositories.GetFoldersWithFeeds
@ -28,10 +27,9 @@ import org.koin.core.component.KoinComponent
class FeedScreenModel( class FeedScreenModel(
database: Database, database: Database,
private val getFoldersWithFeeds: GetFoldersWithFeeds, private val getFoldersWithFeeds: GetFoldersWithFeeds,
private val localRSSDataSource: LocalRSSDataSource,
private val context: Context, private val context: Context,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : TabScreenModel(database), KoinComponent { ) : TabScreenModel(database, context), KoinComponent {
private val _feedState = MutableStateFlow(FeedState()) private val _feedState = MutableStateFlow(FeedState())
val feedsState = _feedState.asStateFlow() val feedsState = _feedState.asStateFlow()
@ -112,14 +110,14 @@ class FeedScreenModel(
it.copy( it.copy(
value = "", value = "",
textFieldError = null, textFieldError = null,
exception = null, error = null,
isLoading = false isLoading = false
) )
} }
} }
is DialogState.UpdateFeed -> { is DialogState.UpdateFeed -> {
_updateFeedDialogState.update { it.copy(exception = null, isLoading = false) } _updateFeedDialogState.update { it.copy(error = null, isLoading = false) }
} }
else -> {} else -> {}
@ -162,7 +160,7 @@ class FeedScreenModel(
try { try {
repository?.deleteFeed(feed) repository?.deleteFeed(feed)
} catch (e: Exception) { } catch (e: Exception) {
_feedState.update { it.copy(exception = e) } _feedState.update { it.copy(error = accountError?.deleteFeedMessage(e)) }
} }
} }
} }
@ -172,7 +170,7 @@ class FeedScreenModel(
try { try {
repository?.deleteFolder(folder) repository?.deleteFolder(folder)
} catch (e: Exception) { } catch (e: Exception) {
_feedState.update { it.copy(exception = e) } _feedState.update { it.copy(error = accountError?.deleteFolderMessage(e)) }
} }
} }
} }
@ -236,7 +234,7 @@ class FeedScreenModel(
} }
else -> { else -> {
_updateFeedDialogState.update { it.copy(exception = null, isLoading = true) } _updateFeedDialogState.update { it.copy(error = null, isLoading = true) }
screenModelScope.launch(dispatcher) { screenModelScope.launch(dispatcher) {
with(_updateFeedDialogState.value) { with(_updateFeedDialogState.value) {
@ -256,7 +254,7 @@ class FeedScreenModel(
} catch (e: Exception) { } catch (e: Exception) {
_updateFeedDialogState.update { _updateFeedDialogState.update {
it.copy( it.copy(
exception = e, error = accountError?.updateFeedMessage(e),
isLoading = false isLoading = false
) )
} }
@ -304,7 +302,16 @@ class FeedScreenModel(
repository?.addFolder(Folder(name = name, accountId = currentAccount!!.id)) repository?.addFolder(Folder(name = name, accountId = currentAccount!!.id))
} }
} catch (e: Exception) { } catch (e: Exception) {
_folderState.update { it.copy(exception = e, isLoading = false) } _folderState.update {
it.copy(
error = if (updateFolder) {
accountError?.updateFolderMessage(e)
} else {
accountError?.newFolderMessage(e)
},
isLoading = false
)
}
return@launch return@launch
} }
@ -312,7 +319,7 @@ class FeedScreenModel(
} }
} }
fun resetException() = _feedState.update { it.copy(exception = null) } fun resetException() = _feedState.update { it.copy(error = null) }
//endregion //endregion
} }

View File

@ -9,7 +9,7 @@ data class FeedState(
val foldersAndFeeds: FolderAndFeedsState = FolderAndFeedsState.InitialState, val foldersAndFeeds: FolderAndFeedsState = FolderAndFeedsState.InitialState,
val dialog: DialogState? = null, val dialog: DialogState? = null,
val areFoldersExpanded: Boolean = false, val areFoldersExpanded: Boolean = false,
val exception: Exception? = null, val error: String? = null,
val config: AccountConfig? = null val config: AccountConfig? = null
) { ) {
@ -48,7 +48,7 @@ data class UpdateFeedDialogState(
val folders: List<Folder> = listOf(), val folders: List<Folder> = listOf(),
val isFolderDropDownExpanded: Boolean = false, val isFolderDropDownExpanded: Boolean = false,
val isFeedUrlReadOnly: Boolean = true, val isFeedUrlReadOnly: Boolean = true,
val exception: Exception? = null, val error: String? = null,
val isLoading: Boolean = false val isLoading: Boolean = false
) { ) {
val isFeedNameError val isFeedNameError

View File

@ -32,7 +32,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -48,7 +47,6 @@ import com.readrops.app.R
import com.readrops.app.feeds.dialogs.FeedModalBottomSheet import com.readrops.app.feeds.dialogs.FeedModalBottomSheet
import com.readrops.app.feeds.dialogs.UpdateFeedDialog import com.readrops.app.feeds.dialogs.UpdateFeedDialog
import com.readrops.app.feeds.newfeed.NewFeedScreen import com.readrops.app.feeds.newfeed.NewFeedScreen
import com.readrops.app.util.ErrorMessage
import com.readrops.app.util.components.CenteredProgressIndicator import com.readrops.app.util.components.CenteredProgressIndicator
import com.readrops.app.util.components.ErrorMessage import com.readrops.app.util.components.ErrorMessage
import com.readrops.app.util.components.Placeholder import com.readrops.app.util.components.Placeholder
@ -75,7 +73,6 @@ object FeedTab : Tab {
override fun Content() { override fun Content() {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val screenModel = koinScreenModel<FeedScreenModel>() val screenModel = koinScreenModel<FeedScreenModel>()
@ -85,9 +82,9 @@ object FeedTab : Tab {
val topAppBarScrollBehavior = val topAppBarScrollBehavior =
TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
LaunchedEffect(state.exception) { LaunchedEffect(state.error) {
if (state.exception != null) { if (state.error != null) {
snackbarHostState.showSnackbar(ErrorMessage.get(state.exception!!, context)) snackbarHostState.showSnackbar((state.error!!))
screenModel.resetException() screenModel.resetException()
} }
} }

View File

@ -12,13 +12,11 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.readrops.app.R import com.readrops.app.R
import com.readrops.app.feeds.FeedScreenModel import com.readrops.app.feeds.FeedScreenModel
import com.readrops.app.util.ErrorMessage
import com.readrops.app.util.components.LoadingTextButton import com.readrops.app.util.components.LoadingTextButton
import com.readrops.app.util.components.dialog.BaseDialog import com.readrops.app.util.components.dialog.BaseDialog
import com.readrops.app.util.theme.LargeSpacer import com.readrops.app.util.theme.LargeSpacer
@ -123,11 +121,11 @@ fun UpdateFeedDialog(
) )
} }
if (state.exception != null) { if (state.error != null) {
MediumSpacer() MediumSpacer()
Text( Text(
text = ErrorMessage.get(state.exception!!, LocalContext.current), text = state.error!!,
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
) )
} }

View File

@ -1,11 +1,13 @@
package com.readrops.app.home package com.readrops.app.home
import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.core.model.screenModelScope
import com.readrops.api.services.Credentials import com.readrops.api.services.Credentials
import com.readrops.api.utils.AuthInterceptor import com.readrops.api.utils.AuthInterceptor
import com.readrops.app.repositories.BaseRepository import com.readrops.app.repositories.BaseRepository
import com.readrops.app.util.accounterror.AccountError
import com.readrops.db.Database import com.readrops.db.Database
import com.readrops.db.entities.account.Account import com.readrops.db.entities.account.Account
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
@ -24,6 +26,7 @@ import org.koin.core.parameter.parametersOf
*/ */
abstract class TabScreenModel( abstract class TabScreenModel(
private val database: Database, private val database: Database,
private val context: Context,
dispatcher: CoroutineDispatcher = Dispatchers.IO dispatcher: CoroutineDispatcher = Dispatchers.IO
) : ScreenModel, KoinComponent { ) : ScreenModel, KoinComponent {
@ -34,6 +37,8 @@ abstract class TabScreenModel(
protected var currentAccount: Account? = null protected var currentAccount: Account? = null
protected var accountError: AccountError? = null
private val _accountEvent = MutableSharedFlow<Account>() private val _accountEvent = MutableSharedFlow<Account>()
protected val accountEvent = protected val accountEvent =
_accountEvent.shareIn(scope = screenModelScope, started = SharingStarted.Eagerly) _accountEvent.shareIn(scope = screenModelScope, started = SharingStarted.Eagerly)
@ -61,6 +66,7 @@ abstract class TabScreenModel(
currentAccount = account currentAccount = account
repository = get(parameters = { parametersOf(account) }) repository = get(parameters = { parametersOf(account) })
accountError = AccountError.from(account, context)
_accountEvent.emit(account) _accountEvent.emit(account)
} }

View File

@ -45,8 +45,9 @@ class TimelineScreenModel(
private val database: Database, private val database: Database,
private val getFoldersWithFeeds: GetFoldersWithFeeds, private val getFoldersWithFeeds: GetFoldersWithFeeds,
private val preferences: Preferences, private val preferences: Preferences,
context: Context,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : TabScreenModel(database) { ) : TabScreenModel(database, context) {
private val _timelineState = MutableStateFlow(TimelineState()) private val _timelineState = MutableStateFlow(TimelineState())
val timelineState = _timelineState.asStateFlow() val timelineState = _timelineState.asStateFlow()

View File

@ -10,10 +10,8 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.readrops.app.R import com.readrops.app.R
import com.readrops.app.util.ErrorMessage
import com.readrops.app.util.components.LoadingTextButton import com.readrops.app.util.components.LoadingTextButton
import com.readrops.app.util.components.TextFieldError import com.readrops.app.util.components.TextFieldError
import com.readrops.app.util.theme.LargeSpacer import com.readrops.app.util.theme.LargeSpacer
@ -21,7 +19,7 @@ import com.readrops.app.util.theme.LargeSpacer
data class TextFieldDialogState( data class TextFieldDialogState(
val value: String = "", val value: String = "",
val textFieldError: TextFieldError? = null, val textFieldError: TextFieldError? = null,
val exception: Exception? = null, val error: String? = null,
val isLoading: Boolean = false val isLoading: Boolean = false
) { ) {
val isTextFieldError val isTextFieldError
@ -66,9 +64,9 @@ fun TextFieldDialog(
supportingText = { Text(text = state.textFieldError?.errorText().orEmpty()) } supportingText = { Text(text = state.textFieldError?.errorText().orEmpty()) }
) )
if (state.exception != null) { if (state.error != null) {
Text( Text(
text = ErrorMessage.get(state.exception, LocalContext.current), text = state.error,
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
) )
} }