Snook A Look, Compose Multiplatform components
Five pieces of production code from the live Snook A Look app, extracted and written up as standalone components.

The components
iOS-like predictive back
compose-predictive-back-parallax
Decompose's predictive back gesture driving an iOS-style transition: the screen follows the finger, the previous screen parallaxes in from minus 30 percent, and a scrim fades out. A cancelled swipe springs back from exactly where the finger left.
Code and write-up on GitHuboverride val exitModifier: Modifier
get() = Modifier.graphicsLayer {
// Active screen follows finger: 0% → 100% of its own width
translationX = rawProgress * size.width
}
override val enterModifier: Modifier
get() = Modifier
.graphicsLayer {
// Previous screen parallaxes from -30% at rest toward 0 on complete
translationX = (1f - rawProgress) * (-0.30f * size.width)
}
.drawWithContent {
drawContent()
// Scrim fades from 40% at rest to 0 as gesture progresses
val scrimAlpha = (1f - rawProgress) * scrimColor.alpha
if (scrimAlpha > 0f) {
drawRect(color = scrimColor.copy(alpha = scrimAlpha))
}
}Lifecycle-safe iOS camera bridge
kmp-ios-camera-bridge
The native UIImagePickerController bridged into Compose: the delegate is retained in Compose state so Kotlin/Native cannot collect it, state is written only after the dismiss animation finishes, and resizing runs off the main thread.
Code and write-up on GitHuboverride fun imagePickerController(
picker: UIImagePickerController,
didFinishPickingMediaWithInfo: Map<Any?, *>,
) {
val image = didFinishPickingMediaWithInfo[UIImagePickerControllerOriginalImage] as? UIImage
// Capture image ref BEFORE dismiss; move delegate cleanup + encode INSIDE
// completion so capturedBytes is only written after the dismiss animation
// fully finishes, prevents UIKit "presentation in progress" collision
// when Compose consent AlertDialog tries to present mid-dismiss.
picker.dismissViewControllerAnimated(true) {
picker.delegate = null
retainedDelegate = null
if (image != null) {Mapbox in a WKWebView, sharing KMP state
kmp-ios-mapbox-webview-bridge
mapbox-gl-js inside a WKWebView instead of the native SDK: markers, theme and user location flow in from shared Kotlin state through JavaScript, so the camera never reloads mid-flight.
Code and write-up on GitHubval html = remember(isLight) { buildMapHtml(isLight, MapPoseSession.last) }
val readyFlow = remember { MutableStateFlow(false) }
var webViewRef by remember { mutableStateOf<WKWebView?>(null) }
val currentUserLoc by rememberUpdatedState(userLocation)
val currentIsOutsideUae by rememberUpdatedState(isOutsideUae)
// Inject / refresh markers when centers change. Map state preserved.
LaunchedEffect(centers) {
readyFlow.first { it }
val webView = webViewRef ?: return@LaunchedEffect
val markersJson = buildMarkersJson(centers)
webView.evaluateJavaScript("snookSetMarkers($markersJson);", null)
}Cinematic map intro, as a state machine
kmp-map-choreography
A four-beat Mapbox camera intro, from country overview to the Dubai cluster to the user, that survives late GPS, users outside the UAE and mid-flight drags. Camera requests are serialised through one channel that defers to the intro.
Code and write-up on GitHubobject MapCameraRequestChannel {
data class Target(
val lat: Double,
val lng: Double,
val zoom: Double,
val durationMs: Int,
)
private val _requests = MutableSharedFlow<Target>(
replay = 0,
extraBufferCapacity = 4,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)
val requests: SharedFlow<Target> = _requests.asSharedFlow()
fun request(lat: Double, lng: Double, zoom: Double = 14.0, durationMs: Int = 2000) {
_requests.tryEmit(Target(lat, lng, zoom, durationMs))
}Apple Sign-In on Android
kmp-android-apple-signin
Sign in with Apple through Chrome Custom Tabs: shared code suspends on a continuation keyed by the OAuth state, and the redirect resumes it, even if the OS killed the app in between.
Code and write-up on GitHubobject AppleAuthRegistry {
private val pending = ConcurrentHashMap<String, CancellableContinuation<AppleAuthArtifact>>()
fun newState(): String = UUID.randomUUID().toString()
suspend fun await(state: String): AppleAuthArtifact = suspendCancellableCoroutine { cont ->
pending[state] = cont
cont.invokeOnCancellation { pending.remove(state) }
}
fun resume(state: String, artifact: AppleAuthArtifact) {
pending.remove(state)?.resume(artifact)
}
fun cancel(state: String) {
pending.remove(state)?.resumeWithException(
OAuthFlowException(OAuthErrorCode.USER_CANCELLED),
)
}
fun isPending(state: String): Boolean = pending.containsKey(state)
}