Skip to content

feat(react-native-uikit-docs): Pin & Save, Pin Conversation and Thread Subscription - #516

Open
suraj-chauhan-cometchat wants to merge 14 commits into
mainfrom
feat/rn-pin-save-thread-subscription-uikit-docs
Open

feat(react-native-uikit-docs): Pin & Save, Pin Conversation and Thread Subscription#516
suraj-chauhan-cometchat wants to merge 14 commits into
mainfrom
feat/rn-pin-save-thread-subscription-uikit-docs

Conversation

@suraj-chauhan-cometchat

Copy link
Copy Markdown
Contributor

Brings the React Native UI Kit docs to parity with the Android and React kits for the four features shipped in @cometchat/chat-uikit-react-native@5.5.0.

Before this, React Native had the two panel component pages (pinned-messages, saved-messages) but no core-features entries, no guides, and no mention of the thread-subscription bell anywhere.

Core features

ui-kit/react-native/core-features.mdx gains three sections, placed in the same order Android uses:

Mentions → Pin & Save Messages → Pin Conversations → Rich Text Formatting
Threaded Conversations → Thread Subscription → Group Chat

Thread Subscription sits directly after Threaded Conversations, as requested.

New guides

File Modelled on
guide-pin-and-save-messages.mdx ui-kit/react/guide-pin-and-save-messages.mdx
guide-thread-subscription.mdx ui-kit/android/guide-thread-subscription.mdx

Both are added to docs.json in Android's relative order: threaded-messages → thread-subscription → pin-and-save.

Thread header component

threaded-messages-header.mdx gains a Thread Subscription section, mirroring the React thread-header page.

Two deliberate divergences from the reference platforms

These are real platform differences, documented rather than copied:

1. The bell is on CometChatMessageHeader, not CometChatThreadHeader.
React puts its toggle on the thread header. The landed React Native design places it in the thread screen's top bar, driven by parentMessage + threadSubscriptionVisibility. CometChatThreadHeader's TrailingView is the escape hatch for a custom control there and explicitly does not host the bell. The section says so, so nobody goes looking for a prop that isn't there.

2. Thread Subscription is ON by default on React Native, and has no dashboard flag — so it is documented as opt-out via ThreadSubscriptionConfig.setEnabled(false). Android documents the same feature as opt-in because its default differs. The React Native text matches what v5.5.0 actually ships and the published release notes.

Pin is documented as available to every member, with the server enforcing permission — matching React. The React Native role gate was removed in ENG-38197, so canPin() now only asserts that somebody is logged in.

Verification

  • 0 dangling navigation refs across the whole docs.json — build is safe
  • 100 internal links across the changed files, all resolve
  • docs.json diff is 3 insertions / 1 deletion — no reformat churn
  • Every prop, method and default documented here was read from the shipped 5.5.0 source, not from the design doc

🤖 Generated with Claude Code

…d subscription

The React Native UI Kit shipped Pin Message, Save Message, Pin Conversation and
Thread Subscription in v5.5.0, but the docs only covered the two panel components.
This brings React Native to parity with the Android and React kits.

Core features (ui-kit/react-native/core-features.mdx)

  Three sections, placed in the same order Android uses:

    Mentions -> Pin & Save Messages -> Pin Conversations -> Rich Text Formatting
    Threaded Conversations -> Thread Subscription -> Group Chat

  Thread Subscription sits directly after Threaded Conversations, matching Android.

New guides

  guide-pin-and-save-messages.mdx  modelled on the React guide
  guide-thread-subscription.mdx    modelled on the Android guide

  Both are wired into docs.json in Android's relative order — threaded-messages,
  then thread-subscription, then pin-and-save.

Thread header component (threaded-messages-header.mdx)

  Adds a Thread Subscription section, mirroring the React thread-header page.

