diff --git a/README.md b/README.md index 846825e..69e2f03 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,9 @@ pip install -r requirements.txt - Setup database ``` python manage.py runserver makemigrations profiles -python manage.py runserver makemigrations chat -python manage.py migrate +python manage.py migrate profiles ``` - Start the developpement server ``` python manage.py runserver 0.0.0.0:8000 ``` - -coc nvim -``` -pip install django-stubs -``` diff --git a/accounts/views/logged.py b/accounts/views/logged.py index 7deff05..8e2fecb 100644 --- a/accounts/views/logged.py +++ b/accounts/views/logged.py @@ -15,4 +15,4 @@ class LoggedView(APIView): def get(self, request: HttpRequest): if (request.user.is_authenticated): return Response({'id': request.user.pk}, status=status.HTTP_200_OK) - return Response('false', status=status.HTTP_200_OK) + return Response('false', status=status.HTTP_200_OK) \ No newline at end of file diff --git a/accounts/views/register.py b/accounts/views/register.py index 667ef2a..ee5724a 100644 --- a/accounts/views/register.py +++ b/accounts/views/register.py @@ -15,4 +15,4 @@ class RegisterView(APIView): if user: login(request, user) return Response("user created", status=status.HTTP_201_CREATED) - return Response(status=status.HTTP_400_BAD_REQUEST) + return Response(status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/chat/admin.py b/chat/admin.py index 8f38a1d..8c38f3f 100644 --- a/chat/admin.py +++ b/chat/admin.py @@ -1,6 +1,3 @@ from django.contrib import admin -from .models import ChannelModel, MemberModel, MessageModel -admin.site.register(ChannelModel) -admin.site.register(MemberModel) -admin.site.register(MessageModel) +# Register your models here. diff --git a/chat/consumers.py b/chat/consumers.py index d1c33d3..fb7bba5 100644 --- a/chat/consumers.py +++ b/chat/consumers.py @@ -1,24 +1,10 @@ import json from channels.generic.websocket import WebsocketConsumer from asgiref.sync import async_to_sync -from .models import MemberModel, MessageModel -import time class ChatConsumer(WebsocketConsumer): def connect(self): - channel_id : str = self.scope['path'].split('/')[3] - - self.room_group_name = 'chat' + channel_id - - user = self.scope["user"] - if (user.is_anonymous or not user.is_authenticated): - return - - if MemberModel.objects.filter(member_id=user.pk, channel_id=int(channel_id)).count() != 1: - return - - if (self.channel_layer == None): - return + self.room_group_name = 'test' async_to_sync(self.channel_layer.group_add)( self.room_group_name, @@ -28,58 +14,31 @@ class ChatConsumer(WebsocketConsumer): self.accept() - def receive(self, text_data=None, bytes_data=None): - if text_data == None: - return - + def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] - channel_id : int = int(self.scope['path'].split('/')[3]) user = self.scope["user"] - if (user.is_anonymous or not user.is_authenticated): - return + if user.is_anonymous: + return; - if MemberModel.objects.filter(member_id=user.pk, channel_id=channel_id).count() != 1: - return - - if (self.channel_layer == None): - return - - print(message) - - message_time : int = int(time.time() * 1000) async_to_sync(self.channel_layer.group_send)( self.room_group_name, { 'type':'chat_message', - 'author_id':user.pk, - 'content':message, - 'time':message_time, + 'username':user.username, + 'message':message } ) - - new_message = MessageModel() - new_message.channel_id = channel_id - new_message.author_id = user.pk - new_message.content = message - new_message.time = message_time - new_message.save() - def chat_message(self, event): - channel_id : int = int(self.scope['path'].split('/')[3]) user = self.scope["user"] - if (user.is_anonymous or not user.is_authenticated): - return - - if MemberModel.objects.filter(member_id=user.pk, channel_id=channel_id).count() != 1: - return + if user.is_anonymous: + return; self.send(text_data=json.dumps({ 'type':'chat', - 'author_id':event['author_id'], - 'content':event['content'], - 'time': event['time'], + 'username':event['username'], + 'message':event['message'] })) diff --git a/chat/models.py b/chat/models.py index 236c4ee..3479bc7 100644 --- a/chat/models.py +++ b/chat/models.py @@ -1,7 +1,6 @@ from django.db import models from django.db.models import IntegerField from django.contrib.auth.models import User -from django.contrib import admin # Create your models here. class ChannelModel(models.Model): @@ -11,14 +10,8 @@ class MemberModel(models.Model): member_id = IntegerField(primary_key=False) channel_id = IntegerField(primary_key=False) - def __str__(self): - return "member_id: " + str(self.member_id) + ", channel_id: " + str(self.channel_id) - class MessageModel(models.Model): channel_id = IntegerField(primary_key=False) author_id = IntegerField(primary_key=False) content = models.CharField(max_length=255) - time = IntegerField(primary_key=False) - - def __str__(self): - return "author_id: " + str(self.author_id) + ", channel_id: " + str(self.channel_id) + ", content: " + self.content + time = models.DateField() diff --git a/chat/routing.py b/chat/routing.py index c799d8a..5df8609 100644 --- a/chat/routing.py +++ b/chat/routing.py @@ -2,5 +2,5 @@ from django.urls import re_path from . import consumers websocket_urlpatterns = [ - re_path(r'ws/chat/(?P\d+)/$', consumers.ChatConsumer.as_asgi()) + re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi()) ] diff --git a/chat/urls.py b/chat/urls.py index f6a905e..f9300cf 100644 --- a/chat/urls.py +++ b/chat/urls.py @@ -6,5 +6,4 @@ from . import views urlpatterns = [ path("", views.ChatView.as_view(), name="chat_page"), - path("", views.ChatsView.as_view(), name="chats_page"), ] diff --git a/chat/views.py b/chat/views.py index 9e8a655..51dc909 100644 --- a/chat/views.py +++ b/chat/views.py @@ -1,100 +1,29 @@ from rest_framework.views import APIView from rest_framework.response import Response -from rest_framework import authentication, permissions, status +from rest_framework import authentication, permissions from rest_framework.authentication import SessionAuthentication from .models import ChannelModel, MemberModel, MessageModel -from django.core import serializers class ChatView(APIView): permission_classes = (permissions.IsAuthenticated,) authentication_classes = (SessionAuthentication,) - def get(self, request, pk): - if (ChannelModel.objects.filter(pk=pk)): - return Response({'channel_id': pk}) - else: - return Response("Channel doesn't exist") - - def delete(self, request, pk): - - ChannelModel.objects.filter(pk=pk).delete() - MessageModel.objects.filter(pk=pk).delete() - MemberModel.objects.filter(pk=pk).delete() - - return Response({'channel_id': pk}) - - """ def post(self, request, pk): - channel = ChannelModel.objects.filter(pk=pk) - message = request.data.get("message", []) - print(message) - if (message == []): - return Response('No message', status=status.HTTP_400_BAD_REQUEST) - - new_message = MessageModel() - new_message.channel_id = message["channel_id"] - new_message.author_id = message["author_id"] - new_message.content = message["content"] - new_message.time = message["time"] - new_message.save() - - messages = MessageModel.objects.filter(channel_id=pk) - messages = serializers.serialize("json", messages) - return Response({'messages':messages}, status=status.HTTP_200_OK) - """ - - -class ChatsView(APIView): - def post(self, request): + if (ChannelModel.objects.filter(pk = pk)): + return Response("Channel already exist") data: dict = request.data users_id = request.data.get("users_id", []) if len(users_id) < 2: - return Response('Not enought members to create the channel', status=status.HTTP_400_BAD_REQUEST) - if users_id[0] == users_id[1]: - return Response('Same member', status=status.HTTP_400_BAD_REQUEST) + return Response("Not enought members to create the channel") - for user_id1 in users_id: - for member1 in MemberModel.objects.filter(member_id=user_id1): - for user_id2 in users_id: - if user_id1 == user_id2: - continue - for member2 in MemberModel.objects.filter(member_id=user_id2): - if (member1.channel_id == member2.channel_id): - messages = MessageModel.objects.filter(channel_id=member1.channel_id) - messages = serializers.serialize("json", messages) - return Response({'channel_id': member1.channel_id, 'messages':messages}, status=status.HTTP_200_OK) - new_channel = ChannelModel() new_channel.save() for user_id in users_id: - new_member = MemberModel() new_member.channel_id = new_channel.pk new_member.member_id = user_id new_member.save() - return Response({'channel_id': new_channel.pk}, status=status.HTTP_201_CREATED) - - def delete(self, request): - - data: dict = request.data - users_id = request.data.get("users_id", []) - - #print(list(MemberModel.objects.all())) - - for user_id1 in users_id: - for member1 in MemberModel.objects.filter(member_id=user_id1): - for user_id2 in users_id: - if user_id1 == user_id2: - break - for member2 in MemberModel.objects.filter(member_id=user_id2): - if (member1.channel_id == member2.channel_id): - MessageModel.objects.filter(channel_id=member1.channel_id).delete() - member1.delete() - member2.delete() - ChannelModel.objects.get(pk=member1.channel_id).delete() - return Response("Channel removed", status=status.HTTP_200_OK) - - return Response("Channel doesn't exist", status=status.HTTP_404_NOT_FOUND) + return Response("Channel created") diff --git a/frontend/static/css/search.css b/frontend/static/css/search.css index 50cd3a1..21e3e8f 100644 --- a/frontend/static/css/search.css +++ b/frontend/static/css/search.css @@ -15,56 +15,3 @@ { margin: 10px 10px 0 0; } - -#app #chats { - overflow: hidden; - display: flex; - text-align: left; -} -#app #users { - margin-right: 50px; -} - -#app #chat { - position: relative; - height: 100%; - width: 60%; - /*border: 4px solid green;*/ - overflow:hidden; - /*overflow-y: scroll; - overflow-x: hidden;*/ -} - -#app #input_chat{ - position: sticky; - bottom: 0; - /*width: calc(100% - 8px);*/ - width: 100%; - border: none; - outline: none; - border-bottom: 2px solid green; - caret-color: green; -} - -#app #you { - text-align: left; - position: relative; - max-width: 48%; - left: 10px; - margin: 5px 0 0 0; - color: green; - - word-wrap: break-word; -} - -#app #other { - text-align: right; - position: relative; - max-width: 48%; - margin: 5px 0 0 auto; - right: 10px; - color: red; - - /* permet le retour à la ligne à la place de dépasser*/ - word-wrap: break-word; -} diff --git a/frontend/static/js/api/chat/channel.js b/frontend/static/js/api/chat/channel.js index 13c3db6..d7d31ce 100644 --- a/frontend/static/js/api/chat/channel.js +++ b/frontend/static/js/api/chat/channel.js @@ -1,77 +1,9 @@ -import {Message} from "./message.js" - class Channel { - constructor(client, channel_id, members_id, messages, reload) { - this.client = client; - this.channel_id = channel_id; - this.members_id = members_id; - this.messages = []; - if (messages != undefined) - this.updateMessages(messages); - - this.connect(reload); + constructor(id, members, messages) { + this.id = id; + this.members = members; + this.messages = messages; } - - // reload = function to use when we receive a message - async connect(reload) { - let url = `ws://${window.location.host}/ws/chat/${this.channel_id}/`; - - this.chatSocket = new WebSocket(url); - this.chatSocket.onmessage = (event) =>{ - let data = JSON.parse(event.data) - - this.messages.push(new Message( - this.channel_id, - data.author_id, - data.content, - data.time, - )); - - reload(); - }; - } - - async disconnect() { - this.chatSocket.close(); - } - - updateMessages(messages) { - messages = JSON.parse(messages); - let new_messages = []; - - messages.forEach((message) => { - message = message["fields"]; - new_messages.push(new Message( - message["channel_id"], - message["author_id"], - message["content"], - message["time"], - )); - }); - - //console.log(new_messages); - this.messages = new_messages; - return new_messages; - } - - async sendMessageChannel(message) { - - if (this.chatSocket == undefined) - return; - - this.chatSocket.send(JSON.stringify({ - 'message':message - })); - } - - async deleteChannel() { - let response = await this.client._delete("/api/chat/" + this.channel_id, { - }); - - let data = await response.json(); - return data; - } - } export {Channel} diff --git a/frontend/static/js/api/chat/channels.js b/frontend/static/js/api/chat/channels.js index afafba0..666d709 100644 --- a/frontend/static/js/api/chat/channels.js +++ b/frontend/static/js/api/chat/channels.js @@ -1,37 +1,19 @@ -import {Channel} from "./channel.js" -import {Message} from "./message.js" - class Channels { constructor(client) { this.client = client; } - async createChannel(users_id, reload) { + async createChannel(users_id) { + console.log(users_id); let response = await this.client._post("/api/chat/", { users_id:users_id }); let data = await response.json(); - let exit_code = await response.status; - if (exit_code >= 300) - return undefined; - - let messages = undefined; - if (exit_code == 200) - messages = data.messages; - return new Channel(this.client, data.channel_id, users_id, messages, reload); - } - - async deleteChannel(users_id) { - let response = await this.client._delete("/api/chat/", { - users_id:users_id - }); - - let data = await response.json(); - console.log(response.status) + if (data == "Channel already exist") + return null; return data; } - } export {Channels} diff --git a/frontend/static/js/api/chat/message.js b/frontend/static/js/api/chat/message.js deleted file mode 100644 index 4106512..0000000 --- a/frontend/static/js/api/chat/message.js +++ /dev/null @@ -1,10 +0,0 @@ -class Message { - constructor(channel_id, author_id, content, time) { - this.channel_id = channel_id; - this.author_id = author_id; - this.content = content; - this.time = time; - } -} - -export {Message} diff --git a/frontend/static/js/api/client.js b/frontend/static/js/api/client.js index b8d9700..90fc88e 100644 --- a/frontend/static/js/api/client.js +++ b/frontend/static/js/api/client.js @@ -1,7 +1,6 @@ import { Account } from "./account.js"; import { Profile } from "./profile.js"; import { Profiles } from "./profiles.js"; -import { Channels } from './chat/channels.js'; function getCookie(name) { @@ -21,9 +20,6 @@ class Client this.account = new Account(this); this.profiles = new Profiles(this); this._logged = undefined; - - this.channels = new Channels(this); - this.channel = undefined; } async isAuthentificate() diff --git a/frontend/static/js/views/Chat.js b/frontend/static/js/views/Chat.js index becd31f..c84e2c2 100644 --- a/frontend/static/js/views/Chat.js +++ b/frontend/static/js/views/Chat.js @@ -4,7 +4,7 @@ export default class extends AbstractView { constructor(params) { super(params, "Chat"); - let url = `ws://${window.location.host}/ws/chat/` + let url = `ws://${window.location.host}/ws/socket-server/` this.chatSocket = new WebSocket(url) this.chatSocket.onmessage = function(e){ diff --git a/frontend/static/js/views/Search.js b/frontend/static/js/views/Search.js index 828aa0c..883388f 100644 --- a/frontend/static/js/views/Search.js +++ b/frontend/static/js/views/Search.js @@ -1,6 +1,5 @@ import AbstractView from "./AbstractView.js"; import {client} from "../index.js"; -import {Message} from "../api/chat/message.js" export default class extends AbstractView { constructor(params) { @@ -9,20 +8,16 @@ export default class extends AbstractView { async postInit() { - let search = document.getElementById("input_user"); + let search = document.getElementById("form"); search.addEventListener("input", this.users) - let chat_input = document.getElementById("input_chat"); - //chat_input.addEventListener("keydown", this.chat_manager) - this.users(); - this.chat(); } async users() { - let search = document.getElementById("input_user").value.toLowerCase(); + let search = document.getElementById("form").value; let logged = await client.isAuthentificate(); @@ -30,7 +25,7 @@ export default class extends AbstractView { let list_users = document.getElementById('list_users'); list_users.innerHTML = ""; - users.filter(user => user.username.toLowerCase().startsWith(search) == true).forEach((user) => { + users.filter(user => user.username.startsWith(search) == true).forEach((user) => { var new_user = document.createElement("li"); // username @@ -43,41 +38,20 @@ export default class extends AbstractView { new_user.appendChild(document.createTextNode(" ")); // chat - if (logged && client.me.user_id != user.user_id) { - let add_chat = document.createElement("a"); - add_chat.addEventListener("click", async () => { - if (client.channel != undefined) { - client.channel.members_id.forEach((member_id) => { - if (member_id == user.user_id) - client.channel = undefined; - }); - - if (client.channel == undefined) - return this.hideChat(); - - client.channel.disconnect(); - } - - client.channel = await client.channels.createChannel([client.me.user_id , user.user_id], this.chat); - this.chat(); + if (logged) { + let chat = document.createElement("a"); + let array = [ + client.me.user_id, + user.user_id, + ]; + console.log(client.me.id); + chat.addEventListener("click", async function(){ + console.log("click"); + await client.channels.createChannel([client.me.user_id , user.user_id]); }); - add_chat.appendChild(document.createTextNode("Chat")); - new_user.appendChild(add_chat); - - /*new_user.appendChild(document.createTextNode(" ")); - - let remove = document.createElement("a"); - remove.addEventListener("click", async () => { - if (client.me.user_id != user.user_id) { - await client.channels.deleteChannel([client.me.user_id , user.user_id]); - if - client.channel.disconnect(); - client.channel = undefined; - this.chat() - } - }); - remove.appendChild(document.createTextNode("Remove")); - new_user.appendChild(remove);*/ + //chat.href = `/chat` + chat.appendChild(document.createTextNode("Chat")); + new_user.appendChild(chat); } // break line @@ -95,112 +69,15 @@ export default class extends AbstractView { } - async chat() { - - let logged = await client.isAuthentificate(); - let reload = document.getElementById("messages"); - if (reload != null) - reload.remove(); - - reload = document.getElementById("members"); - if (reload != null) - reload.remove(); - - if (client.channel == undefined || !logged) - return ; - - let chats = document.getElementById("chats"); - - if (document.getElementById("chat") == null) { - let chat = document.createElement("div"); - chat.id = "chat"; - chats.appendChild(chat); - } - - // div des messages - let messages = document.createElement("div"); - messages.id = "messages"; - if (document.getElementById("input_chat") == null) - chat.appendChild(messages); - else - document.getElementById("input_chat").before(messages); - - // Input pour rentrer un message - if (document.getElementById("input_chat") == null) { - let chat_input = document.createElement("input"); - chat_input.id="input_chat"; - chat_input.type="text"; - chat_input.name="message"; - chat_input.placeholder="message bozo"; - chat_input.maxLength=255; - chat.appendChild(chat_input); - - chat_input.addEventListener("keydown", async () => { - if (event.keyCode == 13 && client.channel != undefined) { - //let chat_input = document.getElementById("input_chat"); - let chat_text = chat_input.value; - - await client.channel.sendMessageChannel(chat_text) - - // Reset - chat_input.value = ""; - } - }); - } - - // nom des membres du chat - let users = await client.profiles.all(); - let members = document.createElement("h2"); - members.id = "members"; - let usernames = ""; - client.channel.members_id.forEach((member_id) => { - if (member_id != client.me.user_id) { - if (usernames.length > 0) - usernames += ", "; - usernames += (users.filter(user => user.user_id == member_id)[0].username); - } - }); - members.appendChild(document.createTextNode(usernames)); - messages.before(members); - - // les messages - client.channel.messages.forEach((message) => { - let text = document.createElement("p"); - text.appendChild(document.createTextNode(message.content)); - if (message.author_id == client.me.user_id) - text.id = "you"; - else - text.id = "other"; - - messages.appendChild(text); - }); - - } - - async hideChat() { - - let close = document.getElementById("chat"); - if (close != null) - close.remove(); - - } - - async leavePage() { - if (client.channel != undefined) - client.channel.disconnect(); - client.channel = undefined - } - async getHtml() { return ` -
-
- -
    -
-
+ + +
+
    +
`;