diff --git a/frontend/static/js/api/Client.js b/frontend/static/js/api/Client.js index 5341b08..3732b9f 100644 --- a/frontend/static/js/api/Client.js +++ b/frontend/static/js/api/Client.js @@ -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'; diff --git a/frontend/static/js/api/MyProfile.js b/frontend/static/js/api/MyProfile.js index ef2e694..17dd2df 100644 --- a/frontend/static/js/api/MyProfile.js +++ b/frontend/static/js/api/MyProfile.js @@ -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) )); } diff --git a/frontend/static/js/api/Profile.js b/frontend/static/js/api/Profile.js index feb9570..a1e553d 100644 --- a/frontend/static/js/api/Profile.js +++ b/frontend/static/js/api/Profile.js @@ -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); } /** diff --git a/frontend/static/js/api/Profiles.js b/frontend/static/js/api/Profiles.js index 796abc7..04d1666 100644 --- a/frontend/static/js/api/Profiles.js +++ b/frontend/static/js/api/Profiles.js @@ -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; } diff --git a/frontend/static/js/api/chat/Notice.js b/frontend/static/js/api/chat/Notice.js deleted file mode 100644 index 9448e2a..0000000 --- a/frontend/static/js/api/chat/Notice.js +++ /dev/null @@ -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}; diff --git a/frontend/static/js/api/notice/Notice.js b/frontend/static/js/api/notice/Notice.js new file mode 100644 index 0000000..e2407e4 --- /dev/null +++ b/frontend/static/js/api/notice/Notice.js @@ -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', `${author.username} 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', `${friend.username} 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(); + } + } +} diff --git a/frontend/static/js/index.js b/frontend/static/js/index.js index 81a72fe..8b5c5e0 100644 --- a/frontend/static/js/index.js +++ b/frontend/static/js/index.js @@ -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 }; diff --git a/frontend/static/js/utils/noticeUtils.js b/frontend/static/js/utils/noticeUtils.js index b604de1..f5e1eb7 100644 --- a/frontend/static/js/utils/noticeUtils.js +++ b/frontend/static/js/utils/noticeUtils.js @@ -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(` -