diff --git a/wearos/src/main/AndroidManifest.xml b/wearos/src/main/AndroidManifest.xml
index 0e6bed31a..a821035ac 100644
--- a/wearos/src/main/AndroidManifest.xml
+++ b/wearos/src/main/AndroidManifest.xml
@@ -37,6 +37,7 @@
+
\ No newline at end of file
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/models/DisplayedError.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/models/DisplayedError.kt
new file mode 100644
index 000000000..0626da42b
--- /dev/null
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/models/DisplayedError.kt
@@ -0,0 +1,3 @@
+package com.habitrpg.wearos.habitica.models
+
+data class DisplayedError(val title: String)
\ No newline at end of file
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/AvatarActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/AvatarActivity.kt
index c6473abde..525698f29 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/AvatarActivity.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/AvatarActivity.kt
@@ -7,8 +7,8 @@ import com.habitrpg.wearos.habitica.ui.viewmodels.AvatarViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
-class AvatarActivity: BaseActivity() {
- val viewModel: AvatarViewModel by viewModels()
+class AvatarActivity: BaseActivity() {
+ override val viewModel: AvatarViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivityAvatarBinding.inflate(layoutInflater)
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt
index 1b4b30da7..707eae5f0 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/BaseActivity.kt
@@ -1,14 +1,27 @@
package com.habitrpg.wearos.habitica.ui.activities
+import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.viewbinding.ViewBinding
+import androidx.wear.activity.ConfirmationActivity
+import com.habitrpg.wearos.habitica.ui.viewmodels.BaseViewModel
-open class BaseActivity : ComponentActivity() {
+abstract class BaseActivity : ComponentActivity() {
protected lateinit var binding: B
+ abstract val viewModel: VM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
+
+ viewModel.errorValues.observe(this) {
+ val intent = Intent(this, ConfirmationActivity::class.java).apply {
+ putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.FAILURE_ANIMATION)
+ putExtra(ConfirmationActivity.EXTRA_MESSAGE, it.title)
+ putExtra(ConfirmationActivity.EXTRA_ANIMATION_DURATION_MILLIS, 3000)
+ }
+ startActivity(intent)
+ }
}
}
\ No newline at end of file
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/MainActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/MainActivity.kt
index 1ddca6f42..f31e7cc9c 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/MainActivity.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/MainActivity.kt
@@ -26,8 +26,8 @@ data class MenuItem(
)
@AndroidEntryPoint
-class MainActivity : BaseActivity() {
- val viewModel: MainViewModel by viewModels()
+class MainActivity : BaseActivity() {
+ override val viewModel: MainViewModel by viewModels()
private val adapter = HubAdapter()
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt
index a65da21d0..c7f82d1de 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/activities/TaskListActivity.kt
@@ -11,9 +11,9 @@ import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
-class TaskListActivity: BaseActivity() {
+class TaskListActivity: BaseActivity() {
private val adapter = TaskListAdapter()
- private val viewModel: TaskListViewModel by viewModels()
+ override val viewModel: TaskListViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivityTasklistBinding.inflate(layoutInflater)
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt
index 36cf02489..685606f1c 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/AvatarViewModel.kt
@@ -5,17 +5,24 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
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
-class AvatarViewModel @Inject constructor(userRepository: UserRepository) : BaseViewModel(userRepository) {
+class AvatarViewModel @Inject constructor(
+ userRepository: UserRepository,
+ exceptionBuilder: ExceptionHandlerBuilder
+) : BaseViewModel(
+ userRepository,
+ exceptionBuilder
+) {
val _user = MutableLiveData()
val user: LiveData = _user
init {
- viewModelScope.launch {
+ viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_user.value = userRepository.retrieveUser()
}
}
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/BaseViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/BaseViewModel.kt
index 747aaa515..2130e1980 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/BaseViewModel.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/BaseViewModel.kt
@@ -1,6 +1,15 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
+import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
+import com.habitrpg.wearos.habitica.models.DisplayedError
+import com.habitrpg.wearos.habitica.util.ErrorPresenter
+import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
-open class BaseViewModel(val userRepository: UserRepository): ViewModel()
\ No newline at end of file
+open class BaseViewModel(
+ val userRepository: UserRepository,
+ val exceptionBuilder: ExceptionHandlerBuilder
+): ViewModel(), ErrorPresenter {
+ override val errorValues = MutableLiveData()
+}
\ No newline at end of file
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt
index 997c6f6c9..649111ff9 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/MainViewModel.kt
@@ -5,17 +5,21 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
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
-class MainViewModel @Inject constructor(userRepository: UserRepository) : BaseViewModel(userRepository) {
+class MainViewModel @Inject constructor(
+ userRepository: UserRepository,
+ exceptionBuilder: ExceptionHandlerBuilder
+) : BaseViewModel(userRepository, exceptionBuilder) {
val _user = MutableLiveData()
val user: LiveData = _user
init {
- viewModelScope.launch {
+ viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_user.value = userRepository.retrieveUser()
}
}
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt
index 12dae28ad..50d786ca8 100644
--- a/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/ui/viewmodels/TaskListViewModel.kt
@@ -8,6 +8,7 @@ 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
@@ -16,15 +17,16 @@ import javax.inject.Inject
class TaskListViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
private val taskRepository: TaskRepository,
- userRepository: UserRepository
-) : BaseViewModel(userRepository) {
+ userRepository: UserRepository,
+ exceptionBuilder: ExceptionHandlerBuilder
+) : BaseViewModel(userRepository, exceptionBuilder) {
val _tasks = MutableLiveData>()
val tasks: LiveData> = _tasks
val taskType = TaskType.from(savedStateHandle.get("task_type"))
init {
- viewModelScope.launch {
+ viewModelScope.launch(exceptionBuilder.userFacing(this)) {
_tasks.value = taskRepository.retrieveTasks()?.tasks?.values?.filter {
it.type == taskType
}?.toList()
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/data/DateJSONAdapter.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/DateJSONAdapter.kt
similarity index 100%
rename from wearos/src/main/java/com/habitrpg/wearos/habitica/data/DateJSONAdapter.kt
rename to wearos/src/main/java/com/habitrpg/wearos/habitica/util/DateJSONAdapter.kt
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ErrorPresenter.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ErrorPresenter.kt
new file mode 100644
index 000000000..1383598e9
--- /dev/null
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/ErrorPresenter.kt
@@ -0,0 +1,8 @@
+package com.habitrpg.wearos.habitica.util
+
+import androidx.lifecycle.MutableLiveData
+import com.habitrpg.wearos.habitica.models.DisplayedError
+
+interface ErrorPresenter {
+ val errorValues: MutableLiveData
+}
diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/util/HabiticaCoroutineExceptionhandler.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/HabiticaCoroutineExceptionhandler.kt
new file mode 100644
index 000000000..5351ba9d3
--- /dev/null
+++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/util/HabiticaCoroutineExceptionhandler.kt
@@ -0,0 +1,22 @@
+package com.habitrpg.wearos.habitica.util
+
+import android.util.Log
+import com.habitrpg.wearos.habitica.models.DisplayedError
+import dagger.hilt.android.scopes.ViewModelScoped
+import kotlinx.coroutines.CoroutineExceptionHandler
+import javax.inject.Inject
+
+@ViewModelScoped
+class ExceptionHandlerBuilder @Inject constructor() {
+ fun silent(): CoroutineExceptionHandler {
+ return CoroutineExceptionHandler { context, throwable ->
+ Log.e(context.toString(), "Error: ${throwable.cause}", throwable)
+ }
+ }
+
+ fun userFacing(errorPresenter: ErrorPresenter): CoroutineExceptionHandler {
+ return CoroutineExceptionHandler { _, throwable ->
+ errorPresenter.errorValues.value = throwable.message?.let { DisplayedError(it) }
+ }
+ }
+}
\ No newline at end of file