| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat: enhanced mentions (#3631) ## 🎯 Goal This PR implements the enhanced mentions featureinto the SDK so RN apps can mention not just users but also `@channel`, `@here`, custom roles and user groups - with per type colors in the rendered message and full offline draft round tripping. Bundles the architectural fixes that surfaced while wiring this up (Android `a11y` bounds, cross screen portal teleport leak, composer/list animation sync, iOS multiline regression). ## 🛠 Implementation details Enhanced mentions Consumes the LLC's five variant `MentionSuggestion`/`MentionEntity` union (`user | channel | here | role | user_group`). Composer suggestion rows - `package/src/components/AutoCompleteInput/` - `AutoCompleteSuggestionItem.tsx`'s `MentionSuggestionItem` is now a dispatcher that switches on `item.mentionType` and routes to a per type row. Still overridable via `useComponentsContext().MentionSuggestionItem` so integrators can replace just the mention branch. - New mentionItems/ directory with one component per variant (MentionUserItem, MentionBroadcastItem, MentionRoleItem, MentionUserGroupItem), a shared MentionItem primitive, plus reusable EnhancedMentionContent, EnhancedMentionIcon, TokenizedSuggestionParts — all exported for custom dispatcher composition. - New icons: megaphone.tsx (broadcast), shield.tsx (role). User-group rows reuse the existing PeopleIcon. Rendered message text - `Message/MessageItemView/utils/renderText.tsx` - Builds a `MentionEntity[]` from `mentioned_users` + `mentioned_channel` + `mentioned_here` + `mentioned_roles` + `mentioned_groups` (`mentioned_group_ids` fallback). - Regex alternation built longest-first to avoid prefix collisions (`@here` mustn't shadow `@here-team`). - Per type color via semantic tokens (chatTextMentionUser / …Broadcast / …Role / …Group), each defaulting to the umbrella `chatTextMention` so existing themes look identical. - `onPress` now carries `additionalInfo: { mentionedEntity, user? }`. `user` stays populated for user mentions (for back compatibility reasons). - Markdown cache key extended to all five mention sources so the text rerenders when only non-user mentions change. Memo comparator — MessageItemView/MessageTextContainer.tsx - React.memo comparator extended to diff mentioned_channel, mentioned_here, mentioned_roles, and mentioned_groups/mentioned_group_ids in addition to mentioned_users. Without this, messages differing only in non-user mentions would skip re-render. Offline draft persistence has also been modified to reflect enhanced mentions. **Suggestion list architecture** The mount location of `<AutoCompleteSuggestionList />` is now moved to `MessageList.tsx` and `MessageFlashList.tsx` - not `MessageComposer.tsx`, inside its own `<PortalWhileClosingView portalHostName='overlay-suggestion-list' portalName='autocomplete-suggestion-list'>` wrapper. Why: Android's `getBoundsInScreen()` clamps `a11y` bounds to the parent's measured rect. The composer's wrapping View (~`228` px with safe area padding) was clipping the absolutely positioned suggestion list to inverted/empty bounds - `TalkBack` saw nothing, taps didn't activate. Hoisting into the `flex: 1` `MessageList` container restores valid `a11y` bounds. Verified with `uiautomator` dump. **`PortalWhileClosingView` cross screen leak fix** Removed the early return guard in `syncPortalLayout`: ``` if (!width || !height) { return; } ``` The guard kept unmeasured (0×0) wrappers off the closing portal stack, but as a side effect, wrappers with no children (e.g. autocomplete list before the user types @) never registered. Navigating `Channel` -> `Thread` (both mount such wrappers, as an example) left the previous screen's stale entry as the only thing on the host stack and the closing overlay teleport then stamped `Channel` autocomplete content into the `Thread` screen. Removing the guard lets empty wrappers register; teleport for an empty wrapper renders `null` children so nothing visible. Accessibility - New hook `useAnnounceOnShow(visible, message, { delayMs?, priority? })` - announces on each visible: false -> true transition and resets on hide. Unlike `useAnnounceOnStateChange`, it doesn't dedupe consecutive identical strings, so reshows reannounce. - Applied to `BottomSheetModal` (replaces adhoc `ref` + `useEffect`) and `AutoCompleteSuggestionList` - `ai-docs/accessibility.md` and the team `a11y` skill updated to document `useAnnounceOnShow`, the menu/menuitem iOS only caveat and a new "floating overlays need a tall parent for Android a11y" rule. **ClippingFadeBottom** New `UIComponents/ClippingFadeBottom.tsx` reusable fade primitive used at the bottom edge of the suggestion list so long lists fade out instead of hard clipping at the composer edge. Bundled bug fixes - iOS multiline `TextInput` regression after RN upgrade - caret jumping on newline - `AutoCompleteSuggestionList` animation desync when swithcing between attachment picker and keyboard - Accessibility bugs with the suggestions list ## 🎨 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 个月前 | |
docs: add AI-agent migration guide for v8 → v9 (#3557) ## Summary Adds `ai-docs/ai-migration.md` — a compact, machine-friendly v8 → v9 migration reference built for AI coding agents (Claude Code, Cursor, Copilot, etc.). The human-oriented v8 → v9 guide at https://getstream.io/chat/docs/sdk/react-native/basics/upgrading-from-v8/ is ~40k tokens. Loading it wholesale eats most of an agent's context window before any code work begins. This sibling doc is ~4k tokens (5× smaller) — prose rationale stripped, rename tables/decision rules/source pointers kept. Customers point their agent at the raw GitHub URL. It is **not** shipped in the npm package. ### Key agent-oriented features - **§0 primer** tells agents not to trust training data for v9 symbols (their cutoff predates v9) and names the correct `node_modules` path — the installed package is `stream-chat-react-native-core`, not `stream-chat-react-native` (which is the bare-RN wrapper). - **§1 detection greps** let agents scope the work with a single `rg` pass and skip sections whose patterns don't match the customer codebase. - **§3 big-3 structural migrations** enforce ordering: `WithComponents`, 5 component renames, inverted audio semantics — done first because many leaf renames evaporate after the big moves. - **§6 behavior changes** captures runtime-semantic shifts that aren't pure renames (`messageContentOrder` default swap, `deletedMessagesVisibilityType` removal, swipe-to-reply boundary, `MessageActionType.type` field, etc.). - **§7 JSON rename block** is the full v8 → v9 symbol map in a single parseable block for programmatic find/replace. - **§9 verification workflow** gives agents a hard gate: `rg` + `tsc` commands that must come back clean before the agent declares done. ### Stacked on #3556 This PR targets `refactor/v9-finish-message-menu-and-audio-hook` so the guide can accurately claim `useAudioPlayer` is the v9 hook name and `MessageMenu` is removed. GitHub will auto-retarget to `develop` when #3556 merges. ## Test plan - [x] Verified every v9 symbol in the guide resolves in `package/src/` - [x] Verified every `node_modules/` path referenced exists under `package/src/` - [x] Verified every `rg` pattern is syntactically valid (no exit-2 from ripgrep) - [x] Confirmed all "removed" claims in the JSON block are genuinely absent from v9 source (only i18n translation keys and stale JSDoc comments mention them) - [ ] Dogfood check: paste the raw URL into Claude Code on a fresh v8 example app and have it migrate ## Related docs updates Human migration guide edits (correcting the MessageMenu and AudioAttachment claims that this agent guide is also correcting) are a separate PR in the `docs-content` repo. | 4 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 4 个月前 |