| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat: native multipart upload (#3566) ## 🎯 Goal This PR adds optional native multipart upload support for React Native and Expo packages, with native iOS/Android uploaders, a JS axios adapter, upload progress propagation and new attachment progress UI. Additionally, it also moves pending attachment uploads onto `client.uploadManager`, adds local attachment id tracking, improves video/document attachment handling, and updates SampleApp to exercise the new native upload path. The reason why we decided to add an opt-in native upload is related to the fact that `axios` does not always report upload progress correctly on React Native, especially Android. It will sometimes either not update the progress at all or report it badly, causing UI glitches. Additionally, native uploads are much, much faster as we take advantage of streaming directly without any intermediate ephemeral files in order to do that. Finally, `axios` can easily break if an override to the underlying RN's `fetch` implementation has been made, especially on `Android`. ## What Changed - Added a shared native multipart upload module for iOS and Android, including request parsing, file/text multipart parts, progress events, cancellation, timeouts, response handling, and bounded response body reads. - Added native package and Expo package bindings for `StreamMultipartUploader`, plus native handler registration through `stream-chat-react-native` and `stream-chat-expo` - Added core JS helpers and public types for native multipart upload requests, responses, progress events, abort handling, and uploader creation - Added `installNativeMultipartAdapter` / `wrapAxiosAdapterWithNativeMultipart` to route multipart `FormData` axios requests through the native uploader when available, while leaving non-multipart requests on the existing adapter - Added `Chat` support for enabling native multipart uploads via `useNativeMultipartUpload`; SampleApp enables this path - Reworked pending message attachment uploads to use `client.uploadManager.upload` by local attachment id instead of directly calling `channel.sendImage` / `channel.sendFile` - Added `localId` propagation from local attachments into message attachments so pending uploads can be correlated with `client.uploadManager` - Updated message sendability and upload indicator behavior to depend on `allowSendBeforeAttachmentsUpload` rather than offline support - Added upload progress UI for image, video, file, and audio attachments, including circular determinate progress, media overlays, file/audio byte progress labels, and a short completion hold to avoid UI flicker - Added new overrideable/default components for attachment upload progress: `AttachmentUploadIndicator`, `CircularProgressIndicator`, and `MediaUploadProgressOverlay` - Updated gallery/video thumbnail rendering so pending media attachments can show upload progress overlays - Updated document picking in both native and Expo packages to generate thumbnails for picked video files (this was missing from V9 initially) - Updated iOS video thumbnail URL handling to strip query and fragment data from local file URLs - Refined native iOS shimmer behavior to reduce animation restarts, handle foreground/background transitions, visibility, alpha, trait changes, and resolved color updates more reliably (this should improve shimmer performance for iOS significantly) - Updated `Android` shared native source syncing to resolve shared native sources from the canonical project path - Replaced SampleApp’s `react-native-fast-image` dependency with `@d11/react-native-fast-image` ## 🛠 Implementation details <!-- Provide a description of the implementation --> ## 🎨 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 --------- Co-authored-by: Zita Szupera <szuperaz@gmail.com> | 5 个月前 | |
fix(android): set the Kotlin jvmTarget without requiring the Kotlin G… (#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. | 18 天前 | |
refactor: rn 0.87 compatibility (#3786) ## 🎯 Goal Support React Native 0.87. 0.87 makes the Strict TypeScript API the default and drops several types from the root `react-native` export, which breaks our type-check. Its Babel preset also miscompiles one of our shipped files. The SDK now builds, type-checks and runs on **both 0.86 and 0.87**. Peer range (`>= 0.76.0`) naturally remains unchanged, no public API removed. ## 🛠 Implementation details **Strict TypeScript API** - new `src/types/react-native-compat.ts` exporting `ViewRef`/`TextInputRef`/`ScrollViewRef`/`FlatListRef` etc. as `React.ComponentRef<typeof X>`. The "fix" is in the semantics, as it resolves to the old class-instance types on `<= 0.86` and the new ones on `0.87`, so we keep the `0.76` floor. Using RN's own `*Instance` names would have dropped everything below `0.87`. Same file redeclares `KeyboardEventListener`, `ViewToken` and `ViewabilityConfig`, which 0.87 no longer exports. **API shape changes** - `useColorScheme()` and `findNodeHandle()` have become `null`able, `AppState.currentState` widened to `string | null | undefined`, `FlatList`'s `data` and `ListFooterComponent` have stopped accepting `null`, style objects have become `Readonly`, `NativeEventEmitter` has become generic. `onAccessibilityAction` moved to `ViewProps`. **Type leaks** - explicit annotations on `Input`, `useAnimatedGalleryStyle`, `SafeAreaViewWrapper` and `ImageGalleryFooter`, plus a `ThemeStyle` union, to stop RN-internal names leaking into `lib/typescript`. **`SqliteClient` runtime fix** - statics were arrow class fields calling `this.foo()`. `0.87`'s Babel preset hoists that to a module-level `var _this = this`, so `lib/commonjs` shipped calls against the wrong object and threw. Now references the class explicitly. **Build config** - both wrappers' `tsconfig.json` opt into legacy deep-import types (the codegen spec must keep the deep `codegenNativeComponent` import; the root export only exists from 0.80). Android: Java 1.8 => 17, Kotlin 1.7 => 2.2, `minSdk` 21 => 24, `compileSdk` fallback 31 => 34. `compileSdk` is 34 rather than 37 on purpose, as `0.87`'s `react-android` declares `minCompileSdk=34` and a library's `compileSdk` caps what *we* may call, it isn't a floor on integrators. It's only reached when the app doesn't set `rootProject.ext.compileSdkVersion`, which basically any app always does. **Jest** - two `moduleNameMapper` shims, both third-party: For our integration tests to work I had to do some mental gymnastics to get everything off the ground. - `react-native-svg` (<= `15.15.5`) reads `Touchable.Mixin` off the RN root. `0.87` keeps that export alive for exactly this call site but installs it late and non-enumerably, so Babel's ESM interop drops it under Jest. - reanimated `4.6.0`'s `initializeReanimatedModule()` calls `setCSSEventHandler()` unconditionally, which throws on the JS only backend Jest uses. `moduleNameMapper` rather than `jest.mock('react-native', …)` because it's resolver-level, so it also covers the separate registry Jest builds for automocks and it doesn't shadow per suite RN mocks. **Example apps** - SampleApp gets the AGP 9 proguard fix (`proguard-android-optimize.txt`; AGP 9 rejects `proguard-android.txt` outright and since it's evaluated at configuration time it breaks the *debug* build too), AGP 9 opt-outs, SDK 37/36, and 13 strict-API fixes in its own code. ExpoMessaging deliberately stays on Expo 57 / RN 0.86 for now, while Expo `58` remains canary only and holding it back doubles as backwards-compat coverage for now. Once 58 ships we can likely bump that too pretty easily. **Native source** - no changes. None of `0.87`'s removed native APIs are used, headers already use the namespaced `<React/...>` form, and `StreamShimmerViewComponentView` already sets `_props = defaultProps` in `initWithFrame` — the thing `0.87` now asserts on. ## 🎨 UI Changes ## 🧪 Testing ## ☑️ 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 - [x] New code is tested in main example apps, including all possible scenarios - [x] SampleApp iOS and Android - [ ] Expo iOS and Android | 1 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 5 个月前 | ||
| 18 天前 | ||
| 1 个月前 |