diff --git a/api/chat.php b/api/chat.php
index 182fbfb..e9e014e 100644
--- a/api/chat.php
+++ b/api/chat.php
@@ -18,7 +18,7 @@ if ($method === 'GET') {
unlink($path);
}
}
- db()->query("DELETE FROM messages WHERE (type = 'image' OR type = 'reaction') AND created_at < DATE_SUB(NOW(), INTERVAL 5 SECOND)");
+ db()->query("DELETE FROM messages WHERE (type = 'image' OR type = 'reaction' OR type = 'flash_poll') AND created_at < DATE_SUB(NOW(), INTERVAL 5 SECOND)");
// Limpiar otros mensajes y archivos de más de 7 días
$oldImages = db()->prepare("SELECT message FROM messages WHERE type = 'image' AND created_at < DATE_SUB(NOW(), INTERVAL 7 DAY)");
@@ -117,7 +117,14 @@ if ($method === 'GET') {
// Award points to the fan based on chat activity
require_once __DIR__ . '/../includes/points_helper.php';
- $pts = ($type === 'reaction') ? 1 : 5;
+
+ if ($type === 'flash_poll_response') {
+ awardLoyaltyPoints($username, 10);
+ $pts = 10; // Also add to general ranking
+ } else {
+ $pts = ($type === 'reaction') ? 1 : 5;
+ }
+
$newPoints = awardPoints($username, $pts);
// Auto-update Fan of the Month if this user has the highest points
diff --git a/includes/points_helper.php b/includes/points_helper.php
index a3f6543..08a9553 100644
--- a/includes/points_helper.php
+++ b/includes/points_helper.php
@@ -36,6 +36,29 @@ function awardPoints($username, $pointsToAdd) {
return $newPoints;
}
+function awardLoyaltyPoints($username, $pointsToAdd) {
+ if (empty($username) || $username === 'Anónimo') {
+ return false;
+ }
+
+ $db = db();
+
+ // Get current loyalty points
+ $stmt = $db->prepare("SELECT id, loyalty_points FROM fans WHERE name = ?");
+ $stmt->execute([$username]);
+ $fan = $stmt->fetch();
+
+ if ($fan) {
+ $newPoints = $fan['loyalty_points'] + $pointsToAdd;
+ $db->prepare("UPDATE fans SET loyalty_points = ? WHERE id = ?")->execute([$newPoints, $fan['id']]);
+ } else {
+ $newPoints = $pointsToAdd;
+ $db->prepare("INSERT INTO fans (name, loyalty_points) VALUES (?, ?)")->execute([$username, $newPoints]);
+ }
+
+ return $newPoints;
+}
+
function getNextLevelInfo($username) {
$db = db();
$stmt = $db->prepare("SELECT points FROM fans WHERE name = ?");
diff --git a/index.php b/index.php
index 4eb95d3..ffbd096 100644
--- a/index.php
+++ b/index.php
@@ -1652,18 +1652,15 @@ $twitter_link = "https://twitter.com/";
}
@keyframes flyUp {
- 0% {
- transform: translateY(0) translateX(0) scale(0.5) rotate(0deg);
- opacity: 0;
- }
- 10% {
- opacity: 1;
- transform: translateY(-20px) translateX(var(--drift)) scale(1.2) rotate(var(--rot));
- }
- 100% {
- transform: translateY(-100vh) translateX(calc(var(--drift) * 2)) scale(1) rotate(calc(var(--rot) * 2));
- opacity: 0;
- }
+ 0% { transform: translateY(0) translateX(0) rotate(0deg); opacity: 0; }
+ 10% { opacity: 1; }
+ 100% { transform: translateY(-80vh) translateX(var(--drift)) rotate(var(--rot)); opacity: 0; }
+ }
+
+ @keyframes floatUpFade {
+ 0% { transform: translate(-50%, -50%) scale(0.5); opacity: 0; }
+ 20% { opacity: 1; transform: translate(-50%, -80%) scale(1.2); }
+ 100% { transform: translate(-50%, -150%) scale(1); opacity: 0; }
}
/* Reaction Buttons Container */
@@ -1680,6 +1677,73 @@ $twitter_link = "https://twitter.com/";
animation: slideUpFade 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
+ /* Flash Poll Styles */
+ #flash-poll-container {
+ position: fixed;
+ top: 20%;
+ left: 50%;
+ transform: translate(-50%, -50%) scale(0.8);
+ z-index: 9995;
+ width: 90%;
+ max-width: 400px;
+ background: linear-gradient(145deg, rgba(30, 41, 59, 0.95), rgba(15, 23, 42, 0.98));
+ border: 2px solid #facc15;
+ border-radius: 24px;
+ padding: 20px;
+ box-shadow: 0 0 50px rgba(250, 204, 21, 0.4), 0 20px 40px rgba(0,0,0,0.5);
+ display: none;
+ opacity: 0;
+ transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ text-align: center;
+ }
+ #flash-poll-container.show {
+ display: block;
+ opacity: 1;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ .poll-question {
+ font-size: 1.2rem;
+ font-weight: 800;
+ color: #fff;
+ margin-bottom: 15px;
+ line-height: 1.3;
+ }
+ .poll-options {
+ display: flex;
+ gap: 10px;
+ justify-content: center;
+ }
+ .poll-btn {
+ background: rgba(255,255,255,0.1);
+ border: 1px solid rgba(255,255,255,0.2);
+ color: white;
+ padding: 10px 20px;
+ border-radius: 12px;
+ font-weight: 700;
+ cursor: pointer;
+ transition: all 0.2s;
+ flex: 1;
+ }
+ .poll-btn:hover {
+ background: var(--primary-color);
+ border-color: #fff;
+ transform: translateY(-3px);
+ }
+ .poll-timer-bar {
+ width: 100%;
+ height: 4px;
+ background: rgba(255,255,255,0.1);
+ border-radius: 2px;
+ margin-top: 15px;
+ overflow: hidden;
+ }
+ .poll-timer-fill {
+ height: 100%;
+ background: #facc15;
+ width: 100%;
+ transition: width linear;
+ }
+
/* Energy Thermometer for DJ */
.energy-thermometer-container {
display: none;
@@ -1893,6 +1957,11 @@ $twitter_link = "https://twitter.com/";
LILI
+
+
+
Cargando hype...
@@ -2043,7 +2112,7 @@ $twitter_link = "https://twitter.com/";
-
+
Nivel 1
@@ -2054,6 +2123,23 @@ $twitter_link = "https://twitter.com/";
+
+
+
+
+
+
+
+
+
Loyalty Points
+
0 LP
+
+
+
+
+
Siguiente: Color de chat azul
@@ -2428,6 +2514,22 @@ $twitter_link = "https://twitter.com/";
+
+
+
+ Pregunta Flash del DJ
+
+
¿Qué canción prefieren para cerrar el set?
+
🎁 ¡RESPONDE Y GANA +10 LOYALTY POINTS!
+
+
+
+
+
+
+
@@ -3018,12 +3120,17 @@ $twitter_link = "https://twitter.com/";
showReactionButtons();
}
+ // Trigger flash poll UI
+ if (msg.type === 'flash_poll' && index >= lastMessageCount && lastMessageCount > 0) {
+ showFlashPoll(msg.message);
+ }
+
// Trigger flying emoji for reaction messages
if (msg.type === 'reaction' && index >= lastMessageCount && lastMessageCount > 0) {
spawnReactionEmoji(msg.message);
}
- if (msg.type === 'reaction') return;
+ if (msg.type === 'reaction' || msg.type === 'flash_poll') return;
const div = document.createElement('div');
const isLike = msg.message.includes('❤️');
@@ -3217,7 +3324,8 @@ $twitter_link = "https://twitter.com/";
setTimeout(() => { emojiEl.remove(); }, duration * 1000);
// Massive Celebration Logic
- globalReactionCount++;
+ const boost = window.isPollActive ? 10 : 1;
+ globalReactionCount += boost;
// Update Energy Thermometer for DJ
const energyFill = document.getElementById('energy-fill');
@@ -3260,6 +3368,87 @@ $twitter_link = "https://twitter.com/";
}
}
+ async function promptFlashPoll() {
+ const question = prompt("Ingresa la Pregunta Flash para la audiencia:");
+ if (!question) return;
+ const userName = document.getElementById('user-name').value.trim() || 'Lili';
+ await sendChatMessage(question, 'flash_poll', userName);
+ }
+
+ function showFlashPoll(question) {
+ const container = document.getElementById('flash-poll-container');
+ const qEl = document.getElementById('poll-question');
+ const timerFill = document.getElementById('poll-timer-fill');
+
+ qEl.innerText = question;
+ container.style.display = 'block';
+ setTimeout(() => container.classList.add('show'), 10);
+
+ timerFill.style.transition = 'none';
+ timerFill.style.width = '100%';
+
+ setTimeout(() => {
+ timerFill.style.transition = 'width 30s linear';
+ timerFill.style.width = '0%';
+ }, 100);
+
+ window.isPollActive = true;
+ showReactionButtons(); // Activar botones de reacción para el combo
+
+ setTimeout(() => {
+ container.classList.remove('show');
+ window.isPollActive = false;
+ setTimeout(() => { container.style.display = 'none'; }, 500);
+ }, 30000);
+ }
+
+ async function answerFlashPoll(answer) {
+ const emoji = answer === 'SÍ' ? '🔥' : '🎧';
+ const userName = document.getElementById('user-name').value.trim() || 'Anónimo';
+
+ try {
+ await fetch('api/chat.php', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ username: userName,
+ message: emoji,
+ type: 'flash_poll_response'
+ })
+ });
+
+ // Show floating +10 LP animation
+ showFloatingPoints('+10 LP', '#00e676');
+
+ spawnReactionEmoji(emoji);
+ } catch (error) {
+ console.error('Error sending poll response:', error);
+ }
+
+ document.getElementById('flash-poll-container').classList.remove('show');
+ window.isPollActive = false;
+ }
+
+ function showFloatingPoints(text, color) {
+ const container = document.getElementById('flash-poll-container');
+ const floating = document.createElement('div');
+ floating.innerText = text;
+ floating.style.position = 'absolute';
+ floating.style.top = '50%';
+ floating.style.left = '50%';
+ floating.style.transform = 'translate(-50%, -50%)';
+ floating.style.color = color;
+ floating.style.fontWeight = '900';
+ floating.style.fontSize = '2rem';
+ floating.style.zIndex = '10005';
+ floating.style.pointerEvents = 'none';
+ floating.style.animation = 'floatUpFade 1.5s forwards';
+ floating.style.textShadow = '0 0 10px rgba(0,0,0,0.5)';
+
+ container.appendChild(floating);
+ setTimeout(() => floating.remove(), 1500);
+ }
+
async function sendReaction(emoji) {
const userName = document.getElementById('user-name').value.trim() || 'Anónimo';
try {
@@ -3457,6 +3646,10 @@ $twitter_link = "https://twitter.com/";
const thermometer = document.getElementById('dj-energy-thermometer');
if (thermometer) thermometer.style.display = isGuestDj ? 'flex' : 'none';
+ // Show/hide Flash Poll control
+ const pollControl = document.getElementById('dj-flash-poll-control');
+ if (pollControl) pollControl.style.display = isGuestDj ? 'block' : 'none';
+
if (result.success) {
const list = document.getElementById('song-requests-list');
if (result.requests.length === 0) {
@@ -4024,8 +4217,10 @@ $twitter_link = "https://twitter.com/";
// Update shop points display
const shopPoints = document.getElementById('shop-user-points');
const shopLoyalty = document.getElementById('shop-user-loyalty');
+ const mainLoyalty = document.getElementById('loyalty-points-display');
if (shopPoints) shopPoints.innerText = `${parseInt(fan.total_likes).toLocaleString()} PTS`;
if (shopLoyalty) shopLoyalty.innerText = `${parseInt(fan.loyalty_points || 0).toLocaleString()} LP`;
+ if (mainLoyalty) mainLoyalty.innerText = `${parseInt(fan.loyalty_points || 0).toLocaleString()} LP`;
container.style.display = 'block';
badge.innerText = `Nivel ${fan.level}`;