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 1. Frontend, built using SvelteKit
2. WebSockets server, built using Node.js 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 ## Frontend
For full functionality, ensure there is a copy of the WebSockets server running. For full functionality, ensure there is a copy of the WebSockets server running.
+50 -1
View File
@@ -24,7 +24,7 @@
</script> </script>
<div style="position: relative;"> <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... {selectedEmoji} Choose your emoji...
</button> </button>
</div> </div>
@@ -33,4 +33,53 @@
.emoji-button { .emoji-button {
cursor: pointer; 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> </style>
+7 -2
View File
@@ -4,6 +4,7 @@
export let users: any; export let users: any;
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;
let customEmoji = '🧽'; // default emoji let customEmoji = '🧽'; // default emoji
let shieldActive = false; let shieldActive = false;
@@ -13,11 +14,15 @@
}; };
function handleCardClick(cardId) { function handleCardClick(cardId) {
handleEmojiTrigger(cardId, customEmoji);
}
export function triggerEmoji(cardId, emoji) {
// Get the user from the cardId // Get the user from the cardId
let user = users.find((user) => `user-card-${user.userId}` === 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 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; shieldActive = true;
// After 2 seconds, remove the shield // After 2 seconds, remove the shield
@@ -31,7 +36,7 @@
let times = Math.floor(Math.random() * 3) + 3; // Random number between 3 and 5 let times = Math.floor(Math.random() * 3) + 3; // Random number between 3 and 5
for (let i = 0; i < times; i++) { 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 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} */ /** @type {import('./$types').PageData} */
export let data; export let data;
let usersList;
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import UsersList from '../../../components/UsersList.svelte'; import UsersList from '../../../components/UsersList.svelte';
import EstimateGroupsList from '../../../components/EstimateGroupsList.svelte'; import EstimateGroupsList from '../../../components/EstimateGroupsList.svelte';
@@ -86,6 +88,14 @@
sendMessage(socket, new SelectEstimateMessage(data.roomId, userId, estimate)); sendMessage(socket, new SelectEstimateMessage(data.roomId, userId, estimate));
} }
function handleEmojiTrigger(cardId: string, emoji: string) {
sendMessage(socket, {
type: 'trigger-emoji',
cardId,
emoji
});
}
function restartEstimation() { function restartEstimation() {
sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' }); sendMessage(socket, { roomId: data.roomId, type: 'restart-estimation' });
} }
@@ -122,6 +132,10 @@
showRestartButton = false; showRestartButton = false;
showEstimates = false; showEstimates = false;
sendMessage(socket, { type: 'get-user-estimates' }); 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> </script>
<h1>Estimation Page</h1>
{#if showModal} {#if showModal}
<Modal {closeModal} {joinRoom} /> <Modal {closeModal} {joinRoom} />
{/if} {/if}
<UsersList bind:this={usersList} {users} {showEstimates} {userId} {handleEmojiTrigger} />
<div class="button-container">
{#if showRestartButton} {#if showRestartButton}
<button <button
class="button button-red" class="button button-red"
@@ -150,8 +167,7 @@
tabindex="0">Restart estimation</button tabindex="0">Restart estimation</button
> >
{/if} {/if}
</div>
<UsersList {users} {showEstimates} {userId} />
<Estimates onEstimateClick={handleEstimateClick} /> <Estimates onEstimateClick={handleEstimateClick} />
@@ -161,6 +177,12 @@
{/if} {/if}
<style> <style>
.button-container {
display: flex;
justify-content: center;
margin-bottom: 1em;
}
.button { .button {
appearance: none; appearance: none;
border: 1px solid rgba(27, 31, 35, 0.15); 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) { if (allEstimates.size === room.getUsers().length) {
const users = room.getUsers(); const users = room.getUsers();
const average = calculateAverageEstimate(users); 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(); const users = room.getUsers();
broadcastToRoom(room.id, { type: 'user-estimates', users }); 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
});
}
} }
}); });