profiles: online status and friend rework
This commit is contained in:
parent
c2aafe9a42
commit
17bcee764b
@ -4,8 +4,8 @@ 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 "./notice/Notice.js";
|
|
||||||
import { Channel } from "./chat/Channel.js";
|
import { Channel } from "./chat/Channel.js";
|
||||||
|
import Notice from "./Notice.js";
|
||||||
import LanguageManager from './LanguageManager.js';
|
import LanguageManager from './LanguageManager.js';
|
||||||
|
|
||||||
function getCookie(name)
|
function getCookie(name)
|
||||||
|
@ -15,26 +15,26 @@ class MyProfile extends Profile
|
|||||||
* @type {[Profile]}
|
* @type {[Profile]}
|
||||||
*/
|
*/
|
||||||
this.blockedUsers = [];
|
this.blockedUsers = [];
|
||||||
/**
|
// /**
|
||||||
* @type {[Profile]}
|
// * @type {[Profile]}
|
||||||
*/
|
// */
|
||||||
this.friendList = [];
|
// this.friendList = [];
|
||||||
/**
|
// /**
|
||||||
* @type {[Profile]}
|
// * @type {[Profile]}
|
||||||
*/
|
// */
|
||||||
this.incomingFriendRequests = [];
|
// this.incomingFriendRequests = [];
|
||||||
/**
|
// /**
|
||||||
* @type {[Profile]}
|
// * @type {[Profile]}
|
||||||
*/
|
// */
|
||||||
this.outgoingFriendRequests = [];
|
// this.outgoingFriendRequests = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await super.init();
|
await super.init();
|
||||||
await this.getBlockedUsers();
|
await this.getBlockedUsers();
|
||||||
await this.getFriends();
|
// await this.getFriends();
|
||||||
await this.getIncomingFriendRequests()
|
// await this.getIncomingFriendRequests()
|
||||||
await this.getOutgoingFriendRequests()
|
// await this.getOutgoingFriendRequests()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlockedUsers() {
|
async getBlockedUsers() {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import {Client} from '../Client.js';
|
import {Client} from './Client.js';
|
||||||
import {createNotification} from '../../utils/noticeUtils.js'
|
import {createNotification} from '../utils/noticeUtils.js'
|
||||||
import { client, lastView } from '../../index.js';
|
import { lastView } from '../index.js';
|
||||||
import { Profile } from '../Profile.js';
|
import ProfilePageView from '../views/ProfilePageView.js';
|
||||||
import ProfilePageView from '../../views/ProfilePageView.js';
|
|
||||||
|
|
||||||
export default class Notice {
|
export default class Notice {
|
||||||
|
|
||||||
@ -23,6 +22,7 @@ export default class Notice {
|
|||||||
this._socket.onclose = _ => this._socket = undefined;
|
this._socket.onclose = _ => this._socket = undefined;
|
||||||
this._socket.onmessage = message => {
|
this._socket.onmessage = message => {
|
||||||
const data = JSON.parse(message.data);
|
const data = JSON.parse(message.data);
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
if (data.type === 'friend_request') {
|
if (data.type === 'friend_request') {
|
||||||
this.friend_request(data.author);
|
this.friend_request(data.author);
|
||||||
@ -32,6 +32,10 @@ export default class Notice {
|
|||||||
this.friend_removed(data.friend);
|
this.friend_removed(data.friend);
|
||||||
} else if (data.type === 'friend_request_canceled') {
|
} else if (data.type === 'friend_request_canceled') {
|
||||||
this.friend_request_canceled(data.author);
|
this.friend_request_canceled(data.author);
|
||||||
|
} else if (data.type === 'online') {
|
||||||
|
this.online(data.user)
|
||||||
|
} else if (data.type === 'offline') {
|
||||||
|
this.offline(data.user)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -43,8 +47,22 @@ export default class Notice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setOnlineStatus(user, status) {
|
||||||
|
if (lastView instanceof ProfilePageView && lastView.profile.id === user.id) {
|
||||||
|
lastView.profile.online = status;
|
||||||
|
lastView.loadFriendshipStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
online(user) {
|
||||||
|
this._setOnlineStatus(user, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
offline(user) {
|
||||||
|
this._setOnlineStatus(user, false)
|
||||||
|
}
|
||||||
|
|
||||||
friend_request(author) {
|
friend_request(author) {
|
||||||
client.me.incomingFriendRequests.push(new Profile(author.username, author.id, author.avatar));
|
|
||||||
createNotification('Friend Request', `<strong>${author.username}</strong> sent you a friend request.`);
|
createNotification('Friend Request', `<strong>${author.username}</strong> sent you a friend request.`);
|
||||||
if (lastView instanceof ProfilePageView && lastView.profile.id === author.id) {
|
if (lastView instanceof ProfilePageView && lastView.profile.id === author.id) {
|
||||||
lastView.profile.hasIncomingRequest = true;
|
lastView.profile.hasIncomingRequest = true;
|
||||||
@ -53,7 +71,6 @@ export default class Notice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new_friend(friend) {
|
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.`);
|
createNotification('New Friend', `<strong>${friend.username}</strong> accepted your friend request.`);
|
||||||
if (lastView instanceof ProfilePageView && lastView.profile.id === friend.id) {
|
if (lastView instanceof ProfilePageView && lastView.profile.id === friend.id) {
|
||||||
lastView.profile.isFriend = true;
|
lastView.profile.isFriend = true;
|
||||||
@ -64,15 +81,14 @@ export default class Notice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend_removed(exFriend) {
|
friend_removed(exFriend) {
|
||||||
client.me.friendList = client.me.friendList.filter(friend => friend.id !== exFriend.id);
|
|
||||||
if (lastView instanceof ProfilePageView && lastView.profile.id === exFriend.id) {
|
if (lastView instanceof ProfilePageView && lastView.profile.id === exFriend.id) {
|
||||||
lastView.profile.isFriend = false;
|
lastView.profile.isFriend = false;
|
||||||
|
lastView.profile.online = null;
|
||||||
lastView.loadFriendshipStatus();
|
lastView.loadFriendshipStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend_request_canceled(author) {
|
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) {
|
if (lastView instanceof ProfilePageView && lastView.profile.id === author.id) {
|
||||||
lastView.profile.hasIncomingRequest = false;
|
lastView.profile.hasIncomingRequest = false;
|
||||||
lastView.loadFriendshipStatus();
|
lastView.loadFriendshipStatus();
|
@ -59,19 +59,19 @@ export class Profile extends AExchangeable
|
|||||||
if (response.status !== 200)
|
if (response.status !== 200)
|
||||||
return response.status;
|
return response.status;
|
||||||
|
|
||||||
let response_data = await response.json();
|
const responseData = await response.json();
|
||||||
this.id = response_data.id;
|
this.id = responseData.id;
|
||||||
this.username = response_data.username;
|
this.username = responseData.username;
|
||||||
this.avatar = response_data.avatar;
|
this.avatar = responseData.avatar;
|
||||||
this.online = response_data.online
|
this.online = responseData.online
|
||||||
|
|
||||||
if (!this.client.me || this.client.me.id === this.id)
|
if (!this.client.me || this.client.me.id === this.id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.hasIncomingRequest = responseData.has_incoming_request;
|
||||||
|
this.hasOutgoingRequest = responseData.has_outgoing_request;
|
||||||
|
this.isFriend = responseData.is_friend;
|
||||||
this.isBlocked = this.client.me._isBlocked(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,8 @@ export default class extends AbstractView {
|
|||||||
|
|
||||||
loadFriendshipStatus() {
|
loadFriendshipStatus() {
|
||||||
const addFriendButton = document.getElementById('addFriendButton'),
|
const addFriendButton = document.getElementById('addFriendButton'),
|
||||||
removeFriendButton = document.getElementById('removeFriendButton');
|
removeFriendButton = document.getElementById('removeFriendButton'),
|
||||||
|
statusIndicator = document.getElementById('statusIndicator');
|
||||||
|
|
||||||
if (this.profile.hasIncomingRequest) {
|
if (this.profile.hasIncomingRequest) {
|
||||||
removeFriendButton.classList.add('d-none');
|
removeFriendButton.classList.add('d-none');
|
||||||
@ -59,6 +60,12 @@ export default class extends AbstractView {
|
|||||||
removeFriendButton.classList.add('d-none');
|
removeFriendButton.classList.add('d-none');
|
||||||
addFriendButton.classList.remove('d-none');
|
addFriendButton.classList.remove('d-none');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statusIndicator.classList.remove('bg-success', 'bg-danger');
|
||||||
|
if (this.profile.online === true)
|
||||||
|
statusIndicator.classList.add('bg-success');
|
||||||
|
else if (this.profile.online === false)
|
||||||
|
statusIndicator.classList.add('bg-danger');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHtml() {
|
async getHtml() {
|
||||||
@ -70,7 +77,7 @@ export default class extends AbstractView {
|
|||||||
return `
|
return `
|
||||||
<div>
|
<div>
|
||||||
<div class='mb-3' id='profileInfo'>
|
<div class='mb-3' id='profileInfo'>
|
||||||
<h1>${this.username}</h1>
|
<h1>${this.username}<span id='statusIndicator' style='height:0.75em; width:0.75em' class='ms-2 rounded-circle border d-inline-block'></span></h1>
|
||||||
<a href=${this.profile.avatar} target='_blank'>
|
<a href=${this.profile.avatar} target='_blank'>
|
||||||
<img class='img-thumbnail' src=${this.profile.avatar} style='width:auto; max-height:20vh; min-height:10vh'>
|
<img class='img-thumbnail' src=${this.profile.avatar} style='width:auto; max-height:20vh; min-height:10vh'>
|
||||||
</a>
|
</a>
|
||||||
@ -99,20 +106,18 @@ export default class extends AbstractView {
|
|||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
removeFriendButton.innerHTML = 'Cancel Request';
|
removeFriendButton.innerHTML = 'Cancel Request';
|
||||||
removeFriendButton.classList.replace('btn-danger', 'btn-secondary');
|
removeFriendButton.classList.replace('btn-danger', 'btn-secondary');
|
||||||
client.me.outgoingFriendRequests.push(this.profile);
|
|
||||||
this.profile.hasOutgoingRequest = true;
|
this.profile.hasOutgoingRequest = true;
|
||||||
} else if (response.status === 201) {
|
} else if (response.status === 201) {
|
||||||
removeFriendButton.innerHTML = 'Remove Friend';
|
removeFriendButton.innerHTML = 'Remove Friend';
|
||||||
removeFriendButton.classList.replace('btn-secondary', 'btn-danger');
|
removeFriendButton.classList.replace('btn-secondary', 'btn-danger');
|
||||||
this.profile.friend = true;
|
this.profile.isFriend = true;
|
||||||
this.profile.hasIncomingRequest = false;
|
this.profile.hasIncomingRequest = false;
|
||||||
client.me.incomingFriendRequests = client.me.incomingFriendRequests.filter(profile => profile.id !== this.profile.id);
|
|
||||||
client.me.friendList.push(this.profile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeFriend() {
|
async removeFriend() {
|
||||||
const addFriendButton = document.getElementById('addFriendButton');
|
const addFriendButton = document.getElementById('addFriendButton'),
|
||||||
|
statusIndicator = document.getElementById('statusIndicator');
|
||||||
|
|
||||||
const response = await client._delete(`/api/profiles/friends/${this.profile.id}`);
|
const response = await client._delete(`/api/profiles/friends/${this.profile.id}`);
|
||||||
const body = await response.json();
|
const body = await response.json();
|
||||||
@ -121,14 +126,14 @@ export default class extends AbstractView {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
addFriendButton.innerHTML = 'Add Friend';
|
addFriendButton.innerHTML = 'Add Friend';
|
||||||
addFriendButton.classList.remove('d-none');
|
addFriendButton.classList.remove('d-none');
|
||||||
|
statusIndicator.classList.remove('bg-danger', 'bg-success');
|
||||||
document.getElementById('removeFriendButton').classList.add('d-none');
|
document.getElementById('removeFriendButton').classList.add('d-none');
|
||||||
}
|
}
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.profile.hasOutgoingRequest = false;
|
this.profile.hasOutgoingRequest = false;
|
||||||
client.me.outgoingFriendRequests = client.me.outgoingFriendRequests.filter(profile => profile.id !== this.profile.id);
|
|
||||||
} else if (response.status === 201) {
|
} else if (response.status === 201) {
|
||||||
this.profile.isFriend = false;
|
this.profile.isFriend = false;
|
||||||
client.me.friendList = client.me.friendList.filter(friend => friend.id !== this.profile.id);
|
this.profile.online = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,14 @@ class NoticeManager:
|
|||||||
consumer.send(notice.data)
|
consumer.send(notice.data)
|
||||||
notice.delete()
|
notice.delete()
|
||||||
|
|
||||||
|
for friend in consumer.user.profilemodel.get_friends():
|
||||||
|
self.notify_user(friend.user, {'type': 'online',
|
||||||
|
'user': ProfileSerializer(consumer.user.profilemodel).data})
|
||||||
|
|
||||||
def remove(self, consumer: NoticeConsumer):
|
def remove(self, consumer: NoticeConsumer):
|
||||||
|
for friend in consumer.user.profilemodel.get_friends():
|
||||||
|
self.notify_user(friend.user, {'type': 'offline',
|
||||||
|
'user': ProfileSerializer(consumer.user.profilemodel).data})
|
||||||
self._list.remove(consumer)
|
self._list.remove(consumer)
|
||||||
|
|
||||||
def get_consumer_by_user(self, user: User):
|
def get_consumer_by_user(self, user: User):
|
||||||
@ -44,7 +51,16 @@ class NoticeManager:
|
|||||||
self.notify_user(user, {'type': 'friend_request_canceled', 'author': ProfileSerializer(friend).data})
|
self.notify_user(user, {'type': 'friend_request_canceled', 'author': ProfileSerializer(friend).data})
|
||||||
|
|
||||||
def notify_new_friend(self, user: User, friend: ProfileModel):
|
def notify_new_friend(self, user: User, friend: ProfileModel):
|
||||||
self.notify_user(user, {'type': 'new_friend', 'friend': ProfileSerializer(friend).data})
|
serialized_data = ProfileSerializer(friend).data
|
||||||
|
if self.get_consumer_by_user(user) is not None:
|
||||||
|
status = 'online'
|
||||||
|
else:
|
||||||
|
status = 'offline'
|
||||||
|
print(status)
|
||||||
|
|
||||||
|
self.notify_user(user, {'type': 'new_friend', 'friend': serialized_data})
|
||||||
|
self.notify_user(user, {'type': 'online', 'user': serialized_data})
|
||||||
|
self.notify_user(friend.user, {'type': status, 'user': ProfileSerializer(user.profilemodel).data})
|
||||||
|
|
||||||
def notify_friend_removed(self, user: User, friend: ProfileModel):
|
def notify_friend_removed(self, user: User, friend: ProfileModel):
|
||||||
self.notify_user(user, {'type': 'friend_removed', 'friend': ProfileSerializer(friend).data})
|
self.notify_user(user, {'type': 'friend_removed', 'friend': ProfileSerializer(friend).data})
|
||||||
|
@ -11,19 +11,19 @@ class ProfileSerializer(serializers.ModelSerializer):
|
|||||||
username = serializers.ReadOnlyField(source='user.username')
|
username = serializers.ReadOnlyField(source='user.username')
|
||||||
avatar = serializers.ImageField(required=False)
|
avatar = serializers.ImageField(required=False)
|
||||||
online = serializers.SerializerMethodField()
|
online = serializers.SerializerMethodField()
|
||||||
|
is_friend = serializers.SerializerMethodField()
|
||||||
|
has_incoming_request = serializers.SerializerMethodField()
|
||||||
|
has_outgoing_request = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProfileModel
|
model = ProfileModel
|
||||||
fields = ["username", "avatar", "id", 'online']
|
fields = ["username", "avatar", "id", 'online', 'is_friend',
|
||||||
|
'has_outgoing_request', 'has_incoming_request']
|
||||||
|
|
||||||
def get_online(self, obj: ProfileModel):
|
def get_online(self, obj: ProfileModel):
|
||||||
from notice.consumers import notice_manager
|
from notice.consumers import notice_manager
|
||||||
|
|
||||||
user = None
|
user = self.context.get('user')
|
||||||
request = self.context.get("request")
|
|
||||||
if request and hasattr(request, "user"):
|
|
||||||
user = request.user
|
|
||||||
|
|
||||||
if user is None or not user.is_authenticated:
|
if user is None or not user.is_authenticated:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -32,6 +32,27 @@ class ProfileSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
return notice_manager.get_consumer_by_user(obj.user) is not None
|
return notice_manager.get_consumer_by_user(obj.user) is not None
|
||||||
|
|
||||||
|
def get_is_friend(self, obj: ProfileModel):
|
||||||
|
user = self.context.get('user')
|
||||||
|
if user is None or not user.is_authenticated or user.pk == obj.pk:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return obj.is_friend(user.profilemodel)
|
||||||
|
|
||||||
|
def get_has_incoming_request(self, obj: ProfileModel):
|
||||||
|
user = self.context.get('user')
|
||||||
|
if user is None or not user.is_authenticated or user.pk == obj.pk:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return obj.is_friend_requesting(user.profilemodel)
|
||||||
|
|
||||||
|
def get_has_outgoing_request(self, obj: ProfileModel):
|
||||||
|
user = self.context.get('user')
|
||||||
|
if user is None or not user.is_authenticated or user.pk == obj.pk:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return obj.is_friend_requested_by(user.profilemodel)
|
||||||
|
|
||||||
def validate_avatar(self, value):
|
def validate_avatar(self, value):
|
||||||
'''
|
'''
|
||||||
Check that the image is not too large
|
Check that the image is not too large
|
||||||
|
@ -35,4 +35,4 @@ class MyProfileViewSet(viewsets.ModelViewSet):
|
|||||||
return Response(ProfileSerializer(profile).data)
|
return Response(ProfileSerializer(profile).data)
|
||||||
|
|
||||||
def retrieve(self, pk=None):
|
def retrieve(self, pk=None):
|
||||||
return Response(self.serializer_class(self.get_object(), context={'request': self.request}).data)
|
return Response(self.serializer_class(self.get_object(), context={'user': self.request.user}).data)
|
||||||
|
@ -16,12 +16,12 @@ class ProfileViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
def retrieve(self, request, username=None):
|
def retrieve(self, request, username=None):
|
||||||
user = get_object_or_404(User, username=username)
|
user = get_object_or_404(User, username=username)
|
||||||
return Response(self.serializer_class(user.profilemodel, context={'request': request}).data)
|
return Response(self.serializer_class(user.profilemodel, context={'user': request.user}).data)
|
||||||
|
|
||||||
def retrieve_id(self, request, pk=None):
|
def retrieve_id(self, request, pk=None):
|
||||||
user = get_object_or_404(User, pk=pk)
|
user = get_object_or_404(User, pk=pk)
|
||||||
return Response(self.serializer_class(user.profilemodel, context={'request': request}).data)
|
return Response(self.serializer_class(user.profilemodel, context={'user': request.user}).data)
|
||||||
|
|
||||||
def list(self, request):
|
def list(self, request):
|
||||||
serializer = ProfileSerializer(self.get_queryset(), many=True, context={'request': request})
|
serializer = ProfileSerializer(self.get_queryset(), many=True, context={'user': request.user})
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
Loading…
Reference in New Issue
Block a user