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

Open
opened 2026-02-25 21:38:39 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/cypht-org/cypht/pull/1498
Author: @Revisto
Created: 5/1/2025
Status: 🔄 Open

Base: masterHead: feature/emoji-reactions


📝 Commits (5)

  • d461392 feat(frontend/backend): add emoji reaction support for email messages
  • 73e9720 fix(imap): remove unnecessary error logging in Hm_IMAP class
  • 6a1795f feat(smtp): implement send_smtp_message function and refactor email sending logic to avoid repeated code
  • 8f86948 Merge remote-tracking branch 'origin/master' into feature/emoji-reactions
  • 0b7149c Merge remote-tracking branch 'origin/master' into feature/emoji-reactions

📊 Changes

18 files changed (+1189 additions, -45 deletions)

View changed files

📝 lib/js_libs.php (+1 -0)
📝 modules/core/handler_modules.php (+1 -1)
📝 modules/core/hm-mailbox.php (+22 -0)
📝 modules/core/output_modules.php (+16 -0)
📝 modules/imap/handler_modules.php (+273 -0)
📝 modules/imap/hm-imap.php (+181 -11)
📝 modules/imap/setup.php (+23 -10)
📝 modules/imap/site.css (+32 -0)
📝 modules/imap/site.js (+162 -0)
📝 modules/smtp/functions.php (+27 -0)
📝 modules/smtp/hm-mime-message.php (+102 -0)
📝 modules/smtp/modules.php (+250 -21)
📝 modules/smtp/setup.php (+11 -1)
📝 modules/smtp/site.js (+55 -0)
modules/themes/assets/reactions-dark.css (+15 -0)
📝 modules/themes/modules.php (+15 -1)
📝 modules/themes/setup.php (+1 -0)
third_party/emoji-mart/browser.js (+2 -0)

📄 Description

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

  • Implements feature request #1366

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cypht-org/cypht/pull/1498 **Author:** [@Revisto](https://github.com/Revisto) **Created:** 5/1/2025 **Status:** 🔄 Open **Base:** `master` ← **Head:** `feature/emoji-reactions` --- ### 📝 Commits (5) - [`d461392`](https://github.com/cypht-org/cypht/commit/d4613921fedf39277913cc9b4f7343d7cdf5fe79) feat(frontend/backend): add emoji reaction support for email messages - [`73e9720`](https://github.com/cypht-org/cypht/commit/73e97203fd5281047f22bd38b5f0d0122336d57e) fix(imap): remove unnecessary error logging in Hm_IMAP class - [`6a1795f`](https://github.com/cypht-org/cypht/commit/6a1795fbc7711ccef4cd0dbdcb3293fabe92a825) feat(smtp): implement send_smtp_message function and refactor email sending logic to avoid repeated code - [`8f86948`](https://github.com/cypht-org/cypht/commit/8f86948ef559b9fa74980d041441390b4028bd72) Merge remote-tracking branch 'origin/master' into feature/emoji-reactions - [`0b7149c`](https://github.com/cypht-org/cypht/commit/0b7149cfcfd82116bcdad9ffe8f056e3f51cad4d) Merge remote-tracking branch 'origin/master' into feature/emoji-reactions ### 📊 Changes **18 files changed** (+1189 additions, -45 deletions) <details> <summary>View changed files</summary> 📝 `lib/js_libs.php` (+1 -0) 📝 `modules/core/handler_modules.php` (+1 -1) 📝 `modules/core/hm-mailbox.php` (+22 -0) 📝 `modules/core/output_modules.php` (+16 -0) 📝 `modules/imap/handler_modules.php` (+273 -0) 📝 `modules/imap/hm-imap.php` (+181 -11) 📝 `modules/imap/setup.php` (+23 -10) 📝 `modules/imap/site.css` (+32 -0) 📝 `modules/imap/site.js` (+162 -0) 📝 `modules/smtp/functions.php` (+27 -0) 📝 `modules/smtp/hm-mime-message.php` (+102 -0) 📝 `modules/smtp/modules.php` (+250 -21) 📝 `modules/smtp/setup.php` (+11 -1) 📝 `modules/smtp/site.js` (+55 -0) ➕ `modules/themes/assets/reactions-dark.css` (+15 -0) 📝 `modules/themes/modules.php` (+15 -1) 📝 `modules/themes/setup.php` (+1 -0) ➕ `third_party/emoji-mart/browser.js` (+2 -0) </details> ### 📄 Description 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](https://github.com/missive/emoji-mart?tab=readme-ov-file#options--props)) ## 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](https://developers.google.com/workspace/gmail/reactions/format), 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: ```json { "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](https://github.com/user-attachments/assets/a385e395-feaa-4c64-8065-6ae05fad6dc9) *An email message with the "Add reaction" button visible at the bottom.* ### Emoji Picker Interface ![Emoji picker opened](https://github.com/user-attachments/assets/17aa0030-ec9e-4445-be97-e9852a2c303b) *The emoji picker overlay provides a searchable interface with categories and recent emojis.* ### Multiple Reactions in Dark Mode ![Multiple reactions in dark mode](https://github.com/user-attachments/assets/af461f86-ce38-48c9-851d-cb52edec2a28) *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](https://github.com/user-attachments/assets/e3f62108-649e-4d44-8cbc-b30816c352f6) *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](https://github.com/user-attachments/assets/47e2d145-4b76-4f3f-a820-c37506cf575d) *The emoji picker automatically adapts to dark mode when a dark theme is active.* ### Localization Support ![Light mode with French language interface](https://github.com/user-attachments/assets/94a3df3e-af61-4d8d-b2a0-6d76ed7e7db4) *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 - Implements feature request #1366 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/cypht#1561
No description provided.