Merge with Xamora

This commit is contained in:
Xamora 2024-01-24 16:14:15 +01:00
commit 910a8861e5
15 changed files with 798 additions and 153 deletions

View File

@ -1,6 +1,9 @@
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from games.models import GameModel
from profiles.models import FriendModel, AskFriendModel
import time
import json
@ -31,19 +34,7 @@ class ChatNoticeConsumer(WebsocketConsumer):
self.accept()
message_time: int = int(time.time() * 1000)
targets = list(self.channel_layer.users_channels.keys())
for target in targets:
channel = self.channel_layer.users_channels.get(target)
if (channel == None or target == user.pk):
continue
async_to_sync(self.channel_layer.send)(channel, {
'type':"online_users",
'author_id':user.pk,
'targets': targets,
'time':message_time,
'status': 200,
})
self.sync()
def disconnect(self, code):
@ -51,22 +42,15 @@ class ChatNoticeConsumer(WebsocketConsumer):
if (user.is_anonymous or not user.is_authenticated):
return
self.channel_layer.users_channels.pop(user.pk)
del self.channel_layer.users_channels[user.pk]
del self.channel_layer.invite[user.pk]
message_time: int = int(time.time() * 1000)
for inviter_id, inviteds_id in self.channel_layer.invite.items():
if (user.pk in inviteds_id):
self.channel_layer.invite[inviter_id].remove(user.pk)
self.sync()
targets = list(self.channel_layer.users_channels.keys())
for target in targets:
channel = self.channel_layer.users_channels.get(target)
if (channel == None or target == user.pk):
continue
async_to_sync(self.channel_layer.send)(channel, {
'type':"online_users",
'author_id':user.pk,
'targets': targets,
'time':message_time,
'status': 200,
})
def receive(self, text_data=None, bytes_data=None):
@ -89,50 +73,113 @@ class ChatNoticeConsumer(WebsocketConsumer):
if (self.channel_layer == None):
return
message_time: int = int(time.time() * 1000)
status = 200;
message_time: int = text_data_json.get('time')
#print("receive" + str(user.pk))
if (message_time == None):
message_time: int = int(time.time() * 1000)
result = None
try:
status = getattr(self, "pre_" + type_notice)(user, targets)
except AttributeError:
print(f"La fonction pre_{type_notice} n'existe pas.")
status, result = getattr(self, "pre_" + type_notice)(user, targets)
except AttributeError as error:
print(error)
status = 200
if targets == "all":
targets = list(self.channel_layer.users_channels.keys())
if (status < 300):
if targets == "all":
targets = list(self.channel_layer.users_channels.keys())
for target in targets:
channel = self.channel_layer.users_channels.get(target)
if (channel == None or target == user.pk):
if (channel == None):
status = 444 # target not connected
continue
async_to_sync(self.channel_layer.send)(channel, {
'type':type_notice,
'author_id':user.pk,
'content':content,
'result':result,
'targets': targets,
'time':message_time,
'status': 200,
})
for target in targets:
channel = self.channel_layer.users_channels.get(target)
if (channel == None or target == user.pk):
if (channel == None):
status = 404
continue
async_to_sync(self.channel_layer.send)(channel, {
'type':type_notice,
'author_id':user.pk,
'content':content,
'targets': targets,
'time':message_time,
'status': 200,
})
async_to_sync(self.channel_layer.send)(self.channel_layer.users_channels.get(user.pk), {
'type':type_notice,
'author_id':user.pk,
'content':"notice return",
'result':result,
'targets': targets,
'time':message_time,
'status':status,
})
def sync(self, user = None, level = None):
sendToUser = True
if (user == None):
user = self.scope["user"]
sendToUser = False
if (level == None):
level = 0
message_time: int = int(time.time() * 1000)
if (sendToUser):
targets = [user.pk]
else:
targets = list(self.channel_layer.users_channels.keys())
for target in targets:
channel = self.channel_layer.users_channels.get(target)
if (channel == None or (not sendToUser and target == user.pk)):
continue
async_to_sync(self.channel_layer.send)(channel, {
'type':"online_users",
'author_id':user.pk,
'targets': targets,
'time':message_time,
'status': 200,
})
if (level >= 1):
async_to_sync(self.channel_layer.send)(channel, {
'type':"invite",
'author_id':user.pk,
'targets': targets,
'time':message_time,
'status': 200,
})
def pre_invite(self, user, targets):
status = 200
if (user.is_anonymous or not user.is_authenticated):
return 400, None
status = 200
for target in targets:
if (target in self.channel_layer.invite[user.pk]):
status = 409
return status
continue
channel = self.channel_layer.users_channels.get(target)
if (channel == None):
status = 404
continue
# Add the invited in "self.channel_layer.invite"
if (user.pk != target):
self.channel_layer.invite[user.pk].append(target)
return status, None
def get_invites(self, user):
invites = []
for inviter_id, inviteds_id in self.channel_layer.invite.items():
if (user.pk in inviteds_id and user.pk != inviter_id):
invites.append(inviter_id)
return invites;
def invite(self, event):
@ -140,38 +187,187 @@ class ChatNoticeConsumer(WebsocketConsumer):
if (user.is_anonymous or not user.is_authenticated):
return
if (user.pk in self.channel_layer.invite[event["author_id"]]):
return
if (user.pk != event["author_id"]):
self.channel_layer.invite[event["author_id"]].append(user.pk)
invites = self.get_invites(user)
self.send(text_data=json.dumps({
'type':event['type'],
'author_id':event['author_id'],
'content':event['content'],
'invites': invites,
'targets': event['targets'],
'time': event['time'],
'status':event['status'],
}))
def pre_online_users(self, user, targets):
pass
def pre_accept_invite(self, user, targets):
def online_users(self, event):
if (user.is_anonymous or not user.is_authenticated):
return 400, None
if (user.pk not in self.channel_layer.invite[targets[0]]):
return 400, None
self.channel_layer.invite[targets[0]].remove(user.pk)
if (targets[0] in self.channel_layer.invite[user.pk]):
self.channel_layer.invite[user.pk].remove(targets[0])
id_game = GameModel().create([user.pk, targets[0]]);
return 200, id_game
def accept_invite(self, event):
user = self.scope["user"]
#if (user.is_anonymous or not user.is_authenticated):
#return
if (user.is_anonymous or not user.is_authenticated):
return
#print("online_users" + str(user.pk))
event['content'] = self.channel_layer.users_channels
invites = self.get_invites(user)
self.send(text_data=json.dumps({
'type':event['type'],
'author_id':event['author_id'],
'content':event['content'],
'id_game': event['result'],
'invites': invites,
'time': event['time'],
'status':event['status'],
}))
def pre_refuse_invite(self, user, targets):
if (user.is_anonymous or not user.is_authenticated):
return 400, None
if (user.pk not in self.channel_layer.invite[targets[0]]):
return 400, None
self.channel_layer.invite[targets[0]].remove(user.pk)
if (targets[0] in self.channel_layer.invite[user.pk]):
self.channel_layer.invite[user.pk].remove(targets[0])
return 200, None
def refuse_invite(self, event):
user = self.scope["user"]
if (user.is_anonymous or not user.is_authenticated):
return
invites = self.get_invites(user)
self.send(text_data=json.dumps({
'type':event['type'],
'author_id':event['author_id'],
'invites': invites,
'time': event['time'],
'status':event['status'],
}))
def pre_ask_friend(self, user, targets):
if (user.is_anonymous or not user.is_authenticated):
return 400, None
if (AskFriendModel.objects.filter(asker=user.pk, asked=targets[0])):
return 409, None
if (FriendModel().isFriend(user.pk, targets[0])):
return 409, None
if (targets[0] != None):
AskFriendModel(asker=user.pk, asked=targets[0]).save()
return 200, None
def send_ask_friend(self, event):
user = self.scope["user"]
if (user.is_anonymous or not user.is_authenticated):
return
asked = AskFriendModel().getAsked(user.pk)
asker = AskFriendModel().getAsker(user.pk)
self.send(text_data=json.dumps({
'type':event['type'],
'author_id':event['author_id'],
'targets':event['targets'],
'asker': asker,
'asked': asked,
'time': event['time'],
'status':event['status'],
}))
def ask_friend(self, event):
self.send_ask_friend(event)
def delete_ask(self, asker, user_asked):
if (user_asked.is_anonymous or not user_asked.is_authenticated):
return 400, None
asked = user_asked.pk
if (not AskFriendModel.objects.filter(asker=asker, asked=asked)):
return 404, None
if (FriendModel().isFriend(asker, asked)):
return 409, None
if (not AskFriendModel().deleteAsk(asker, asked)):
return 400, None
return 200, None
def pre_accept_friend(self, user, targets):
status, result = self.delete_ask(targets[0], user)
if (status == 200):
FriendModel(user_id1=user.pk, user_id2=targets[0]).save()
return status, result
def accept_friend(self, event):
self.send_ask_friend(event)
def pre_refuse_friend(self, user, targets):
return self.delete_ask(targets[0], user)
def refuse_friend(self, event):
self.send_ask_friend(event)
def pre_remove_friend(self, user, targets):
if (user.is_anonymous or not user.is_authenticated):
return 400, None
if (not FriendModel().isFriend(user.pk, targets[0])):
return 409, None
if (not FriendModel().deleteFriend(user.pk, targets[0])):
return 400, None
return 200, None
def remove_friend(self, event):
self.send_ask_friend(event)
def online_users(self, event):
user = self.scope["user"]
if (user.is_anonymous or not user.is_authenticated):
return
online_friends = {}
for friend in FriendModel().getFriends(user.pk):
if (friend in self.channel_layer.users_channels):
online_friends[friend] = "green"
else:
online_friends[friend] = "red"
self.send(text_data=json.dumps({
'type':event['type'],
'author_id':event['author_id'],
'content':online_friends,
'time': event['time'],
'status':event['status'],
}))

