Skip to content

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

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

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

Conversation

@suraj-chauhan-cometchat

@suraj-chauhan-cometchat suraj-chauhan-cometchat commented Sep 10, 2026 •

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-threaded-messages.mdx (thread-subscription section) ui-kit/android/guide-thread-subscription.mdx

Both are added to docs.json in Android's relative order. Note RN keeps thread subscription inside guide-threaded-messages.mdx rather than as its own page, so there is no guide-thread-subscription.mdx on this branch.

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 25, 2026, 11:37 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>
…pping alpha

The regex was /{3,6}/ while React and Angular publish /{3,8}/. A message written on the web
with an alpha color — {color=#e5484dff}text{/color} — did not match here, so the marker was
left untouched and the reader saw the raw text rather than colored text.

Now /{3,8}/, with the alpha dropped before the value reaches the UI Kit:

    #rgba     -> #rgb
    #rrggbbaa -> #rrggbb

That step is needed because the UI Kit renders #rgb and #rrggbb only, and an unrecognised
value is not silently uncolored — it leaves the raw <color=...> tag visible in the message,
which is the worse failure.

Verified by extracting the guide's code from the .mdx and running it against the release
branch — all five forms the marker allows now render:

    3  #rgb       -> #f00
    4  #rgba      -> #f00
    6  #rrggbb    -> #e5484d
    8  #rrggbbaa  -> #e5484d
    name          -> #e5484d

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tter', as React does

Three React Native pages all carried title: "Custom Text Formatter", and the sidebar name
was held by guide-text-color — the page whose own first section says "In React Native you
do not need to write a text formatter for this". The one page that IS React's counterpart
was called "Color Formatter".

Sorted out so each page is named for what it teaches:

  guide-color-formatter        Custom Text Formatter      <- matches React and Angular
  guide-text-color             Text Color                 <- built-in toolbar, no formatter
  custom-text-formatter-guide  Text Formatter Base Class  <- the base class

guide-text-color also had title: "Custom Text Formatter", which is now "Text Color" —
three pages sharing one title made them indistinguishable in search.

Also updated the link TEXT that still called guide-text-color the Custom Text Formatter
guide, in compact-message-composer and guide-overview, and added the new guide to the
guide-overview table, where it was missing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ct's parity

Four public APIs land in the React Native UI Kit that the docs never mentioned,
three of which React has documented since its own pin/save shipped. Reading only
the React Native docs, an integrator could not discover any of them.

  messagesRequestBuilder   CometChatPinnedMessages, CometChatSavedMessages
  textFormatters           the same two, plus CometChatSearch and
                           CometChatMessageInformation
  replaceSelection(text)   ComposerInputHandle — the one method the color
                           formatter guide already tells the reader to call
  onError(e)               CometChatGroupMembers now receives the exception

Pinned and Saved each gain a Filtering section and two reference entries,
matching React's pinned-messages / saved-messages pages heading for heading. The
prose is React Native's own, because the two kits differ where it matters: the
builder methods are setPinnedOnly() / setSavedOnly(), the component works on a
prototype-preserving COPY so one builder can feed both panels, the limit falls
back prop -> builder -> 30, and the saved panel clears any uid/guid because a
save is account-wide. All four are stated, since each one is a way to be
surprised.

CometChatMessageInformation had no v5 page at all — only the v4 one — while
React, Angular and Vue all carry theirs, so its new textFormatters prop had
nowhere to live. Added the page: what it shows for a group (server receipts, one
row per recipient) versus a one-on-one (the timestamps already on the message),
why you normally do not render it yourself, and the one case where you must pass
textFormatters — a standalone screen, which has no template to inherit them
from. Its style type is spelled DeepPartial<CometChatTheme["messageInformation
Styles"]> and the ListItemView receipt shape is written out, because neither
MessageInformationStyle nor Recipient is an exported name.

Verified against the shipping source on bugfixes/release-2026-09-week-4-v5, not
from the commit messages: every prop read off its own interface, the builder
invariants off buildPinnedMessagesRequest / buildSavedMessagesRequest, and
setPinnedOnly/setSavedOnly confirmed public in the SDK's CometChat.d.ts. Both
Accordion JSON blocks and docs.json re-parse, and every internal link in the
seven files resolves to a page that exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both the composer snippet in Step 3 and four of the five components in Step 4
were written with `user={user} group={group}` on the same element. They are
mutually exclusive on every one of those components — CometChatPinnedMessages
picks the group and ignores the user, and a reader following the guide's own
instruction to copy the block gets a panel scoped to the wrong conversation with
nothing on screen saying why.

This guide exists to be pasted, so it now shows one scope with the alternative in
a comment.

Verified the rest of the guide by running it: ColorFormatter.ts extracted
verbatim from this page, with only its import path redirected to the real class,
passes 24 assertions through the shipping code — the bubble, conversation-row and
search chains each render red for the plain example and for text that also
carries bold, italics, a link, a bullet and a code span; alpha hex narrows to
what HEX_COLOR_REGEX accepts; an unknown color name leaves the marker alone
instead of leaking a raw <color=> tag; and handlePreMessageSend converts the kit
token back to the marker. Also confirmed against source that the toolbar hosting
the button is on by default, that a consumer's array is added to the built-in
formatters rather than replacing them, and that a formatter with no tracking
character is keyed by id so its send hook still runs.

Co-Authored-By: Claude Opus 5 <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.

Build, nav, links and images are all fine. The blocking problem: several documented APIs aren't in the published @cometchat/chat-uikit-react-native@5.5.0 (npm latest). They exist only on dev-v5 (5.5.1, unreleased). I checked each one against the 5.5.0 npm tarball and dev-v5.

Blocking: 5.5.1-only APIs documented as current

  • formatRawText() and composer.replaceSelection(): custom-text-formatter-guide.mdx:51,84-100,139,196, guide-color-formatter.mdx:13,33,80,96,103,123,191, compact-message-composer.mdx:579. The ColorButton sample fails type-check and throws on 5.5.0. The rewritten HashTag example is a silent no-op on 5.5.0, and the old getFormattedText approach that works on 5.5.0 was removed.
  • textFormatters on Pinned, Saved, Search and MessageInformation: pinned-messages.mdx:25,419, saved-messages.mdx:23,365, search.mdx:348, message-information.mdx:20,58,105,228.
  • messagesRequestBuilder on Pinned and Saved (the new Filtering sections): pinned-messages.mdx:24,105-130,404, saved-messages.mdx:22,102-130,350.
  • GroupMembers onError(error): 5.5.0 types it as () => void, so group-members.mdx:268 fails TS.

Fix: hold until 5.5.1 is on npm, or add "Requires 5.5.1+" callouts and keep the 5.5.0 approach alongside.

Should fix

  1. guide-pin-and-save-messages.mdx:53 says pin/save is hidden while moderation is pending. isPinSaveEligible() explicitly allows pending (PinSaveHelper.ts:308).
  2. The ThreadSubscriptionConfig.setEnabled(false) snippet was removed from message-list.mdx, but it is still exported, still gates both surfaces, and is the only app-wide opt-out. It is now undocumented anywhere, although the PR body says it is documented.
  3. message-header.mdx:441,586 and guide-pin-and-save-messages.mdx:18,58 call the pinned entry point a "button". It is a "Pinned Messages" item in the ⋮ overflow menu and needs both showPinnedMessagesButton and onPinnedMessagesPress, as pinned-messages.mdx:192,221 correctly says.

Nits

  • guide-color-formatter.mdx:2 and custom-text-formatter-guide.mdx:2 share the title "Custom Text Formatter".
  • message-list.mdx:1177: the label is "Subscribe to thread" / "Unsubscribe from thread", not "Follow / Unfollow thread".
  • SavedMessageSource isn't exported from the package root (saved-messages.mdx:27,396).
  • custom-text-formatter-guide.mdx:177 has a stray top-level <CometChatConversations …/>;, and the .tsx samples use untyped props (:159, guide-text-color.mdx:48).
  • The helper docs (isPinned, isSystemPin, isSaved, getPinSaveFeatures, refreshPinSaveFeatures) were removed but are still exported and correct.
  • The PR body mentions guide-thread-subscription.mdx; that content lives in guide-threaded-messages.mdx.

Verified OK: bell on CometChatMessageHeader, thread subscription on by default, PinConversationConfig removal, the pin/save hide* props, onThreadRepliesPress, all style keys, Message Information props, and the compact composer toolbar and color wire format.

🤖 Generated with Claude Code

….5.1

The blocking item is retired by the release, not by an edit. Every API the review
called "5.5.1-only, unreleased" is in the published tarball, which is now npm
`latest`: formatRawText (CometChatTextFormatter.ts:235), replaceSelection
(compact composer :566, :3652), textFormatters on Pinned, Saved, Search and
MessageInformation, messagesRequestBuilder on Pinned and Saved, and
GroupMembers `onError?: (e: CometChat.CometChatException) => void` (:190). The
review's own remedy was "hold until 5.5.1 is on npm"; that has happened, so no
version callouts were added — no RN page carries one, and inventing the
convention here would be inconsistent.

Everything else was checked against that same tarball and fixed:

* Moderation. isPinSaveEligible() explicitly allows `pending`
  (PinSaveHelper.ts:308) — the guide claimed the options were hidden until a
  verdict arrived. Rewritten to say what the kit does: offer the option, let the
  server refuse, render the refusal.
* ThreadSubscriptionConfig. Still exported, still ON by default
  (ThreadSubscriptionHelper.ts:82-102), and setEnabled(false) is the only
  app-wide opt-out — it was undocumented anywhere after the rewrite. Documented
  on message-list beside hideThreadSubscriptionOption, with the AND relationship
  between the two spelled out.
* The pinned entry point is a ⋮ overflow-menu item, not a button
  (CometChatMessageHeader.tsx:343-346 pushes `{ text: 'Pinned Messages' }` into
  the options list), and needs BOTH showPinnedMessagesButton and
  onPinnedMessagesPress — setting one does nothing. Corrected in all four places.
* Menu labels are "Subscribe to thread" / "Unsubscribe from thread"
  (translation.json:231-232), not Follow / Unfollow.
* SavedMessageSource is not exported from the package root, so the callback's
  parameter is now shown as an inline type with its real fields instead of a name
  a reader cannot import.
* The five pin/save helpers — isPinned, isSystemPin, isSaved, getPinSaveFeatures,
  refreshPinSaveFeatures — are all still exported and correct. Restored as a
  Helpers section, with a note that refreshPinSaveFeatures is not needed in
  normal use because the kit re-resolves on every reconnect.
* custom-text-formatter-guide: title was "Custom Text Formatter", the same as
  guide-color-formatter — now "Text Formatter Base Class", matching its own
  sidebar entry. The stray top-level `<CometChatConversations …/>;` expression is
  now a comment, since it was neither valid at that position nor part of the
  component above it.

Checked after the edits: every in-page anchor on the five files resolves to a
heading that exists, every internal link resolves to a page that exists, and the
Custom Text Formatter title collision is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The last nit from the review that cc26136 missed: both guides declared
`function ChatScreen({ user, group })` in a .tsx block, which is an implicit-any
error under the strict settings the rest of the samples assume. Annotated with
the SDK types, and guide-text-color gains the `CometChat` import the annotation
needs — custom-text-formatter-guide already had it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@suraj-chauhan-cometchat

Copy link
Copy Markdown
Contributor Author

@raj-dubey1 thanks — all of it addressed across cc261366 and aa1a7794.

Blocking item: retired by the release, not by an edit

5.5.1 is now npm latest. Your remedy was "hold until 5.5.1 is on npm"; that happened on release day. I re-checked every API you listed against the published tarball (not dev-v5):

API In published 5.5.1
formatRawText() CometChatTextFormatter.ts:235
composer.replaceSelection() compact composer :566, :3652
textFormatters Pinned ✅ Saved ✅ Search ✅ MessageInformation ✅
messagesRequestBuilder Pinned ✅ Saved ✅
GroupMembers.onError :190 — (e: CometChat.CometChatException) => void

I did not add "Requires 5.5.1+" callouts: no RN page carries a version callout today, so introducing the convention on these pages alone would be inconsistent. Happy to add them everywhere if you'd rather have that as a house rule.

Should fix — all three, each verified against the same tarball first

  1. Moderation. You're right, isPinSaveEligible() allows pending (PinSaveHelper.ts:308). Rewritten to describe what the kit actually does: offer the option, let the server refuse, render the refusal.
  2. ThreadSubscriptionConfig. Still exported, still on by default (ThreadSubscriptionHelper.ts:95), and setEnabled(false) is the only app-wide opt-out — documented on message-list beside hideThreadSubscriptionOption, with the AND relationship spelled out.
  3. The pinned entry point. Correct — CometChatMessageHeader.tsx:343 pushes { text: 'Pinned Messages' } into the options list, and it needs both props. Fixed in all four places you pointed at.

Nits — all done

  • custom-text-formatter-guide title → "Text Formatter Base Class", matching its own sidebar entry
  • Labels → "Subscribe to thread" / "Unsubscribe from thread" (translation.json:231-232)
  • SavedMessageSource isn't exported from the root, so the callback param now shows its real fields inline instead of a name nobody can import
  • The stray top-level <CometChatConversations …/>; is a comment; both ChatScreen samples are now typed (aa1a7794)
  • The five helpers (isPinned, isSystemPin, isSaved, getPinSaveFeatures, refreshPinSaveFeatures) are back, as a Helpers section
  • PR body corrected — RN keeps thread subscription inside guide-threaded-messages.mdx, there is no standalone page

Re-checked after the edits: every in-page anchor and internal link on the touched files resolves, and the title collision is gone.

One thing outside this PR

CometChatMessageHeader.tsx:130 and CometChatMessageList.tsx:477 both say ThreadSubscriptionConfig.setEnabled is "off by default", and ThreadSubscriptionHelper.ts:79 says "Default OFF: the integrator opts in" — but the implementation is private static enabled: boolean = true. Stale comments in the shipped package, not a docs problem; raising separately.

Also worth flagging: UI Kit 5.5.x needs chat SDK ≥ 4.1.0 (setPinnedOnly / setSavedOnly land there; 4.0.29 doesn't have them), but the peer range is "*". Not this PR either.

Ready for another look.

raj-dubey1
raj-dubey1 previously approved these changes Sep 25, 2026

@jitvarpatil jitvarpatil 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: RN UI Kit — Pin & Save, Pin Conversation, Thread Subscription

Requesting changes. The structure and the documented divergences hold up, but several documented APIs exist only in 5.5.1, not the 5.5.0 the PR verified against — and the code samples that use them are ones customers copy verbatim.

🔴 Blockers

1. Several documented APIs don't exist in 5.5.0 — only in 5.5.1

latest on npm is 5.5.1. Diffing the two published tarballs, these are 5.5.1-only:

API Documented in In 5.5.0?
composer.replaceSelection(text) guide-color-formatter.mdx (Step 2 button), compact-message-composer.mdx (handle table) ❌ added in 5.5.1
textFormatters on CometChatPinnedMessages / CometChatSavedMessages guide-color-formatter.mdx Step 4 + both component pages ❌ added in 5.5.1
textFormatters on CometChatSearch / CometChatMessageInformation same ❌ added in 5.5.1
messagesRequestBuilder on pinned / saved both component pages ❌ added in 5.5.1

On 5.5.0 the colour-formatter guide's toolbar button doesn't compile, and its "Render It Everywhere the Message Appears" step silently does nothing on four of the five surfaces — the reader sees raw {color=...} markers, which is precisely the failure that section warns about. No page states a required version, so nothing tells a 5.5.0 reader why.

Please re-verify against 5.5.1 and add a version note — e.g. "Requires @cometchat/chat-uikit-react-native 5.5.1 or later" — on the colour-formatter guide and on the affected component pages (pinned, saved, search, message-information, compact composer).

2. validate-branch-name is failing — this is why the PR is BLOCKED

The branch is feat/rn-pin-save-thread-subscription-uikit-docs, but .github/branch-naming-convention.md requires docs/<section-name> for documentation changes (and the PR checklist's branch-naming box is unticked). Please re-push on a docs/… branch, or get an admin override. Everything else is green — vale-spellcheck NEUTRAL is its normal non-blocking result.

🟠 Should fix: no documented way to turn thread subscription off

The pages say thread subscription is "Enabled by default" and offer only the per-surface hideThreadSubscriptionOption / threadSubscriptionVisibility flags. The app-wide gate is ThreadSubscriptionConfig.setEnabled(false) — a public, exported API (src/index.ts; shared/utils/ThreadSubscriptionHelper.ts:82-101) that the bell itself checks:

!!parentMessage && ThreadSubscriptionConfig.isEnabled() && threadSubscriptionVisibility

bf75dc12 dropped every reference to it, so a customer who wants the feature off app-wide has no documented option and has to hide it screen by screen. Same gap as iOS #519, where the opt-out was also the missing piece. Worth a short "Turning the feature off" note in the threaded-messages guide.

✅ Verified correct

  • Nav: all six new/renamed pages are in docs.json — no orphans, and the new guides sit in Android's relative order.
  • The three colour guides are not duplicates (my first suspicion): custom-text-formatter-guide (base class), guide-text-color (built-in rich text, no formatter), guide-color-formatter (your own marker, cross-platform). Each says when to use the others.
  • Divergence #1 is accurate: threadSubscriptionVisibility is on CometChatMessageHeader (:138), defaults to true (:216), and CometChatThreadHeader.tsx:105 itself points at CometChatMessageHeader (parentMessage + threadSubscriptionVisibility) for the bell.
  • ToolbarTrailingButtonsView exists on CometChatCompactMessageComposer only, as both guides' Warning says.
  • guide-text-color's composer calls (applyInlineStyle, removeInlineStyle, getActiveStyles, getSelection, getText) all exist in 5.5.0, so that guide is fine on either version.
  • CometChatMessageInformation exists and is correctly added to the nav.

…othing

Self-review of #516 against the published 5.5.1 tarball. Three props were
documented as working that the component never reads — each is declared in
CometChatMessageInformationInterface, destructured at the top of the component,
and then not referenced again.

  emptyStateText   removed. The default empty view is `<></>`; there is no string
                   to override (:343-346).
  errorStateText   removed. The error view hard-codes t("WRONG_TEXT") and
                   t("WRONG_TEXT_TRY_AGAIN") (:329-330).
  onBack           kept, with a warning. Unlike the other two it appears in both
                   code samples and in the public type, so removing it silently
                   would leave a reader to rediscover it in autocomplete with no
                   explanation. The screen renders no back control at all — its
                   header is a centred <Text> (:350-354) — so the page now says
                   plainly that 5.5.1 accepts the callback and never calls it, and
                   to give the screen a navigator that provides its own back.

Two smaller corrections on the same page:

* The default title was documented as Localized "Message Information". The en
  bundle maps MESSAGE_INFORMATION to "Message Info" (translation.json:278).
* EmptyStateView was described as replacing the empty state. There is no default
  empty state to replace — without the prop the screen renders nothing in that
  condition — so it ADDS one.

Found by checking each documented prop's occurrence count in the shipped source
rather than trusting the interface: a prop that appears exactly twice is declared
and destructured and never used. onBack surfaced from that same check while
verifying the first two fixes.

The new #onback anchor was checked against IDs scraped from the rendered preview,
not a slug rule.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… the opt-out

Three things from jitvarpatil's review, plus a build break my previous commit
introduced and the review predates.

## The deployment was failing — message-information.mdx

"Failed to parse page content: Unexpected end of file in expression, expected a
corresponding closing brace for `{`". The cause is one table row:

  | Type | `(… receipt: { sender: CometChat.User | CometChat.Group; … })` |

Markdown splits a table row on unescaped pipes BEFORE inline code is parsed, so
the `|` inside the backticks cut the code span in half. The left fragment ends
with an open backtick and an unclosed `{`, which MDX then reads as a JSX
expression that never closes. Escaped as `\|`, the form already used on the
saved-messages page.

Worth recording how it was found: a per-line brace check said the file was
balanced, because it stripped intact inline code — and the span only breaks
AFTER markdown splits the row. The check that finds it splits each table row on
unescaped pipes first, then looks for a cell with an odd number of backticks.
That sweep now runs over every changed page; this was the only occurrence.

## Version notes (blocker 1)

`replaceSelection`, `textFormatters` on Pinned/Saved/Search/MessageInformation,
and `messagesRequestBuilder` on Pinned/Saved all landed in 5.5.1. 5.5.1 is npm
`latest`, but nothing told a reader still on 5.5.0 why the samples fail, and on
that version the colour guide's Step 4 silently renders the raw marker on four of
five surfaces — the exact failure that section warns about.

Each note names only the APIs that are actually 5.5.1-only on that page, and says
the rest of the page works on either version. The colour-formatter guide is the
exception: it is built on the new hook end to end, so the whole guide needs 5.5.1
and the note says so.

I declined this when raj-dubey1 first raised it, reasoning that 5.5.1 being
`latest` made it moot and no RN page carries a version callout. Two reviewers
asking for the same thing is the answer: a reader on a pinned 5.5.0 has no other
way to find out.

## App-wide thread-subscription opt-out (should-fix)

`ThreadSubscriptionConfig.setEnabled(false)` was documented on message-list in
cc26136, but a reader wanting the feature off app-wide looks in the threaded-
messages guide, next to the per-surface flags. Added there as "Turning the feature
off app-wide", with the actual gate expression the bell evaluates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@suraj-chauhan-cometchat

Copy link
Copy Markdown
Contributor Author

Closed by a branch rename, not abandoned — continues in #536.

The branch was feat/rn-pin-save-thread-subscription-uikit-docs, which .github/branch-naming-convention.md doesn't allow for docs changes (feat/ isn't in either list), so validate-branch-name was failing and blocking the merge. Renaming it to docs/react-native-pin-save-thread-subscription closed this PR rather than retargeting it.

#536 has the identical 30 commits and the same head SHA (7846abd9) — nothing was rewritten. Every point from @raj-dubey1's and @jitvarpatil's reviews here is already addressed in those commits; the discussion stays readable on this PR.

hritika-cometchat added a commit that referenced this pull request Sep 26, 2026
…ct Native

Mirror the landed React Native wording from PR #516 across the Android docs:

- conversations: replace the "Built-in Pin Conversation Option" subsection
  with a top-level "Pinning Conversations" section using RN's framing, and
  move the setPinnedBy builder snippet under Filtering Conversations. Keep
  Android's own ConversationListener pin callbacks rather than RN's
  no-real-time-channel warning.
- threaded-messages-header: replace the Subscription Bell callback
  subsection with a "Thread Subscription" section parallel to RN's, noting
  the bell lives in CometChatThreadHeader and can be hosted in the thread
  screen's top bar via ThreadSubscriptionBell.
- pinned-messages / saved-messages: trim the overviews to RN's minimal
  shape and add the pin and save screenshots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
hritika-cometchat added a commit that referenced this pull request Sep 26, 2026
… toolbar

Mirrors the React Native text color guide from #516 for
Android, adapted to what the Android UI Kit actually ships.

React Native colors text through a built-in rich-text format
(applyInlineStyle("color", ...)), so its guide has nothing to render.
Android's RichTextFormat has no color entry, so the Android path is a
two-part one: a swatch row in the rich-text toolbar's trailing slot writes
a {color:#rrggbb}...{/color} token through ComposerInputController, and a
CometChatTextFormatter renders that token - applyComposerSpans() on XML and
composerVisualTransformation() on Compose for the live input,
prepare*Span() on bubbles, conversation subtitles and previews.

Every API in the guide was read from the shipped source: the trailing slot
(RichTextToolbarTrailingViewListener / trailingToolbarContent), the
controller members, the null tracking-character idiom used by
CometChatRichTextFormatter, and the formatter hooks whose KDoc documents
this exact colour-token case.

Also follows the RN naming: the new guide takes the "Custom Text Formatter"
title and the base-class guide becomes "Text Formatter Base Class" in the
sidebar, so the group has no two identical entries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
staging — 7846abd9 Deployed Sep 25, 2026 by mintlify[bot]
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.

4 participants