Skip to content

Conversation

@emphor11
Copy link

@emphor11 emphor11 commented Jan 20, 2026

🎯 Summary

This PR fixes the issue where pin and star icons don't appear immediately after pinning or starring a message. The fix implements optimistic UI updates that immediately reflect the user's action in the local database, providing instant visual feedback.

📋 Description

Problem

When users pin or star a message, they have to wait for the server to send the updated message via stream-room-messages before the icon appears. This creates confusion and poor user experience.

Solution

After a successful pin/star API call, immediately update the message in the local WatermelonDB database:

  1. Retrieve the message from the database
  2. Update the pinned or starred property
  3. Set _updatedAt to trigger re-render via experimentalSubscribe
  4. Server stream update still arrives and keeps everything in sync

Result

  • ⚡ Instant visual feedback (icon appears immediately)
  • 🎯 Better UX (users know their action worked)
  • 🔄 Graceful fallback (server stream still syncs state)
  • ✅ Production ready (type-safe, error-handled)

🔧 Technical Details

Files Changed: app/containers/MessageActions/index.tsx (+30 lines)

Functions Modified:

  • handleStar() - Added immediate DB update after API call succeeds
  • handlePin() - Added immediate DB update after API call succeeds

🧪 Testing

  1. Run the app and login to Rocket.Chat
  2. Long-press a message and tap "Pin" → Pin icon appears INSTANTLY ✨
  3. Long-press again and tap "Unpin" → Pin icon disappears INSTANTLY ✨
  4. Long-press a message and tap "Star" → Star icon appears INSTANTLY ✨
  5. Test with multiple quick actions - all update instantly

✨ Benefits

  • ✅ Instant visual feedback
  • ✅ Optimistic UI pattern
  • ✅ Error handling with graceful fallback
  • ✅ Type safe (TypeScript)
  • ✅ No breaking changes
  • ✅ Production ready

Summary by CodeRabbit

  • Bug Fixes
    • Pin and star actions now provide instant visual feedback. When you pin or star a message, the icon updates immediately instead of waiting for server confirmation. Server synchronization continues in the background to ensure consistency.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add immediate database update after pin/star API calls succeed
- Update message in local database with new pinned/starred state
- Set _updatedAt timestamp to trigger UI re-render via experimentalSubscribe
- Ensures icons appear immediately without waiting for stream-room-messages

Fixes issue where pin and star icons didn't appear immediately after
pinning or starring a message. The UI now updates optimistically while
still allowing server updates to sync via the message stream.
- QUICK_START.md: Simple 3-step guide to run the project
- CHANGES_SUMMARY.md: Detailed explanation of changes and how they work
- VISUAL_SUMMARY.md: Visual diagrams, code flow, and testing checklist
- RUN_PROJECT_GUIDE.md: Complete setup guide with troubleshooting

These docs help developers understand the fix, test it, and run the project.
@CLAassistant
Copy link

CLAassistant commented Jan 20, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Walkthrough

Introduces optimistic UI updates for pin and star actions in MessageActions. After successful API calls (toggleStarMessage, togglePinMessage), the code immediately updates the local WatermelonDB store by toggling the starred/pinned flags and updating _updatedAt timestamps. Server streams maintain synchronization while UI reflects changes instantly.

Changes

