Auto commit: 2026-02-19T20:09:03.045Z
This commit is contained in:
parent
29838e7f6a
commit
ceada41f52
73
api/dj_actions.php
Normal file
73
api/dj_actions.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!$data) {
|
||||
$data = $_POST;
|
||||
}
|
||||
|
||||
$username = $data['username'] ?? '';
|
||||
$action = $data['action'] ?? '';
|
||||
$requestId = $data['request_id'] ?? null;
|
||||
|
||||
if (empty($username) || empty($action)) {
|
||||
echo json_encode(['success' => false, 'error' => 'Datos incompletos']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
|
||||
// Verify Guest DJ status
|
||||
$stmt = $db->prepare("SELECT dj_day_until FROM fans WHERE name = ?");
|
||||
$stmt->execute([$username]);
|
||||
$dj_day_until = $stmt->fetchColumn();
|
||||
|
||||
$isGuestDj = $dj_day_until && (strtotime($dj_day_until) > time());
|
||||
|
||||
if (!$isGuestDj) {
|
||||
echo json_encode(['success' => false, 'error' => 'No tienes permisos de DJ Invitado activos']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'skip') {
|
||||
// Log skip action
|
||||
$stmt = $db->prepare("INSERT INTO radio_actions (action_type, performed_by, details) VALUES ('skip', ?, ?)");
|
||||
$stmt->execute([$username, "El DJ Invitado ha solicitado saltar la canción"]);
|
||||
|
||||
// Announce in chat
|
||||
$chatMsg = "🚨 [DJ INVITADO] **$username** ha usado su poder para SALTAR la canción actual. ⏭️";
|
||||
$stmt = $db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'text')");
|
||||
$stmt->execute([$chatMsg]);
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Acción de saltar ejecutada y anunciada']);
|
||||
|
||||
} elseif ($action === 'prioritize') {
|
||||
if (!$requestId) {
|
||||
echo json_encode(['success' => false, 'error' => 'ID de petición faltante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("UPDATE song_requests SET is_priority = 1 WHERE id = ?");
|
||||
$stmt->execute([$requestId]);
|
||||
|
||||
// Get request details for announcement
|
||||
$stmt = $db->prepare("SELECT artist, song FROM song_requests WHERE id = ?");
|
||||
$stmt->execute([$requestId]);
|
||||
$req = $stmt->fetch();
|
||||
|
||||
if ($req) {
|
||||
$chatMsg = "🔥 [DJ INVITADO] **$username** ha PRIORIZADO la canción: **{$req['artist']} - {$req['song']}**. ¡Sonará muy pronto! 🎵";
|
||||
$stmt = $db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'text')");
|
||||
$stmt->execute([$chatMsg]);
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Petición priorizada con éxito']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Acción no válida']);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||
}
|
||||
@ -152,9 +152,9 @@ if ($method === 'GET') {
|
||||
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
|
||||
|
||||
if ($status === 'all') {
|
||||
$stmt = $db->query("SELECT * FROM song_requests ORDER BY created_at DESC LIMIT $limit");
|
||||
$stmt = $db->query("SELECT * FROM song_requests ORDER BY is_priority DESC, created_at DESC LIMIT $limit");
|
||||
} else {
|
||||
$stmt = $db->prepare("SELECT * FROM song_requests WHERE status = ? ORDER BY created_at DESC LIMIT $limit");
|
||||
$stmt = $db->prepare("SELECT * FROM song_requests WHERE status = ? ORDER BY is_priority DESC, created_at DESC LIMIT $limit");
|
||||
$stmt->execute([$status]);
|
||||
}
|
||||
|
||||
|
||||
11
db/migrations/20260219_dj_powers.sql
Normal file
11
db/migrations/20260219_dj_powers.sql
Normal file
@ -0,0 +1,11 @@
|
||||
-- Add priority support for Guest DJs
|
||||
ALTER TABLE song_requests ADD COLUMN is_priority TINYINT(1) DEFAULT 0;
|
||||
|
||||
-- Table for radio actions (skips, etc)
|
||||
CREATE TABLE IF NOT EXISTS radio_actions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
action_type VARCHAR(50) NOT NULL,
|
||||
performed_by VARCHAR(255) NOT NULL,
|
||||
details TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
91
index.php
91
index.php
@ -1809,6 +1809,9 @@ $twitter_link = "https://twitter.com/";
|
||||
<div class="controls">
|
||||
<button id="play-pause" class="play-btn" onclick="togglePlay()">
|
||||
<i id="play-icon" class="bi bi-play-fill"></i>
|
||||
</button>
|
||||
<button id="dj-skip-btn" onclick="djSkipSong()" style="display: none; background: rgba(250, 204, 21, 0.2); border: 1px solid #facc15; color: #facc15; width: 45px; height: 45px; border-radius: 50%; align-items: center; justify-content: center; cursor: pointer; margin-left: 10px; transition: all 0.3s;" title="Saltar Canción (Poder DJ)">
|
||||
<i class="bi bi-skip-forward-fill"></i>
|
||||
</button>
|
||||
<i class="bi bi-volume-up"></i>
|
||||
<input type="range" class="volume-slider" min="0" max="1" step="0.01" value="1" oninput="changeVolume(this.value)">
|
||||
@ -3087,28 +3090,106 @@ $twitter_link = "https://twitter.com/";
|
||||
try {
|
||||
const response = await fetch('api/song_requests.php');
|
||||
const result = await response.json();
|
||||
|
||||
// Check if current user is Guest DJ
|
||||
const currentUserName = document.getElementById('user-name').value.trim();
|
||||
let isGuestDj = false;
|
||||
|
||||
// We can check if the current user has the Guest DJ status from the online users data or another check
|
||||
// For simplicity, let's do a quick local check if we've already fetched online users
|
||||
const onlineUsersResponse = await fetch('api/get_online_users.php');
|
||||
const onlineData = await onlineUsersResponse.json();
|
||||
if (onlineData.success && currentUserName) {
|
||||
const me = onlineData.users.find(u => u.username.toLowerCase() === currentUserName.toLowerCase());
|
||||
if (me && me.dj_day_until && (new Date(me.dj_day_until) > new Date())) {
|
||||
isGuestDj = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Show/hide Skip button
|
||||
const skipBtn = document.getElementById('dj-skip-btn');
|
||||
if (skipBtn) skipBtn.style.display = isGuestDj ? 'flex' : 'none';
|
||||
|
||||
if (result.success) {
|
||||
const list = document.getElementById('song-requests-list');
|
||||
if (result.requests.length === 0) {
|
||||
list.innerHTML = '<div style="opacity: 0.5; font-size: 0.85rem; text-align: center; padding: 2rem;">No hay peticiones recientes.</div>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = result.requests.map(req => `
|
||||
<div class="request-item">
|
||||
list.innerHTML = result.requests.map(req => {
|
||||
const isPriority = req.is_priority == 1;
|
||||
return `
|
||||
<div class="request-item" style="${isPriority ? 'border-left: 4px solid #facc15; background: rgba(250, 204, 21, 0.05);' : ''}">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px;">
|
||||
<span class="artist">${req.artist}</span>
|
||||
<span class="artist" style="${isPriority ? 'color: #facc15;' : ''}">${isPriority ? '⭐ ' : ''}${req.artist}</span>
|
||||
<span style="font-size: 0.6rem; opacity: 0.4;">${new Date(req.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</span>
|
||||
</div>
|
||||
<div class="song">${req.song}</div>
|
||||
<div class="requester"><i class="bi bi-person-fill"></i> ${req.requester}</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 5px;">
|
||||
<div class="requester"><i class="bi bi-person-fill"></i> ${req.requester}</div>
|
||||
${isGuestDj && !isPriority ? `
|
||||
<button onclick="djPrioritizeSong(${req.id})" style="background: #facc15; color: black; border: none; font-size: 0.6rem; padding: 2px 8px; border-radius: 4px; font-weight: 800; cursor: pointer;">
|
||||
<i class="bi bi-star-fill"></i> PRIORIZAR
|
||||
</button>
|
||||
` : ''}
|
||||
${isPriority ? '<span style="color: #facc15; font-size: 0.6rem; font-weight: 800;"><i class="bi bi-lightning-fill"></i> PRIORIDAD DJ</span>' : ''}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching requests:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function djSkipSong() {
|
||||
const username = document.getElementById('user-name').value.trim();
|
||||
if (!username) return;
|
||||
|
||||
if (!confirm('¿Estás seguro de que quieres usar tu poder de DJ para SALTAR esta canción?')) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('api/dj_actions.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: username, action: 'skip' })
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
alert('¡Canción saltada! Se ha anunciado en el chat.');
|
||||
fetchMessages();
|
||||
} else {
|
||||
alert('Error: ' + result.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error skipping song:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function djPrioritizeSong(requestId) {
|
||||
const username = document.getElementById('user-name').value.trim();
|
||||
if (!username) return;
|
||||
|
||||
try {
|
||||
const response = await fetch('api/dj_actions.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: username, action: 'prioritize', request_id: requestId })
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
alert('¡Petición priorizada! Sonará pronto.');
|
||||
fetchSongRequests();
|
||||
fetchMessages();
|
||||
} else {
|
||||
alert('Error: ' + result.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error prioritizing song:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function submitSongRequest() {
|
||||
const artistInput = document.getElementById('req-artist');
|
||||
const songInput = document.getElementById('req-song');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user