Auto commit: 2026-02-18T23:19:00.580Z
This commit is contained in:
parent
1840105cf9
commit
2b84812642
33
admin.php
33
admin.php
@ -60,6 +60,27 @@ $requests_today = $stmt->fetchColumn();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card p-3 border-success" style="background: rgba(37, 211, 102, 0.1);">
|
||||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-success p-3 rounded-circle me-3 shadow-lg">
|
||||
<i class="bi bi-whatsapp fs-3 text-white"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-0">Comunidad WhatsApp de Lili Records</h5>
|
||||
<p class="mb-0 text-secondary small">Monitorea y comparte anuncios directamente en el grupo oficial.</p>
|
||||
</div>
|
||||
</div>
|
||||
<a href="https://chat.whatsapp.com/DkG96pTzAFO3hvLqmzwmTY" target="_blank" class="btn btn-success d-flex align-items-center gap-2">
|
||||
<i class="bi bi-box-arrow-up-right"></i> IR AL GRUPO DE WHATSAPP
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Now Playing Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
@ -254,6 +275,7 @@ $requests_today = $stmt->fetchColumn();
|
||||
<th>Artista</th>
|
||||
<th>Canción</th>
|
||||
<th>Solicitado por</th>
|
||||
<th>Vía</th>
|
||||
<th>Fecha</th>
|
||||
<th>Estado</th>
|
||||
<th>Acciones</th>
|
||||
@ -261,7 +283,7 @@ $requests_today = $stmt->fetchColumn();
|
||||
</thead>
|
||||
<tbody id="requests-body">
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-secondary">Cargando peticiones...</td>
|
||||
<td colspan="7" class="text-center text-secondary">Cargando peticiones...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -353,13 +375,18 @@ $requests_today = $stmt->fetchColumn();
|
||||
if (data.success) {
|
||||
const tbody = document.getElementById('requests-body');
|
||||
if (data.requests.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="text-center text-secondary">No hay peticiones pendientes</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-secondary">No hay peticiones pendientes</td></tr>';
|
||||
} else {
|
||||
tbody.innerHTML = data.requests.map(req => `
|
||||
<tr>
|
||||
<tr class="${req.source === 'whatsapp' ? 'table-success' : ''}" style="${req.source === 'whatsapp' ? 'background: rgba(37, 211, 102, 0.1) !important;' : ''}">
|
||||
<td>${req.artist}</td>
|
||||
<td>${req.song}</td>
|
||||
<td>${req.requester}</td>
|
||||
<td>
|
||||
${req.source === 'whatsapp'
|
||||
? '<span class="badge bg-success"><i class="bi bi-whatsapp"></i> WhatsApp</span>'
|
||||
: '<span class="badge bg-secondary"><i class="bi bi-globe"></i> Web</span>'}
|
||||
</td>
|
||||
<td>${new Date(req.created_at).toLocaleString()}</td>
|
||||
<td><span class="badge bg-warning text-dark">${req.status}</span></td>
|
||||
<td>
|
||||
|
||||
18
api/chat.php
18
api/chat.php
@ -34,6 +34,18 @@ if ($method === 'GET') {
|
||||
|
||||
db()->query("DELETE FROM messages WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)");
|
||||
|
||||
// Obtener el Oyente de la Semana (Top 1)
|
||||
$topStmt = db()->query("
|
||||
SELECT requester
|
||||
FROM song_requests
|
||||
WHERE requester IS NOT NULL AND requester != '' AND requester != 'Anónimo'
|
||||
AND created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||
GROUP BY requester
|
||||
ORDER BY COUNT(*) DESC
|
||||
LIMIT 1
|
||||
");
|
||||
$topRequester = $topStmt->fetchColumn();
|
||||
|
||||
$stmt = db()->prepare("SELECT m.*, f.points, f.is_fan_of_month FROM messages m LEFT JOIN fans f ON m.username = f.name ORDER BY m.created_at DESC LIMIT 50");
|
||||
$stmt->execute();
|
||||
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
@ -43,7 +55,11 @@ if ($method === 'GET') {
|
||||
$msg['level_color'] = '#94a3b8';
|
||||
$msg['level_emoji'] = '';
|
||||
|
||||
if ($msg['is_fan_of_month']) {
|
||||
if ($msg['username'] === $topRequester) {
|
||||
$msg['level_color'] = '#facc15';
|
||||
$msg['level_emoji'] = '👑';
|
||||
$msg['is_top_listener'] = true;
|
||||
} elseif ($msg['is_fan_of_month']) {
|
||||
$msg['level_color'] = '#facc15';
|
||||
} elseif ($points >= 2500) {
|
||||
$msg['level_color'] = '#a855f7';
|
||||
|
||||
@ -36,6 +36,7 @@ if ($method === 'POST') {
|
||||
$artist = trim($_POST['artist'] ?? '');
|
||||
$song = trim($_POST['song'] ?? '');
|
||||
$requester = trim($_POST['requester'] ?? 'Anónimo');
|
||||
$source = trim($_POST['source'] ?? 'web');
|
||||
|
||||
if (empty($artist) || empty($song)) {
|
||||
echo json_encode(['success' => false, 'error' => 'Falta artista o canción']);
|
||||
@ -43,8 +44,8 @@ if ($method === 'POST') {
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$artist, $song, $requester]);
|
||||
$stmt = $db->prepare("INSERT INTO song_requests (artist, song, requester, source) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$artist, $song, $requester, $source]);
|
||||
|
||||
// Award points for song request
|
||||
if ($requester !== 'Anónimo') {
|
||||
|
||||
117
index.php
117
index.php
@ -1577,6 +1577,51 @@ $twitter_link = "https://twitter.com/";
|
||||
.chat-msg-item.is-me .chat-msg-time {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Top Listener Banner */
|
||||
.top-listener-banner {
|
||||
background: linear-gradient(135deg, rgba(250, 204, 21, 0.2), rgba(245, 158, 11, 0.3));
|
||||
border: 1px solid rgba(250, 204, 21, 0.4);
|
||||
border-radius: 16px;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
animation: fadeIn 0.8s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.top-listener-banner::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
transform: rotate(25deg);
|
||||
animation: modal-shine 6s infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
.top-listener-crown {
|
||||
font-size: 1.5rem;
|
||||
color: #facc15;
|
||||
filter: drop-shadow(0 0 5px rgba(250, 204, 21, 0.5));
|
||||
}
|
||||
.top-listener-name {
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.top-listener-label {
|
||||
font-size: 0.65rem;
|
||||
font-weight: 800;
|
||||
color: #facc15;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -1623,6 +1668,22 @@ $twitter_link = "https://twitter.com/";
|
||||
</header>
|
||||
|
||||
<div class="radio-player">
|
||||
<!-- Top Listener of the Week Banner -->
|
||||
<div id="top-listener-section" style="display: none;">
|
||||
<div class="top-listener-banner">
|
||||
<div class="top-listener-crown">
|
||||
<i class="bi bi-crown-fill"></i>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<span class="top-listener-label">Oyente de la Semana</span>
|
||||
<div id="top-listener-display" class="top-listener-name">Cargando...</div>
|
||||
</div>
|
||||
<div style="font-size: 0.7rem; opacity: 0.6; font-weight: 700; text-transform: uppercase;">
|
||||
<i class="bi bi-graph-up-arrow"></i> #1 Ranking
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="visualizer-container">
|
||||
<div id="audio-visualizer" class="audio-visualizer"></div>
|
||||
</div>
|
||||
@ -2861,12 +2922,35 @@ $twitter_link = "https://twitter.com/";
|
||||
btn.innerHTML = '<i class="bi bi-check-circle-fill"></i> ¡PEDIDA!';
|
||||
btn.style.backgroundColor = 'var(--accent-color)';
|
||||
|
||||
confetti({
|
||||
particleCount: 50,
|
||||
spread: 60,
|
||||
origin: { y: 0.8 },
|
||||
colors: ['#38bdf8', '#00e676']
|
||||
});
|
||||
// Celebration if the user is #1
|
||||
if (result.is_top) {
|
||||
confetti({
|
||||
particleCount: 200,
|
||||
spread: 90,
|
||||
origin: { y: 0.7 },
|
||||
colors: ['#facc15', '#ffffff', '#38bdf8']
|
||||
});
|
||||
|
||||
// Show special shoutout
|
||||
const shoutoutModal = document.getElementById('shoutout-modal');
|
||||
const shoutoutTarget = document.getElementById('shoutout-target');
|
||||
const shoutoutMsg = document.getElementById('shoutout-message');
|
||||
|
||||
shoutoutTarget.innerText = `¡FELICIDADES ${result.top_name.toUpperCase()}!`;
|
||||
shoutoutMsg.innerText = `¡Te has convertido en el Oyente #1 de la Semana! Gracias por tu increíble apoyo a Lili Records Radio. 👑📻`;
|
||||
|
||||
shoutoutModal.style.display = 'flex';
|
||||
setTimeout(() => shoutoutModal.classList.add('show'), 10);
|
||||
|
||||
fetchTopListener(); // Update banner
|
||||
} else {
|
||||
confetti({
|
||||
particleCount: 50,
|
||||
spread: 60,
|
||||
origin: { y: 0.8 },
|
||||
colors: ['#38bdf8', '#00e676']
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
btn.disabled = false;
|
||||
@ -3026,6 +3110,23 @@ $twitter_link = "https://twitter.com/";
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchTopListener() {
|
||||
try {
|
||||
const response = await fetch('api/get_top_requesters.php');
|
||||
const result = await response.json();
|
||||
if (result.success && result.data && result.data.length > 0) {
|
||||
const top = result.data[0];
|
||||
const section = document.getElementById('top-listener-section');
|
||||
const display = document.getElementById('top-listener-display');
|
||||
|
||||
display.innerHTML = `${top.requester} <span style="opacity: 0.7; font-size: 0.7rem; font-weight: 400;">(${top.total_requests} peticiones)</span>`;
|
||||
section.style.display = 'block';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching top listener:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Sleep Timer & Upcoming Tracks ---
|
||||
let sleepTimeout = null;
|
||||
let sleepInterval = null;
|
||||
@ -3527,16 +3628,20 @@ $twitter_link = "https://twitter.com/";
|
||||
// Update cycles
|
||||
setInterval(updateMetadata, 30000);
|
||||
setInterval(fetchTopSongs, 60000);
|
||||
setInterval(fetchTopListener, 60000);
|
||||
setInterval(fetchGallery, 3000); // Frecuencia aumentada para fotos efímeras (5s)
|
||||
setInterval(fetchLeaderboard, 60000);
|
||||
setInterval(fetchUpcomingTracks, 30000);
|
||||
setInterval(fetchActivePerks, 30000);
|
||||
|
||||
// Initial fetch
|
||||
updateMetadata();
|
||||
fetchTopSongs();
|
||||
fetchTopListener();
|
||||
fetchGallery();
|
||||
fetchLeaderboard();
|
||||
fetchUpcomingTracks();
|
||||
fetchActivePerks();
|
||||
|
||||
// Theme Toggle Functionality
|
||||
function toggleTheme() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user