Cohort / File(s) Summary
Core Implementation
app/containers/MessageActions/index.tsx
Added immediate local database updates in handleStar() and handlePin() methods. After successful API calls, toggles message starred/pinned state and updates _updatedAt to trigger instant UI re-render via WatermelonDB subscriptions. Includes error logging if message not found locally.
Documentation
START_HERE.md, QUICK_START.md, FIX_README.md, PROJECT_SUMMARY.md, RUN_PROJECT_GUIDE.md, VISUAL_SUMMARY.md, CHANGES_SUMMARY.md
Comprehensive documentation suite describing the optimistic UI pattern, setup instructions, testing procedures, visual flow diagrams, and quick-start guides. Covers branch details, code modifications, testing checklist, troubleshooting, and server synchronization behavior.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App as App<br/>(MessageActions)
    participant API as API<br/>(Server)
    participant LocalDB as WatermelonDB<br/>(Local)
    participant Stream as Server Stream<br/>(Sync)
    participant UI as UI<br/>(Renderer)

    User->>App: Tap Star/Pin Icon
    App->>API: toggleStarMessage/<br/>togglePinMessage
    API-->>App: Success
    App->>LocalDB: Update message<br/>(toggle starred/pinned,<br/>set _updatedAt)
    LocalDB-->>UI: experimentalSubscribe<br/>fires (immediate)
    UI->>UI: Re-render with<br/>updated icon state
    User->>User: Sees instant<br/>visual feedback
    
    Note over Stream: Later...
    Stream->>LocalDB: Server sync arrives<br/>(stream-room-messages)
    LocalDB->>UI: Re-render if state<br/>differs
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • diegolmello
  • OtavioStasiak

Poem

🐰 Hops with glee through instant updates,
Stars and pins need not wait—
Local DB now speaks first,
Quenching the impatient user's thirst!
Server streams follow with care,
Optimistic UX beyond compare!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix/pin star icons immediate update' clearly summarizes the main change: implementing immediate visual feedback for pin and star actions through optimistic UI updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@PROJECT_SUMMARY.md`:
- Around line 134-145: The fenced code block that begins with "Branch:          
fix/pin-star-icons-immediate-update" is missing a language identifier; update
that Markdown block delimiter from ``` to ```text so linters recognize it as
plain text (i.e., add the language tag to the fenced code block containing the
branch/commits/stats summary).

In `@QUICK_START.md`:
- Around line 5-7: Replace the user-specific absolute path string "cd
/Users/dakshyadav/Rocket.Chat.ReactNative" in QUICK_START.md with a portable
placeholder such as "cd ~/Rocket.Chat.ReactNative" or "cd
<repo-root>/Rocket.Chat.ReactNative" so readers can run the command on their own
systems; update the single line containing that path accordingly.

In `@RUN_PROJECT_GUIDE.md`:
- Around line 24-27: Replace the hard-coded user-specific absolute path string
"/Users/dakshyadav/Rocket.Chat.ReactNative" found under the "### 1. Clean
Previous Installation (Recommended)" section with a portable placeholder (e.g.,
"~/Rocket.Chat.ReactNative" or "<project-root>") and update the same pattern
wherever it appears (notably the occurrences referenced around lines 134-139) so
the guide uses non-user-specific paths.
- Around line 215-235: Replace bare URLs in RUN_PROJECT_GUIDE.md with markdown
link syntax to satisfy MD034: change the Server URL line and all resource links
to formatted links (e.g. the server URL text should be a link, and the three
resource URLs https://developer.rocket.chat/docs/mobile-app,
https://reactnative.dev/docs/getting-started, and
https://github.com/RocketChat/Rocket.Chat.ReactNative/issues should be rewritten
using [text](url) form; also convert the plain CONTRIBUTING.md mention into a
markdown link). Update the lines containing "Server URL:", "Project
Documentation:", "React Native Docs:", "Contributing Guide:", and the footer
"For questions or issues, visit:" to use link syntax.

