From b8f73373b2c950486184d031a5d2d2b6abb8602d Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Tue, 24 Jul 2018 11:27:30 +0200 Subject: [PATCH] Fix task filtering --- Habitica/AndroidManifest.xml | 4 +- .../implementation/ChallengeRepositoryImpl.kt | 5 +- .../android/habitica/helpers/SoundFile.kt | 2 +- .../habitica/helpers/TaskFilterHelper.java | 149 ------------- .../habitica/helpers/TaskFilterHelper.kt | 116 +++++++++++ .../ui/activities/CreateChallengeActivity.kt | 3 +- .../ChallengeTasksRecyclerViewAdapter.java | 197 ------------------ .../ChallengeTasksRecyclerViewAdapter.kt | 141 +++++++++++++ .../tasks/BaseTasksRecyclerViewAdapter.kt | 43 +--- .../RealmBaseTasksRecyclerViewAdapter.kt | 4 +- .../tasks/TaskRecyclerViewFragment.kt | 6 +- .../ui/fragments/tasks/TasksFragment.kt | 18 +- .../habitica/ui/views/HabiticaAlertDialog.kt | 9 +- .../InsufficientCurrencyDialog.kt | 7 +- .../ui/views/tasks/TaskFilterDialog.kt | 34 +-- 15 files changed, 311 insertions(+), 427 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 0724d963f..7323bbdf4 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -2,8 +2,8 @@ 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 e9b766625..288f184d1 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 @@ -1,6 +1,5 @@ package com.habitrpg.android.habitica.data.implementation -import com.github.underscore.U import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.local.ChallengeLocalRepository @@ -53,12 +52,12 @@ class ChallengeRepositoryImpl(localRepository: ChallengeLocalRepository, apiClie } private fun getTaskOrders(taskList: List): TasksOrder { - val stringListMap = U.groupBy(taskList) { t -> t.type } + val stringListMap = taskList.groupBy { t -> t.type } val tasksOrder = TasksOrder() for ((key, value) in stringListMap) { - val taskIdList = U.map(value) { t -> t.id } + val taskIdList = value.map { t -> t.id } when (key) { Task.TYPE_HABIT -> tasksOrder.habits = taskIdList diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt index 9ab6c9ab3..cb9ed25ca 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/SoundFile.kt @@ -22,7 +22,7 @@ class SoundFile(val theme: String, private val fileName: String) : MediaPlayer.O } fun play() { - if (isPlaying) { + if (isPlaying || file?.path == null) { return } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.java b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.java deleted file mode 100644 index 66794663a..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.habitrpg.android.habitica.helpers; - -import android.support.annotation.Nullable; - -import com.habitrpg.android.habitica.models.tasks.Task; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.realm.OrderedRealmCollection; -import io.realm.RealmQuery; - -public class TaskFilterHelper { - private List tagsId; - private Map activeFilters = new HashMap<>(); - - public TaskFilterHelper() { - tagsId = new ArrayList<>(); - - } - - public void addTags(String tags) { - this.tagsId.add(tags); - } - - public int howMany(@Nullable String type) { - return this.tagsId.size() + (isTaskFilterActive(type) ? 1 : 0); - } - - private boolean isTaskFilterActive(@Nullable String type) { - if (activeFilters.get(type) == null) { - return false; - } - if (Task.TYPE_TODO.equals(type)) { - return !Task.FILTER_ACTIVE.equals(activeFilters.get(type)); - } else { - return !Task.FILTER_ALL.equals(activeFilters.get(type)); - } - } - - public List getTags() { - return this.tagsId; - } - - public void setTags(List tagsId) { - this.tagsId = tagsId; - } - - public boolean isTagChecked(String tagID) { - return this.tagsId.contains(tagID); - } - - public List filter(List tasks) { - if (tasks.size() == 0) { - return tasks; - } - List filtered = new ArrayList<>(); - String activeFilter = null; - if (activeFilters != null && activeFilters.size() > 0) { - activeFilter = activeFilters.get(tasks.get(0).getType()); - } - for (Task task : tasks) { - if (isFiltered(task, activeFilter)) { - filtered.add(task); - } - } - - return filtered; - } - - private boolean isFiltered(Task task, @Nullable String activeFilter) { - if (!task.containsAllTagIds(tagsId)) { - return false; - } - if (activeFilter != null && !activeFilter.equals(Task.FILTER_ALL)) { - switch (activeFilter) { - case Task.FILTER_ACTIVE: - if (task.getType().equals(Task.TYPE_DAILY)) { - return task.isDisplayedActive(); - } else { - return !task.getCompleted(); - } - case Task.FILTER_GRAY: - return task.getCompleted() || !task.isDisplayedActive(); - case Task.FILTER_WEAK: - return task.getValue() < 0; - case Task.FILTER_STRONG: - return task.getValue() >= 0; - case Task.FILTER_DATED: - return task.getDueDate() != null; - case Task.FILTER_COMPLETED: - return task.getCompleted(); - } - } - return true; - } - - public void setActiveFilter(String type, String activeFilter) { - activeFilters.put(type, activeFilter); - } - - public String getActiveFilter(String type) { - return activeFilters.get(type); - } - - public RealmQuery createQuery(OrderedRealmCollection unfilteredData) { - RealmQuery query = unfilteredData.where(); - - if (unfilteredData.size() == 0) { - return query; - } - - String taskType = unfilteredData.get(0).getType(); - String activeFilter = getActiveFilter(taskType); - - if (tagsId != null && tagsId.size() > 0) { - query = query.in("tags.id", tagsId.toArray(new String[0])); - } - if (activeFilter != null && !activeFilter.equals(Task.FILTER_ALL)) { - switch (activeFilter) { - case Task.FILTER_ACTIVE: - if (Task.TYPE_DAILY.equals(taskType)) { - query = query.equalTo("completed", false).equalTo("isDue", true); - } else { - query = query.equalTo("completed", false); - } - break; - case Task.FILTER_GRAY: - query = query.equalTo("completed", true).or().equalTo("isDue", false); - break; - case Task.FILTER_WEAK: - query = query.lessThan("value", 0.0d); - break; - case Task.FILTER_STRONG: - query = query.greaterThanOrEqualTo("value", 0.0d); - break; - case Task.FILTER_DATED: - query = query.isNotNull("dueDate"); - break; - case Task.FILTER_COMPLETED: - query = query.equalTo("completed", true); - break; - } - } - return query; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.kt new file mode 100644 index 000000000..190db2ef4 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskFilterHelper.kt @@ -0,0 +1,116 @@ +package com.habitrpg.android.habitica.helpers + +import com.habitrpg.android.habitica.models.tasks.Task + +import java.util.ArrayList +import java.util.HashMap + +import io.realm.OrderedRealmCollection +import io.realm.RealmQuery + +class TaskFilterHelper { + private var tagsId: MutableList = ArrayList() + private val activeFilters = HashMap() + + var tags: MutableList + get() = this.tagsId + set(tagsId) { + this.tagsId = tagsId + } + + fun howMany(type: String?): Int { + return this.tagsId.size + if (isTaskFilterActive(type)) 1 else 0 + } + + private fun isTaskFilterActive(type: String?): Boolean { + if (activeFilters[type] == null) { + return false + } + return if (Task.TYPE_TODO == type) { + Task.FILTER_ACTIVE != activeFilters[type] + } else { + Task.FILTER_ALL != activeFilters[type] + } + } + + fun isTagChecked(tagID: String): Boolean { + return this.tagsId.contains(tagID) + } + + fun filter(tasks: List): List { + if (tasks.isEmpty()) { + return tasks + } + val filtered = ArrayList() + var activeFilter: String? = null + if (activeFilters.size > 0) { + activeFilter = activeFilters[tasks[0].type] + } + for (task in tasks) { + if (isFiltered(task, activeFilter)) { + filtered.add(task) + } + } + + return filtered + } + + private fun isFiltered(task: Task, activeFilter: String?): Boolean { + if (!task.containsAllTagIds(tagsId)) { + return false + } + if (activeFilter != null && activeFilter != Task.FILTER_ALL) { + when (activeFilter) { + Task.FILTER_ACTIVE -> return if (task.type == Task.TYPE_DAILY) { + task.isDisplayedActive + } else { + !task.completed + } + Task.FILTER_GRAY -> return task.completed || !task.isDisplayedActive + Task.FILTER_WEAK -> return task.value < 0 + Task.FILTER_STRONG -> return task.value >= 0 + Task.FILTER_DATED -> return task.dueDate != null + Task.FILTER_COMPLETED -> return task.completed + } + } + return true + } + + fun setActiveFilter(type: String, activeFilter: String) { + activeFilters[type] = activeFilter + } + + fun getActiveFilter(type: String): String? { + return activeFilters[type] + } + + fun createQuery(unfilteredData: OrderedRealmCollection): RealmQuery { + var query = unfilteredData.where() + + if (unfilteredData.size == 0) { + return query + } + + val taskType = unfilteredData[0].type + val activeFilter = getActiveFilter(taskType) + + if (tagsId.size > 0) { + query = query.`in`("tags.id", tagsId.toTypedArray()) + } + if (activeFilter != null && activeFilter != Task.FILTER_ALL) { + when (activeFilter) { + Task.FILTER_ACTIVE -> query = if (Task.TYPE_DAILY == taskType) { + query.equalTo("completed", false).equalTo("isDue", true) + } else { + query.equalTo("completed", false) + } + Task.FILTER_GRAY -> query = query.equalTo("completed", true).or().equalTo("isDue", false) + Task.FILTER_WEAK -> query = query.lessThan("value", 0.0) + Task.FILTER_STRONG -> query = query.greaterThanOrEqualTo("value", 0.0) + Task.FILTER_DATED -> query = query.isNotNull("dueDate") + Task.FILTER_COMPLETED -> query = query.equalTo("completed", true) + } + } + return query + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/CreateChallengeActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/CreateChallengeActivity.kt index 5c0483d70..408185766 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/CreateChallengeActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/CreateChallengeActivity.kt @@ -14,7 +14,6 @@ import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.view.* import android.widget.* -import com.github.underscore.U import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.AppComponent import com.habitrpg.android.habitica.data.ChallengeRepository @@ -181,7 +180,7 @@ class CreateChallengeActivity : BaseActivity() { } val builder = AlertDialog.Builder(this) - .setMessage(U.join(errorMessages, "\n")) + .setMessage(errorMessages.joinToString("\n")) val alert = builder.create() alert.show() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.java deleted file mode 100644 index 795018af3..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social.challenges; - -import android.content.Context; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import com.github.underscore.U; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.helpers.TaskFilterHelper; -import com.habitrpg.android.habitica.models.tasks.Task; -import com.habitrpg.android.habitica.ui.adapter.tasks.SortableTasksRecyclerViewAdapter; -import com.habitrpg.android.habitica.ui.viewHolders.tasks.BaseTaskViewHolder; -import com.habitrpg.android.habitica.ui.viewHolders.tasks.DailyViewHolder; -import com.habitrpg.android.habitica.ui.viewHolders.tasks.HabitViewHolder; -import com.habitrpg.android.habitica.ui.viewHolders.tasks.RewardViewHolder; -import com.habitrpg.android.habitica.ui.viewHolders.tasks.TodoViewHolder; - -import java.util.List; - -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; - -public class ChallengeTasksRecyclerViewAdapter - extends SortableTasksRecyclerViewAdapter { - public static final String TASK_TYPE_ADD_ITEM = "ADD_ITEM"; - - private static final int TYPE_HEADER = 0; - private static final int TYPE_HABIT = 1; - private static final int TYPE_DAILY = 2; - private static final int TYPE_TODO = 3; - private static final int TYPE_REWARD = 4; - private static final int TYPE_ADD_ITEM = 5; - - private int dailyResetOffset = 0; - private PublishSubject addItemSubject = PublishSubject.create(); - private boolean openTaskDisabled; - private boolean taskActionsDisabled; - - public ChallengeTasksRecyclerViewAdapter(@Nullable TaskFilterHelper taskFilterHelper, int layoutResource, - Context newContext, String userID, @Nullable SortTasksCallback sortCallback, - boolean openTaskDisabled, boolean taskActionsDisabled) { - super("", taskFilterHelper, layoutResource, newContext, userID, sortCallback); - this.openTaskDisabled = openTaskDisabled; - this.taskActionsDisabled = taskActionsDisabled; - } - - public void setDailyResetOffset(int newResetOffset) { - dailyResetOffset = newResetOffset; - } - - @Override - protected void injectThis(AppComponent component) { - component.inject(this); - } - - @Override - public boolean loadFromDatabase() { - return false; - } - - @Override - public int getItemViewType(int position) { - Task task = this.getFilteredContent().get(position); - - if (task.getType().equals(Task.TYPE_HABIT)) - return TYPE_HABIT; - - if (task.getType().equals(Task.TYPE_DAILY)) - return TYPE_DAILY; - - if (task.getType().equals(Task.TYPE_TODO)) - return TYPE_TODO; - - if (task.getType().equals(Task.TYPE_REWARD)) - return TYPE_REWARD; - - if (addItemSubject.hasObservers() && task.getType().equals(TASK_TYPE_ADD_ITEM)) - return TYPE_ADD_ITEM; - - return TYPE_HEADER; - } - - public Flowable addItemObservable(){ - return addItemSubject.toFlowable(BackpressureStrategy.BUFFER); - } - - public int addTaskUnder(Task taskToAdd, @Nullable Task taskAbove) { - int position = U.findIndex(this.getContent(), t -> t.getId().equals(taskAbove.getId())); - - getContent().add(position + 1, taskToAdd); - filter(); - - return position; - } - - @Override - public BaseTaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - BaseTaskViewHolder viewHolder = null; - - switch (viewType) { - case TYPE_HABIT: - viewHolder = new HabitViewHolder(getContentView(parent, R.layout.habit_item_card)); - break; - case TYPE_DAILY: - viewHolder = new DailyViewHolder(getContentView(parent, R.layout.daily_item_card)); - break; - case TYPE_TODO: - viewHolder = new TodoViewHolder(getContentView(parent, R.layout.todo_item_card)); - break; - case TYPE_REWARD: - viewHolder = new RewardViewHolder(getContentView(parent, R.layout.reward_item_card)); - break; - case TYPE_ADD_ITEM: - viewHolder = new AddItemViewHolder(getContentView(parent, R.layout.challenge_add_task_item), addItemSubject); - break; - default: - viewHolder = new DividerViewHolder(getContentView(parent, R.layout.challenge_task_divider)); - break; - } - - viewHolder.setDisabled(openTaskDisabled, taskActionsDisabled); - return viewHolder; - } - - public List getTaskList(){ - return U.map(getContent(), t -> t); - } - - - /** - * @param task - * @return true if task found&updated - */ - public boolean replaceTask(Task task) { - int i; - for (i = 0; i < this.getContent().size(); ++i) { - if (getContent().get(i).getId().equals(task.getId())) { - break; - } - } - if (i < getContent().size()) { - getContent().set(i, task); - - filter(); - return true; - } - - return false; - } - - public class AddItemViewHolder extends BaseTaskViewHolder { - - private Button addBtn; - private PublishSubject callback; - private Task newTask; - - AddItemViewHolder(View itemView, PublishSubject callback) { - super(itemView); - this.callback = callback; - - addBtn = itemView.findViewById(R.id.btn_add_task); - addBtn.setClickable(true); - addBtn.setOnClickListener(view -> callback.onNext(newTask)); - setContext(itemView.getContext()); - } - - @Override - public void bindHolder(@NonNull Task newTask, int position) { - this.newTask = newTask; - addBtn.setText(newTask.getText()); - } - } - - private class DividerViewHolder extends BaseTaskViewHolder { - - private TextView divider_name; - - DividerViewHolder(View itemView) { - super(itemView); - - divider_name = itemView.findViewById(R.id.divider_name); - - setContext(itemView.getContext()); - } - - @Override - public void bindHolder(@NonNull Task newTask, int position) { - divider_name.setText(newTask.getText()); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt new file mode 100644 index 000000000..47d7626e4 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengeTasksRecyclerViewAdapter.kt @@ -0,0 +1,141 @@ +package com.habitrpg.android.habitica.ui.adapter.social.challenges + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.components.AppComponent +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.helpers.TaskFilterHelper +import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.ui.adapter.tasks.SortableTasksRecyclerViewAdapter +import com.habitrpg.android.habitica.ui.viewHolders.tasks.* +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject + +class ChallengeTasksRecyclerViewAdapter(taskFilterHelper: TaskFilterHelper?, layoutResource: Int, + newContext: Context, userID: String, sortCallback: SortableTasksRecyclerViewAdapter.SortTasksCallback?, + private val openTaskDisabled: Boolean, private val taskActionsDisabled: Boolean) : SortableTasksRecyclerViewAdapter("", taskFilterHelper, layoutResource, newContext, userID, sortCallback) { + + private val addItemSubject = PublishSubject.create() + + val taskList: MutableList + get() = content?.map { t -> t }?.toMutableList() ?: mutableListOf() + + override fun injectThis(component: AppComponent) { + component.inject(this) + } + + override fun loadFromDatabase(): Boolean { + return false + } + + override fun getItemViewType(position: Int): Int { + val task = this.filteredContent?.get(position) + + if (task?.type == Task.TYPE_HABIT) { + return TYPE_HABIT + } + if (task?.type == Task.TYPE_DAILY) { + return TYPE_DAILY + } + if (task?.type == Task.TYPE_TODO) { + return TYPE_TODO + } + if (task?.type == Task.TYPE_REWARD) { + return TYPE_REWARD + } + + return if (addItemSubject.hasObservers() && task?.type == TASK_TYPE_ADD_ITEM) TYPE_ADD_ITEM else TYPE_HEADER + + } + + fun addItemObservable(): Flowable { + return addItemSubject.toFlowable(BackpressureStrategy.BUFFER) + } + + fun addTaskUnder(taskToAdd: Task, taskAbove: Task?): Int { + val position = content?.indexOfFirst { t -> t.id == taskAbove?.id } ?: 0 + + content?.add(position + 1, taskToAdd) + filter() + + return position + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseTaskViewHolder { + val viewHolder: BaseTaskViewHolder = when (viewType) { + TYPE_HABIT -> HabitViewHolder(getContentView(parent, R.layout.habit_item_card)) + TYPE_DAILY -> DailyViewHolder(getContentView(parent, R.layout.daily_item_card)) + TYPE_TODO -> TodoViewHolder(getContentView(parent, R.layout.todo_item_card)) + TYPE_REWARD -> RewardViewHolder(getContentView(parent, R.layout.reward_item_card)) + TYPE_ADD_ITEM -> AddItemViewHolder(getContentView(parent, R.layout.challenge_add_task_item), addItemSubject) + else -> DividerViewHolder(getContentView(parent, R.layout.challenge_task_divider)) + } + + viewHolder.setDisabled(openTaskDisabled, taskActionsDisabled) + return viewHolder + } + + + /** + * @param task + * @return true if task found&updated + */ + fun replaceTask(task: Task): Boolean { + var i = 0 + while (i < this.content?.size ?: 0) { + if (content?.get(i)?.id == task.id) { + break + } + ++i + } + if (i < content?.size ?: 0) { + content?.set(i, task) + + filter() + return true + } + + return false + } + + inner class AddItemViewHolder internal constructor(itemView: View, private val callback: PublishSubject) : BaseTaskViewHolder(itemView) { + + private val addBtn: Button = itemView.findViewById(R.id.btn_add_task) + private var newTask: Task? = null + + init { + addBtn.isClickable = true + addBtn.setOnClickListener { newTask.notNull { callback.onNext(it) } } + } + + override fun bindHolder(newTask: Task, position: Int) { + this.newTask = newTask + addBtn.text = newTask.text + } + } + + private inner class DividerViewHolder internal constructor(itemView: View) : BaseTaskViewHolder(itemView) { + + private val dividerName: TextView = itemView.findViewById(R.id.divider_name) + + override fun bindHolder(newTask: Task, position: Int) { + dividerName.text = newTask.text + } + } + + companion object { + const val TASK_TYPE_ADD_ITEM = "ADD_ITEM" + + private const val TYPE_HEADER = 0 + private const val TYPE_HABIT = 1 + private const val TYPE_DAILY = 2 + private const val TYPE_TODO = 3 + private const val TYPE_REWARD = 4 + private const val TYPE_ADD_ITEM = 5 + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.kt index 74b6921ff..a3940c88e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.kt @@ -67,10 +67,10 @@ abstract class BaseTasksRecyclerViewAdapter(var taskTyp protected fun getContentView(parent: ViewGroup, layoutResource: Int): View = LayoutInflater.from(parent.context).inflate(layoutResource, parent, false) - fun updateTask(task: Task) { + private fun updateTask(task: Task) { if (taskType != task.type) return - var i: Int = 0 + var i = 0 while (i < this.content!!.size) { if (content!![i].id == task.id) { break @@ -88,13 +88,15 @@ abstract class BaseTasksRecyclerViewAdapter(var taskTyp filteredContent = content } else { filteredContent = ArrayList() - filteredContent!!.addAll(this.taskFilterHelper.filter(content)) + content.notNull { + filteredContent?.addAll(this.taskFilterHelper.filter(it)) + } } this.notifyDataSetChanged() } - fun loadContent(forced: Boolean) { + private fun loadContent(forced: Boolean) { if (this.content == null || forced) { taskRepository.getTasks(this.taskType, this.userID!!) .flatMap { Flowable.fromIterable(it) } @@ -116,37 +118,4 @@ abstract class BaseTasksRecyclerViewAdapter(var taskTyp } open fun loadFromDatabase(): Boolean = true - - fun checkTask(task: Task, completed: Boolean?) { - if (taskType != task.type) - return - - if (completed!! && task.type == "todo") { - // remove from the list - content!!.remove(task) - } - this.updateTask(task) - filter() - } - - fun addTask(task: Task) { - if (taskType != task.type) - return - - content!!.add(0, task) - filter() - } - - fun removeTask(deletedTaskId: String) { - val taskToDelete: Task? = content?.firstOrNull { it.id == deletedTaskId } - - if (taskToDelete != null) { - content?.remove(taskToDelete) - filter() - } - } - - open fun setDailyResetOffset(dayStart: Int) { - - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt index b946bf169..c3b384f60 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt @@ -141,9 +141,7 @@ abstract class RealmBaseTasksRecyclerViewAdapter(privat LayoutInflater.from(parent.context).inflate(layoutResource, parent, false) final override fun filter() { - if (unfilteredData == null) { - return - } + val unfilteredData = this.unfilteredData ?: return if (taskFilterHelper != null) { val query = taskFilterHelper.createQuery(unfilteredData) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt index 83289b5aa..d73a67f50 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt @@ -260,9 +260,7 @@ open class TaskRecyclerViewFragment : BaseFragment(), View.OnClickListener, Swip } fun setActiveFilter(activeFilter: String) { - if (classType != null) { - taskFilterHelper.setActiveFilter(classType, activeFilter) - } + taskFilterHelper.setActiveFilter(classType ?: "", activeFilter) recyclerAdapter?.filter() if (activeFilter == Task.FILTER_COMPLETED) { @@ -271,7 +269,7 @@ open class TaskRecyclerViewFragment : BaseFragment(), View.OnClickListener, Swip } companion object { - private val CLASS_TYPE_KEY = "CLASS_TYPE_KEY" + private const val CLASS_TYPE_KEY = "CLASS_TYPE_KEY" fun newInstance(context: Context?, user: User?, classType: String): TaskRecyclerViewFragment { val fragment = TaskRecyclerViewFragment() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt index 2119f7e25..01b0a8ecd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt @@ -35,8 +35,8 @@ class TasksFragment : BaseMainFragment() { @Inject lateinit var tagRepository: TagRepository - internal var refreshItem: MenuItem? = null - internal var floatingMenu: FloatingActionMenu? = null + private var refreshItem: MenuItem? = null + private var floatingMenu: FloatingActionMenu? = null internal var viewFragmentsDictionary: MutableMap? = WeakHashMap() private var displayingTaskForm: Boolean = false @@ -71,7 +71,7 @@ class TasksFragment : BaseMainFragment() { todoFab?.setOnClickListener { openNewTaskActivity(Task.TYPE_TODO) } val rewardFab = floatingMenu?.findViewById(R.id.fab_new_reward) rewardFab?.setOnClickListener { openNewTaskActivity(Task.TYPE_REWARD) } - floatingMenu?.setOnMenuButtonLongClickListener { this.onFloatingMenuLongClicked(it) } + floatingMenu?.setOnMenuButtonLongClickListener { this.onFloatingMenuLongClicked() } loadTaskLists() @@ -95,7 +95,7 @@ class TasksFragment : BaseMainFragment() { super.onDestroy() } - private fun onFloatingMenuLongClicked(view: View): Boolean { + private fun onFloatingMenuLongClicked(): Boolean { val currentFragment = activeFragment if (currentFragment != null) { val className = currentFragment.className @@ -148,7 +148,7 @@ class TasksFragment : BaseMainFragment() { } dialog.setListener(object : TaskFilterDialog.OnFilterCompletedListener { - override fun onFilterCompleted(activeTaskFilter: String?, activeTags: List?) { + override fun onFilterCompleted(activeTaskFilter: String?, activeTags: MutableList) { if (viewFragmentsDictionary == null) { return } @@ -329,10 +329,6 @@ class TasksFragment : BaseMainFragment() { //endregion Events - override fun onDestroyView() { - super.onDestroyView() - } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) @@ -383,7 +379,7 @@ class TasksFragment : BaseMainFragment() { override fun addToBackStack(): Boolean = false companion object { - private val TASK_CREATED_RESULT = 1 - private val TASK_UPDATED_RESULT = 2 + private const val TASK_CREATED_RESULT = 1 + private const val TASK_UPDATED_RESULT = 2 } } \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaAlertDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaAlertDialog.kt index 250221086..8cd282d58 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaAlertDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaAlertDialog.kt @@ -14,14 +14,17 @@ import com.habitrpg.android.habitica.extensions.layoutInflater open class HabiticaAlertDialog(context: Context) : AlertDialog(context) { private val view: LinearLayout = LayoutInflater.from(context).inflate(R.layout.dialog_habitica_base, null) as LinearLayout - private val titleTextView: TextView by bindView(R.id.titleTextView) - private val subtitleTextView: TextView by bindView(R.id.subtitleTextView) - private val messageTextView: TextView by bindView(R.id.messageTextView) + private var titleTextView: TextView + private var subtitleTextView: TextView + private var messageTextView: TextView private var additionalContentView: View? = null init { setView(view) + titleTextView = view.findViewById(R.id.titleTextView) + subtitleTextView = view.findViewById(R.id.subtitleTextView) + messageTextView = view.findViewById(R.id.messageTextView) } override fun setTitle(title: CharSequence?) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientCurrencyDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientCurrencyDialog.kt index 64c81f634..d627fae1a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientCurrencyDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/insufficientCurrency/InsufficientCurrencyDialog.kt @@ -14,8 +14,8 @@ import com.habitrpg.android.habitica.ui.helpers.bindView abstract class InsufficientCurrencyDialog(context: Context) : AlertDialog(context) { - protected val imageView: ImageView by bindView(R.id.imageView) - protected val textView: TextView by bindView(R.id.textView) + protected var imageView: ImageView + protected var textView: TextView init { @@ -23,6 +23,9 @@ abstract class InsufficientCurrencyDialog(context: Context) : AlertDialog(contex val view = inflater.inflate(R.layout.dialog_insufficient_currency, null) setView(view) + imageView = view.findViewById(R.id.imageView) + textView = view.findViewById(R.id.textView) + this.setButton(AlertDialog.BUTTON_NEUTRAL, context.getString(R.string.close)) { _, _ -> this.dismiss() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/TaskFilterDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/TaskFilterDialog.kt index 5688cf71c..8250a99aa 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/TaskFilterDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/TaskFilterDialog.kt @@ -23,7 +23,6 @@ import com.habitrpg.android.habitica.data.TagRepository import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.Tag import com.habitrpg.android.habitica.models.tasks.Task -import com.habitrpg.android.habitica.ui.helpers.bindView import io.reactivex.Observable import io.reactivex.functions.Consumer import java.util.* @@ -34,13 +33,14 @@ class TaskFilterDialog(context: Context, component: AppComponent?) : AlertDialog @Inject lateinit var repository: TagRepository - private val taskTypeTitle: TextView by bindView(R.id.task_type_title) - private val taskFilters: RadioGroup by bindView(R.id.task_filter_wrapper) - private val allTaskFilter: RadioButton by bindView(R.id.all_task_filter) - private val secondTaskFilter: RadioButton by bindView(R.id.second_task_filter) - private val thirdTaskFilter: RadioButton by bindView(R.id.third_task_filter) - private val tagsEditButton: Button by bindView(R.id.tag_edit_button) - private val tagsList: LinearLayout by bindView(R.id.tags_list) + private var taskTypeTitle: TextView + private var taskFilters: RadioGroup + private var allTaskFilter: RadioButton + private var secondTaskFilter: RadioButton + private var thirdTaskFilter: RadioButton + private var tagsEditButton: Button + private var tagsList: LinearLayout + private var taskType: String? = null private var listener: OnFilterCompletedListener? = null @@ -60,11 +60,19 @@ class TaskFilterDialog(context: Context, component: AppComponent?) : AlertDialog val inflater = LayoutInflater.from(context) val view = inflater.inflate(R.layout.dialog_task_filter, null) + setTitle(R.string.filters) + setView(view) + + taskTypeTitle = view.findViewById(R.id.task_type_title) + taskFilters = view.findViewById(R.id.task_filter_wrapper) + allTaskFilter = view.findViewById(R.id.all_task_filter) + secondTaskFilter = view.findViewById(R.id.second_task_filter) + thirdTaskFilter = view.findViewById(R.id.third_task_filter) + tagsEditButton = view.findViewById(R.id.tag_edit_button) + tagsList = view.findViewById(R.id.tags_list) taskFilters.setOnCheckedChangeListener(this) - setTitle(R.string.filters) - setView(view) this.setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.done)) { _, _ -> if (isEditing) { stopEditing() @@ -78,7 +86,7 @@ class TaskFilterDialog(context: Context, component: AppComponent?) : AlertDialog tagsEditButton.setOnClickListener { editButtonClicked() } } - override fun onCreate(savedInstanceState: Bundle) { + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val clearButton = getButton(AlertDialog.BUTTON_NEUTRAL) if (clearButton != null) { @@ -262,7 +270,7 @@ class TaskFilterDialog(context: Context, component: AppComponent?) : AlertDialog return -1 } - fun setTaskType(taskType: String, activeFilter: String) { + fun setTaskType(taskType: String, activeFilter: String?) { this.taskType = taskType when (taskType) { Task.TYPE_HABIT -> { @@ -358,6 +366,6 @@ class TaskFilterDialog(context: Context, component: AppComponent?) : AlertDialog interface OnFilterCompletedListener { - fun onFilterCompleted(activeTaskFilter: String?, activeTags: List?) + fun onFilterCompleted(activeTaskFilter: String?, activeTags: MutableList) } }