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