From 2e6e75cd4ef5d6a52544b003ae25fe6ac0bd5dbd Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Thu, 9 Apr 2020 13:07:02 -0300 Subject: [PATCH] Add filter to the feed group dialog to show only ungrouped subscriptions --- .../database/subscription/SubscriptionDAO.kt | 36 ++++++++++++++++- .../local/subscription/SubscriptionManager.kt | 39 ++++++++++++++----- .../subscription/dialog/FeedGroupDialog.kt | 13 ++++++- .../dialog/FeedGroupDialogViewModel.kt | 32 +++++++++------ .../main/res/menu/menu_feed_group_dialog.xml | 13 ++++++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 107 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt index aa34a2867..60dd343b9 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt @@ -22,10 +22,42 @@ abstract class SubscriptionDAO : BasicDAO { @Query(""" SELECT * FROM subscriptions + WHERE name LIKE '%' || :filter || '%' + ORDER BY name COLLATE NOCASE ASC """) - abstract fun filterByName(filter: String): Flowable> + abstract fun getSubscriptionsFiltered(filter: String): Flowable> + + @Query(""" + SELECT * FROM subscriptions s + + LEFT JOIN feed_group_subscription_join fgs + ON s.uid = fgs.subscription_id + + WHERE (fgs.subscription_id IS NULL OR fgs.group_id = :currentGroupId) + + ORDER BY name COLLATE NOCASE ASC + """) + abstract fun getSubscriptionsOnlyUngrouped( + currentGroupId: Long + ): Flowable> + + @Query(""" + SELECT * FROM subscriptions s + + LEFT JOIN feed_group_subscription_join fgs + ON s.uid = fgs.subscription_id + + WHERE (fgs.subscription_id IS NULL OR fgs.group_id = :currentGroupId) + AND s.name LIKE '%' || :filter || '%' + + ORDER BY name COLLATE NOCASE ASC + """) + abstract fun getSubscriptionsOnlyUngroupedFiltered( + currentGroupId: Long, + filter: String + ): Flowable> @Query("SELECT * FROM subscriptions WHERE url LIKE :url AND service_id = :serviceId") abstract fun getSubscriptionFlowable(serviceId: Int, url: String): Flowable> @@ -59,7 +91,7 @@ abstract class SubscriptionDAO : BasicDAO { entity.uid = uidFromInsert } else { val subscriptionIdFromDb = getSubscriptionIdInternal(entity.serviceId, entity.url) - ?: throw IllegalStateException("Subscription cannot be null just after insertion.") + ?: throw IllegalStateException("Subscription cannot be null just after insertion.") entity.uid = subscriptionIdFromDb update(entity) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index ce272c856..2740591e6 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -2,9 +2,11 @@ package org.schabi.newpipe.local.subscription import android.content.Context import io.reactivex.Completable +import io.reactivex.Flowable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers import org.schabi.newpipe.NewPipeDatabase +import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.subscription.SubscriptionDAO import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.extractor.ListInfo @@ -21,11 +23,28 @@ class SubscriptionManager(context: Context) { fun subscriptionTable(): SubscriptionDAO = subscriptionTable fun subscriptions() = subscriptionTable.all - fun filterByName(filter: String) = subscriptionTable.filterByName(filter) + fun getSubscriptions( + currentGroupId: Long = FeedGroupEntity.GROUP_ALL_ID, + filterQuery: String = "", + showOnlyUngrouped: Boolean = false + ): Flowable> { + return when { + filterQuery.isNotEmpty() -> { + return if (showOnlyUngrouped) { + subscriptionTable.getSubscriptionsOnlyUngroupedFiltered( + currentGroupId, filterQuery) + } else { + subscriptionTable.getSubscriptionsFiltered(filterQuery) + } + } + showOnlyUngrouped -> subscriptionTable.getSubscriptionsOnlyUngrouped(currentGroupId) + else -> subscriptionTable.all + } + } fun upsertAll(infoList: List): List { val listEntities = subscriptionTable.upsertAll( - infoList.map { SubscriptionEntity.from(it) }) + infoList.map { SubscriptionEntity.from(it) }) database.runInTransaction { infoList.forEachIndexed { index, info -> @@ -37,13 +56,13 @@ class SubscriptionManager(context: Context) { } fun updateChannelInfo(info: ChannelInfo): Completable = subscriptionTable.getSubscription(info.serviceId, info.url) - .flatMapCompletable { - Completable.fromRunnable { - it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) - subscriptionTable.update(it) - feedDatabaseManager.upsertAll(it.uid, info.relatedItems) - } + .flatMapCompletable { + Completable.fromRunnable { + it.setData(info.name, info.avatarUrl, info.description, info.subscriberCount) + subscriptionTable.update(it) + feedDatabaseManager.upsertAll(it.uid, info.relatedItems) } + } fun updateFromInfo(subscriptionId: Long, info: ListInfo) { val subscriptionEntity = subscriptionTable.getSubscription(subscriptionId) @@ -59,8 +78,8 @@ class SubscriptionManager(context: Context) { fun deleteSubscription(serviceId: Int, url: String): Completable { return Completable.fromCallable { subscriptionTable.deleteSubscription(serviceId, url) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun insertSubscription(subscriptionEntity: SubscriptionEntity, info: ChannelInfo) { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt index 0b77ec1d8..66387d298 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt @@ -65,6 +65,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable { @State @JvmField var iconsListState: Parcelable? = null @State @JvmField var wasSearchSubscriptionsVisible = false @State @JvmField var subscriptionsCurrentSearchQuery = "" + @State @JvmField var subscriptionsShowOnlyUngrouped = false private val subscriptionMainSection = Section() private val subscriptionEmptyFooter = Section() @@ -116,7 +117,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable { viewModel = ViewModelProvider(this, FeedGroupDialogViewModel.Factory(requireContext(), - groupId, subscriptionsCurrentSearchQuery) + groupId, subscriptionsCurrentSearchQuery, subscriptionsShowOnlyUngrouped) ).get(FeedGroupDialogViewModel::class.java) viewModel.groupLiveData.observe(viewLifecycleOwner, Observer(::handleGroup)) @@ -216,6 +217,16 @@ class FeedGroupDialog : DialogFragment(), BackPressable { true } + headerMenu.findItem(R.id.feed_group_toggle_show_only_ungrouped_subscriptions).apply { + isChecked = subscriptionsShowOnlyUngrouped + setOnMenuItemClickListener { + subscriptionsShowOnlyUngrouped = !subscriptionsShowOnlyUngrouped + it.isChecked = subscriptionsShowOnlyUngrouped + viewModel.toggleShowOnlyUngrouped(subscriptionsShowOnlyUngrouped) + true + } + } + toolbar_search_clear.setOnClickListener { if (TextUtils.isEmpty(toolbar_search_edit_text.text)) { hideSearch() diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt index a7ab300f2..e9a7e4eb7 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt @@ -20,24 +20,25 @@ import org.schabi.newpipe.local.subscription.item.PickerSubscriptionItem class FeedGroupDialogViewModel( applicationContext: Context, private val groupId: Long = FeedGroupEntity.GROUP_ALL_ID, - initialQuery: String = "" + initialQuery: String = "", + initialShowOnlyUngrouped: Boolean = false ) : ViewModel() { private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(applicationContext) private var subscriptionManager = SubscriptionManager(applicationContext) private var filterSubscriptions = BehaviorProcessor.create() - private var allSubscriptions = subscriptionManager.subscriptions() + private var toggleShowOnlyUngrouped = BehaviorProcessor.create() - private var subscriptionsFlowable = filterSubscriptions - .startWith(initialQuery) + private var subscriptionsFlowable = Flowable + .combineLatest( + filterSubscriptions.startWith(initialQuery), + toggleShowOnlyUngrouped.startWith(initialShowOnlyUngrouped), + BiFunction { t1: String, t2: Boolean -> Filter(t1, t2) } + ) .distinctUntilChanged() - .switchMap { query -> - if (query.isEmpty()) { - allSubscriptions - } else { - subscriptionManager.filterByName(query) - } + .switchMap { filter -> + subscriptionManager.getSubscriptions(groupId, filter.query, filter.showOnlyUngrouped) }.map { list -> list.map { PickerSubscriptionItem(it) } } private val mutableGroupLiveData = MutableLiveData() @@ -100,20 +101,27 @@ class FeedGroupDialogViewModel( filterSubscriptions.onNext("") } + fun toggleShowOnlyUngrouped(showOnlyUngrouped: Boolean) { + toggleShowOnlyUngrouped.onNext(showOnlyUngrouped) + } + sealed class DialogEvent { object ProcessingEvent : DialogEvent() object SuccessEvent : DialogEvent() } + data class Filter(val query: String, val showOnlyUngrouped: Boolean) + class Factory( private val context: Context, private val groupId: Long = FeedGroupEntity.GROUP_ALL_ID, - private val initialQuery: String = "" + private val initialQuery: String = "", + private val initialShowOnlyUngrouped: Boolean = false ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return FeedGroupDialogViewModel(context.applicationContext, - groupId, initialQuery) as T + groupId, initialQuery, initialShowOnlyUngrouped) as T } } } diff --git a/app/src/main/res/menu/menu_feed_group_dialog.xml b/app/src/main/res/menu/menu_feed_group_dialog.xml index 390088b39..af9be1c65 100644 --- a/app/src/main/res/menu/menu_feed_group_dialog.xml +++ b/app/src/main/res/menu/menu_feed_group_dialog.xml @@ -1,10 +1,19 @@ - + app:showAsAction="always" + tools:ignore="AlwaysShowAction" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f2e79a79b..a4dfd255d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -637,6 +637,7 @@ Name Do you want to delete this group? New + Show only ungrouped subscriptions Feed Feed update threshold Time after last update before a subscription is considered outdated — %s