mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 03:02:14 +01:00 
			
		
		
		
	Manage private chats
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -37,6 +37,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
        channels = await Channel.get_accessible_channels(user, 'read')
 | 
					        channels = await Channel.get_accessible_channels(user, 'read')
 | 
				
			||||||
        async for channel in channels.all():
 | 
					        async for channel in channels.all():
 | 
				
			||||||
            await self.channel_layer.group_add(f"chat-{channel.id}", self.channel_name)
 | 
					            await self.channel_layer.group_add(f"chat-{channel.id}", self.channel_name)
 | 
				
			||||||
 | 
					        await self.channel_layer.group_add(f"user-{user.id}", self.channel_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def disconnect(self, close_code) -> None:
 | 
					    async def disconnect(self, close_code) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -50,6 +51,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
        channels = await Channel.get_accessible_channels(self.scope['user'], 'read')
 | 
					        channels = await Channel.get_accessible_channels(self.scope['user'], 'read')
 | 
				
			||||||
        async for channel in channels.all():
 | 
					        async for channel in channels.all():
 | 
				
			||||||
            await self.channel_layer.group_discard(f"chat-{channel.id}", self.channel_name)
 | 
					            await self.channel_layer.group_discard(f"chat-{channel.id}", self.channel_name)
 | 
				
			||||||
 | 
					        await self.channel_layer.group_discard(f"user-{self.scope['user'].id}", self.channel_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def receive_json(self, content, **kwargs):
 | 
					    async def receive_json(self, content, **kwargs):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -63,6 +65,8 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
                await self.receive_message(content)
 | 
					                await self.receive_message(content)
 | 
				
			||||||
            case 'fetch_messages':
 | 
					            case 'fetch_messages':
 | 
				
			||||||
                await self.fetch_messages(**content)
 | 
					                await self.fetch_messages(**content)
 | 
				
			||||||
 | 
					            case 'start_private_chat':
 | 
				
			||||||
 | 
					                await self.start_private_chat(content['user_id'])
 | 
				
			||||||
            case unknown:
 | 
					            case unknown:
 | 
				
			||||||
                print("Unknown message type:", unknown)
 | 
					                print("Unknown message type:", unknown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,12 +80,12 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            'channels': [
 | 
					            'channels': [
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    'id': channel.id,
 | 
					                    'id': channel.id,
 | 
				
			||||||
                    'name': channel.name,
 | 
					                    'name': channel.get_visible_name(user),
 | 
				
			||||||
                    'category': channel.category,
 | 
					                    'category': channel.category,
 | 
				
			||||||
                    'read_access': True,
 | 
					                    'read_access': True,
 | 
				
			||||||
                    'write_access': await write_channels.acontains(channel),
 | 
					                    'write_access': await write_channels.acontains(channel),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                async for channel in read_channels.all()
 | 
					                async for channel in read_channels.prefetch_related('invited').all()
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        await self.send_json(message)
 | 
					        await self.send_json(message)
 | 
				
			||||||
@@ -105,6 +109,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            'id': message.id,
 | 
					            'id': message.id,
 | 
				
			||||||
            'channel_id': channel.id,
 | 
					            'channel_id': channel.id,
 | 
				
			||||||
            'timestamp': message.created_at.isoformat(),
 | 
					            'timestamp': message.created_at.isoformat(),
 | 
				
			||||||
 | 
					            'author_id': message.author_id,
 | 
				
			||||||
            'author': await message.aget_author_name(),
 | 
					            'author': await message.aget_author_name(),
 | 
				
			||||||
            'content': message.content,
 | 
					            'content': message.content,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
@@ -125,6 +130,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    'id': message.id,
 | 
					                    'id': message.id,
 | 
				
			||||||
                    'timestamp': message.created_at.isoformat(),
 | 
					                    'timestamp': message.created_at.isoformat(),
 | 
				
			||||||
 | 
					                    'author_id': message.author_id,
 | 
				
			||||||
                    'author': await message.aget_author_name(),
 | 
					                    'author': await message.aget_author_name(),
 | 
				
			||||||
                    'content': message.content,
 | 
					                    'content': message.content,
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -132,7 +138,50 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
            ]))
 | 
					            ]))
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def start_private_chat(self, user_id: int) -> 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)
 | 
				
			||||||
 | 
					        if not await channel_qs.aexists():
 | 
				
			||||||
 | 
					            channel = await Channel.objects.acreate(
 | 
				
			||||||
 | 
					                name=f"{user.first_name} {user.last_name}, {other_user.first_name} {other_user.last_name}",
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.PRIVATE,
 | 
				
			||||||
 | 
					                private=True,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            await channel.invited.aset([user, other_user])
 | 
				
			||||||
 | 
					            await channel.asave()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await self.channel_layer.group_add(f"chat-{channel.id}", self.channel_name)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            channel = await channel_qs.afirst()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await self.channel_layer.group_send(f"user-{user.id}", {
 | 
				
			||||||
 | 
					            'type': 'chat.start_private_chat',
 | 
				
			||||||
 | 
					            'channel': {
 | 
				
			||||||
 | 
					                'id': channel.id,
 | 
				
			||||||
 | 
					                'name': f"{other_user.first_name} {other_user.last_name}",
 | 
				
			||||||
 | 
					                'category': channel.category,
 | 
				
			||||||
 | 
					                'read_access': True,
 | 
				
			||||||
 | 
					                'write_access': True,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        if user != other_user:
 | 
				
			||||||
 | 
					            await self.channel_layer.group_send(f"user-{other_user.id}", {
 | 
				
			||||||
 | 
					                'type': 'chat.start_private_chat',
 | 
				
			||||||
 | 
					                'channel': {
 | 
				
			||||||
 | 
					                    'id': channel.id,
 | 
				
			||||||
 | 
					                    'name': f"{user.first_name} {user.last_name}",
 | 
				
			||||||
 | 
					                    'category': channel.category,
 | 
				
			||||||
 | 
					                    'read_access': True,
 | 
				
			||||||
 | 
					                    'write_access': True,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def chat_send_message(self, message) -> None:
 | 
					    async def chat_send_message(self, message) -> None:
 | 
				
			||||||
        await self.send_json({'type': 'send_message', 'id': message['id'], 'channel_id': message['channel_id'],
 | 
					        await self.send_json({'type': 'send_message', 'id': message['id'], 'channel_id': message['channel_id'],
 | 
				
			||||||
                              'timestamp': message['timestamp'], 'author': message['author'],
 | 
					                              'timestamp': message['timestamp'], 'author': message['author'],
 | 
				
			||||||
                              'content': message['content']})
 | 
					                              'content': message['content']})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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']})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,6 +91,13 @@ class Channel(models.Model):
 | 
				
			|||||||
                    "in addition to the permitted group of the channel."),
 | 
					                    "in addition to the permitted group of the channel."),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_visible_name(self, user: User) -> str:
 | 
				
			||||||
 | 
					        if self.private:
 | 
				
			||||||
 | 
					            users = [f"{u.first_name} {u.last_name}" for u in self.invited.all() if u != user] \
 | 
				
			||||||
 | 
					                    or [f"{user.first_name} {user.last_name}"]
 | 
				
			||||||
 | 
					            return ", ".join(users)
 | 
				
			||||||
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return str(format_lazy(_("Channel {name}"), name=self.name))
 | 
					        return str(format_lazy(_("Channel {name}"), name=self.name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,7 +113,7 @@ class Channel(models.Model):
 | 
				
			|||||||
        registration = await Registration.objects.prefetch_related('user').aget(user_id=user.id)
 | 
					        registration = await Registration.objects.prefetch_related('user').aget(user_id=user.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if registration.is_admin:
 | 
					        if registration.is_admin:
 | 
				
			||||||
            return Channel.objects.all()
 | 
					            return Channel.objects.prefetch_related('invited').exclude(~Q(invited=user) & Q(private=True)).all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if registration.is_volunteer:
 | 
					        if registration.is_volunteer:
 | 
				
			||||||
            registration = await VolunteerRegistration.objects \
 | 
					            registration = await VolunteerRegistration.objects \
 | 
				
			||||||
@@ -153,7 +160,7 @@ class Channel(models.Model):
 | 
				
			|||||||
            qs |= Channel.objects.filter(Q(team=team),
 | 
					            qs |= Channel.objects.filter(Q(team=team),
 | 
				
			||||||
                                         **{permission_type: PermissionType.TEAM_MEMBER})
 | 
					                                         **{permission_type: PermissionType.TEAM_MEMBER})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        qs |= Channel.objects.filter(invited=user)
 | 
					        qs |= Channel.objects.filter(invited=user).prefetch_related('invited')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return qs
 | 
					        return qs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,8 +95,13 @@ function setChannels(new_channels) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (new_channels && (!selected_channel_id || !channels[selected_channel_id])) {
 | 
					    if (new_channels && (!selected_channel_id || !channels[selected_channel_id])) {
 | 
				
			||||||
        if (window.location.hash)
 | 
					        if (window.location.hash) {
 | 
				
			||||||
            selectChannel(window.location.hash.substring(9))
 | 
					            let channel_id = parseInt(window.location.hash.substring(9))
 | 
				
			||||||
 | 
					            if (channels[channel_id])
 | 
				
			||||||
 | 
					                selectChannel(channel_id)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                selectChannel(Object.keys(channels)[0])
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            selectChannel(Object.keys(channels)[0])
 | 
					            selectChannel(Object.keys(channels)[0])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user