Menu β–Ύ β–΄

#201 Notify with emoji and the group sender's face

closed
nobody
None
2026-07-26
2026-07-25
Anonymous
No

Originally created by: kristofferR

What's wrong

Two bugs in the row-driven notification fallback, both visible in a single group banner:

  1. Emoji vanished. Messenger renders emoji as sprite <img> elements inside the preview span, so scraping the row with textContent dropped them. "Kim: 😒" notified as "Kim:", and an emoji-only message produced an empty body β€” which the fallback reads as an unhydrated row, so it never notified at all.
  2. Every group sender wore the same face. A group row only carries the thread picture, and a photo-less group's composite avatar is two member images with empty alt β€” no per-sender identity anywhere in the row. The first image (alphabetically first member) was used for every sender.

What changed

Emoji β€” conversationNodeText() (new, in lib/conversation-row.ts) walks a row node and restores the glyph from the sprite's alt, from aria-label for background-image emoji, and from a bare-emoji alt when features/emoji-images.ts has deferred the src. It skips the System emoji feature's injected glyph spans so nothing doubles, and emojiGlyph() now keeps keycap sequences (1️⃣, #️⃣) that its numeric-label guard used to reject. The same text now feeds the unread-weight check, and the row's own image pick skips emoji sprites.

Group sender avatars β€” Messenger does pair a name with a face wherever it renders people: each message row carries an h3 short name plus an avatar whose alt is the full name, and the conversation-info chat-member list is shaped the same way. SenderAvatarStore (new lib/sender-avatars.ts) harvests those pairings as they render β€” throttled to once per 5s inside the existing scan β€” into a bounded (120-entry, LRU) cache persisted so the auto-refresh reload doesn't empty it. A group fallback notification parses the "Kim:" prefix and looks it up: exact match, or a unique full-name match; an ambiguous "Kim" and an expired avatar URL both fall back to the row's own image, so a wrong face is never preferred over the group photo.

Coverage note: a group's senders resolve once that thread (or its member list) has rendered at least once β€” before that, the thread picture is used, i.e. today's behaviour.

Dev tooling β€” two sanitized probes in the dev-only MCP bridge, documented in AGENTS.md: __carrier_mcp_notification_row_probe__ (row/message-row shape) and __carrier_mcp_sender_avatar_probe__ (what the harvest would take, what it cached, and how each visible group preview resolves). Both report classifications and counts only β€” never message text, contact names, or image URLs.

Verification

Unit tests for the new logic (conversationNodeText, SenderAvatarStore, groupPreviewSender, keycap glyphs), plus live checks against real Messenger DOM in a --features mcp debug build:

  • 4 of 14 rendered row previews carried emoji through the injected extraction, where before they carried none.
  • After opening a group thread, 8 nameβ†’face pairs were cached and that group's row resolved exact β€” its next notification shows the sender rather than the group photo.

cargo fmt / clippy -D warnings / cargo test --lib, and Biome + tsc + bun test with the inject bundles regenerated.

Ref [#135]

Summary by CodeRabbit

  • New Features
  • Group notification previews can now use the correct sender avatar when available via a persisted sender-avatar cache.
  • Added privacy-safe diagnostic probes for notification rows and sender-avatar matching (classification/counts only).
  • Bug Fixes
  • Improved conversation-row text extraction to preserve emojis (including keycaps) and avoid duplicate system emoji glyphs.
  • More reliable unread detection and preview rendering for group threads, including smarter sender/preview icon selection.
  • Tests
  • Expanded emoji/text reconstruction, sender-avatar cache, and group-preview sender parsing coverage.
  • Documentation
  • Updated dev webview probe documentation for notification-related privacy-safe checks.

Related

Tickets: #135

Discussion

1 2 3 > >> (Page 1 of 3)
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: coderabbitai[bot]

    Review Change Stack

    [!WARNING]

    Review limit reached

    @kristofferR, you've reached your PR review limit, so we couldn't start this review.

    Next review available in: 48 minutes

    Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
    You're only billed for reviews past your plan's rate limits ($0.25/file).


    How can I continue?

    After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

    To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.


    How do review limits work?

    CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

    For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

    Please refer docs for additional details.


    Review details


    βš™οΈ Run configuration

    Configuration used: Path: .coderabbit.yaml

    Review profile: ASSERTIVE

    Plan: Pro Plus

    Run ID: 7255519a-e7de-485f-b78c-bbf8b8bed6f6


    πŸ“₯ Commits

    Reviewing files that changed from the base of the PR and between [a69cb5] and aaf7a10f291a9e16730394975918623ac5c6df7b.


    πŸ“’ Files selected for processing (2)

    • inject/src/messenger/features/notifications.ts
    • src-tauri/inject/mcp-bridge.js
    πŸ“ Walkthrough ## Walkthrough Messenger notification handling now reconstructs emoji-aware row text, harvests and persists sender avatars for group fallback icons, and exposes privacy-safe notification diagnostics through MCP probes. Tests cover parsing, keycaps, sender-avatar persistence, and group sender extraction. ### Changes **Notification inspection and fallback flow** |Layer / File(s)|Summary| |---|---| |**Emoji-aware conversation text parsing**
    `inject/src/messenger/lib/emoji.ts`, `inject/src/messenger/lib/conversation-row.ts`, `inject/src/messenger/features/system-emoji.ts`, `src-tauri/inject/messenger.js`, `inject/src/messenger/lib/*test.ts`|Shared emoji constants and keycap handling support DOM text reconstruction while excluding Carrier system-emoji glyphs; related tests cover the new parsing cases.| |**Thread-scoped sender-avatar storage**
    `inject/src/messenger/lib/sender-avatars.ts`, `inject/src/messenger/lib/sender-avatars.test.ts`|A bounded persistent store tracks thread-specific avatar mappings, ambiguity, group threads, photo identities, eviction, and resolution statistics.| |**Sender-avatar harvesting and fallback icons**
    `inject/src/messenger/features/notifications.ts`, `inject/src/messenger/lib/notification-fallback.ts`, `src-tauri/inject/messenger.js`, `inject/src/types.d.ts`, `inject/src/messenger/lib/*test.ts`|Throttled UI harvesting, group sender parsing, richer row classification, persisted notification-version updates, and sender-specific fallback icons were added and tested.| |**Privacy-safe notification probes**
    `src-tauri/inject/mcp-bridge.js`, `AGENTS.md`|MCP handlers inspect notification rows and sender-avatar resolution while returning sanitized classifications, counts, and masked metadata.| **Estimated code review effort:** 4 (Complex) | ~45 minutes ### Sequence Diagram(s) :::mermaid sequenceDiagram participant MessengerDOM participant scanUnreadConversations participant SenderAvatarStore participant scheduleFallback participant NativeNotification MessengerDOM->>scanUnreadConversations: visible rows and avatar candidates scanUnreadConversations->>SenderAvatarStore: remember sender/avatar mappings scanUnreadConversations->>scheduleFallback: group conversation preview scheduleFallback->>SenderAvatarStore: lookup sender avatar scheduleFallback->>NativeNotification: selected notification icon **Possibly related PRs** - [[kristofferR/Carrier#99](https://github.com/kristofferR/Carrier/issues/99)](https://github.com/kristofferR/Carrier/pull/99): Modifies the persisted notification fallback and unread-scanning flow. - [[kristofferR/Carrier#137](https://github.com/kristofferR/Carrier/issues/137)](https://github.com/kristofferR/Carrier/pull/137): Touches conversation-row parsing and Messenger notification routing paths. - [[kristofferR/Carrier#164](https://github.com/kristofferR/Carrier/issues/164)](https://github.com/kristofferR/Carrier/pull/164): Touches notification reconciliation and persisted notification matching paths.
    πŸš₯ Pre-merge checks | βœ… 4 | ❌ 1 ### ❌ Failed checks (1 warning) | Check name | Status | Explanation | Resolution | | :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- | | Docstring Coverage | ⚠️ Warning | Docstring coverage is 47.17% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
    βœ… Passed checks (4 passed) | Check name | Status | Explanation | | :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------------ | | Description Check | βœ… Passed | Check skipped - CodeRabbit’s high-level summary is enabled. | | Title check | βœ… Passed | The title matches the main changes: restoring emoji handling and using the group sender’s avatar for notifications. | | Linked Issues check | βœ… Passed | Check skipped because no linked issues were found for this pull request. | | Out of Scope Changes check | βœ… Passed | Check skipped because no linked issues were found for this pull request. |
    ✨ Finishing Touches
    πŸ§ͺ Generate unit tests (beta) - [ ] Create PR with unit tests - [ ] Commit unit tests in branch `fix/notification-emoji-and-group-sender-avatars`

    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 - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

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

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-25

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @codex review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: kristofferR

    @coderabbitai review

     
  • Anonymous

    Anonymous - 2026-07-26

    Originally posted by: coderabbitai[bot]

    βœ… Action performed Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
     
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.