feat(#25): Add ability to kick a user

This commit is contained in:
Josh Creek
2024-01-05 18:52:34 +00:00
parent 397aa528dc
commit 6ae45d9c6a
4 changed files with 118 additions and 2 deletions
+89 -1
View File
@@ -5,6 +5,7 @@
export let showEstimates: boolean = false; export let showEstimates: boolean = false;
export let userId: string; export let userId: string;
export let handleEmojiTrigger: (cardId: string, emoji: string) => void; export let handleEmojiTrigger: (cardId: string, emoji: string) => void;
export let handleKickUser: (userId: string) => void;
let customEmoji = '🧽'; // default emoji let customEmoji = '🧽'; // default emoji
let shieldActive = false; let shieldActive = false;
@@ -101,9 +102,35 @@
document.body.removeChild(emojiElement); document.body.removeChild(emojiElement);
}, 2000); }, 2000);
} }
let selectedUserId = '';
export function kickUser() {
if (selectedUserId) {
let confirmed = confirm('Are you sure you want to kick this user?');
if (confirmed) {
console.log('confirmed');
handleKickUser(selectedUserId);
}
}
}
</script> </script>
<EmojiPicker on:emojiSelected={handleEmojiSelected} /> <div id="top-container">
<EmojiPicker on:emojiSelected={handleEmojiSelected} />
<div id="user-kicker">
<select bind:value={selectedUserId}>
<option value="">Select a user</option>
{#each users as user (user.userId)}
<option value={user.userId}>{user.name}</option>
{/each}
</select>
<button class="emoji-button button button-red" on:click={kickUser}>Kick User</button>
</div>
</div>
<div id="users-list"> <div id="users-list">
<div class="users-container"> <div class="users-container">
@@ -128,6 +155,19 @@
</div> </div>
<style> <style>
#top-container {
display: flex;
justify-content: space-between;
}
select {
font-size: 0.8rem;
padding: 0.5rem;
border-radius: 0.25rem;
border: 1px solid gray;
margin-bottom: 0.5rem;
}
#users-list { #users-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@@ -239,4 +279,52 @@
box-shadow: 0 0 10px 5px rgba(0, 0, 255, 0.5); box-shadow: 0 0 10px 5px rgba(0, 0, 255, 0.5);
} }
} }
.button {
appearance: none;
border: 1px solid rgba(27, 31, 35, 0.15);
border-radius: 6px;
box-shadow: rgba(27, 31, 35, 0.1) 0 1px 0;
box-sizing: border-box;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji';
font-size: 14px;
font-weight: 600;
line-height: 20px;
padding: 6px 16px;
position: relative;
text-align: center;
text-decoration: none;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
vertical-align: middle;
white-space: nowrap;
}
.button:focus:not(:focus-visible):not(.focus-visible) {
box-shadow: none;
outline: none;
}
.button:disabled {
border-color: rgba(27, 31, 35, 0.1);
color: rgba(255, 255, 255, 0.8);
cursor: default;
}
.button:focus {
outline: none;
}
.button-red {
background-color: #b60223;
}
.button-red:hover {
background-color: #a2021f;
}
</style> </style>
+9 -1
View File
@@ -97,6 +97,14 @@
}); });
} }
function handleKickUser(userId: string) {
console.log('sending kick-user message');
sendMessage(socket, {
type: 'kick-user',
userId
});
}
function restartEstimation() { function restartEstimation() {
sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' }); sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' });
} }
@@ -167,7 +175,7 @@
<Modal {closeModal} {joinRoom} /> <Modal {closeModal} {joinRoom} />
{/if} {/if}
<UsersList bind:this={usersList} {users} {showEstimates} {userId} {handleEmojiTrigger} /> <UsersList bind:this={usersList} {users} {showEstimates} {userId} {handleEmojiTrigger} {handleKickUser} />
<div class="button-container"> <div class="button-container">
{#if showRestartButton} {#if showRestartButton}
+9
View File
@@ -66,6 +66,15 @@ export class Room {
return null; return null;
} }
getWebSocketByUserId(userId: String): WebSocket | null {
for (const [ws, u] of this.users) {
if (u.userId === userId) {
return ws;
}
}
return null;
}
broadcast(message: any) { broadcast(message: any) {
this.users.forEach((user, client) => { this.users.forEach((user, client) => {
if (client.readyState === WebSocket.OPEN) { if (client.readyState === WebSocket.OPEN) {
+11
View File
@@ -167,6 +167,17 @@ wss.on('connection', (ws: WebSocket, req) => {
if (room) { if (room) {
broadcastToRoom(room.id, 'pong'); broadcastToRoom(room.id, 'pong');
} }
} else if (data.type === 'kick-user') {
console.log('kick user message received');
if (room) {
const userIdToKick = data.userId;
const ws = room.getWebSocketByUserId(userIdToKick);
console.log(userIdToKick, ws);
if (ws) {
console.log('closing ws');
ws.close();
}
}
} }
}); });