Skip to content

feat(frontend/backend): add emoji reaction support for email messages #1498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Revisto
Copy link
Contributor

@Revisto Revisto commented May 1, 2025

This PR adds emoji reactions to email messages, similar to how modern messaging apps work, but for emails. Users can now react with emojis to emails they receive, and see reactions from others.

Features

  • React to emails with emojis: Users can add emoji reactions to received emails
  • View others' reactions: Shows who reacted to messages with tooltips
  • Reaction management:
    • Prevents duplicate reactions
    • Limits the number of reactions per user (max 20)
  • Full integration: Works with both IMAP and SMTP to send and view reactions
  • Optimized performance: Uses batch operations and local caching
  • Theme support: Compatible with both light and dark themes
  • Localization: Uses the user's locale for emoji display and categories (supported languages)

Implementation Details

Frontend

  • Added emoji picker using the emoji-mart library
  • Created UI components for displaying reactions below the message content
  • Implemented local storage caching
  • Added dark mode support for reactions

Backend

  • Extended IMAP functionality to handle reaction messages
  • Added support for finding and parsing text/vnd.google.email-reaction+json MIME parts
  • Implemented batch operations for retrieving multiple message parts efficiently
  • Created handlers for sending reactions (MIME structure for sending reactions)

Technical Approach

The implementation follows the Gmail Email Reactions Format specification, which provides a standardized way to handle emoji reactions to email messages. These reactions are implemented as specialized MIME-formatted emails with the following key characteristics:

Message Format

  • MIME Structure: Each reaction is a multipart MIME message with three content parts:

    1. text/plain part containing fallback text for clients without reaction support
    2. text/vnd.google.email-reaction+json part containing the structured reaction data
    3. text/html part with HTML-formatted fallback content
  • Special Content Type: The reaction data is stored in a dedicated MIME part with content type text/vnd.google.email-reaction+json

  • JSON Format: The reaction part contains JSON with two required fields:

    {
      "version": 1,
      "emoji": "👍"
    }
  • Message References: Each reaction includes an In-Reply-To header referencing the Message-ID of the original email.

Limitations

The implementation enforces several recommended limits:

  • Per-user limits: Users are limited to 20 reactions per message (as recommended by Gmail)
  • Duplicate prevention: Users cannot react with the same emoji multiple times

Screenshots

Basic Interface with Add Reaction Button

Email with no reaction yet and add reaction button
An email message with the "Add reaction" button visible at the bottom.

Emoji Picker Interface

Emoji picker opened
The emoji picker overlay provides a searchable interface with categories and recent emojis.

Multiple Reactions in Dark Mode

Multiple reactions in dark mode
Dark mode view showing multiple emoji reactions applied to a message, with counts indicating how many users reacted with each emoji.

Reaction Tooltips for User Information

Tooltip showing who reacted with emoji
Hovering over a reaction displays a tooltip showing the names/emails of users who reacted with that emoji.

Emoji Picker in Dark Mode

Emoji picker in dark mode
The emoji picker automatically adapts to dark mode when a dark theme is active.

Localization Support

Light mode with French language interface
Demonstration of localization support: the emoji picker displays in French when the user's locale is set to French.

File Changes

Third-Party Integration

  • third_party/emoji-mart/browser.js: Added emoji-mart browser library for emoji selection UI
  • lib/js_libs.php: Added emoji-mart to JS_LIBS definition for proper loading

Core System Extensions

  • modules/core/handler_modules.php: Modified Content Security Policy to allow connections to cdn.jsdelivr.net for emoji-mart resources
  • modules/core/hm-mailbox.php: Added get_message_parts_content() and get_message_structures() methods to support batch operations

IMAP Protocol Extensions

  • modules/imap/handler_modules.php: Implemented Hm_Handler_imap_message_reactions to search for reaction messages by:
    • Finding emails with In-Reply-To headers matching the original message ID
    • Fetching headers and filtering for unique message IDs
    • Processing the UIDs folder by folder to retrieve body structures
    • Identifying parts with MIME type text/vnd.google.email-reaction+json
    • Extracting reaction data and grouping by emoji
  • modules/imap/hm-imap.php: Added optimized batch operations:
    • get_message_structures(): Fetches message structures in a single request
    • get_message_parts_content(): Retrieves multiple message parts in a single request
    • decode_message_part_content(): Centralizes decoding logic for both single and batch operations
  • modules/imap/setup.php: Added ajax_imap_message_reactions endpoint and registered reactions output

SMTP Integration

  • modules/smtp/hm-mime-message.php: Created Hm_Reaction_MIME_Msg class for formatting reaction emails
  • modules/smtp/modules.php: Implemented Hm_Handler_send_message_reaction to:
    • Find the appropriate SMTP server based on user profile settings
    • Fall back to matching IMAP/SMTP servers if no profile exists
    • Validate sender addresses and recipient information
    • Create and send properly formatted reaction messages
  • modules/smtp/setup.php: Added ajax_send_message_reaction endpoint and registered reaction parameters

Frontend Components

  • modules/imap/site.js: Implemented UI handling for message reactions:
    • Local storage caching for immediate display
    • Emoji picker initialization with theme and locale support
    • Reaction rendering with counts and user tooltips
    • AJAX interfaces for fetching and refreshing reaction data
  • modules/imap/site.css: Added styling for message reaction components
  • modules/smtp/site.js: Implemented reaction sending with duplicate prevention and limits (max 20)

Theming Support

  • modules/themes/assets/reactions-dark.css: Added dark theme styling for reaction UI
  • modules/themes/modules.php: Added logic to determine which themes are dark and pass theme mode information
  • modules/themes/setup.php: Registered theme mode module to all pages
  • modules/core/output_modules.php: Added Hm_Output_theme_mode to expose theme mode (dark/light) to front-end for emoji-mart

Discussion Points

  • Reaction Visibility: Should reaction messages be filtered out as separate emails? In the April 2025 Cypht meeting, we decided to show them as both visual reactions and separate email messages to ensure transparency. Are there better approaches we should consider?

  • Search Performance: Currently, finding reactions requires searching through all folders, which can be time-consuming for accounts with many folders. Does anyone have ideas for optimizing this?

  • Restriction to only Gmail? As discussed in the 2025 April Cypht meeting, we decided anyone can react to emails from everyone, since the reactions are shown as separate understandable emails so if the user's client doesn't support reactions, they still can get the meaning.

Issues

- Users can react to messages with emojis
- Reactions are stored and displayed per message
- Prevents duplicate reactions and enforces per-user limits
- Includes backend handlers, IMAP/SNTP integration, and frontend UI/UX
@marclaporte marclaporte requested a review from kroky May 1, 2025 14:23
@JadedBlueEyes
Copy link

Is this compatible with outlook's emoji reactions? Not sure if it's possible to be compatible with both outlook and Gmail at the same time.

@marclaporte marclaporte mentioned this pull request May 1, 2025
@Revisto
Copy link
Contributor Author

Revisto commented May 1, 2025

Hi @JadedBlueEyes, unfortunately, not (at least for now), Outlook365 supports reactions, but it’s only available to users with a work or school account and a qualifying Microsoft 365 subscription. Not all users see this option, including myself, so I implemented it the way Gmail does.

@JadedBlueEyes
Copy link

Hi @Revisto ,

That's perfectly understandable, given you can't test it.

Keep up the good work! ❤️

@m4tinbeigi-official
Copy link

🤌🏼🔥

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.

3 participants