Skip to content

Conversation

@igennova
Copy link
Contributor

@igennova igennova commented Apr 8, 2025

Fixes #3681

Summary by CodeRabbit

  • New Features
    • Introduced emoji reactions for chat messages, allowing users to add or remove reactions with ease.
    • Enhanced the chat interface with a dynamic emoji picker and real-time updates, streamlining interaction across the conversation.
    • Implemented persistent tracking of reactions to enrich user experience during message exchanges.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 8, 2025

Walkthrough

This pull request implements emoji reaction functionality for chat messages. Server-side updates include new methods in the WebSocket consumer to add and broadcast reactions, along with model and migration changes to support storing reactions in a JSONField. On the client side, JavaScript is enhanced with functions to handle user interactions with emoji pickers, send reaction events via WebSocket, and update the UI dynamically.

Changes

Files Change Summary
website/consumers.py Added methods add_reaction and reaction_update; updated receive method to handle the new add_reaction event type.
website/migrations/0237_message_reactions.py, website/models.py Introduced a new JSONField reactions (with default empty dictionary) to the message model, along with a corresponding migration file.
website/templates/join_room.html Integrated emoji reaction features by adding functions (addReaction, updateReactions, showEmojiPicker, closeEmojiPicker, closeEmojiPickerOnClickOutside) and a new variable for UI control.

Assessment against linked issues

Objective Addressed Explanation
Add emoji reactions to chat messages (#3681)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

🧹 Nitpick comments (3)
website/consumers.py (1)

578-591: Consider including user information in reaction broadcasts.

The reaction_update method effectively broadcasts reaction changes to all connected clients. However, for a richer UI, you might want to include information about which user added/removed each reaction, enabling customized displays for the current user's reactions.

async def reaction_update(self, event):
    """Handles broadcasting reaction updates to all users in the room."""
    if not self.connected:
        return

    try:
        await self.send(
            text_data=json.dumps(
-               {"type": "reaction_update", "message_id": event["message_id"], "reactions": event["reactions"]}
+               {
+                   "type": "reaction_update", 
+                   "message_id": event["message_id"], 
+                   "reactions": event["reactions"],
+                   "current_user": self.scope["user"].username if self.scope["user"].is_authenticated else "Anonymous"
+               }
            )
        )
    except Exception as error:
        logger.error(f"Error sending reaction update: {str(error)}")
website/templates/join_room.html (2)

60-73: Good emoji picker implementation, but consider adding more emojis.

The emoji picker modal has a clean grid layout. Consider expanding beyond the current 8 emojis to give users more options, possibly with categories or a search feature for larger sets.


156-173: Effective reaction rendering with click functionality.

The updateReactions function efficiently rebuilds the reaction display each time. Nice touch making each reaction clickable to toggle it on/off. Consider adding a visual indicator for reactions the current user has already added.

function updateReactions(messageId, reactions) {
    const messageElement = document.querySelector(`[data-message-id="${messageId}"]`);
    if (!messageElement) return;

    const reactionsContainer = messageElement.querySelector('.reactions-container');
    reactionsContainer.innerHTML = '';

    Object.entries(reactions).forEach(([emoji, users]) => {
+       const username = '{{ request.user.username }}';
+       const hasReacted = users.includes(username);
        const reactionButton = document.createElement('button');
-       reactionButton.className = 'inline-flex items-center px-2 py-1 rounded-full bg-gray-100 hover:bg-gray-200 transition-colors duration-200';
+       reactionButton.className = `inline-flex items-center px-2 py-1 rounded-full ${hasReacted ? 'bg-blue-100' : 'bg-gray-100'} hover:bg-gray-200 transition-colors duration-200`;
        reactionButton.innerHTML = `
            <span class="mr-1">${emoji}</span>
            <span class="text-xs text-gray-600">${users.length}</span>
        `;
        reactionButton.onclick = () => addReaction(messageId, emoji);
        reactionsContainer.appendChild(reactionButton);
    });
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec1013f and d2e4f28.

📒 Files selected for processing (4)
  • website/consumers.py (3 hunks)
  • website/migrations/0237_message_reactions.py (1 hunks)
  • website/models.py (1 hunks)
  • website/templates/join_room.html (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
website/migrations/0237_message_reactions.py (1)

1-18: Clean migration for adding reactions field.

This is a well-structured migration that adds a JSONField to store emoji reactions. Using default=dict ensures new messages will have an empty reactions dictionary by default. The migration properly depends on the previous migration file.

website/models.py (1)

2412-2412: Good implementation of reactions field.

The JSONField is appropriately configured with a default empty dictionary and clear help text. This will effectively store emoji reactions and their counts for each message.

website/consumers.py (2)

396-420: Well-structured reaction handling logic.

The add_reaction method follows a good pattern for toggling reactions - adding a user to the emoji list if they haven't reacted or removing them if they have. The method handles error cases appropriately with null returns for non-existent messages or exceptions.


436-461: Proper validation and WebSocket message handling.

Good validation of required parameters (message_id and emoji) before processing the reaction. The error responses are consistent with other WebSocket error patterns in the file. Broadcasting the reaction update to all clients follows the established pattern.

website/templates/join_room.html (5)

28-42: Clean implementation of the reaction UI elements.

The reactions container is well-structured, and the initialization script for existing reactions follows best practices by waiting for DOM content to be loaded. The emoji button is appropriately styled with hover effects for better user experience.


119-155: Well-positioned emoji picker with proper event cleanup.

The positioning of the emoji picker relative to the clicked button works well. Good implementation of click-outside listener cleanup to prevent memory leaks. The addReaction function correctly sends the message to the WebSocket and handles socket state.


217-230: Good integration of reaction buttons in newly appended messages.

The reaction button event listeners are properly set up for dynamically added messages, maintaining consistent behavior with existing messages.


246-248: Appropriate handling of reaction updates in the WebSocket message handler.

The WebSocket message handler properly processes reaction updates and passes them to the updateReactions function.


360-379: Good setup of event handlers for emoji options and reaction buttons.

Event delegation is used appropriately to attach handlers to emoji options and reaction buttons. The code stops event propagation to prevent unwanted clicks from bubbling up.

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 8, 2025
@igennova
Copy link
Contributor Author

igennova commented Apr 8, 2025

@coderabbitai review this full code and tell me if there is any error
?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 8, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the content of the modified files to conduct a proper review
echo "=== website/consumers.py ==="
cat website/consumers.py

echo -e "\n\n=== website/migrations/0237_message_reactions.py ==="
cat website/migrations/0237_message_reactions.py

echo -e "\n\n=== website/models.py ==="
cat website/models.py

echo -e "\n\n=== website/templates/join_room.html ==="
cat website/templates/join_room.html

Length of output: 94904


🏁 Script executed:

#!/bin/bash
# Let's check the structure of the HTML file to better understand the emoji reaction implementation
grep -n "function addReaction" website/templates/join_room.html -A 20
echo -e "\n=== Checking for emoji picker structure ==="
grep -n "emoji-picker" website/templates/join_room.html -A 10
echo -e "\n=== Checking for reaction rendering code ==="
grep -n "updateReactions" website/templates/join_room.html -A 15
echo -e "\n=== Checking message socket handling ==="
grep -n "handleWebSocketMessage" website/templates/join_room.html -A 20

Length of output: 7423


@igennova After reviewing the emoji reaction feature implementation, I've identified a few potential issues:

Backend Issues:

  1. Anonymous User Handling: In add_reaction method, it uses self.scope["user"].username without properly checking if the user is anonymous. If an anonymous user tries to add a reaction, this could cause errors.

  2. Error Handling: When add_reaction returns None (message not found or exception), the error message sent to the client is generic ("Failed to add reaction") without details about what went wrong.

  3. Race Conditions: Multiple users reacting simultaneously could cause race conditions since there's no transaction or locking mechanism when modifying the reactions dictionary.

Frontend Issues:

  1. Interface Feedback: No visual feedback when a reaction fails to be added.

  2. Mobile Responsiveness: The emoji picker positioning is fixed and might not work well on mobile devices:

    function showEmojiPicker(button, messageId) {
        // Positioning might not adapt well to mobile screens
    }
  3. Empty State Handling: When all users remove their reactions for an emoji, the code properly removes the empty list, but if all emojis are removed, the container remains empty without any default state.

Security Considerations:

  1. Input Validation: There's no validation or sanitization of emoji input on the frontend, which could potentially allow for unexpected characters.

Recommendations:

  1. Add proper anonymous user handling in the backend
  2. Improve error messages with specific details
  3. Add visual feedback for successful/failed reactions
  4. Consider adding responsive positioning for the emoji picker
  5. Implement basic emoji validation

The feature works functionally, but these improvements would make it more robust and user-friendly.

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: 1

🧹 Nitpick comments (7)
website/templates/join_room.html (7)

28-42: Inline Reaction Script – Consider Centralizing Update Calls
The markup embeds a <script> tag inside each message block to call updateReactions on DOMContentLoaded when reactions exist. This can lead to duplicated code and potential performance overhead when many messages are rendered. Consider centralizing the update logic (e.g. by iterating over all message elements after the DOM loads) and moving the script out of the loop.


60-81: Emoji Picker Modal – Accessibility & Maintainability
The emoji picker modal is well integrated with appropriate classes and transition classes. However, consider adding ARIA attributes (like role="dialog" and aria-label) to improve accessibility. Additionally, if future designs require re-theming, moving these styles to an external CSS file might improve maintainability.


179-191: Smooth Dismissal in closeEmojiPicker Function
Using a CSS class change combined with a timeout creates a smooth exit animation for the emoji picker. As an optional improvement, you might use the CSS transitionend event instead of a fixed 200 ms timeout to better synchronize with the actual end of the transition.


212-229: Dynamic Reaction Rendering in updateReactions Function – Accessibility Suggestions
The function rebuilds the reaction buttons dynamically and reflects the updated count. For improved accessibility and semantics, consider:

  • Adding appropriate aria-label attributes to the reaction buttons (e.g. "React with [emoji], [count] reactions").
  • Setting the button type explicitly (e.g. type="button") to avoid accidental form submissions in certain contexts.

245-251: New Message Rendering in appendMessage – Timestamp Handling
Within dynamically appended messages, the timestamp is hard-coded to "just now". If the backend provides a more precise timestamp, consider using it to help users better contextualize new messages. Otherwise, document that this is an intentional design decision for new messages.


416-424: Emoji Option Click Handler – User Feedback Opportunity
The event handler for emoji options uses the globally stored activeEmojiButton. While it functions correctly when set, consider adding a fallback (or visual indication) if no active reaction button is detected. This would improve the user experience in edge cases.


453-467: Inline Style Injection for Emoji Picker Transitions – Consider External Stylesheet
The code dynamically injects a <style> block for emoji picker transitions. While this approach works in a single-page context, moving such styles to an external stylesheet could enhance maintainability and leverage browser caching.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2e4f28 and d073846.

📒 Files selected for processing (1)
  • website/templates/join_room.html (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
  • GitHub Check: Analyze (python)
🔇 Additional comments (3)
website/templates/join_room.html (3)

127-177: Dynamic Emoji Picker Positioning in showEmojiPicker Function
The logic for dynamically positioning the emoji picker based on available screen space is clear and thorough (including handling mobile centering). One minor consideration is that fetching the element (document.getElementById('emoji-picker')) on every call might be cached if used frequently, though it isn’t a critical issue. The addition of an outside click listener is appropriately placed.


193-197: Robust Outside Click Handling in closeEmojiPickerOnClickOutside
The function correctly checks whether the clicked target lies outside both the emoji picker and the reaction button, ensuring a proper close action. This implementation is concise and effective.


426-435: Existing Reaction Buttons Initialization
The block that attaches click listeners to existing .add-reaction-btn elements ensures that the emoji picker is shown for messages present at page load. This redundancy with the dynamic event attachment in appendMessage is acceptable to cover both initial and new messages.

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: 0

🧹 Nitpick comments (9)
website/templates/join_room.html (9)

28-42: Review of Inline Reaction Update in Message Loop
The markup for displaying reactions is clear and correctly integrated into each message. However, embedding a script tag that adds a DOMContentLoaded listener for every message with reactions may lead to redundant event attachments if there are many messages. Consider initializing these updates once after the entire DOM is loaded or refactoring to update the reactions on demand.


60-72: Emoji Picker Modal Markup Accessibility
The emoji picker modal markup is well organized using a grid layout for emoji options. To improve accessibility, consider adding ARIA attributes (e.g. aria-label, role="dialog") so that assistive technologies can better interpret the modal content.


127-177: Dynamic Emoji Picker Positioning
The showEmojiPicker function effectively calculates the position of the emoji picker relative to the trigger button and adjusts for mobile screens. A couple of suggestions:

  • Instead of a hard-coded picker height (const pickerHeight = 200;), consider using picker.offsetHeight for dynamic measurement.
  • Verify that attaching the click listener for closing the picker (via closeEmojiPickerOnClickOutside) on every invocation does not lead to unintended multiple registrations over time.

200-223: User Notification System
The showNotification function effectively provides feedback with animated notifications. To further enhance accessibility, consider adding an ARIA role (e.g. role="alert") to the notification elements.


225-268: Asynchronous Reaction Submission and Reconnection Logic
The addReaction function robustly checks for a valid WebSocket connection and attempts reconnection if needed before sending the reaction payload. While this is a solid approach, be mindful of potential race conditions if users trigger multiple reactions in quick succession. Ensuring that concurrent reconnection attempts are handled gracefully would improve robustness.


398-440: WebSocket Connection Management and Error Handling
The connectWebSocket function correctly establishes a connection, manages reconnection attempts, and updates the UI based on connection status. It might be beneficial to log more detailed error information in the onerror handler to facilitate debugging if connection issues persist.


449-459: Deletion Request Functionality
The deleteMessage function sends a deletion request via WebSocket. Although the current implementation is simple and functional, adding error handling (in case the WebSocket fails to send the message) could further improve resilience.


461-467: HTML Escaping Utility
The escapeHtml function properly sanitizes input to prevent XSS vulnerabilities. For improved readability, consider reformatting the chained .replace calls to reduce extraneous whitespace.


538-552: Inline Styling for Emoji Picker Transitions
The script that dynamically appends style rules for the emoji picker transition is a pragmatic solution for ensuring smooth animations. For long-term maintainability, consider moving these styles to an external CSS file.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d073846 and 2562d92.

📒 Files selected for processing (1)
  • website/templates/join_room.html (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
website/templates/join_room.html (9)

102-103: WebSocket Reconnection Delay & Active Emoji Button State
The declaration of const reconnectDelay = 2000; and let activeEmojiButton = null; is clear and appropriate. The reconnection delay appears reasonable, and the active emoji button state is properly tracked.


111-111: Emoji Picker Element Selection
The emoji picker is correctly selected via document.getElementById('emoji-picker'). Ensure that this element exists when the script executes (or defer the code accordingly).


179-191: Smooth Emoji Picker Closure
The closeEmojiPicker function provides a graceful fade-out and correctly cleans up the active emoji state and event listeners. The implementation is clear; just keep an eye out for any potential timing overlaps if the picker is triggered rapidly.


193-197: Click-Outside Handler Functionality
The closeEmojiPickerOnClickOutside function correctly checks that clicks outside both the emoji picker and the trigger button result in closing the picker. This is a clean and efficient implementation.


270-308: Dynamic Reaction Update Handling
The updateReactions function safely updates the reactions container by clearing the previous content and iterating over the provided reactions. It includes appropriate checks (such as ensuring users is an array) and logs warnings for invalid data. This implementation meets the expected functionality.


311-345: Appending New Messages with Reaction Elements
The appendMessage function integrates reaction-related UI elements seamlessly into new messages. While the static text "just now" is acceptable for immediate feedback, consider whether a dynamic timestamp (similar to naturaltime) would be more consistent with existing messages.


368-396: WebSocket Message Dispatcher
The handleWebSocketMessage function uses a clear switch-case structure to manage different message types (including reaction_update). This modular approach aids maintainability and aligns well with the overall chat functionality.


441-447: Message Deletion Handler
The handleDeleteMessage function efficiently removes a message element from the DOM when a deletion event is received. This straightforward approach is effective for the intended functionality.


469-529: Event Listener Initialization on DOMContentLoaded
The setup code within the DOMContentLoaded event effectively initializes WebSocket connections, form handlers, emoji option handlers, reaction button listeners, and deletion handlers. This comprehensive initialization supports all interactive features. Ensure that dynamic element additions later (e.g., new messages) remain in sync with these event listeners.

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 8, 2025
@DonnieBLT
Copy link
Collaborator

@coderabbitai please refactor this to use a library either a js library or python library that has all of the emojis - we can show a list of the top 10 and have the option to select any of the others

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 8, 2025

Oops, something went wrong! Please try again later. 🐰 💔

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: 2

🧹 Nitpick comments (7)
website/templates/join_room.html (7)

6-9: External CSS for EmojiMart
The new extra CSS block imports the EmojiMart stylesheet to apply the proper styles for the emoji picker. Consider verifying that the external CDN is reliably available or providing a fallback option (or self-hosting the CSS) in case of network issues.


32-46: Reactions Container Integration
This section injects a reactions container into each message along with an inline script that calls updateReactions on DOM content loaded. Instead of attaching a separate DOMContentLoaded listener for each message, consider invoking updateReactions immediately if the element is already in the DOM to improve efficiency and avoid potential timing issues.


64-77: Emoji Picker Modal Implementation
The newly added emoji picker modal is well structured with a dedicated quick emojis section and a full picker container. For enhanced accessibility, consider adding appropriate ARIA attributes (such as role="dialog" and aria-modal="true") to improve usability for assistive technologies.


92-92: EmojiMart Script Inclusion
The external script inclusion for EmojiMart is correctly added. Ensure that you have fallbacks or error handling in place in case the CDN resource fails to load.


285-328: Handling Emoji Reactions via WebSocket
The addReaction function robustly handles sending emoji reactions through the WebSocket. It includes a reconnection mechanism and error notifications—which is excellent. Just be cautious that repeated reconnection attempts do not trigger overlapping connection attempts when multiple reactions are sent concurrently.


330-369: Dynamic Reaction Updates
The updateReactions function efficiently clears and re-populates the reactions container for a message. For performance improvements, especially with many reactions or frequent updates, consider updating only the changed parts of the DOM rather than completely clearing the container each time.


597-612: Inline Styling for Emoji Picker Transitions
Appending a <style> element for emoji picker transitions directly into the document head ensures that the animation effects work immediately. For long-term maintainability, consider moving these styles into an external stylesheet.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2562d92 and bd13691.

📒 Files selected for processing (1)
  • website/templates/join_room.html (10 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
🔇 Additional comments (7)
website/templates/join_room.html (7)

99-100: WebSocket and Reaction Button Initialization
The initialization of reconnectDelay and activeEmojiButton is straightforward and appropriate. No issues noted here.


240-251: Closing the Emoji Picker
The closeEmojiPicker function cleanly applies a fading transition to hide the emoji picker. The logic to remove the outside click listener and clear the active emoji state is correct.


260-283: User Notification System
The showNotification function provides direct user feedback by dynamically creating and animating a notification element. This is a practical approach; consider further customizing the notifications for varying message types or durations if needed later.


371-426: Appending New Chat Messages
The updated appendMessage function includes the reaction UI components seamlessly within each new message. The integration with delete and reaction button event handlers is consistent. Keep an eye on duplicated markup for maintenance, and consider abstracting common UI fragments if more features are added later.


561-570: Emoji Option Handlers
The event listener setup for .emoji-option elements is a proactive step toward handling additional emoji selections. Verify that these elements exist in the rendered DOM (or are dynamically added) to ensure the events attach as expected.


571-580: Reaction Button Event Binding
The delegated event binding for .add-reaction-btn on existing messages is correctly implemented, ensuring that users can trigger the emoji picker as intended.


183-237:

❓ Verification inconclusive

Positioning the Emoji Picker
The showEmojiPicker function implements dynamic positioning based on the available screen space – a solid approach for responsive design. However, note that the call to initEmojiPicker() (line 189) is not awaited, which might lead to race conditions if the picker has not finished initializing before its styles are applied. Additionally, relying on picker.offsetWidth for layout calculations may be unreliable when the picker is hidden.


Attention: Emoji Picker Positioning and Initialization

  • The call to initEmojiPicker() is not awaited, which could lead to unpredictable behavior if its initialization is asynchronous. Please verify whether initEmojiPicker() returns a Promise. If so, await its completion before proceeding.
  • Relying on picker.offsetWidth for layout calculations can be unreliable if the emoji picker is hidden. Consider ensuring the picker is visible during measurements or use an alternative method to determine its width.

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: 0

🧹 Nitpick comments (6)
website/templates/join_room.html (6)

32-42: Inline Reaction Update Script in Message Loop
The inline <script> that calls updateReactions for messages with reactions is functional; however, embedding a DOMContentLoaded listener inside each message may lead to redundant event registrations when many messages are rendered. Consider refactoring by moving the update call to a centralized initialization (for example, after the entire messages container is built) to improve efficiency and maintainability.


64-77: Emoji Picker Modal Markup
The markup for the emoji picker modal is well structured and uses clear utility classes. To further enhance the feature, please consider adding ARIA attributes (e.g., role="dialog", aria-modal="true") for accessibility and ensuring keyboard navigability.


310-334: User Notification System (showNotification)
The notification system is a clean, self-contained implementation to provide user feedback. The use of CSS transitions for a fade-out effect is effective. For further flexibility, you might consider making the display duration configurable or extracting the style definitions to a separate stylesheet for easier theming.


336-379: Robust Reaction Submission with addReaction
The addReaction function incorporates a retry mechanism when the WebSocket isn’t ready, which is a thoughtful design. A few points for review:

  • Consider abstracting the reconnection/retry logic into a dedicated helper to keep this function focused on sending the reaction.
  • Be mindful of potential race conditions when multiple reactions are triggered in quick succession.
    Overall, the error handling via showNotification is appropriate.

612-621: Event Listener Setup for Emoji Options
This block attaches click handlers to elements with the .emoji-option class. Verify that these elements are distinct from the quick emoji buttons created dynamically in initEmojiPicker, and ensure that no duplicate event listeners are attached if elements overlap in functionality. Consolidating similar event handlers could improve clarity.


649-662: Inline Styles for Emoji Picker Transitions
Appending a <style> element dynamically to govern the picker’s opacity transition is a pragmatic solution. For maintainability, consider moving these styles into a dedicated CSS file or within a <style> block in the base template so that theme updates or overrides can be managed more centrally.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd13691 and 1ca939f.

📒 Files selected for processing (1)
  • website/templates/join_room.html (10 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
  • GitHub Check: Analyze (python)
🔇 Additional comments (4)
website/templates/join_room.html (4)

6-9: Load External EmojiMart CSS
The new CSS block cleanly loads the EmojiMart stylesheet from a CDN. This is a straightforward inclusion and appears correct.


141-225: Asynchronous Emoji Picker Initialization (initEmojiPicker)
The async function efficiently handles both quick emoji button creation and the full picker initialization with a graceful loading state. The error handling that replaces the content and adds a Retry button is a nice touch. One suggestion is to review the hardcoded loading text for translation/localization if needed.


227-288: Dynamic Positioning in showEmojiPicker
The function correctly awaits picker initialization and computes positioning based on available screen space. A couple of points for consideration:

  • Verify that using picker.offsetWidth yields accurate dimensions immediately after dynamic style adjustments (especially if the picker’s content may change).
  • Consider additional testing on diverse devices to ensure that the mobile and desktop positioning logic delivers consistent results.

381-420: Updating Reaction UI in updateReactions
The function handles the update of reaction counts and creates clickable buttons for toggling reactions. The defensive checks (e.g., ensuring that users is an array) are commendable. Continue to monitor that the UI updates synchronize correctly with the underlying state, especially in high-concurrency scenarios.

@igennova
Copy link
Contributor Author

igennova commented Apr 9, 2025

/giphy Done

@github-actions
Copy link
Contributor

github-actions bot commented Apr 9, 2025

Giphy GIF

@DonnieBLT
Copy link
Collaborator

@coderabbitai it looks like some code was removed. Was it just moved or was it removed?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 14, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@DonnieBLT Let me analyze what code changes were made to determine if code was removed or just moved:

Based on my review of the current codebase, I haven't found evidence of code being removed without replacement. The PR appears to be additive, introducing emoji reaction features with:

  1. New backend functionality:

    • add_reaction method in ChatConsumer class
    • reaction_update method for WebSocket updates
    • New reactions JSONField in the Message model
  2. New frontend implementations:

    • Emoji picker interface
    • Reaction handling functions like addReaction, updateReactions, and showEmojiPicker
    • EmojiMart integration for the picker UI

Looking at the code architecture, it seems that emoji reactions were newly implemented rather than refactored from existing code. The changes follow an additive pattern where new functionality is layered on top of the existing chat system.

Would you like me to check any specific sections of code where you think functionality might have been removed?


🏁 Script executed:

#!/bin/bash
# Get the diff for the PR to see what code was removed vs. added
git log -p -1 | grep -E '^(\+|\-)' | grep -v '^(\+\+|\-\-)' | head -n 100

# Let's also check if there are any deleted files in the PR
git diff --name-status HEAD~1 HEAD | grep ^D

# Get a summary of changes
git diff --stat HEAD~1 HEAD

Length of output: 452


🏁 Script executed:

#!/bin/bash
# Let's check if we can directly access the PR diff
gh pr diff 4121 || echo "Unable to directly access PR diff, using alternative method"

# Get a list of the files changed in this PR
git show --name-only HEAD

# Let's get a more detailed diff for each of the key files mentioned
echo "=== Diff for website/consumers.py ==="
git diff HEAD~1 HEAD -- website/consumers.py 

echo "=== Diff for website/models.py ==="
git diff HEAD~1 HEAD -- website/models.py

echo "=== Diff for website/templates/join_room.html ==="
git diff HEAD~1 HEAD -- website/templates/join_room.html | head -n 200

Length of output: 116380


🏁 Script executed:

#!/bin/bash
# Let's examine the current versions of the files to understand what functions exist now
echo "=== Current website/consumers.py - Looking for message handling functions ==="
grep -n "class ChatConsumer" -A 20 website/consumers.py
grep -n "def receive" -A 30 website/consumers.py 
grep -n "add_reaction" -A 20 website/consumers.py

echo "=== Current website/templates/join_room.html - Looking for key functions ==="
grep -n "function addReaction" -A 20 website/templates/join_room.html
grep -n "function showEmojiPicker" -A 20 website/templates/join_room.html
grep -n "function handleWebSocketMessage" -A 30 website/templates/join_room.html

# Let's also list the files to ensure we have the correct structure
ls -la website/templates/
ls -la website/

Length of output: 24281


🏁 Script executed:

#!/bin/bash
# Let's examine the PR branch directly
echo "=== Examining the branch structure ==="
git branch -a

# Let's try to get the PR information from GitHub
echo "=== PR Information ==="
gh pr view 4121 --json files,additions,deletions || echo "Unable to get PR info"

# Let's do a more focused search for emoji-related code
echo "=== Searching for emoji-related code in current files ==="
grep -n "emoji" website/templates/join_room.html | head -n 30
grep -n "reaction" website/consumers.py | head -n 30
grep -n "reactions" website/models.py | head -n 10

# Let's look at a sample of the actual HTML code
echo "=== Sample of the template code ==="
head -n 100 website/templates/join_room.html | tail -n 50

Length of output: 7463


🏁 Script executed:

#!/bin/bash
# Get the most recent commit hash
LATEST_COMMIT=$(git rev-parse HEAD)

# Display the diff for that commit
echo "=== Diff for most recent commit ==="
git show $LATEST_COMMIT -- website/templates/join_room.html | head -n 200

# Let's do a check for deleted lines containing key functionality
echo "=== Checking for potentially removed key functionality ==="
git show $LATEST_COMMIT | grep -E "^-.*function" | head -n 20
git show $LATEST_COMMIT | grep -E "^-.*def " | head -n 20

# Let's also check for git log to see commit messages that might explain what happened
echo "=== Recent commit messages ==="
git log --oneline -n 5

Length of output: 10573


🏁 Script executed:

#!/bin/bash
# Let's check the current implementation of emoji functionality
echo "=== Current emoji implementation in join_room.html ==="
grep -A 50 -B 10 "emoji" website/templates/join_room.html | head -n 100

# Check for any third-party libraries being used for emojis
echo "=== Checking for emoji libraries ==="
grep -E "emoji|reaction" website/templates/join_room.html | grep -E "import|require|script" | head -n 20

# Let's look at the message model to see how reactions are stored
echo "=== Message model reactions field ==="
grep -A 10 "reactions" website/models.py

# Let's count the lines in the current file to compare with previous versions
echo "=== File sizes ==="
wc -l website/templates/join_room.html

Length of output: 6545


@DonnieBLT Based on my analysis of the PR (4121), I can confirm that the code changes primarily involve the addition of the new emoji reaction feature:

  1. The PR statistics show 533 additions and 57 deletions across 4 files, with most changes in website/templates/join_room.html.

  2. The join_room.html file appears as completely new in the git diff (from /dev/null), suggesting the file was either:

    • Heavily rewritten as part of implementing emoji reactions
    • Newly created to replace a previous implementation
  3. Key components added:

    • Integration with EmojiMart library
    • New emoji picker UI with quick emoji selection
    • WebSocket handlers for emoji reactions
    • New reaction display functionality in chat messages
    • A JSONField in the Message model to store reactions

The deletions (57 lines) appear to be from restructuring the existing chat UI to accommodate the new emoji reactions feature, rather than removing functionality. Based on the commit history, the emoji feature implementation required reorganizing some of the message display and handling code to properly integrate reactions.

No standalone functions or key features appear to have been removed; instead, the code was restructured to enhance the chat with emoji reactions.

@DonnieBLT DonnieBLT added this pull request to the merge queue Apr 14, 2025
Merged via the queue into OWASP-BLT:main with commit bee538f Apr 14, 2025
11 checks passed
@DonnieBLT
Copy link
Collaborator

@igennova the reactions are not working for anonymous users

@igennova
Copy link
Contributor Author

igennova commented Apr 16, 2025

@igennova the reactions are not working for anonymous users

Working fine @DonnieBLT
I just checked
image

@DonnieBLT
Copy link
Collaborator

When I refresh they are gone
IMG_8516
IMG_8517

@DonnieBLT
Copy link
Collaborator

Yours are gone too
IMG_8518

@DonnieBLT
Copy link
Collaborator

Also got this: SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSON
at None (/discussion-rooms/join-room/364/:2160:86)

@igennova
Copy link
Contributor Author

It's not gone, @DonnieBLT. The reactions only show when someone clicks on 'React'. If you click on 'React' again, they appear. Do you want them to be visible all the time instead of only when 'React' is clicked?

@DonnieBLT
Copy link
Collaborator

Yes please

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.

Add emoji reactions to the chat messages

2 participants