Two platform differences are documented rather than copied over:

  * The bell is on CometChatMessageHeader, NOT CometChatThreadHeader. React puts
    its toggle on the thread header; the landed React Native design places it in
    the thread screen's top bar, driven by `parentMessage` +
    `threadSubscriptionVisibility`. CometChatThreadHeader's TrailingView is the
    escape hatch for a custom control there and does not host the bell.

  * Thread Subscription is ON by default on React Native and has no dashboard
    flag, so it is documented as opt-OUT via ThreadSubscriptionConfig.setEnabled(false).
    Android documents the same feature as opt-in because its default differs.
    The text matches what v5.5.0 actually ships and the published release notes.

Pin is documented as available to every member with the server enforcing
permission, matching React — the React Native role gate was removed in ENG-38197,
so canPin() now only asserts that somebody is logged in.

Verified: 0 dangling navigation refs, and 100 internal links across the changed
files all resolve.
@mintlify

mintlify Bot commented Sep 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cometchat 🟢 Ready View Preview Sep 11, 2026, 11:42 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

The section had drifted from the Android original: different table headers
(Components/Functionality vs Component/Role), a shortened link label, and two
extra paragraphs about the dashboard flag and server-owned ordering.

Now byte-identical to ui-kit/android/core-features.mdx, with only the platform
path in the link differing.
…ve and Thread Subscription

Pin Conversations was aligned in 984ef98; these two had drifted the same way —
"Components/Functionality" table headers instead of "Component/Role", shortened
link labels, and extra "Hide it with ..." clauses and paragraphs Android does not
carry.

Both now follow the Android sections verbatim. Three differences remain, each a
real platform fact rather than drift:

  * Pin & Save — "Pinned messages entry point", not "menu entry point": on React
    Native it is a header button (showPinnedMessagesButton), not a menu item.
  * Thread Subscription — "Enabled by default" rather than Android's "Opt-in".
    React Native ships ThreadSubscriptionConfig with enabled = true.
  * Thread Subscription — the bell is on CometChatMessageHeader, not
    CometChatThreadHeader, per the landed React Native design.
Removes all 12 mentions across four pages. Thread subscription is now documented
purely through its two per-surface props:

  hideThreadSubscriptionOption   CometChatMessageList
  threadSubscriptionVisibility   CometChatMessageHeader

message-list.mdx           dropped the opt-out paragraph, the TypeScript/JavaScript
                           tabs that only demonstrated setEnabled, and the mention
                           in the hideThreadSubscriptionOption prop description
guide-thread-subscription  "Enable the Feature" rewritten around the two props
threaded-messages-header   dropped the global row from the controls table
core-features              points at the two props instead

The feature is still described as enabled by default, which is what 5.5.0 ships.
… Android

The five bullets specify per-section references, and Pin & Save in core features
is a React one — it had been switched to Android's format along with the other
two sections.

Now follows ui-kit/react/core-features.mdx: React's heading ("Pin and Save
Messages"), intro, Components/Functionality table, and — the part Android's
version does not carry — the app-settings limits table and its closing paragraph
on cap toasts.

Five deliberate differences:

  * the Storybook <Info> + <iframe> block is dropped; React Native has no
    Storybook to embed
  * the #pin-and-save-options deep link is dropped; that anchor does not exist on
    the React Native message-list page
  * "message options menu" -> "message options": React Native uses an action sheet
  * "panel" -> "screen": React Native navigates rather than opening a panel
  * the Conversations row is dropped; Pin Conversations is its own section here,
    per the Android reference, so listing it twice would duplicate

The heading change moves the anchor, so the inbound link in the guide is updated
to #pin-and-save-messages — which is also React's own anchor.
…has it

CometChatThreadHeader was carrying the thread-subscription section, but on React
Native it renders no bell — the control belongs to CometChatMessageHeader, which
said nothing about it. Every other platform documents the bell on the component
that owns it: React and Android on their thread header, iOS on both because iOS
supports both.

message-header.mdx gains two sections, with worked examples:

  Pinned Messages      showPinnedMessagesButton (OFF by default) and
                       onPinnedMessagesPress. The guide tells integrators to use
                       these while the component's own page never listed them.
  Thread Subscription  parentMessage as the thread-mode switch that renders the
                       bell, threadSubscriptionVisibility, and
                       onThreadSubscriptionChange — the last of which was
                       undocumented anywhere, though React documents its own.

Both toggles are added to the Visibility Props table too.

threaded-messages-header.mdx keeps a Thread Subscription section, but it is now a
pointer rather than a duplicate: it states plainly that this component renders no
bell, shows the two components side by side as a thread screen actually composes
them, and links to the message header for the props. Its TrailingView note stays —
that slot is the escape hatch for a custom control and is easily mistaken for the
bell's home.

All five props shipped in 5.5.0 are now documented on the component that has them.
…ubscription section

Leads with where the bell is rather than where it is not.
Thread subscription was a top-level entry in both places. It belongs inside threaded
messages, which is how the other kits structure it.

Core features

  `## Thread Subscription` becomes `### Thread Subscription` inside
  `## Threaded Conversations`, matching iOS — its core-features page nests the same
  section at h3 under the same parent.

Guides

  The standalone guide-thread-subscription.mdx is removed and its content folded into
  guide-threaded-messages.mdx as a `## Thread Subscription` section, matching React —
  its threaded-messages guide carries the feature with the same three subsections:

    Automatic subscription
    Reacting to changes
    Hiding the controls

  The React Native text differs where the platform does: the bell is on
  CometChatMessageHeader rather than the thread header, and CometChatMessageList takes
  the whole `parentMessage` rather than an id, since a reply arriving over the socket
  carries no subscription flag of its own and is stamped from the parent.

  onThreadSubscriptionChange is documented here as well as on the component page —
  React documents its own equivalent in both places.

The nav entry is dropped and all three inbound links now point at
guide-threaded-messages#thread-subscription.

Verified: 0 dangling navigation refs, and 413 internal links across the React Native
pages all resolve.
The React component pages carry a live Storybook iframe so a reader can see the
panel before wiring it up. There is no React Native Storybook to embed, so these
pages had no visual at all — and neither do Android's or iOS's. Static screenshots
are the closest equivalent.

  pinned-messages.mdx              the Pinned Messages screen
  saved-messages.mdx               the Saved Messages screen
  guide-pin-and-save-messages.mdx  both, beside the step that builds each screen

Placed right after "Where It Fits", which is where React puts its preview.

Each carries descriptive alt text rather than a label. React's iframe has none, and
on these pages the screenshot is the only visual explanation of what the feature
looks like — so it needs to work for a reader who cannot see it.

Verified: all four references resolve, and 175 image references across the React
Native pages were checked. The one miss,
compact-message-composer-overview.png, is untouched by this branch and is already
broken on main.
The pin & save pages documented kit-internal plumbing alongside the
public surface. Nothing here is API a customer writes against:

- `## Enabling the feature` (PinSaveConfig / getPinSaveFeatures /
  refreshPinSaveFeatures) — the kit resolves these itself at login and
  re-reads them on every reconnection (CometChatUIKit onLoggedIn +
  ConnectionListener.onConnected), so there is nothing to call. The
  page's opening <Warning> already states the Dashboard requirement.
- `## Reading pin state yourself` / `## Reading save state yourself`
  (isPinned / isSaved / isSystemPin / SYSTEM_PINNER) and the matching
  "helpers" blocks in the AI Integration Quick Reference accordions.
- Two implementation asides: how the panel routes local vs SDK save
  events, and that the RN SDK has no isPinned() of its own.

Also corrects a stale instruction on conversations.mdx: Pin Conversation
no longer needs `PinConversationConfig.enable(true)` from the
integrator — PinSaveFeatureGates applies it from the server flag. The
<Warning> framed it as a required setup step, so anyone following it was
writing dead code.

