| ๆไปถ | ๆๅๆไบค่ฎฐๅฝ | ๆๅๆดๆฐๆถ้ด |
|---|---|---|
feat: offline db encryption (#3780) ## ๐ฏ Goal Let integrators encrypt the offline database at rest. The offline cache stores channels, messages, members, drafts and reminders, and right now we write all of it as plaintext `SQLite`. It's opt-in. Apps that don't pass the new prop behave exactly as they do today. One thing to know up front, since it shapes the rest of the PR: `op-sqlite` accepts an `encryptionKey` on a build without `SQLCipher` and then ignores it. You get a plaintext database and no error at any layer. So part of this change is detecting that and refusing to open the database, instead of passing the key along and assuming it was used. Accompanying docs PR: https://github.com/GetStream/docs-content/pull/1521 ## ๐ Implementation details ### API `Chat` takes one new prop: ```tsx <Chat client={client} enableOfflineSupport getEncryptionKey={getEncryptionKey}> ``` `getEncryptionKey?: () => Promise<string | undefined>` runs once per database open, so once per launch and again after a sign-out. Its result is passed to `SQLCipher` through `op-sqlite`. `SqliteClientError` and `SqliteClientErrorCode` are exported too. ### We throw instead of recovering When the database can't be opened with the encryption that was asked for, `Chat` throws a `SqliteClientError` from render and the integrator's error boundary handles it. We don't fall back to plaintext, we don't switch offline support off, and we don't delete anything. The reason is that all of those recoveries have a security consequence and there's no default that's right for everyone. Falling back to plaintext defeats the point of the feature and nothing tells you it happened. Dropping the cache decides a compliance question for the integrator. Deleting the file throws away offline actions that are still queued. We also can't tell "the Keystore isn't unlocked yet, try again shortly" from "something is wrong here, sign this device out". So we detect the failure and classify it, and the app decides what to do about it. ### Scenarios | Scenario | What it means | What the SDK does | Recommended recovery | | ------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------------ | | No `getEncryptionKey` passed | Encryption not requested | Opens plaintext, same as today | n/a | | Key supplied, fresh install | Nothing on disk yet | Creates the database encrypted with that key | n/a | | Key supplied, plaintext database already on disk | Integrator is turning encryption on for an existing install | Throws `OFFLINE_DB_UNREADABLE` | Delete the database, remount `Chat` | | Key differs from the one the database was written with | Key rotated, or read from the wrong place | Throws `OFFLINE_DB_UNREADABLE` | Delete the database, remount `Chat` | | `getEncryptionKey` removed, encrypted database on disk | Integrator is turning encryption off again | Throws `OFFLINE_DB_UNREADABLE` | Delete the database, remount `Chat` | | `getEncryptionKey` throws | Key isn't available yet, e.g. Keystore still locked | Throws `ENCRYPTION_KEY_UNAVAILABLE` | Remount to retry, e.g. on next app foreground | | `getEncryptionKey` resolves `undefined` | Same as above | Throws `ENCRYPTION_KEY_UNAVAILABLE` | Remount to retry, e.g. on next app foreground | | Key supplied, native build has no `SQLCipher` | The key would be ignored and the database left plaintext | Throws `SQLCIPHER_BUILD_MISSING`, doesn't open | Not fixable at runtime, remount with `enableOfflineSupport={false}` | | Database file corrupted | Nothing to do with encryption | Throws `OFFLINE_DB_UNREADABLE` | Delete the database, remount `Chat` | Two of those rows need a closer look in review. `OFFLINE_DB_UNREADABLE` is not gated on `getEncryptionKey` being set, and that's on purpose, because of the "turning encryption off again" row. If we only threw it when a key was supplied, an integrator removing the prop would get a blank screen instead of an error they can recover from. I hit that on device. The last row is why the boundary is useful even for apps that never use encryption. A corrupted database gives you the same code, so anything using `enableOfflineSupport` can end up there. ### Where the error comes from `AbstractOfflineDB.init` in the LLC catches whatever `initializeDB` throws and doesn't re-throw it, so a caller can't find out why initialisation failed. I left that alone, because changing it would tie this PR to an LLC release. `OfflineDB` stores the reason on the instance on the way out instead, and the new hook reads it back once `init` has settled. No LLC changes needed for this. - `SqliteClient` resolves the key, opens through `SQLCipher` and maps failures onto the codes above. It also gets `preflightEncryption()`, which runs before `setOfflineDBApi`. Without that ordering the client attaches a database that's already dead, and the unguarded `await this.offlineDb.upsertChannels(...)` inside `queryChannels` rejects. You end up on a loading screen that never resolves. - `useInitializeOfflineDb()` is new and does preflight, attach, init and raise, with the init options behind an `options` param. It's pulled out of `Chat`, which loses 72 lines. - `OfflineDB` records `initializationError` and re-throws, so `init` still marks the database uninitialised. ## ๐จ UI Changes ## ๐งช Testing <!-- Explain how this change can be tested (or why it can't be tested) --> ## โ๏ธ Checklist - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [x] PR targets the `develop` branch - [x] Documentation is updated - [ ] New code is tested in main example apps, including all possible scenarios - [ ] SampleApp iOS and Android - [ ] Expo iOS and Android | 20 ๅคฉๅ | |
feat: channel info screens (#3590) 1/2 PR for channel details | [Figma](https://www.figma.com/design/Us73erK1xFNcB5EH3hyq6Y/Chat-SDK-Design-System?node-id=21176-240736&m=dev) This PR implements the 20/25 channel details related Figma screens. The rest will come in a separate PR. The missing screens are implemented in SampleApp (as channel details screens are currently implemented there). All new components/hooks/contexts are marked as experimental by the SDK, the flag will be removed once channel details are fully implemented. Some follow-up tasks we discovered with Ivan that are not related to channel details, I'll implement it in separate follow-up PRs: - Move channel actions override to channel preview (and deprecate channel list override?) - Add capability checks to channel actions - Add an alert to existing destructive actions - Add search to members screen - Fix useChannelMemberOnlineCount - Finalize role display Overview of implemented screens: <img width="1792" height="752" alt="Screenshot 2026-06-03 at 12 25 02" src="https://github.com/user-attachments/assets/04e5279c-017c-4646-8048-4a1c0ef79133" /> Some screenshots, mixed from iOS and Android, dark and light theme: <img height="500" alt="IMG_1242" src="https://github.com/user-attachments/assets/36d2b468-25d3-4022-a695-e8b2eeb53103" /> <img height="500" alt="Screenshot_20260602_204533_Chat Sample React Native" src="https://github.com/user-attachments/assets/c943ce6d-dea8-4482-8a6d-d91389fc0f6b" /> <img height="500" alt="IMG_1247" src="https://github.com/user-attachments/assets/bf26308b-2e1e-46ea-891c-e3b8fb6f35b8" /> <img height="500" alt="Screenshot_20260602_204600_Chat Sample React Native" src="https://github.com/user-attachments/assets/b5a877dd-3f52-47cb-b90f-8c387414ae77" /> <img height="500" alt="Screenshot_20260602_204615_Chat Sample React Native" src="https://github.com/user-attachments/assets/7fc08a5a-b553-46dc-81a2-4202789c5df0" /> <img height="500" alt="IMG_1246" src="https://github.com/user-attachments/assets/fd39e56b-94cc-4826-9916-c4591366b2a5" /> <img height="500" alt="Screenshot_20260602_204633_Chat Sample React Native" src="https://github.com/user-attachments/assets/18f172ff-c649-4946-b9bb-76de2960ab99" /> Claude's recap: The headline of this branch is a brand-new **Channel Details screen** shipped as a reusable SDK component, with the SampleApp migrated off its old custom overlay implementation. ## SampleApp **Removed** the entire legacy overlay-based channel info system: - Overlay infrastructure: `AppOverlayContext`, `AppOverlayProvider`, `ChannelInfoOverlayContext`, `UserInfoOverlayContext`, `OverlayBackdrop`, `ChannelInfoOverlay`, `UserInfoOverlay`, `ContactDetailBottomSheet` - Old member UI: `AddMembersBottomSheet`, `AllMembersBottomSheet`, `MemberListItem`, `ChannelDetailProfileSection`, and hooks `useChannelInfoOverlayActions` / `useUserInfoOverlayActions` - Old screens: `GroupChannelDetailsScreen`, `OneOnOneChannelDetailScreen`, `SharedGroupsScreen` **Added / updated:** - New thin `ChannelDetailsScreen` that consumes the SDK component, plus a `ChannelDetailsNavigationSection` override example - New `SendDirectMessage` icon (removed `Archive`, `UserMinus`) - Updated `ChannelListScreen`, `ChannelScreen`, `NewDirectMessagingScreen`, `App.tsx`, `types.ts`, and `SampleAppComponentOverrides` to wire up the new screen ## SDK โ new **`ChannelDetailsScreen` component suite** (new export from `components/index.ts`): - Core: `ChannelDetailsScreen`, `ChannelDetailsProfile`, `ChannelDetailsActionsSection`, `ChannelDetailsActionItem`, `ChannelDetailsMemberSection`, `ChannelDetailsNavigationSection`, `ChannelDetailsScreenHeader` - Edit flow: `ChannelEditDetails`, `ChannelEditDetailsModal`, `ChannelEditName`, `ChannelEditImageSheet` - Members: `ChannelMemberList`, `ChannelMemberItem`, `ChannelMemberActionsSheet`, `ChannelAddMembers` (+modal), `ChannelAllMembersModal`, `AddMemberSearchResultItem`, and loading skeletons - Generic `Modal` / `ModalHeader` building blocks **New hooks** โ `package/src/hooks/actions/` namespace (`useChannelActions`, `useChannelActionItems`, `useChannelMemberActionItems`, `useUserActions`, shared `types`), feature hooks (`useChannelDetailsActionItems`, `useChannelDetailsMembersPreview`, `useChannelDetailsMemberStatusText`, `useEditChannelImage`, `useUserActivityStatus`, `useChannelAddMembers`, `useChannelAllMembers`, `useMemberRoleLabel`), and reusable channel hooks now exported publicly: `useChannelName`, `useChannelImage`, `useChannelMemberCount`, `useChannelOwnCapabilities`, `useChannelMuteActive`, `useIsDirectChat`, plus `useSyncClientEvents` (reactive channel name/image/member-count updates) **New reusable UI / contexts / icons:** - UI components: `SearchInput`, `SelectionCircle`, `EmptySearchResult` - Contexts: `channelDetailsContext` and `BottomSheetContext` - Icons: `chevron-right`, `x-circle` - ~196 lines of new theme tokens for the new components - ~50 new translation keys across all 14 locales (member roles, add-members, edit-channel, a11y labels) ## SDK โ updates to existing - **BottomSheetModal** โ reworked (~100 lines); fixes the iOS close-callback-fires-too-early bug and now exposes context via the new `BottomSheetContext` - **ChannelAvatar** โ extended to show a live preview of pending channel-image changes - **Hook relocations** โ `useChannelActions` / `useChannelActionItems` / `useIsDirectChat` / `useChannelMuteActive` moved out of `ChannelList/hooks` into the shared `src/hooks` tree (and `useChannelActions` significantly extended: `onFailure`/`onSuccess` handlers, member/image/name updates, separate dismiss API) - **componentsContext** โ registered the new components as defaults (~31 lines); `OwnCapabilitiesContext` gained a capability - **ChannelPreview** โ `ChannelDetailsBottomSheet` and `ChannelSwipableWrapper` updated; `useChannelPreviewDisplayName` / `useUserMuteActive` tweaked - **camera icon redesign** โ drove snapshot updates for `AttachButton`, `SendButton`, `Thread` - **notificationTarget** โ minor update for channel-delete/edit notifications - Repo housekeeping: `CLAUDE.md` typecheck note, accessibility skill tweak, new RTL skill **Scale:** ~80 commits, +12,961 / โ3,635 across 166 files, with a large accompanying test suite (~40 new `__tests__` file --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 2 ไธชๆๅ | |
chore: upgrade to TypeScript 6.0.3, ES2022 target, and shared ts-config presets (#3663) ## What & why Upgrades every workspace to **TypeScript 6.0.3** with **`target: ES2022`**, and removes tsconfig duplication via a new shared preset package. Enabling type-checking across the previously-unchecked packages also surfaced (and this PR fixes) a pre-existing bug in the core package's published type resolution plus a batch of latent type errors. ## Changes ### Shared config - New **private** `@stream-io/typescript-config` workspace (`configs/typescript-config/`): - `base.json` โ cross-cutting policy (ES2022 target, strict, interop, โฆ) - `library.json` โ full React Native library config (extends `base`) - Core, the native/expo wrappers, and all 3 example apps extend these instead of duplicating compiler options. Example apps array-extend `["<framework base>", "@stream-io/typescript-config/base.json"]`. ### TypeScript 6.0.3 / ES2022 - TS `6.0.3` in all 7 manifests; `target: ES2022` everywhere. - `lib` kept at `ESNext` โ the SDK uses the ES2023 `Array.prototype.toReversed()`. - TS 6.0 no longer auto-includes `@types/jest`, so it's referenced explicitly from a test-only `package/src/__tests__/jest-globals.d.ts` (excluded from the published build). ### Core publishing fix (consumer-facing) - `react-native-builder-bob` emitted declarations under `lib/typescript/src/` while `package.json#types` pointed at `lib/typescript/index.d.ts` โ so TS consumers couldn't resolve the SDK's types via `types`. Added `rootDir: "./src"` so declarations emit flat to match `types`. This was also the root cause that blocked the wrappers/examples from resolving core's types. - Exported `PickImageOptions` from the core entrypoint (defined+exported in `native.ts` but never surfaced from `index`). ### Wrappers (`stream-chat-react-native`, `stream-chat-expo`) - Added a `typecheck` script + tsconfig (they had neither). The dynamic optional-`require` shims relax `noImplicitAny`/`strictNullChecks`/unused checks (kept `noImplicitReturns`). - Fixed real bugs: missing `return`s in `shareImage`, missing `resizeMode`/`rate` on the video shim, an inconsistent `startRecording` return shape. ### Example apps - Fixed ~60 pre-existing latent type errors unmasked by enabling typecheck: theme palette typing (the legacy flat `colors` palette, read via a local `AppTheme` cast โ behavior-preserving), null-safety guards, and several SDK-API-drift fixes. ### CI - `check-pr.yml` now runs `yarn typecheck` across the whole workspace (core + 2 wrappers + 3 examples) instead of only the core package; the root `typecheck` aggregate includes the wrappers. ## Verification - `yarn build` โ
- `yarn typecheck` (core + 2 wrappers + 3 examples) โ
**0 errors** - `yarn lint` โ
## Notes for reviewers - **Commit type**: filed as `chore:` (release-neutral). The core changes (flat `types` path + `PickImageOptions` export) are genuinely consumer-facing โ if you want them shipped, retype as `fix:` to cut a patch. - **Wrapper strictness**: `strictNullChecks`/`noImplicitAny` are relaxed **only** for the two wrapper packages (dynamic optional-dep shims), not for core. - **Example theming**: the apps' custom `colors` palette was already inert for SDK theming (the SDK reads semantics/primitives, not `theme.colors`); this PR preserves that behavior. Migrating the palette to the token model to restore custom branding would be a separate enhancement. - Did not run the full unit suite locally (the only core source change is the additive `PickImageOptions` export); CI runs `test:coverage`. --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 1 ไธชๆๅ | |
chore: upgrade to TypeScript 6.0.3, ES2022 target, and shared ts-config presets (#3663) ## What & why Upgrades every workspace to **TypeScript 6.0.3** with **`target: ES2022`**, and removes tsconfig duplication via a new shared preset package. Enabling type-checking across the previously-unchecked packages also surfaced (and this PR fixes) a pre-existing bug in the core package's published type resolution plus a batch of latent type errors. ## Changes ### Shared config - New **private** `@stream-io/typescript-config` workspace (`configs/typescript-config/`): - `base.json` โ cross-cutting policy (ES2022 target, strict, interop, โฆ) - `library.json` โ full React Native library config (extends `base`) - Core, the native/expo wrappers, and all 3 example apps extend these instead of duplicating compiler options. Example apps array-extend `["<framework base>", "@stream-io/typescript-config/base.json"]`. ### TypeScript 6.0.3 / ES2022 - TS `6.0.3` in all 7 manifests; `target: ES2022` everywhere. - `lib` kept at `ESNext` โ the SDK uses the ES2023 `Array.prototype.toReversed()`. - TS 6.0 no longer auto-includes `@types/jest`, so it's referenced explicitly from a test-only `package/src/__tests__/jest-globals.d.ts` (excluded from the published build). ### Core publishing fix (consumer-facing) - `react-native-builder-bob` emitted declarations under `lib/typescript/src/` while `package.json#types` pointed at `lib/typescript/index.d.ts` โ so TS consumers couldn't resolve the SDK's types via `types`. Added `rootDir: "./src"` so declarations emit flat to match `types`. This was also the root cause that blocked the wrappers/examples from resolving core's types. - Exported `PickImageOptions` from the core entrypoint (defined+exported in `native.ts` but never surfaced from `index`). ### Wrappers (`stream-chat-react-native`, `stream-chat-expo`) - Added a `typecheck` script + tsconfig (they had neither). The dynamic optional-`require` shims relax `noImplicitAny`/`strictNullChecks`/unused checks (kept `noImplicitReturns`). - Fixed real bugs: missing `return`s in `shareImage`, missing `resizeMode`/`rate` on the video shim, an inconsistent `startRecording` return shape. ### Example apps - Fixed ~60 pre-existing latent type errors unmasked by enabling typecheck: theme palette typing (the legacy flat `colors` palette, read via a local `AppTheme` cast โ behavior-preserving), null-safety guards, and several SDK-API-drift fixes. ### CI - `check-pr.yml` now runs `yarn typecheck` across the whole workspace (core + 2 wrappers + 3 examples) instead of only the core package; the root `typecheck` aggregate includes the wrappers. ## Verification - `yarn build` โ
- `yarn typecheck` (core + 2 wrappers + 3 examples) โ
**0 errors** - `yarn lint` โ
## Notes for reviewers - **Commit type**: filed as `chore:` (release-neutral). The core changes (flat `types` path + `PickImageOptions` export) are genuinely consumer-facing โ if you want them shipped, retype as `fix:` to cut a patch. - **Wrapper strictness**: `strictNullChecks`/`noImplicitAny` are relaxed **only** for the two wrapper packages (dynamic optional-dep shims), not for core. - **Example theming**: the apps' custom `colors` palette was already inert for SDK theming (the SDK reads semantics/primitives, not `theme.colors`); this PR preserves that behavior. Migrating the palette to the token model to restore custom branding would be a separate enhancement. - Did not run the full unit suite locally (the only core source change is the additive `PickImageOptions` export); CI runs `test:coverage`. --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 1 ไธชๆๅ | |
chore: upgrade to TypeScript 6.0.3, ES2022 target, and shared ts-config presets (#3663) ## What & why Upgrades every workspace to **TypeScript 6.0.3** with **`target: ES2022`**, and removes tsconfig duplication via a new shared preset package. Enabling type-checking across the previously-unchecked packages also surfaced (and this PR fixes) a pre-existing bug in the core package's published type resolution plus a batch of latent type errors. ## Changes ### Shared config - New **private** `@stream-io/typescript-config` workspace (`configs/typescript-config/`): - `base.json` โ cross-cutting policy (ES2022 target, strict, interop, โฆ) - `library.json` โ full React Native library config (extends `base`) - Core, the native/expo wrappers, and all 3 example apps extend these instead of duplicating compiler options. Example apps array-extend `["<framework base>", "@stream-io/typescript-config/base.json"]`. ### TypeScript 6.0.3 / ES2022 - TS `6.0.3` in all 7 manifests; `target: ES2022` everywhere. - `lib` kept at `ESNext` โ the SDK uses the ES2023 `Array.prototype.toReversed()`. - TS 6.0 no longer auto-includes `@types/jest`, so it's referenced explicitly from a test-only `package/src/__tests__/jest-globals.d.ts` (excluded from the published build). ### Core publishing fix (consumer-facing) - `react-native-builder-bob` emitted declarations under `lib/typescript/src/` while `package.json#types` pointed at `lib/typescript/index.d.ts` โ so TS consumers couldn't resolve the SDK's types via `types`. Added `rootDir: "./src"` so declarations emit flat to match `types`. This was also the root cause that blocked the wrappers/examples from resolving core's types. - Exported `PickImageOptions` from the core entrypoint (defined+exported in `native.ts` but never surfaced from `index`). ### Wrappers (`stream-chat-react-native`, `stream-chat-expo`) - Added a `typecheck` script + tsconfig (they had neither). The dynamic optional-`require` shims relax `noImplicitAny`/`strictNullChecks`/unused checks (kept `noImplicitReturns`). - Fixed real bugs: missing `return`s in `shareImage`, missing `resizeMode`/`rate` on the video shim, an inconsistent `startRecording` return shape. ### Example apps - Fixed ~60 pre-existing latent type errors unmasked by enabling typecheck: theme palette typing (the legacy flat `colors` palette, read via a local `AppTheme` cast โ behavior-preserving), null-safety guards, and several SDK-API-drift fixes. ### CI - `check-pr.yml` now runs `yarn typecheck` across the whole workspace (core + 2 wrappers + 3 examples) instead of only the core package; the root `typecheck` aggregate includes the wrappers. ## Verification - `yarn build` โ
- `yarn typecheck` (core + 2 wrappers + 3 examples) โ
**0 errors** - `yarn lint` โ
## Notes for reviewers - **Commit type**: filed as `chore:` (release-neutral). The core changes (flat `types` path + `PickImageOptions` export) are genuinely consumer-facing โ if you want them shipped, retype as `fix:` to cut a patch. - **Wrapper strictness**: `strictNullChecks`/`noImplicitAny` are relaxed **only** for the two wrapper packages (dynamic optional-dep shims), not for core. - **Example theming**: the apps' custom `colors` palette was already inert for SDK theming (the SDK reads semantics/primitives, not `theme.colors`); this PR preserves that behavior. Migrating the palette to the token model to restore custom branding would be a separate enhancement. - Did not run the full unit suite locally (the only core source change is the additive `PickImageOptions` export); CI runs `test:coverage`. --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 1 ไธชๆๅ | |
chore: upgrade to TypeScript 6.0.3, ES2022 target, and shared ts-config presets (#3663) ## What & why Upgrades every workspace to **TypeScript 6.0.3** with **`target: ES2022`**, and removes tsconfig duplication via a new shared preset package. Enabling type-checking across the previously-unchecked packages also surfaced (and this PR fixes) a pre-existing bug in the core package's published type resolution plus a batch of latent type errors. ## Changes ### Shared config - New **private** `@stream-io/typescript-config` workspace (`configs/typescript-config/`): - `base.json` โ cross-cutting policy (ES2022 target, strict, interop, โฆ) - `library.json` โ full React Native library config (extends `base`) - Core, the native/expo wrappers, and all 3 example apps extend these instead of duplicating compiler options. Example apps array-extend `["<framework base>", "@stream-io/typescript-config/base.json"]`. ### TypeScript 6.0.3 / ES2022 - TS `6.0.3` in all 7 manifests; `target: ES2022` everywhere. - `lib` kept at `ESNext` โ the SDK uses the ES2023 `Array.prototype.toReversed()`. - TS 6.0 no longer auto-includes `@types/jest`, so it's referenced explicitly from a test-only `package/src/__tests__/jest-globals.d.ts` (excluded from the published build). ### Core publishing fix (consumer-facing) - `react-native-builder-bob` emitted declarations under `lib/typescript/src/` while `package.json#types` pointed at `lib/typescript/index.d.ts` โ so TS consumers couldn't resolve the SDK's types via `types`. Added `rootDir: "./src"` so declarations emit flat to match `types`. This was also the root cause that blocked the wrappers/examples from resolving core's types. - Exported `PickImageOptions` from the core entrypoint (defined+exported in `native.ts` but never surfaced from `index`). ### Wrappers (`stream-chat-react-native`, `stream-chat-expo`) - Added a `typecheck` script + tsconfig (they had neither). The dynamic optional-`require` shims relax `noImplicitAny`/`strictNullChecks`/unused checks (kept `noImplicitReturns`). - Fixed real bugs: missing `return`s in `shareImage`, missing `resizeMode`/`rate` on the video shim, an inconsistent `startRecording` return shape. ### Example apps - Fixed ~60 pre-existing latent type errors unmasked by enabling typecheck: theme palette typing (the legacy flat `colors` palette, read via a local `AppTheme` cast โ behavior-preserving), null-safety guards, and several SDK-API-drift fixes. ### CI - `check-pr.yml` now runs `yarn typecheck` across the whole workspace (core + 2 wrappers + 3 examples) instead of only the core package; the root `typecheck` aggregate includes the wrappers. ## Verification - `yarn build` โ
- `yarn typecheck` (core + 2 wrappers + 3 examples) โ
**0 errors** - `yarn lint` โ
## Notes for reviewers - **Commit type**: filed as `chore:` (release-neutral). The core changes (flat `types` path + `PickImageOptions` export) are genuinely consumer-facing โ if you want them shipped, retype as `fix:` to cut a patch. - **Wrapper strictness**: `strictNullChecks`/`noImplicitAny` are relaxed **only** for the two wrapper packages (dynamic optional-dep shims), not for core. - **Example theming**: the apps' custom `colors` palette was already inert for SDK theming (the SDK reads semantics/primitives, not `theme.colors`); this PR preserves that behavior. Migrating the palette to the token model to restore custom branding would be a separate enhancement. - Did not run the full unit suite locally (the only core source change is the additive `PickImageOptions` export); CI runs `test:coverage`. --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 1 ไธชๆๅ | |
fix(a11y): focus inputs on enter and page transitions (#3671) ## ๐ฏ Goal When a screen-reader user opens a channel or thread, VoiceOver/TalkBack focus previously landed on an arbitrary stop (the back button, or a message mid-list). This moves the entry point to where the user acts โ the message composer โ while keeping the header/back reachable via standard OS gestures. - Add `useSetAccessibilityFocus()` - a public, generic primitive that moves the screen reader cursor onto a ref/node (SR-gated, RAF deferred). It only moves accessibility focus; it never opens the keyboard or activates the field. - Add `useScreenReaderMountFocus(ref)` - built on the primitive; focuses on mount (and once the SR state resolves). `MessageComposer` uses it on `inputBoxRef`, so the composer is focused on entry. This is the path that lands Android forward navigation as well (but not always on iOS, which is why we need the actual transitional effect as well) `SampleApp` reference implementation: - `useScreenReaderComposerFocusEffect` - wires React Navigation's `transitionEnd` to `useSetAccessibilityFocus`, covering back navigation (both platforms) and iOS forward navigation (where firing on mount loses a race with the OS focus pass). Returns a stable `setInputRef` for `<Channel>`. - Header reachability is done by adding `accessibilityRole='header'` on the screen header title (reachable via iOS Headings rotor / jump to top and Android Headings reading control swipe up) and `onAccessibilityEscape` -> `goBack` on the screen root for the iOS back scrub (Android uses the system Back gesture). Note: `onAccessibilityEscape` is inert on a layout only `View` under `Fabric` - it gets flattened and never receives the gesture. The view hosting it needs `collapsable={false}` if it does not apply any `layout` relevant props itself. ## ๐ 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 | 2 ไธชๆๅ | |
feat: V7 (#2999) * chore: modify gh workflows * feat: removal of StreamChatGenerics (#2993) * feat: remove StreamChatGenerics and introduce interface merging * fix: some of the outstanding todos * chore: add default interfaces * chore: remove SCG from sample app * fix: remove redundant types * fix: remove type module * fix: change the way interface declaration is consumed * fix: ignore ts complaints for interface declaration * chore: migrate TypescriptMessagingApp away from SCG * chore: migrate the Expo sample app away from SCG * fix: commit missing files * fix: revert mistaken change * fix: add resolutions for symlinked libs * chore: remove support for react-native-document-picker (#3000) * BREAKING CHANGE: V7 release candidate * chore: add rc channel * fix: typo in branch name * feat: trigger breaking change for v7 (#3005) BREAKING CHANGE: Release V7 * chore: remove dryRun * chore: bump stream-chat version to latest rc * chore: bump stream-chat to latest * feat: introduce expo-video support (#3010) * feat: introduce support for expo-video * fix: remove redundant test * fix: add check for audio component * fix: lint issues * fix: different types inference with latest stream-chat changes * chore(deps): update sample apps too * fix: remove generics from new hook * fix: remove remnants from SCG and fix missing types * fix: lint issues * fix: replace TouchableOpacity with Pressable * fix: move to RN TouchableOpacity instead * chore(deps): update peer deps * chore: remove unused hooks * chore: remove deps scope * fix: all instances of FormatMessageResponse in respect to the new llc changes * chore: ref branch specifically * fix: try clearing cache * fix: remove cache clean * fix: remove console.log * fix: use latest commit * fix: use latest rc of llc * chore: use specific commit again * fix: SCG remnants from merge * fix: lint issues * fix: lint issues * fix: unify file and image types (#3050) * fix: unify file and image types * fix: refine types * fix: remove props from auto complete input * chore: update deps * fix: failing tests and AutoCompleteInput type * chore: update custom data module interfaces * fix: change RNFile to FileReference as per latest client changes (#3061) * fix: merge conflicts * fix: remove MessageType type from the SDK * fix: resolve conflicts from V7 branch * fix: broken tests * fix: useMessageActions remove reserved fields logic * revert: useMessageActions change * fix: confine readBy data to Message Status component * fix: change date separator and group styles to ref * fix: add app changes * fix: bump stream-chat to latest rc * chore: bump stream-chat version to latest rc again * fix: thread messages state not updating properly * chore: change type to inferred one * fix: set correct core lib versions * chore: bump stream-chat to latest rc again * chore: update sample app yarn.locks as well * fix: keyboard taking full screen issue when the prefer cross-fade transition setting is enabled (#3073) * fix: respect the hasCommand channel prop as well * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled (#3072) * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled * chore: bump stream-chat-js rc again * chore: full reinstall after merge from develop * fix: add back mistakenly removed mime dep * fix: revert gh action changes * chore: bump stream-chat to latest stable major --------- Co-authored-by: Khushal Agarwal <khushal.agarwal987@gmail.com> | 1 ๅนดๅ | |
feat: V7 (#2999) * chore: modify gh workflows * feat: removal of StreamChatGenerics (#2993) * feat: remove StreamChatGenerics and introduce interface merging * fix: some of the outstanding todos * chore: add default interfaces * chore: remove SCG from sample app * fix: remove redundant types * fix: remove type module * fix: change the way interface declaration is consumed * fix: ignore ts complaints for interface declaration * chore: migrate TypescriptMessagingApp away from SCG * chore: migrate the Expo sample app away from SCG * fix: commit missing files * fix: revert mistaken change * fix: add resolutions for symlinked libs * chore: remove support for react-native-document-picker (#3000) * BREAKING CHANGE: V7 release candidate * chore: add rc channel * fix: typo in branch name * feat: trigger breaking change for v7 (#3005) BREAKING CHANGE: Release V7 * chore: remove dryRun * chore: bump stream-chat version to latest rc * chore: bump stream-chat to latest * feat: introduce expo-video support (#3010) * feat: introduce support for expo-video * fix: remove redundant test * fix: add check for audio component * fix: lint issues * fix: different types inference with latest stream-chat changes * chore(deps): update sample apps too * fix: remove generics from new hook * fix: remove remnants from SCG and fix missing types * fix: lint issues * fix: replace TouchableOpacity with Pressable * fix: move to RN TouchableOpacity instead * chore(deps): update peer deps * chore: remove unused hooks * chore: remove deps scope * fix: all instances of FormatMessageResponse in respect to the new llc changes * chore: ref branch specifically * fix: try clearing cache * fix: remove cache clean * fix: remove console.log * fix: use latest commit * fix: use latest rc of llc * chore: use specific commit again * fix: SCG remnants from merge * fix: lint issues * fix: lint issues * fix: unify file and image types (#3050) * fix: unify file and image types * fix: refine types * fix: remove props from auto complete input * chore: update deps * fix: failing tests and AutoCompleteInput type * chore: update custom data module interfaces * fix: change RNFile to FileReference as per latest client changes (#3061) * fix: merge conflicts * fix: remove MessageType type from the SDK * fix: resolve conflicts from V7 branch * fix: broken tests * fix: useMessageActions remove reserved fields logic * revert: useMessageActions change * fix: confine readBy data to Message Status component * fix: change date separator and group styles to ref * fix: add app changes * fix: bump stream-chat to latest rc * chore: bump stream-chat version to latest rc again * fix: thread messages state not updating properly * chore: change type to inferred one * fix: set correct core lib versions * chore: bump stream-chat to latest rc again * chore: update sample app yarn.locks as well * fix: keyboard taking full screen issue when the prefer cross-fade transition setting is enabled (#3073) * fix: respect the hasCommand channel prop as well * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled (#3072) * fix: keybaord taking full screen issue when the prefer cross-fade transition setting is enabled * chore: bump stream-chat-js rc again * chore: full reinstall after merge from develop * fix: add back mistakenly removed mime dep * fix: revert gh action changes * chore: bump stream-chat to latest stable major --------- Co-authored-by: Khushal Agarwal <khushal.agarwal987@gmail.com> | 1 ๅนดๅ | |
feat: channel info screens (#3590) 1/2 PR for channel details | [Figma](https://www.figma.com/design/Us73erK1xFNcB5EH3hyq6Y/Chat-SDK-Design-System?node-id=21176-240736&m=dev) This PR implements the 20/25 channel details related Figma screens. The rest will come in a separate PR. The missing screens are implemented in SampleApp (as channel details screens are currently implemented there). All new components/hooks/contexts are marked as experimental by the SDK, the flag will be removed once channel details are fully implemented. Some follow-up tasks we discovered with Ivan that are not related to channel details, I'll implement it in separate follow-up PRs: - Move channel actions override to channel preview (and deprecate channel list override?) - Add capability checks to channel actions - Add an alert to existing destructive actions - Add search to members screen - Fix useChannelMemberOnlineCount - Finalize role display Overview of implemented screens: <img width="1792" height="752" alt="Screenshot 2026-06-03 at 12 25 02" src="https://github.com/user-attachments/assets/04e5279c-017c-4646-8048-4a1c0ef79133" /> Some screenshots, mixed from iOS and Android, dark and light theme: <img height="500" alt="IMG_1242" src="https://github.com/user-attachments/assets/36d2b468-25d3-4022-a695-e8b2eeb53103" /> <img height="500" alt="Screenshot_20260602_204533_Chat Sample React Native" src="https://github.com/user-attachments/assets/c943ce6d-dea8-4482-8a6d-d91389fc0f6b" /> <img height="500" alt="IMG_1247" src="https://github.com/user-attachments/assets/bf26308b-2e1e-46ea-891c-e3b8fb6f35b8" /> <img height="500" alt="Screenshot_20260602_204600_Chat Sample React Native" src="https://github.com/user-attachments/assets/b5a877dd-3f52-47cb-b90f-8c387414ae77" /> <img height="500" alt="Screenshot_20260602_204615_Chat Sample React Native" src="https://github.com/user-attachments/assets/7fc08a5a-b553-46dc-81a2-4202789c5df0" /> <img height="500" alt="IMG_1246" src="https://github.com/user-attachments/assets/fd39e56b-94cc-4826-9916-c4591366b2a5" /> <img height="500" alt="Screenshot_20260602_204633_Chat Sample React Native" src="https://github.com/user-attachments/assets/18f172ff-c649-4946-b9bb-76de2960ab99" /> Claude's recap: The headline of this branch is a brand-new **Channel Details screen** shipped as a reusable SDK component, with the SampleApp migrated off its old custom overlay implementation. ## SampleApp **Removed** the entire legacy overlay-based channel info system: - Overlay infrastructure: `AppOverlayContext`, `AppOverlayProvider`, `ChannelInfoOverlayContext`, `UserInfoOverlayContext`, `OverlayBackdrop`, `ChannelInfoOverlay`, `UserInfoOverlay`, `ContactDetailBottomSheet` - Old member UI: `AddMembersBottomSheet`, `AllMembersBottomSheet`, `MemberListItem`, `ChannelDetailProfileSection`, and hooks `useChannelInfoOverlayActions` / `useUserInfoOverlayActions` - Old screens: `GroupChannelDetailsScreen`, `OneOnOneChannelDetailScreen`, `SharedGroupsScreen` **Added / updated:** - New thin `ChannelDetailsScreen` that consumes the SDK component, plus a `ChannelDetailsNavigationSection` override example - New `SendDirectMessage` icon (removed `Archive`, `UserMinus`) - Updated `ChannelListScreen`, `ChannelScreen`, `NewDirectMessagingScreen`, `App.tsx`, `types.ts`, and `SampleAppComponentOverrides` to wire up the new screen ## SDK โ new **`ChannelDetailsScreen` component suite** (new export from `components/index.ts`): - Core: `ChannelDetailsScreen`, `ChannelDetailsProfile`, `ChannelDetailsActionsSection`, `ChannelDetailsActionItem`, `ChannelDetailsMemberSection`, `ChannelDetailsNavigationSection`, `ChannelDetailsScreenHeader` - Edit flow: `ChannelEditDetails`, `ChannelEditDetailsModal`, `ChannelEditName`, `ChannelEditImageSheet` - Members: `ChannelMemberList`, `ChannelMemberItem`, `ChannelMemberActionsSheet`, `ChannelAddMembers` (+modal), `ChannelAllMembersModal`, `AddMemberSearchResultItem`, and loading skeletons - Generic `Modal` / `ModalHeader` building blocks **New hooks** โ `package/src/hooks/actions/` namespace (`useChannelActions`, `useChannelActionItems`, `useChannelMemberActionItems`, `useUserActions`, shared `types`), feature hooks (`useChannelDetailsActionItems`, `useChannelDetailsMembersPreview`, `useChannelDetailsMemberStatusText`, `useEditChannelImage`, `useUserActivityStatus`, `useChannelAddMembers`, `useChannelAllMembers`, `useMemberRoleLabel`), and reusable channel hooks now exported publicly: `useChannelName`, `useChannelImage`, `useChannelMemberCount`, `useChannelOwnCapabilities`, `useChannelMuteActive`, `useIsDirectChat`, plus `useSyncClientEvents` (reactive channel name/image/member-count updates) **New reusable UI / contexts / icons:** - UI components: `SearchInput`, `SelectionCircle`, `EmptySearchResult` - Contexts: `channelDetailsContext` and `BottomSheetContext` - Icons: `chevron-right`, `x-circle` - ~196 lines of new theme tokens for the new components - ~50 new translation keys across all 14 locales (member roles, add-members, edit-channel, a11y labels) ## SDK โ updates to existing - **BottomSheetModal** โ reworked (~100 lines); fixes the iOS close-callback-fires-too-early bug and now exposes context via the new `BottomSheetContext` - **ChannelAvatar** โ extended to show a live preview of pending channel-image changes - **Hook relocations** โ `useChannelActions` / `useChannelActionItems` / `useIsDirectChat` / `useChannelMuteActive` moved out of `ChannelList/hooks` into the shared `src/hooks` tree (and `useChannelActions` significantly extended: `onFailure`/`onSuccess` handlers, member/image/name updates, separate dismiss API) - **componentsContext** โ registered the new components as defaults (~31 lines); `OwnCapabilitiesContext` gained a capability - **ChannelPreview** โ `ChannelDetailsBottomSheet` and `ChannelSwipableWrapper` updated; `useChannelPreviewDisplayName` / `useUserMuteActive` tweaked - **camera icon redesign** โ drove snapshot updates for `AttachButton`, `SendButton`, `Thread` - **notificationTarget** โ minor update for channel-delete/edit notifications - Repo housekeeping: `CLAUDE.md` typecheck note, accessibility skill tweak, new RTL skill **Scale:** ~80 commits, +12,961 / โ3,635 across 166 files, with a large accompanying test suite (~40 new `__tests__` file --------- Co-authored-by: Ivan Sekovanikj <ivan.sekovanikj@getstream.io> | 2 ไธชๆๅ |
| ๆไปถ | ๆๅๆไบค่ฎฐๅฝ | ๆๅๆดๆฐๆถ้ด |
|---|---|---|
| 20 ๅคฉๅ | ||
| 2 ไธชๆๅ | ||
| 1 ไธชๆๅ | ||
| 1 ไธชๆๅ | ||
| 1 ไธชๆๅ | ||
| 1 ไธชๆๅ | ||
| 2 ไธชๆๅ | ||
| 1 ๅนดๅ | ||
| 1 ๅนดๅ | ||
| 2 ไธชๆๅ |