This commit is contained in:
Xamora 2024-05-14 03:30:42 +02:00
parent c91ca959f6
commit 3f1a396975
10 changed files with 161 additions and 35 deletions

View File

@ -30,3 +30,11 @@ class ChatMessageModel(models.Model):
def __str__(self): def __str__(self):
return "author_id: " + str(self.author_id) + ", channel_id: " + str(self.channel_id) + ", content: " + self.content return "author_id: " + str(self.author_id) + ", channel_id: " + str(self.channel_id) + ", content: " + self.content
class AskModel(models.Model):
asker_id = IntegerField(primary_key=False)
asked_id = IntegerField(primary_key=False)
# return if the asker ask the asked to play a game
def is_asked(self, asker_id, asked_id):
return AskModel.objects.get(asker_id=asker_id, asked_id=asked_id) != None

10
chat/serializers/ask.py Normal file
View File

@ -0,0 +1,10 @@
from rest_framework import serializers
from django.utils.translation import gettext as _
from profiles.models import ProfileModel
from ..models import ChatChannelModel, ChatMessageModel
class AskSerializer(serializers.ModelSerializer):
members_id = serializers.ListField(child=serializers.IntegerField())

View File

@ -3,8 +3,7 @@ from rest_framework import serializers
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from profiles.models import ProfileModel from profiles.models import ProfileModel
from .models import ChatChannelModel, ChatMessageModel from ..models import ChatChannelModel, ChatMessageModel
class ChatChannelSerializer(serializers.ModelSerializer): class ChatChannelSerializer(serializers.ModelSerializer):

View File

@ -2,8 +2,11 @@ from django.urls import path
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from . import views from .views import chat
from .views import ask
urlpatterns = [ urlpatterns = [
path("", views.ChannelView.as_view(), name="chats_page"), path("", chat.ChannelView.as_view(), name="chats_page"),
path("ask/", ask.AskView.as_view(), name="chats_ask"),
path("ask/accept", ask.AskAccepteView.as_view(), name="chats_ask_accept"),
] ]

78
chat/views/ask.py Normal file
View File

@ -0,0 +1,78 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions, status
from rest_framework.authentication import SessionAuthentication
from django.http import HttpRequest
from django.contrib.auth import login
from django.db.models import QuerySet
from django.core import serializers
from chat.models import AskModel
from profiles.models import ProfileModel
from ..serializers.ask import AskSerializer
from notice.consumers import notice_manager
from django.contrib.auth.models import User
class AskView(APIView):
serializer_class = AskSerializer
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
def post(self, request):
data : dict = request.data
if (data["asked"] == None):
return
asker_id = request.user.pk
asked_id = data["asked"]
if AskModel().is_asked(asker_id, asked_id):
return Response(status=status.HTTP_208_ALREADY_REPORTED)
AskModel(asker_id=asker_id, asked_id=asked_id).save()
return Response(status=status.HTTP_201_CREATED)
def delete(self, request):
data : dict = request.data
if (data["asker"] == None):
return
asker_id = data["asker"]
asked_id = request.user.pk
if not AskModel().is_asked(asker_id, asked_id):
return Response(status=status.HTTP_404_NOT_FOUND)
asker = User.objects.filter(pk=asked_id)[0]
notice_manager.refuse_game(request.user, asker)
AskModel(asker_id=asker_id, asked_id=asked_id).delete()
return Response(status=status.HTTP_200_OK)
class AskAccepteView(APIView):
serializer_class = AskSerializer
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
def post(self, request):
data : dict = request.data
if (data["asker"] == None):
return
asker_id = data["asker"]
asked_id = request.user.pk
if not AskModel().is_asked(asker_id, asked_id):
return Response(status=status.HTTP_404_NOT_FOUND)
notice_manager.accept_game(asker=User.objects.filter(pk=asker_id)[0], asked=User.objects.filter(pk=asked_id)[0])
AskModel(asker_id=asker_id, asked_id=asked_id).delete()
return Response(status=status.HTTP_200_OK)

View File

@ -9,8 +9,8 @@ from django.db.models import QuerySet
from django.core import serializers from django.core import serializers
from .models import ChatChannelModel, ChatMemberModel, ChatMessageModel from ..models import ChatChannelModel, ChatMemberModel, ChatMessageModel
from .serializers import ChatChannelSerializer, ChatMessageSerializer from ..serializers.chat import ChatChannelSerializer, ChatMessageSerializer
class ChannelView(APIView): class ChannelView(APIView):

View File

