mirror of
https://github.com/readrops/Readrops.git
synced 2025-02-02 19:56:50 +01:00
Combine a feed/folder filter with a main filter (all, new, stars)
This commit is contained in:
parent
e31ebe487f
commit
6664903532
@ -62,7 +62,7 @@ import com.readrops.db.entities.Feed;
|
||||
import com.readrops.db.entities.Folder;
|
||||
import com.readrops.db.entities.Item;
|
||||
import com.readrops.db.entities.account.Account;
|
||||
import com.readrops.db.filters.FilterType;
|
||||
import com.readrops.db.filters.MainFilter;
|
||||
import com.readrops.db.filters.ListSortType;
|
||||
import com.readrops.db.pojo.ItemWithFeed;
|
||||
|
||||
@ -273,7 +273,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
|
||||
switch (id) {
|
||||
default:
|
||||
case DrawerManager.ARTICLES_ITEM_ID:
|
||||
viewModel.setFilterType(FilterType.NO_FILTER);
|
||||
viewModel.setFilterType(MainFilter.ALL);
|
||||
scrollToTop = true;
|
||||
viewModel.invalidate();
|
||||
setTitle(R.string.articles);
|
||||
@ -284,7 +284,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
|
||||
setTitle(R.string.read_later);
|
||||
break;
|
||||
case DrawerManager.STARS_ID:
|
||||
viewModel.setFilterType(FilterType.STARS_FILTER);
|
||||
viewModel.setFilterType(MainFilter.STARS);
|
||||
viewModel.invalidate();
|
||||
setTitle(R.string.favorites);
|
||||
break;
|
||||
@ -302,14 +302,14 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
|
||||
drawer.closeDrawer();
|
||||
|
||||
viewModel.setFilterFeedId((int) drawerItem.getIdentifier());
|
||||
viewModel.setFilterType(FilterType.FEED_FILTER);
|
||||
viewModel.setFilterType(MainFilter.ALL);
|
||||
viewModel.invalidate();
|
||||
setTitle(((SecondaryDrawerItem) drawerItem).getName().getText());
|
||||
} else if (drawerItem instanceof CustomExpandableBadgeDrawerItem) {
|
||||
drawer.closeDrawer();
|
||||
|
||||
viewModel.setFilerFolderId((int) (drawerItem.getIdentifier() / 1000));
|
||||
viewModel.setFilterType(FilterType.FOLDER_FILER);
|
||||
viewModel.setFilterType(MainFilter.ALL);
|
||||
viewModel.invalidate();
|
||||
setTitle(((CustomExpandableBadgeDrawerItem) drawerItem).getName().getText());
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import com.readrops.db.entities.Feed;
|
||||
import com.readrops.db.entities.Folder;
|
||||
import com.readrops.db.entities.Item;
|
||||
import com.readrops.db.entities.account.Account;
|
||||
import com.readrops.db.filters.FilterType;
|
||||
import com.readrops.db.filters.MainFilter;
|
||||
import com.readrops.db.filters.ListSortType;
|
||||
import com.readrops.db.pojo.ItemWithFeed;
|
||||
import com.readrops.db.queries.ItemsQueryBuilder;
|
||||
@ -54,8 +54,8 @@ public class MainViewModel extends ViewModel {
|
||||
itemsWithFeed = new MediatorLiveData<>();
|
||||
|
||||
queryFilters = new QueryFilters();
|
||||
queryFilters.setShowReadItems(SharedPreferencesManager.readBoolean(
|
||||
SharedPreferencesManager.SharedPrefKey.SHOW_READ_ARTICLES));
|
||||
/* queryFilters.setShowReadItems(SharedPreferencesManager.readBoolean(
|
||||
SharedPreferencesManager.SharedPrefKey.SHOW_READ_ARTICLES));*/
|
||||
}
|
||||
|
||||
//region main query
|
||||
@ -71,7 +71,7 @@ public class MainViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
DataSource.Factory<Integer, ItemWithFeed> items;
|
||||
items = database.itemDao().selectAll(ItemsQueryBuilder.buildItemsQuery(queryFilters, currentAccount.getConfig().getUseSeparateState()));
|
||||
items = database.itemDao().selectAll(ItemsQueryBuilder.INSTANCE.buildItemsQuery(queryFilters, currentAccount.getConfig().getUseSeparateState()));
|
||||
|
||||
lastFetch = new LivePagedListBuilder<>(new RoomFactoryWrapper<>(items),
|
||||
new PagedList.Config.Builder()
|
||||
@ -89,23 +89,23 @@ public class MainViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
public void setShowReadItems(boolean showReadItems) {
|
||||
queryFilters.setShowReadItems(showReadItems);
|
||||
//queryFilters.setShowReadItems(showReadItems);
|
||||
}
|
||||
|
||||
public boolean showReadItems() {
|
||||
return queryFilters.getShowReadItems();
|
||||
}
|
||||
|
||||
public void setFilterType(FilterType filterType) {
|
||||
queryFilters.setFilterType(filterType);
|
||||
public void setFilterType(MainFilter filterType) {
|
||||
//queryFilters.setMainFilter(filterType);
|
||||
}
|
||||
|
||||
public FilterType getFilterType() {
|
||||
return queryFilters.getFilterType();
|
||||
public MainFilter getFilterType() {
|
||||
return queryFilters.getMainFilter();
|
||||
}
|
||||
|
||||
public void setSortType(ListSortType sortType) {
|
||||
queryFilters.setSortType(sortType);
|
||||
//queryFilters.setSortType(sortType);
|
||||
}
|
||||
|
||||
public ListSortType getSortType() {
|
||||
@ -113,11 +113,11 @@ public class MainViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
public void setFilterFeedId(int filterFeedId) {
|
||||
queryFilters.setFilterFeedId(filterFeedId);
|
||||
//queryFilters.setFilterFeedId(filterFeedId);
|
||||
}
|
||||
|
||||
public void setFilerFolderId(int folderId) {
|
||||
queryFilters.setFilterFolderId(folderId);
|
||||
//queryFilters.setFilterFolderId(folderId);
|
||||
}
|
||||
|
||||
public MediatorLiveData<PagedList<ItemWithFeed>> getItemsWithFeed() {
|
||||
@ -128,7 +128,7 @@ public class MainViewModel extends ViewModel {
|
||||
itemsWithFeed.removeSource(lastFetch);
|
||||
|
||||
// get current viewed feed
|
||||
if (feeds == null && queryFilters.getFilterType() == FilterType.FEED_FILTER) {
|
||||
if (feeds == null && queryFilters.getMainFilter() == MainFilter.ALL) {
|
||||
return Single.<Feed>create(emitter -> emitter.onSuccess(database.feedDao()
|
||||
.getFeedById(queryFilters.getFilterFeedId())))
|
||||
.flatMapCompletable(feed -> repository.sync(Collections.singletonList(feed), update));
|
||||
@ -181,7 +181,7 @@ public class MainViewModel extends ViewModel {
|
||||
public void setCurrentAccount(Account currentAccount) {
|
||||
this.currentAccount = currentAccount;
|
||||
setRepository();
|
||||
queryFilters.setAccountId(currentAccount.getId());
|
||||
//queryFilters.setAccountId(currentAccount.getId());
|
||||
buildPagedList();
|
||||
|
||||
// set the new account as the current one
|
||||
@ -212,7 +212,7 @@ public class MainViewModel extends ViewModel {
|
||||
currentAccountExists = true;
|
||||
|
||||
setRepository();
|
||||
queryFilters.setAccountId(currentAccount.getId());
|
||||
//queryFilters.setAccountId(currentAccount.getId());
|
||||
buildPagedList();
|
||||
break;
|
||||
}
|
||||
@ -252,7 +252,7 @@ public class MainViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
public Completable setAllItemsReadState(boolean read) {
|
||||
if (queryFilters.getFilterType() == FilterType.FEED_FILTER)
|
||||
if (queryFilters.getMainFilter() == MainFilter.ALL)
|
||||
return repository.setAllFeedItemsReadState(queryFilters.getFilterFeedId(), read);
|
||||
else
|
||||
return repository.setAllItemsReadState(read);
|
||||
|
@ -10,7 +10,7 @@ import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.entities.account.Account
|
||||
import com.readrops.db.entities.account.AccountType
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.joda.time.LocalDateTime
|
||||
@ -73,7 +73,7 @@ class GetFoldersWithFeedsTest {
|
||||
@Test
|
||||
fun getFoldersWithFeedsTest() = runTest {
|
||||
getFoldersWithFeeds = GetFoldersWithFeeds(database)
|
||||
val foldersAndFeeds = getFoldersWithFeeds.get(account.id, FilterType.NO_FILTER).first()
|
||||
val foldersAndFeeds = getFoldersWithFeeds.get(account.id, MainFilter.ALL).first()
|
||||
|
||||
assertTrue { foldersAndFeeds.size == 4 }
|
||||
assertTrue { foldersAndFeeds.entries.first().value.size == 2 }
|
||||
|
@ -11,7 +11,7 @@ import com.readrops.db.Database
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.entities.account.Account
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -47,7 +47,7 @@ class FeedScreenModel(
|
||||
screenModelScope.launch(context = Dispatchers.IO) {
|
||||
accountEvent
|
||||
.flatMapConcat { account ->
|
||||
getFoldersWithFeeds.get(account.id, FilterType.NO_FILTER)
|
||||
getFoldersWithFeeds.get(account.id, MainFilter.ALL)
|
||||
}
|
||||
.catch { throwable ->
|
||||
_feedState.update {
|
||||
|
@ -3,7 +3,7 @@ package com.readrops.app.compose.repositories
|
||||
import com.readrops.db.Database
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import com.readrops.db.queries.FoldersAndFeedsQueriesBuilder
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@ -12,11 +12,11 @@ class GetFoldersWithFeeds(
|
||||
private val database: Database,
|
||||
) {
|
||||
|
||||
fun get(accountId: Int, filterType: FilterType): Flow<Map<Folder?, List<Feed>>> {
|
||||
fun get(accountId: Int, mainFilter: MainFilter): Flow<Map<Folder?, List<Feed>>> {
|
||||
val foldersAndFeedsQuery =
|
||||
FoldersAndFeedsQueriesBuilder.buildFoldersAndFeedsQuery(accountId, filterType)
|
||||
FoldersAndFeedsQueriesBuilder.buildFoldersAndFeedsQuery(accountId, mainFilter)
|
||||
val feedsWithoutFolderQuery =
|
||||
FoldersAndFeedsQueriesBuilder.buildFeedsWithoutFolderQuery(accountId, filterType)
|
||||
FoldersAndFeedsQueriesBuilder.buildFeedsWithoutFolderQuery(accountId, mainFilter)
|
||||
|
||||
return combine(
|
||||
flow = database.newFolderDao()
|
||||
|
@ -14,8 +14,9 @@ import com.readrops.db.Database
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.ListSortType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import com.readrops.db.filters.SubFilter
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import com.readrops.db.queries.ItemsQueryBuilder
|
||||
import com.readrops.db.queries.QueryFilters
|
||||
@ -47,8 +48,7 @@ class TimelineScreenModel(
|
||||
accountEvent,
|
||||
filters
|
||||
) { account, filters ->
|
||||
filters.accountId = account.id
|
||||
Pair(account, filters)
|
||||
Pair(account, filters.copy(accountId = account.id))
|
||||
}.collectLatest { (account, filters) ->
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(filters)
|
||||
|
||||
@ -67,7 +67,7 @@ class TimelineScreenModel(
|
||||
)
|
||||
}
|
||||
|
||||
getFoldersWithFeeds.get(account.id, filters.filterType)
|
||||
getFoldersWithFeeds.get(account.id, filters.mainFilter)
|
||||
.collect { foldersAndFeeds ->
|
||||
_timelineState.update {
|
||||
it.copy(
|
||||
@ -103,12 +103,15 @@ class TimelineScreenModel(
|
||||
_timelineState.update { it.copy(isDrawerOpen = false) }
|
||||
}
|
||||
|
||||
fun updateDrawerDefaultItem(selection: FilterType) {
|
||||
fun updateDrawerDefaultItem(selection: MainFilter) {
|
||||
_timelineState.update {
|
||||
it.copy(
|
||||
filters = updateFilters {
|
||||
it.filters.copy(
|
||||
filterType = selection
|
||||
mainFilter = selection,
|
||||
subFilter = SubFilter.ALL,
|
||||
filterFeedId = 0,
|
||||
filterFolderId = 0
|
||||
)
|
||||
},
|
||||
isDrawerOpen = false
|
||||
@ -121,7 +124,7 @@ class TimelineScreenModel(
|
||||
it.copy(
|
||||
filters = updateFilters {
|
||||
it.filters.copy(
|
||||
filterType = FilterType.FOLDER_FILER,
|
||||
subFilter = SubFilter.FOLDER,
|
||||
filterFolderId = folder.id,
|
||||
filterFeedId = 0
|
||||
)
|
||||
@ -137,7 +140,7 @@ class TimelineScreenModel(
|
||||
it.copy(
|
||||
filters = updateFilters {
|
||||
it.filters.copy(
|
||||
filterType = FilterType.FEED_FILTER,
|
||||
subFilter = SubFilter.FEED,
|
||||
filterFeedId = feed.id,
|
||||
filterFolderId = 0
|
||||
)
|
||||
@ -187,21 +190,25 @@ class TimelineScreenModel(
|
||||
|
||||
fun setAllItemsRead() {
|
||||
screenModelScope.launch(dispatcher) {
|
||||
when (_timelineState.value.filters.filterType) {
|
||||
FilterType.FEED_FILTER ->
|
||||
when (_timelineState.value.filters.subFilter) {
|
||||
SubFilter.FEED ->
|
||||
repository?.setAllItemsReadByFeed(
|
||||
_timelineState.value.filters.filterFeedId,
|
||||
currentAccount!!.id
|
||||
)
|
||||
|
||||
FilterType.FOLDER_FILER -> repository?.setAllItemsReadByFolder(
|
||||
SubFilter.FOLDER -> repository?.setAllItemsReadByFolder(
|
||||
_timelineState.value.filters.filterFolderId,
|
||||
currentAccount!!.id
|
||||
)
|
||||
|
||||
FilterType.STARS_FILTER -> repository?.setAllStarredItemsRead(currentAccount!!.id)
|
||||
FilterType.NO_FILTER -> repository?.setAllItemsRead(currentAccount!!.id)
|
||||
FilterType.NEW -> TODO()
|
||||
else -> when (_timelineState.value.filters.mainFilter) {
|
||||
MainFilter.STARS -> repository?.setAllStarredItemsRead(currentAccount!!.id)
|
||||
MainFilter.ALL -> repository?.setAllItemsRead(currentAccount!!.id)
|
||||
MainFilter.NEW -> TODO()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,8 @@ import com.readrops.app.compose.timelime.drawer.TimelineDrawer
|
||||
import com.readrops.app.compose.util.components.CenteredColumn
|
||||
import com.readrops.app.compose.util.components.TwoChoicesDialog
|
||||
import com.readrops.app.compose.util.theme.spacing
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import com.readrops.db.filters.SubFilter
|
||||
|
||||
|
||||
object TimelineTab : Tab {
|
||||
@ -168,12 +169,14 @@ object TimelineTab : Tab {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = when (state.filters.filterType) {
|
||||
FilterType.FEED_FILTER -> state.filterFeedName
|
||||
FilterType.FOLDER_FILER -> state.filterFolderName
|
||||
FilterType.STARS_FILTER -> stringResource(R.string.favorites)
|
||||
FilterType.NO_FILTER -> stringResource(R.string.articles)
|
||||
FilterType.NEW -> stringResource(R.string.new_articles)
|
||||
text = when (state.filters.subFilter) {
|
||||
SubFilter.FEED -> state.filterFeedName
|
||||
SubFilter.FOLDER -> state.filterFolderName
|
||||
else -> when (state.filters.mainFilter) {
|
||||
MainFilter.STARS -> stringResource(R.string.favorites)
|
||||
MainFilter.ALL -> stringResource(R.string.articles)
|
||||
MainFilter.NEW -> stringResource(R.string.new_articles)
|
||||
}
|
||||
},
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
@ -213,7 +216,7 @@ object TimelineTab : Tab {
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
onClick = {
|
||||
if (state.filters.filterType == FilterType.NO_FILTER) {
|
||||
if (state.filters.mainFilter == MainFilter.ALL) {
|
||||
viewModel.openDialog(DialogState.ConfirmDialog)
|
||||
} else {
|
||||
viewModel.setAllItemsRead()
|
||||
|
@ -51,7 +51,7 @@ fun DrawerFolderItem(
|
||||
) {
|
||||
val colors = NavigationDrawerItemDefaults.colors()
|
||||
|
||||
var isExpanded by remember { mutableStateOf(false) }
|
||||
var isExpanded by remember { mutableStateOf(feeds.any { it.id == selectedFeed }) }
|
||||
val rotationState by animateFloatAsState(
|
||||
targetValue = if (isExpanded) 180f else 0f,
|
||||
label = "drawer item arrow rotation"
|
||||
|
@ -28,12 +28,12 @@ import com.readrops.app.compose.timelime.TimelineState
|
||||
import com.readrops.app.compose.util.theme.spacing
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
|
||||
@Composable
|
||||
fun TimelineDrawer(
|
||||
state: TimelineState,
|
||||
onClickDefaultItem: (FilterType) -> Unit,
|
||||
onClickDefaultItem: (MainFilter) -> Unit,
|
||||
onFolderClick: (Folder) -> Unit,
|
||||
onFeedClick: (Feed) -> Unit,
|
||||
) {
|
||||
@ -47,7 +47,7 @@ fun TimelineDrawer(
|
||||
Spacer(modifier = Modifier.size(MaterialTheme.spacing.drawerSpacing))
|
||||
|
||||
DrawerDefaultItems(
|
||||
selectedItem = state.filters.filterType,
|
||||
selectedItem = state.filters.mainFilter,
|
||||
onClick = { onClickDefaultItem(it) }
|
||||
)
|
||||
|
||||
@ -116,8 +116,8 @@ fun TimelineDrawer(
|
||||
|
||||
@Composable
|
||||
fun DrawerDefaultItems(
|
||||
selectedItem: FilterType,
|
||||
onClick: (FilterType) -> Unit,
|
||||
selectedItem: MainFilter,
|
||||
onClick: (MainFilter) -> Unit,
|
||||
) {
|
||||
NavigationDrawerItem(
|
||||
label = { Text(text = stringResource(R.string.articles)) },
|
||||
@ -127,8 +127,8 @@ fun DrawerDefaultItems(
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
selected = selectedItem == FilterType.NO_FILTER,
|
||||
onClick = { onClick(FilterType.NO_FILTER) },
|
||||
selected = selectedItem == MainFilter.ALL,
|
||||
onClick = { onClick(MainFilter.ALL) },
|
||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||
)
|
||||
|
||||
@ -140,8 +140,8 @@ fun DrawerDefaultItems(
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
selected = selectedItem == FilterType.NEW,
|
||||
onClick = { onClick(FilterType.NEW) },
|
||||
selected = selectedItem == MainFilter.NEW,
|
||||
onClick = { onClick(MainFilter.NEW) },
|
||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||
)
|
||||
|
||||
@ -153,8 +153,8 @@ fun DrawerDefaultItems(
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
selected = selectedItem == FilterType.STARS_FILTER,
|
||||
onClick = { onClick(FilterType.STARS_FILTER) },
|
||||
selected = selectedItem == MainFilter.STARS,
|
||||
onClick = { onClick(MainFilter.STARS) },
|
||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||
)
|
||||
}
|
||||
|
@ -4,8 +4,9 @@ import android.content.Context
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.ListSortType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import com.readrops.db.filters.SubFilter
|
||||
import com.readrops.db.queries.ItemsQueryBuilder
|
||||
import com.readrops.db.queries.QueryFilters
|
||||
import junit.framework.TestCase.assertFalse
|
||||
@ -51,7 +52,7 @@ class ItemsQueryBuilderTest {
|
||||
|
||||
@Test
|
||||
fun feedFilterCaseTest() {
|
||||
val queryFilters = QueryFilters(accountId = 1, filterType = FilterType.FEED_FILTER,
|
||||
val queryFilters = QueryFilters(accountId = 1, subFilter = SubFilter.FEED,
|
||||
filterFeedId = 15)
|
||||
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(queryFilters)
|
||||
@ -62,7 +63,7 @@ class ItemsQueryBuilderTest {
|
||||
|
||||
@Test
|
||||
fun starsFilterCaseTest() {
|
||||
val queryFilters = QueryFilters(accountId = 1, filterType = FilterType.STARS_FILTER)
|
||||
val queryFilters = QueryFilters(accountId = 1, mainFilter = MainFilter.STARS)
|
||||
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(queryFilters)
|
||||
database.query(query)
|
||||
@ -72,7 +73,7 @@ class ItemsQueryBuilderTest {
|
||||
|
||||
@Test
|
||||
fun folderFilterCaseTest() {
|
||||
val queryFilters = QueryFilters(accountId = 1, filterType = FilterType.FOLDER_FILER, filterFolderId = 1)
|
||||
val queryFilters = QueryFilters(accountId = 1, subFilter = SubFilter.FOLDER, filterFolderId = 1)
|
||||
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(queryFilters)
|
||||
database.query(query)
|
||||
@ -97,7 +98,7 @@ class ItemsQueryBuilderTest {
|
||||
|
||||
@Test
|
||||
fun separateStateTest() {
|
||||
val queryFilters = QueryFilters(accountId = 1, showReadItems = false, filterType = FilterType.STARS_FILTER)
|
||||
val queryFilters = QueryFilters(accountId = 1, showReadItems = false, mainFilter = MainFilter.STARS)
|
||||
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(queryFilters, true)
|
||||
database.query(query)
|
||||
@ -117,7 +118,7 @@ class ItemsQueryBuilderTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun filterFeedIdExceptionTest() {
|
||||
val queryFilters = QueryFilters(accountId = 1, filterType = FilterType.FEED_FILTER)
|
||||
val queryFilters = QueryFilters(accountId = 1, subFilter = SubFilter.FEED)
|
||||
ItemsQueryBuilder.buildItemsQuery(queryFilters)
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.readrops.db.filters;
|
||||
|
||||
enum class FilterType {
|
||||
FEED_FILTER,
|
||||
FOLDER_FILER,
|
||||
STARS_FILTER,
|
||||
NO_FILTER,
|
||||
NEW
|
||||
}
|
13
db/src/main/java/com/readrops/db/filters/Filters.kt
Normal file
13
db/src/main/java/com/readrops/db/filters/Filters.kt
Normal file
@ -0,0 +1,13 @@
|
||||
package com.readrops.db.filters
|
||||
|
||||
enum class MainFilter {
|
||||
STARS,
|
||||
NEW,
|
||||
ALL
|
||||
}
|
||||
|
||||
enum class SubFilter {
|
||||
FEED,
|
||||
FOLDER,
|
||||
ALL
|
||||
}
|
@ -2,15 +2,15 @@ package com.readrops.db.queries
|
||||
|
||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import org.intellij.lang.annotations.Language
|
||||
|
||||
object FoldersAndFeedsQueriesBuilder {
|
||||
|
||||
fun buildFoldersAndFeedsQuery(accountId: Int, filterType: FilterType): SupportSQLiteQuery {
|
||||
val filter = when (filterType) {
|
||||
FilterType.STARS_FILTER -> "And Item.starred = 1"
|
||||
FilterType.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
|
||||
fun buildFoldersAndFeedsQuery(accountId: Int, mainFilter: MainFilter): SupportSQLiteQuery {
|
||||
val filter = when (mainFilter) {
|
||||
MainFilter.STARS -> "And Item.starred = 1"
|
||||
MainFilter.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
|
||||
else -> ""
|
||||
}
|
||||
|
||||
@ -29,10 +29,10 @@ object FoldersAndFeedsQueriesBuilder {
|
||||
return query
|
||||
}
|
||||
|
||||
fun buildFeedsWithoutFolderQuery(accountId: Int, filterType: FilterType): SupportSQLiteQuery {
|
||||
val filter = when (filterType) {
|
||||
FilterType.STARS_FILTER -> "And Item.starred = 1 "
|
||||
FilterType.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
|
||||
fun buildFeedsWithoutFolderQuery(accountId: Int, mainFilter: MainFilter): SupportSQLiteQuery {
|
||||
val filter = when (mainFilter) {
|
||||
MainFilter.STARS -> "And Item.starred = 1 "
|
||||
MainFilter.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") "
|
||||
else -> ""
|
||||
}
|
||||
|
||||
|
@ -2,90 +2,121 @@ package com.readrops.db.queries
|
||||
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQueryBuilder
|
||||
import com.readrops.db.filters.FilterType
|
||||
import com.readrops.db.filters.ListSortType
|
||||
import com.readrops.db.filters.MainFilter
|
||||
import com.readrops.db.filters.SubFilter
|
||||
|
||||
object ItemsQueryBuilder {
|
||||
|
||||
private val COLUMNS = arrayOf("Item.id", "Item.remoteId", "title", "clean_description", "image_link", "pub_date", "link",
|
||||
"read_it_later", "Feed.name", "text_color", "background_color", "icon_url", "read_time",
|
||||
"Feed.id as feedId", "Feed.account_id", "Folder.id as folder_id", "Folder.name as folder_name")
|
||||
private val COLUMNS = arrayOf(
|
||||
"Item.id",
|
||||
"Item.remoteId",
|
||||
"title",
|
||||
"clean_description",
|
||||
"image_link",
|
||||
"pub_date",
|
||||
"link",
|
||||
"read_it_later",
|
||||
"Feed.name",
|
||||
"text_color",
|
||||
"background_color",
|
||||
"icon_url",
|
||||
"read_time",
|
||||
"Feed.id as feedId",
|
||||
"Feed.account_id",
|
||||
"Folder.id as folder_id",
|
||||
"Folder.name as folder_name"
|
||||
)
|
||||
|
||||
private val SEPARATE_STATE_COLUMNS = arrayOf("case When ItemState.remote_id is NULL Or ItemState.read = 1 Then 1 else 0 End read",
|
||||
"case When ItemState.remote_id is NULL or ItemState.starred = 1 Then 1 else 0 End starred")
|
||||
private val SEPARATE_STATE_COLUMNS = arrayOf(
|
||||
"case When ItemState.remote_id is NULL Or ItemState.read = 1 Then 1 else 0 End read",
|
||||
"case When ItemState.remote_id is NULL or ItemState.starred = 1 Then 1 else 0 End starred"
|
||||
)
|
||||
|
||||
private val OTHER_COLUMNS = arrayOf("read", "starred")
|
||||
|
||||
private val SELECT_ALL_JOIN = """Item INNER JOIN Feed on Item.feed_id = Feed.id
|
||||
LEFT JOIN Folder on Feed.folder_id = Folder.id """.trimIndent()
|
||||
|
||||
private const val SEPARATE_STATE_JOIN = "LEFT JOIN ItemState On Item.remoteId = ItemState.remote_id"
|
||||
private const val SEPARATE_STATE_JOIN =
|
||||
"LEFT JOIN ItemState On Item.remoteId = ItemState.remote_id"
|
||||
|
||||
private const val ORDER_BY_ASC = "pub_date DESC"
|
||||
|
||||
private const val ORDER_BY_DESC = "pub_date ASC"
|
||||
|
||||
@JvmStatic
|
||||
fun buildItemsQuery(queryFilters: QueryFilters, separateState: Boolean): SupportSQLiteQuery =
|
||||
buildQuery(queryFilters, separateState)
|
||||
buildQuery(queryFilters, separateState)
|
||||
|
||||
@JvmStatic
|
||||
fun buildItemsQuery(queryFilters: QueryFilters): SupportSQLiteQuery =
|
||||
buildQuery(queryFilters, false)
|
||||
buildQuery(queryFilters, false)
|
||||
|
||||
private fun buildQuery(queryFilters: QueryFilters, separateState: Boolean): SupportSQLiteQuery = with(queryFilters) {
|
||||
if (accountId == 0)
|
||||
throw IllegalArgumentException("AccountId must be greater than 0")
|
||||
private fun buildQuery(queryFilters: QueryFilters, separateState: Boolean): SupportSQLiteQuery =
|
||||
with(queryFilters) {
|
||||
if (accountId == 0)
|
||||
throw IllegalArgumentException("AccountId must be greater than 0")
|
||||
|
||||
if (filterType == FilterType.FEED_FILTER && filterFeedId == 0)
|
||||
throw IllegalArgumentException("FeedId must be greater than 0 if current filter is FEED_FILTER")
|
||||
if (queryFilters.subFilter == SubFilter.FEED && filterFeedId == 0)
|
||||
throw IllegalArgumentException("FeedId must be greater than 0 if current filter is FEED_FILTER")
|
||||
|
||||
val columns = if (separateState) COLUMNS.plus(SEPARATE_STATE_COLUMNS) else COLUMNS.plus(OTHER_COLUMNS)
|
||||
val selectAllJoin = if (separateState) SELECT_ALL_JOIN + SEPARATE_STATE_JOIN else SELECT_ALL_JOIN
|
||||
|
||||
SupportSQLiteQueryBuilder.builder(selectAllJoin).run {
|
||||
columns(columns)
|
||||
selection(buildWhereClause(this@with, separateState), null)
|
||||
orderBy(if (sortType == ListSortType.NEWEST_TO_OLDEST) ORDER_BY_ASC else ORDER_BY_DESC)
|
||||
|
||||
create()
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildWhereClause(queryFilters: QueryFilters, separateState: Boolean): String = StringBuilder(500).run {
|
||||
append("Feed.account_id = ${queryFilters.accountId} And ")
|
||||
|
||||
if (!queryFilters.showReadItems) {
|
||||
if (separateState)
|
||||
append("ItemState.read = 0 And ")
|
||||
val columns = if (separateState)
|
||||
COLUMNS.plus(SEPARATE_STATE_COLUMNS)
|
||||
else
|
||||
append("Item.read = 0 And ")
|
||||
}
|
||||
COLUMNS.plus(OTHER_COLUMNS)
|
||||
|
||||
when (queryFilters.filterType) {
|
||||
FilterType.FEED_FILTER -> append("feed_id = ${queryFilters.filterFeedId} And read_it_later = 0")
|
||||
FilterType.FOLDER_FILER -> append("folder_id = ${queryFilters.filterFolderId} And read_it_later = 0")
|
||||
FilterType.STARS_FILTER -> {
|
||||
if (separateState) {
|
||||
append("ItemState.starred = 1 And read_it_later = 0")
|
||||
} else {
|
||||
append("starred = 1 And read_it_later = 0")
|
||||
}
|
||||
val selectAllJoin =
|
||||
if (separateState) SELECT_ALL_JOIN + SEPARATE_STATE_JOIN else SELECT_ALL_JOIN
|
||||
|
||||
SupportSQLiteQueryBuilder.builder(selectAllJoin).run {
|
||||
columns(columns)
|
||||
selection(buildWhereClause(this@with, separateState), null)
|
||||
orderBy(if (sortType == ListSortType.NEWEST_TO_OLDEST) ORDER_BY_ASC else ORDER_BY_DESC)
|
||||
|
||||
create()
|
||||
}
|
||||
FilterType.NEW -> append("DateTime(Round(pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") ")
|
||||
else -> append("read_it_later = 0")
|
||||
}
|
||||
|
||||
toString()
|
||||
}
|
||||
private fun buildWhereClause(queryFilters: QueryFilters, separateState: Boolean): String =
|
||||
StringBuilder(500).run {
|
||||
append("Feed.account_id = ${queryFilters.accountId} And ")
|
||||
|
||||
if (!queryFilters.showReadItems) {
|
||||
if (separateState)
|
||||
append("ItemState.read = 0 And ")
|
||||
else
|
||||
append("Item.read = 0 And ")
|
||||
}
|
||||
|
||||
when (queryFilters.mainFilter) {
|
||||
MainFilter.STARS -> {
|
||||
if (separateState) {
|
||||
append("ItemState.starred = 1 And read_it_later = 0 ")
|
||||
} else {
|
||||
append("starred = 1 And read_it_later = 0 ")
|
||||
}
|
||||
}
|
||||
|
||||
MainFilter.NEW -> append("DateTime(Round(pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") ")
|
||||
else -> append("read_it_later = 0 ")
|
||||
}
|
||||
|
||||
when (queryFilters.subFilter) {
|
||||
SubFilter.FEED -> append("And feed_id = ${queryFilters.filterFeedId} And read_it_later = 0")
|
||||
SubFilter.FOLDER -> append("And folder_id = ${queryFilters.filterFolderId} And read_it_later = 0")
|
||||
else -> {}
|
||||
}
|
||||
|
||||
toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class QueryFilters(
|
||||
var showReadItems: Boolean = true,
|
||||
var filterFeedId: Int = 0,
|
||||
var filterFolderId: Int = 0,
|
||||
var accountId: Int = 0,
|
||||
var filterType: FilterType = FilterType.NO_FILTER,
|
||||
var sortType: ListSortType = ListSortType.NEWEST_TO_OLDEST,
|
||||
val showReadItems: Boolean = true,
|
||||
val filterFeedId: Int = 0,
|
||||
val filterFolderId: Int = 0,
|
||||
val accountId: Int = 0,
|
||||
val mainFilter: MainFilter = MainFilter.ALL,
|
||||
val subFilter: SubFilter = SubFilter.ALL,
|
||||
val sortType: ListSortType = ListSortType.NEWEST_TO_OLDEST,
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user