diff --git a/CHANGELOG.md b/CHANGELOG.md index c795c66920..e04e343e08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,75 @@ # Changelog +## [2.0.0] - May 10, 2022 + +Coil 2.0.0 is a major iteration of the library and includes breaking changes. Check out the [upgrade guide](https://coil-kt.github.io/coil/upgrading/) for how to upgrade. + +- **New** Add support `AsyncImage` and `SubcomposeAsyncImage` to `coil-compose`. Check out [the documentation](https://coil-kt.github.io/coil/compose/) for more info. + +```kotlin +// Display an image from the network. +AsyncImage( + model = "https://example.com/image.jpg", + contentDescription = null +) + +// Display an image from the network with a placeholder, circle crop, and crossfade animation. +AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data("https://example.com/image.jpg") + .crossfade(true) + .build(), + placeholder = painterResource(R.drawable.placeholder), + contentDescription = stringResource(R.string.description), + contentScale = ContentScale.Crop, + modifier = Modifier.clip(CircleShape) +) +``` + +- **New** Introduce a public `DiskCache` API. + - Use `ImageLoader.Builder.diskCache` and `DiskCache.Builder` to configure the disk cache. + - You should not use OkHttp's `Cache` with Coil 2.0. See [here](https://coil-kt.github.io/coil/upgrading/#disk-cache) for more info. + - `Cache-Control` and other cache headers are still supported - except `Vary` headers, as the cache only checks that the URLs match. Additionally, only responses with a response code in the range [200..300) are cached. + - Existing disk caches will be cleared when upgrading to 2.0. +- The minimum supported API is now 21. +- `ImageRequest`'s default `Scale` is now `Scale.FIT`. + - This was changed to make `ImageRequest.scale` consistent with other classes that have a default `Scale`. + - Requests with an `ImageViewTarget` still have their `Scale` auto-detected. +- Rework the image pipeline classes: + - `Mapper`, `Fetcher`, and `Decoder` have been refactored to be more flexible. + - `Fetcher.key` has been replaced with a new `Keyer` interface. `Keyer` creates the cache key from the input data. + - Add `ImageSource`, which allows `Decoder`s to read `File`s directly using Okio's file system API. +- Rework the Jetpack Compose integration: + - `rememberImagePainter` and `ImagePainter` have been renamed to `rememberAsyncImagePainter` and `AsyncImagePainter` respectively. + - Deprecate `LocalImageLoader`. Check out the deprecation message for more info. +- Disable generating runtime not-null assertions. + - If you use Java, passing null as a not-null annotated argument to a function will no longer throw a `NullPointerException` immediately. Kotlin's compile-time null safety guards against this happening. + - This change allows the library's size to be smaller. +- `Size` is now composed of two `Dimension` values for its width and height. `Dimension` can either be a positive pixel value or `Dimension.Undefined`. See [here](https://coil-kt.github.io/coil/upgrading/#size-refactor) for more info. +- `BitmapPool` and `PoolableViewTarget` have been removed from the library. +- `VideoFrameFileFetcher` and `VideoFrameUriFetcher` have been removed from the library. Use `VideoFrameDecoder` instead, which supports all data sources. +- [`BlurTransformation`](https://github.com/coil-kt/coil/blob/845f39383f332428077c666e3567b954675ce248/coil-base/src/main/java/coil/transform/BlurTransformation.kt) and [`GrayscaleTransformation`](https://github.com/coil-kt/coil/blob/845f39383f332428077c666e3567b954675ce248/coil-base/src/main/java/coil/transform/GrayscaleTransformation.kt) are removed from the library. If you use them, you can copy their code into your project. +- Change `Transition.transition` to be a non-suspending function as it's no longer needed to suspend the transition until it completes. +- Add support for `bitmapFactoryMaxParallelism`, which restricts the maximum number of in-progress `BitmapFactory` operations. This value is 4 by default, which improves UI performance. +- Add support for `interceptorDispatcher`, `fetcherDispatcher`, `decoderDispatcher`, and `transformationDispatcher`. +- Add `GenericViewTarget`, which handles common `ViewTarget` logic. +- Add `ByteBuffer` to the default supported data types. +- `Disposable` has been refactored and exposes the underlying `ImageRequest`'s job. +- Rework the `MemoryCache` API. +- `ImageRequest.error` is now set on the `Target` if `ImageRequest.fallback` is null. +- `Transformation.key` is replaced with `Transformation.cacheKey`. +- Update Kotlin to 1.6.10. +- Update Compose to 1.1.1. +- Update OkHttp to 4.9.3. +- Update Okio to 3.0.0. + +Changes from `2.0.0-rc03`: +- Convert `Dimension.Original` to be `Dimension.Undefined`. + - This changes the semantics of the non-pixel dimension slightly to fix some edge cases ([example](https://github.com/coil-kt/coil/issues/1246)) in the size system. +- Load images with `Size.ORIGINAL` if ContentScale is None. +- Fix applying `ImageView.load` builder argument first instead of last. +- Fix not combining HTTP headers if response is not modified. + ## [2.0.0-rc03] - April 11, 2022 - Remove the `ScaleResolver` interface. @@ -36,7 +106,7 @@ Significant changes since `1.4.0`: - Rework the image pipeline classes: - `Mapper`, `Fetcher`, and `Decoder` have been refactored to be more flexible. - `Fetcher.key` has been replaced with a new `Keyer` interface. `Keyer` creates the cache key from the input data. - - Adds `ImageSource`, which allows `Decoder`s to read `File`s directly using Okio's file system API. + - Add `ImageSource`, which allows `Decoder`s to read `File`s directly using Okio's file system API. - Disable generating runtime not-null assertions. - If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a `NullPointerException` immediately. Kotlin's compile-time null safety guards against this happening. - This change allows the library's size to be smaller. diff --git a/README-ko.md b/README-ko.md index c92f962cdb..8ea29cb1c1 100644 --- a/README-ko.md +++ b/README-ko.md @@ -16,7 +16,7 @@ Coil은: **Co**routine **I**mage **L**oader의 약자입니다. Coil은 `mavenCentral()`로 이용 가능합니다. ```kotlin -implementation("io.coil-kt:coil:2.0.0-rc03") +implementation("io.coil-kt:coil:2.0.0") ``` ## 빠른 시작 @@ -50,7 +50,7 @@ imageView.load("https://www.example.com/image.jpg") { [Jetpack Compose](https://developer.android.com/jetpack/compose) 확장 라이브러리 추가: ```kotlin -implementation("io.coil-kt:coil-compose:2.0.0-rc03") +implementation("io.coil-kt:coil-compose:2.0.0") ``` 이미지를 불러오려면, `AsyncImage` composable를 사용하세요: diff --git a/README-tr.md b/README-tr.md index 00146fa2fb..7aeaa2497f 100644 --- a/README-tr.md +++ b/README-tr.md @@ -17,7 +17,7 @@ Coil şunların baş harflerinden oluşur: **Co**routine **I**mage **L**oader. Coil `mavenCentral()`'da mevcuttur. ```kotlin -implementation("io.coil-kt:coil:2.0.0-rc03") +implementation("io.coil-kt:coil:2.0.0") ``` ## Hızlı Başlangıç diff --git a/README-zh.md b/README-zh.md index f537350285..b301f97729 100644 --- a/README-zh.md +++ b/README-zh.md @@ -16,7 +16,7 @@ Coil 名字的由来:取 **Co**routine **I**mage **L**oader 首字母得来。 Coil 可以在 `mavenCentral()` 下载 ```kotlin -implementation("io.coil-kt:coil:2.0.0-rc03") +implementation("io.coil-kt:coil:2.0.0") ``` ## 快速上手 diff --git a/README.md b/README.md index f9b92e293a..e66333277a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Made with ❤️ at [Instacart](https://www.instacart.com). Translations: [한 Coil is available on `mavenCentral()`. ```kotlin -implementation("io.coil-kt:coil:2.0.0-rc03") +implementation("io.coil-kt:coil:2.0.0") ``` ## Quick Start @@ -50,7 +50,7 @@ imageView.load("https://www.example.com/image.jpg") { Import the [Jetpack Compose](https://developer.android.com/jetpack/compose) extension library: ```kotlin -implementation("io.coil-kt:coil-compose:2.0.0-rc03") +implementation("io.coil-kt:coil-compose:2.0.0") ``` To load an image, use the `AsyncImage` composable: diff --git a/coil-compose-singleton/README.md b/coil-compose-singleton/README.md index 98f9381b4e..485c84bcf3 100644 --- a/coil-compose-singleton/README.md +++ b/coil-compose-singleton/README.md @@ -3,7 +3,7 @@ To add support for [Jetpack Compose](https://developer.android.com/jetpack/compose), import the extension library: ```kotlin -implementation("io.coil-kt:coil-compose:2.0.0-rc03") +implementation("io.coil-kt:coil-compose:2.0.0") ``` Then use the `AsyncImage` composable to load and display an image: diff --git a/coil-gif/README.md b/coil-gif/README.md index e53639d548..563753d735 100644 --- a/coil-gif/README.md +++ b/coil-gif/README.md @@ -5,7 +5,7 @@ Unlike Glide, GIFs are not supported by default. However, Coil has an extension To add GIF support, import the extension library: ```kotlin -implementation("io.coil-kt:coil-gif:2.0.0-rc03") +implementation("io.coil-kt:coil-gif:2.0.0") ``` And add the decoders to your component registry when constructing your `ImageLoader`: diff --git a/coil-svg/README.md b/coil-svg/README.md index c92aa8e108..675481134a 100644 --- a/coil-svg/README.md +++ b/coil-svg/README.md @@ -3,7 +3,7 @@ To add SVG support, import the extension library: ```kotlin -implementation("io.coil-kt:coil-svg:2.0.0-rc03") +implementation("io.coil-kt:coil-svg:2.0.0") ``` And add the decoder to your component registry when constructing your `ImageLoader`: diff --git a/coil-video/README.md b/coil-video/README.md index c2eba1c505..ccaafd6b98 100644 --- a/coil-video/README.md +++ b/coil-video/README.md @@ -3,7 +3,7 @@ To add video frame support, import the extension library: ```kotlin -implementation("io.coil-kt:coil-video:2.0.0-rc03") +implementation("io.coil-kt:coil-video:2.0.0") ``` And add the decoder to your component registry when constructing your `ImageLoader`: diff --git a/docs/upgrading.md b/docs/upgrading.md index a557e712cb..623b6c9a2c 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -8,11 +8,11 @@ Coil 2.x requires minimum API 21. This is also the minimum API required for Jetp ## ImageRequest default scale -Coil 2.x changes `ImageRequest`'s default scale from `Scale.FILL` to `Scale.FIT`. This was done to ensure be consistent with `ImageView`'s default `ScaleType` and `Image`'s default `ContentScale`. Scale is still autodetected if you set an `ImageView` as your `ImageRequest.target`. +Coil 2.x changes `ImageRequest`'s default scale from `Scale.FILL` to `Scale.FIT`. This was done to be consistent with `ImageView`'s default `ScaleType` and `Image`'s default `ContentScale`. Scale is still autodetected if you set an `ImageView` as your `ImageRequest.target`. ## Size refactor -`Size`'s `width` and `height` is now composed of two `Dimension`s instead of `Int` pixel values. `Dimension` is either a pixel value or `Dimension.Original`, which represents the source value for that dimension (similar to how `Size.ORIGINAL` represents the source values for both width and height). You can use the `pxOrElse` extension to get the pixel value (if present), else use a fallback: +`Size`'s `width` and `height` are now two `Dimension`s instead of `Int` pixel values. `Dimension` is either a pixel value or `Dimension.Undefined`, which represents an undefined/unbounded constraint. For example, if the size is `Size(400, Dimension.Undefined)` that means the image should be scaled to have 400 pixels for its width irrespective of its height. You can use the `pxOrElse` extension to get the pixel value (if present), else use a fallback: ```kotlin val width = size.width.pxOrElse { -1 } @@ -90,6 +90,14 @@ ImageLoader.Builder(context) .build() ``` +This change was made to add functionality and improve performance: + +- Support thread interruption while decoding images. + - Thread interruption allows fast cancellation of decode operations. This is particularly important for quickly scrolling through a list. + - By using a custom disk cache Coil is able to ensure a network source is fully read to disk before decoding. This is necessary as writing the data to disk cannot be interrupted - only the decode step can be interrupted. OkHttp's `Cache` shouldn't be used with Coil 2.0 as it's not possible to guarantee that all data is written to disk before decoding. +- Avoid buffering/creating temporary files for decode APIs that don't support `InputStream`s or require direct access to a `File` (e.g. `ImageDecoder`, `MediaMetadataRetriever`). +- Add a public read/write `DiskCache` API. + In Coil 2.x `Cache-Control` and other cache headers are still supported - except `Vary` headers, as the cache only checks that the URLs match. Additionally, only responses with a response code in the range [200..300) are cached. When upgrading from Coil 1.x to 2.x, any existing disk cache will be cleared as the internal format has changed. @@ -101,7 +109,7 @@ Coil 2.x refactors the image pipeline classes to be more flexible. Here's a high - Introduce a new class, `Keyer`, that computes the memory cache key for a request. It replaces `Fetcher.key`. - `Mapper`, `Keyer`, `Fetcher`, and `Decoder` can return `null` to delegate to the next element in the list of components. - Add `Options` to `Mapper.map`'s signature. -- Introduce `Fetcher.Factory` and `Decoder.Factory`. Use the factories to determine if a specific `Fetcher`/`Decoder` is applicable. +- Introduce `Fetcher.Factory` and `Decoder.Factory`. Use the factories to determine if a specific `Fetcher`/`Decoder` is applicable. Return `null` if that `Fetcher`/`Decoder` is not applicable. ## Remove bitmap pooling diff --git a/gradle.properties b/gradle.properties index 1aa1de6fcd..cd38e65462 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ compileSdk=31 # Maven GROUP=io.coil-kt -VERSION_NAME=2.0.0-SNAPSHOT +VERSION_NAME=2.0.0 POM_DESCRIPTION=An image loading library for Android backed by Kotlin Coroutines. POM_INCEPTION_YEAR=2019