mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-23 22:27:15 +00:00
Merge pull request #1815 from Hafizzle/Hafiz/todo-wear-fixes
Show all to-dos and reset after cron
This commit is contained in:
commit
95ec04bd70
5 changed files with 102 additions and 27 deletions
|
|
@ -45,19 +45,24 @@ class AppModule {
|
|||
}
|
||||
|
||||
@Provides
|
||||
fun providesConverterFactory(): Converter.Factory {
|
||||
fun providesConverterFactory(moshi: Moshi): Converter.Factory {
|
||||
return MoshiConverterFactory.create(
|
||||
Moshi.Builder()
|
||||
.add(WrappedTasklistAdapter())
|
||||
.add(customDateAdapter)
|
||||
.add(FrequencyAdapter())
|
||||
.add(TaskTypeAdapter())
|
||||
.add(AttributeAdapter())
|
||||
.addLast(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
moshi
|
||||
).asLenient()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesMoshi(): Moshi {
|
||||
return Moshi.Builder()
|
||||
.add(WrappedTasklistAdapter())
|
||||
.add(customDateAdapter)
|
||||
.add(FrequencyAdapter())
|
||||
.add(TaskTypeAdapter())
|
||||
.add(AttributeAdapter())
|
||||
.addLast(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesApiHClient(
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ class TaskListActivity : BaseActivity<ActivityTasklistBinding, TaskListViewModel
|
|||
}
|
||||
|
||||
viewModel.tasks.observe(this) {
|
||||
adapter.data = it
|
||||
if (!it.isNullOrEmpty()) {
|
||||
adapter.data = it
|
||||
}
|
||||
}
|
||||
viewModel.taskCount.observe(this) {
|
||||
adapter.title = getTitle(it)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.habitrpg.common.habitica.models.responses.TaskDirection
|
||||
|
|
@ -19,6 +21,7 @@ import javax.inject.Inject
|
|||
class RYAViewModel @Inject constructor(
|
||||
userRepository: UserRepository,
|
||||
taskRepository: TaskRepository,
|
||||
val sharedPreferences: SharedPreferences,
|
||||
exceptionBuilder: ExceptionHandlerBuilder, appStateManager: AppStateManager
|
||||
) : BaseViewModel(userRepository, taskRepository, exceptionBuilder, appStateManager) {
|
||||
var hasRunCron: Boolean = false
|
||||
|
|
@ -50,6 +53,8 @@ class RYAViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun runCron(function: (Boolean) -> Unit) {
|
||||
//Clear shared pref values for saved to-do tasks
|
||||
sharedPreferences.edit { putString("to_do_tasks", null) }
|
||||
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
|
||||
appStateManager.startLoading()
|
||||
for (task in tasksToComplete) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.asLiveData
|
||||
|
|
@ -12,11 +14,15 @@ import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
|||
import com.habitrpg.wearos.habitica.managers.AppStateManager
|
||||
import com.habitrpg.wearos.habitica.models.tasks.Task
|
||||
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.reflect.Type
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -24,26 +30,27 @@ class TaskListViewModel @Inject constructor(
|
|||
savedStateHandle: SavedStateHandle,
|
||||
taskRepository: TaskRepository,
|
||||
userRepository: UserRepository,
|
||||
val sharedPreferences: SharedPreferences,
|
||||
moshi: Moshi,
|
||||
exceptionBuilder: ExceptionHandlerBuilder, appStateManager: AppStateManager
|
||||
) : BaseViewModel(userRepository, taskRepository, exceptionBuilder, appStateManager) {
|
||||
var type: Type = Types.newParameterizedType(
|
||||
MutableList::class.java,
|
||||
Task::class.java
|
||||
)
|
||||
private val moshiAdapter: JsonAdapter<MutableList<Task>> = moshi.adapter(type)
|
||||
val taskType = TaskType.from(savedStateHandle.get<String>("task_type"))
|
||||
val taskCount = MutableLiveData(0)
|
||||
val completedToDos: MutableList<Task> by lazy {
|
||||
val tasksString = sharedPreferences.getString("to_do_tasks", null) ?: return@lazy mutableListOf()
|
||||
return@lazy moshiAdapter.fromJson(tasksString) ?: mutableListOf()
|
||||
}
|
||||
val tasks = taskRepository.getTasks(taskType ?: TaskType.HABIT)
|
||||
.map {
|
||||
if (taskType == TaskType.DAILY || taskType == TaskType.TODO) {
|
||||
val taskList: MutableList<Any> = it.filter { it.isDue == true || it.type == TaskType.TODO }.sortedBy { it.completed }.toMutableList()
|
||||
val firstCompletedIndex = taskList.indexOfFirst { it is Task && it.completed }
|
||||
if (firstCompletedIndex >= 0) {
|
||||
// since this is the index of the first completed task, this is also the number of incomplete tasks
|
||||
taskCount.value = firstCompletedIndex
|
||||
taskList.add(firstCompletedIndex, "Done today")
|
||||
} else {
|
||||
taskCount.value = taskList.size
|
||||
}
|
||||
taskList
|
||||
} else {
|
||||
taskCount.value = it.size
|
||||
it
|
||||
when(taskType) {
|
||||
TaskType.DAILY -> mapDaily(it)
|
||||
TaskType.TODO -> mapTodos(it)
|
||||
else -> map(it)
|
||||
}
|
||||
}
|
||||
.asLiveData()
|
||||
|
|
@ -51,7 +58,22 @@ class TaskListViewModel @Inject constructor(
|
|||
.asLiveData()
|
||||
|
||||
fun scoreTask(task: Task, direction: TaskDirection, onResult: (TaskScoringResult?) -> Unit) {
|
||||
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
|
||||
if (taskType == TaskType.TODO) {
|
||||
if (direction == TaskDirection.UP) {
|
||||
completedToDos.add(task)
|
||||
} else {
|
||||
completedToDos.remove(task)
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(exceptionBuilder.userFacing(this) {
|
||||
if (taskType == TaskType.TODO) {
|
||||
if (direction == TaskDirection.UP) {
|
||||
completedToDos.remove(task)
|
||||
} else {
|
||||
completedToDos.add(task)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
val result = taskRepository.scoreTask(
|
||||
userRepository.getUser().first(),
|
||||
task,
|
||||
|
|
@ -65,4 +87,45 @@ class TaskListViewModel @Inject constructor(
|
|||
onResult(result)
|
||||
}
|
||||
}
|
||||
|
||||
private fun map(tasks: List<Task>): List<Task> {
|
||||
taskCount.value = tasks.size
|
||||
return tasks
|
||||
}
|
||||
|
||||
private fun mapDaily(tasks: List<Task>): MutableList<Any> {
|
||||
val taskList: MutableList<Any> = tasks.filter { it.isDue == true || it.type == TaskType.TODO }.sortedBy { it.completed }.toMutableList()
|
||||
val firstCompletedIndex = taskList.indexOfFirst { it is Task && it.completed }
|
||||
if (firstCompletedIndex >= 0) {
|
||||
// since this is the index of the first completed task, this is also the number of incomplete tasks
|
||||
taskCount.value = firstCompletedIndex
|
||||
taskList.add(firstCompletedIndex, "Done today")
|
||||
} else {
|
||||
taskCount.value = taskList.size
|
||||
}
|
||||
return taskList
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
saveCurrentToDos()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun mapTodos(tasks: List<Task>): List<Any> {
|
||||
val taskList: MutableList<Any> = tasks.filter { !it.completed }.toMutableList()
|
||||
taskCount.value = taskList.size
|
||||
if (completedToDos.isNotEmpty()) {
|
||||
taskList.add("Done today")
|
||||
taskList.addAll(completedToDos)
|
||||
}
|
||||
|
||||
return taskList
|
||||
}
|
||||
|
||||
private fun saveCurrentToDos() {
|
||||
sharedPreferences.edit {
|
||||
putString("to_do_tasks", moshiAdapter.toJson(completedToDos))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ class ExceptionHandlerBuilder @Inject constructor(val appStateManager: AppStateM
|
|||
}
|
||||
}
|
||||
|
||||
fun userFacing(errorPresenter: ErrorPresenter): CoroutineExceptionHandler {
|
||||
fun userFacing(errorPresenter: ErrorPresenter, handler: ((Throwable) -> Unit)? = null): CoroutineExceptionHandler {
|
||||
return CoroutineExceptionHandler { _, throwable ->
|
||||
Log.e("Coroutine Error", "Error: ${throwable.cause}", throwable)
|
||||
if (throwable is IOException) {
|
||||
|
|
@ -30,7 +30,7 @@ class ExceptionHandlerBuilder @Inject constructor(val appStateManager: AppStateM
|
|||
DisplayedError(R.drawable.error, it)
|
||||
}
|
||||
}
|
||||
|
||||
handler?.invoke(throwable)
|
||||
appStateManager.endLoading()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue