Browse Source

* Fixed race condition in leave channel

* Blocking users now updates instantly
* Fixed leaderboard not updating after a pong match
master
vvandenb 2 years ago
parent
commit
f85c293e8f
  1. 13
      back/src/chat/chat.gateway.ts
  2. 2
      back/src/chat/message.service.ts
  3. 1
      back/src/pong/pong.service.ts
  4. 2
      back/src/users/users.controller.ts
  5. 7
      front/src/App.svelte
  6. 5
      front/src/components/Channels.svelte
  7. 54
      front/src/components/Chat.svelte

13
back/src/chat/chat.gateway.ts

@ -48,10 +48,9 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
socket: socket.id socket: socket.id
}); });
if (connect) { if (connect) {
console.log('socket %s has disconnected', socket.id)
await this.connectedUserRepository.delete({ user: connect.user }) await this.connectedUserRepository.delete({ user: connect.user })
} }
socket.disconnect()
console.log('socket %s has disconnected', socket.id)
} }
@SubscribeMessage('joinChannel') @SubscribeMessage('joinChannel')
@ -90,15 +89,16 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
} }
@SubscribeMessage('leaveChannel') @SubscribeMessage('leaveChannel')
async onLeaveChannel(socket: Socket): Promise<void> { async onLeaveChannel(socket: Socket): Promise<boolean> {
console.log('socket %s has left channel', socket.id)
const connect = await this.connectedUserRepository.findOneBy({ const connect = await this.connectedUserRepository.findOneBy({
socket: socket.id, socket: socket.id,
}); });
if (connect == null) return; if (connect == null) return false;
const channel = await this.chatService.getFullChannel(connect.channel); const channel = await this.chatService.getFullChannel(connect.channel);
socket.disconnect();
if (connect.user === channel.owner.ftId) { if (connect.user === channel.owner.ftId) {
this.server.in(channel.id.toString()).disconnectSockets(); this.server.in(channel.id.toString()).emit('kicked');
await this.chatService.removeChannel(channel.id); await this.chatService.removeChannel(channel.id);
} else { } else {
channel.users = channel.users.filter((usr: User) => usr.ftId !== connect.user); channel.users = channel.users.filter((usr: User) => usr.ftId !== connect.user);
@ -106,6 +106,7 @@ export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
await this.chatService.save(channel); await this.chatService.save(channel);
} }
await this.connectedUserRepository.delete({ socket: socket.id }); await this.connectedUserRepository.delete({ socket: socket.id });
return true;
} }
@SubscribeMessage('addMessage') @SubscribeMessage('addMessage')

2
back/src/chat/message.service.ts

@ -41,6 +41,6 @@ export class MessageService {
messages.forEach((msg) => { messages.forEach((msg) => {
msg.author.socketKey = '' msg.author.socketKey = ''
}) })
return messages.filter((m) => !blockeds.includes(m.author.ftId)) return messages
} }
} }

1
back/src/pong/pong.service.ts

@ -59,6 +59,7 @@ export class PongService {
await this.resultsRepository.save(result) await this.resultsRepository.save(result)
await this.updatePlayer(0, result, nameWhoWon) await this.updatePlayer(0, result, nameWhoWon)
await this.updatePlayer(1, result, nameWhoWon) await this.updatePlayer(1, result, nameWhoWon)
await this.usersService.getLeaderboard()
} }
async getHistory ( async getHistory (

2
back/src/users/users.controller.ts

@ -74,7 +74,7 @@ export class UsersController {
user.blocked = user.blocked.filter((usr: User) => { user.blocked = user.blocked.filter((usr: User) => {
return usr.ftId !== id return usr.ftId !== id
}) })
if (lenBefore === user.blocked.length) throw new BadRequestException('User not found') if (lenBefore === user.blocked.length) throw new BadRequestException('User not blocked')
await this.usersService.save(user) await this.usersService.save(user)
} }

7
front/src/App.svelte

@ -11,7 +11,6 @@
MATCHMAKING = "/matchmaking", MATCHMAKING = "/matchmaking",
PROFILE_ID = "/profile_id", PROFILE_ID = "/profile_id",
} }
</script> </script>
<script lang="ts"> <script lang="ts">
@ -22,13 +21,11 @@
import MatchHistory from "./components/MatchHistory.svelte"; import MatchHistory from "./components/MatchHistory.svelte";
import Friends, { addFriend } from "./components/Friends.svelte"; import Friends, { addFriend } from "./components/Friends.svelte";
import Chat from "./components/Chat.svelte"; import Chat from "./components/Chat.svelte";
import Channels, { formatChannelNames, type chatMessagesType } from "./components/Channels.svelte"; import Channels from "./components/Channels.svelte";
import Leaderboard from "./components/Leaderboard.svelte"; import Leaderboard from "./components/Leaderboard.svelte";
import { popup, show_popup } from "./components/Alert/content"; import { popup } from "./components/Alert/content";
import Pong from "./components/Pong/Pong.svelte"; import Pong from "./components/Pong/Pong.svelte";
import type { ChannelsType } from "./components/Channels.svelte"; import type { ChannelsType } from "./components/Channels.svelte";
import { API_URL } from "./Auth";
import { store, getUser, login, verify } from "./Auth"; import { store, getUser, login, verify } from "./Auth";
// Single Page Application config // Single Page Application config

5
front/src/components/Channels.svelte

@ -20,11 +20,14 @@
muted: Array<User>; muted: Array<User>;
isDM: boolean; isDM: boolean;
} }
export interface chatMessagesType { export interface ChatMessageServer {
id: number; id: number;
author: User; author: User;
text: string; text: string;
} }
export interface ChatMessage extends ChatMessageServer {
hidden: boolean;
}
export async function formatChannelNames(channel: Array<ChannelsType>): Promise<void> { export async function formatChannelNames(channel: Array<ChannelsType>): Promise<void> {
const res = await fetch(API_URL + "/users/all", { const res = await fetch(API_URL + "/users/all", {

54
front/src/components/Chat.svelte

@ -4,19 +4,18 @@
import { io, Socket } from "socket.io-client"; import { io, Socket } from "socket.io-client";
import { show_popup, content } from "./Alert/content"; import { show_popup, content } from "./Alert/content";
import { APPSTATE } from "../App.svelte"; import { APPSTATE } from "../App.svelte";
import { formatChannelNames, type ChannelsType, type chatMessagesType } from "./Channels.svelte"; import { formatChannelNames, type ChannelsType, type ChatMessage, type ChatMessageServer } from "./Channels.svelte";
import type User from "./Profile.svelte"; import type User from "./Profile.svelte";
import type { CreateChannelDto } from "./dtos/create-channel.dto"; import type { CreateChannelDto } from "./dtos/create-channel.dto";
import type { IdDto, MuteDto } from "./dtos/updateUser.dto"; import type { IdDto, MuteDto } from "./dtos/updateUser.dto";
import type { ConnectionDto } from "./dtos/connection.dto"; import type { ConnectionDto } from "./dtos/connection.dto";
import type { CreateMessageDto } from "./dtos/create-message.dto"; import type { CreateMessageDto } from "./dtos/create-message.dto";
import type { kickUserDto } from "./dtos/kickUser.dto"; import type { kickUserDto } from "./dtos/kickUser.dto";
</script> </script>
<script lang="ts"> <script lang="ts">
export let channel: ChannelsType; export let channel: ChannelsType;
export let messages: Array<chatMessagesType> = []; export let messages: Array<ChatMessage> = [];
export let appState: string; export let appState: string;
export let setAppState: (newState: APPSTATE | string) => void; export let setAppState: (newState: APPSTATE | string) => void;
@ -67,20 +66,27 @@
}; };
socket.emit("joinChannel", data); socket.emit("joinChannel", data);
} }
socket.on("newMessage", (msg: chatMessagesType) => {
console.log(msg); socket.on("newMessage", (serverMsg: ChatMessageServer) => {
if (blockedUsers.findIndex((user) => msg.author.ftId === user.ftId) === -1) console.log(serverMsg);
messages = [...messages, msg]; const newMsg: ChatMessage = {...serverMsg, hidden: false};
if (blockedUsers.some((user) => newMsg.author.ftId === user.ftId))
newMsg.hidden = true;
messages = [...messages, newMsg];
}); });
socket.on("messages", (msgs: Array<chatMessagesType>) => { socket.on("messages", (msgs: Array<ChatMessageServer>) => {
messages = msgs;
getMembers().then(() => { getMembers().then(() => {
console.log("You are joining channel: ", channel.name); console.log("You are joining channel: ", channel.name);
console.log(`Blocked users: ${blockedUsers.map((user) => user.username)}`); console.log(`Blocked users: ${blockedUsers.map((user) => user.username)}`);
console.log(`Chat members: ${chatMembers.map((user) => user.username)}`); console.log(`Chat members: ${chatMembers.map((user) => user.username)}`);
console.log(`Banned members: ${channel.banned.map((user) => user.username)}`); console.log(`Banned members: ${channel.banned.map((user) => user[0])}`);
console.log(`Muted users: ${channel.muted.map((user) => user.username)}`); console.log(`Muted users: ${channel.muted.map((user) => user[0])}`);
messages = msgs.map((msg) => {
const hidden = blockedUsers.some((user) => msg.author.ftId === user.ftId)
return {...msg, hidden: hidden};
});
}); });
usersInterval = setInterval(async () => { usersInterval = setInterval(async () => {
@ -145,7 +151,6 @@
function openProfile(username: string) { function openProfile(username: string) {
showProfileMenu = true; showProfileMenu = true;
selectedUser = username; selectedUser = username;
showChatMembers = false;
} }
function closeProfileMenu() { function closeProfileMenu() {
showProfileMenu = false; showProfileMenu = false;
@ -231,6 +236,14 @@
credentials: "include", credentials: "include",
mode: "cors" mode: "cors"
}); });
messages = messages.map((message) => {
if (message.author.username === username) {
message.hidden = true;
}
return message;
});
closeProfileMenu();
} }
if (response.ok) await show_popup("User blocked", false); if (response.ok) await show_popup("User blocked", false);
else { else {
@ -253,6 +266,13 @@
method: "DELETE", method: "DELETE",
mode: "cors" mode: "cors"
}); });
messages = messages.map((message) => {
if (message.author.username === username) {
message.hidden = false;
}
return message;
});
} }
if (response.ok) await show_popup("User unblocked", false); if (response.ok) await show_popup("User unblocked", false);
else { else {
@ -442,9 +462,8 @@
const leaveChannel = async () => { const leaveChannel = async () => {
await show_popup('Press "Okay" to leave this channel?', false); await show_popup('Press "Okay" to leave this channel?', false);
if ($content == "ok") { if ($content == "ok") {
socket.emit("leaveChannel"); await socket.emitWithAck("leaveChannel")
dispatch("return-home"); dispatch("return-home")
socket.disconnect();
} }
}; };
</script> </script>
@ -454,7 +473,7 @@
<div class="messages"> <div class="messages">
{#each messages as message} {#each messages as message}
<p class="message"> <p class="message">
{#if !blockedUsers.filter((user) => user.username == message.author).length} {#if !message.hidden}
<span <span
class="message-name" class="message-name"
on:click={() => openProfile(message.author.username)} on:click={() => openProfile(message.author.username)}
@ -623,8 +642,7 @@
height: 16px; height: 16px;
} }
.profile-menu, .profile-menu {
.chatMembers {
position: absolute; position: absolute;
background-color: #ffffff; background-color: #ffffff;
border: 1px solid #dedede; border: 1px solid #dedede;

Loading…
Cancel
Save