feat(*): Handle emoji throwing on server

This commit is contained in:
Josh Creek
2023-07-12 11:14:05 +00:00
parent a4e573d5b9
commit 5b9bd29382
5 changed files with 111 additions and 27 deletions
-5
View File
@@ -6,11 +6,6 @@ There are two components to this:
1. Frontend, built using SvelteKit
2. WebSockets server, built using Node.js
## Potential Enhancements
- throw emoji at people
- add a shield to anyone named 'Tristan' whenever the poop emoji is thrown at them
## Frontend
For full functionality, ensure there is a copy of the WebSockets server running.
+50 -1
View File
@@ -24,7 +24,7 @@
</script>
<div style="position: relative;">
<button bind:this={button} class="emoji-button" on:click={showEmojiPicker}>
<button bind:this={button} class="emoji-button button button-white" on:click={showEmojiPicker}>
{selectedEmoji} Choose your emoji...
</button>
</div>
@@ -33,4 +33,53 @@
.emoji-button {
cursor: pointer;
}
.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-white {
background-color: #ffffff;
color: black;
}
.button-white:hover {
background-color: #E6E6E6;
}
</style>
+7 -2
View File
@@ -4,6 +4,7 @@
export let users: any;
export let showEstimates: boolean = false;
export let userId: string;
export let handleEmojiTrigger: (cardId: string, emoji: string) => void;
let customEmoji = '🧽'; // default emoji
let shieldActive = false;
@@ -13,11 +14,15 @@
};
function handleCardClick(cardId) {
handleEmojiTrigger(cardId, customEmoji);
}
export function triggerEmoji(cardId, emoji) {
// Get the user from the cardId
let user = users.find((user) => `user-card-${user.userId}` === cardId);
// If the user is Tristan and the selected emoji is poop, activate the shield
if (user && user.name === 'Tristan' && customEmoji === '💩') {
if (user && user.name === 'Tristan' && emoji === '💩') {
shieldActive = true;
// After 2 seconds, remove the shield
@@ -31,7 +36,7 @@
let times = Math.floor(Math.random() * 3) + 3; // Random number between 3 and 5
for (let i = 0; i < times; i++) {
let timeout = Math.random() * 100 + 100 * i; // Random number between 100 and 200, multiplied by i to stagger the emojis
setTimeout(() => addEmojiToElement(cardId, customEmoji), timeout);
setTimeout(() => addEmojiToElement(cardId, emoji), timeout);
}
}
+26 -4
View File
@@ -2,6 +2,8 @@
/** @type {import('./$types').PageData} */
export let data;
let usersList;
import { onMount } from 'svelte';
import UsersList from '../../../components/UsersList.svelte';
import EstimateGroupsList from '../../../components/EstimateGroupsList.svelte';
@@ -86,6 +88,14 @@
sendMessage(socket, new SelectEstimateMessage(data.roomId, userId, estimate));
}
function handleEmojiTrigger(cardId: string, emoji: string) {
sendMessage(socket, {
type: 'trigger-emoji',
cardId,
emoji
});
}
function restartEstimation() {
sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' });
}
@@ -122,6 +132,10 @@
showRestartButton = false;
showEstimates = false;
sendMessage(socket, { type: 'get-user-estimates' });
} else if (message.type === 'trigger-emoji') {
if (usersList && typeof usersList.triggerEmoji === 'function') {
usersList.triggerEmoji(message.cardId, message.emoji);
}
}
}
@@ -130,12 +144,15 @@
});
</script>
<h1>Estimation Page</h1>
{#if showModal}
<Modal {closeModal} {joinRoom} />
{/if}
<UsersList bind:this={usersList} {users} {showEstimates} {userId} {handleEmojiTrigger} />
<div class="button-container">
{#if showRestartButton}
<button
class="button button-red"
@@ -150,8 +167,7 @@
tabindex="0">Restart estimation</button
>
{/if}
<UsersList {users} {showEstimates} {userId} />
</div>
<Estimates onEstimateClick={handleEstimateClick} />
@@ -161,6 +177,12 @@
{/if}
<style>
.button-container {
display: flex;
justify-content: center;
margin-bottom: 1em;
}
.button {
appearance: none;
border: 1px solid rgba(27, 31, 35, 0.15);
+14 -1
View File
@@ -110,7 +110,11 @@ wss.on('connection', (ws: WebSocket, req) => {
if (allEstimates.size === room.getUsers().length) {
const users = room.getUsers();
const average = calculateAverageEstimate(users);
broadcastToRoom(room.id, { type: 'estimation-closed', average, groupedEstimates: groupEstimates(users)});
broadcastToRoom(room.id, {
type: 'estimation-closed',
average,
groupedEstimates: groupEstimates(users)
});
}
}
}
@@ -124,6 +128,15 @@ wss.on('connection', (ws: WebSocket, req) => {
const users = room.getUsers();
broadcastToRoom(room.id, { type: 'user-estimates', users });
}
} else if (data.type === 'trigger-emoji') {
const { cardId, emoji } = data;
if (room) {
broadcastToRoom(room.id, {
type: 'trigger-emoji',
cardId,
emoji
});
}
}
});