90 lines
2.5 KiB
JavaScript
90 lines
2.5 KiB
JavaScript
const socket = io();
|
|
|
|
// DOM Elements
|
|
const counterDisplay = document.getElementById('counter-display');
|
|
const incrementBtn = document.getElementById('increment-btn');
|
|
const usernameInput = document.getElementById('username');
|
|
const quoteInput = document.getElementById('quote');
|
|
const errorMessage = document.getElementById('error-message');
|
|
const timerDisplay = document.getElementById('timer-display');
|
|
|
|
// Cookie Helpers
|
|
function setCookie(name, value, days) {
|
|
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
|
document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=/';
|
|
}
|
|
|
|
function getCookie(name) {
|
|
return document.cookie.split('; ').reduce((r, v) => {
|
|
const parts = v.split('=');
|
|
return parts[0] === name ? decodeURIComponent(parts[1]) : r;
|
|
}, '');
|
|
}
|
|
|
|
// Load name from cookie
|
|
const savedName = getCookie('username');
|
|
if (savedName) {
|
|
usernameInput.value = savedName;
|
|
}
|
|
|
|
// Socket Events
|
|
socket.on('update', (data) => {
|
|
counterDisplay.innerText = data.count;
|
|
// Animate
|
|
counterDisplay.parentElement.classList.remove('pop-anim');
|
|
void counterDisplay.parentElement.offsetWidth; // trigger reflow
|
|
counterDisplay.parentElement.classList.add('pop-anim');
|
|
});
|
|
|
|
socket.on('error', (msg) => {
|
|
showError(msg);
|
|
});
|
|
|
|
// Logic
|
|
usernameInput.addEventListener('input', (e) => {
|
|
setCookie('username', e.target.value, 365);
|
|
});
|
|
|
|
incrementBtn.addEventListener('click', () => {
|
|
const name = usernameInput.value.trim();
|
|
if (!name) {
|
|
showError("Please enter your name!");
|
|
usernameInput.focus();
|
|
return;
|
|
}
|
|
|
|
const quote = quoteInput.value.trim();
|
|
|
|
// Optimistic disable
|
|
startCooldown();
|
|
|
|
socket.emit('increment', { name, quote });
|
|
});
|
|
|
|
function showError(msg) {
|
|
errorMessage.innerText = msg;
|
|
errorMessage.classList.remove('hidden');
|
|
setTimeout(() => {
|
|
errorMessage.classList.add('hidden');
|
|
}, 3000);
|
|
}
|
|
|
|
let cooldownInterval;
|
|
function startCooldown() {
|
|
incrementBtn.disabled = true;
|
|
let secondsLeft = 30;
|
|
timerDisplay.classList.remove('hidden');
|
|
timerDisplay.innerText = `Wait ${secondsLeft}s`;
|
|
|
|
clearInterval(cooldownInterval);
|
|
cooldownInterval = setInterval(() => {
|
|
secondsLeft--;
|
|
timerDisplay.innerText = `Wait ${secondsLeft}s`;
|
|
if (secondsLeft <= 0) {
|
|
clearInterval(cooldownInterval);
|
|
incrementBtn.disabled = false;
|
|
timerDisplay.classList.add('hidden');
|
|
}
|
|
}, 1000);
|
|
}
|