React, Android and iOS document none of these APIs; this brings React
Native into line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ndard

Both pages were missing sections every other React Native component page
has, and ordered the ones they did have differently. They now follow the
house order used by conversations / message-list / users / groups:

  Where It Fits -> Minimal Render -> Actions and Events ->
  Custom View Slots -> Common Patterns -> Styling -> Props -> Next Steps

Added:
- `## Styling` with a worked example and a Style Properties table for
  every key of PinnedMessagesStyle and SavedMessagesStyle, including
  `closeButtonIcon`, the saved row's `previewIconStyle`, and the
  empty/error state styles. None of this was documented; the pages just
  listed `style` as one row with an opaque DeepPartial type.
- `## Custom View Slots` for ItemView, noting that empty/error/loading
  are restyled rather than replaced on these two components.
- `## Opening from the Message Header` (pinned), stating that
  `showPinnedMessagesButton` adds an item to the header's overflow menu
  rather than rendering a standalone button, and that it is a silent
  no-op without `onPinnedMessagesPress`.
- Per-prop `### name` entries with Type/Default tables, replacing the
  single flat table — matches every other RN component page.
- The SavedMessageSource field table, so `onItemPress`'s second argument
  is usable. The type is not exported from the package, so the example
  no longer annotates with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@raj-dubey1 raj-dubey1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — React Native Pin & Save, Pin Conversation, Thread Subscription

Verdict: request changes (one code fix + a few small ones). The structure is safe to merge and nearly every claim matches the shipped kit. I checked the pages against the @cometchat/chat-uikit-react-native@5.5.0 source from npm. One code sample in the new guide is wrong, though, and it contradicts the component page in this same PR.

Must fix

1. The Saved Messages guide code reads fields that don't exist on source. ui-kit/react-native/guide-pin-and-save-messages.mdx:153-160 does:

onItemPress={(message, source) => {
  navigation.navigate("Messages", { user: source?.user, group: source?.group, ... });
}}

In 5.5.0, SavedMessageSource is { receiverType, receiverId, label, name, avatar? }, with no user or group (src/shared/utils/SavedMessagesHelper.ts:16-27). So this fails TypeScript, and at runtime it opens "Messages" with user and group both undefined. saved-messages.mdx:113-114 in this PR already does it correctly with source?.receiverType / source?.receiverId. Mirror that here, for example by resolving the User/Group from receiverId and receiverType before navigating.

Should fix

2. The threads guide wires a prop the RN message list doesn't have. guide-threaded-messages.mdx:129, 165, 362 use onThreadRepliesClick, but the RN prop is onThreadRepliesPress (CometChatMessageList.tsx:346). So the guide's navigation to the thread screen never fires. This predates the PR, but the new Thread Subscription section on the same page depends on reaching that screen.

