Skip to content

feat(pin-save-thread-subscription-react-native-sdk): add documentation for pin/save messages, pin conversations and thread subscription - #493

Merged
ketanyekale merged 6 commits into
mainfrom
feature/pin-save-thread-subscription-react-native-sdk
Sep 8, 2026
Merged

ketanyekale merged 6 commits into
mainfrom
feature/pin-save-thread-subscription-react-native-sdk

Conversation

@suraj-chauhan-cometchat

Copy link
Copy Markdown
Contributor

Description

Add documentation for pin/save messages, pin conversations and thread subscription to the React Native SDK.

This is the React Native counterpart to #469 (JavaScript SDK) and mirrors it page-for-page and in nav placement.

New pages

Page Covers
sdk/react-native/pin-message pin/unpin, fetch the pinned list, read pin state, real-time events, caps, feature availability
sdk/react-native/save-message save/unsave, the cross-conversation saved list, read save state, multi-device events, cap
sdk/react-native/pin-conversation pin/unpin, the pinned conversation list, read pin state, keeping the list in sync, caps
sdk/react-native/thread-subscription subscribe/unsubscribe, reading subscription state, the thread inbox via ThreadsRequest

Updated pages

  • additional-message-filtering — new Pinned messages and Saved messages sections
  • real-time-listenersonMessagePinned / onMessageUnpinned / onMessageSaved / onMessageUnsaved rows
  • threaded-messageswithParent() and a Subscribe to a Thread section
  • docs.json — nav entries, in the same positions the JavaScript pages took

Additional Information

These pages were written against the React Native SDK surface rather than translated from the JavaScript pages. The two APIs diverge enough that a translation would have shipped code that does not run. Every sample was checked against dist/CometChat.d.ts on the SDK release branch.

Method names that differ:

JavaScript SDK React Native SDK
setPinned(true) setPinnedOnly(true)
setSaved(true) setSavedOnly(true)
getPinnedMessagesLimit() getPinMessageLimit()
getSystemPinnedMessagesLimit() getSystemPinMessageLimit()
getSavedMessagesLimit() getSaveMessageLimit()
getPinnedConversationsLimit() getPinConversationLimit()
getSystemPinnedConversationsLimit() getSystemPinConversationLimit()

Not present in the React Native SDK:

  • isPinned(), isSaved(), isSystemPinned() — the pages derive state from getPinnedAt(), getSavedAt() and getPinnedBy() instead
  • CometChat.PINNED_BYsetPinnedBy() takes the bare strings "me" / "system", matched case-sensitively and dropped silently when unmatched, so the page warns that a typo returns the full list rather than an error
  • ConversationListener (addConversationListener, onConversationPinned, onConversationUnpinned) — absent entirely, so conversation pins have no real-time channel and the page documents re-fetching instead

React Native behaviour documented here that the JavaScript pages do not cover: the 5-per-user conversation pin cap (not 100), the unseeded features.ux.conversations.pinned.enabled flag that makes conversation pinning off by default, errorParams.limit on a cap breach, the ThreadsRequestBuilder setUid() / setGuid() casing that differs from MessagesRequestBuilder, and getUnreadReplyCount() returning null for unknown rather than zero.

One item for the #469 author

The JavaScript pin-conversation page states that addressing by peer "lets you pin a conversation that has no messages yet." The React Native SDK rejects that case with ERR_CONVERSATION_NOT_ACCESSIBLE. Either the two SDKs genuinely differ here or that note needs correcting on #469 — worth confirming before both pages ship.

Type of Change

  • Documentation correction/update
  • New documentation
  • Improvement to existing documentation
  • Typo fix
  • Other (please specify)

Checklist

  • I have read the CONTRIBUTING document
  • My branch name follows the naming convention
  • My changes follow the documentation style guide
  • I have checked for spelling and grammar errors
  • All links in my changes are valid and working
  • My changes are accurately described in this pull request

🤖 Generated with Claude Code

…n for pin/save messages, pin conversations and thread subscription

Mirrors #469 (JavaScript SDK) for the React Native SDK.

New pages:
- sdk/react-native/pin-message
- sdk/react-native/save-message
- sdk/react-native/pin-conversation
- sdk/react-native/thread-subscription