In `@START_HERE.md`:
- Around line 92-101: Update the fenced code block in START_HERE.md to include a
language identifier (use "text") for the tree snippet and replace the emphasized
line "**Total: 30 lines of focused code**" with a heading (e.g., "### Total: 30
lines of focused code"); locate the tree snippet and the emphasized summary near
the block that shows "app/containers/MessageActions/index.tsx" and modify the
backticks to "```text" and change the emphasized markdown to a heading to
satisfy markdownlint.
- Around line 154-177: Add the missing language identifier to both fenced code
blocks in START_HERE.md (the "Before" flow diagram and the "After (New - Our
Fix)" flow diagram) by changing the opening backticks to include a language tag
(e.g., ```text or ```bash) so the blocks satisfy MD040 and render correctly;
update the two blocks that show the user/app/server flows (the one starting with
'User: "Pin this message"' in the Before section and the corresponding block in
the After section) to use ```text (recommended) at their openings.

In `@VISUAL_SUMMARY.md`:
- Around line 6-46: The fenced code blocks in VISUAL_SUMMARY.md lack language
identifiers causing markdownlint MD040 failures; update each triple-backtick
block (including the flows showing USER ACTION/API CALL/WAIT and the code-like
steps that reference togglePinMessage(), message.pinned, message._updatedAt,
experimentalSubscribe(), MessageContainer, and 'stream-room-messages') to
include an appropriate language tag (e.g., ```text or ```flow or ```mermaid
where suitable) so linting passes and readability improves across the blocks
mentioned (lines referenced in the review: around the user flow and the Solution
sections).
🧹 Nitpick comments (1)
app/containers/MessageActions/index.tsx (1)

335-353: Consider deduplicating the optimistic DB update path.

handleStar and handlePin now share the same lookup/write/error pattern; extracting a small helper would reduce drift and keep error handling consistent.

Comment on lines +134 to +145
```
Branch: fix/pin-star-icons-immediate-update
Base: develop
Commits: 3
Files Changed: 5
Lines Added: 793
Code Changes: 30 lines
Documentation: 763 lines
Type: Bug Fix / UX Improvement
Risk Level: Very Low
Status: Ready for Testing
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the fenced code block.

Markdownlint flags this block as missing a language tag. Consider text for the stats block.

Suggested change
-```
+```text
 Branch:                 fix/pin-star-icons-immediate-update
 Base:                   develop
 Commits:                3
 Files Changed:          5
 Lines Added:            793
 Code Changes:           30 lines
 Documentation:          763 lines
 Type:                   Bug Fix / UX Improvement
 Risk Level:             Very Low
 Status:                 Ready for Testing
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
Branch: fix/pin-star-icons-immediate-update
Base: develop
Commits: 3
Files Changed: 5
Lines Added: 793
Code Changes: 30 lines
Documentation: 763 lines
Type: Bug Fix / UX Improvement
Risk Level: Very Low
Status: Ready for Testing
```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

134-134: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@PROJECT_SUMMARY.md` around lines 134 - 145, The fenced code block that begins
with "Branch:                 fix/pin-star-icons-immediate-update" is missing a
language identifier; update that Markdown block delimiter from ``` to ```text so
linters recognize it as plain text (i.e., add the language tag to the fenced
code block containing the branch/commits/stats summary).

Comment on lines +5 to +7
```bash
cd /Users/dakshyadav/Rocket.Chat.ReactNative

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace the user-specific absolute path with a placeholder.

The current path won’t work for most readers. Use a generic placeholder (or ~/...) to keep the guide portable.

💡 Suggested update
-cd /Users/dakshyadav/Rocket.Chat.ReactNative
+cd /path/to/Rocket.Chat.ReactNative
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
cd /Users/dakshyadav/Rocket.Chat.ReactNative
🤖 Prompt for AI Agents
In `@QUICK_START.md` around lines 5 - 7, Replace the user-specific absolute path
string "cd /Users/dakshyadav/Rocket.Chat.ReactNative" in QUICK_START.md with a
portable placeholder such as "cd ~/Rocket.Chat.ReactNative" or "cd
<repo-root>/Rocket.Chat.ReactNative" so readers can run the command on their own
systems; update the single line containing that path accordingly.

