Skip to content

Conversation

@4555jan
Copy link
Contributor

@4555jan 4555jan commented Oct 21, 2025

Description

Implemented delete message feature with soft delete functionality. Messages are not permanently removed from the database but are marked as deleted and display "This message was deleted" in the UI. Users can delete their own messages through a long-press context menu, similar to WhatsApp's UX pattern.

Fixes #571

screen-recording-2025-10-21-192333_A3sFcoA6.mp4

Type of change

  • New feature (non-breaking change which adds functionality)

Changes Made

1. Message Model (lib/models/message.dart)

  • Added isdeleted boolean field to track deleted messages
  • Updated fromJson(), toJson(), toJsonForUpload(), and copyWith() methods
  • Default value set to false for backward compatibility

2. RoomChatController (lib/controllers/room_chat_controller.dart)

  • Added deleteMessage() method for soft-deleting messages (sets isDeleted: true, clears content)
  • Updated sendMessage() to initialize isdeleted: false

3. RoomChatScreen (lib/views/screens/room_chat_screen.dart)

  • Added options: Edit, delete, Cancel
  • Added confirmation dialog before message deletion
  • Updated UI to display "This message was deleted" with delete icon for deleted messages
  • Changed background color to grey for deleted messages
  • Disabled editing and replying to deleted messages
  • added 2 methods _showMessageContextMenu and confirm delete

How Has This Been Tested

Test Scenarios:

  1. Delete own message: Long-press on own message → Delete → Confirm → Message shows as deleted
  2. i started 2 emulator checked and how its working

Test Configuration:

  • Device: [Android]- android emulators
  1. Long-press context menu
  2. Delete confirmation dialog
  3. Deleted message UI
  4. Real-time deletion across multiple devices

Database Changes Required

  • Add isdeleted boolean attribute to the chat messages collection
  • Attribute key: isdeleted (case-sensitive)
  • Type: Boolean
  • Default value: false
  • Required: No
  • in the content attribute it is saveing null and not "this message is deleted"

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

Maintainer Checklist

@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request implements message deletion functionality in the room chat feature. It adds an isdeleted flag to the Message model, introduces a backend deletion method that marks messages as deleted in Appwrite and sends notifications, updates the UI to display deleted messages with visual distinction, and adds permission-based context menu options for message removal.

Changes

Cohort / File(s) Summary
Message Model
lib/models/message.dart
Added isdeleted boolean field to Message class. Updated constructor, JSON serialization (toJson, toJsonForUpload), JSON deserialization (fromJson with false default), and copyWith method to handle the new field.
Chat Controller
lib/controllers/room_chat_controller.dart
Added deleteMessage(String messageId) method to locate, mark messages as deleted, update Appwrite, and send optional notifications. Updated sendMessage, editMessage, and real-time subscription handling in subscribeToMessages to initialize/propagate isdeleted field.
Chat UI & Interactions
lib/views/screens/room_chat_screen.dart
Added deletion workflow with onDeleteMessage callback and canDelete permission parameter to ChatMessageItem. Implemented long-press context menu offering Delete/Cancel options. Added visual feedback: greyed background/text for deleted messages, placeholder "This message was deleted" row, and suppressed editing/reply-to rendering for deleted messages.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant UI as Room Chat UI
    participant Controller as Room Chat Controller
    participant Appwrite as Appwrite Backend
    participant RealtimeDB as Realtime Subscription

    User->>UI: Long-press message
    UI->>UI: Show context menu
    User->>UI: Tap "Delete"
    UI->>UI: Show confirmation dialog
    User->>UI: Confirm deletion
    UI->>Controller: deleteMessage(messageId)
    activate Controller
    Controller->>Controller: Find message in list
    Controller->>Controller: Mark isdeleted=true, clear content
    Controller->>Appwrite: Update message document
    activate Appwrite
    Appwrite->>Appwrite: Persist deletion
    Appwrite-->>Appwrite: Broadcast realtime event
    Appwrite-->>Controller: Update confirmation
    deactivate Appwrite
    Controller->>Controller: Send deletion notification
    Controller->>UI: Rebuild with updated message
    deactivate Controller
    RealtimeDB->>UI: Propagate isdeleted from subscription
    UI->>UI: Render deleted message placeholder
    User->>User: Sees "This message was deleted"
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Rationale: The changes introduce a focused feature across three files with clear intent. Model updates are straightforward (single field addition with proper serialization). Controller logic is simple (deletion marking and notification dispatch). However, the UI layer introduces moderate complexity with conditional rendering branches, permission checks, context menus, and state-dependent styling that require careful verification of logic paths.

Poem

🐰 A whisker-twitching fix, so neat—
Messages deleted, now complete!
Long-press magic makes them fade,
With placeholders gently made.
Chat flows freer, users freed,
Just what the bunnyverse did need! 🗑️✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat: implement delete message feature in chat room" accurately summarizes the primary objective of the changeset. The title clearly identifies that a delete message feature is being added to the chat room, which is precisely what the code changes accomplish. The title is concise, specific, and avoids vague language, making it immediately clear to reviewers scanning history that this PR is about implementing message deletion functionality.
Linked Issues Check ✅ Passed The code changes comprehensively address all primary objectives from linked issue #571. Backend support is implemented through the new deleteMessage() method in RoomChatController and the isdeleted field added to the Message model [#571]. User-facing deletion is enabled via the long-press context menu with confirmation dialog in the room_chat_screen, allowing users to delete their own messages [#571]. Real-time reflection of deletions across clients is handled through the subscription update logic that propagates the isdeleted state [#571]. The UI displays deleted messages with a placeholder text, greyed styling, and disabled editing, aligning with common messaging app behavior [#571]. All database and UI changes necessary to mark and display deleted messages are included.
Out of Scope Changes Check ✅ Passed All code changes in the pull request are directly related to implementing the delete message feature specified in issue #571. The additions to the Message model (isdeleted field) are necessary for tracking deletion state. The new deleteMessage() method in RoomChatController directly implements backend deletion logic. The UI changes in room_chat_screen (context menu, confirmation dialog, deletion state handling, greyed styling) are essential components of the user-facing feature. The real-time synchronization logic for propagating isdeleted state is required for cross-device deletion reflection. No changes appear to be unrelated to the primary objective of adding message deletion functionality.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

@github-actions
Copy link
Contributor

🎉 Welcome @4555jan!
Thank you for your pull request! Our team will review it soon. 🔍

  • Please ensure your PR follows the contribution guidelines. ✅
  • All automated tests should pass before merging. 🔄
  • If this PR fixes an issue, link it in the description. 🔗

We appreciate your contribution! 🚀

@4555jan
Copy link
Contributor Author

4555jan commented Oct 21, 2025

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

✅ Actions performed

Review triggered.

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 similar comment
@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

✅ Actions performed

Review triggered.

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.

Copy link

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/models/message.dart (1)

69-84: Null-safe deserialization for deleted messages

content can be null in the DB after deletion; assigning null to a non-nullable String will crash at runtime. Guard it.

   Message.fromJson(Map<String, dynamic> json)
     : roomId = json['roomId'],
@@
-      isEdited = json['isEdited'],
-      content = json['content'],
+      isEdited = json['isEdited'],
+      content = (json['content'] as String?) ?? '',
       creationDateTime = DateTime.parse(json['creationDateTime']),
-      isdeleted = json['isdeleted'] ?? false,
+      isdeleted = json['isdeleted'] ?? false,
       replyTo = json['replyTo'] != null
           ? ReplyTo.fromJson(json['replyTo'])
           : null;
lib/controllers/room_chat_controller.dart (1)

280-298: Treat deletions separately in realtime updates; guard index −1

Avoid “Edited” notifications for deletions and handle out‑of‑order updates.

-            if (action == 'update') {
+            if (action == 'update') {
               Message updatedMessage = Message.fromJson(data.payload);
-              var index = messages.indexWhere(
+              final index = messages.indexWhere(
                 (msg) => msg.messageId == updatedMessage.messageId,
               );
-              messages[index] = messages[index].copyWith(
+              if (index == -1) {
+                // Out-of-order update; insert or ignore
+                messages.add(updatedMessage);
+              } else {
+                messages[index] = messages[index].copyWith(
                 content: updatedMessage.content,
                 isEdited: updatedMessage.isEdited,
                 isdeleted: updatedMessage.isdeleted,
-              );
-              if (appwriteRoom != null) {
-                auth.flutterLocalNotificationsPlugin.show(
-                  0,
-                  'Message Edited in ${appwriteRoom?.name ?? appwriteUpcommingRoom!.name}',
-                  '${updatedMessage.creatorName} updated his message: ${updatedMessage.content}',
-                  notificationDetails,
-                );
-              }
+                );
+              }
+              if (appwriteRoom != null) {
+                final deleted = updatedMessage.isdeleted;
+                final title = deleted
+                    ? 'Message Deleted in ${appwriteRoom?.name ?? appwriteUpcommingRoom!.name}'
+                    : 'Message Edited in ${appwriteRoom?.name ?? appwriteUpcommingRoom!.name}';
+                final body = deleted
+                    ? '${updatedMessage.creatorName} deleted a message'
+                    : '${updatedMessage.creatorName} updated his message: ${updatedMessage.content}';
+                auth.flutterLocalNotificationsPlugin.show(
+                  0,
+                  title,
+                  body,
+                  notificationDetails,
+                );
+              }
             }
🧹 Nitpick comments (3)
lib/views/screens/room_chat_screen.dart (3)

121-127: Only enable delete for non-deleted messages

Avoid opening a menu that can only cancel.

-                          canDelete:
-                              auth.appwriteUser.$id ==
-                              chatController.messages[index].creatorId,
+                          canDelete:
+                              auth.appwriteUser.$id ==
+                                  chatController.messages[index].creatorId &&
+                              !chatController.messages[index].isdeleted,

206-243: Add “Edit” to the context menu (when allowed)

Matches the PR UX (“Edit, Delete, Cancel”) and improves discoverability.

   void _showMessageContextMenu(BuildContext context) {
     showModalBottomSheet(
@@
           child: Wrap(
             children: [
+              if (widget.canEdit && !widget.message.isdeleted)
+                ListTile(
+                  leading: const Icon(Icons.edit),
+                  title: const Text('Edit'),
+                  onTap: () {
+                    Navigator.pop(context);
+                    startEditing();
+                  },
+                ),
               if (widget.canDelete && !widget.message.isdeleted)
                 ///delete option
                 ListTile(

414-435: Deleted placeholder copy/UI

Clear and unobtrusive. Consider i18n in a follow-up.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e204dd5 and d5b69f3.

📒 Files selected for processing (3)
  • lib/controllers/room_chat_controller.dart (4 hunks)
  • lib/models/message.dart (7 hunks)
  • lib/views/screens/room_chat_screen.dart (10 hunks)
🔇 Additional comments (6)
lib/controllers/room_chat_controller.dart (1)

137-138: Initialize deletion flag on new messages

Good: defaulting to not deleted.

If you adopt isDeleted naming, update here too.

lib/views/screens/room_chat_screen.dart (4)

115-118: Wire-up delete action

Hook looks correct.


147-160: ChatMessageItem API additions

Constructor and fields look consistent.


306-309: Visual state for deleted messages

Good UX affordance with greyed bubble.


344-346: Hide reply preview on deleted

Correct guard.

lib/models/message.dart (1)

11-11: Verify complete refactoring scope across all PR files

The grep results show isdeleted is referenced in three files, but the diff only covers lib/models/message.dart. If lib/views/screens/room_chat_screen.dart (8 usages) and lib/controllers/room_chat_controller.dart (4 usages) are included in this PR, they must also be updated to use isDeleted consistently. Confirm that all files have been refactored and no usages of the old snake_case field name remain.

Comment on lines 47 to 81
/// delete method
Future<void> deleteMessage(String messageId) async {
try {
Message messageToDelete = messages.firstWhere(
(msg) => msg.messageId == messageId,
);
messageToDelete = messageToDelete.copyWith(content: '', isdeleted: true);

await databases.updateDocument(
databaseId: masterDatabaseId,
collectionId: chatMessagesCollectionId,
documentId: messageId,
data: messageToDelete.toJsonForUpload(),
);
if (appwriteUpcommingRoom != null) {
log('Sending notification for deleted message');
var body = json.encode({
'roomId': appwriteUpcommingRoom?.id,
'payload': {
'title': 'Message Deleted in ${appwriteUpcommingRoom?.name}',
'body': '${messageToDelete.creatorName} deleted a message',
},
});
var results = await functions.createExecution(
functionId: sendMessageNotificationFunctionID,
body: body.toString(),
);
log(results.status);
}
log('Message deleted successfully');
} catch (e) {
log('Error deleting message: $e');
return;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Harden delete path: enforce ownership, handle not-found

Prevent deleting others’ messages client-side (in addition to backend ACLs) and avoid firstWhere throw.

   /// delete method
   Future<void> deleteMessage(String messageId) async {
     try {
-      Message messageToDelete = messages.firstWhere(
-        (msg) => msg.messageId == messageId,
-      );
-      messageToDelete = messageToDelete.copyWith(content: '', isdeleted: true);
+      final idx = messages.indexWhere((m) => m.messageId == messageId);
+      if (idx == -1) {
+        log('Message not found: $messageId');
+        return;
+      }
+      var messageToDelete = messages[idx];
+      if (messageToDelete.creatorId != auth.appwriteUser.$id) {
+        log('Forbidden: cannot delete others\' messages');
+        return;
+      }
+      messageToDelete =
+          messageToDelete.copyWith(content: '', isdeleted: true);
@@
-        data: messageToDelete.toJsonForUpload(),
+        data: {
+          // Update only the fields that change
+          'content': '',
+          'isdeleted': true,
+        },
       );

Confirm backend rules also restrict updates to message owner to avoid client bypass.


I'll verify the review comment by examining the codebase for the relevant concerns.


---

🏁 Script executed:

```shell
#!/bin/bash
# Find Message model definition
echo "=== Searching for Message model definition ==="
fd -e dart | xargs rg -n "class Message" -A 10 | head -50

Length of output: 549


🏁 Script executed:

#!/bin/bash
# Search for auth object and appwriteUser usage
echo "=== Searching for auth object and appwriteUser ==="
rg -n "auth\.appwriteUser" lib/controllers/ -C 2

Length of output: 496


🏁 Script executed:

#!/bin/bash
# Check the Message model fields, especially creatorId and creatorName
echo "=== Searching for creatorId field in Message ==="
rg -n "creatorId|creatorName" lib/ -C 1 | head -60

Length of output: 3646


🏁 Script executed:

#!/bin/bash
# Look for toJsonForUpload method to understand what data is being sent
echo "=== Searching for toJsonForUpload implementation ==="
rg -n "toJsonForUpload" lib/ -A 5 | head -50

Length of output: 1870


🏁 Script executed:

#!/bin/bash
# Check if there are any Appwrite ACL or permission configurations
echo "=== Searching for Appwrite permissions and ACL configuration ==="
rg -n "permissions|Permissions|ACL|acl" lib/ | grep -i "message\|delete\|document" | head -30

Length of output: 64



---

🏁 Script executed:

```shell
#!/bin/bash
# Search for serverless function implementations that might handle backend validation
echo "=== Searching for function handlers and backend validation ==="
rg -n "sendMessageNotification|Function|handler" lib/ -C 2 | head -50

Length of output: 3336


🏁 Script executed:

#!/bin/bash
# Look for any Appwrite Rules configuration files
echo "=== Searching for Appwrite config files ==="
fd -e json -e yaml -e yml | xargs rg -l "appwrite\|permission\|rule" 2>/dev/null | head -20

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Check for any backend-related configuration or environment setup
echo "=== Searching for Appwrite database/collection initialization ==="
rg -n "chatMessagesCollectionId|createDocument|updateDocument" lib/ -B 2 -A 2 | head -80

Length of output: 5266


🏁 Script executed:

#!/bin/bash
# Look at the complete deleteMessage implementation including surrounding context
echo "=== Full deleteMessage method context ==="
rg -n "deleteMessage" lib/controllers/room_chat_controller.dart -B 2 -A 35

Length of output: 1374


Add ownership check and not-found handling to deleteMessage() method

The review identifies legitimate security and error-handling gaps in the current implementation.

Verified issues:

Missing ownership validation: deleteMessage() lacks a client-side check despite the UI layer already enforcing it (room_chat_screen.dart lines 121-126). Calling the method directly bypasses this protection.

Unhandled not-found case: firstWhere() throws StateError if the message doesn't exist, caught generically without distinction from other errors.

Full object serialization: toJsonForUpload() sends all fields including creatorId—though the proposed change only updates content and isdeleted, which is the safer approach.

Backend validation note: No Appwrite ACL configuration is visible in the codebase; backend rules must be verified separately via Appwrite console or documentation to confirm message owner restrictions are enforced server-side.

The proposed changes are sound and should be applied.

Comment on lines 185 to 190
updatedMessage = updatedMessage.copyWith(
content: newContent,
isEdited: true,
isdeleted: false,
);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t resurrect deleted messages on edit

Editing currently forces isdeleted: false. Block edits for deleted messages and keep the flag unchanged.

   updatedMessage = updatedMessage.copyWith(
     content: newContent,
     isEdited: true,
-    isdeleted: false,
   );
+  if (updatedMessage.isdeleted) {
+    log('Editing a deleted message is not allowed');
+    return;
+  }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/controllers/room_chat_controller.dart around lines 185-190, the copyWith
call forces isdeleted: false which resurrects deleted messages; change the logic
to first check the existing message's isdeleted flag and if it's true, block the
edit (return/throw or no-op) so deleted messages cannot be edited, otherwise
perform the copyWith but do not override isdeleted (preserve the original flag)
— remove the hardcoded isdeleted: false and ensure edits only proceed for
non-deleted messages.

@M4dhav M4dhav self-requested a review October 21, 2025 19:11
@M4dhav M4dhav added the enhancement New feature or request label Oct 21, 2025
@M4dhav M4dhav linked an issue Oct 21, 2025 that may be closed by this pull request
@M4dhav
Copy link
Contributor

M4dhav commented Oct 21, 2025

Please confirm that you have tested this functionality on more than 1 device (multiple users in the same chat session)

@4555jan
Copy link
Contributor Author

4555jan commented Oct 21, 2025

Well I tested on 2 emulators and the video is about that basically if you want 2 real android device video I can share that also @M4dhav

@M4dhav
Copy link
Contributor

M4dhav commented Oct 21, 2025

Please share a video recording of the functionality on 2 emulators

@4555jan
Copy link
Contributor Author

4555jan commented Oct 22, 2025

@M4dhav i uploaded the video .....what u think about this in the 2nd emulator the after the long press the it still opens should i remove it from there and only the person who messaged it.. allow to open that

@4555jan
Copy link
Contributor Author

4555jan commented Oct 25, 2025

@M4dhav in this change dialog box will only open if the sender wants to delete the the message

@M4dhav
Copy link
Contributor

M4dhav commented Oct 25, 2025

Since there is a variable added to the backend, you will need to link a. backend PR along with this.

@M4dhav
Copy link
Contributor

M4dhav commented Oct 25, 2025

I think it would be better to merge this once that PR is opened as well.

@4555jan
Copy link
Contributor Author

4555jan commented Oct 25, 2025

@M4dhav sorry by that I meant is there any front-end related issue or something?

log(appwriteUpcommingRoom.toString());
}

/// delete method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to add tests for this function

Comment on lines 61 to 80
if (appwriteUpcommingRoom != null) {
log('Sending notification for deleted message');
var body = json.encode({
'roomId': appwriteUpcommingRoom?.id,
'payload': {
'title': 'Message Deleted in ${appwriteUpcommingRoom?.name}',
'body': '${messageToDelete.creatorName} deleted a message',
},
});
var results = await functions.createExecution(
functionId: sendMessageNotificationFunctionID,
body: body.toString(),
);
log(results.status);
}
log('Message deleted successfully');
} catch (e) {
log('Error deleting message: $e');
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to send notifications on deleted messages, we can remove tis

Comment on lines 120 to 123
!chatController.messages[index].isEdited,
!chatController.messages[index].isdeleted,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

messages cannot be edited twice, so the isEdited check also needs to be there

Comment on lines 418 to 424
Row(
children: [
Icon(
Icons.delete_outline,
color: Colors.grey[600],
size: 18,
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should reove the icon, the representation would be better with just text. subsequently, row can be removed as well

@4555jan
Copy link
Contributor Author

4555jan commented Oct 25, 2025

@M4dhav I am supposed to add test for delete method only right?

@M4dhav
Copy link
Contributor

M4dhav commented Oct 25, 2025

Yes, as a general rule of thumb going forward, contributors are recommended to add tests for any functionality they implement that can be easily tested via unit/widget tests.

@4555jan
Copy link
Contributor Author

4555jan commented Oct 26, 2025

@M4dhav i added the attribute to appwrite.json which wil basically create it messages collection when any dev first time runs the script please review it as well i even run the entire script after the change

@M4dhav
Copy link
Contributor

M4dhav commented Oct 26, 2025

Backend PR is ready to merge, once you have completed your changes here then I will merge both the PRs at once

@4555jan
Copy link
Contributor Author

4555jan commented Oct 26, 2025

@M4dhav i am also supoosed to add mocks file too for the test ?

@M4dhav
Copy link
Contributor

M4dhav commented Oct 26, 2025

If your tests need mocks then yes

@4555jan
Copy link
Contributor Author

4555jan commented Oct 26, 2025

@M4dhav in tests it is bascially tests for deletes a message Handles message not found error Handles database errors and in the recent pr i added because in the last pr i changed some existing code which was unrelated to my change please check/review if i made any major mistakes again i will fix it asap
image

@4555jan
Copy link
Contributor Author

4555jan commented Oct 28, 2025

@M4dhav "messages cannot be edited twice, so the isEdited check also needs to be there" sorry in my last pr i misundershood this and fixed it in the recent one now messages cannot be edited twice and also made changes in the test description of room_chat_controller

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Delete Message Functionality in Room Chat

2 participants