Updated:
- additional-message-filtering: setPinnedOnly / setSavedOnly sections
- real-time-listeners: onMessagePinned/Unpinned/Saved/Unsaved rows
- threaded-messages: withParent() and a Subscribe to a Thread section
- docs.json: nav entries, mirroring the JavaScript placement

Written against the React Native SDK surface rather than translated from the
JavaScript pages, because the two APIs diverge:

- setPinnedOnly()/setSavedOnly(), not setPinned()/setSaved()
- getPinMessageLimit(), getSystemPinMessageLimit(), getSaveMessageLimit(),
  getPinConversationLimit(), getSystemPinConversationLimit() — all spelled
  differently from their JavaScript counterparts
- no isPinned()/isSaved()/isSystemPinned() helpers; state is derived from
  getPinnedAt()/getSavedAt()/getPinnedBy()
- no CometChat.PINNED_BY constant; setPinnedBy() takes the bare strings
  "me"/"system", matched case-sensitively and dropped silently when unmatched
- no ConversationListener at all, so conversation pins have no real-time
  channel and the pages say to re-fetch instead

Also documents React Native behaviour absent from the JavaScript pages: the
5-per-user conversation pin cap, the unseeded
features.ux.conversations.pinned.enabled flag, errorParams.limit on cap
breach, the ThreadsRequestBuilder setUid/setGuid casing, and
getUnreadReplyCount() returning null for unknown rather than zero.

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

mintlify Bot commented Sep 7, 2026

Copy link
Copy Markdown

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

Project Status Preview Updated
cometchat 🟢 Ready View Preview Sep 7, 2026, 12:30 PM

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

…caps, document moderation window

Review findings on this PR.

Message IDs are documented as `number` in pin-message and save-message, matching
thread-subscription, threaded-messages and the JavaScript pages. They were
`string` because the signature reads `messageId: string | any`, which was a
misread — that union collapses to `any` and carries no type information. The
runtime validator is `isNaN()` and rejects with "Message Id must be a number",
so the string form contradicted the SDK's own error text.

The conversation pin note no longer states "5 per user, not 100". Both numbers
were unverified: our measured settings record `conversations.pinned.limit=10`
and `messages.pinned.limit=5`, so the sentence may have been inverted. It also
contradicted pin-message, which tells readers never to hard-code a cap. The note
now states only that the two quotas are separate and must be read at runtime.

Both pin-message and save-message now document the moderation window: a message
that is still `moderation.status: "pending"` is refused with
403 ERR_MESSAGE_NO_ACCESS, which is the same code the server returns for a real
permission refusal, so the two cannot be distinguished from the error alone. The
window runs from send rather than from the user's tap, so the guidance is to
retry rather than disable the control. Moderation is per-app and does not
reproduce where it is switched off.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…I Kit surface for pin/save, pin conversation and thread subscription

Adds the UI Kit half of this PR, alongside the SDK pages already here.

New component pages:
- ui-kit/react-native/pinned-messages  (CometChatPinnedMessages)
- ui-kit/react-native/saved-messages   (CometChatSavedMessages)

Updated:
- message-list: hidePinMessageOption, hideUnpinMessageOption,
  hideSaveMessageOption, hideUnsaveMessageOption and
  hideThreadSubscriptionOption, in the visibility block and as per-prop
  sections in alphabetical order, plus a section on how the gates compose
- conversations: pinConversationOptionVisibility and a Pinning Conversations
  section
- docs.json: nav entries in the Components group, after message-list

The point the pages lead with is that a `false` default on a hide* prop does
not mean the option is visible. Pin and Save are gated twice — the integrator's
PinSaveConfig opt-in, which defaults to OFF, ANDed with a server flag the kit
resolves at login and on reconnect. Thread subscription inverts this:
ThreadSubscriptionConfig defaults to ON to match the React UI Kit, so its prop
is the usual way to hide it. Pin Conversation additionally needs
features.ux.conversations.pinned.enabled, which is seeded in no plan.

Also documents the UI Kit's own state helpers — isPinned, isSaved, isSystemPin,
isConversationPinned, isSystemPinnedConversation — which have no equivalent in
the Chat SDK and exist because the SDK exposes only the raw timestamps.

conversations.mdx now distinguishes CometChatUIEventHandler.addConversationListener,
which the page already used, from the Chat SDK's ConversationListener, which does
not exist. The identical names on the two libraries are otherwise a trap.

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

Copy link
Copy Markdown
Contributor

Docs review — structurally clean, two content items.

Ran the mechanical checks (redirect coverage, nav integrity, orphans, in-content link rot) plus a content read of all 12 changed files, including the two new UI Kit pages. Build is safe: 0 unresolved nav refs, 0 missing redirects (fully additive), 0 orphans — the new ui-kit/react-native/pinned-messages / saved-messages pages are correctly wired into docs.json. Method-name accuracy is spot-on: I grepped every JavaScript name (setPinned(, getPinnedMessagesLimit, …) across the RN SDK and UI Kit pages and found zero leakage — the RN names (setPinnedOnly, getPinMessageLimit, …) are used consistently everywhere.

Two things worth fixing:

1. real-time-listeners.mdx — the listener table documents four callbacks the code sample omits (should-fix)

The Message Listener table adds all four new events (lines 355–358): onMessagePinned / onMessageUnpinned / onMessageSaved / onMessageUnsaved. But the "add the MessageListener" code sample right below — both the TypeScript and JavaScript tabs (~lines 364–475) — ends at onCardMessageReceived and includes none of them. A reader who copies the sample gets no pin/save handling despite the table promising it. The correct callbacks are already shown in pin-message.mdx and save-message.mdx, so they can be copied into both tabs here.

2. pin-conversation.mdx — paired TS/JS example passes different setPinnedBy args (nit)

Line 183 (TypeScript tab): .setPinnedBy(["system", "me"]); line 202 (JavaScript tab): .setPinnedBy(["me"]). Same example, two tabs — they should match so it doesn't read as a behavioral TS-vs-JS difference. The Accordion (line 18) uses ["system", "me"], so aligning the JS tab to that is the consistent fix.

Everything else checks out — package/import names (@cometchat/chat-sdk-react-native, @cometchat/chat-uikit-react-native), images (none), placeholders (none), cross-links, the two new UI Kit pages' prop tables, and the setPinnedBy filter token ("system") vs getPinnedBy() value ("app_system") distinction, which is correctly documented.

raj-dubey1
raj-dubey1 previously approved these changes Sep 7, 2026
hritika-cometchat added a commit that referenced this pull request Sep 7, 2026
… RN parity

Verified every documented symbol against chat-sdk-android and uikit-android
and brought the pages in line with the React Native counterpart (#493).

Corrections — these APIs do not exist in the Android SDK:
- CometChat.getThreadSubscriptionState() and the ThreadSubscriptionState enum
- CometChat.addThreadListener(), ThreadListener, ThreadSubscriptionEvent,
  ThreadReplyEvent
- MessageThread.getSubscriptionState() (it is isSubscribed())

Thread subscription is rewritten around the real model: the subscribe/
unsubscribe callback is the acknowledgement, state rides on the message via
BaseMessage.isThreadSubscribed() with MessagesRequestBuilder.withThreadSubscribed()
(default true), and setThreadSubscribed() is a local-only mirror. Replies arrive
on the ordinary MessageListener. The Thread Listener section is removed from
real-time-listeners and replaced with a note explaining why there is none.

CometChatThreadEvent.SubscriptionChanged is (parentMessageId: Long,
subscribed: Boolean) — not the subscriptionState/source signature documented.

Pin permission is enforced by the server (ERR_PERMISSION_DENIED), not by a
client-side Admin/Moderator/Owner gate; MessageOptionsUtils shows the option to
every participant. Corrected in the SDK page, message-list and the guide.

Parity with the React Native pages:
- sidebarTitle/description frontmatter and an AI Integration Quick Reference
  accordion on the four new SDK pages
- pin/save/pin-conversation caps via getPinMessageLimit(),
  getSystemPinMessageLimit(), getSaveMessageLimit(), getPinConversationLimit()
  and getSystemPinConversationLimit(), with Settings.LIMIT_UNSPECIFIED,
  replacing a hard-coded "100 by default"
- isSystemPinned(), pin-time/save-time ordering and cursor notes, the
  moderation-pending ERR_MESSAGE_NO_ACCESS warning
- error tables with the real codes, and Next Steps card groups

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…two review items

Three fixes.

The two new UI Kit component pages used the SDK's javascript-snippet form of the
AI Integration Quick Reference. Every other page in the Components group —
conversations, users, groups, group-members, message-header, message-list,
message-composer, compact-message-composer, threaded-messages-header,
incoming-call, outgoing-call, call-buttons, call-logs, notification-feed — uses
a structured JSON schema instead, keyed on component/package/import/description
plus props grouped as data, callbacks, visibility and customization. Both pages
now follow that, with a `requires` block for the PinSaveConfig opt-in and the
server flag, and a `helpers` block for the kit's own state helpers. Both blocks
parse as valid JSON.

Review item 1 — real-time-listeners documented onMessagePinned, onMessageUnpinned,
onMessageSaved and onMessageUnsaved in the Message Listener table, but the
addMessageListener sample below it ended at onCardMessageReceived in both tabs.
A reader copying the sample got no pin/save handling. All four are now in the
TypeScript and JavaScript tabs.

Review item 2 — pin-conversation passed different arguments in paired tabs:
setPinnedBy(["system", "me"]) in TypeScript, setPinnedBy(["me"]) in JavaScript,
which reads as a behavioural difference between the two languages. The
JavaScript tab now matches the TypeScript tab and the accordion.

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

The pages showed setLimit(50) in examples but never said what happens without
it. MessagesRequestBuilder defaults to 30 and rejects anything above 100
(Constants.ts — MSGS_LIMIT 30, MSGS_MAX_LIMIT 100), so both SDK pages now say
so in the same words retrieve-conversations already uses.

The two UI Kit panels documented `limit` as "SDK default" with an em dash in the
prop table, which told a reader nothing. Both now state 30 — the value
CometChatPinnedMessages and CometChatSavedMessages actually pass
(`builder.setLimit(limit ?? 30)`) — and note the 100 ceiling.

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

The three pages told developers the feature is off until they call
PinSaveConfig.enablePin(true) / enableSave(true) at app start. That is backwards.

PinSaveFeatureGates.applyToConfigs() sets those switches itself from the app's
Dashboard flags, at login and on every reconnect:

    PinSaveConfig.enablePin(flags.pinMessage);
    PinSaveConfig.enableSave(flags.saveMessage);
    PinConversationConfig.enable(flags.pinConversation);

The sample app never references PinSaveConfig at all, and pin/save works there —
which is what surfaced this. As written, the docs sent integrators looking for a
missing call, and implied a feature enabled in their Dashboard would still be
dark until they wrote code.

Corrected on all three pages: the Dashboard setting is the gate, the kit resolves
it, and PinSaveConfig is described as the read/override surface it actually is.
Thread subscription keeps its own wording — it is not an app setting, so
ThreadSubscriptionConfig really is a switch, defaulting to on.

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

Copy link
Copy Markdown
Contributor Author

Both items are fixed in 4c3ffd0a.

1. real-time-listeners.mdx — the four callbacks are now in the code sample.
Added onMessagePinned, onMessageUnpinned, onMessageSaved and onMessageUnsaved to both tabs, so the sample matches the listener table above it:

  • TypeScript tab — lines 413–422
  • JavaScript tab — lines 481–490

2. pin-conversation.mdx — the paired tabs now agree.

-  .setPinnedBy(["me"])
+  .setPinnedBy(["system", "me"])

All three occurrences (lines 18, 183, 202) are now ["system", "me"], matching the Accordion. No bare setPinnedBy(["me"]) remains in the file.

Since these went up as a push, the approvals were auto-dismissed — the PR is back at REVIEW_REQUIRED. It is MERGEABLE with no conflicts and fully additive (12 files, +2570/-0), so it just needs a re-approve when you have a moment.

@jitvarpatil

Copy link
Copy Markdown
Contributor

Docs review — ✅ Approve (one should-fix)

The React Native counterpart of #461 — six new pages plus supporting updates (12 files, +2,570, all new content). Structurally clean, 0 new broken links, and every documented API verifies against the published npm packages.

✅ API verified against published npm packages

@cometchat/chat-sdk-react-native@4.1.0 — all 14 documented symbols present:
pinMessage · unpinMessage · saveMessage · unsaveMessage · pinConversation · unpinConversation · subscribeToThread · unsubscribeFromThread · isPinMessageEnabled · isSaveMessageEnabled · getPinMessageLimit · getSystemPinMessageLimit · MessageThread · ThreadsRequest

@cometchat/chat-uikit-react-native@5.5.0CometChatPinnedMessages, CometChatSavedMessages, and the ccMessagePinned / ccMessageSaved events all present.

Structure: all 6 new pages wired into nav; 0 nav breaks, 0 orphans, redirects +0; no placeholders/TODOs across 2,570 new lines. The 3 broken links the analyzer flagged (direct-call, default-call, login-listener) are pre-existing in unchanged files — none appear in this PR's added lines.

🟡 Should-fix — no minimum version stated

I traced the introduction point:

Package Present in Absent in
@cometchat/chat-sdk-react-native 4.1.0 only 4.0.28, 4.0.29

A developer on 4.0.29 — the previously-latest release — will follow these pages and hit "method doesn't exist" errors, with nothing explaining why. Suggested note, matching the precedent from the transcription PR (#487):

<Note>
**Available since v4.1.0** — pin, save, and thread subscriptions require
`@cometchat/chat-sdk-react-native` v4.1.0 or later. See [Setup](/sdk/react-native/setup) to upgrade.
</Note>

Cross-PR note

This is the second platform (after Flutter #461) shipping this feature set with no availability note. If Android/iOS versions follow, it's worth making the version callout a standard part of the template — the transcription rollout (#487) did exactly that across all 5 platforms, and it's the difference between a clean upgrade and a support ticket.

Minor: RN uses singular page slugs (pin-message, save-message) where Flutter used plural (pin-messages, save-messages) — harmless, but inconsistent if anyone cross-links between platforms.

Content is accurate and well-structured. Approving on the assumption the version note lands here or in a quick follow-up. 🚀

🤖 Automated docs review (Mintlify link/redirect/nav checks + API verification against published @cometchat/chat-sdk-react-native and chat-uikit-react-native packages).

@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.

Docs review — ✅ Approve (one should-fix)

The React Native counterpart of #461 — six new pages plus supporting updates (12 files, +2,570, all new content). Structurally clean, 0 new broken links, and every documented API verifies against the published npm packages.

✅ API verified against published npm packages

@cometchat/chat-sdk-react-native@4.1.0 — all 14 documented symbols present:
pinMessage · unpinMessage · saveMessage · unsaveMessage · pinConversation · unpinConversation · subscribeToThread · unsubscribeFromThread · isPinMessageEnabled · isSaveMessageEnabled · getPinMessageLimit · getSystemPinMessageLimit · MessageThread · ThreadsRequest

@cometchat/chat-uikit-react-native@5.5.0CometChatPinnedMessages, CometChatSavedMessages, and the ccMessagePinned / ccMessageSaved events all present.

Structure: all 6 new pages wired into nav; 0 nav breaks, 0 orphans, redirects +0; no placeholders/TODOs across 2,570 new lines. The 3 broken links the analyzer flagged (direct-call, default-call, login-listener) are pre-existing in unchanged files — none appear in this PR's added lines.

🟡 Should-fix — no minimum version stated

I traced the introduction point:

Package Present in Absent in
@cometchat/chat-sdk-react-native 4.1.0 only 4.0.28, 4.0.29

A developer on 4.0.29 — the previously-latest release — will follow these pages and hit "method doesn't exist" errors, with nothing explaining why. Suggested note, matching the precedent from the transcription PR (#487):

<Note>
**Available since v4.1.0** — pin, save, and thread subscriptions require
`@cometchat/chat-sdk-react-native` v4.1.0 or later. See [Setup](/sdk/react-native/setup) to upgrade.
</Note>

Cross-PR note

This is the second platform (after Flutter #461) shipping this feature set with no availability note. If Android/iOS versions follow, it's worth making the version callout a standard part of the template — the transcription rollout (#487) did exactly that across all 5 platforms, and it's the difference between a clean upgrade and a support ticket.

Minor: RN uses singular page slugs (pin-message, save-message) where Flutter used plural (pin-messages, save-messages) — harmless, but inconsistent if anyone cross-links between platforms.

Content is accurate and well-structured. Approving on the assumption the version note lands here or in a quick follow-up. 🚀

🤖 Automated docs review (Mintlify link/redirect/nav checks + API verification against published @cometchat/chat-sdk-react-native and chat-uikit-react-native packages).

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.

5 participants