mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-09 22:08:44 +00:00
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:
parent
e3f66e57df
commit
bdfb475a99
9 changed files with 74 additions and 14 deletions
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue