From 0aade62bce206fb3a1d14b571b907cb471aeaac9 Mon Sep 17 00:00:00 2001 From: Yoan Le Clanche Date: Mon, 27 Jun 2022 17:23:37 +0200 Subject: [PATCH] Add reply option to chat --- .../migrations/0020_chatmessage_reply_to.py | 19 ++++++++++++ teleforma/models/chat.py | 15 +++++++--- teleforma/src/js/components/Chat.vue | 14 +++++++-- teleforma/src/package.json | 2 +- teleforma/src/yarn.lock | 29 ++++++++----------- teleforma/ws/chat.py | 20 ++++++++++--- 6 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 teleforma/migrations/0020_chatmessage_reply_to.py diff --git a/teleforma/migrations/0020_chatmessage_reply_to.py b/teleforma/migrations/0020_chatmessage_reply_to.py new file mode 100644 index 00000000..cad99787 --- /dev/null +++ b/teleforma/migrations/0020_chatmessage_reply_to.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.3 on 2022-06-27 16:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('teleforma', '0019_merge_20220627_1418'), + ] + + operations = [ + migrations.AddField( + model_name='chatmessage', + name='reply_to', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='teleforma.chatmessage'), + ), + ] diff --git a/teleforma/models/chat.py b/teleforma/models/chat.py index ac52266b..145d2cc4 100644 --- a/teleforma/models/chat.py +++ b/teleforma/models/chat.py @@ -20,6 +20,7 @@ class ChatMessage(models.Model): User, related_name='chat_messages', verbose_name=_('user'), on_delete=models.CASCADE, blank=True, null=True) created = models.DateTimeField('Creation date', auto_now_add=True) system = models.BooleanField(default=False) + reply_to = models.ForeignKey("ChatMessage", on_delete=models.CASCADE, null=True, blank=True) class Meta(MetaCore): db_table = app_label + '_' + 'chat_messages' @@ -28,10 +29,9 @@ class ChatMessage(models.Model): return f"{str(self.user)} - {self.room_name} - {self.message[:20]}" @classmethod - def add_message(cls, user, room_name, message, system=False): + def add_message(cls, user, room_name, message, system=False, reply_to=None): message = ChatMessage(user=user, message=message, - room_name=room_name, system=system) - print("message added", message) + room_name=room_name, system=system, reply_to=reply_to) message.save() return message.to_dict() @@ -60,7 +60,7 @@ class ChatMessage(models.Model): }) def to_dict(self): - return { + message = { '_id': self.id, 'content': self.message, 'senderId': self.user and self.user.id or "system", @@ -69,3 +69,10 @@ class ChatMessage(models.Model): 'timestamp': self.created.strftime('%H:%M'), 'system': self.system } + if self.reply_to: + message.update( + { + 'replyMessage': self.reply_to.to_dict() + } + ) + return message diff --git a/teleforma/src/js/components/Chat.vue b/teleforma/src/js/components/Chat.vue index 9ee8dc0b..500a8c23 100644 --- a/teleforma/src/js/components/Chat.vue +++ b/teleforma/src/js/components/Chat.vue @@ -10,7 +10,12 @@ :show-reaction-emojis="false" :show-audio="false" :messages="messages" - :message-actions="[]" + :message-actions="[ + { + name: 'replyMessage', + title: 'Répondre' + } + ]" :link-options="{ disabled: false, target: '_self' }" :text-messages="{ ROOMS_EMPTY: 'Aucune conversation', @@ -46,6 +51,7 @@ export default class Chat extends Vue { { roomId: "global", roomName: "", + avatar: "", users: [] } ] @@ -66,6 +72,7 @@ export default class Chat extends Vue { { roomId: roomInfo.room_name, roomName: roomInfo.room_title, + avatar: "", // add fake users to make sure username are displayed in the chat (if less than two, name are not displayed) users: [ { @@ -130,11 +137,12 @@ export default class Chat extends Vue { } } - sendMessage({ content }: { content: Message }) { + sendMessage({ content, replyMessage }: Message) { /** send message to socket */ this.socket!.send( JSON.stringify({ - message: content + message: content, + replyTo: replyMessage._id || null }) ) } diff --git a/teleforma/src/package.json b/teleforma/src/package.json index 0114b670..aa419895 100644 --- a/teleforma/src/package.json +++ b/teleforma/src/package.json @@ -15,7 +15,7 @@ "extract-css": "^2.0.0", "path": "^0.12.7", "vue": "^2.6.11", - "vue-advanced-chat": "^1.1.0", + "vue-advanced-chat": "^1.5.5", "vue-class-component": "^7.2.3", "vue-property-decorator": "^9.1.2", "webpack-manifest-plugin": "^3.1.1" diff --git a/teleforma/src/yarn.lock b/teleforma/src/yarn.lock index 98f32ed3..a6397589 100644 --- a/teleforma/src/yarn.lock +++ b/teleforma/src/yarn.lock @@ -3560,10 +3560,10 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emoji-picker-element@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/emoji-picker-element/-/emoji-picker-element-1.7.1.tgz#4d4269f1bbde105d11dd0d6156e226be3047ed15" - integrity sha512-Onv1JJsMkXixKM8dnYa9YsRAHhzd7vosPEVUPpJGNPf1zH6bKt8Kjl4sw8vcwlMWCHTWIRiU6uEBm7KsduDGdg== +emoji-picker-element@^1.8.2: + version "1.12.1" + resolved "https://registry.yarnpkg.com/emoji-picker-element/-/emoji-picker-element-1.12.1.tgz#854a9bbae4d9a04fa2b5cd0763845921f4904c83" + integrity sha512-F9AY/re8uqZmBcCXLHLGvyy7fxuMQdZl9R8OToLRH8Vnns+WMX8RYUbI2nSJklzl5+82qzpYWeus1/puDepWcQ== emoji-regex@^7.0.1: version "7.0.3" @@ -5588,10 +5588,10 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -lamejs@^1.2.0: +lamejs@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/lamejs/-/lamejs-1.2.0.tgz#0259f83db4666141a7b671b8caa6369d95177d08" - integrity sha1-Aln4PbRmYUGntnG4yqY2nZUXfQg= + integrity sha512-xEYvsB2sZ9jIccqfUQpQEBdB6UYQDG/ta2xQkH7oEpENb0JHFJii965WVF8ErUMdZzoe7EdIruz1WpICdhZ9Pw== dependencies: use-strict "1.0.1" @@ -9007,17 +9007,16 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-advanced-chat@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vue-advanced-chat/-/vue-advanced-chat-1.1.0.tgz#1c46eb8383e7933775f96fa59f588f6d15107c12" - integrity sha512-wJMFWA9olzfvSdAtgA1qKM9h7hxrADCKSr28eXp/xj2n3YKpvMgd5FurTX3WD6tqBxHOh0o85wT1I6Hp64c2VA== +vue-advanced-chat@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/vue-advanced-chat/-/vue-advanced-chat-1.5.5.tgz#6a9af8af18364a15d01a6308ac7ae663d7311a93" + integrity sha512-v3+STQXHoTNWlIWOFlzDzhXlUVZXAFoWRpcZXv0pVNcILzGUXSZ4wQeetWyWx42PhXvNhD4h6ktPLBbZzbqTTQ== dependencies: - emoji-picker-element "^1.7.0" + emoji-picker-element "^1.8.2" linkifyjs "^2.1.9" v-click-outside "^3.1.2" - vue-infinite-loading "https://github.com/antoine92190/vue-infinite-loading/tarball/master" optionalDependencies: - lamejs "^1.2.0" + lamejs "1.2.0" vue-class-component@^7.2.3: version "7.2.6" @@ -9041,10 +9040,6 @@ vue-hot-reload-api@^2.3.0: resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== -"vue-infinite-loading@https://github.com/antoine92190/vue-infinite-loading/tarball/master": - version "2.4.5" - resolved "https://github.com/antoine92190/vue-infinite-loading/tarball/master#064f4f302a586407685b6ca80f955543781d9aa7" - "vue-loader-v16@npm:vue-loader@^16.1.0": version "16.2.0" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.2.0.tgz#046a53308dd47e58efe20ddec1edec027ce3b46e" diff --git a/teleforma/ws/chat.py b/teleforma/ws/chat.py index fa909243..ec15ed0d 100644 --- a/teleforma/ws/chat.py +++ b/teleforma/ws/chat.py @@ -37,8 +37,8 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): # Receive message from user async def receive_json(self, content): message_content = content['message'][:255] - - message = await self.add_message_to_db(self.scope['user'], self.room_name, message_content) + reply_to = await self.get_message_from_id(content.get('replyTo')) + message = await self.add_message_to_db(self.scope['user'], self.room_name, message_content, reply_to=reply_to) # Send message to room group await self.channel_layer.group_send( self.room_group_name, @@ -47,11 +47,23 @@ class ChatConsumer(AsyncJsonWebsocketConsumer): 'message': message } ) + + @database_sync_to_async + def get_message_from_id(self, message_id): + if not message_id: + return None + message = None + try: + message = ChatMessage.objects.get(pk=message_id) + except ChatMessage.DoesNotExist: + print("does not exists") + pass + return message @database_sync_to_async - def add_message_to_db(self, user, room_name, message): - return ChatMessage.add_message(user, room_name, message) + def add_message_to_db(self, user, room_name, message, reply_to=None): + return ChatMessage.add_message(user, room_name, message, system=False, reply_to=reply_to) @database_sync_to_async def get_messages_list(self): -- 2.39.5