Comment on lines +24 to +27
### 1. Clean Previous Installation (Recommended)
```bash
cd /Users/dakshyadav/Rocket.Chat.ReactNative

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid user-specific absolute paths in instructions.

These paths are not portable; use a placeholder or ~/ to keep the guide broadly applicable.

💡 Suggested update
-cd /Users/dakshyadav/Rocket.Chat.ReactNative
+cd /path/to/Rocket.Chat.ReactNative

Also applies to: 134-139

🤖 Prompt for AI Agents
In `@RUN_PROJECT_GUIDE.md` around lines 24 - 27, Replace the hard-coded
user-specific absolute path string "/Users/dakshyadav/Rocket.Chat.ReactNative"
found under the "### 1. Clean Previous Installation (Recommended)" section with
a portable placeholder (e.g., "~/Rocket.Chat.ReactNative" or "<project-root>")
and update the same pattern wherever it appears (notably the occurrences
referenced around lines 134-139) so the guide uses non-user-specific paths.

Comment on lines +215 to +235
- **Server URL:** http://localhost:3000 (for local testing) or your server URL

## Success Criteria

✅ App builds and runs without errors
✅ Can login to Rocket.Chat server
✅ Pin icon appears **immediately** after pinning
✅ Star icon appears **immediately** after starring
✅ Icons disappear **immediately** after unpinning/unstarring
✅ Multiple quick actions work without issues
✅ Icons stay in sync with server state

## Additional Resources

- **Project Documentation:** https://developer.rocket.chat/docs/mobile-app
- **React Native Docs:** https://reactnative.dev/docs/getting-started
- **Contributing Guide:** CONTRIBUTING.md in the repository

---

**For questions or issues, visit:** https://github.com/RocketChat/Rocket.Chat.ReactNative/issues
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix MD034 bare URL linting by using markdown links.

markdownlint flags bare URLs here; wrap them in link syntax to keep docs lint-clean.

💡 Suggested update
-**Project Documentation:** https://developer.rocket.chat/docs/mobile-app
-**React Native Docs:** https://reactnative.dev/docs/getting-started
-**For questions or issues, visit:** https://github.com/RocketChat/Rocket.Chat.ReactNative/issues
+**Project Documentation:** [developer.rocket.chat/docs/mobile-app](https://developer.rocket.chat/docs/mobile-app)
+**React Native Docs:** [reactnative.dev/docs/getting-started](https://reactnative.dev/docs/getting-started)
+**For questions or issues, visit:** [github.com/RocketChat/Rocket.Chat.ReactNative/issues](https://github.com/RocketChat/Rocket.Chat.ReactNative/issues)
🧰 Tools
🪛 LanguageTool

[style] ~224-~224: Consider an alternative to avoid wordiness and to strengthen your wording.
Context: ...g/unstarring ✅ Multiple quick actions work without issues ✅ Icons stay in sync with server stat...

(WORKS_WITHOUT_PROBLEMS)

🪛 markdownlint-cli2 (0.18.1)

215-215: Bare URL used

(MD034, no-bare-urls)


229-229: Bare URL used

(MD034, no-bare-urls)


230-230: Bare URL used

(MD034, no-bare-urls)


235-235: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In `@RUN_PROJECT_GUIDE.md` around lines 215 - 235, Replace bare URLs in
RUN_PROJECT_GUIDE.md with markdown link syntax to satisfy MD034: change the
Server URL line and all resource links to formatted links (e.g. the server URL
text should be a link, and the three resource URLs
https://developer.rocket.chat/docs/mobile-app,
https://reactnative.dev/docs/getting-started, and
https://github.com/RocketChat/Rocket.Chat.ReactNative/issues should be rewritten
using [text](url) form; also convert the plain CONTRIBUTING.md mention into a
markdown link). Update the lines containing "Server URL:", "Project
Documentation:", "React Native Docs:", "Contributing Guide:", and the footer
"For questions or issues, visit:" to use link syntax.

Comment on lines +92 to +101
```
app/containers/MessageActions/index.tsx
├── handleStar() function
│ └── Added: Immediate DB update after API call
└── handlePin() function
└── Added: Immediate DB update after API call
```

**Total: 30 lines of focused code**
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks and use a heading instead of emphasis.

Markdownlint flags the block and the emphasized line. Consider text for the tree block and convert the emphasized line to a heading.

Suggested change
-```
+```text
 app/containers/MessageActions/index.tsx
 ├── handleStar() function
 │   └── Added: Immediate DB update after API call
 │
 └── handlePin() function
     └── Added: Immediate DB update after API call

-Total: 30 lines of focused code
+### Total: 30 lines of focused code

</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

92-92: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


101-101: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
In `@START_HERE.md` around lines 92 - 101, Update the fenced code block in
START_HERE.md to include a language identifier (use "text") for the tree snippet
and replace the emphasized line "**Total: 30 lines of focused code**" with a
heading (e.g., "### Total: 30 lines of focused code"); locate the tree snippet
and the emphasized summary near the block that shows
"app/containers/MessageActions/index.tsx" and modify the backticks to "```text"
and change the emphasized markdown to a heading to satisfy markdownlint.

