mirror of https://github.com/readrops/Readrops.git
Implement FreshRSS add/update/delete feed actions
This commit is contained in:
parent
940b6de97a
commit
133d8e6992
|
@ -121,21 +121,29 @@ class FeedScreenModel(
|
|||
_feedState.update { it.copy(areFoldersExpanded = isExpanded) }
|
||||
|
||||
fun closeDialog(dialog: DialogState? = null) {
|
||||
if (dialog is DialogState.AddFeed) {
|
||||
_addFeedDialogState.update {
|
||||
it.copy(
|
||||
url = "",
|
||||
error = null,
|
||||
)
|
||||
when (dialog) {
|
||||
is DialogState.AddFeed -> {
|
||||
_addFeedDialogState.update {
|
||||
it.copy(
|
||||
url = "",
|
||||
error = null,
|
||||
exception = null
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (dialog is DialogState.AddFolder || dialog is DialogState.UpdateFolder) {
|
||||
_folderState.update {
|
||||
it.copy(
|
||||
folder = Folder(),
|
||||
nameError = null,
|
||||
exception = null
|
||||
)
|
||||
is DialogState.AddFolder, is DialogState.UpdateFolder -> {
|
||||
_folderState.update {
|
||||
it.copy(
|
||||
folder = Folder(),
|
||||
nameError = null,
|
||||
exception = null
|
||||
)
|
||||
}
|
||||
}
|
||||
is DialogState.UpdateFeed -> {
|
||||
_updateFeedDialogState.update { it.copy(exception = null) }
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
_feedState.update { it.copy(dialog = null) }
|
||||
|
@ -166,7 +174,11 @@ class FeedScreenModel(
|
|||
|
||||
fun deleteFeed(feed: Feed) {
|
||||
screenModelScope.launch(Dispatchers.IO) {
|
||||
repository?.deleteFeed(feed)
|
||||
try {
|
||||
repository?.deleteFeed(feed)
|
||||
} catch (e: Exception) {
|
||||
_feedState.update { it.copy(exception = e) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +192,7 @@ class FeedScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
// Add feed
|
||||
//region Add Feed
|
||||
|
||||
fun setAddFeedDialogURL(url: String) {
|
||||
_addFeedDialogState.update {
|
||||
|
@ -218,12 +230,7 @@ class FeedScreenModel(
|
|||
else -> screenModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
if (localRSSDataSource.isUrlRSSResource(url)) {
|
||||
// TODO add support for all account types
|
||||
repository?.insertNewFeeds(
|
||||
newFeeds = listOf(Feed(url = url))
|
||||
) {}
|
||||
|
||||
closeDialog(DialogState.AddFeed)
|
||||
insertFeeds(listOf(Feed(url = url)))
|
||||
} else {
|
||||
val rssUrls = HtmlParser.getFeedLink(url, get())
|
||||
|
||||
|
@ -232,12 +239,7 @@ class FeedScreenModel(
|
|||
it.copy(error = TextFieldError.NoRSSFeed)
|
||||
}
|
||||
} else {
|
||||
// TODO add support for all account types
|
||||
repository?.insertNewFeeds(
|
||||
newFeeds = rssUrls.map { Feed(url = it.url) }
|
||||
) {}
|
||||
|
||||
closeDialog(DialogState.AddFeed)
|
||||
insertFeeds(rssUrls.map { Feed(url = it.url) })
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -250,9 +252,22 @@ class FeedScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
// add feed
|
||||
private suspend fun insertFeeds(feeds: List<Feed>) {
|
||||
val errors = repository?.insertNewFeeds(
|
||||
newFeeds = feeds,
|
||||
onUpdate = { /* no need of this here */ }
|
||||
)!!
|
||||
|
||||
// update feed
|
||||
if (errors.isEmpty()) {
|
||||
closeDialog(DialogState.AddFeed)
|
||||
} else {
|
||||
_addFeedDialogState.update { it.copy(exception = errors.values.first()) }
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
//region Update feed
|
||||
|
||||
fun setAccountDropDownState(isExpanded: Boolean) {
|
||||
_updateFeedDialogState.update {
|
||||
|
@ -311,16 +326,24 @@ class FeedScreenModel(
|
|||
}
|
||||
|
||||
else -> {
|
||||
_updateFeedDialogState.update { it.copy(exception = null) }
|
||||
|
||||
screenModelScope.launch(Dispatchers.IO) {
|
||||
with(_updateFeedDialogState.value) {
|
||||
repository?.updateFeed(
|
||||
Feed(
|
||||
id = feedId,
|
||||
name = feedName,
|
||||
url = feedUrl,
|
||||
folderId = selectedFolder?.id
|
||||
try {
|
||||
repository?.updateFeed(
|
||||
Feed(
|
||||
id = feedId,
|
||||
name = feedName,
|
||||
url = feedUrl,
|
||||
folderId = selectedFolder?.id,
|
||||
remoteFolderId = selectedFolder?.remoteId
|
||||
)
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
_updateFeedDialogState.update { it.copy(exception = e) }
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
closeDialog()
|
||||
|
@ -329,9 +352,9 @@ class FeedScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
// update feed
|
||||
//endregion
|
||||
|
||||
// add/update folder
|
||||
//region Add/Update folder
|
||||
|
||||
fun setFolderName(name: String) = _folderState.update {
|
||||
it.copy(
|
||||
|
@ -369,5 +392,5 @@ class FeedScreenModel(
|
|||
|
||||
fun resetException() = _feedState.update { it.copy(exception = null) }
|
||||
|
||||
// add/update folder
|
||||
//endregion
|
||||
}
|
|
@ -34,6 +34,7 @@ data class AddFeedDialogState(
|
|||
val selectedAccount: Account = Account(accountName = ""),
|
||||
val accounts: List<Account> = listOf(),
|
||||
val error: TextFieldError? = null,
|
||||
val exception: Exception? = null
|
||||
) {
|
||||
val isError: Boolean get() = error != null
|
||||
}
|
||||
|
@ -48,7 +49,8 @@ data class UpdateFeedDialogState(
|
|||
val folders: List<Folder> = listOf(),
|
||||
val isAccountDropDownExpanded: Boolean = false,
|
||||
val isFeedUrlReadOnly: Boolean = true,
|
||||
val isNoFolderCase: Boolean = false
|
||||
val isNoFolderCase: Boolean = false,
|
||||
val exception: Exception? = null
|
||||
) {
|
||||
val isFeedNameError
|
||||
get() = feedNameError != null
|
||||
|
|
|
@ -123,7 +123,7 @@ object FeedTab : Tab {
|
|||
is DialogState.UpdateFeed -> {
|
||||
UpdateFeedDialog(
|
||||
viewModel = viewModel,
|
||||
onDismissRequest = { viewModel.closeDialog() }
|
||||
onDismissRequest = { viewModel.closeDialog(dialog) }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.compose.material3.ExposedDropdownMenuBox
|
|||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
|
@ -19,15 +20,19 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.readrops.app.compose.R
|
||||
import com.readrops.app.compose.account.selection.adaptiveIconPainterResource
|
||||
import com.readrops.app.compose.feeds.FeedScreenModel
|
||||
import com.readrops.app.compose.util.ErrorMessage
|
||||
import com.readrops.app.compose.util.components.BaseDialog
|
||||
import com.readrops.app.compose.util.theme.LargeSpacer
|
||||
import com.readrops.app.compose.util.theme.MediumSpacer
|
||||
import com.readrops.app.compose.util.theme.ShortSpacer
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
@ -118,6 +123,16 @@ fun AddFeedDialog(
|
|||
)
|
||||
}
|
||||
|
||||
if (state.exception != null) {
|
||||
MediumSpacer()
|
||||
|
||||
Text(
|
||||
text = ErrorMessage.get(state.exception!!, LocalContext.current),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
LargeSpacer()
|
||||
|
||||
TextButton(
|
||||
|
|
|
@ -5,17 +5,20 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.readrops.app.compose.R
|
||||
import com.readrops.app.compose.feeds.FeedScreenModel
|
||||
import com.readrops.app.compose.util.ErrorMessage
|
||||
import com.readrops.app.compose.util.components.BaseDialog
|
||||
import com.readrops.app.compose.util.theme.LargeSpacer
|
||||
import com.readrops.app.compose.util.theme.MediumSpacer
|
||||
|
@ -119,6 +122,15 @@ fun UpdateFeedDialog(
|
|||
)
|
||||
}
|
||||
|
||||
if (state.exception != null) {
|
||||
MediumSpacer()
|
||||
|
||||
Text(
|
||||
text = ErrorMessage.get(state.exception!!, LocalContext.current),
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
|
||||
LargeSpacer()
|
||||
|
||||
TextButton(
|
||||
|
|
|
@ -85,7 +85,31 @@ class FreshRSSRepository(
|
|||
override suspend fun insertNewFeeds(
|
||||
newFeeds: List<Feed>,
|
||||
onUpdate: (Feed) -> Unit
|
||||
): ErrorResult = TODO("Not yet implemented")
|
||||
): ErrorResult {
|
||||
val errors = mutableMapOf<Feed, Exception>()
|
||||
|
||||
for (newFeed in newFeeds) {
|
||||
onUpdate(newFeed)
|
||||
|
||||
try {
|
||||
dataSource.createFeed(account.writeToken!!, newFeed.url!!)
|
||||
} catch (e: Exception) {
|
||||
errors[newFeed] = e
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
override suspend fun updateFeed(feed: Feed) {
|
||||
dataSource.updateFeed(account.writeToken!!, feed.url!!, feed.name!!, feed.remoteFolderId!!)
|
||||
super.updateFeed(feed)
|
||||
}
|
||||
|
||||
override suspend fun deleteFeed(feed: Feed) {
|
||||
dataSource.deleteFeed(account.writeToken!!, feed.url!!)
|
||||
super.deleteFeed(feed)
|
||||
}
|
||||
|
||||
override suspend fun updateFolder(folder: Folder) {
|
||||
dataSource.updateFolder(account.writeToken!!, folder.remoteId!!, folder.name!!)
|
||||
|
|
Loading…
Reference in New Issue