Skip to content

Next release - #3805

Merged
szuperaz merged 3 commits into
mainfrom
develop
Sep 15, 2026
Merged

szuperaz merged 3 commits into
mainfrom
develop

Conversation

@szuperaz

Copy link
Copy Markdown
Contributor

🎯 Goal

πŸ›  Implementation details

🎨 UI Changes

iOS
Before After
Android
Before After

πŸ§ͺ Testing

β˜‘οΈ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

gabrieldonadel and others added 3 commits September 8, 2026 11:02
…in extension (#3798)

## Problem

Android Gradle Plugin 9 ships built-in Kotlin support and enables it by
default, so
AGP registers the `kotlin` extension itself. When a library *also*
applies `kotlin-android`
explicitly, the two collide and configuration fails before anything
compiles. AGP
words it two ways, both the same problem:

```
> Failed to apply plugin 'kotlin-android'.
   > Cannot add extension with name 'kotlin', as there is an extension already registered with that name.
```
```
> The 'kotlin-android' plugin is no longer required for Kotlin support since AGP 9.0.
```

The apply is unconditional in all 2 modules below, so on an AGP 9
project this cannot be built
at all. There is no consumer-side workaround short of patching the file
β€” setting
`android.builtInKotlin=false` project-wide just to build one dependency
is not a
reasonable ask, and that escape hatch is removed in AGP 10.

## Change

Apply the plugin only when nothing has registered the `kotlin` extension
yet:

```groovy
if (project.extensions.findByName('kotlin') == null) {
    apply plugin: 'kotlin-android'
}
```

Files changed:

- `package/expo-package/android/build.gradle`
- `package/native-package/android/build.gradle`

This tests the condition that actually fails, so there is no AGP version
table to
keep in sync, and it covers AGP 10 β€” where the `android.builtInKotlin`
opt-out is
removed β€” without a special case.

| AGP | `android.builtInKotlin` | `kotlin` extension | explicit apply |
|---|---|---|---|
| 8.x | unset or `false` | absent | yes (unchanged) |
| 9.x | unset or `true` | registered by AGP | no |
| 9.x | `false` | absent | yes |
| 10+ | n/a (removed) | registered by AGP | no |

The guard sits after `apply plugin: 'com.android.library'` in every file
it touches,
so AGP has already registered its extensions by the time it runs. I
checked that
ordering per file rather than assuming it.

## What I verified, and what I did not

- **Verified end to end** on a real Expo SDK 58 / React Native 0.87
project with AGP
  9.2.1 and Gradle 9.4.1: `:app:assembleDebug` succeeds both with
`-Pandroid.newDsl=true -Pandroid.builtInKotlin=true` and with both flags
off.
- Confirmed both branches actually execute rather than one path always
winning: with
the flags off, `compileDebugKotlin` runs from the explicitly applied
plugin; with
  them on the build completes without it.
- Every changed file passes a Groovy `Phases.CONVERSION` syntax check.
- **Not run:** this repo's own CI or example app.

## Where this came from

A sweep of 500 popular React Native libraries against the AGP 9
defaults. 152 failed
with the new DSL enabled, and **144 of those failed on exactly this
collision** β€” by
far the most common blocker. Affects `stream-chat-expo` here.

The same guard shape was accepted in

[RevenueCat/react-native-purchases#1934](RevenueCat/react-native-purchases#1934),
at that maintainer's suggestion.
#3799)

Follow-up to #3798. That change stops applying `kotlin-android` when AGP
has already
registered the `kotlin` extension, which is what AGP 9 does by default.
But
`android.kotlinOptions` is contributed by the Kotlin Gradle plugin
itself, so skipping the
plugin left both wrapper modules unable to configure at all:

> Could not find method kotlinOptions() for arguments [...] on extension
'android'
      of type com.android.build.gradle.LibraryExtension.

Set the target on the KotlinCompile tasks instead. That form resolves on
both paths.

A note for integrators: the `android.builtInKotlin=false` is still
necessary because the SDK has peer dependencies that require this
setting.
…alpha channel to a format without it (#3800)

## 🎯 Goal

Feature request:
https://getstream.slack.com/archives/C02GBL5M1BK/p1788176084433019

The problem:
- When transforming images with an alpha channel (PNG/Webp) to a format
without an alpha channel (for example JPEG) the resulting image's
background is platform-dependent: black on Android, white on iOS 26
- The request: provide an option for integrators to specify an explicit
background color for these transforms

How to use it?

```ts
const localCompressImage = defaultNativeHandlers.compressImage;

registerNativeHandlers({
  compressImage: localCompressImage
    ? (params) => localCompressImage({ ...params, backgroundColor: '#FFFFFF' })
    : undefined,
});
```

## πŸ›  Implementation details

Works for CLI-only because `expo-image-manipulator` doesn't have such
option. The default background color is white.

## 🎨 UI Changes

<!-- Add relevant screenshots -->

<details>
<summary>iOS</summary>


<table>
    <thead>
        <tr>
            <td>Before</td>
            <td>After</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <!--<img src="" /> -->
            </td>
            <td>
                <!--<img src="" /> -->
            </td>
        </tr>
    </tbody>
</table>
</details>


<details>
<summary>Android</summary>

<table>
    <thead>
        <tr>
            <td>Before</td>
            <td>After</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <!--<img src="" /> -->
            </td>
            <td>
                <!--<img src="" /> -->
            </td>
        </tr>
    </tbody>
</table>
</details>

## πŸ§ͺ Testing

<!-- Explain how this change can be tested (or why it can't be tested)
-->

## β˜‘οΈ Checklist

- [ ] I have signed the [Stream
CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform)
(required)
- [ ] PR targets the `develop` branch
- [ ] Documentation is updated
- [ ] New code is tested in main example apps, including all possible
scenarios
  - [ ] SampleApp iOS and Android
  - [ ] Expo iOS and Android
@github-actions

Copy link
Copy Markdown

Next releases

v9.9.0

9.9.0 (2026-09-15)

Bug Fixes

  • android: set the Kotlin jvmTarget without requiring the Kotlin G… (#3799) (cb145c7)
  • android: skip explicit Kotlin plugin when AGP registers the kotlin extension (#3798) (ca5692a)

Features

  • allow providing background color when transforming images with alpha channel to a format without it (#3800) (1d46a53)

@Stream-SDK-Bot

Copy link
Copy Markdown
Contributor

SDK Size

title develop branch diff status
js_bundle_size 2031 KB 2031 KB 0 B 🟒

@szuperaz
szuperaz merged commit ef4e7d5 into main Sep 15, 2026
18 checks passed
@stream-ci-bot

Copy link
Copy Markdown
Contributor

πŸŽ‰ This PR is included in version 9.9.0 πŸŽ‰

The release is available on:

Your semantic-release bot πŸ“¦πŸš€

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants