Fixes#4863
Before this update, when a new `resource` value was passed to
`org.jetbrains.compose.resources.Font` composable, it kept the original
value.
Test sample code. `Res.font` here is autogenerated from
`commonMain/composeResources/font/` folder content.
```kt
var flag by remember {
mutableStateOf(false)
}
Column {
Text(
"hey",
fontFamily = FontFamily(Font(if (flag) Res.font.HelveticaNeueMedium else Res.font.COMICSANS, FontWeight.Normal))
)
Switch(checked = flag, onCheckedChange = { flag = it })
}
```
## Release Notes
### Fixes - Resources
- Fix a cached font if the resource acessor was changed
(cherry picked from commit 0485f03f42)
Fixes: https://github.com/JetBrains/compose-multiplatform/issues/4823
In https://github.com/JetBrains/compose-multiplatform/pull/4796 we
intentionally started to configure the web app for all k/js and k/wasm
targets. The configuration involves adding a dependency on skiko-wasm
runtime and unpacking it.
Some projects don't need skiko-wasm-runtime (like those based on
compose.html or just compose.runtime).
**Solution:**
We check if there is a dependency on org.jetbrains.compose.ui libraries
(including transitive dependencies). If we find it, then we enable
skikoUnpack task. Otherwise it's disabled.
## Testing
- Build the gradle plugin locally (with this change)
- Used it in our html landing example:
https://github.com/JetBrains/compose-multiplatform/blob/master/examples/html/landing
- Run `./gradlew jsBrowserDistribution`, check
`.../compose-multiplatform/examples/html/landing/build/dist/js/productionExecutable`
and see NO skiko.* files added there
- Then add `implementation(compose.foundation)` dependency in
build.gradle.jts and run `./gradlew clean jsBrowserDistribution` again -
the build/dist contains skiko.* now
(cherry picked from commit 30164c5f27)
Before the fix we could cancel a coroutine and the cancelled deferred
was saved in cache.
## Release Notes
### Fixes - Resources
- _(prerelease fix)_ Fix a cached empty resource on a Compose for Web if
the resource loading was canceled during progress
(cherry picked from commit dbab89354a)
Since 1.6.10 Compose for Web goes to Alpha and experimental
configuration is not needed anymore. We'll configure the web targets by
default when they're added to projects.
## Testing
- I built the plugin to mavenLocal. And used it in a couple of our
samples.
- After gradle sync completes, I observe the Deprecation warning in
build.gradle.kts on `compose.experimental.web` usages (see a screenshot
below)
<img width="1022" alt="Screenshot 2024-05-10 at 15 41 14"
src="https://github.com/JetBrains/compose-multiplatform/assets/7372778/e8ede073-8d34-4dd7-ae74-c83ca0ff5c96">
Then I remove deprecated API usages and test that the project works
without it:
- run `./gradlew clean` just in case
- run the app: `./gradlew wasmJsBrowserRun` and `./gradlew jsBrowserRun`
- both run fine
- build the production distribution: `./gradlew
wasmJsBrowserDistribution`
- `cd ..../build/dist/wasmJs/productionExecutable` and run `python -m
http.server`, open a browser at `http://localhost:8000` - the app should
work the same way it works with gradle tasks above
<!-- Optional -->
This should be tested by QA
## Release Notes
### Highlights - Web
- Compose for Web goes to Alpha!
Some experimental Compose Multiplatform Gradle plugin APIs for web app
configuration were deprecated. Their usage is not required anymore.
(cherry picked from commit 885ea3da2a)
The PR sets a static path to the compose resources for the cocoapods
integration because there maybe only one integration framework for a
gradle module.
Fixes https://github.com/JetBrains/compose-multiplatform/issues/4720
## Release Notes
### Fixes - Resources
- _(prerelease fix)_ Fix resources with cocoapods integration
(cherry picked from commit b8846788ce)
The Compose Multiplatform Resources with the mulimodule.publication
support is a new feature and may have some not found problems. The PR
introduces a gradle property to switch back to the previous behavior:
`org.jetbrains.compose.resources.multimodule.disable=true`
## Testing
After update to Kotlin 2.0.0 and CMP 1.6.10 all projects will be
switched to the new logic with the multimodule support.
Gradle info output should contain a message:
```
Configure KMP resources
```
If the new feature breaks user's projects they may add
`org.jetbrains.compose.resources.multimodule.disable=true` to the
`gradle.properties` to disable it. After that Gradle info output will
contain:
```
Configure compose resources
```
## Release Notes
### Resources
To disable the Compose Resources publication and the multimodule support
in cases of problems add
`org.jetbrains.compose.resources.multimodule.disable=true` to the root
`gradle.properties`.
(cherry picked from commit bf6142ddf5)
Implemented two new experimental functions:
```kotlin
/**
* Retrieves the byte array of the drawable resource.
*
* @param environment The resource environment, which can be obtained from [rememberResourceEnvironment] or [getSystemResourceEnvironment].
* @param resource The drawable resource.
* @return The byte array representing the drawable resource.
*/
@ExperimentalResourceApi
suspend fun getDrawableResourceBytes(
environment: ResourceEnvironment,
resource: DrawableResource
): ByteArray {...}
/**
* Retrieves the byte array of the font resource.
*
* @param environment The resource environment, which can be obtained from [rememberResourceEnvironment] or [getSystemResourceEnvironment].
* @param resource The font resource.
* @return The byte array representing the font resource.
*/
@ExperimentalResourceApi
suspend fun getFontResourceBytes(
environment: ResourceEnvironment,
resource: FontResource
): ByteArray {...}
```
fixes https://github.com/JetBrains/compose-multiplatform/issues/4360
## Proposed changes
1. Added support to join JARs to the uber JAR with ProGuard, disabled by
default:
```
compose.desktop {
application {
buildTypes.release.proguard {
joinOutputJars.set(true)
}
}
}
```
2. All 'release' tasks now really depend on ProGuard, as stated in
[tutorial](https://github.com/JetBrains/compose-multiplatform/tree/master/tutorials/Native_distributions_and_local_execution#minification--obfuscation).
## Testing
- A new auto test
- Manual:
1. Test on Windows/macOs/Linux
2. Test the new Gradle parameter `joinOutputJars`:
```
compose.desktop {
application {
buildTypes.release.proguard {
joinOutputJars.set(true)
}
}
}
```
`false` (by default) should generate multiple jars (except for
`package*UberJarForCurrentOS`)
`true` should generate a single jar in a result distribution
3. Test debug tasks:
```
run
runDistributable
createDistributable
packageUberJarForCurrentOS
```
4. Test release tasks:
```
runRelease
runReleaseDistributable
createReleaseDistributable
packageReleaseUberJarForCurrentOS
```
The jars should be reduced in size (because Proguard is enabled in the
release mode)
This should be test by QA.
## Issues fixed
Fixes https://github.com/JetBrains/compose-multiplatform/issues/4129
---------
Co-authored-by: Igor Demin <igordmn@users.noreply.github.com>
Compose resources can be located in different KMP source sets in the
`composeResources` directory. For each resource an accessor will be
generated in the suitable kotlin source set.
We need to filter by language and region together because there is
slightly different logic:
1) if there is the exact match language+region then use it
2) if there is the language WITHOUT region match then use it
3) in other cases use items WITHOUT language and region qualifiers at
all
Given resources:
values
values-en-rUS
values-de
Filter results:
"en" -> values
"en-US" -> values-en-rUS
"en-GB" -> values
"de-IT" -> values-de
fixes https://github.com/JetBrains/compose-multiplatform/issues/4571
Adds a public `Res.getUri(path: String): String` function.
It lets external libraries a way to read resource files by a platform
dependent Uri.
E.g.: video players, image loaders or embedded web browsers.
```kotlin
val uri = Res.getUri("files/my_video.mp4")
```
fixes https://github.com/JetBrains/compose-multiplatform/issues/4360
The issue was in a case where there wasn't a direct dependency on the
skiko artifact, the task would attempt to get one at task execution
time. This moves that to task configuration time.
Users noticed if an app has big a `string.xml` file it affects the app
startup time:
https://github.com/JetBrains/compose-multiplatform/issues/4537
The problem is slow XML parsing.
Possible ways for optimization:
1) inject text resources direct to the source code
2) convert XMLs to an optimized format to read it faster
We selected the second way because texts injected to source code have
several problems:
- strict limitations on text size
- increase compilation and analysation time
- affects a class loader and GC
> Note: android resources do the same and converts xml values to own
`resources.arsc` file
Things was done in the PR:
1) added support any XML files in the `values` directory
2) **[BREAKING CHANGE]** added `Res.array` accessor for string-array
resources
3) in a final app there won't be original `values*/*.xml` files. There
will be converted `values*/*.cvr` files.
4) generated code points on string resources as file -> offset+size
5) string resource cache is by item now (it was by the full xml file
before)
6) implemented random access to read CVR files
7) tasks for syncing ios resources to a final app were seriously
refactored to support generated resources (CVR files)
8) restriction for 3-party resources plugin were deleted
9) Gradle property `compose.resources.always.generate.accessors` was
deleted. It was for internal needs only.
Fixes https://github.com/JetBrains/compose-multiplatform/issues/4537