Auto commit: 2026-02-16T22:52:33.215Z

This commit is contained in:
Flatlogic Bot 2026-02-16 22:52:33 +00:00
parent 1151eb2fd7
commit e7beea1aa6
4 changed files with 369 additions and 7 deletions

35
api/record_history.php Normal file
View File

@ -0,0 +1,35 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
$input = json_decode(file_get_contents('php://input'), true);
if (!$input || empty($input['title']) || empty($input['artist'])) {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
exit;
}
$title = $input['title'];
$artist = $input['artist'];
$cover = $input['cover'] ?? null;
try {
$db = db();
// Check if the last recorded song is the same to avoid duplicates on refresh
$stmt = $db->prepare("SELECT title, artist FROM song_history ORDER BY played_at DESC LIMIT 1");
$stmt->execute();
$last = $stmt->fetch();
if ($last && $last['title'] === $title && $last['artist'] === $artist) {
echo json_encode(['success' => true, 'message' => 'Already recorded']);
exit;
}
$stmt = $db->prepare("INSERT INTO song_history (title, artist, cover) VALUES (?, ?, ?)");
$stmt->execute([$title, $artist, $cover]);
echo json_encode(['success' => true]);
} catch (PDOException $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS song_history (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
artist VARCHAR(255) NOT NULL,
cover VARCHAR(500),
played_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

263
history.php Normal file
View File

@ -0,0 +1,263 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Lili Records Radio - Historial de canciones.';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? 'assets/pasted-20260215-164611-6d2aee42.png';
$db = db();
$stmt = $db->query("SELECT * FROM song_history WHERE played_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) ORDER BY played_at DESC LIMIT 50");
$history = $stmt->fetchAll();
?>
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Historial - Lili Records Radio</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<style>
:root {
--accent-color: #00c853;
--primary-color: #38bdf8;
--bg-overlay: rgba(0, 0, 0, 0.4);
--glass-bg: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.2);
--text-color: #ffffff;
}
[data-theme="light"] {
--bg-overlay: rgba(255, 255, 255, 0.6);
--glass-bg: rgba(255, 255, 255, 0.8);
--glass-border: rgba(0, 0, 0, 0.1);
--text-color: #1a1a1a;
}
body, html {
margin: 0;
padding: 0;
width: 100%;
min-height: 100%;
font-family: 'Inter', sans-serif;
color: var(--text-color);
background: #111;
transition: color 0.3s ease;
}
.background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('assets/images/background.jpg') center/cover no-repeat;
z-index: -1;
}
.background::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--bg-overlay);
}
.app-container {
display: flex;
flex-direction: column;
width: 100%;
min-height: 100vh;
align-items: center;
padding: 2rem 1.5rem;
box-sizing: border-box;
}
.glass-card {
background: var(--glass-bg);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid var(--glass-border);
border-radius: 32px;
padding: 2.5rem;
width: 100%;
max-width: 600px;
box-shadow: 0 15px 45px rgba(0, 0, 0, 0.4);
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 2rem;
}
.header h1 {
font-size: 1.8rem;
font-weight: 800;
margin: 0;
background: linear-gradient(to right, #fff, var(--primary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.back-btn {
color: var(--text-color);
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: 600;
opacity: 0.8;
transition: opacity 0.2s;
}
.back-btn:hover {
opacity: 1;
}
.history-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.history-item {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.05);
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.1);
transition: transform 0.2s;
}
.history-item:hover {
transform: translateX(10px);
background: rgba(255, 255, 255, 0.1);
}
.history-item img {
width: 50px;
height: 50px;
border-radius: 8px;
object-fit: cover;
}
.history-info {
flex: 1;
overflow: hidden;
}
.history-title {
font-weight: 700;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
.history-artist {
font-size: 0.85rem;
opacity: 0.7;
color: var(--primary-color);
}
.history-time {
font-size: 0.7rem;
opacity: 0.5;
text-align: right;
}
.theme-toggle {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
color: var(--text-color);
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
backdrop-filter: blur(5px);
transition: all 0.3s;
}
</style>
</head>
<body data-theme="dark">
<div class="background"></div>
<div class="app-container">
<div class="glass-card">
<div class="header">
<a href="index.php" class="back-btn">
<i class="bi bi-arrow-left"></i> VOLVER
</a>
<h1>HISTORIAL</h1>
<button onclick="toggleTheme()" id="theme-toggle" class="theme-toggle">
<i class="bi bi-moon-fill"></i>
</button>
</div>
<div class="history-list">
<?php if (empty($history)): ?>
<div style="text-align: center; opacity: 0.5; padding: 2rem;">No hay canciones registradas en las últimas 24 horas.</div>
<?php else: ?>
<?php foreach ($history as $track): ?>
<div class="history-item">
<img src="<?= htmlspecialchars($track['cover'] ?: './assets/pasted-20260215-163754-def41f49.png') ?>" alt="Cover">
<div class="history-info">
<span class="history-title"><?= htmlspecialchars($track['title']) ?></span>
<span class="history-artist"><?= htmlspecialchars($track['artist']) ?></span>
</div>
<div class="history-time">
<?= date('H:i', strtotime($track['played_at'])) ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<script>
function toggleTheme() {
const body = document.body;
const currentTheme = body.getAttribute('data-theme');
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
body.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
if (newTheme === 'light') {
themeBtn.classList.remove('bi-moon-fill');
themeBtn.classList.add('bi-sun-fill');
} else {
themeBtn.classList.remove('bi-sun-fill');
themeBtn.classList.add('bi-moon-fill');
}
}
// Initialize Theme
(function() {
const savedTheme = localStorage.getItem('theme') || 'dark';
if (savedTheme === 'light') {
document.body.setAttribute('data-theme', 'light');
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
themeBtn.classList.remove('bi-moon-fill');
themeBtn.classList.add('bi-sun-fill');
}
})();
</script>
</body>
</html>

View File

@ -39,6 +39,16 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
--bg-overlay: rgba(0, 0, 0, 0.15); /* Even lighter for maximum transparency */
--glass-bg: rgba(255, 255, 255, 0.03); /* Almost invisible glass */
--glass-border: rgba(255, 255, 255, 0.2);
--text-color: #ffffff;
--card-shadow: rgba(0, 0, 0, 0.4);
}
[data-theme="light"] {
--bg-overlay: rgba(255, 255, 255, 0.6);
--glass-bg: rgba(255, 255, 255, 0.8);
--glass-border: rgba(0, 0, 0, 0.1);
--text-color: #1a1a1a;
--card-shadow: rgba(0, 0, 0, 0.15);
}
body, html {
@ -47,8 +57,9 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
width: 100%;
height: 100%;
font-family: 'Inter', sans-serif;
color: #ffffff;
color: var(--text-color);
background-color: transparent;
transition: color 0.3s ease;
}
.background {
@ -144,7 +155,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
font-size: 2.8rem;
font-weight: 800;
margin: 0 0 0.5rem;
background: linear-gradient(to right, #fff, var(--primary-color), var(--accent-color));
background: linear-gradient(to right, var(--text-color), var(--primary-color), var(--accent-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
letter-spacing: -1px;
@ -248,7 +259,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
overflow: hidden;
text-overflow: ellipsis;
transition: color 0.05s ease, transform 0.05s ease, text-shadow 0.05s ease, opacity 0.5s ease;
color: #ffffff;
color: var(--text-color);
text-shadow: 0 0 15px rgba(56, 189, 248, 0.6);
display: block;
margin-top: 0.2rem;
@ -500,9 +511,9 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
width: 100%;
padding: 0.8rem;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
background-color: rgba(255, 255, 255, 0.05); /* Even more transparent */
color: #ffffff;
border: 1px solid var(--glass-border);
background-color: var(--glass-bg);
color: var(--text-color);
font-family: inherit;
font-size: 0.95rem;
box-sizing: border-box;
@ -518,7 +529,8 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
.interaction-form input::placeholder,
.interaction-form textarea::placeholder {
color: rgba(255, 255, 255, 0.6);
color: var(--text-color);
opacity: 0.5;
}
.send-whatsapp-btn {
@ -900,6 +912,14 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
<section class="player-section">
<div class="glass-card">
<header class="brand">
<div style="position: absolute; top: 1rem; right: 1rem; display: flex; gap: 0.5rem; z-index: 100;">
<button onclick="toggleTheme()" id="theme-toggle" style="background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-color); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; backdrop-filter: blur(5px); transition: all 0.3s;" title="Cambiar tema">
<i class="bi bi-moon-fill"></i>
</button>
<a href="history.php" style="background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-color); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; backdrop-filter: blur(5px); transition: all 0.3s; text-decoration: none;" title="Historial de canciones">
<i class="bi bi-clock-history"></i>
</a>
</div>
<div class="logo-wrapper">
<img src="./assets/pasted-20260215-163754-def41f49.png" alt="Lili Records Logo" class="brand-logo">
<img src="./assets/pasted-20260215-171328-d90df4ce.jpg" alt="Logo Secundario" class="brand-logo">
@ -1929,6 +1949,13 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
if (coverPlaceholder) coverPlaceholder.style.display = 'none';
trackCover.style.opacity = '1';
// Record History in Database
fetch('api/record_history.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: title, artist: artist, cover: coverUrl })
}).catch(err => console.error("Error recording history:", err));
// Dynamic Color Extraction
trackCover.onload = function() {
try {
@ -2032,6 +2059,36 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
fetchTopSongs();
}, 30000);
// Theme Toggle Functionality
function toggleTheme() {
const body = document.body;
const currentTheme = body.getAttribute('data-theme');
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
body.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
if (newTheme === 'light') {
themeBtn.classList.remove('bi-moon-fill');
themeBtn.classList.add('bi-sun-fill');
} else {
themeBtn.classList.remove('bi-sun-fill');
themeBtn.classList.add('bi-moon-fill');
}
}
// Initialize Theme
(function() {
const savedTheme = localStorage.getItem('theme') || 'dark';
if (savedTheme === 'light') {
document.body.setAttribute('data-theme', 'light');
const themeBtn = document.getElementById('theme-toggle').querySelector('i');
themeBtn.classList.remove('bi-moon-fill');
themeBtn.classList.add('bi-sun-fill');
}
})();
// Handle possible audio interruptions
audio.addEventListener('error', function(e) {
console.error('Audio error:', e);