Manage private chats
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
c6b9a84def
commit
d6aa5eb0cc
|
@ -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])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue