Skip to content

Instantly share code, notes, and snippets.

View skydoves's full-sized avatar
💡
Practice is the only shortcut

Jaewoong Eum skydoves

💡
Practice is the only shortcut
View GitHub Profile
@skydoves
skydoves / MigrationFromCoil.kt
Created January 4, 2026 08:58
Landscapist: Migration from Coil
// Before: Coil
CoilImage(
model = imageUrl,
contentDescription = "Photo",
component = rememberImageComponent {
+ShimmerPlugin()
+CrossfadePlugin()
}
)
@skydoves
skydoves / MigrationFromGlide.kt
Created January 4, 2026 08:58
Landscapist: Migration from Glide
// Before: Glide
GlideImage(
model = imageUrl,
contentDescription = "Photo",
modifier = Modifier.size(200.dp)
)
// After: LandscapistImage (same API)
LandscapistImage(
model = imageUrl,
@skydoves
skydoves / ExpectActualPattern.kt
Created January 4, 2026 08:58
Landscapist: Expect/Actual Pattern
// commonMain: Define expected interface
expect fun createPlatformLandscapist(): Landscapist
// androidMain: Provide Android implementation
actual fun createPlatformLandscapist(): Landscapist {
return Landscapist.builder(applicationContext)
.config(LandscapistConfig(diskCacheSize = 200 * 1024 * 1024L))
.build()
}
@skydoves
skydoves / CombinedPlugins.kt
Created January 4, 2026 08:58
Landscapist: Combined Plugins
val imageComponent = rememberImageComponent {
+ShimmerPlugin(Shimmer.Flash())
+CrossfadePlugin(duration = 500)
+PalettePlugin(
imageModel = imageUrl,
useCache = true,
paletteLoadedListener = { palette ->
dominantColor = palette.dominantSwatch?.rgb
}
)
@skydoves
skydoves / PluginDSL.kt
Created January 4, 2026 08:58
Landscapist: Plugin DSL
LandscapistImage(
model = imageUrl,
component = rememberImageComponent {
+ShimmerPlugin(
shimmer = Shimmer.Resonate(
baseColor = Color.LightGray,
highlightColor = Color.White
)
)
+CrossfadePlugin(
@skydoves
skydoves / StateChangeCallbacks.kt
Created January 4, 2026 08:57
Landscapist: State Change Callbacks
LandscapistImage(
model = imageUrl,
onImageStateChanged = { state ->
when (state) {
is LandscapistImageState.Loading -> {
analytics.trackImageLoadStart(imageUrl)
}
is LandscapistImageState.Success -> {
analytics.trackImageLoadComplete(
url = imageUrl,
@skydoves
skydoves / LoadingStateComposables.kt
Created January 4, 2026 08:57
Landscapist: Loading State Composables
LandscapistImage(
model = imageUrl,
loading = {
Box(modifier = Modifier.matchParentSize()) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center)
)
}
},
success = { state ->
@skydoves
skydoves / BasicLandscapistImage.kt
Created January 4, 2026 08:57
Landscapist: Basic LandscapistImage
import com.skydoves.landscapist.image.LandscapistImage
@Composable
fun ProfileImage(imageUrl: String) {
LandscapistImage(
model = imageUrl,
contentDescription = "Profile photo",
modifier = Modifier
.size(120.dp)
.clip(CircleShape),
@skydoves
skydoves / AutomaticDownsampling.kt
Created January 4, 2026 08:57
Landscapist: Automatic Downsampling
// Without explicit size - calculates from Compose constraints
LandscapistImage(
model = "https://example.com/large-image.jpg",
modifier = Modifier.size(200.dp) // Auto-calculates target size
)
// With explicit size constraint
val request = ImageRequest.builder()
.model(imageUrl)
.size(width = 400, height = 300) // Target size in pixels
@skydoves
skydoves / CachePolicies.kt
Created January 4, 2026 08:57
Landscapist: Cache Policies
val request = ImageRequest.builder()
.model(imageUrl)
.memoryCachePolicy(CachePolicy.ENABLED) // Read and write
.diskCachePolicy(CachePolicy.READ_ONLY) // Only read, never write
.build()
// Available policies:
// CachePolicy.ENABLED - Read and write (default)
// CachePolicy.READ_ONLY - Only read from cache
// CachePolicy.WRITE_ONLY - Only write to cache