Comment on lines +154 to +177
```
User: "Pin this message"
App: Sends API request to server
App: Waits for server response
⏳ WAIT... Server sends update
App: Updates UI with icon (DELAYED)
```

**After (New - Our Fix):**
```
User: "Pin this message"
App: Sends API request to server
App: IMMEDIATELY updates local database ✨
UI: Re-renders with icon INSTANTLY ⚡
Server: Sends update (keeps everything synced)
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Specify languages on the fenced code blocks.

Add text (or bash if you prefer) to satisfy MD040 and improve rendering.

Suggested change
-```
+```text
 User: "Pin this message"
   ↓
 App: Sends API request to server
   ↓
 App: Waits for server response
   ↓
 ⏳ WAIT... Server sends update
   ↓
 App: Updates UI with icon (DELAYED)

- +text
User: "Pin this message"

App: Sends API request to server

App: IMMEDIATELY updates local database ✨

UI: Re-renders with icon INSTANTLY ⚡

Server: Sends update (keeps everything synced)

</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.18.1)</summary>

154-154: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

---

167-167: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @START_HERE.md around lines 154 - 177, Add the missing language identifier to
both fenced code blocks in START_HERE.md (the "Before" flow diagram and the
"After (New - Our Fix)" flow diagram) by changing the opening backticks to
include a language tag (e.g., text or bash) so the blocks satisfy MD040
and render correctly; update the two blocks that show the user/app/server flows
(the one starting with 'User: "Pin this message"' in the Before section and the
corresponding block in the After section) to use ```text (recommended) at their
openings.


</details>

<!-- fingerprinting:phantom:triton:eagle -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +6 to +46
```
USER ACTION: Tap "Pin" on message
API CALL: togglePinMessage() succeeds
⏳ WAIT... (server hasn't sent update yet)
UI: Icon still not visible ❌
[User does something else or waits]
SERVER STREAM: 'stream-room-messages' arrives
DATABASE: Message updated
UI: Icon finally appears ✅ (after delay)
```

## Solution
Immediately update the database after the API call succeeds, triggering an instant UI update.

```
USER ACTION: Tap "Pin" on message
API CALL: togglePinMessage() succeeds
✨ DATABASE UPDATE (immediate):
- Set message.pinned = !pinned
- Set message._updatedAt = now()
DATABASE CHANGE TRIGGERS:
- experimentalSubscribe() fires
- MessageContainer re-renders
UI: Icon appears IMMEDIATELY ✅
SERVER STREAM: 'stream-room-messages' arrives (keeps things in sync)
DATABASE: Message syncs with server state
UI: Already showing correct state (no jump)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add language identifiers to fenced code blocks (MD040).

This avoids markdownlint failures and improves readability.

Also applies to: 27-47, 107-123, 146-182

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

6-6: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


27-27: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@VISUAL_SUMMARY.md` around lines 6 - 46, The fenced code blocks in
VISUAL_SUMMARY.md lack language identifiers causing markdownlint MD040 failures;
update each triple-backtick block (including the flows showing USER ACTION/API
CALL/WAIT and the code-like steps that reference togglePinMessage(),
message.pinned, message._updatedAt, experimentalSubscribe(), MessageContainer,
and 'stream-room-messages') to include an appropriate language tag (e.g.,
```text or ```flow or ```mermaid where suitable) so linting passes and
readability improves across the blocks mentioned (lines referenced in the
review: around the user flow and the Solution sections).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants