correctly display task completion for group tasks

# Conflicts:
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RealmBaseTasksRecyclerViewAdapter.kt
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.kt
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.kt
This commit is contained in:
Phillip Thelen 2022-10-31 12:16:09 +01:00
parent e3f66e57df
commit bdfb475a99
9 changed files with 74 additions and 14 deletions

View file

@ -6,6 +6,8 @@ import com.google.gson.reflect.TypeToken;
import com.habitrpg.android.habitica.models.Achievement;
import com.habitrpg.android.habitica.models.ContentResult;
import com.habitrpg.android.habitica.models.FAQArticle;
import com.habitrpg.android.habitica.models.tasks.GroupAssignedDetails;
import com.habitrpg.android.habitica.utils.AssignedDetailsDeserializer;
import com.habitrpg.common.habitica.models.Notification;
import com.habitrpg.android.habitica.models.Skill;
import com.habitrpg.android.habitica.models.Tag;
@ -101,6 +103,8 @@ public class GSonFactoryCreator {
}.getType();
Type achievementsListType = new TypeToken<List<Achievement>>() {
}.getType();
Type assignedDetailsListType = new TypeToken<RealmList<GroupAssignedDetails>>() {
}.getType();
return new GsonBuilder()
.registerTypeAdapter(taskTagClassListType, new TaskTagDeserializer())
@ -129,6 +133,7 @@ public class GSonFactoryCreator {
.registerTypeAdapter(ownedPetListType, new OwnedPetListDeserializer())
.registerTypeAdapter(ownedMountListType, new OwnedMountListDeserializer())
.registerTypeAdapter(achievementsListType, new AchievementListDeserializer())
.registerTypeAdapter(assignedDetailsListType, new AssignedDetailsDeserializer())
.registerTypeAdapter(Quest.class, new QuestDeserializer())
.registerTypeAdapter(Member.class, new MemberSerialization())
.registerTypeAdapter(WorldState.class, new WorldStateSerialization())

View file

@ -117,6 +117,19 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
val completedChecklistCount: Int
get() = checklist?.count { it.completed } ?: 0
fun completed(byUserID: String?): Boolean {
return if (isGroupTask) {
group?.assignedUsersDetail?.firstOrNull { it.assignedUserID == byUserID }?.completed ?: false
} else {
completed
}
}
fun isDisplayedActiveForUser(userID: String?): Boolean {
val isActive = ((isDue == true && type == TaskType.DAILY) || type == TaskType.TODO)
return isActive && completed(userID)
}
val streakString: String?
get() {
return if (counterUp != null && (counterUp ?: 0) > 0 && counterDown != null && (counterDown ?: 0) > 0) {

View file

@ -7,6 +7,15 @@ import io.realm.RealmObject
import io.realm.annotations.RealmClass
import java.util.Date
@RealmClass(embedded = true)
open class GroupAssignedDetails: RealmObject(), BaseObject {
var assignedDate: String? = null
var assignedUsername: String? = null
var assignedUserID: String? = null
var assigningUsername: String? = null
var completed: Boolean = false
}
@RealmClass(embedded = true)
open class TaskGroupPlan : RealmObject(), BaseObject {
@ -17,6 +26,7 @@ open class TaskGroupPlan : RealmObject(), BaseObject {
var assignedDate: Date? = null
var assigningUsername: String? = null
var assignedUsers: RealmList<String> = RealmList()
var assignedUsersDetail: RealmList<GroupAssignedDetails> = RealmList()
var approvalRequested: Boolean? = false
var approvalApproved: Boolean? = false

View file

@ -79,6 +79,7 @@ abstract class RealmBaseTasksRecyclerViewAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
if (item != null && holder is BaseTaskViewHolder) {
holder.userID = user?.id
holder.isLocked = !viewModel.canScoreTask(item)
holder.bind(item, position, taskDisplayMode, viewModel.ownerID.value)
holder.errorButtonClicked = Action {

View file

@ -43,6 +43,7 @@ abstract class BaseTaskViewHolder constructor(
var task: Task? = null
var movingFromPosition: Int? = null
var errorButtonClicked: Action? = null
var userID: String? = null
var isLocked = false
protected var context: Context
private val mainTaskWrapper: ViewGroup = itemView.findViewById(R.id.main_task_wrapper)

View file

@ -56,7 +56,7 @@ abstract class ChecklistedViewHolder(
displayMode: String,
ownerID: String?
) {
var completed = data.completed
var completed = data.completed(userID)
if (data.isPendingApproval) {
completed = false
}
@ -80,11 +80,11 @@ abstract class ChecklistedViewHolder(
val regularBoxBackground = if (task?.type == TaskType.DAILY) R.drawable.daily_unchecked else R.drawable.todo_unchecked
val completedBoxBackground = if (task?.type == TaskType.DAILY) R.drawable.daily_checked else R.drawable.todo_checked
val inactiveBoxBackground = R.drawable.daily_inactive
if (this.shouldDisplayAsActive(data) && !data.isPendingApproval) {
if (this.shouldDisplayAsActive(data, userID) && !data.isPendingApproval) {
this.checkboxHolder.setBackgroundResource(data.lightTaskColor)
checkboxBackground.setBackgroundResource(regularBoxBackground)
} else {
if (data.completed) {
if (completed) {
titleTextView.setTextColor(ContextCompat.getColor(context, R.color.text_quad))
notesTextView?.setTextColor(ContextCompat.getColor(context, R.color.text_quad))
this.checkboxHolder.setBackgroundColor(context.getThemeColor(R.attr.colorWindowBackground))
@ -98,7 +98,7 @@ abstract class ChecklistedViewHolder(
}
}
abstract fun shouldDisplayAsActive(newTask: Task?): Boolean
abstract fun shouldDisplayAsActive(task: Task?, userID: String?): Boolean
private fun updateChecklistDisplay() {
// This needs to be a LinearLayout, as ListViews can not be inside other ListViews.
@ -116,7 +116,7 @@ abstract class ChecklistedViewHolder(
context,
(
if (context.isUsingNightModeResources()) {
if (task?.completed == true || (task?.type == TaskType.DAILY && task?.isDue == false)) {
if (task?.completed(userID) == true || (task?.type == TaskType.DAILY && task?.isDue == false)) {
R.color.checkbox_fill
} else {
task?.lightTaskColor
@ -151,7 +151,7 @@ abstract class ChecklistedViewHolder(
}
val color = ContextCompat.getColor(
context,
if (task?.completed == true || (task?.type == TaskType.DAILY && task?.isDue == false)) {
if (task?.completed(userID) == true || (task?.type == TaskType.DAILY && task?.isDue == false)) {
checkmark?.drawable?.setTint(ContextCompat.getColor(context, R.color.text_dimmed))
R.color.offset_background
} else {
@ -207,7 +207,7 @@ abstract class ChecklistedViewHolder(
override fun onLeftActionTouched() {
super.onLeftActionTouched()
if (task?.isValid == true) {
onCheckedChanged(!(task?.completed ?: false))
onCheckedChanged(!(task?.completed(userID) ?: false))
}
}
@ -224,8 +224,8 @@ abstract class ChecklistedViewHolder(
if (task?.isValid != true) {
return
}
if (isChecked != task?.completed) {
task?.let { scoreTaskFunc(it, if (task?.completed == false) TaskDirection.UP else TaskDirection.DOWN) }
if (isChecked != task?.completed(userID)) {
task?.let { scoreTaskFunc(it, if (task?.completed(userID) == false) TaskDirection.UP else TaskDirection.DOWN) }
}
}

View file

@ -1,7 +1,6 @@
package com.habitrpg.android.habitica.ui.viewHolders.tasks
import android.view.View
import com.habitrpg.android.habitica.helpers.GroupPlanInfoProvider
import com.habitrpg.android.habitica.models.tasks.ChecklistItem
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.shared.habitica.models.responses.TaskDirection
@ -69,8 +68,8 @@ class DailyViewHolder(
super.bind(data, position, displayMode, ownerID)
}
override fun shouldDisplayAsActive(newTask: Task?): Boolean {
return newTask?.isDisplayedActive ?: false
override fun shouldDisplayAsActive(task: Task?, userID: String?): Boolean {
return task?.isDisplayedActive ?: false
}
override fun configureSpecialTaskTextView(task: Task) {

View file

@ -42,7 +42,7 @@ class TodoViewHolder(
}
}
override fun shouldDisplayAsActive(newTask: Task?): Boolean {
return newTask?.completed != true
override fun shouldDisplayAsActive(task: Task?, userID: String?): Boolean {
return task?.completed(userID) != true
}
}

View file

@ -0,0 +1,31 @@
package com.habitrpg.android.habitica.utils
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.habitrpg.android.habitica.models.tasks.GroupAssignedDetails
import io.realm.RealmList
import java.lang.reflect.Type
class AssignedDetailsDeserializer: JsonDeserializer<RealmList<GroupAssignedDetails?>> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): RealmList<GroupAssignedDetails?> {
val list = RealmList<GroupAssignedDetails?>()
if (json == null) {
return list
} else if (json.isJsonArray) {
json.asJsonArray.forEach { list.add(context?.deserialize(it, GroupAssignedDetails::class.java)) }
} else {
val jsonObject = json.asJsonObject
jsonObject.keySet().forEach {
val details= context?.deserialize<GroupAssignedDetails>(jsonObject[it], GroupAssignedDetails::class.java)
details?.assignedUserID = it
list.add(details)
}
}
return list
}
}