notice but without the t

This commit is contained in:
AdrienLSH 2024-04-25 15:45:32 +02:00
parent dbb8e07d7d
commit 5f58b65a34
29 changed files with 258 additions and 371 deletions

View File

@ -4,7 +4,7 @@ import { Profiles } from "./Profiles.js";
import { Channels } from './chat/Channels.js'; import { Channels } from './chat/Channels.js';
import { MyProfile } from "./MyProfile.js"; import { MyProfile } from "./MyProfile.js";
import { Tourmanents } from "./tournament/Tournaments.js"; import { Tourmanents } from "./tournament/Tournaments.js";
import { Notice } from "./chat/Notice.js"; import Notice from "./notice/Notice.js";
import { Channel } from "./chat/Channel.js"; import { Channel } from "./chat/Channel.js";
import LanguageManager from './LanguageManager.js'; import LanguageManager from './LanguageManager.js';
@ -83,7 +83,7 @@ class Client
{ {
if (this._logged == undefined) if (this._logged == undefined)
this._logged = await this._test_logged(); this._logged = await this._test_logged();
return this._logged; return this._logged;
} }
/** /**
@ -217,7 +217,7 @@ class Client
{ {
this.me = new MyProfile(this); this.me = new MyProfile(this);
await this.me.init(); await this.me.init();
this.notice.connect(); this.notice.start();
document.getElementById('navbarLoggedOut').classList.add('d-none'); document.getElementById('navbarLoggedOut').classList.add('d-none');
document.getElementById('navbarLoggedIn').classList.remove('d-none'); document.getElementById('navbarLoggedIn').classList.remove('d-none');
document.getElementById('navbarDropdownButton').innerHTML = this.me.username; document.getElementById('navbarDropdownButton').innerHTML = this.me.username;
@ -226,7 +226,7 @@ class Client
else else
{ {
this.me = undefined; this.me = undefined;
this.notice.disconnect(); this.notice.stop();
document.getElementById('navbarLoggedOut').classList.remove('d-none'); document.getElementById('navbarLoggedOut').classList.remove('d-none');
document.getElementById('navbarLoggedIn').classList.add('d-none'); document.getElementById('navbarLoggedIn').classList.add('d-none');
document.getElementById('navbarDropdownButton').innerHTML = 'Me'; document.getElementById('navbarDropdownButton').innerHTML = 'Me';

View File

@ -40,26 +40,26 @@ class MyProfile extends Profile
async getBlockedUsers() { async getBlockedUsers() {
const response = await this.client._get('/api/profiles/block'); const response = await this.client._get('/api/profiles/block');
const data = await response.json(); const data = await response.json();
data.forEach(profileData => this.blockedUsers.push(new Profile(this.client, profileData.username, profileData.user_id, profileData.avatar))); data.forEach(profileData => this.blockedUsers.push(new Profile(this.client, profileData.username, profileData.id, profileData.avatar)));
} }
async getFriends() { async getFriends() {
const response = await this.client._get('/api/profiles/friends'); const response = await this.client._get('/api/profiles/friends');
const data = await response.json(); const data = await response.json();
data.forEach(profileData => this.friendList.push(new Profile(this.client, profileData.username, profileData.user_id, profileData.avatar))); data.forEach(profileData => this.friendList.push(new Profile(this.client, profileData.username, profileData.id, profileData.avatar)));
} }
async getIncomingFriendRequests() { async getIncomingFriendRequests() {
const response = await this.client._get('/api/profiles/incoming_friend_requests'); const response = await this.client._get('/api/profiles/incoming_friend_requests');
const data = await response.json(); const data = await response.json();
data.forEach(profileData => this.incomingFriendRequests.push( data.forEach(profileData => this.incomingFriendRequests.push(
new Profile(this.client, profileData.username, profileData.user_id, profileData.avatar) new Profile(this.client, profileData.username, profileData.id, profileData.avatar)
)); ));
} }
async getOutgoingFriendRequests() { async getOutgoingFriendRequests() {
const response = await this.client._get('/api/profiles/outgoing_friend_requests'); const response = await this.client._get('/api/profiles/outgoing_friend_requests');
const data = await response.json(); const data = await response.json();
data.forEach(profileData => this.outgoingFriendRequests.push( data.forEach(profileData => this.outgoingFriendRequests.push(
new Profile(this.client, profileData.username, profileData.user_id, profileData.avatar) new Profile(this.client, profileData.username, profileData.id, profileData.avatar)
)); ));
} }

View File

@ -55,17 +55,17 @@ export class Profile extends AExchangeable
return response.status; return response.status;
let response_data = await response.json(); let response_data = await response.json();
this.id = response_data.user_id; this.id = response_data.id;
this.username = response_data.username; this.username = response_data.username;
this.avatar = response_data.avatar; this.avatar = response_data.avatar;
if (!this.client.me || this.client.me.id === this.id) if (!this.client.me || this.client.me.id === this.id)
return; return;
this.isFriend = this.client.me._isFriend(this);
this.isBlocked = this.client.me._isBlocked(this); this.isBlocked = this.client.me._isBlocked(this);
this.hasIncomingRequest = this.client.me._hasIncomingRequestFrom(this); this.hasIncomingRequest = this.client.me._hasIncomingRequestFrom(this);
this.hasOutgoingRequest = this.client.me._hasOutgoingRequestTo(this); this.hasOutgoingRequest = this.client.me._hasOutgoingRequestTo(this);
this.isFriend = this.client.me._isFriend(this);
} }
/** /**

View File

@ -24,7 +24,7 @@ class Profiles
let profiles = []; let profiles = [];
response_data.forEach((profile) => { response_data.forEach((profile) => {
profiles.push(new Profile(this.client, profile.username, profile.user_id, profile.avatar)); profiles.push(new Profile(this.client, profile.username, profile.id, profile.avatar));
}); });
return profiles; return profiles;
} }

View File

@ -1,308 +0,0 @@
import { navigateTo } from "../../index.js";
import {createNotification} from "../../utils/noticeUtils.js";
class Notice {
constructor(client) {
this.client = client;
this.data = {};
// users online, invited by ..., asked by ..., asker to ...
let data_variable = ["online", "invited", "asked", "asker"];
for (let i in data_variable)
this.data[data_variable[i]] = [];
//this.connect();
}
async connect() {
return
let url = `${window.location.protocol[4] === 's' ? 'wss' : 'ws'}://${window.location.host}/ws/chat/notice`;
this.chatSocket = new WebSocket(url);
this.chatSocket.onmessage = (event) =>{
let send = JSON.parse(event.data);
//console.log("notice: ", send);
try {
this["receive_" + send.type](send);
}
catch (error) {
console.log("receive_" + send.type + ": Function not found");
}
};
this.chatSocket.onopen = (event) => {
this.getOnlineUser();
this.ask_friend();
};
}
async disconnect() {
if (this.chatSocket == undefined)
return ;
this.chatSocket.close();
}
async reconnect() {
this.disconnect();
this.connect();
}
async accept_invite(invitedBy) {
this.sendRequest({
type: "accept_invite",
targets: [invitedBy],
});
}
async receive_accept_invite(send) {
this.data.invited = send.invites;
let id_game = send.id_game;
navigateTo("/game/" + id_game);
}
async refuse_invite(invitedBy) {
this.sendRequest({
type: "refuse_invite",
targets: [invitedBy],
});
}
async receive_refuse_invite(send) {
this.data.invited = send.invites;
if (send.author_id == this.client.me.id) {
if (this.rewrite_invite !== undefined)
this.rewrite_invite();
}
else {
let sender = await this.client.profiles.getProfileId(send.author_id);
createNotification(sender.username + " refuse your invitation");
}
}
async send_invite(id_inviteds) {
this.sendRequest({
type: "invite",
targets: id_inviteds,
time: new Date().getTime(),
});
}
async receive_invite(send) {
if (this.client.me == undefined)
return ;
let content = send.invites;
if (send.author_id == this.client.me.id) {
if (send.status == 200) {
for (let target in send.targets)
return createNotification("Invitation send");
}
else if (send.status == 444)
return createNotification("User not connected");
else if (send.status == 409)
return createNotification("Already invited");
}
else {
// Regarder qu'il est bien invité par l'auteur
// Et qu'il n'est pas déjà invité
if (!content.includes(send.author_id) ||
this.data.invited.includes(send.author_id))
return;
this.data.invited = content;
let sender = await this.client.profiles.getProfileId(send.author_id);
createNotification("Invitation received by " + sender.username);
if (this.rewrite_invite !== undefined)
this.rewrite_invite();
}
}
async getOnlineUser() {
this.online_users = {};
this.sendRequest({
type: "online_users",
targets: [],
time: new Date().getTime(),
});
}
async receive_online_users(send) {
let content = send.online;
if (content !== undefined) {
if (this.data.online.length > 0) {
// get all disconnect user
//let disconnects = this.data["online"].filter(id => !Object.keys(content).includes(id));
let disconnects = [];
for (const [key, value] of Object.entries(this.data.online)) {
if (content[key] == "red" && value == "green")
disconnects.push(key);
}
// delete invite
this.data.invited = this.data.invited.filter(id => !disconnects.includes(id));
//console.log(this.data["invited"]);
}
this.data.online = content;
if (this.rewrite_usernames !== undefined)
this.rewrite_usernames();
}
}
async ask_friend(user_id=undefined) {
this.sendRequest({
type: "ask_friend",
targets: [user_id],
time: new Date().getTime(),
});
}
async receive_ask_friend(send) {
let my_id = (this.client.me && this.client.me.id) || send.author_id;
if (send.author_id == my_id) {
if (send.status == 400)
createNotification("Friend ask error");
else if (send.status == 409)
createNotification("Already asked friend");
}
//if (!send.asked.includes(send.author_id) ||
//this.data["asked"].includes(send.author_id))
//return;
//if (!send.asker.includes(send.author_id) ||
//this.data["asker"].includes(send.author_id))
//return;
this.data.asked = send.asked;
this.data.asker = send.asker;
if (send.author_id != my_id) {
let sender = await this.client.profiles.getProfileId(send.author_id);
if (this.data.asker.includes(send.author_id))
createNotification(sender.username + " ask you as friend");
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
}
}
async remove_friend(user_id) {
this.sendRequest({
type: "remove_friend",
targets: [user_id],
time: new Date().getTime(),
});
}
async receive_remove_friend(send) {
if (send.author_id == this.client.me.id) {
if (send.status == 400)
createNotification("Error remove Friend");
else if (send.status == 409)
createNotification("Not friend, wtf");
}
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
this.receive_online_users(send);
}
async accept_friend(user_id) {
this.sendRequest({
type: "accept_friend",
targets: [user_id],
time: new Date().getTime(),
});
}
async receive_accept_friend(send) {
this.data.asked = send.asked;
this.data.asker = send.asker;
let sender = await this.client.profiles.getProfileId(send.author_id);
if (send.author_id == this.client.me.id) {
if (send.status == 400)
createNotification("Error accept Friend");
else if (send.status == 404)
createNotification("Not found request Friend");
else if (send.status == 409)
createNotification("Already Friend, wtf");
}
else {
createNotification(sender.username + " accept your friend request");
}
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
this.receive_online_users(send);
}
async refuse_friend(user_id) {
this.sendRequest({
type: "refuse_friend",
targets: [user_id],
time: new Date().getTime(),
});
}
async receive_refuse_friend(send) {
this.data.asked = send.asked;
this.data.asker = send.asker;
let sender = await this.client.profiles.getProfileId(send.author_id);
if (send.author_id == this.client.me.id) {
if (send.status == 400)
createNotification("Error refuse Friend");
else if (send.status == 404)
createNotification("Not found request Friend");
else if (send.status == 409)
createNotification("Already Friend, WTF");
}
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
}
async sendRequest(content) {
if (this.chatSocket == undefined)
return;
this.chatSocket.send(JSON.stringify(content));
}
}
export {Notice};

View File

@ -0,0 +1,83 @@
import {Client} from '../Client.js';
import {createNotification} from '../../utils/noticeUtils.js'
import { client, lastView } from '../../index.js';
import { Profile } from '../Profile.js';
import ProfilePageView from '../../views/ProfilePageView.js';
export default class Notice {
/**
* @param {Client} client
*/
constructor(client) {
/**
* @type {Client}
*/
this.client = client;
this.url = location.origin.replace('http', 'ws') + '/ws/notice';
}
start() {
this._socket = new WebSocket(this.url);
this._socket.onclose = _ => this._socket = undefined;
this._socket.onmessage = message => {
const data = JSON.parse(message.data);
console.log(data)
if (data.type === 'friend_request') {
this.friend_request(data.author);
} else if (data.type === 'new_friend') {
this.new_friend(data.friend);
} else if (data.type === 'friend_removed') {
this.friend_removed(data.friend);
} else if (data.type === 'friend_request_canceled') {
this.friend_request_canceled(data.author);
}
};
}
stop() {
if (this._socket) {
this._socket.close();
this._socket = undefined;
}
}
friend_request(author) {
console.log('hey')
client.me.incomingFriendRequests.push(new Profile(author.username, author.id, author.avatar));
createNotification('Friend Request', `<strong>${author.username}</strong> sent you a friend request.`);
if (lastView instanceof ProfilePageView && lastView.profile.id === author.id) {
lastView.profile.hasIncomingRequest = true;
lastView.loadFriendshipStatus();
}
}
new_friend(friend) {
client.me.friendList.push(new Profile(friend.username, friend.id, friend.avatar));
createNotification('New Friend', `<strong>${friend.username}</strong> accepted your friend request.`);
if (lastView instanceof ProfilePageView && lastView.profile.id === friend.id) {
lastView.profile.isFriend = true;
lastView.profile.hasIncomingRequest = false;
lastView.profile.hasOutgoingRequest = false;
lastView.loadFriendshipStatus();
}
}
friend_removed(exFriend) {
client.me.friendList = client.me.friendList.filter(friend => friend.id !== exFriend.id);
if (lastView instanceof ProfilePageView && lastView.profile.id === exFriend.id) {
lastView.profile.isFriend = false;
lastView.loadFriendshipStatus();
}
}
friend_request_canceled(author) {
client.me.incomingFriendRequests = client.me.incomingFriendRequests.filter(user => user.id !== author.id);
if (lastView instanceof ProfilePageView && lastView.profile.id === author.id) {
lastView.profile.hasIncomingRequest = false;
lastView.loadFriendshipStatus();
}
}
}

