Skip to content

Instantly share code, notes, and snippets.

View NikolaDespotoski's full-sized avatar

Nikola Despotoski NikolaDespotoski

View GitHub Profile
@NikolaDespotoski
NikolaDespotoski / generate-proguard-from-apidump.kt
Last active October 10, 2025 14:20
Generate proguard rules out of output of apiDump task of Kotlin binary compatibility plugin
tasks.register("updateProguardFromApiDump") {
group = "verification"
description =
"Updates proguard-rules.pro with -keep rules for public classes found in a .api dump (default: uses the first .api file under api/)."
dependsOn("apiDump")
doLast {
val apiDir = file("api")
val proguardFile = file("proguard-rules.pro")
val apiFilePath = if (project.hasProperty("apiFile")) project.property("apiFile") else null
@Composable
fun SampleScreen(modifier: Modifier = Modifier) {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
//when modifierLocalConsumer { } block is called, next composition
// will make this local prop non null.
val myScope by remember { mutableStateOf<MyScope?>(null) }
Column {
MyLayout(
modifier = Modifier
.padding(innerPadding)
val ModifierLocalMyScope =
modifierLocalOf<MyScope> { error("Scope not provided") }
@Composable
fun MyLayout(
modifier: Modifier = Modifier,
properties: MyProperties = MyProperties(),
colors: MyLayoutColors = MyLayoutDefaults.colors(),
content: @Composable (MyScope.() -> Unit)
) {
@NikolaDespotoski
NikolaDespotoski / LayoutModifierKtx.kt
Last active August 17, 2024 14:35
Search for largest composable parent given a selector
/**
* Searches largest parent with [LayoutCoordinates]
*
* @param selector property selector
*
* @return Largest parent in the tree [LayoutCoordinates] starting from calling
* receiver and searching up the tree until the last parent is visited. If receiver object doesn't
* have parent, it assumes this is the max.
*/
inline fun <reified P : Comparable<P>> LayoutCoordinates.maxOf(selector: LayoutCoordinates.() -> P): LayoutCoordinates {
@file:OptIn(ExperimentalComposeUiApi::class)
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.RawRes
import androidx.annotation.StringRes
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerInputChange
/**
* Should warn when making unattended a viewmodel function in a composable without considering
* potential recompositions
*
* Should warn when:
*
* @Composable
* fun MyComposable(viewModel : MyViewModel) {
*
* viewModel.startOperation()
@NikolaDespotoski
NikolaDespotoski / TintModifier.kt
Last active June 28, 2023 21:49
Compose tint modifier that will apply color tint over composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
@NikolaDespotoski
NikolaDespotoski / CameraControllCompose.kt
Created March 4, 2023 16:34
Exposing CameraController in Compose.
import androidx.camera.core.CameraSelector
import androidx.camera.view.CameraController
import androidx.camera.view.LifecycleCameraController
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@NikolaDespotoski
NikolaDespotoski / MlKitAnalyzerKtx.kt
Created November 22, 2022 17:49
Convert MlKitAnalyzer.Result into kotlin.Result so you can utilize kotlin's Result API
/**
* Converts [MlKitAnalyzer.Result] into [kotlin.Result]
* @param detector Any [Detector]
* @returns [kotlin.Result]
*/
fun <T> MlKitAnalyzer.Result.toResult(detector: Detector<T>): Result<T> =
kotlin.runCatching {
val value = getValue(detector) ?: throw getThrowable(detector)!!
value
}
@NikolaDespotoski
NikolaDespotoski / CancelFlow.kt
Created April 12, 2022 00:00
cancelWhen operator for Kotlin Flow
/**
* Cancels current flow when the predicate is matched, throws [CancellationException] up in
* current coroutine.
* @param cause class that will be used as cause for [CancellationException]
* @param predicate if result of this function is [true] then the flow is stopped
*/
inline fun <T> Flow<T>.cancelWhen(
cause: KClass<out Throwable>? = null,
crossinline predicate: (T) -> Boolean
): Flow<T> = transform {