Repository navigation
Next Release - #3966
Closed
isekovanic wants to merge 6 commits into
Closed
Next Release#3966isekovanic wants to merge 6 commits into
isekovanic wants to merge 6 commits into
Conversation
…3953) Ticket: https://linear.app/stream/issue/REACT-1537 ## 🎯 Goal Make the SampleApp start new conversations the way the v10 "Starting a conversation" UI cookbook does, so the sample exercises the path integrators follow. It also bumps `stream-chat` to 10.0.1, which has the fix for the first-message error (GetStream/stream-chat-js#2007). | Commit | Change | | --- | --- | | [`39a2be3b0`](39a2be3b0) | SampleApp new-conversation screen follows the UI cookbook | | [`caec3a002`](caec3a002) | `stream-chat` bumped to 10.0.1 | Its new-conversation screen had a custom send button that composed the message, called `channel.watch()` and the raw `channel.sendMessage()`, then replaced the screen with `ChannelScreen`. The message never showed as sending, and the cookbook's flow was never run in the sample, which is how the first-message error fixed in GetStream/stream-chat-js#2007 went unnoticed. ## 🛠 Implementation details - `utils/startConversation.ts` holds the cookbook's two helpers. `startLocalConversation()` gets the channel from its members and places an empty first page while it's provisional, so the list shows its empty state. `createOnFirstSend()` is a `sendMessageRequest` handler: for a provisional channel it calls `Channel.watch()`, which creates the channel, and sends on the instance `watch()` resolves with. Every other channel sends through the default request. - `useChatClient` registers the handler in its existing `client.config.set()` call, where the client is created. - `NewDirectMessagingScreen` builds its draft with `startLocalConversation()`, uses the default `MessageComposer`, and passes `overrideOwnCapabilities` (`sendMessage` and `sendLinks`) only while the channel is provisional. It stays open after the first send, and `<Channel>` moves to the created channel, or to the one that superseded it. - Once the first message creates a conversation started on this screen, `NewConversationHeader` replaces the recipient picker with the channel header. An existing conversation keeps the picker, so its recipients can still be changed. - `ChannelHeader` is exported from `ChannelScreen` with two optional props: `onBack`, so the new-conversation screen still resets its user search on back, and `inSafeArea`, since that screen already applies the top inset. `ChannelScreen` passes neither and is unchanged. - `NewDirectMessagingSendButton` is removed. The other example apps don't start conversations from members (ExpoChatGPTSample creates its channels with an id), so they need no change. `stream-chat` goes from `^10.0.0` to `^10.0.1` in the SDK and every example app, as in #3951. 10.0.1 is 10.0.0 plus GetStream/stream-chat-js#2007: the first message in a channel whose newest page was loaded empty now starts the newest interval, so `jumpToTheLatestMessage()` no longer fails right after the first send of a new conversation. ## 🎨 UI Changes The new-conversation screen keeps the conversation open after the first message and swaps the recipient picker for the channel header. Before, it navigated to `ChannelScreen`. ## 🧪 Testing Tested in SampleApp on iOS (debug build, iPhone 17 Pro simulator), starting new conversations with throwaway users. Each first send went through the superseded-channel path from the cookbook report. - With `stream-chat` 10.0.0-rc.34, a new direct conversation sends from the same screen, and `stream-chat` emits `api:message:jumpToLatest:failed`, the error the cookbook report describes. - With a local build of GetStream/stream-chat-js#2007 (the code 10.0.1 ships), the same flow emits no notifications and the channel the screen moves to is at the newest messages. - A new group of three: the empty state shows before the first message and the attach button is hidden while the channel is provisional. After the send, the channel header replaces the picker ("3 members, 1 online"), back returns to the channel list, and "New Chat" opens empty again. The created channels show in the channel list, and `ChannelScreen`'s header is unchanged. - On 10.0.1: the full unit suite, `yarn test:typecheck`, SampleApp `tsc` and `yarn lint` pass. ## ☑️ Checklist - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [x] 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
…expo-av is installed (#3954) Ticket: https://linear.app/stream/issue/REACT-1538 Stacked on #3953. ## 🎯 Goal Stop `stream-chat-expo` from logging "install the expo-av package" in apps that have `expo-audio` installed. Audio works in those apps, so the log is wrong, and it points to a package Expo has deprecated. ## 🛠 Implementation details `AudioVideo.ts` logged whenever `require('expo-av')` failed, without checking for `expo-audio`. `Audio.ts` and `Sound.ts` use `expo-audio` first and fall back to `expo-av` only when it's missing. - The log is removed from `AudioVideo.ts`. - `Sound.ts` already loads both packages, so it now logs once, only when neither is installed, and names `expo-audio`, for playback and voice recording. The `expo-av` fallback stays. `stream-chat-expo` v10 supports Expo 53 and 54, where `expo-av` still works, so an app that never moved to `expo-audio` keeps its audio without a log. The same log has been on `develop` since v7, so this isn't a v10 regression. ## 🎨 UI Changes None. ## 🧪 Testing - New `Sound.test.ts`, with the optional packages mocked. With only `expo-audio` installed there's no log, with only `expo-av` there's no log, and with neither there's one log naming `expo-audio`. Without the fix, the first and third cases fail. - The expo-package typecheck, `yarn test:typecheck`, `prettier` and `yarn lint` pass. ## ☑️ Checklist - [x] 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
Ticket: https://linear.app/stream/issue/RN-449 ## 🎯 Goal Port the native iOS and Android e2e suites to the V10 Detox suite in `examples/E2ETestApp`, and bring its CI up to the native SDKs: per-test impact analysis on pull requests, a nightly run that builds the coverage map, and Allure TestOps reporting. ## 🛠 Implementation details **Tests** - 19 suites, 255 tests, ported from the Android compose and iOS UIKit suites (the union of both, with the native names and expectations). Every test links an Allure case in project 3. - When the SDK disagrees with the native expectation, the test keeps the native expectation and is skipped with `it.skip` and a comment that links a ticket. That covers 72 tests, tracked in RN-489 to RN-506 and RN-510. With those skipped, 183 tests run. - Robots, pages and support code grew to cover the suites: offline toggling (Android), the media library, JWT asserts, and Android system dialogs. **E2E app** - Offline support is on (`@op-engineering/op-sqlite`, `<Chat enableOfflineSupport>`). The database is wiped at login, so every test starts clean. - Added a JWT test screen, plus the channel details and thread screens the suites need. - No `setupCommandUIMiddlewares` call: since stream-chat `10.0.0-rc.31` (#3919), the client installs the command middlewares itself. **SDK** - Additive `testID`s only (channel preview, reactions, link previews, unread indicators, swipe actions, and a few others). There is no behaviour change. One snapshot changed because `ScrollToBottomButton` got a new `testID`. **Impact analysis (`e2e/README.md`, "Impact analysis")** - `E2E_COVERAGE=1` builds add a small Babel plugin (`e2e/coverage/babelPlugin.js`) that records which files run code. It isn't istanbul, because worklets capture istanbul's counters and then throw on the UI runtime. - After each test, the app reports its coverage to a collector in the test process, which writes one lcov file per test. - `build_e2e_coverage_map` and `select_e2e_tests` use `fastlane-plugin-stream_actions` (bumped from 0.4.14 to 0.4.19). - A PR runs only the tests its diff can reach. Changes to the harness, native code, dependencies or lanes still run everything. - The `Check E2E Required` job now also selects the tests, and skips e2e when none are selected. - Android runs in batches, like the native Android SDK: `Build Android` builds the APKs once, `Launch Allure TestOps (Android)` opens one launch, and `Test Android` runs up to 8 batches (one per selected test when fewer than 8 are selected), each taking a round-robin share of the selection. - A new nightly workflow, `e2e-test-cron.yml`, runs everything on Android with the coverage build and uploads the `e2e-coverage-map` artifact. It also runs every test on iOS. Until its first run on the default branch, every PR runs all tests. **Allure** - The Allure lanes moved into `examples/SampleApp/fastlane/Allurefile`, the same layout as stream-chat-swift. A new `allure_testcase` lane creates test cases. - Allure uses the `ALLURE_TOKEN` repository secret. **Mock server** - The suite runs the mock with `api_version=v2×tamps=ns`. That mode comes from GetStream/stream-chat-test-mock-server#98, which is now merged into `main`. ## 🎨 UI Changes None. The SDK changes are `testID`s only. ## 🧪 Testing - Full Android run (debug build, emulator): 255 tests, 182 passed, 70 skipped and 3 failed. All 3 passed when rerun: - A mock server start timeout, which is a harness issue. - RN-489 (the channel actions sheet sometimes opens empty). - RN-506 (after jumping to a quoted message, the list stays on the jumped page when the user sends). - Impact analysis: - Coverage collection checked on debug and release builds (17 of 17 tests collected). - A map built from those tests gave sensible selections from changed files. - A selection file ran exactly the selected tests. - First batched CI run (Android release build, 8 batches): batches 0 to 3 passed. Of the rest: - The two long-thread jump tests hung in release builds only: the open thread keeps enqueuing JS timers, so the app never becomes idle. Reproduced locally, ticketed as RN-510, and skipped. - The multiple-votes poll test pressed Back to hide a keyboard the CI emulator never showed, which closed the sheet. It now presses Back only when the keyboard is up. - One batch lost its emulator mid-run (runner issue, no test failure). - `yarn lint`, E2ETestApp `typecheck` and the SDK unit tests pass. - iOS isn't tuned yet. On PRs its e2e job runs on dispatch only; the nightly runs it. ## ☑️ Checklist - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [ ] PR targets the `develop` branch (targets `V10`: the suite needs the v10 SDK) - [x] Documentation is updated (`examples/E2ETestApp/e2e/README.md`) - [ ] New code is tested in main example apps, including all possible scenarios (e2e app only, no SampleApp/Expo changes)
…3961) Ticket: https://linear.app/stream/issue/RN-519 ## 🎯 Goal Design fix: the number next to the clustered reactions should be the total number of reactions on the message, shown whenever it is greater than 1. It was showing the number of reaction types beyond the first four, and only when there were more than four types. ## 🛠 Implementation details - `ReactionListClustered` sums the `count` of every reaction type and shows the badge when the total is above 1. - The badge's accessibility label now reads "N reaction(s)", using the `message.reactionList.total.accessibilityLabel` key. ## 🧪 Testing - New `ReactionListClustered.test.tsx`: the total across types, a single type reacted twice, the accessibility label, and no badge for a single reaction.
Ticket: https://linear.app/stream/issue/RN-520 ## 🎯 Goal The first nightly e2e run ([42739845823](https://github.com/GetStream/stream-chat-react-native/actions/runs/42739845823)) failed on both platforms and nothing reached Slack: - **Android:** a temporary Gradle Plugin Portal outage (`foojay-resolver-convention` not found) broke the build. The coverage-map step then failed too, because no tests had run. - **iOS:** the full suite had never run in CI before. 77 tests failed, and with `--retries 2` the job went over the 180-minute timeout and was cancelled, so no report was uploaded. Most of the time went to the iOS photo-library permission prompt, which blocked every later `launchApp`. - **Slack:** `e2e-test-cron.yml` had no notification job. The nightly also tested one OS version per platform, and ran the Android coverage pass as a single job that had never finished. The Flutter nightly covers several versions and splits coverage into batches, so this PR does the same here. ## 🛠 Implementation details **Nightly matrix, as in the Flutter nightly** | | Before | After | |---|---|---| | iOS | 26.2 (iPhone 17 Pro) | 26.2 (iPhone 17 Pro) and 17.5 (iPhone 15 Pro) | | Android | API 36 with coverage, one job | API 36 with coverage in 4 batches, plus API 34, 31 and 28 without coverage | - iOS 17.5 isn't on the runner image. The new `setup-ios-runtime` action installs it with `ipsw` (`fastlane install_runtime`, `bin/install_ios_runtime.sh`, both copied from Flutter) and creates the simulator. If that simulator is missing, the job fails instead of letting Detox pick another iOS version. - Android builds two sets of APKs once, one instrumented for coverage and one plain, and every test job downloads the set it needs. - After its tests, each coverage batch writes `failed_tests_<n>.json`: every test in the batch that didn't pass, including tests that never ran. - A new `coverage_map` job merges the batches and runs `build_e2e_coverage_map batch_count:4`. Failed tests keep their previous coverage. If a batch is missing, the job fails and the previous map stays in use. - The emulator now uses `-gpu swangle_indirect`, as PR runs do (RN-513). **Workflows** - Android `Build app` (nightly and PR) retries once after 60s. - The iOS test step has `timeout-minutes: 120`, so it fails (and reports) instead of being cancelled with the job. - A new `slack` job posts to `SLACK_WEBHOOK_NIGHTLY_CHECKS` when a scheduled run fails or is cancelled. It covers every nightly job. **iOS harness**, where Detox runs without synchronization - `IOSSimulator.grantIOSPermissions()` grants photos and camera through `applesimutils`, then restarts `tccd`. `simctl privacy grant` writes a TCC row that iOS 18 Photos ignores, so the system prompt still appeared. - `waitToSettleAndClick`: waits for the element to appear, then 1s, before tapping. Used for sheets, swipe actions, back, reaction pill, Paste, the attachment picker and polls. - After a message-menu action, wait until the backdrop is gone. If the menu doesn't open, retry the long-press. - `isAnyDisplayed`: iOS reports off-screen list cells as matches, so a check passes if any match is visible. The scroll loops use it, and scroll steps are smaller on iOS and settle before each check. - Visibility checks became existence checks where iOS Fabric mounts the container with no content of its own. Assertions that checked once now wait. - Three offline tests use `disableInternetConnection`, which only exists on Android, so they are now `itOnAndroid`. None of the failures were SDK bugs. ## 🧪 Testing - Full iOS suite on a fresh simulator (iPhone 16 Pro, iOS 18.5): **178 passed, 77 skipped, 0 failed, no retries, about 26 min**. Before this change, CI got 84 passing and 77 failing, then the job was cancelled after 3h. - I didn't run Android locally. The Android code paths barely change, so this PR's e2e run covers them. - The nightly on this branch: [42874414367](https://github.com/GetStream/stream-chat-react-native/actions/runs/42874414367). - I ran `e2e_failed_tests` and `build_e2e_coverage_map` locally on real coverage and Allure results. They built the map with the batches complete and stopped when a batch was missing; a test that never ran was listed as failed. - eslint, prettier, actionlint and `tsc -p e2e` are clean. Before the next nightly, the `SLACK_WEBHOOK_NIGHTLY_CHECKS` repo secret has to be added. ## ☑️ Checklist - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [x] 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
Next releasesv10.0.110.0.1 (2026-11-10)Bug Fixes
sampleapp@v5.0.15.0.1 (2026-11-10)Bug Fixes
|
Contributor
SDK Size
|
Ticket: https://linear.app/stream/issue/RN-522 ## 🎯 Goal Editing a message with a video attachment creates a crash. The video upload preview reads the duration off `localMetadata.file`, which doesn't exist for attachments restored from a sent message or a draft. ## 🛠 Implementation details - Guard the `localMetadata.file` read in `VideoAttachmentUploadPreview`. Already sent videos now render without the duration pill and nothing else changes. ## 🧪 Testing - Added a regression test that puts the composer into the editing state with a video attachment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 Goal
🛠 Implementation details
🎨 UI Changes
iOS
Android
🧪 Testing
☑️ Checklist
developbranch