Skip to content

Instantly share code, notes, and snippets.

View gab-stargazer's full-sized avatar
🌟
Happy

LeleStacia gab-stargazer

🌟
Happy
  • TheLorry Indonesia
  • Jambi, Indonesia
  • 20:16 (UTC +07:00)
  • LinkedIn in/kamil-malik
View GitHub Profile
@gab-stargazer
gab-stargazer / Snackbar-Manager-Compose.md
Last active July 22, 2024 08:55
This is how to provide a single source for managing snackbar in compose, including on how to make queue system

The Problem in Compose

If you ever use Jetpack Compose, you will probably know how hard it is to use snackbar. Because in Compose, Snackbar require a Host, and a State. Unlike in Android XML, we can just refer any UI part as a snackbar Host, but in Compose, we require specific Component for it so called SnackbarHost which usually placed in a Scaffold Snackbar Slot.

The Solution

In order to solve this problem, we need a way where we can provide Snackbar Host into the Child composable without the need to pass it as a parameter in composable function. Therefore, we're gonna utilize Compose feature, which is Composition Local Provider that was able to provide specific stuff into it's composable Tree, and we're gonna make a custom class to manage this Queue System utilizing Java LinkedList and a Mutex in order to prevent value loss due to concurrency.

The Snackbar Manager

A custom class is required for this in order to make a queue system. Use the code below to achieve the behavior.

@gab-stargazer
gab-stargazer / adapter
Last active January 26, 2024 07:34
Dynamic Recyclerview Adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
class DynamicAdapter<T : Any, VB : ViewBinding>(
private val inflate: (LayoutInflater, ViewGroup, Boolean) -> VB,
@gab-stargazer
gab-stargazer / collectInLaunchedEffectWithLifecycle.txt
Last active December 6, 2023 11:24
Handle Flow On LaunchedEffect with Jetpack Compose
@Composable
inline fun <reified T> Flow<T>.CollectInLaunchEffect(
key: Any,
noinline block: suspend (T) -> Unit
) {
val lifeCycle = LocalLifecycleOwner.current.lifecycle
LaunchedEffect(key1 = key) {
lifeCycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
this@CollectInLaunchEffect.collectLatest(block)
}
@gab-stargazer
gab-stargazer / calculator.kt
Created September 22, 2023 12:47
Basic Calculator
fun main(args: Array<String>) {
println("Basic Calculator")
val firstNumber: Number?
val secondNumber: Number?
val operation: String?
while (true) {
print("Input first Number: ")
val input = readln()
@gab-stargazer
gab-stargazer / Function for Parsing Error Resposne from JSON
Last active January 23, 2023 14:44
This function is for parsing Error Response from Json by using custom class for deserialization for specific error response by using custom class for deserialization JSON. Replace ErrorResponse::class.java with your own custom class. One thing to note is JSON can only be used once, so if you want to reuse it then store the JSON on a variable.
private fun parseHttpError(t: HttpException): String {
val body = t.response()?.errorBody()
val gson = Gson()
val adapter: TypeAdapter<ErrorResponse> = gson.getAdapter(ErrorResponse::class.java)
return try {
val error = adapter.fromJson(body?.string())
"Error ${error.status}: ${error.message}"
} catch (e: Exception) {
"Response failed to parse"
}