1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-06-22 21:18:23 +02:00

Setup chat UI

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello
2024-04-27 12:08:10 +02:00
parent 46fc5f39c8
commit f3a4a99b78
5 changed files with 161 additions and 45 deletions

View File

@ -4,6 +4,9 @@
await Notification.requestPermission()
})()
let channels = {}
let selected_channel_id = null
/**
* Display a new notification with the given title and the given body.
* @param title The title of the notification
@ -18,6 +21,33 @@ function showNotification(title, body, timeout = 5000) {
return notif
}
function selectChannel(channel_id) {
let channel = channels[channel_id]
if (!channel) {
console.error('Channel not found:', channel_id)
return
}
selected_channel_id = channel_id
let channelTitle = document.getElementById('channel-title')
channelTitle.innerText = channel['name']
let messageInput = document.getElementById('input-message')
messageInput.disabled = !channel['write_access']
}
function setChannels(new_channels) {
channels = {}
for (let channel of new_channels) {
channels[channel['id']] = channel
}
if (new_channels && (!selected_channel_id || !channels[selected_channel_id])) {
selectChannel(Object.keys(channels)[0])
}
}
document.addEventListener('DOMContentLoaded', () => {
/**
* Process the received data from the server.
@ -25,7 +55,15 @@ document.addEventListener('DOMContentLoaded', () => {
*/
function processMessage(data) {
// TODO Implement chat protocol
console.log(data)
switch (data['type']) {
case 'fetch_channels':
setChannels(data['channels'])
break
default:
console.log(data)
console.error('Unknown message type:', data['type'])
break
}
}
function setupSocket(nextDelay = 1000) {

View File

@ -4,6 +4,64 @@
{% load i18n %}
{% block content %}
<noscript>
{% trans "JavaScript must be enabled on your browser to access chat." %}
</noscript>
<div class="offcanvas offcanvas-start" tabindex="-1" id="channelSelector" aria-labelledby="offcanvasExampleLabel">
<div class="offcanvas-header">
<h4 class="offcanvas-title" id="offcanvasExampleLabel">{% trans "Chat channels" %}</h4>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<ul class="list-group list-group-flush" id="nav-channels-tab">
{% for channel in channels %}
<li class="list-group-item" id="tab-channel-{{ channel.id }}" data-bs-dismiss="offcanvas"
onclick="selectChannel({{ channel.id }})">
<button class="nav-link">{{ channel.name }}</button>
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="card tab-content w-100 mh-100" style="height: 95vh" id="nav-channels-content">
<div class="card-header">
<h3>
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#channelSelector"
aria-controls="channelSelector" aria-expanded="false" aria-label="Toggle channel selector">
<span class="navbar-toggler-icon"></span>
</button>
<span id="channel-title"></span>
</h3>
</div>
<div class="card-body overflow-y-scroll mw-100 h-100 flex-grow-0" id="chat-messages">
<ul class="list-group list-group-flush">
<li class="list-group-item">
<div class="fw-bold">Emmy D'Anello (CNO)</div>
Message 1
</li>
<li class="list-group-item">
<div class="fw-bold">Emmy D'Anello (CNO)</div>
Message 2
</li>
<li class="list-group-item">
<div class="fw-bold">Emmy D'Anello (CNO)</div>
Message 3
</li>
</ul>
</div>
<div class="card-footer mt-auto">
<div class="input-group">
<label for="input-message" class="input-group-text">
<i class="fas fa-comment"></i>
</label>
<input type="text" class="form-control" id="input-message" placeholder="{% trans "Send message" %}" autocomplete="off">
<button class="input-group-text btn btn-success">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
{% endblock %}
{% block extrajavascript %}

View File

@ -4,6 +4,8 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView
from chat.models import Channel
class ChatView(LoginRequiredMixin, TemplateView):
"""
@ -11,3 +13,9 @@ class ChatView(LoginRequiredMixin, TemplateView):
with Javascript and websockets.
"""
template_name = "chat/chat.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
from asgiref.sync import async_to_sync
context['channels'] = async_to_sync(Channel.get_accessible_channels)(self.request.user, 'read')
return context