View File

@ -167,4 +167,4 @@ document.addEventListener("DOMContentLoaded", async () => {
document.querySelector('a[href=\'' + location.pathname + '\']')?.classList.add('active'); document.querySelector('a[href=\'' + location.pathname + '\']')?.classList.add('active');
}); });
export { client, lang, navigateTo, reloadView }; export { client, lang, lastView, navigateTo, reloadView };

View File

@ -1,22 +1,15 @@
export function createNotification(text, timer = 3000) { export function createNotification(title = 'New notification', content, delay = 3000) {
if (!createNotification.templateToast) { const toastElement = document.createElement('div');
createNotification.templateToast = new DOMParser().parseFromString(` toastElement.classList.add('toast');
<div class='toast' role='alert' data-bs-delay='${timer}'> toastElement.role = 'alert';
<div class='toast-header'> toastElement.setAttribute('data-bs-delay', delay);
<strong class='me-auto'>Notification</strong> toastElement.innerHTML =
<button type='button' class='btn-close' data-bs-dismiss='toast'></button> `<div class='toast-header'>
</div> <strong class='me-auto'>${title}</strong>
<div class='toast-body'> <button type='button' class='btn-close' data-bs-dismiss='toast'></button>
</div> </div>
</div> <div class='toast-body'>${content}</div>`
`, 'text/html')
.querySelector('body')
.firstChild;
}
const toastElement = createNotification.templateToast.cloneNode(true);
toastElement.getElementsByClassName('toast-body')[0].innerHTML = text;
toastElement.addEventListener('hidden.bs.toast', e => e.target.remove()); toastElement.addEventListener('hidden.bs.toast', e => e.target.remove());
new bootstrap.Toast(toastElement).show(); new bootstrap.Toast(toastElement).show();

View File

@ -16,23 +16,15 @@ export default class extends AbstractView {
if (!this.profile) if (!this.profile)
return 404; return 404;
if (this.profile.id === client.me.id)
return;
const addFriendButton = document.getElementById('addFriendButton'), const addFriendButton = document.getElementById('addFriendButton'),
removeFriendButton = document.getElementById('removeFriendButton'), removeFriendButton = document.getElementById('removeFriendButton'),
blockButton = document.getElementById('blockButton'), blockButton = document.getElementById('blockButton'),
unblockButton = document.getElementById('unblockButton'); unblockButton = document.getElementById('unblockButton');
if (this.profile.hasIncomingRequest) { this.loadFriendshipStatus();
addFriendButton.classList.remove('d-none');
addFriendButton.innerHTML = 'Accept Request';
} else if (this.profile.hasOutgoingRequest) {
removeFriendButton.classList.remove('d-none');
removeFriendButton.classList.replace('btn-danger', 'btn-secondary');
removeFriendButton.innerHTML = 'Cancel Request'
} else if (this.profile.isFriend)
removeFriendButton.classList.remove('d-none');
else
addFriendButton.classList.remove('d-none');
if (this.profile.isBlocked) if (this.profile.isBlocked)
unblockButton.classList.remove('d-none'); unblockButton.classList.remove('d-none');
else else
@ -44,6 +36,31 @@ export default class extends AbstractView {
blockButton.onclick = _ => this.blockUser(); blockButton.onclick = _ => this.blockUser();
} }
loadFriendshipStatus() {
const addFriendButton = document.getElementById('addFriendButton'),
removeFriendButton = document.getElementById('removeFriendButton');
if (this.profile.hasIncomingRequest) {
removeFriendButton.classList.add('d-none');
addFriendButton.classList.remove('d-none');
addFriendButton.innerHTML = 'Accept Request';
} else if (this.profile.hasOutgoingRequest) {
addFriendButton.classList.add('d-none');
removeFriendButton.classList.remove('d-none');
removeFriendButton.classList.replace('btn-danger', 'btn-secondary');
removeFriendButton.innerHTML = 'Cancel Request';
} else if (this.profile.isFriend) {
addFriendButton.classList.add('d-none');
removeFriendButton.classList.remove('d-none');
removeFriendButton.classList.replace('btn-secondary', 'btn-danger');
removeFriendButton.innerHTML = 'Remove Friend';
} else {
addFriendButton.innerHTML = 'Add Friend';
removeFriendButton.classList.add('d-none');
addFriendButton.classList.remove('d-none');
}
}
async getHtml() { async getHtml() {
this.profile = await client.profiles.getProfile(this.username); this.profile = await client.profiles.getProfile(this.username);

View File

@ -10,7 +10,6 @@ export default class extends AbstractAuthenticatedView
async postInit() { async postInit() {
await client.logout(); await client.logout();
await client.notice.disconnect();
navigateTo(this.lastPageUrl); navigateTo(this.lastPageUrl);
} }
} }

View File

@ -45,9 +45,8 @@
</div> </div>
</div> </div>
</nav> </nav>
<div class='toast-container position-fixed end-0 p-3 pt-0' id='toastContainer'></div>
<div id="app" class="m-3"></div> <div id="app" class="m-3"></div>
<div class='toast-container position-fixed bottom-0 end-0 p-3' id='toastContainer'>
</div>
<script type="module" src="{% static 'js/index.js' %}"></script> <script type="module" src="{% static 'js/index.js' %}"></script>
<script src="{% static 'js/bootstrap/bootstrap.bundle.min.js' %}"></script> <script src="{% static 'js/bootstrap/bootstrap.bundle.min.js' %}"></script>
</body> </body>

View File

@ -4,7 +4,7 @@ from django.contrib.auth.models import User
from django.db.models import QuerySet from django.db.models import QuerySet
from .models import GameModel from .models import GameModel
from profiles.serializers.ProfileSerializer import ProfileSerializer from profiles.serializers import ProfileSerializer
class GameSerializer(serializers.ModelSerializer): class GameSerializer(serializers.ModelSerializer):
@ -29,4 +29,4 @@ class GameSerializer(serializers.ModelSerializer):
return "waiting" return "waiting"
def get_players(self, instance: GameModel): def get_players(self, instance: GameModel):
return ProfileSerializer(instance.get_players_profiles(), many=True).data return ProfileSerializer(instance.get_players_profiles(), many=True).data

0
notice/__init__.py Normal file
View File

3
notice/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
notice/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class NoticeConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'notice'

68
notice/consumers.py Normal file
View File

@ -0,0 +1,68 @@
from __future__ import annotations
import json
from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth.models import User
from profiles.serializers import ProfileSerializer
from profiles.models import ProfileModel
from .models import NoticeModel
class NoticeManager:
def __init__(self):
self._list: list[NoticeConsumer] = []
def add(self, consumer: NoticeConsumer):
self._list.append(consumer)
unsend_notices = NoticeModel.objects.filter(user=consumer.user)
for notice in unsend_notices:
self.notify_user(consumer.user, json_data=notice.data)
notice.delete()
def remove(self, consumer: NoticeConsumer):
self._list.remove(consumer)
def get_consumer_by_user(self, user: User):
for consumer in self._list:
if consumer.user == user:
return consumer
def notify_user(self, user: User, data: dict = None, json_data: str = None):
consumer = self.get_consumer_by_user(user)
data_str: str = json.dumps(data) if json_data is None else json_data
if consumer:
consumer.send(data_str)
else:
NoticeModel(user=user, data=data_str).save()
def notify_friend_request(self, user: User, friend: ProfileModel):
self.notify_user(user, {'type': 'friend_request', 'author': ProfileSerializer(friend).data})
def notify_friend_request_canceled(self, user: User, friend: ProfileModel):
self.notify_user(user, {'type': 'friend_request_canceled', 'author': ProfileSerializer(friend).data})
def notify_new_friend(self, user: User, friend: ProfileModel):
self.notify_user(user, {'type': 'new_friend', 'friend': ProfileSerializer(friend).data})
def notify_friend_removed(self, user: User, friend: ProfileModel):
self.notify_user(user, {'type': 'friend_removed', 'friend': ProfileSerializer(friend).data})
notice_manager = NoticeManager()
class NoticeConsumer(WebsocketConsumer):
def connect(self):
self.user: User = self.scope['user']
if not self.user.is_authenticated:
self.close()
return
self.accept()
notice_manager.add(self)
def disconnect(self, code):
notice_manager.remove(self)
super().disconnect(code)

7
notice/models.py Normal file
View File

@ -0,0 +1,7 @@
from django.db.models import Model, ForeignKey, CharField, CASCADE
from django.contrib.auth.models import User
class NoticeModel(Model):
user = ForeignKey(User, on_delete=CASCADE)
data = CharField(max_length=100)

7
notice/routing.py Normal file
View File

@ -0,0 +1,7 @@
from django.urls import re_path
from .consumers import NoticeConsumer
websocket_urlpatterns = [
re_path(r'ws/notice$', NoticeConsumer.as_asgi()),
]

3
notice/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
notice/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -3,7 +3,7 @@ from django.utils.translation import gettext as _
from rest_framework import serializers from rest_framework import serializers
from ..models import ProfileModel from .models import ProfileModel
class ProfileSerializer(serializers.ModelSerializer): class ProfileSerializer(serializers.ModelSerializer):
@ -13,7 +13,7 @@ class ProfileSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = ProfileModel model = ProfileModel
fields = ["username", "avatar", "user_id"] fields = ["username", "avatar", "id"]
def validate_avatar(self, value): def validate_avatar(self, value):
''' '''

View File

@ -8,7 +8,7 @@ from django.utils.translation import gettext as _
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from ..models import BlockModel, ProfileModel from ..models import BlockModel, ProfileModel
from ..serializers.ProfileSerializer import ProfileSerializer from ..serializers import ProfileSerializer
class GetBlocksView(APIView): class GetBlocksView(APIView):

View File

@ -7,7 +7,8 @@ from django.utils.translation import gettext as _
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from ..models import ProfileModel, FriendRequestModel from ..models import ProfileModel, FriendRequestModel
from ..serializers.ProfileSerializer import ProfileSerializer from ..serializers import ProfileSerializer
from notice.consumers import notice_manager
class GetFriendsView(APIView): class GetFriendsView(APIView):
@ -41,9 +42,11 @@ class EditFriendView(APIView):
incoming_request = user_profile.get_received_friend_request_from(friend_profile) incoming_request = user_profile.get_received_friend_request_from(friend_profile)
if incoming_request: if incoming_request:
incoming_request.accept() incoming_request.accept()
return Response(_('Friendship succssfully created.'), status.HTTP_201_CREATED) notice_manager.notify_new_friend(friend_profile.user, user_profile)
return Response(_('Friendship successfully created.'), status.HTTP_201_CREATED)
FriendRequestModel(author=user_profile, target=friend_profile).save() FriendRequestModel(author=user_profile, target=friend_profile).save()
notice_manager.notify_friend_request(friend_profile.user, user_profile)
return Response(_('Friend request sent.'), status.HTTP_200_OK) return Response(_('Friend request sent.'), status.HTTP_200_OK)
def delete(self, request, pk=None): def delete(self, request, pk=None):
@ -53,13 +56,15 @@ class EditFriendView(APIView):
outgoing_request = user_profile.get_outgoing_friend_request_to(friend_profile) outgoing_request = user_profile.get_outgoing_friend_request_to(friend_profile)
if outgoing_request: if outgoing_request:
outgoing_request.delete() outgoing_request.delete()
notice_manager.notify_friend_request_canceled(friend_profile.user, user_profile)
return Response(_('Friend request cancelled.')) return Response(_('Friend request cancelled.'))
if not user_profile.is_friend(friend_profile): if not user_profile.is_friend(friend_profile):
return Response(_('You are not friend with this user.'), status.HTTP_400_BAD_REQUEST) return Response(_('You are not friend with this user.'), status.HTTP_400_BAD_REQUEST)
user_profile.delete_friend(friend_profile) user_profile.delete_friend(friend_profile)
return Response(_('Friendship succssfully deleted.'), status.HTTP_201_CREATED) notice_manager.notify_friend_removed(friend_profile.user, user_profile)
return Response(_('Friendship successfully deleted.'), status.HTTP_201_CREATED)
class GetIncomingFriendRequestView(APIView): class GetIncomingFriendRequestView(APIView):

View File

@ -3,7 +3,7 @@ from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import SessionAuthentication
from ..serializers.ProfileSerializer import ProfileSerializer from ..serializers import ProfileSerializer
from ..models import ProfileModel from ..models import ProfileModel

View File

@ -5,7 +5,7 @@ from rest_framework import permissions
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
from ..serializers.ProfileSerializer import ProfileSerializer from ..serializers import ProfileSerializer
from ..models import ProfileModel from ..models import ProfileModel

View File

@ -9,7 +9,7 @@ from django.utils.translation import gettext as _
from games.models import GameModel from games.models import GameModel
from games.serializers import GameSerializer from games.serializers import GameSerializer
from profiles.models import ProfileModel from profiles.models import ProfileModel
from profiles.serializers.ProfileSerializer import ProfileSerializer from profiles.serializers import ProfileSerializer
from .models import TournamentModel from .models import TournamentModel
import json import json
@ -228,4 +228,4 @@ class TournamentWebConsumer(WebsocketConsumer):
self.room.leave(self.member) self.room.leave(self.member)
super().disconnect(close_code) # proutman à encore frappé super().disconnect(close_code) # proutman à encore frappé

View File

@ -2,7 +2,7 @@ from rest_framework import serializers
from .models import TournamentModel, TournamentGameModel from .models import TournamentModel, TournamentGameModel
from profiles.serializers.ProfileSerializer import ProfileSerializer from profiles.serializers import ProfileSerializer
from games.serializers import GameSerializer from games.serializers import GameSerializer
nb_participants = [2 ** i for i in range(2, 6)] nb_participants = [2 ** i for i in range(2, 6)]
@ -58,4 +58,4 @@ class TournamentGameSerializer(serializers.ModelSerializer):
return "waiting" return "waiting"
def get_players(self, instance: TournamentGameModel): def get_players(self, instance: TournamentGameModel):
return ProfileSerializer(instance.get_players_profiles(), many=True).data return ProfileSerializer(instance.get_players_profiles(), many=True).data

View File

@ -15,20 +15,21 @@ import chat.routing
import matchmaking.routing import matchmaking.routing
import tournament.routing import tournament.routing
import games.routing import games.routing
import notice.routing
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'trancendence.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'trancendence.settings')
application = ProtocolTypeRouter({ application = ProtocolTypeRouter({
'http':get_asgi_application(), 'http': get_asgi_application(),
'websocket':AuthMiddlewareStack( 'websocket': AuthMiddlewareStack(
URLRouter( URLRouter(
chat.routing.websocket_urlpatterns + chat.routing.websocket_urlpatterns +
matchmaking.routing.websocket_urlpatterns + matchmaking.routing.websocket_urlpatterns +
tournament.routing.websocket_urlpatterns + tournament.routing.websocket_urlpatterns +
games.routing.websocket_urlpatterns games.routing.websocket_urlpatterns +
notice.routing.websocket_urlpatterns
) )
) )
}) })

View File

@ -51,6 +51,7 @@ INSTALLED_APPS = [
'profiles.apps.ProfilesConfig', 'profiles.apps.ProfilesConfig',
'frontend.apps.FrontendConfig', 'frontend.apps.FrontendConfig',
'chat.apps.ChatConfig', 'chat.apps.ChatConfig',
'notice.apps.NoticeConfig',
'corsheaders', 'corsheaders',
'rest_framework', 'rest_framework',