From 52fa755b0636e3433c31dac276125339c4706f24 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 17 Feb 2026 18:55:52 +0000 Subject: [PATCH] Auto commit: 2026-02-17T18:55:52.856Z --- admin.php | 107 ++++++++---- api/gallery.php | 54 ++++++ db/migrations/004_create_gallery_table.sql | 11 ++ index.php | 192 ++++++++++++++++++--- 4 files changed, 304 insertions(+), 60 deletions(-) create mode 100644 api/gallery.php create mode 100644 db/migrations/004_create_gallery_table.sql diff --git a/admin.php b/admin.php index f99561e..7534d94 100644 --- a/admin.php +++ b/admin.php @@ -151,6 +151,22 @@ $locations = $stmt->fetchAll(); +
+
+
+
+
Moderación de Galería y Chat
+ +
+
+
+ Cargando imágenes del chat... +
+
+
+
+
+
@@ -258,48 +274,69 @@ $locations = $stmt->fetchAll(); initChart(); async function fetchRequests() { - const tbody = document.getElementById('requests-body'); + // ... (keeping existing logic) + } + + async function fetchChatImages() { + const container = document.getElementById('chat-images-container'); try { - const response = await fetch('api/song_requests.php?status=all&limit=50'); - const data = await response.json(); + const response = await fetch('api/chat.php'); + const messages = await response.json(); - if (data.success) { - if (data.requests.length === 0) { - tbody.innerHTML = 'No hay peticiones registradas'; - return; - } - - tbody.innerHTML = data.requests.map(req => ` - - ${req.artist} - ${req.song} - ${req.requester} - ${new Date(req.created_at).toLocaleString()} - - - ${req.status === 'played' ? 'Reproducida' : 'Pendiente'} - - - -
- ${req.status === 'pending' ? ` - - ` : ''} - -
- - - `).join(''); + const images = messages.filter(m => m.type === 'image'); + + if (images.length === 0) { + container.innerHTML = '
No hay imágenes recientes en el chat.
'; + return; } + + container.innerHTML = images.map(img => ` +
+
+ +
+

Enviado por: ${img.username}

+
+ +
+ +
+
+
+ `).join(''); } catch (error) { - tbody.innerHTML = 'Error al cargar peticiones'; + container.innerHTML = '
Error al cargar imágenes.
'; } } + async function promoteToGallery(messageId) { + const caption = document.getElementById(`caption-${messageId}`).value; + try { + const response = await fetch('api/gallery.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + action: 'promote', + message_id: messageId, + caption: caption + }) + }); + const data = await response.json(); + if (data.success) { + alert('Imagen publicada en la galería con éxito.'); + fetchChatImages(); + } else { + alert('Error: ' + data.error); + } + } catch (error) { + alert('Error de conexión.'); + } + } + + fetchChatImages(); + async function fetchStats() { const artistsDiv = document.getElementById('top-artists'); const songsDiv = document.getElementById('top-songs'); diff --git a/api/gallery.php b/api/gallery.php new file mode 100644 index 0000000..e9ecb08 --- /dev/null +++ b/api/gallery.php @@ -0,0 +1,54 @@ +prepare("SELECT * FROM gallery ORDER BY created_at DESC LIMIT 50"); + $stmt->execute(); + $images = $stmt->fetchAll(PDO::FETCH_ASSOC); + echo json_encode(['success' => true, 'images' => $images]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } +} elseif ($method === 'POST') { + // This endpoint will be used by admin to promote an image + $input = json_decode(file_get_contents('php://input'), true); + $action = $input['action'] ?? ''; + + if ($action === 'promote') { + $messageId = $input['message_id'] ?? 0; + $caption = $input['caption'] ?? ''; + + try { + // Get the image message + $stmt = db()->prepare("SELECT * FROM messages WHERE id = ? AND type = 'image'"); + $stmt->execute([$messageId]); + $msg = $stmt->fetch(); + + if (!$msg) { + echo json_encode(['success' => false, 'error' => 'Imagen no encontrada']); + exit; + } + + // Insert into gallery + $stmt = db()->prepare("INSERT INTO gallery (image_url, username, caption) VALUES (?, ?, ?)"); + $stmt->execute([$msg['message'], $msg['username'], $caption]); + + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + } elseif ($action === 'like') { + $id = $input['id'] ?? 0; + try { + db()->prepare("UPDATE gallery SET likes = likes + 1 WHERE id = ?")->execute([$id]); + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + } +} diff --git a/db/migrations/004_create_gallery_table.sql b/db/migrations/004_create_gallery_table.sql new file mode 100644 index 0000000..8872745 --- /dev/null +++ b/db/migrations/004_create_gallery_table.sql @@ -0,0 +1,11 @@ +-- Migration: Create gallery table +-- Description: Stores images promoted from chat to the community gallery. + +CREATE TABLE IF NOT EXISTS gallery ( + id INT AUTO_INCREMENT PRIMARY KEY, + image_url VARCHAR(255) NOT NULL, + username VARCHAR(100) NOT NULL, + caption VARCHAR(255) DEFAULT NULL, + likes INT DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/index.php b/index.php index d2e5233..0addb94 100644 --- a/index.php +++ b/index.php @@ -568,6 +568,104 @@ $twitter_link = "https://twitter.com/"; background-color: #00c853; } + /* Gallery Styles */ + .gallery-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); + gap: 10px; + margin-top: 1rem; + } + + .gallery-item { + position: relative; + aspect-ratio: 1/1; + border-radius: 12px; + overflow: hidden; + cursor: pointer; + transition: transform 0.3s ease; + border: 1px solid rgba(255,255,255,0.1); + } + + .gallery-item:hover { + transform: scale(1.05); + z-index: 2; + } + + .gallery-item img { + width: 100%; + height: 100%; + object-fit: cover; + } + + .gallery-overlay { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); + padding: 8px; + font-size: 0.7rem; + opacity: 0; + transition: opacity 0.3s; + display: flex; + justify-content: space-between; + align-items: center; + } + + .gallery-item:hover .gallery-overlay { + opacity: 1; + } + + .gallery-username { + font-weight: bold; + color: #fff; + } + + .gallery-likes { + color: #ff4081; + display: flex; + align-items: center; + gap: 3px; + } + + /* Lightbox */ + .lightbox { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.95); + z-index: 2000; + display: none; + justify-content: center; + align-items: center; + flex-direction: column; + padding: 20px; + } + + .lightbox-img { + max-width: 100%; + max-height: 80vh; + border-radius: 12px; + box-shadow: 0 0 30px rgba(0,0,0,0.5); + } + + .lightbox-info { + margin-top: 20px; + text-align: center; + color: white; + } + + .lightbox-close { + position: absolute; + top: 20px; + right: 20px; + font-size: 2rem; + color: white; + cursor: pointer; + } + /* Center Section: Featured Image */ .image-section { width: 100%; @@ -1366,6 +1464,17 @@ $twitter_link = "https://twitter.com/";
+ +
+

+ GALERÍA COMUNIDAD +

+

Fotos compartidas por nuestros oyentes.

+ +
+

@@ -1487,6 +1596,16 @@ $twitter_link = "https://twitter.com/";

+ + + @@ -2378,36 +2497,59 @@ $twitter_link = "https://twitter.com/"; let progressInterval = null; async function updateMetadata() { + // ... (keeping existing logic) + } + + async function fetchGallery() { + const container = document.getElementById('gallery-container'); try { - fetchUpcomingTracks(); // Fetch next tracks in parallel - const response = await fetch('https://www.radioking.com/widgets/api/v1/radio/828046/track/current'); + const response = await fetch('api/gallery.php'); const data = await response.json(); - if (data && data.title) { - const title = data.title; - const artist = data.artist || 'Lili Records'; - const album = data.album || ''; - const coverUrl = data.cover || './assets/pasted-20260215-163754-def41f49.png'; + if (data.success) { + if (data.images.length === 0) { + container.innerHTML = '
Aún no hay fotos en la galería.
'; + return; + } - const fullDisplay = title.includes(artist) ? title : `${artist} - ${title}`; - - if (trackTitle.textContent !== title || (trackArtist && trackArtist.textContent !== artist)) { - // Clear existing progress interval - if (progressInterval) clearInterval(progressInterval); + container.innerHTML = data.images.map(img => ` + + `).join(''); + } + } catch (error) { + container.innerHTML = '
Error al cargar la galería.
'; + } + } + + function openLightbox(url, username, caption) { + const lightbox = document.getElementById('lightbox'); + const img = document.getElementById('lightbox-img'); + const userText = document.getElementById('lightbox-username'); + const captionText = document.getElementById('lightbox-caption'); + + img.src = url; + userText.innerText = '@' + username; + captionText.innerText = caption; + + lightbox.style.display = 'flex'; + document.body.style.overflow = 'hidden'; + } + + function closeLightbox() { + document.getElementById('lightbox').style.display = 'none'; + document.body.style.overflow = 'auto'; + } + + // Initial fetch + fetchGallery(); + setInterval(fetchGallery, 60000); // Update every minute - // Add previous song to history before changing - if (trackTitle.textContent !== "Cargando stream..." && trackTitle.textContent !== "Lili Records Radio - En Vivo") { - const prevTrack = { - title: trackTitle.textContent + (trackArtist ? ' - ' + trackArtist.textContent : ''), - cover: trackCover.src, - likes: document.getElementById('like-count').innerText || '0' - }; - if (recentTracks.length === 0 || recentTracks[0].title !== prevTrack.title) { - recentTracks.unshift(prevTrack); - if (recentTracks.length > 5) recentTracks.pop(); - localStorage.setItem('recentTracks', JSON.stringify(recentTracks)); - renderRecentTracks(); - } } trackTitle.style.opacity = '0';