start using local repositories

This commit is contained in:
Phillip Thelen 2022-06-03 16:05:24 +02:00
parent 774a5c9c82
commit b090ac537b
10 changed files with 114 additions and 40 deletions

View file

@ -37,9 +37,11 @@ dependencies {
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.wear:wear:1.2.0'
implementation "androidx.wear:wear-input:1.1.0"
//Networking
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
//REST API handling
implementation('com.squareup.retrofit2:retrofit:2.9.0') {
exclude module: 'okhttp'

View file

@ -6,6 +6,7 @@ import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.api.Server
import com.habitrpg.common.habitica.models.auth.UserAuth
import com.habitrpg.common.habitica.models.auth.UserAuthSocial
import com.habitrpg.wearos.habitica.models.WearableHabitResponse
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.Request
@ -84,18 +85,23 @@ class ApiClient @Inject constructor(
this.apiService = retrofitAdapter.create(ApiService::class.java)
}
suspend fun getUser() = apiService.getUser().data
suspend fun updateUser(data: Map<String, Any>) = apiService.updateUser(data).data
suspend fun sleep() = apiService.sleep().data
suspend fun revive() = apiService.revive().data
private fun <T> process(response: WearableHabitResponse<T>): T? {
return response.data
}
suspend fun loginLocal(auth: UserAuth) = apiService.connectLocal(auth).data
suspend fun loginSocial(auth: UserAuthSocial) = apiService.connectSocial(auth).data
suspend fun getUser() = process(apiService.getUser())
suspend fun updateUser(data: Map<String, Any>) = process(apiService.updateUser(data))
suspend fun sleep() = process(apiService.sleep())
suspend fun revive() = process(apiService.revive())
suspend fun addPushDevice(data: Map<String, String>) = apiService.addPushDevice(data).data
suspend fun removePushDevice(id: String) = apiService.removePushDevice(id).data
suspend fun loginLocal(auth: UserAuth) = process(apiService.connectLocal(auth))
suspend fun loginSocial(auth: UserAuthSocial) = process(apiService.connectSocial(auth))
suspend fun runCron() = apiService.runCron().data
suspend fun addPushDevice(data: Map<String, String>) = process(apiService.addPushDevice(data))
suspend fun removePushDevice(id: String) = process(apiService.removePushDevice(id))
suspend fun getTasks() = apiService.getTasks().data
suspend fun runCron() = process(apiService.runCron())
suspend fun getTasks() = process(apiService.getTasks())
suspend fun scoreTask(id: String, direction: String) = process(apiService.scoreTask(id, direction))
}

View file

@ -41,7 +41,7 @@ interface ApiService {
suspend fun getTask(@Path("id") id: String): WearableHabitResponse<Task>
@POST("tasks/{id}/score/{direction}")
suspend fun postTaskDirection(@Path("id") id: String, @Path("direction") direction: String): WearableHabitResponse<TaskDirectionData>
suspend fun scoreTask(@Path("id") id: String, @Path("direction") direction: String): WearableHabitResponse<TaskDirectionData>
@POST("tasks/bulk-score")
suspend fun bulkScoreTasks(@Body data: List<Map<String, String>>): WearableHabitResponse<BulkTaskScoringData>

View file

@ -1,5 +1,41 @@
package com.habitrpg.wearos.habitica.data.repositories
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asFlow
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.models.tasks.TaskList
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import javax.inject.Inject
import javax.inject.Singleton
class TaskLocalRepository @Inject constructor()
@Singleton
class TaskLocalRepository @Inject constructor() {
private val tasks = mapOf(
TaskType.HABIT to MutableLiveData<List<Task>>(),
TaskType.DAILY to MutableLiveData<List<Task>>(),
TaskType.TODO to MutableLiveData<List<Task>>(),
TaskType.REWARD to MutableLiveData<List<Task>>()
)
fun getTasks(type: TaskType): Flow<List<Task>> {
return tasks[type]?.asFlow() ?: emptyFlow()
}
fun saveTasks(tasks: TaskList) {
val taskMap = mutableMapOf(
TaskType.HABIT to mutableListOf<Task>(),
TaskType.DAILY to mutableListOf<Task>(),
TaskType.TODO to mutableListOf<Task>(),
TaskType.REWARD to mutableListOf<Task>()
)
for (task in tasks.tasks) {
if (task.value.type != null) {
taskMap[task.value.type]?.add(task.value)
}
}
for (type in taskMap) {
this.tasks[type.key]?.value = type.value
}
}
}

View file

@ -1,10 +1,24 @@
package com.habitrpg.wearos.habitica.data.repositories
import com.habitrpg.common.habitica.models.responses.TaskDirection
import com.habitrpg.common.habitica.models.tasks.TaskType
import com.habitrpg.wearos.habitica.data.ApiClient
import com.habitrpg.wearos.habitica.models.tasks.Task
import com.habitrpg.wearos.habitica.models.tasks.TaskList
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class TaskRepository @Inject constructor(val apiClient: ApiClient, val localRepository: TaskLocalRepository) {
suspend fun retrieveTasks() = apiClient.getTasks()
suspend fun retrieveTasks(): TaskList? {
val tasks = apiClient.getTasks()
tasks?.let { localRepository.saveTasks(tasks) }
return tasks
}
fun getTasks(taskType: TaskType): Flow<List<Task>> = localRepository.getTasks(taskType)
suspend fun scoreTask(task: Task, direction: TaskDirection) {
val id = task.id ?: return
val response = apiClient.scoreTask(id, direction.text)
}
}

View file

@ -1,5 +1,20 @@
package com.habitrpg.wearos.habitica.data.repositories
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asFlow
import com.habitrpg.wearos.habitica.models.User
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
import javax.inject.Singleton
class UserLocalRepository @Inject constructor()
@Singleton
class UserLocalRepository @Inject constructor() {
private val user = MutableLiveData<User>()
fun getUser(): Flow<User> {
return user.asFlow()
}
fun saveUser(user: User) {
this.user.value = user
}
}

View file

@ -1,12 +1,23 @@
package com.habitrpg.wearos.habitica.data.repositories
import com.habitrpg.wearos.habitica.data.ApiClient
import com.habitrpg.wearos.habitica.models.User
import javax.inject.Inject
class UserRepository @Inject constructor(val apiClient: ApiClient, val localRepository: UserLocalRepository) {
suspend fun retrieveUser() = apiClient.getUser()
suspend fun updateUser(data: Map<String, Any>) = apiClient.updateUser(data)
fun getUser() = localRepository.getUser()
suspend fun retrieveUser(): User? {
val user = apiClient.getUser()
user?.let { localRepository.saveUser(it) }
return user
}
suspend fun updateUser(data: Map<String, Any>): User? {
val user = apiClient.updateUser(data)
user?.let { localRepository.saveUser(it) }
return user
}
suspend fun sleep() = apiClient.sleep()
suspend fun revive() = apiClient.revive()

View file

@ -1,13 +1,11 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.asLiveData
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
import com.habitrpg.wearos.habitica.models.User
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
@ -18,12 +16,9 @@ class AvatarViewModel @Inject constructor(
userRepository,
exceptionBuilder
) {
val _user = MutableLiveData<User>()
val user: LiveData<User> = _user
var user: LiveData<User>
init {
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_user.value = userRepository.retrieveUser()
}
user = userRepository.getUser().asLiveData()
}
}

View file

@ -1,8 +1,9 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.habitrpg.wearos.habitica.data.repositories.TaskRepository
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
import com.habitrpg.wearos.habitica.models.User
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
@ -13,14 +14,16 @@ import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
userRepository: UserRepository,
val taskRepository: TaskRepository,
exceptionBuilder: ExceptionHandlerBuilder
) : BaseViewModel(userRepository, exceptionBuilder) {
val _user = MutableLiveData<User>()
val user: LiveData<User> = _user
var user: LiveData<User>
init {
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_user.value = userRepository.retrieveUser()
user = userRepository.getUser().asLiveData()
viewModelScope.launch {
userRepository.retrieveUser()
taskRepository.retrieveTasks()
}
}
}

View file

@ -1,16 +1,14 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.asLiveData
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
@ -20,16 +18,10 @@ class TaskListViewModel @Inject constructor(
userRepository: UserRepository,
exceptionBuilder: ExceptionHandlerBuilder
) : BaseViewModel(userRepository, exceptionBuilder) {
val _tasks = MutableLiveData<List<Task>>()
val tasks: LiveData<List<Task>> = _tasks
var tasks: LiveData<List<Task>>
val taskType = TaskType.from(savedStateHandle.get<String>("task_type"))
init {
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_tasks.value = taskRepository.retrieveTasks()?.tasks?.values?.filter {
it.type == taskType
}?.toList()
}
tasks = taskRepository.getTasks(taskType ?: TaskType.HABIT).asLiveData()
}
}