very very basic task checking off

This commit is contained in:
Phillip Thelen 2022-06-07 12:35:53 +02:00
parent f3adb040a1
commit 1f22d10b67
14 changed files with 128 additions and 10 deletions

View file

@ -38,4 +38,12 @@ class TaskLocalRepository @Inject constructor() {
this.tasks[type.key]?.value = type.value
}
}
fun updateTask(task: Task) {
val oldList = tasks[task.type]?.value?.toMutableList()
oldList?.indexOfFirst { task.id == it.id }?.let { index ->
oldList.set(index, task)
}
tasks[task.type]?.value = oldList
}
}

View file

@ -1,6 +1,7 @@
package com.habitrpg.wearos.habitica.data.repositories
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.data.ApiClient
import com.habitrpg.wearos.habitica.models.tasks.Task
@ -17,12 +18,14 @@ class TaskRepository @Inject constructor(val apiClient: ApiClient, val localRepo
}
fun getTasks(taskType: TaskType): Flow<List<Task>> = localRepository.getTasks(taskType)
suspend fun scoreTask(taskID: String, direction: TaskDirection) {
val response = apiClient.scoreTask(taskID, direction.text)
}
suspend fun scoreTask(task: Task, direction: TaskDirection) {
val id = task.id ?: return
val response = scoreTask(id, direction)
suspend fun scoreTask(task: Task, direction: TaskDirection): TaskScoringResult? {
val id = task.id ?: return null
val result = apiClient.scoreTask(id, direction.text)
if (result != null) {
task.completed = direction == TaskDirection.UP
localRepository.updateTask(task)
}
return result?.let { TaskScoringResult(it, null) }
}
}

View file

@ -1,11 +1,16 @@
package com.habitrpg.wearos.habitica.ui.activities
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.wear.activity.ConfirmationActivity
import androidx.wear.widget.WearableLinearLayoutManager
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.R
import com.habitrpg.wearos.habitica.databinding.ActivityTasklistBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.ui.adapters.DailyListAdapter
import com.habitrpg.wearos.habitica.ui.adapters.HabitListAdapter
import com.habitrpg.wearos.habitica.ui.adapters.RewardListAdapter
@ -33,6 +38,37 @@ class TaskListActivity: BaseActivity<ActivityTasklistBinding, TaskListViewModel>
viewModel.tasks.observe(this) {
adapter.data = it
}
adapter.onTaskScore = {
scoreTask(it)
}
}
private fun scoreTask(task: Task) {
var direction = TaskDirection.UP
if (task.type == TaskType.HABIT) {
if (task.up == true && task.down == true) {
return
} else {
direction = if (task.up == true) TaskDirection.UP else TaskDirection.DOWN
}
} else if (task.completed) {
direction = TaskDirection.DOWN
}
viewModel.scoreTask(task, direction) {
if (it != null) {
showTaskScoringResult(it)
}
}
}
private fun showTaskScoringResult(result: TaskScoringResult) {
val intent = Intent(this, ConfirmationActivity::class.java).apply {
putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION)
putExtra(ConfirmationActivity.EXTRA_MESSAGE, result.experienceDelta?.toString())
putExtra(ConfirmationActivity.EXTRA_ANIMATION_DURATION_MILLIS, 3000)
}
startActivity(intent)
}
private fun configureAdapter() {

View file

@ -10,6 +10,7 @@ import com.habitrpg.wearos.habitica.ui.viewHolders.tasks.TaskViewHolder
open class TaskListAdapter(): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var title: String = ""
var onTaskScore: ((Task) -> Unit)? = null
var data: List<Task> = listOf()
set(value) {
field = value
@ -24,6 +25,9 @@ open class TaskListAdapter(): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
if (holder is TaskViewHolder) {
val item = data[position - 1]
holder.bind(item)
holder.onTaskScore = {
onTaskScore?.invoke(item)
}
} else if (holder is HeaderViewHolder){
holder.bind(title)
}

View file

@ -1,16 +1,25 @@
package com.habitrpg.wearos.habitica.ui.viewHolders.tasks
import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowDailyBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
class DailyViewHolder(itemView: View) : TaskViewHolder(itemView) {
private val binding = RowHabitBinding.bind(itemView)
private val binding = RowDailyBinding.bind(itemView)
override val titleView: TextView
get() = binding.title
init {
binding.checkbox.setOnCheckedChangeListener { buttonView, isChecked ->
onTaskScore?.invoke()
}
}
override fun bind(data: Task) {
super.bind(data)
binding.checkbox.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(itemView.context, data.mediumTaskColor))
}
}

View file

@ -1,7 +1,9 @@
package com.habitrpg.wearos.habitica.ui.viewHolders.tasks
import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
@ -10,7 +12,14 @@ class HabitViewHolder(itemView: View) : TaskViewHolder(itemView) {
override val titleView: TextView
get() = binding.title
init {
binding.habitButton.setOnClickListener {
onTaskScore?.invoke()
}
}
override fun bind(data: Task) {
super.bind(data)
binding.habitButton.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(itemView.context, data.mediumTaskColor))
}
}

