notice but without the t
This commit is contained in:
parent
dbb8e07d7d
commit
5f58b65a34
@ -4,7 +4,7 @@ import { Profiles } from "./Profiles.js";
|
||||
import { Channels } from './chat/Channels.js';
|
||||
import { MyProfile } from "./MyProfile.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 LanguageManager from './LanguageManager.js';
|
||||
|
||||
@ -83,7 +83,7 @@ class Client
|
||||
{
|
||||
if (this._logged == undefined)
|
||||
this._logged = await this._test_logged();
|
||||
return this._logged;
|
||||
return this._logged;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,7 +217,7 @@ class Client
|
||||
{
|
||||
this.me = new MyProfile(this);
|
||||
await this.me.init();
|
||||
this.notice.connect();
|
||||
this.notice.start();
|
||||
document.getElementById('navbarLoggedOut').classList.add('d-none');
|
||||
document.getElementById('navbarLoggedIn').classList.remove('d-none');
|
||||
document.getElementById('navbarDropdownButton').innerHTML = this.me.username;
|
||||
@ -226,7 +226,7 @@ class Client
|
||||
else
|
||||
{
|
||||
this.me = undefined;
|
||||
this.notice.disconnect();
|
||||
this.notice.stop();
|
||||
document.getElementById('navbarLoggedOut').classList.remove('d-none');
|
||||
document.getElementById('navbarLoggedIn').classList.add('d-none');
|
||||
document.getElementById('navbarDropdownButton').innerHTML = 'Me';
|
||||
|
@ -40,26 +40,26 @@ class MyProfile extends Profile
|
||||
async getBlockedUsers() {
|
||||
const response = await this.client._get('/api/profiles/block');
|
||||
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() {
|
||||
const response = await this.client._get('/api/profiles/friends');
|
||||
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() {
|
||||
const response = await this.client._get('/api/profiles/incoming_friend_requests');
|
||||
const data = await response.json();
|
||||
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() {
|
||||
const response = await this.client._get('/api/profiles/outgoing_friend_requests');
|
||||
const data = await response.json();
|
||||
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)
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -55,17 +55,17 @@ export class Profile extends AExchangeable
|
||||
return response.status;
|
||||
|
||||
let response_data = await response.json();
|
||||
this.id = response_data.user_id;
|
||||
this.id = response_data.id;
|
||||
this.username = response_data.username;
|
||||
this.avatar = response_data.avatar;
|
||||
|
||||
if (!this.client.me || this.client.me.id === this.id)
|
||||
return;
|
||||
|
||||
this.isFriend = this.client.me._isFriend(this);
|
||||
this.isBlocked = this.client.me._isBlocked(this);
|
||||
this.hasIncomingRequest = this.client.me._hasIncomingRequestFrom(this);
|
||||
this.hasOutgoingRequest = this.client.me._hasOutgoingRequestTo(this);
|
||||
this.isFriend = this.client.me._isFriend(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ class Profiles
|
||||
|
||||
let profiles = [];
|
||||
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;
|
||||
}
|
||||
|
@ -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};
|
83
frontend/static/js/api/notice/Notice.js
Normal file
83
frontend/static/js/api/notice/Notice.js
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
@ -167,4 +167,4 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
document.querySelector('a[href=\'' + location.pathname + '\']')?.classList.add('active');
|
||||
});
|
||||
|
||||
export { client, lang, navigateTo, reloadView };
|
||||
export { client, lang, lastView, navigateTo, reloadView };
|
||||
|
@ -1,22 +1,15 @@
|
||||
export function createNotification(text, timer = 3000) {
|
||||
export function createNotification(title = 'New notification', content, delay = 3000) {
|
||||
|
||||
if (!createNotification.templateToast) {
|
||||
createNotification.templateToast = new DOMParser().parseFromString(`
|
||||
<div class='toast' role='alert' data-bs-delay='${timer}'>
|
||||
<div class='toast-header'>
|
||||
<strong class='me-auto'>Notification</strong>
|
||||
<button type='button' class='btn-close' data-bs-dismiss='toast'></button>
|
||||
</div>
|
||||
<div class='toast-body'>
|
||||
</div>
|
||||
</div>
|
||||
`, 'text/html')
|
||||
.querySelector('body')
|
||||
.firstChild;
|
||||
}
|
||||
|
||||
const toastElement = createNotification.templateToast.cloneNode(true);
|
||||
toastElement.getElementsByClassName('toast-body')[0].innerHTML = text;
|
||||
const toastElement = document.createElement('div');
|
||||
toastElement.classList.add('toast');
|
||||
toastElement.role = 'alert';
|
||||
toastElement.setAttribute('data-bs-delay', delay);
|
||||
toastElement.innerHTML =
|
||||
`<div class='toast-header'>
|
||||
<strong class='me-auto'>${title}</strong>
|
||||
<button type='button' class='btn-close' data-bs-dismiss='toast'></button>
|
||||
</div>
|
||||
<div class='toast-body'>${content}</div>`
|
||||
toastElement.addEventListener('hidden.bs.toast', e => e.target.remove());
|
||||
new bootstrap.Toast(toastElement).show();
|
||||
|
||||
|
@ -16,23 +16,15 @@ export default class extends AbstractView {
|
||||
if (!this.profile)
|
||||
return 404;
|
||||
|
||||
if (this.profile.id === client.me.id)
|
||||
return;
|
||||
|
||||
const addFriendButton = document.getElementById('addFriendButton'),
|
||||
removeFriendButton = document.getElementById('removeFriendButton'),
|
||||
blockButton = document.getElementById('blockButton'),
|
||||
unblockButton = document.getElementById('unblockButton');
|
||||
|
||||
if (this.profile.hasIncomingRequest) {
|
||||
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');
|
||||
|
||||
this.loadFriendshipStatus();
|
||||
if (this.profile.isBlocked)
|
||||
unblockButton.classList.remove('d-none');
|
||||
else
|
||||
@ -44,6 +36,31 @@ export default class extends AbstractView {
|
||||
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() {
|
||||
|
||||
this.profile = await client.profiles.getProfile(this.username);
|
||||
|
@ -10,7 +10,6 @@ export default class extends AbstractAuthenticatedView
|
||||
|
||||
async postInit() {
|
||||
await client.logout();
|
||||
await client.notice.disconnect();
|
||||
navigateTo(this.lastPageUrl);
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class='toast-container position-fixed end-0 p-3 pt-0' id='toastContainer'></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 src="{% static 'js/bootstrap/bootstrap.bundle.min.js' %}"></script>
|
||||
</body>
|
||||
|
@ -4,7 +4,7 @@ from django.contrib.auth.models import User
|
||||
from django.db.models import QuerySet
|
||||
|
||||
from .models import GameModel
|
||||
from profiles.serializers.ProfileSerializer import ProfileSerializer
|
||||
from profiles.serializers import ProfileSerializer
|
||||
|
||||
class GameSerializer(serializers.ModelSerializer):
|
||||
|
||||
@ -29,4 +29,4 @@ class GameSerializer(serializers.ModelSerializer):
|
||||
return "waiting"
|
||||
|
||||
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
0
notice/__init__.py
Normal file
3
notice/admin.py
Normal file
3
notice/admin.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
6
notice/apps.py
Normal file
6
notice/apps.py
Normal 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
68
notice/consumers.py
Normal 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
7
notice/models.py
Normal 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
7
notice/routing.py
Normal 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
3
notice/tests.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
3
notice/views.py
Normal file
3
notice/views.py
Normal file
@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
@ -3,7 +3,7 @@ from django.utils.translation import gettext as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from ..models import ProfileModel
|
||||
from .models import ProfileModel
|
||||
|
||||
|
||||
class ProfileSerializer(serializers.ModelSerializer):
|
||||
@ -13,7 +13,7 @@ class ProfileSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ProfileModel
|
||||
fields = ["username", "avatar", "user_id"]
|
||||
fields = ["username", "avatar", "id"]
|
||||
|
||||
def validate_avatar(self, value):
|
||||
'''
|
@ -8,7 +8,7 @@ from django.utils.translation import gettext as _
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from ..models import BlockModel, ProfileModel
|
||||
from ..serializers.ProfileSerializer import ProfileSerializer
|
||||
from ..serializers import ProfileSerializer
|
||||
|
||||
|
||||
class GetBlocksView(APIView):
|
||||
|
@ -7,7 +7,8 @@ from django.utils.translation import gettext as _
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from ..models import ProfileModel, FriendRequestModel
|
||||
from ..serializers.ProfileSerializer import ProfileSerializer
|
||||
from ..serializers import ProfileSerializer
|
||||
from notice.consumers import notice_manager
|
||||
|
||||
|
||||
class GetFriendsView(APIView):
|
||||
@ -41,9 +42,11 @@ class EditFriendView(APIView):
|
||||
incoming_request = user_profile.get_received_friend_request_from(friend_profile)
|
||||
if incoming_request:
|
||||
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()
|
||||
notice_manager.notify_friend_request(friend_profile.user, user_profile)
|
||||
return Response(_('Friend request sent.'), status.HTTP_200_OK)
|
||||
|
||||
def delete(self, request, pk=None):
|
||||
@ -53,13 +56,15 @@ class EditFriendView(APIView):
|
||||
outgoing_request = user_profile.get_outgoing_friend_request_to(friend_profile)
|
||||
if outgoing_request:
|
||||
outgoing_request.delete()
|
||||
notice_manager.notify_friend_request_canceled(friend_profile.user, user_profile)
|
||||
return Response(_('Friend request cancelled.'))
|
||||
|
||||
if not user_profile.is_friend(friend_profile):
|
||||
return Response(_('You are not friend with this user.'), status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
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):
|
||||
|
@ -3,7 +3,7 @@ from rest_framework import viewsets
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
|
||||
from ..serializers.ProfileSerializer import ProfileSerializer
|
||||
from ..serializers import ProfileSerializer
|
||||
from ..models import ProfileModel
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ from rest_framework import permissions
|
||||
from rest_framework import viewsets
|
||||
from rest_framework.response import Response
|
||||
|
||||
from ..serializers.ProfileSerializer import ProfileSerializer
|
||||
from ..serializers import ProfileSerializer
|
||||
from ..models import ProfileModel
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ from django.utils.translation import gettext as _
|
||||
from games.models import GameModel
|
||||
from games.serializers import GameSerializer
|
||||
from profiles.models import ProfileModel
|
||||
from profiles.serializers.ProfileSerializer import ProfileSerializer
|
||||
from profiles.serializers import ProfileSerializer
|
||||
from .models import TournamentModel
|
||||
|
||||
import json
|
||||
@ -228,4 +228,4 @@ class TournamentWebConsumer(WebsocketConsumer):
|
||||
|
||||
self.room.leave(self.member)
|
||||
|
||||
super().disconnect(close_code) # proutman à encore frappé
|
||||
super().disconnect(close_code) # proutman à encore frappé
|
||||
|
@ -2,7 +2,7 @@ from rest_framework import serializers
|
||||
|
||||
from .models import TournamentModel, TournamentGameModel
|
||||
|
||||
from profiles.serializers.ProfileSerializer import ProfileSerializer
|
||||
from profiles.serializers import ProfileSerializer
|
||||
from games.serializers import GameSerializer
|
||||
|
||||
nb_participants = [2 ** i for i in range(2, 6)]
|
||||
@ -58,4 +58,4 @@ class TournamentGameSerializer(serializers.ModelSerializer):
|
||||
return "waiting"
|
||||
|
||||
def get_players(self, instance: TournamentGameModel):
|
||||
return ProfileSerializer(instance.get_players_profiles(), many=True).data
|
||||
return ProfileSerializer(instance.get_players_profiles(), many=True).data
|
||||
|
@ -15,20 +15,21 @@ import chat.routing
|
||||
import matchmaking.routing
|
||||
import tournament.routing
|
||||
import games.routing
|
||||
import notice.routing
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'trancendence.settings')
|
||||
|
||||
application = ProtocolTypeRouter({
|
||||
'http':get_asgi_application(),
|
||||
'websocket':AuthMiddlewareStack(
|
||||
'http': get_asgi_application(),
|
||||
'websocket': AuthMiddlewareStack(
|
||||
URLRouter(
|
||||
chat.routing.websocket_urlpatterns +
|
||||
matchmaking.routing.websocket_urlpatterns +
|
||||
tournament.routing.websocket_urlpatterns +
|
||||
games.routing.websocket_urlpatterns
|
||||
games.routing.websocket_urlpatterns +
|
||||
notice.routing.websocket_urlpatterns
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -51,6 +51,7 @@ INSTALLED_APPS = [
|
||||
'profiles.apps.ProfilesConfig',
|
||||
'frontend.apps.FrontendConfig',
|
||||
'chat.apps.ChatConfig',
|
||||
'notice.apps.NoticeConfig',
|
||||
|
||||
'corsheaders',
|
||||
'rest_framework',
|
||||
|
Loading…
Reference in New Issue
Block a user