cmota / Kamel

Kotlin asynchronous media loading and caching library for Compose.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Kamel

Version Snapshot License Kotlin Compose

Kamel is an asynchronous media loading library for Compose. It provides a simple, customizable and efficient way to load, cache, decode and display images in your application. By default, it uses Ktor client for loading resources.

Table of contents

Setup

Kamel is published on Maven Central:

repositories {
    mavenCentral()
    // ...
}

Multiplatform

Add the dependency to the common source-set:

kotlin {
    sourceSets {
        commonMain {
            dependencies {
                implementation("com.alialbaali.kamel:kamel-image:0.2.2")
                // ...
            }
        }
    }
}

Single-platform

Add the dependency to the dependencies block:

dependencies {
    implementation("com.alialbaali.kamel:kamel-image:0.2.2")
    // ...
}

Usage

Loading an image resource

To load an image, you can use lazyImageResource composable, it can load images from different data sources.

// String
lazyImageResource(data = "https://www.example.com/image.jpg")

// Ktor Url
lazyImageResource(data = Url("https://www.example.com/image.jpg"))

// URI
lazyImageResource(data = URI("https://www.example.com/image.png"))

// File
lazyImageResource(data = File("/path/to/image.png"))

// URL
lazyImageResource(data = URL("https://www.example.com/image.jpg"))

// and more...

Platform specific implementations

Since there isn't any shared resource system between Android and Desktop, some implementations (e.g. fetchers and mappers) are only available for a specific platform:

Desktop only implementations

To load an image file from desktop application resources, you have to add resourcesFetcher to the KamelConfig:

val desktopConfig = KamelConfig {
    takeFrom(KamelConfig.Default)
    resourcesFetcher() // Available only on Desktop.
}

Assuming there's an image.png file in the /resources directory in the project:

CompositionLocalProvider(LocalKamelConfig provides desktopConfig) {
    lazyImageResource("image.png")
}

Android only implementations

To load an image file from android application resources, you have to add resourcesFetcher and resourcesIdMapper to the KamelConfig:

val context : Context = LocalContext.current

val androidConfig = KamelConfig {
    takeFrom(KamelConfig.Default)
    resourcesFetcher(context) // Available only on Android.
    resourcesIdMapper(context) // Available only on Android. 
}

Assuming there's an image.png file in the /res/raw directory in the project:

CompositionLocalProvider(LocalKamelConfig provides androidConfig) {
    lazyImageResource(R.raw.image)
}

Configuring an image resource

lazyImageResource supports configuration using trailing lambda:

val imageResource: Resource<ImageBitmap> = lazyImageResource("https://www.example.com/image.jpg") {

    dispatcher = Dispatchers.IO // Coroutine Dispatcher to be used while loading.

    requestBuilder { // this: HttpRequestBuilder
        header("Key", "Value")
        parameter("Key", "Value")
        cacheControl(CacheControl.MAX_AGE)
    }

}

Displaying an image resource

KamelImage is a composable function that takes an ImageBitmap resource, display it and provide extra functionality:

KamelImage(
    resource = imageResource,
    contentDescription = "Profile"
)

KamelImage can display custom content in failure or loading states through onFailure and onLoading parameters:

KamelImage(
    resource = imageResource,
    contentDescription = "Profile",
    onLoading = {
        Box(modifier = Modifier.fillMaxSize()) {
            CircularProgressIndicator()
        }
    },
    onFailure = { exception ->
        Snackbar {
            Text(exception.message)
        }
    }
)

You can also provide your own custom implementation using a simple when expression:

when (val resource = lazyImageResource("https://www.example.com/image.jpg")) {
    is Resource.Loading -> {
        Text("Loading...")
    }
    is Resource.Success -> {
        val bitmap: ImageBitmap = resource.value
        Image(bitmap, null, modifier = Modifier.clip(CircleShape))
    }
    is Resource.Failure -> {
        log(resource.exception)
        val fallbackImage = imageResource("/path/to/fallbackImage.jpg")
        Image(fallbackImage, null)
    }
}

Crossfade animation

You can enable, disable or customize crossfade (fade-in) animation through the crossfade and animationSpec parameters:

KamelImage(
    resource = imageResource,
    contentDescription = "Profile",
    crossfade = true, // false by default
    animationSpec = tween(),
)

Configuring Kamel

The default implementation is KamelConfig.Default. If you wish to configure it, you can do it like so:

val myKamelConfig = KamelConfig {

    imageBitmapDecoder() // adds an ImageBitmapDecoder

    fileFetcher() // adds a FileFetcher

    httpFetcher { // Configuring Ktor HttpClient
        defaultRequest {
            url("https://www.example.com/")
            cacheControl(CacheControl.MaxAge(maxAgeSeconds = 10000))
        }
        Logging {
            level = LogLevel.INFO
            logger = Logger.SIMPLE
        }
    }

    // more functionality available.
}

Cache size (number of entries)

To Configure memory cache size, you can change the imageBitmapCacheSize property:

KamelConfig {
    imageBitmapCacheSize = 1000
}

Applying Kamel configuration

You can use LocalKamelConfig to apply your custom configuration:

CompositionLocalProvider(LocalKamelConfig provides myKamelConfig) {
    lazyImageResource("image.jpg")
}

Contributions

Contributions are always welcome!. If you'd like to contribute, please feel free to create a PR.

License

Copyright 2021 Ali Albaali

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

About

Kotlin asynchronous media loading and caching library for Compose.

License:Apache License 2.0


Languages

Language:Kotlin 100.0%