From 643e4ec11ecf6193db3209d0d2831481ed658cf5 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Wed, 6 Nov 2019 15:25:52 +0100 Subject: [PATCH] Improve challenge filtering --- Habitica/build.gradle | 2 +- .../habitica/data/ChallengeRepository.kt | 4 +- .../implementation/ChallengeRepositoryImpl.kt | 4 +- .../RealmChallengeLocalRepository.kt | 4 ++ .../habitica/ui/activities/MainActivity.kt | 1 - .../ChallengesFilterRecyclerViewAdapter.kt | 6 +-- .../challenges/ChallengeFilterDialogHolder.kt | 37 ++++--------------- .../challenges/ChallengeListFragment.kt | 20 +++++++--- .../challenges/ChallengesOverviewFragment.kt | 2 - 9 files changed, 33 insertions(+), 47 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 8b74af9b6..3699c5442 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -151,7 +151,7 @@ android { multiDexEnabled true resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW" - versionCode 2291 + versionCode 2292 versionName "2.3" } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ChallengeRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ChallengeRepository.kt index b1eef8770..893c13449 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ChallengeRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ChallengeRepository.kt @@ -4,8 +4,6 @@ import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.ChallengeMembership import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.android.habitica.models.tasks.TaskList -import com.habitrpg.android.habitica.models.user.User - import io.reactivex.Flowable import io.realm.RealmResults @@ -33,7 +31,7 @@ interface ChallengeRepository : BaseRepository { addedTaskList: List, updatedTaskList: List, removedTaskList: List): Flowable fun deleteChallenge(challengeId: String): Flowable - fun getUserChallenges(userId: String): Flowable> + fun getUserChallenges(userId: String? = null): Flowable> fun leaveChallenge(challenge: Challenge, keepTasks: String): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt index 1c691fcf8..32db15bf1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt @@ -118,8 +118,8 @@ class ChallengeRepositoryImpl(localRepository: ChallengeLocalRepository, apiClie return localRepository.challenges } - override fun getUserChallenges(userId: String): Flowable> { - return localRepository.getUserChallenges(userId) + override fun getUserChallenges(userId: String?): Flowable> { + return localRepository.getUserChallenges(userId ?: userID) } override fun retrieveChallenges(page: Int, memberOnly: Boolean): Flowable> { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt index f7e676126..42954e3d7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt @@ -71,7 +71,11 @@ class RealmChallengeLocalRepository(realm: Realm) : RealmBaseLocalRepository(rea }.toTypedArray() realm.where(Challenge::class.java) .isNotNull("name") + .beginGroup() .`in`("id", ids) + .or() + .equalTo("leaderId", userId) + .endGroup() .sort("official", Sort.DESCENDING, "createdAt", Sort.DESCENDING) .findAll() .asFlowable() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 110acce2d..a15439fe6 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -686,7 +686,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { apiClient.readNotification(event.id) .subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) }, RxErrorHandler.handleEmptyError())) - } override fun onEvent(event: ShowConnectionProblemEvent) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt index 57954f74a..413415158 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt @@ -1,16 +1,16 @@ package com.habitrpg.android.habitica.ui.adapter.social.challenges -import androidx.recyclerview.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.CheckBox +import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.ui.helpers.bindView import java.util.* -class ChallengesFilterRecyclerViewAdapter(entries: Collection) : RecyclerView.Adapter() { +class ChallengesFilterRecyclerViewAdapter(entries: List) : RecyclerView.Adapter() { private val entries: List @@ -66,7 +66,7 @@ class ChallengesFilterRecyclerViewAdapter(entries: Collection) : Recycler fun selectAll(groupsToCheck: List) { for (h in holderList) { - h.checkbox.isChecked =groupsToCheck.find { g -> h.group?.id == g.id } != null + h.checkbox.isChecked = groupsToCheck.find { g -> h.group?.id == g.id } != null } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt index ee2e913f3..952f20d44 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt @@ -2,18 +2,16 @@ package com.habitrpg.android.habitica.ui.fragments.social.challenges import android.app.Activity import android.app.AlertDialog -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.view.View import android.widget.Button import android.widget.CheckBox +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengesFilterRecyclerViewAdapter import com.habitrpg.android.habitica.ui.helpers.bindView import com.habitrpg.android.habitica.utils.Action1 -import java.util.* internal class ChallengeFilterDialogHolder private constructor(view: View, private val context: Activity) { @@ -24,7 +22,7 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva private val checkboxNotOwned: CheckBox? by bindView(view, R.id.challenge_filter_not_owned) private var dialog: AlertDialog? = null - private var challengesViewed: List? = null + private var filterGroups: List? = null private var currentFilter: ChallengeFilterOptions? = null private var selectedGroupsCallback: Action1? = null private var adapter: ChallengesFilterRecyclerViewAdapter? = null @@ -34,12 +32,12 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva noneButton?.setOnClickListener { noneClicked() } } - fun bind(builder: AlertDialog.Builder, challengesViewed: List, + fun bind(builder: AlertDialog.Builder, filterGroups: List, currentFilter: ChallengeFilterOptions?, selectedGroupsCallback: Action1) { builder.setPositiveButton(context.getString(R.string.done)) { _, _ -> doneClicked() } .show() - this.challengesViewed = challengesViewed + this.filterGroups = filterGroups this.currentFilter = currentFilter this.selectedGroupsCallback = selectedGroupsCallback fillChallengeGroups() @@ -52,7 +50,7 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva private fun fillChallengeGroups() { this.groupRecyclerView?.layoutManager = LinearLayoutManager(context) - adapter = ChallengesFilterRecyclerViewAdapter(getGroups(challengesViewed)) + adapter = filterGroups?.let { ChallengesFilterRecyclerViewAdapter(it) } if (currentFilter != null && currentFilter?.showByGroups != null) { adapter?.selectAll(currentFilter?.showByGroups ?: emptyList()) } @@ -60,25 +58,6 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva this.groupRecyclerView?.adapter = adapter } - private fun getGroups(challenges: List?): Collection { - val groupMap = HashMap() - - if (challenges != null) { - for (challenge in challenges) { - if (groupMap.containsKey(challenge.groupName)) { - continue - } - val group = Group() - group.id = challenge.groupId ?: "" - group.name = challenge.groupName - - groupMap[challenge.groupName ?: ""] = group - } - } - - return groupMap.values - } - private fun doneClicked() { val options = ChallengeFilterOptions() options.showByGroups = this.adapter?.checkedEntries @@ -100,7 +79,7 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva companion object { - fun showDialog(activity: Activity, challengesViewed: List, + fun showDialog(activity: Activity, filterGroups: List, currentFilter: ChallengeFilterOptions?, selectedGroupsCallback: Action1) { val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_challenge_filter, null) @@ -111,7 +90,7 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva .setTitle(R.string.filter) .setView(dialogLayout) - challengeFilterDialogHolder.bind(builder, challengesViewed, currentFilter, selectedGroupsCallback) + challengeFilterDialogHolder.bind(builder, filterGroups, currentFilter, selectedGroupsCallback) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt index 34350289f..d40982bd9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt @@ -8,12 +8,13 @@ import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository +import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.social.Challenge -import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment @@ -24,6 +25,7 @@ import com.habitrpg.android.habitica.ui.helpers.resetViews import com.habitrpg.android.habitica.utils.Action1 import io.reactivex.Flowable import io.reactivex.functions.Consumer +import io.reactivex.rxkotlin.combineLatest import io.realm.RealmResults import javax.inject.Inject import javax.inject.Named @@ -34,10 +36,11 @@ class ChallengeListFragment : BaseFragment(), androidx.swiperefreshlayout.widget @Inject lateinit var challengeRepository: ChallengeRepository @Inject + lateinit var socialRepository: SocialRepository + @Inject lateinit var userRepository: UserRepository @field:[Inject Named(AppModule.NAMED_USER_ID)] lateinit var userId: String - var user: User? = null private val swipeRefreshLayout: androidx.swiperefreshlayout.widget.SwipeRefreshLayout? by bindView(R.id.refreshLayout) private val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView) @@ -50,6 +53,7 @@ class ChallengeListFragment : BaseFragment(), androidx.swiperefreshlayout.widget private var loadedAllData = false private var challenges: RealmResults? = null + private var filterGroups: MutableList? = null private var filterOptions: ChallengeFilterOptions? = null @@ -85,7 +89,11 @@ class ChallengeListFragment : BaseFragment(), androidx.swiperefreshlayout.widget this.recyclerView?.setBackgroundResource(R.color.white) } - compositeSubscription.add(userRepository.getUser().subscribe(Consumer { this.user = it}, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(socialRepository.getGroup(Group.TAVERN_ID).combineLatest(socialRepository.getUserGroups()).subscribe(Consumer { + this.filterGroups = mutableListOf() + filterGroups?.add(it.first) + filterGroups?.addAll(it.second) + }, RxErrorHandler.handleEmptyError())) recyclerView?.setEmptyView(emptyView) recyclerView?.itemAnimator = SafeDefaultItemAnimator() @@ -123,8 +131,8 @@ class ChallengeListFragment : BaseFragment(), androidx.swiperefreshlayout.widget } private fun loadLocalChallenges() { - val observable: Flowable> = if (viewUserChallengesOnly && user != null) { - challengeRepository.getUserChallenges(user?.id ?: "") + val observable: Flowable> = if (viewUserChallengesOnly) { + challengeRepository.getUserChallenges() } else { challengeRepository.getChallenges() } @@ -156,7 +164,7 @@ class ChallengeListFragment : BaseFragment(), androidx.swiperefreshlayout.widget internal fun showFilterDialog() { activity?.let { ChallengeFilterDialogHolder.showDialog(it, - challenges ?: emptyList(), + filterGroups ?: emptyList(), filterOptions, object : Action1 { override fun call(t: ChallengeFilterOptions) { changeFilter(t) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt index 42ad6394e..752f43090 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt @@ -39,10 +39,8 @@ class ChallengesOverviewFragment : BaseMainFragment() { resetViews() - userChallengesFragment?.user = this.user userChallengesFragment?.setViewUserChallengesOnly(true) - availableChallengesFragment?.user = this.user availableChallengesFragment?.setViewUserChallengesOnly(false) setViewPagerAdapter() }