Add some filters in TimelineTab
This commit is contained in:
parent
adb56cdacf
commit
1cdb98eedb
@ -0,0 +1,93 @@
|
|||||||
|
package com.readrops.app.compose.timelime
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.readrops.app.compose.R
|
||||||
|
import com.readrops.app.compose.util.theme.LargeSpacer
|
||||||
|
import com.readrops.app.compose.util.theme.ShortSpacer
|
||||||
|
import com.readrops.app.compose.util.theme.spacing
|
||||||
|
import com.readrops.db.filters.ListSortType
|
||||||
|
import com.readrops.db.queries.QueryFilters
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun FilterBottomSheet(
|
||||||
|
viewModel: TimelineViewModel,
|
||||||
|
filters: QueryFilters,
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
) {
|
||||||
|
ModalBottomSheet(
|
||||||
|
onDismissRequest = onDismiss
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(MaterialTheme.spacing.mediumSpacing)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.filters)
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { viewModel.setShowReadItemsState(!filters.showReadItems) }
|
||||||
|
) {
|
||||||
|
Checkbox(
|
||||||
|
checked = filters.showReadItems,
|
||||||
|
onCheckedChange = { viewModel.setShowReadItemsState(!filters.showReadItems) }
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.show_read_articles)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
fun setSortTypeState() {
|
||||||
|
viewModel.setSortTypeState(
|
||||||
|
if (filters.sortType == ListSortType.NEWEST_TO_OLDEST)
|
||||||
|
ListSortType.OLDEST_TO_NEWEST
|
||||||
|
else
|
||||||
|
ListSortType.NEWEST_TO_OLDEST
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { setSortTypeState() }
|
||||||
|
) {
|
||||||
|
Checkbox(
|
||||||
|
checked = filters.sortType == ListSortType.OLDEST_TO_NEWEST,
|
||||||
|
onCheckedChange = { setSortTypeState() }
|
||||||
|
)
|
||||||
|
|
||||||
|
ShortSpacer()
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Show oldest items first"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LargeSpacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -97,21 +97,35 @@ object TimelineTab : Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.confirmDialog) {
|
when (state.dialog) {
|
||||||
|
DialogState.ConfirmDialog -> {
|
||||||
TwoChoicesDialog(
|
TwoChoicesDialog(
|
||||||
title = "Mark all items as read",
|
title = "Mark all items as read",
|
||||||
text = "Do you really want to mark all items as read?",
|
text = "Do you really want to mark all items as read?",
|
||||||
icon = painterResource(id = R.drawable.ic_rss_feed_grey),
|
icon = painterResource(id = R.drawable.ic_rss_feed_grey),
|
||||||
confirmText = "Validate",
|
confirmText = "Validate",
|
||||||
dismissText = "Cancel",
|
dismissText = "Cancel",
|
||||||
onDismiss = { viewModel.closeConfirmDialog() },
|
onDismiss = { viewModel.closeDialog() },
|
||||||
onConfirm = {
|
onConfirm = {
|
||||||
viewModel.closeConfirmDialog()
|
viewModel.closeDialog()
|
||||||
viewModel.setAllItemsRead()
|
viewModel.setAllItemsRead()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DialogState.FilterSheet -> {
|
||||||
|
FilterBottomSheet(
|
||||||
|
viewModel = viewModel,
|
||||||
|
filters = state.filters,
|
||||||
|
onDismiss = {
|
||||||
|
viewModel.closeDialog()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerState = drawerState,
|
drawerState = drawerState,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
@ -155,7 +169,9 @@ object TimelineTab : Tab {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = { }) {
|
IconButton(
|
||||||
|
onClick = { viewModel.openDialog(DialogState.FilterSheet) }
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.ic_filter_list),
|
painter = painterResource(id = R.drawable.ic_filter_list),
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
@ -177,7 +193,7 @@ object TimelineTab : Tab {
|
|||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (state.filters.filterType == FilterType.NO_FILTER) {
|
if (state.filters.filterType == FilterType.NO_FILTER) {
|
||||||
viewModel.openConfirmDialog()
|
viewModel.openDialog(DialogState.ConfirmDialog)
|
||||||
} else {
|
} else {
|
||||||
viewModel.setAllItemsRead()
|
viewModel.setAllItemsRead()
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import com.readrops.db.entities.Feed
|
|||||||
import com.readrops.db.entities.Folder
|
import com.readrops.db.entities.Folder
|
||||||
import com.readrops.db.entities.Item
|
import com.readrops.db.entities.Item
|
||||||
import com.readrops.db.filters.FilterType
|
import com.readrops.db.filters.FilterType
|
||||||
|
import com.readrops.db.filters.ListSortType
|
||||||
import com.readrops.db.pojo.ItemWithFeed
|
import com.readrops.db.pojo.ItemWithFeed
|
||||||
import com.readrops.db.queries.ItemsQueryBuilder
|
import com.readrops.db.queries.ItemsQueryBuilder
|
||||||
import com.readrops.db.queries.QueryFilters
|
import com.readrops.db.queries.QueryFilters
|
||||||
@ -197,6 +198,7 @@ class TimelineViewModel(
|
|||||||
_timelineState.value.filters.filterFolderId,
|
_timelineState.value.filters.filterFolderId,
|
||||||
currentAccount!!.id
|
currentAccount!!.id
|
||||||
)
|
)
|
||||||
|
|
||||||
FilterType.READ_IT_LATER_FILTER -> TODO()
|
FilterType.READ_IT_LATER_FILTER -> TODO()
|
||||||
FilterType.STARS_FILTER -> repository?.setAllStarredItemsRead(currentAccount!!.id)
|
FilterType.STARS_FILTER -> repository?.setAllStarredItemsRead(currentAccount!!.id)
|
||||||
FilterType.NO_FILTER -> repository?.setAllItemsRead(currentAccount!!.id)
|
FilterType.NO_FILTER -> repository?.setAllItemsRead(currentAccount!!.id)
|
||||||
@ -205,17 +207,33 @@ class TimelineViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openConfirmDialog() {
|
fun openDialog(dialog: DialogState) = _timelineState.update { it.copy(dialog = dialog) }
|
||||||
_timelineState.value = _timelineState.value.copy(
|
|
||||||
confirmDialog = true
|
fun closeDialog() = _timelineState.update { it.copy(dialog = null) }
|
||||||
|
|
||||||
|
fun setShowReadItemsState(showReadItems: Boolean) {
|
||||||
|
_timelineState.update {
|
||||||
|
it.copy(
|
||||||
|
filters = updateFilters {
|
||||||
|
it.filters.copy(
|
||||||
|
showReadItems = showReadItems
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeConfirmDialog() {
|
|
||||||
_timelineState.value = _timelineState.value.copy(
|
|
||||||
confirmDialog = false
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSortTypeState(sortType: ListSortType) {
|
||||||
|
_timelineState.update {
|
||||||
|
it.copy(
|
||||||
|
filters = updateFilters {
|
||||||
|
it.filters.copy(
|
||||||
|
sortType = sortType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@ -228,5 +246,10 @@ data class TimelineState(
|
|||||||
val filterFolderName: String = "",
|
val filterFolderName: String = "",
|
||||||
val foldersAndFeeds: Map<Folder?, List<Feed>> = emptyMap(),
|
val foldersAndFeeds: Map<Folder?, List<Feed>> = emptyMap(),
|
||||||
val itemState: Flow<PagingData<ItemWithFeed>> = emptyFlow(),
|
val itemState: Flow<PagingData<ItemWithFeed>> = emptyFlow(),
|
||||||
val confirmDialog: Boolean = false
|
val dialog: DialogState? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
sealed interface DialogState {
|
||||||
|
object ConfirmDialog : DialogState
|
||||||
|
object FilterSheet : DialogState
|
||||||
|
}
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
<string name="filter_oldest">Du plus ancien au plus récent</string>
|
<string name="filter_oldest">Du plus ancien au plus récent</string>
|
||||||
<string name="login_failed">La connexion a échoué. Veuillez vérifier vos identifiants</string>
|
<string name="login_failed">La connexion a échoué. Veuillez vérifier vos identifiants</string>
|
||||||
<string name="new_account">Nouveau compte</string>
|
<string name="new_account">Nouveau compte</string>
|
||||||
|
<string name="new_articles">Nouveaux articles</string>
|
||||||
<string name="app_licence">Appli distribuée sous la licence GPLv3</string>
|
<string name="app_licence">Appli distribuée sous la licence GPLv3</string>
|
||||||
<string name="number_items_to_parse">Nombre maximum d\'articles par flux</string>
|
<string name="number_items_to_parse">Nombre maximum d\'articles par flux</string>
|
||||||
<string name="unlimited">Illimité</string>
|
<string name="unlimited">Illimité</string>
|
||||||
@ -140,5 +141,6 @@
|
|||||||
<string name="system">Thème du système</string>
|
<string name="system">Thème du système</string>
|
||||||
<string name="hide_feeds">Cacher les flux sans nouveaux items</string>
|
<string name="hide_feeds">Cacher les flux sans nouveaux items</string>
|
||||||
<string name="mark_items_read">Marquer les items comme lus pendant le défilement</string>
|
<string name="mark_items_read">Marquer les items comme lus pendant le défilement</string>
|
||||||
|
<string name="filters">Filtres</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -147,4 +147,5 @@
|
|||||||
<string name="hide_feeds">Hide feeds without new items</string>
|
<string name="hide_feeds">Hide feeds without new items</string>
|
||||||
<string name="mark_items_read">Mark items read on scroll</string>
|
<string name="mark_items_read">Mark items read on scroll</string>
|
||||||
<string name="new_articles">New articles</string>
|
<string name="new_articles">New articles</string>
|
||||||
|
<string name="filters">Filters</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user