Autosave: 20260217-201214

This commit is contained in:
Flatlogic Bot 2026-02-17 20:12:14 +00:00
parent e433d2380a
commit 4b069537af
4 changed files with 232 additions and 1 deletions

29
api/get_shoutouts.php Normal file
View File

@ -0,0 +1,29 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
$user_name = $_GET['user_name'] ?? '';
if (empty($user_name)) {
echo json_encode(['success' => false, 'error' => 'User name is required.']);
exit;
}
try {
// Get the latest unseen shoutout for this user
$stmt = db()->prepare("SELECT id, message, dj_name FROM dj_shoutouts WHERE target_fan_name = ? AND is_seen = 0 ORDER BY created_at DESC LIMIT 1");
$stmt->execute([$user_name]);
$shoutout = $stmt->fetch();
if ($shoutout) {
// Mark as seen immediately so it doesn't pop up again
$update = db()->prepare("UPDATE dj_shoutouts SET is_seen = 1 WHERE id = ?");
$update->execute([$shoutout['id']]);
echo json_encode(['success' => true, 'shoutout' => $shoutout]);
} else {
echo json_encode(['success' => true, 'shoutout' => null]);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

22
api/send_shoutout.php Normal file
View File

@ -0,0 +1,22 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
$data = json_decode(file_get_contents('php://input'), true);
$target = $data['target_name'] ?? '';
$message = $data['message'] ?? '';
$dj_name = $data['dj_name'] ?? 'Lili';
if (empty($target) || empty($message)) {
echo json_encode(['success' => false, 'error' => 'Target and message are required.']);
exit;
}
try {
$stmt = db()->prepare("INSERT INTO dj_shoutouts (target_fan_name, message, dj_name) VALUES (?, ?, ?)");
$stmt->execute([$target, $message, $dj_name]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

View File

@ -0,0 +1,14 @@
-- Migration: Create dj_shoutouts table
-- Description: Stores personalized mentions from the DJ to fans.
CREATE TABLE IF NOT EXISTS dj_shoutouts (
id INT AUTO_INCREMENT PRIMARY KEY,
target_fan_name VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
dj_name VARCHAR(255) DEFAULT 'Lili',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
is_seen TINYINT(1) DEFAULT 0
);
-- Index for faster polling by target name
CREATE INDEX idx_target_unseen ON dj_shoutouts(target_fan_name, is_seen);

168
index.php
View File

@ -1406,6 +1406,86 @@ $twitter_link = "https://twitter.com/";
box-shadow: 0 4px 12px rgba(236, 72, 153, 0.3);
animation: pulse 2s infinite;
}
/* Shoutout Modal Styles */
.shoutout-modal {
display: none;
position: fixed;
z-index: 5000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.85);
backdrop-filter: blur(15px);
justify-content: center;
align-items: center;
opacity: 0;
transition: opacity 0.5s ease;
}
.shoutout-modal.show {
display: flex;
opacity: 1;
}
.shoutout-card {
background: linear-gradient(145deg, rgba(30, 30, 30, 0.9), rgba(10, 10, 10, 0.95));
border: 2px solid var(--primary-color);
padding: 3rem;
border-radius: 40px;
text-align: center;
max-width: 500px;
width: 90%;
position: relative;
transform: scale(0.5) translateY(100px);
transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 0 50px rgba(56, 189, 248, 0.6);
}
.shoutout-modal.show .shoutout-card {
transform: scale(1) translateY(0);
}
.shoutout-icon {
font-size: 5rem;
color: #facc15;
margin-bottom: 1.5rem;
filter: drop-shadow(0 0 20px rgba(250, 204, 21, 0.6));
animation: bounce 2s infinite;
}
.shoutout-title {
font-size: 2.2rem;
font-weight: 900;
background: linear-gradient(to right, #fff, var(--primary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: 2px;
}
.shoutout-msg {
font-size: 1.2rem;
line-height: 1.6;
color: #fff;
margin-bottom: 2rem;
font-weight: 500;
}
.shoutout-dj {
font-size: 0.8rem;
color: var(--primary-color);
font-weight: 800;
text-transform: uppercase;
letter-spacing: 3px;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.shoutout-confetti {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
</style>
</head>
<body>
@ -1462,7 +1542,7 @@ $twitter_link = "https://twitter.com/";
</div>
<div class="track-info">
<div id="dj-host-container" style="display: flex; align-items: center; gap: 8px;">
<div class="dj-badge"><i class="bi bi-mic-fill"></i> <span id="current-dj-name">LILI</span></div>
<div class="dj-badge" onclick="adminOpenShoutout()" style="cursor: pointer;" title="DJ Panel (Admin)"><i class="bi bi-mic-fill"></i> <span id="current-dj-name">LILI</span></div>
</div>
<span class="track-label">ESTÁS ESCUCHANDO:</span>
<div id="track-title" class="track-title" onclick="copyTrackTitle()" title="Toca para copiar">Cargando stream...</div>
@ -1904,6 +1984,20 @@ $twitter_link = "https://twitter.com/";
<!-- Celebration Overlay -->
<div id="celebration-overlay"></div>
<!-- Shoutout Modal -->
<div id="shoutout-modal" class="shoutout-modal" onclick="this.classList.remove('show'); setTimeout(() => this.style.display = 'none', 500)">
<div class="shoutout-card" onclick="event.stopPropagation()">
<div class="shoutout-icon"><i class="bi bi-megaphone-fill"></i></div>
<div class="shoutout-title">¡Mención Especial!</div>
<div id="shoutout-target" style="font-size: 1.5rem; color: #facc15; font-weight: 800; margin-bottom: 1rem;"></div>
<div id="shoutout-message" class="shoutout-msg"></div>
<div class="shoutout-dj"> Con cariño, <span id="shoutout-dj-name">Lili</span> </div>
<button onclick="document.getElementById('shoutout-modal').classList.remove('show'); setTimeout(() => document.getElementById('shoutout-modal').style.display = 'none', 500)" style="margin-top: 2rem; background: var(--primary-color); border: none; color: black; padding: 10px 30px; border-radius: 20px; font-weight: 800; cursor: pointer; transition: all 0.3s;">
¡GRACIAS!
</button>
</div>
</div>
<audio id="radio-audio" src="https://listen.radioking.com/radio/828046/stream/897251" preload="auto" crossorigin="anonymous"></audio>
<audio id="welcome-sound" src="https://assets.mixkit.co/active_storage/sfx/2013/2013-preview.mp3" preload="auto"></audio>
@ -3385,9 +3479,81 @@ $twitter_link = "https://twitter.com/";
}
// Initialize polling
// --- DJ Shoutout Functionality ---
async function adminOpenShoutout() {
const target = prompt("¿A quién quieres mandarle un saludo?");
if (!target) return;
const message = prompt(`¿Qué mensaje quieres decirle a ${target}?`, "¡Gracias por estar en sintonía con Lili Records!");
if (!message) return;
try {
const response = await fetch('api/send_shoutout.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ target_name: target, message: message })
});
const data = await response.json();
if (data.success) {
alert("¡Mención enviada con éxito!");
} else {
alert("Error: " + data.error);
}
} catch (e) {
console.error("Error sending shoutout:", e);
}
}
async function pollShoutouts() {
const userName = document.getElementById('user-name').value.trim();
if (!userName) return;
try {
const response = await fetch(`api/get_shoutouts.php?user_name=${encodeURIComponent(userName)}`);
const data = await response.json();
if (data.success && data.shoutout) {
showShoutoutModal(data.shoutout);
}
} catch (e) {
console.error("Error polling shoutouts:", e);
}
}
function showShoutoutModal(shoutout) {
const modal = document.getElementById('shoutout-modal');
const targetEl = document.getElementById('shoutout-target');
const msgEl = document.getElementById('shoutout-message');
const djEl = document.getElementById('shoutout-dj-name');
const userName = document.getElementById('user-name').value.trim();
targetEl.innerText = `¡Para ${userName}!`;
msgEl.innerText = shoutout.message;
djEl.innerText = shoutout.dj_name;
modal.style.display = 'flex';
setTimeout(() => modal.classList.add('show'), 10);
// Audio cue if possible
try {
const audio = new Audio('https://www.soundjay.com/buttons/sounds/button-3.mp3');
audio.volume = 0.5;
audio.play();
} catch(e) {}
}
setInterval(pollShoutouts, 5000);
setInterval(pollCelebrations, 5000);
pollCelebrations();
// --- End DJ Shoutout Functionality ---
audio.addEventListener('error', function(e) {
console.error('Audio error:', e);
trackTitle.textContent = "Error de conexión. Reintentando...";
setTimeout(() => {
audio.load();
if (!audio.paused) audio.play();
}, 5000);
});
</script>
</body>
</html>