3. "Jump to this message" is never wired. Both screens in the guide pass messageId back to "Messages" (:94-100, :153-160), with the comment "Jump the main message list to this message". The Complete Example (:200-234) never uses it. Either show goToMessageId={route.params?.messageId} on CometChatMessageList (documented at message-list.mdx#gotomessageid), or drop the jump claim.

Nits

4. The thread option's label doesn't match the kit.

  • message-list.mdx:443 and :1177, which this PR edits, call it "Follow / Unfollow thread".
  • The message-header.mdx:511 example logs "Following this thread".
  • The kit's strings are "Subscribe to thread" and "Unsubscribe from thread" (translation.json:231-232), which core-features.mdx and the guide already use.

5. The pinned-messages button needs both props. message-header.mdx:441 says to set showPinnedMessagesButton to render the button. The kit renders it only when onPinnedMessagesPress is also set (CometChatMessageHeader.tsx:343), so say "set both".

6. The PR description is out of date. It lists a new guide-thread-subscription.mdx (folded into guide-threaded-messages.mdx in 4376a5a) and an opt-out via ThreadSubscriptionConfig.setEnabled(false) (references removed in bf75dc1). It also says docs.json changed by 3 insertions and 1 deletion, but it's +2/−1 including an indentation-only change on "index". Worth updating so reviewers don't look for things that aren't there. Optionally, ThreadSubscriptionConfig (still exported, default on) could get one line as the app-wide off switch.

Checked and fine

  • Build and URLs: 0 unresolved navigation refs; the new guide is in navigation. No files removed or renamed, so no redirects are needed. 0 broken internal links across 62 scanned pages.
  • Images: images/pin.png and images/save.png exist and are referenced with descriptive alt text.
  • Checked against the 5.5.0 source:
    • The kit resolves the Pin, Save and Pin Conversation flags itself at login and on every reconnect (PinSaveFeatureGates.ts:78-80, CometChatUIKit.ts:185,210), so "no app code to write" is correct, including for restored sessions.
    • canPin() only checks for a logged-in user, so "every member, server enforces" is correct.
    • The limit toasts use the server's limit.
    • Header props and defaults: showPinnedMessagesButton is false, threadSubscriptionVisibility is true, and onThreadSubscriptionChange exists.
    • Thread subscription is on by default.
    • CometChatThreadHeader has TrailingView.
    • CometChatMessageList has parentMessage (with parentMessageId deprecated).
    • The CometChatPinnedMessages default page size is 30.
    • The automatic-subscription rules match the kit's thread helper.
    • Every other identifier in backticks across the 9 changed pages exists in 5.5.0.

🤖 Generated with Claude Code

1. (must) Saved Messages guide read `source?.user` / `source?.group`,
   which SavedMessageSource does not have — it is
   { receiverType, receiverId, label, name, avatar? }. The snippet failed
   typecheck and at runtime navigated with both undefined. Now resolves
   the User/Group from receiverId + receiverType before navigating, and
   the prose lists the real fields.

2. (should) Threads guide wired `onThreadRepliesClick`; the RN prop is
   `onThreadRepliesPress` (CometChatMessageList.tsx:346), so navigation
   to the thread screen never fired. Renamed in all 3 places.

3. (should) Both guide screens passed `messageId` back to Messages with a
   "jump to this message" comment, but the Complete Example never used
   it. Wired `goToMessageId` on CometChatMessageList, which is the prop
   that actually performs the jump.

Nits 4-6 deliberately left for a follow-up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@suraj-chauhan-cometchat

Copy link
Copy Markdown
Contributor Author

Thanks — all three Must fix / Should fix items are addressed in 775cdc97. Each was verified against the 5.5.0 source before changing anything; you were right on all three.

1. (must) source?.user / source?.group — confirmed SavedMessageSource is { receiverType, receiverId, label, name, avatar? } (SavedMessagesHelper.ts:16-27). The guide now resolves the User/Group from receiverId + receiverType before navigating, so the Messages screen signature is unchanged, and the prose lists the real fields with a link to the component reference.

2. (should) onThreadRepliesClick — confirmed the prop is onThreadRepliesPress (CometChatMessageList.tsx:346). Renamed in all 3 places plus the handler name. Agreed this predates the PR, but it mattered here because the new Thread Subscription section depends on reaching that screen.

3. (should) unwired jump — confirmed goToMessageId?: string exists (CometChatMessageList.tsx:587) and drives getMessagesAroundId. Wired it in the Complete Example rather than dropping the claim, so the messageId both screens pass is now actually consumed.

Nits 4–6 are knowingly still open: the thread label drift, message-header.mdx saying to set only showPinnedMessagesButton, and the stale PR description.

Not merging yet — a follow-up pass on the newly restructured pinned-messages.mdx / saved-messages.mdx turned up two further must-fixes of our own (ItemView on CometChatPinnedMessages replaces only the bubble, not the row; and one snippet that fails typecheck). Those are being fixed next.

🤖 Generated with Claude Code

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants