feat(frontend/backend): add emoji reaction support for email messages #1498
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Implementation Details
Frontend
Backend
text/vnd.google.email-reaction+json
MIME partsTechnical 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:
text/plain
part containing fallback text for clients without reaction supporttext/vnd.google.email-reaction+json
part containing the structured reaction datatext/html
part with HTML-formatted fallback contentSpecial 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:
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:
Screenshots
Basic Interface with Add Reaction Button
An email message with the "Add reaction" button visible at the bottom.
Emoji Picker Interface
The emoji picker overlay provides a searchable interface with categories and recent emojis.
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
Hovering over a reaction displays a tooltip showing the names/emails of users who reacted with that emoji.
Emoji Picker in Dark Mode
The emoji picker automatically adapts to dark mode when a dark theme is active.
Localization Support
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 UIlib/js_libs.php
: Added emoji-mart to JS_LIBS definition for proper loadingCore System Extensions
modules/core/handler_modules.php
: Modified Content Security Policy to allow connections tocdn.jsdelivr.net
for emoji-mart resourcesmodules/core/hm-mailbox.php
: Addedget_message_parts_content()
andget_message_structures()
methods to support batch operationsIMAP Protocol Extensions
modules/imap/handler_modules.php
: ImplementedHm_Handler_imap_message_reactions
to search for reaction messages by:text/vnd.google.email-reaction+json
modules/imap/hm-imap.php
: Added optimized batch operations:get_message_structures()
: Fetches message structures in a single requestget_message_parts_content()
: Retrieves multiple message parts in a single requestdecode_message_part_content()
: Centralizes decoding logic for both single and batch operationsmodules/imap/setup.php
: Addedajax_imap_message_reactions
endpoint and registeredreactions
outputSMTP Integration
modules/smtp/hm-mime-message.php
: CreatedHm_Reaction_MIME_Msg
class for formatting reaction emailsmodules/smtp/modules.php
: ImplementedHm_Handler_send_message_reaction
to:modules/smtp/setup.php
: Addedajax_send_message_reaction
endpoint and registered reaction parametersFrontend Components
modules/imap/site.js
: Implemented UI handling for message reactions:modules/imap/site.css
: Added styling for message reaction componentsmodules/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 UImodules/themes/modules.php
: Added logic to determine which themes are dark and pass theme mode informationmodules/themes/setup.php
: Registered theme mode module to all pagesmodules/core/output_modules.php
: AddedHm_Output_theme_mode
to expose theme mode (dark/light) to front-end for emoji-martDiscussion 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