Skip to content

Instantly share code, notes, and snippets.

View zach-klippenstein's full-sized avatar

Zach Klippenstein zach-klippenstein

View GitHub Profile
@zach-klippenstein
zach-klippenstein / ThrottledMutableState.kt
Created June 25, 2024 23:38
A sketch of a Compose MutableState object that only accepts writes that happen after a certain time after the previously-accepted write. Writes that happen too quickly are ignored. Inspired by https://x.com/pablisc0/status/1793599496305483881
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.SnapshotMutationPolicy
import androidx.compose.runtime.structuralEqualityPolicy
/**
* Returns a [MutableState] object that only accepts writes that happen [debounceMillis] after the
* previously-accepted write. Writes that happen less than [debounceMillis] after a previous write
* are ignored.
*
* Write times are determined using [System.currentTimeMillis].
@zach-klippenstein
zach-klippenstein / emulator-jank.sh
Last active January 11, 2024 22:19
Shell script to trigger some jank in the Android emulator.
#!/bin/bash
# Tells an Android emulator to take a snapshot of itself and then
# delete that snapshot immediately. The act of taking a snapshot
# forces the emulator to temporarily pause and trigger unexpected
# system behaviors. When it happens during a test run, it can
# trigger certain hard-to-reproduce flakes.
SNAPSHOT=__TEMPORARY_SNAPSHOT
AUTH="$(cat ~/.emulator_console_auth_token)"
PORT=$1
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun App() {
Column {
MarxistRow {
Text("Left Text", Modifier.background(Color.Red))
Text("Right Text", Modifier.background(Color.Blue))
}
MarxistRow {
@zach-klippenstein
zach-klippenstein / CursedButtons.kt
Last active October 20, 2022 18:38
Code for twitter thread about why onClick handlers don't let you emit composables. https://twitter.com/zachklipp/status/1583165356322930688
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@zach-klippenstein
zach-klippenstein / ComicBookApp.kt
Created April 12, 2022 06:40
Demo app with a modifier that renders its node as comic book-style dots.
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Checkbox
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
@zach-klippenstein
zach-klippenstein / comic-book-shader.sksl
Last active April 12, 2022 06:09
SkSL shader program to render a comic-book style effect.
// Paste this code into shaders.skia.org
float tileSize = 12;
float dotMinDiameter = 9;
vec2 maxRedShift = vec2(-2, 3);
vec2 maxGreenShift = vec2(2.5, 0);
vec2 maxBlueShift = vec2(1, -2);
half3 baseColor = half3(0, 0, 0);
half4 main(vec2 fragcoord) {
fun Modifier.saturate(saturation: Float): Modifier =
drawWithCache {
// Cache the paint object so it can be reused between draw calls.
val contentPaint = Paint().apply {
colorFilter = ColorFilter.saturate(saturation)
}
onDrawWithContent {
drawIntoCanvas {
it.saveLayer(Rect(Offset.Zero, size), contentPaint)
@zach-klippenstein
zach-klippenstein / ChipInput.kt
Last active January 25, 2022 00:21
Sketch of a possible chip input implementation
@Composable fun <C> ChipField(
chips: List<C>,
chipContent: @Composable (C) -> Unit.
modifier: Modifier = Modifier
) {
SelectionContainer(
allowCursor = true,
// some sort of callback or hoisted state for reading/mutating selection
modifier.textFieldFocusable()
) {
@zach-klippenstein
zach-klippenstein / Blockify.kt
Last active March 22, 2024 21:47
A Compose modifier to turn your apps into blocks (no, this has nothing to do with NFTs)
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.integration.demos.BlockFilter.Companion.Lighting
@zach-klippenstein
zach-klippenstein / ContextConfigThemeWrapper.kt
Created May 13, 2021 20:09
Custom fork of ContextThemeWrapper that does some extra stuff to support overriding configurations better.
/**
* Fork of AppCompat ContextThemeWrapper (barely) to correctly support applying override
* configurations – all the features we don't need are dropped, it always extends the base context's
* theme, the theme can't be set explicitly, and it adds one critical piece of functionality: the new
* theme is [rebased][Theme.rebase] after being cloned from the base context's theme.
*/
open class ContextConfigThemeWrapper(
base: Context,
private val overrideConfiguration: Configuration
) : ContextWrapper(base) {