Disable feed/folder actions in FeedTab for Fever accounts

This commit is contained in:
Shinokuni 2024-08-10 13:52:24 +02:00
parent 65a49e7fc5
commit 0265b88ff3
7 changed files with 124 additions and 67 deletions

View File

@ -56,21 +56,23 @@ class FeedScreenModel(
init {
screenModelScope.launch(dispatcher) {
accountEvent
.flatMapLatest { account ->
_feedState.update { it.copy(displayFolderCreationButton = account.config.canCreateFolder) }
_updateFeedDialogState.update {
it.copy(
isFeedUrlReadOnly = account.config.isFeedUrlReadOnly,
)
}
accountEvent.flatMapLatest { account ->
_feedState.update {
it.copy(config = account.config)
}
getFoldersWithFeeds.get(
account.id,
MainFilter.ALL,
account.config.useSeparateState
_updateFeedDialogState.update {
it.copy(
isFeedUrlReadOnly = account.config.isFeedUrlReadOnly,
)
}
getFoldersWithFeeds.get(
account.id,
MainFilter.ALL,
account.config.useSeparateState
)
}
.catch { throwable ->
_feedState.update {
it.copy(foldersAndFeeds = FolderAndFeedsState.ErrorState(Exception(throwable)))
@ -81,7 +83,6 @@ class FeedScreenModel(
it.copy(foldersAndFeeds = FolderAndFeedsState.LoadedState(foldersAndFeeds))
}
}
}
screenModelScope.launch(dispatcher) {
@ -174,11 +175,13 @@ class FeedScreenModel(
feedId = state.feed.id,
feedName = state.feed.name!!,
feedUrl = state.feed.url!!,
selectedFolder = state.folder ?: it.folders.find { folder -> folder.id == 0 },
selectedFolder = state.folder
?: it.folders.find { folder -> folder.id == 0 },
feedRemoteId = state.feed.remoteId
)
}
}
is DialogState.UpdateFolder -> {
_folderState.update {
it.copy(
@ -186,11 +189,13 @@ class FeedScreenModel(
)
}
}
is DialogState.AddFeed -> {
_addFeedDialogState.update {
it.copy(url = state.url.orEmpty())
}
}
else -> {}
}
@ -229,7 +234,12 @@ class FeedScreenModel(
}
fun setAddFeedDialogSelectedAccount(account: Account) {
_addFeedDialogState.update { it.copy(selectedAccount = account, isAccountDropDownExpanded = false) }
_addFeedDialogState.update {
it.copy(
selectedAccount = account,
isAccountDropDownExpanded = false
)
}
}
fun setAccountDropDownExpanded(isExpanded: Boolean) {

View File

@ -4,14 +4,19 @@ import com.readrops.app.util.components.TextFieldError
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.entities.account.Account
import com.readrops.db.entities.account.AccountConfig
data class FeedState(
val foldersAndFeeds: FolderAndFeedsState = FolderAndFeedsState.InitialState,
val dialog: DialogState? = null,
val areFoldersExpanded: Boolean = false,
val displayFolderCreationButton: Boolean = false,
val exception: Exception? = null
)
val exception: Exception? = null,
val config: AccountConfig? = null
) {
val displayThreeDotsMenu
get() = config?.canUpdateFolder == true && config.canDeleteFolder
}
sealed interface DialogState {
data class AddFeed(val url: String? = null) : DialogState
@ -20,7 +25,12 @@ sealed interface DialogState {
class DeleteFolder(val folder: Folder) : DialogState
class UpdateFeed(val feed: Feed, val folder: Folder?) : DialogState
class UpdateFolder(val folder: Folder) : DialogState
class FeedSheet(val feed: Feed, val folder: Folder?) : DialogState
data class FeedSheet(
val feed: Feed,
val folder: Folder?,
val config: AccountConfig
) : DialogState
}
sealed class FolderAndFeedsState {

View File

@ -127,7 +127,7 @@ object FeedTab : Tab {
},
floatingActionButton = {
Column {
if (state.displayFolderCreationButton) {
if (state.config?.canCreateFolder == true) {
SmallFloatingActionButton(
modifier = Modifier
.padding(
@ -144,13 +144,15 @@ object FeedTab : Tab {
}
}
FloatingActionButton(
onClick = { screenModel.openDialog(DialogState.AddFeed()) }
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = null
)
if (state.config?.canCreateFeed == true) {
FloatingActionButton(
onClick = { screenModel.openDialog(DialogState.AddFeed()) }
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = null
)
}
}
}
},
@ -186,7 +188,11 @@ object FeedTab : Tab {
isExpanded = state.areFoldersExpanded,
onFeedClick = { feed ->
screenModel.openDialog(
DialogState.FeedSheet(feed, folder)
DialogState.FeedSheet(
feed = feed,
folder = folder,
config = state.config!!
)
)
},
onFeedLongClick = { feed -> onFeedLongClick(feed) },
@ -199,7 +205,8 @@ object FeedTab : Tab {
screenModel.openDialog(
DialogState.DeleteFolder(folder)
)
}
},
displayThreeDotsMenu = state.displayThreeDotsMenu
)
} else {
val feeds = folderWithFeeds.second
@ -209,7 +216,11 @@ object FeedTab : Tab {
feed = feed,
onClick = {
screenModel.openDialog(
DialogState.FeedSheet(feed, null)
DialogState.FeedSheet(
feed = feed,
folder = null,
config = state.config!!
)
)
},
onLongClick = { onFeedLongClick(feed) },
@ -287,7 +298,9 @@ object FeedTab : Tab {
screenModel.openDialog(DialogState.UpdateFeed(dialog.feed, dialog.folder))
},
onUpdateColor = {},
onDelete = { screenModel.openDialog(DialogState.DeleteFeed(dialog.feed)) }
onDelete = { screenModel.openDialog(DialogState.DeleteFeed(dialog.feed)) },
canUpdateFeed = dialog.config.canUpdateFeed,
canDeleteFeed = dialog.config.canDeleteFeed
)
}

View File

@ -34,11 +34,13 @@ import com.readrops.db.entities.Folder
fun FolderExpandableItem(
folder: Folder,
feeds: List<Feed>,
isExpanded: Boolean = false,
onFeedClick: (Feed) -> Unit,
onFeedLongClick: (Feed) -> Unit,
onUpdateFolder: () -> Unit,
onDeleteFolder: () -> Unit
onDeleteFolder: () -> Unit,
displayThreeDotsMenu: Boolean,
modifier: Modifier = Modifier,
isExpanded: Boolean = false
) {
var isFolderExpanded by remember { mutableStateOf(false) }
@ -47,7 +49,7 @@ fun FolderExpandableItem(
}
Column(
modifier = Modifier
modifier = modifier
.animateContentSize(
animationSpec = tween(
durationMillis = 300,
@ -60,8 +62,8 @@ fun FolderExpandableItem(
.clickable { isFolderExpanded = isFolderExpanded.not() }
.padding(
start = MaterialTheme.spacing.mediumSpacing,
top = MaterialTheme.spacing.veryShortSpacing,
bottom = MaterialTheme.spacing.veryShortSpacing
top = if (displayThreeDotsMenu) MaterialTheme.spacing.veryShortSpacing else MaterialTheme.spacing.mediumSpacing,
bottom = if (displayThreeDotsMenu) MaterialTheme.spacing.veryShortSpacing else MaterialTheme.spacing.mediumSpacing
)
) {
Row(
@ -89,18 +91,20 @@ fun FolderExpandableItem(
)
}
ThreeDotsMenu(
items = mapOf(
1 to stringResource(id = R.string.update),
2 to stringResource(id = R.string.delete)
),
onItemClick = { index ->
when (index) {
1 -> onUpdateFolder()
else -> onDeleteFolder()
if (displayThreeDotsMenu) {
ThreeDotsMenu(
items = mapOf(
1 to stringResource(id = R.string.update),
2 to stringResource(id = R.string.delete)
),
onItemClick = { index ->
when (index) {
1 -> onUpdateFolder()
else -> onDeleteFolder()
}
}
}
)
)
}
}
}

View File

@ -42,6 +42,8 @@ fun FeedModalBottomSheet(
onUpdate: () -> Unit,
onUpdateColor: () -> Unit,
onDelete: () -> Unit,
canUpdateFeed: Boolean,
canDeleteFeed: Boolean
) {
ModalBottomSheet(
onDismissRequest = { onDismissRequest() }
@ -100,11 +102,13 @@ fun FeedModalBottomSheet(
onClick = onOpen
)
BottomSheetOption(
text = stringResource(id = R.string.update),
icon = Icons.Default.Create,
onClick = onUpdate
)
if (canUpdateFeed) {
BottomSheetOption(
text = stringResource(id = R.string.update),
icon = Icons.Default.Create,
onClick = onUpdate
)
}
BottomSheetOption(
text = stringResource(R.string.update_color),
@ -112,11 +116,13 @@ fun FeedModalBottomSheet(
onClick = onUpdateColor
)
BottomSheetOption(
text = stringResource(R.string.delete),
icon = Icons.Default.Delete,
onClick = onDelete
)
if (canDeleteFeed) {
BottomSheetOption(
text = stringResource(R.string.delete),
icon = Icons.Default.Delete,
onClick = onDelete
)
}
}
LargeSpacer()

View File

@ -72,20 +72,23 @@ class FeverRepository(
onUpdate: (Feed) -> Unit
): ErrorResult = throw CloneNotSupportedException()
// Not supported by Fever API
override suspend fun updateFeed(feed: Feed) {}
override suspend fun updateFeed(feed: Feed) =
throw NotImplementedError("Update feed action not supported by Fever API")
override suspend fun deleteFeed(feed: Feed) =
throw NotImplementedError("Delete feed action not supported by Fever API")
// Not supported by Fever API
override suspend fun deleteFeed(feed: Feed) {}
override suspend fun addFolder(folder: Folder) =
throw NotImplementedError("Add folder action not supported by Fever API")
// Not supported by Fever API
override suspend fun addFolder(folder: Folder) {}
override suspend fun updateFolder(folder: Folder) =
throw NotImplementedError("Update folder action not supported by Fever API")
// Not supported by Fever API
override suspend fun updateFolder(folder: Folder) {}
// Not supported by Fever API
override suspend fun deleteFolder(folder: Folder) {}
override suspend fun deleteFolder(folder: Folder) =
throw NotImplementedError("Delete folder action not supported by Fever API")
override suspend fun setItemReadState(item: Item) {
val action = if (item.isRead) {

View File

@ -2,9 +2,14 @@ package com.readrops.db.entities.account
data class AccountConfig(
val isFeedUrlReadOnly: Boolean, // Enable or disable feed url modification in Feed Tab
val canCreateFolder: Boolean, // Enable or disable folder creation in Feed Tab
val addNoFolder: Boolean, // Add a "No folder" option when modifying a feed's folder
val useSeparateState: Boolean, // Let know if it uses ItemState table to synchronize read/star state
val canCreateFolder: Boolean, // Enable or disable folder creation in Feed Tab
val canCreateFeed: Boolean = true,
val canUpdateFolder: Boolean = true,
val canUpdateFeed: Boolean = true,
val canDeleteFeed: Boolean = true,
val canDeleteFolder: Boolean = true
) {
companion object {
@ -13,6 +18,7 @@ data class AccountConfig(
canCreateFolder = true,
addNoFolder = true,
useSeparateState = false,
)
val NEXTCLOUD_NEWS = AccountConfig(
@ -31,9 +37,14 @@ data class AccountConfig(
val FEVER = AccountConfig(
isFeedUrlReadOnly = false,
canCreateFolder = false,
addNoFolder = true,
useSeparateState = true,
canCreateFolder = false,
canCreateFeed = false,
canUpdateFolder = false,
canUpdateFeed = false,
canDeleteFeed = false,
canDeleteFolder = false
)
}
}