forked from Writand/writand
feat: added a launchCatching
This commit is contained in:
parent
273c36d2f8
commit
3b95fffad8
2 changed files with 84 additions and 0 deletions
41
app/src/main/java/be/re/writand/screens/WViewModel.kt
Normal file
41
app/src/main/java/be/re/writand/screens/WViewModel.kt
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package be.re.writand.screens
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import be.re.writand.utils.SnackbarManager
|
||||||
|
import be.re.writand.utils.SnackbarMessage.Companion.toSnackbarMessage
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom viewmodel class for this app.
|
||||||
|
*/
|
||||||
|
class WViewModel : ViewModel() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to launch a suspended function in viewmodel scope.
|
||||||
|
* This function catches possible errors and displays them as a snackbar message.
|
||||||
|
* @param[snackbar] controls if a snackbar must be shown or not.
|
||||||
|
* @param[finally] a lambda-function to execute after the [block] is executed.
|
||||||
|
* @param[block] the code that must be executed in a Coroutine-context.
|
||||||
|
*/
|
||||||
|
fun launchCatching(
|
||||||
|
snackbar: Boolean = true,
|
||||||
|
finally: () -> Unit = {},
|
||||||
|
block: suspend CoroutineScope.() -> Unit
|
||||||
|
) =
|
||||||
|
viewModelScope.launch(
|
||||||
|
CoroutineExceptionHandler { _, throwable ->
|
||||||
|
finally()
|
||||||
|
if (snackbar) {
|
||||||
|
SnackbarManager.showMessage(throwable.toSnackbarMessage())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
block = {
|
||||||
|
block()
|
||||||
|
finally()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
43
app/src/main/java/be/re/writand/utils/SnackbarManager.kt
Normal file
43
app/src/main/java/be/re/writand/utils/SnackbarManager.kt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package be.re.writand.utils
|
||||||
|
|
||||||
|
import be.re.writand.utils.SnackbarMessage.Companion.toSnackbarMessage
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a message to be shown inside a snackbar.
|
||||||
|
*/
|
||||||
|
sealed class SnackbarMessage {
|
||||||
|
class StringSnackbar(val message: String) : SnackbarMessage()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun Throwable.toSnackbarMessage(): String {
|
||||||
|
return this.message.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SnackbarMessage.toMessage(): String {
|
||||||
|
return when (this) {
|
||||||
|
is StringSnackbar -> this.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual manager of the snackbar's messages.
|
||||||
|
*/
|
||||||
|
object SnackbarManager {
|
||||||
|
private val messages: MutableStateFlow<SnackbarMessage?> = MutableStateFlow(null)
|
||||||
|
val snackbarMessages: StateFlow<SnackbarMessage?>
|
||||||
|
get() = messages.asStateFlow()
|
||||||
|
|
||||||
|
fun showMessage(message: String) {
|
||||||
|
messages.value = SnackbarMessage.StringSnackbar(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showMessage(message: Throwable) {
|
||||||
|
messages.value = SnackbarMessage.StringSnackbar(message.toSnackbarMessage())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue