From 1e5d0ebcfce91d1fe956f1fb6d0d687f7a663af4 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Sun, 28 Apr 2024 16:56:30 +0200 Subject: [PATCH] Editing and deleting is working Signed-off-by: Emmy D'Anello --- chat/consumers.py | 54 ++++++++++++++++++++++++++++++++++++++++----- chat/static/chat.js | 51 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/chat/consumers.py b/chat/consumers.py index 6e65614..c8d2ce5 100644 --- a/chat/consumers.py +++ b/chat/consumers.py @@ -62,11 +62,15 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): case 'fetch_channels': await self.fetch_channels() case 'send_message': - await self.receive_message(content) + await self.receive_message(**content) + case 'edit_message': + await self.edit_message(**content) + case 'delete_message': + await self.delete_message(**content) case 'fetch_messages': await self.fetch_messages(**content) case 'start_private_chat': - await self.start_private_chat(content['user_id']) + await self.start_private_chat(**content) case unknown: print("Unknown message type:", unknown) @@ -90,10 +94,10 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): } await self.send_json(message) - async def receive_message(self, message: dict) -> None: + async def receive_message(self, channel_id: int, content: str, **kwargs) -> None: user = self.scope['user'] channel = await Channel.objects.prefetch_related('tournament__pools__juries', 'pool', 'team', 'invited') \ - .aget(id=message['channel_id']) + .aget(id=channel_id) write_channels = await Channel.get_accessible_channels(user, 'write') if not await write_channels.acontains(channel): return @@ -101,7 +105,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): message = await Message.objects.acreate( author=user, channel=channel, - content=message['content'], + content=content, ) await self.channel_layer.group_send(f'chat-{channel.id}', { @@ -114,6 +118,36 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): 'content': message.content, }) + async def edit_message(self, message_id: int, content: str, **kwargs) -> None: + message = await Message.objects.aget(id=message_id) + user = self.scope['user'] + if user.id != message.author_id and not user.is_superuser: + return + + message.content = content + await message.asave() + + await self.channel_layer.group_send(f'chat-{message.channel_id}', { + 'type': 'chat.edit_message', + 'id': message_id, + 'channel_id': message.channel_id, + 'content': content, + }) + + async def delete_message(self, message_id: int, **kwargs) -> None: + message = await Message.objects.aget(id=message_id) + user = self.scope['user'] + if user.id != message.author_id and not user.is_superuser: + return + + await message.adelete() + + await self.channel_layer.group_send(f'chat-{message.channel_id}', { + 'type': 'chat.delete_message', + 'id': message_id, + 'channel_id': message.channel_id, + }) + async def fetch_messages(self, channel_id: int, offset: int = 0, limit: int = 50, **_kwargs) -> None: channel = await Channel.objects.aget(id=channel_id) read_channels = await Channel.get_accessible_channels(self.scope['user'], 'read') @@ -138,7 +172,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): ])) }) - async def start_private_chat(self, user_id: int) -> None: + async def start_private_chat(self, user_id: int, **kwargs) -> None: user = self.scope['user'] other_user = await User.objects.aget(id=user_id) channel_qs = Channel.objects.filter(private=True).filter(invited=user).filter(invited=other_user) @@ -183,6 +217,14 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): 'timestamp': message['timestamp'], 'author': message['author'], 'content': message['content']}) + async def chat_edit_message(self, message) -> None: + print(message) + await self.send_json({'type': 'edit_message', 'id': message['id'], 'channel_id': message['channel_id'], + 'content': message['content']}) + + async def chat_delete_message(self, message) -> None: + await self.send_json({'type': 'delete_message', 'id': message['id'], 'channel_id': message['channel_id']}) + async def chat_start_private_chat(self, message) -> None: await self.channel_layer.group_add(f"chat-{message['channel']['id']}", self.channel_name) await self.send_json({'type': 'start_private_chat', 'channel': message['channel']}) diff --git a/chat/static/chat.js b/chat/static/chat.js index 30ce636..74567f1 100644 --- a/chat/static/chat.js +++ b/chat/static/chat.js @@ -122,6 +122,16 @@ function receiveMessage(message) { showNotification(channels[message['channel_id']]['name'], `${message['author']} : ${message['content']}`) } +function editMessage(data) { + messages[data['channel_id']].get(data['id'])['content'] = data['content'] + redrawMessages() +} + +function deleteMessage(data) { + messages[data['channel_id']].delete(data['id']) + redrawMessages() +} + function fetchMessages(channel_id, offset = 0, limit = MAX_MESSAGES) { socket.send(JSON.stringify({ 'type': 'fetch_messages', @@ -270,11 +280,14 @@ function registerMessageContextMenu(message, element) { menu_event.preventDefault() removeAllPopovers() let content = `Envoyer un message privé` - if (message['author_id'] === USER_ID || IS_ADMIN) { + + let has_right_to_edit = message['author_id'] === USER_ID || IS_ADMIN + if (has_right_to_edit) { content += `
` - content += `Modifier` - content += `Supprimer` + content += `Modifier` + content += `Supprimer` } + const popover = bootstrap.Popover.getOrCreateInstance(element, { 'content': content, 'html': true, @@ -290,6 +303,32 @@ function registerMessageContextMenu(message, element) { 'user_id': message['author_id'], })) }) + + if (has_right_to_edit) { + document.getElementById('edit-message-' + message['id']).addEventListener('click', event => { + event.preventDefault() + popover.dispose() + let new_message = prompt("Modifier le message", message['content']) + if (new_message) { + socket.send(JSON.stringify({ + 'type': 'edit_message', + 'message_id': message['id'], + 'content': new_message, + })) + } + }) + + document.getElementById('delete-message-' + message['id']).addEventListener('click', event => { + event.preventDefault() + popover.dispose() + if (confirm("Supprimer le message ?")) { + socket.send(JSON.stringify({ + 'type': 'delete_message', + 'message_id': message['id'], + })) + } + }) + } }) } @@ -322,6 +361,12 @@ document.addEventListener('DOMContentLoaded', () => { case 'send_message': receiveMessage(data) break + case 'edit_message': + editMessage(data) + break + case 'delete_message': + deleteMessage(data) + break case 'fetch_messages': receiveFetchedMessages(data) break