View File

@ -3,12 +3,20 @@
font-size: 0.8em;
}
#app #block {
#app #block, #app #friend {
cursor: pointer;
font-size: 0.7em;
text-decoration: underline;
}
#app {
margin-top: 20px;
margin-top: 1em;
background-color: red;
}
#app #yes, #app #no {
display:inline;
cursor: pointer;
font-size: 0.7em;
text-decoration: underline;
}

View File

@ -78,7 +78,6 @@
border: none;
outline: none;
border-bottom: 0.15em solid green;
caret-color: green;
color: green;
font-size: 0.8em;
}
@ -106,9 +105,8 @@
word-wrap: break-word;
}
#app #invite {
#app #invite, #app #yes, #app #no {
position: relative;
background-color: green;
border: none;
color: white;
text-align: center;
@ -118,3 +116,15 @@
width: 4em;
cursor: pointer;
}
#app #yes, #app #no {
position: relative;
border: none;
color: white;
text-align: center;
text-decoration: none;
font-size: 0.8em;
height: 2em;
width: 2em;
cursor: pointer;
}

View File

@ -1,3 +1,4 @@
import { navigateTo } from "../../index.js";
import {create_popup} from "../../utils/noticeUtils.js";
class Notice {
@ -5,11 +6,10 @@ class Notice {
this.client = client;
this.data = {};
// users online, invited by, asked friend by,
let data_variable = ["online", "invited", "asked"];
for (let i in data_variable) {
// 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();
@ -20,15 +20,20 @@ class Notice {
this.chatSocket = new WebSocket(url);
this.chatSocket.onmessage = (event) =>{
let data = JSON.parse(event.data);
//console.log("notice: ", data);
if (data.type == "invite")
this.receiveInvite(data);
else if (data.type == "online_users" || data.type == "disconnect")
this.receiveOnlineUser(data);
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();
}
}
@ -40,61 +45,119 @@ class Notice {
}
async sendInvite(id_inviter, id_inviteds) {
if (this.chatSocket == undefined)
return;
async accept_invite(invitedBy) {
this.chatSocket.send(JSON.stringify({
type: "invite",
targets: id_inviteds,
}));
this.sendRequest({
type: "accept_invite",
targets: [invitedBy],
});
}
async receiveInvite(data) {
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.getProfile(send.author_id);
create_popup(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 (data.content === "notice return") {
if (data.status == 200) {
for (let target in data.targets)
this.data["invited"].push(target);
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 create_popup("Invitation send");
}
else if (data.status == 404)
else if (send.status == 444)
return create_popup("User not connected");
else if (data.status == 409)
else if (send.status == 409)
return create_popup("Already invited");
}
else {
let sender = await this.client.profiles.getProfile(data.author_id);
this.inviter.push(data.author_id);
// 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.getProfile(send.author_id);
create_popup("Invitation received by " + sender.username);
// Géré la reception de l'invitation
if (this.rewrite_invite !== undefined)
this.rewrite_invite();
}
}
async getOnlineUser() {
if (this.chatSocket == undefined)
return;
this.online_users = {};
this.chatSocket.send(JSON.stringify({
this.sendRequest({
type: "online_users",
targets: "all",
}));
targets: [],
time: new Date().getTime(),
});
}
async receiveOnlineUser(data) {
if (data.content !== undefined) {
async receive_online_users(send) {
let content = send.content;
if (content !== undefined) {
if (this.online_users.length > 0) {
if (this.data["online"].length > 0) {
// get all disconnect user
let disconnects = this.online_users.filter(id => !Object.keys(data.content).includes(id));
//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));
@ -102,12 +165,137 @@ class Notice {
//console.log(this.data["invited"]);
}
this.data["online"] = Object.keys(data.content);
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)
create_popup("Friend ask error");
else if (send.status == 409)
create_popup("Already asked friend or already 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.getProfile(send.author_id);
if (this.data["asker"].includes(send.author_id))
create_popup(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) {
this.data["asked"] = send.asked;
this.data["asker"] = send.asker;
if (send.author_id == this.client.me.id) {
if (send.status == 400)
create_popup("Error remove Friend");
else if (send.status == 409)
create_popup("Not friend, wtf");
}
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
}
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.getProfile(send.author_id);
if (send.author_id == this.client.me.id) {
if (send.status == 400)
create_popup("Error accept Friend");
else if (send.status == 404)
create_popup("Not found request Friend");
else if (send.status == 409)
create_popup("Already Friend, wtf");
}
else {
create_popup(sender.username + " accept your friend request");
}
if (this.rewrite_profile !== undefined)
await this.rewrite_profile();
}
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.getProfile(send.author_id);
if (send.author_id == this.client.me.id) {
if (send.status == 400)
create_popup("Error refuse Friend");
else if (send.status == 404)
create_popup("Not found request Friend");
else if (send.status == 409)
create_popup("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

@ -148,7 +148,7 @@ class Client
async _patch_json(uri, data)
{
let response = await fetch(this._url + uri, {
method: "PATCH",
ethod: "PATCH",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Content-Type": "application/json",

View File

@ -31,6 +31,7 @@ class Profile
* @type {Boolean}
*/
this.isBlocked = false;
this.isFriend = false;
}
async init()
@ -45,23 +46,47 @@ class Profile
this.username = response_data.username;
this.avatar_url = response_data.avatar_url;
if (this.client.me == undefined)
return;
await this.getBlock();
await this.getFriend();
}
async getBlock() {
let block_response = await this.client._get("/api/profiles/block");
if (block_response.status != 200)
return
let block_data = await block_response.json();
let block_list = JSON.parse(block_data);
let block_list = JSON.parse(block_data["blockeds"]);
let client_id = block_data["user_id"];
block_list.forEach(block => {
let blocker = block.fields.blocker;
let blocked = block.fields.blocked;
if (blocker == this.client.me.user_id && blocked == user_id)
if (blocker == client_id && blocked == this.id)
return this.isBlocked = true;
});
}
async getFriend() {
let friend_response = await this.client._get("/api/profiles/friend");
this.isFriend = false;
if (friend_response.status != 200)
return this.isFriend;
let friend_data = await friend_response.json();
let friends_list = friend_data["friends"];
let client_id = friend_data["user_id"];
friends_list.forEach(friend => {
if (friend == this.id) {
this.isFriend = true;
return this.isFriend;
}
});
return this.isFriend;
}
}
export {Profile}

View File

@ -51,7 +51,7 @@ class Profiles
// blocker & blocked
let response = await this.client._post("/api/profiles/block", {
users_id:[this.client.me.user_id, user_id],
users_id:[this.client.me.id, user_id],
});
let data = await response.json();
@ -68,7 +68,7 @@ class Profiles
// blocker & blocked
let response = await this.client._delete("/api/profiles/block", {
users_id:[this.client.me.user_id, user_id],
users_id:[this.client.me.id, user_id],
});
let data = await response.json();

View File

@ -59,6 +59,7 @@ async function renderView(view)
let error_code = await view.postInit();
if (error_code === 404)
renderView(new PageNotFoundView());
else if (error_code === 403)

View File

@ -8,6 +8,7 @@ export default class extends AbstractView {
async getHtml() {
return `
<h1>404 Bozo</h1>
<img src="https://media.giphy.com/media/pm0BKtuBFpdM4/giphy.gif">
<p>Git gud</p>
`;
}

View File

@ -10,16 +10,17 @@ export default class extends AbstractView {
async postInit()
{
this.profile = await client.profiles.getProfile(this.username);
if (this.profile === null)
return 404;
this.userId = this.profile.id;
this.user_id = this.profile.id;
this.info = document.getElementById("info");
// Username
let username = document.createElement("a");
username.id = "username";
username.appendChild(document.createTextNode(this.profile.username));
username.appendChild(document.createTextNode(this.username));
this.info.appendChild(username);
this.info.appendChild(document.createElement("br"));
@ -31,6 +32,14 @@ export default class extends AbstractView {
this.info.appendChild(avatar);
await this.blockButton();
await this.friendButton();
client.notice.rewrite_profile = async () => {
let result = await this.profile.getFriend();
await this.profile.getBlock()
await this.friendButton();
}
}
async blockButton() {
@ -38,23 +47,82 @@ export default class extends AbstractView {
if (await client.isAuthentificate() === false)
return;
if (client.me.id != this.userId) {
let block = document.getElementById("block") || document.createElement("a");
if (client.me.id != this.user_id) {
let block = document.getElementById("block");
if (block == undefined) {
block = document.createElement("p");
this.info.appendChild(block);
}
block.id = "block";
block.innerText = "";
block.onclick = async () => {
if (!this.profile.isBlocked)
await client.profiles.block(this.userId);
else
await client.profiles.deblock(this.userId);
this.profile = await client.profiles.getProfile(this.username);
this.blockButton();
};
if (this.profile.isBlocked)
block.appendChild(document.createTextNode("Deblock"));
block.textContent = "Deblock";
else
block.appendChild(document.createTextNode("Block"));
this.info.appendChild(block);
block.textContent = "Block";
}
}
async friendButton() {
if (await client.isAuthentificate() === false)
return;
if (client.me.id != this.user_id) {
let yes = document.getElementById("yes") || document.createElement("p");
let no = document.getElementById("no") || document.createElement("p");
let friend = document.getElementById("friend") || document.createElement("p");
if (client.notice.data["asker"].includes(this.user_id)) {
if (friend)
friend.remove();
yes.id = "yes";
yes.textContent = "Accept Friend";
yes.onclick = async () => {
client.notice.accept_friend(this.user_id);
}
no.id = "no";
no.textContent = "Refuse Friend";
no.onclick = async () => {
client.notice.refuse_friend(this.user_id);
}
this.info.appendChild(yes);
this.info.appendChild(document.createTextNode(" "));
this.info.appendChild(no);
}
else {
if (yes && no)
yes.remove(); no.remove();
friend.id = "friend"
friend.onclick = async () => {
if (this.profile.isFriend)
await client.notice.remove_friend(this.user_id);
else
await client.notice.ask_friend(this.user_id);
await client.profiles.getProfile(this.username);
this.friendButton();
};
if (this.profile.isFriend)
friend.textContent = "Remove Friend";
else {
friend.textContent = "Ask Friend";
}
this.info.appendChild(friend);
}
}
}

View File

@ -10,12 +10,12 @@ export default class extends AbstractView {
async wait_get_online_users() {
return new Promise((resolve) => {
const checkInterval = setInterval(() => {
//console.log(client.notice.data["online"].length);
if (client.notice.data["online"].length > 0) {
console.log(client.notice.data["online"]);
if (Object.keys(client.notice.data["online"]).length > 0) {
clearInterval(checkInterval);
resolve();
}
}, 100);
}, 1);
});
}
@ -29,11 +29,13 @@ export default class extends AbstractView {
return console.log("Error");
//await client.notice.getOnlineUser();
await this.wait_get_online_users();
//await this.wait_get_online_users();
client.notice.rewrite_usernames = this.rewrite_usernames;
client.notice.rewrite_invite = this.display_invite;
let search = document.getElementById("input_user");
search.oninput = () => this.display_users(logged, profiles);
if (search != undefined)
search.oninput = () => this.display_users(logged, profiles);
let chat_input = document.getElementById("input_chat");
//chat_input.addEventListener("keydown", this.display_chat_manager)
@ -66,7 +68,12 @@ export default class extends AbstractView {
username.setAttribute('data-link', '');
username.id = `username${user.id}`
username.href = `/profiles/${user.username}`;
username.style.color = client.notice.data["online"].includes(user.id.toString()) ? "green" : "red";
if (user.id == client.me.id)
username.style.color = "green";
else {
let online = client.notice.data["online"][user.id];
username.style.color = online !== undefined ? online : "gray";
}
username.appendChild(document.createTextNode(user.username));
new_user.appendChild(username);
@ -135,8 +142,14 @@ export default class extends AbstractView {
profiles.filter(user => user.username.toLowerCase().startsWith(search) == true).forEach((user) => {
let username = document.getElementById(`username${user.id}`);
if (username !== null)
username.style.color = client.notice.data["online"].includes(user.id.toString()) ? "green" : "red";
if (username !== null) {
if (user.id == client.me.id)
username.style.color = "green";
else {
let online = client.notice.data["online"][user.id];
username.style.color = online !== undefined ? online : "gray";
}
}
});
}
@ -175,13 +188,15 @@ export default class extends AbstractView {
chat_input.maxLength=255;
chat.appendChild(chat_input);
let members_id = client.channels.channel.members_id;
chat_input.onkeydown = async () => {
if (event.keyCode == 13 && client.channels.channel != undefined) {
//let chat_input = document.getElementById("input_chat");
let chat_text = chat_input.value;
let receivers_id = [];
client.channels.channel.members_id.forEach((member_id) => {
members_id.forEach((member_id) => {
if (member_id != client.me.id)
receivers_id.push(profiles.filter(user => user.id == member_id)[0].id);
});
@ -196,7 +211,7 @@ export default class extends AbstractView {
// Scroll to the bottom of messages
messages.scrollTop = messages.scrollHeight;
this.display_invite(chat);
this.display_invite();
}
@ -242,33 +257,86 @@ export default class extends AbstractView {
}
async display_members(chat, profiles) {
let members_id = client.channels.channel.members_id;
let members = document.createElement("h2");
members.id = "members";
let usernames = "";
client.channels.channel.members_id.forEach((member_id) => {
members_id.forEach((member_id) => {
if (member_id != client.me.id) {
if (usernames.length > 0)
usernames += ", ";
usernames += (profiles.filter(user => user.id == member_id)[0].username);
}
});
members.appendChild(document.createTextNode(usernames));
members.textContent = usernames;
chat.appendChild(members);
return members
}
async display_invite(chat, profiles) {
async display_invite() {
let chat = document.getElementById("chat");
if (chat == undefined)
return ;
let members_id = client.channels.channel.members_id;
let others = members_id.filter(id => id !== client.me.id);
// Button to send invite to play
let invite = document.getElementById("invite") || document.createElement("button");
invite.id = "invite";
invite.innerText = "invite";
invite.onclick = async () => {
await client.notice.sendInvite(client.me.id,
client.channels.channel.members_id.filter(id => id !== client.me.id));
};
chat.appendChild(invite);
let yes = document.getElementById("yes") || document.createElement("button");
let no = document.getElementById("no") || document.createElement("button");
let invitedBy = undefined;
for (let x in others) {
if (client.notice.data["invited"].includes(others[x])) {
invitedBy = others[x];
}
}
if (invitedBy == undefined) {
if (yes && no) {
yes.remove();
no.remove();
}
// Button to send invite to play
invite.id = "invite";
invite.style.background = "orange";
invite.innerText = "invite";
invite.title = "Invite to play a game"
invite.onclick = async () => {
await client.notice.send_invite(others);
};
chat.appendChild(invite);
}
else {
if (invite)
invite.remove()
yes.id = "yes";
yes.style.background = "green";
yes.title = "Accept to play a game"
yes.onclick = async () => {
await client.notice.accept_invite(invitedBy);
};
no.id = "no";
no.style.background = "red";
no.title = "Refuse to play a game"
no.onclick = async () => {
await client.notice.refuse_invite(invitedBy);
};
chat.appendChild(yes);
chat.appendChild(no);
}
}

View File

@ -1,7 +1,9 @@
from django.contrib import admin
from .models import ProfileModel, BlockModel
from .models import ProfileModel, BlockModel, FriendModel, AskFriendModel
# Register your models here.
admin.site.register(ProfileModel)
admin.site.register(BlockModel)
admin.site.register(FriendModel)
admin.site.register(AskFriendModel)

View File

@ -35,3 +35,67 @@ class BlockModel(models.Model):
def __str__(self):
return "blocker_id: " + str(self.blocker) + ", blocked_id: " + str(self.blocked)
class AskFriendModel(models.Model):
asker = IntegerField(primary_key=False)
asked = IntegerField(primary_key=False)
def getAsked(self, asker):
askeds = []
for ask in AskFriendModel.objects.filter(asker=asker):
askeds.append(ask.asked)
return askeds
def getAsker(self, asked):
askers = []
for ask in AskFriendModel.objects.filter(asked=asked):
askers.append(ask.asker)
return askers
def deleteAsk(self, asker, asked):
deleted = AskFriendModel.objects.filter(asker=asker, asked=asked)
if (deleted.count() == 0 or not deleted):
return False
deleted.delete()
return True
class FriendModel(models.Model):
user_id1 = IntegerField(primary_key=False)
user_id2 = IntegerField(primary_key=False)
def getFriends(self, user_id):
friends = []
for friend in FriendModel.objects.filter(user_id1=user_id):
friends.append(friend.user_id2)
for friend in FriendModel.objects.filter(user_id2=user_id):
friends.append(friend.user_id1)
return friends
def isFriend(self, user_id1, user_id2):
return user_id2 in self.getFriends(user_id1)
def deleteFriend(self, user_id1, user_id2):
first = FriendModel.objects.filter(user_id1=user_id1, user_id2=user_id2)
if (first.count() == 1):
first.delete()
return True
second = FriendModel.objects.filter(user_id1=user_id2, user_id2=user_id1)
if (second.count() == 1):
second.delete()
return True
return False

View File

@ -11,5 +11,6 @@ urlpatterns = [
path("block", views.BlocksView.as_view(), name="block_page"),
path("block/<int:pk>", views.BlockView.as_view(), name="block_page"),
path("<str:username>", viewsets.ProfileViewSet.as_view({'get': 'retrieve'}), name="profile_page"),
path("friend", views.FriendsView.as_view(), name="friend_page"),
] + static("/static/avatars/", document_root="./avatars")

View File

@ -4,7 +4,7 @@ from rest_framework import authentication, permissions, status
from rest_framework.authentication import SessionAuthentication
from rest_framework.renderers import JSONRenderer
from django.core import serializers
from .models import BlockModel
from .models import BlockModel, FriendModel
class BlockView(APIView):
permission_classes = (permissions.IsAuthenticated,)
@ -25,7 +25,7 @@ class BlocksView(APIView):
def get(self, request):
blocks = BlockModel.objects.filter(blocker=request.user.pk)
if (blocks):
return Response(serializers.serialize("json", BlockModel.objects.filter(blocker=request.user.pk)), status=status.HTTP_200_OK)
return Response({"blockeds": serializers.serialize("json", BlockModel.objects.filter(blocker=request.user.pk)), "user_id": request.user.pk}, status=status.HTTP_200_OK)
return Response({}, status=status.HTTP_204_NO_CONTENT)
def post(self, request):
@ -33,7 +33,10 @@ class BlocksView(APIView):
users_id = request.data.get("users_id", None)
if (users_id == None):
return Response({"Error"}, status=status.HTTP_400_BAD_REQUEST)
return Response({"Error send None"}, status=status.HTTP_400_BAD_REQUEST)
if (users_id[0] == None or users_id[1] == None):
return Response({"Error send blocker/ed None"}, status=status.HTTP_400_BAD_REQUEST)
if (BlockModel.objects.filter(blocker=users_id[0], blocked=users_id[1])):
return Response({"Already Exist"}, status=status.HTTP_409_CONFLICT)
@ -52,9 +55,11 @@ class BlocksView(APIView):
if (users_id == None):
return Response({"Error"}, status=status.HTTP_400_BAD_REQUEST)
if (users_id[0] == None or users_id[1] == None):
return Response({"Error send blocker/ed None"}, status=status.HTTP_400_BAD_REQUEST)
block = BlockModel.objects.filter(blocker=users_id[0], blocked=users_id[1])
print(list(block))
if (block.count() > 1):
return Response("Not normal >:[", status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@ -63,3 +68,11 @@ class BlocksView(APIView):
block.delete()
return Response("Deleted", status=status.HTTP_200_OK)
class FriendsView(APIView):
def get(self, request):
friends = FriendModel().getFriends(request.user.pk)
if (friends):
return Response({"friends": friends, "user_id": request.user.pk}, status=status.HTTP_200_OK)
return Response({}, status=status.HTTP_204_NO_CONTENT)