Auto commit: 2026-02-19T20:18:39.606Z

This commit is contained in:
Flatlogic Bot 2026-02-19 20:18:41 +00:00
parent d9d6f803b0
commit 0a7bcfc414
2 changed files with 166 additions and 3 deletions

View File

@ -18,7 +18,7 @@ if ($method === 'GET') {
unlink($path);
}
}
db()->query("DELETE FROM messages WHERE type = 'image' AND created_at < DATE_SUB(NOW(), INTERVAL 5 SECOND)");
db()->query("DELETE FROM messages WHERE (type = 'image' OR type = 'reaction') 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,8 @@ if ($method === 'GET') {
// Award points to the fan based on chat activity
require_once __DIR__ . '/../includes/points_helper.php';
$newPoints = awardPoints($username, 5); // 5 points per message instead of 10 to balance
$pts = ($type === 'reaction') ? 1 : 5;
$newPoints = awardPoints($username, $pts);
// Auto-update Fan of the Month if this user has the highest points
$maxPointsStmt = db()->query("SELECT MAX(points) as max_p FROM fans");

164
index.php
View File

@ -1635,10 +1635,93 @@ $twitter_link = "https://twitter.com/";
text-align: right;
}
.chat-msg-item.is-me .chat-msg-time {
.chat-msg-item.is-me .chat-msg-time {
text-align: left;
}
/* Flying Emojis Animation */
.flying-emoji {
position: fixed;
bottom: 20px;
font-size: 2.5rem;
user-select: none;
pointer-events: none;
z-index: 10000;
animation: flyUp var(--duration) ease-out forwards;
filter: drop-shadow(0 0 10px rgba(0,0,0,0.3));
}
@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;
}
}
/* Reaction Buttons Container */
.reaction-buttons {
display: flex;
gap: 12px;
margin-top: 15px;
justify-content: center;
padding: 10px;
background: rgba(255, 255, 255, 0.05);
border-radius: 50px;
border: 1px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
animation: slideUpFade 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes slideUpFade {
0% { transform: translateY(20px); opacity: 0; }
100% { transform: translateY(0); opacity: 1; }
}
.reaction-btn {
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
width: 45px;
height: 45px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
backdrop-filter: blur(5px);
}
.reaction-btn:hover {
transform: scale(1.2) translateY(-5px);
background: rgba(255, 255, 255, 0.2);
border-color: var(--primary-color);
box-shadow: 0 0 15px var(--primary-color);
}
.reaction-btn:active {
transform: scale(0.9);
}
.reaction-overlay-active {
animation: pulse-reaction 1s infinite;
border: 2px solid #facc15 !important;
}
@keyframes pulse-reaction {
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(250, 204, 21, 0.7); }
70% { transform: scale(1.1); box-shadow: 0 0 0 15px rgba(250, 204, 21, 0); }
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(250, 204, 21, 0); }
}
/* Top Listener Banner */
.top-listener-banner {
background: linear-gradient(135deg, rgba(250, 204, 21, 0.2), rgba(245, 158, 11, 0.3));
@ -2011,6 +2094,16 @@ $twitter_link = "https://twitter.com/";
<!-- Mensajes se cargarán aquí -->
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Cargando mensajes...</div>
</div>
<div id="dj-reaction-area" class="reaction-buttons" style="display: none; flex-direction: column; align-items: center; margin-bottom: 15px; border-radius: 20px; padding: 12px;">
<span style="font-size: 0.65rem; font-weight: 800; color: #facc15; text-transform: uppercase; margin-bottom: 8px; letter-spacing: 1px; opacity: 0.9;">¡Celebra con el DJ! 👇</span>
<div style="display: flex; gap: 12px;">
<button class="reaction-btn" onclick="sendReaction('❤️')" title="¡Me encanta!">❤️</button>
<button class="reaction-btn" onclick="sendReaction('🔥')" title="¡Fuego!">🔥</button>
<button class="reaction-btn" onclick="sendReaction('🎉')" title="¡Celebrar!">🎉</button>
<button class="reaction-btn" onclick="sendReaction('🎧')" title="¡Ese DJ!">🎧</button>
<button class="reaction-btn" onclick="sendReaction('🙌')" title="¡Subidón!">🙌</button>
</div>
</div>
<div class="chat-input-area" style="display: flex; gap: 0.5rem; position: relative;">
<input type="hidden" id="chat-user">
<button onclick="toggleEmojiPicker()" style="background: rgba(255,255,255,0.1); border: none; border-radius: 8px; color: white; padding: 0 0.5rem; cursor: pointer;">
@ -2876,7 +2969,17 @@ $twitter_link = "https://twitter.com/";
setTimeout(() => {
document.body.style.animation = 'shake 0.5s cubic-bezier(.36,.07,.19,.97) both';
}, 10);
// Trigger reaction buttons visibility
showReactionButtons();
}
// Trigger flying emoji for reaction messages
if (msg.type === 'reaction' && index >= lastMessageCount && lastMessageCount > 0) {
spawnReactionEmoji(msg.message);
}
if (msg.type === 'reaction') return;
const div = document.createElement('div');
const isLike = msg.message.includes('❤️');
@ -2986,6 +3089,65 @@ $twitter_link = "https://twitter.com/";
}
}
function spawnReactionEmoji(emoji) {
const container = document.body;
const emojiEl = document.createElement('div');
emojiEl.className = 'flying-emoji';
emojiEl.innerText = emoji;
const startX = Math.random() * 80 + 10;
const drift = (Math.random() - 0.5) * 200;
const rotation = (Math.random() - 0.5) * 90;
const duration = 2 + Math.random() * 2;
emojiEl.style.left = `${startX}%`;
emojiEl.style.setProperty('--drift', `${drift}px`);
emojiEl.style.setProperty('--rot', `${rotation}deg`);
emojiEl.style.setProperty('--duration', `${duration}s`);
container.appendChild(emojiEl);
setTimeout(() => { emojiEl.remove(); }, duration * 1000);
}
async function sendReaction(emoji) {
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: 'reaction'
})
});
// Optimistic UI
spawnReactionEmoji(emoji);
} catch (error) {
console.error('Error sending reaction:', error);
}
}
function showReactionButtons() {
const container = document.getElementById('dj-reaction-area');
if (container) {
container.style.display = 'flex';
container.style.opacity = '1';
container.classList.add('reaction-overlay-active');
if (window.reactionTimeout) clearTimeout(window.reactionTimeout);
window.reactionTimeout = setTimeout(() => {
container.classList.remove('reaction-overlay-active');
container.style.transition = 'opacity 1s ease';
container.style.opacity = '0';
setTimeout(() => {
if (container.style.opacity === '0') container.style.display = 'none';
}, 1000);
}, 20000);
}
}
chatMsg.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendChatMessage();
});