@ -2,6 +2,7 @@ import {Client} from './Client.js';
import {createNotification} from '../utils/noticeUtils.js' import {createNotification} from '../utils/noticeUtils.js'
import { lastView } from '../index.js'; import { lastView } from '../index.js';
import ProfilePageView from '../views/ProfilePageView.js'; import ProfilePageView from '../views/ProfilePageView.js';
import Search from '../views/Search.js';
export default class Notice { export default class Notice {
@ -22,7 +23,7 @@ export default class Notice {
this._socket.onclose = _ => this._socket = undefined; this._socket.onclose = _ => this._socket = undefined;
this._socket.onmessage = message => { this._socket.onmessage = message => {
const data = JSON.parse(message.data); const data = JSON.parse(message.data);
console.log(data) //console.log(data)
if (data.type === 'friend_request') { if (data.type === 'friend_request') {
this.friend_request(data.author); this.friend_request(data.author);
@ -52,6 +53,9 @@ export default class Notice {
lastView.profile.online = status; lastView.profile.online = status;
lastView.loadFriendshipStatus(); lastView.loadFriendshipStatus();
} }
else if (lastView instanceof Search) {
lastView.display_specific_user(user.id);
}
} }
online(user) { online(user) {

View File

@ -18,8 +18,6 @@ export default class extends AbstractView {
const games = await this.profile.getGameHistory(); const games = await this.profile.getGameHistory();
console.log(games)
await this.fillHistory(games); await this.fillHistory(games);
await this.fillStatistics(games); await this.fillStatistics(games);
@ -80,10 +78,10 @@ export default class extends AbstractView {
*/ */
async fillStatistics(games) async fillStatistics(games)
{ {
const winrateDiv = document.getElementById("winrate"); let winrateDiv = document.getElementById("winrate");
const win = 0; let win = 0;
const lose = 0; let lose = 0;
games.forEach(game => { games.forEach(game => {
if (game.finished === false) if (game.finished === false)
@ -100,7 +98,7 @@ export default class extends AbstractView {
async fillHistory(games) async fillHistory(games)
{ {
const game_list = document.getElementById("game-list"); let game_list = document.getElementById("game-list");
games.forEach(game => { games.forEach(game => {

View File

@ -9,30 +9,30 @@ export default class extends AbstractView {
async postInit() { async postInit() {
let logged = await client.isAuthenticated(); this.logged = await client.isAuthenticated();
let profiles = await client.profiles.all(); this.profiles = await client.profiles.all();
let search = document.getElementById("input_user"); let search = document.getElementById("input_user");
if (search != undefined) if (search != undefined)
search.oninput = () => this.display_users(logged, profiles); search.oninput = () => this.display_users();
let chat_input = document.getElementById("input_chat"); let chat_input = document.getElementById("input_chat");
this.last_add_chat = undefined; this.last_add_chat = undefined;
this.display_users(logged, profiles); this.display_users();
this.display_chat(logged, profiles); this.display_chat();
} }
async display_users(logged, profiles) { async display_users() {
let search = document.getElementById("input_user").value.toLowerCase(); let search = document.getElementById("input_user").value.toLowerCase();
let list_users = document.getElementById('list_users'); let list_users = document.getElementById('list_users');
list_users.innerHTML = ""; list_users.innerHTML = "";
profiles.filter(user => user.username.toLowerCase().startsWith(search) == true).forEach(async (user) => { this.profiles.filter(user => user.username.toLowerCase().startsWith(search) == true).forEach(async (user) => {
if (user.id == null) { if (user.id == null) {
console.log("list User one with id null;"); console.log("list User one with id null;");
@ -46,14 +46,14 @@ export default class extends AbstractView {
username.setAttribute('data-link', ''); username.setAttribute('data-link', '');
username.id = `username${user.id}`; username.id = `username${user.id}`;
username.href = `/profiles/${user.username}`; username.href = `/profiles/${user.username}`;
if (logged && user.id == client.me.id) if (this.logged && user.id == client.me.id)
username.style.color = "green"; username.style.color = "green";
else { else {
let profile = await client.profiles.getProfileId(user.id); let profile = await client.profiles.getProfileId(user.id);
let online = profile.online; let online = profile.online;
if (online == undefined) if (online == undefined)
username.style.color = "gray"; username.style.color = "gray";
if (online == true) else if (online == true)
username.style.color = "green"; username.style.color = "green";
else else
username.style.color = "red"; username.style.color = "red";
@ -65,7 +65,7 @@ export default class extends AbstractView {
new_user.appendChild(document.createTextNode(" ")); new_user.appendChild(document.createTextNode(" "));
// button chat // button chat
if (logged && client.me.id != user.id) { if (this.logged && client.me.id != user.id) {
let add_chat = document.createElement("a"); let add_chat = document.createElement("a");
add_chat.id = "add_chat_off"; add_chat.id = "add_chat_off";
add_chat.onclick = async () => { add_chat.onclick = async () => {
@ -86,7 +86,7 @@ export default class extends AbstractView {
await client.channels.channel.disconnect(); await client.channels.channel.disconnect();
} }
client.channels.channel = await client.channels.createChannel([client.me.id , user.id], () => this.reload_display_messages()); client.channels.channel = await client.channels.createChannel([client.me.id , user.id], () => this.reload_display_messages());
this.display_chat(logged, profiles); this.display_chat();
if (this.last_add_chat != undefined) if (this.last_add_chat != undefined)
this.last_add_chat.id = "add_chat_off"; this.last_add_chat.id = "add_chat_off";
this.last_add_chat = add_chat; this.last_add_chat = add_chat;
@ -113,7 +113,27 @@ export default class extends AbstractView {
} }
async display_chat(logged, profiles) async display_specific_user(id) {
let user = document.getElementById("username" + id);
if (user == undefined)
return ;
if (this.logged && id == client.me.id)
user.style.color = "green";
else {
let profile = await client.profiles.getProfileId(id);
let online = profile.online;
if (online == undefined)
user.style.color = "gray";
else if (online == true)
user.style.color = "green";
else
user.style.color = "red";
}
}
async display_chat()
{ {
let reloads = ["members", "messages"]; let reloads = ["members", "messages"];
reloads.forEach(reload => { reloads.forEach(reload => {
@ -121,7 +141,7 @@ export default class extends AbstractView {
document.getElementById(reload).remove(); document.getElementById(reload).remove();
}); });
if (client.channels.channel === undefined || logged === false) if (client.channels.channel === undefined || this.logged === false)
return ; return ;
let chats = document.getElementById("chats"); let chats = document.getElementById("chats");
@ -133,7 +153,7 @@ export default class extends AbstractView {
} }
// nom des membres du channel // nom des membres du channel
let members = await this.display_members(chat, profiles); let members = await this.display_members(chat);
// L'affiche des messages // L'affiche des messages
let messages = await this.display_messages(chat); let messages = await this.display_messages(chat);
@ -157,7 +177,7 @@ export default class extends AbstractView {
let receivers_id = []; let receivers_id = [];
members_id.forEach((member_id) => { members_id.forEach((member_id) => {
if (member_id != client.me.id) if (member_id != client.me.id)
receivers_id.push(profiles.filter(user => user.id == member_id)[0].id); receivers_id.push(this.profiles.filter(user => user.id == member_id)[0].id);
}); });
await client.channels.channel.sendMessageChannel(chat_text, receivers_id); await client.channels.channel.sendMessageChannel(chat_text, receivers_id);
// Reset // Reset
@ -215,7 +235,7 @@ export default class extends AbstractView {
messages.scrollTop = messages.scrollHeight; messages.scrollTop = messages.scrollHeight;
} }
async display_members(chat, profiles) { async display_members(chat) {
let members_id = client.channels.channel.members_id; let members_id = client.channels.channel.members_id;
@ -226,7 +246,7 @@ export default class extends AbstractView {
if (member_id != client.me.id) { if (member_id != client.me.id) {
if (usernames.length > 0) if (usernames.length > 0)
usernames += ", "; usernames += ", ";
usernames += (profiles.filter(user => user.id == member_id)[0].username); usernames += (this.profiles.filter(user => user.id == member_id)[0].username);
} }
}); });
members.textContent = usernames; members.textContent = usernames;
@ -251,11 +271,6 @@ export default class extends AbstractView {
let no = document.getElementById("no") || document.createElement("button"); let no = document.getElementById("no") || document.createElement("button");
let invitedBy; let invitedBy;
for (let x in others) {
if (client.notice.data.invited.includes(others[x])) {
invitedBy = others[x];
}
}
if (invitedBy == undefined) { if (invitedBy == undefined) {

View File

@ -65,6 +65,17 @@ class NoticeManager:
def notify_friend_removed(self, user: User, friend: ProfileModel): def notify_friend_removed(self, user: User, friend: ProfileModel):
self.notify_user(user, {'type': 'friend_removed', 'friend': ProfileSerializer(friend).data}) self.notify_user(user, {'type': 'friend_removed', 'friend': ProfileSerializer(friend).data})
def ask_game(self, asker:User, asked: User):
self.notify_user(asker, {'type': 'game_asked', 'asker': ProfileSerializer(asked).data})
def ask_game_canceled(self, asker:User, asked: User):
self.notify_user(asker, {'type': 'game_canceled', 'asker': ProfileSerializer(asked).data})
def refuse_game(self, asked: User, asker: User):
self.notify_user(asked, {'type': 'game_refused', 'asker': ProfileSerializer(asker).data})
def accept_game(self, asked: User, asker: User):
self.notify_user(asked, {'type': 'game_accepted', 'asker': ProfileSerializer(asker).data})
notice_manager = NoticeManager() notice_manager = NoticeManager()