View file

@ -2,12 +2,11 @@ package com.habitrpg.wearos.habitica.ui.viewHolders.tasks
import android.view.View
import android.widget.TextView
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.ui.viewHolders.BindableViewHolder
abstract class TaskViewHolder(itemView: View) : BindableViewHolder<Task>(itemView) {
var onTaskScored: ((TaskDirection) -> Unit)? = null
var onTaskScore: (() -> Unit)? = null
abstract val titleView: TextView
override fun bind(data: Task) {
titleView.text = data.text

View file

@ -1,7 +1,9 @@
package com.habitrpg.wearos.habitica.ui.viewHolders.tasks
import android.content.res.ColorStateList
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.habitrpg.wearos.habitica.databinding.RowTodoBinding
import com.habitrpg.wearos.habitica.models.tasks.Task
@ -9,7 +11,15 @@ class ToDoViewHolder(itemView: View) : TaskViewHolder(itemView) {
private val binding = RowTodoBinding.bind(itemView)
override val titleView: TextView
get() = binding.title
init {
binding.checkbox.setOnCheckedChangeListener { buttonView, isChecked ->
onTaskScore?.invoke()
}
}
override fun bind(data: Task) {
super.bind(data)
binding.checkbox.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(itemView.context, data.mediumTaskColor))
}
}

View file

@ -3,12 +3,16 @@ package com.habitrpg.wearos.habitica.ui.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.common.habitica.models.responses.TaskScoringResult
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.data.repositories.TaskRepository
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
@ -18,6 +22,13 @@ class TaskListViewModel @Inject constructor(
userRepository: UserRepository,
exceptionBuilder: ExceptionHandlerBuilder
) : BaseViewModel(userRepository, exceptionBuilder) {
fun scoreTask(task: Task, direction: TaskDirection, onResult: (TaskScoringResult?) -> Unit) {
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
val result = taskRepository.scoreTask(task, direction)
onResult(result)
}
}
var tasks: LiveData<List<Task>>
val taskType = TaskType.from(savedStateHandle.get<String>("task_type"))

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="@color/white" />
</shape>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="@dimen/spacing_medium" />
</shape>

View file

@ -7,6 +7,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Chip">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="@dimen/spacing_medium"
android:background="@drawable/daily_square" />
<TextView
android:id="@+id/title"
android:layout_width="match_parent"

View file

@ -7,6 +7,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Chip">
<ImageView
android:id="@+id/habit_button"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/circle"
android:layout_marginEnd="@dimen/spacing_medium"
/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"

View file

@ -7,6 +7,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Chip">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="@dimen/spacing_medium"
android:background="@drawable/circle"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"