Auto commit: 2026-02-16T00:47:47.045Z
This commit is contained in:
parent
e2520899e4
commit
35df30ab56
42
admin.php
42
admin.php
@ -47,48 +47,6 @@ $locations = $stmt->fetchAll();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5><i class="bi bi-star-fill text-warning"></i> Gestión de Top Fans</h5>
|
||||
<span class="badge bg-warning text-dark">Ranking Activo</span>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Puesto</th>
|
||||
<th>Nombre del Fan</th>
|
||||
<th>Likes</th>
|
||||
<th>Color Personalizado</th>
|
||||
<th>Estado</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$stmt = $db->query("SELECT username, total_likes, custom_color FROM user_likes ORDER BY total_likes DESC LIMIT 10");
|
||||
$top_fans = $stmt->fetchAll();
|
||||
$rank = 1;
|
||||
foreach ($top_fans as $fan):
|
||||
$vip_badge = ($rank === 1) ? '<span class="badge bg-warning text-dark">VIP</span>' : '';
|
||||
$color_preview = $fan['custom_color'] ? '<span class="d-inline-block" style="width: 20px; height: 20px; border-radius: 50%; background: '.$fan['custom_color'].'; vertical-align: middle;"></span> ' . $fan['custom_color'] : '<span class="text-secondary small">Predeterminado</span>';
|
||||
?>
|
||||
<tr>
|
||||
<td>#<?= $rank ?></td>
|
||||
<td><?= htmlspecialchars($fan['username']) ?> <?= $vip_badge ?></td>
|
||||
<td><span class="badge bg-outline-success border border-success text-success"><?= $fan['total_likes'] ?></span></td>
|
||||
<td><?= $color_preview ?></td>
|
||||
<td><span class="text-success small"><i class="bi bi-check-circle-fill"></i> Activo</span></td>
|
||||
</tr>
|
||||
<?php $rank++; endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card p-4 text-center">
|
||||
|
||||
21
api/chat.php
21
api/chat.php
@ -7,6 +7,20 @@ $method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
if ($method === 'GET') {
|
||||
try {
|
||||
// Limpiar mensajes y archivos de más de 6 horas
|
||||
$oldImages = db()->prepare("SELECT message FROM messages WHERE type = 'image' AND created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)");
|
||||
$oldImages->execute();
|
||||
$filesToDelete = $oldImages->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($filesToDelete as $fileRow) {
|
||||
$filePath = __DIR__ . '/../' . $fileRow['message'];
|
||||
if (file_exists($filePath) && is_file($filePath)) {
|
||||
unlink($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
db()->query("DELETE FROM messages WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)");
|
||||
|
||||
$stmt = db()->prepare("SELECT m.*, ul.custom_color FROM messages m LEFT JOIN user_likes ul ON m.username = ul.username ORDER BY m.created_at DESC LIMIT 50");
|
||||
$stmt->execute();
|
||||
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
@ -18,6 +32,9 @@ if ($method === 'GET') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$username = $input['username'] ?? 'Anónimo';
|
||||
$message = $input['message'] ?? '';
|
||||
$type = $input['type'] ?? 'text';
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
|
||||
$ip = explode(',', $ip)[0];
|
||||
|
||||
if (empty($message)) {
|
||||
echo json_encode(['error' => 'Mensaje vacío']);
|
||||
@ -25,8 +42,8 @@ if ($method === 'GET') {
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = db()->prepare("INSERT INTO messages (username, message) VALUES (?, ?)");
|
||||
$stmt->execute([$username, $message]);
|
||||
$stmt = db()->prepare("INSERT INTO messages (username, ip_address, message, type) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$username, $ip, $message, $type]);
|
||||
echo json_encode(['success' => true]);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
|
||||
@ -25,8 +25,10 @@ try {
|
||||
|
||||
// 3. Post to chat
|
||||
$message = "¡Le dio un ❤️ a la canción: $song_title!";
|
||||
$stmtChat = $pdo->prepare("INSERT INTO messages (username, message) VALUES (?, ?)");
|
||||
$stmtChat->execute([$username, $message]);
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
|
||||
$ip = explode(',', $ip)[0];
|
||||
$stmtChat = $pdo->prepare("INSERT INTO messages (username, ip_address, message) VALUES (?, ?, ?)");
|
||||
$stmtChat->execute([$username, $ip, $message]);
|
||||
|
||||
// 3. Get total likes for this song
|
||||
$stmtCount = $pdo->prepare("SELECT likes_count FROM song_likes WHERE song_title = ?");
|
||||
|
||||
57
api/upload.php
Normal file
57
api/upload.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['error' => 'Método no permitido']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_FILES['image'])) {
|
||||
echo json_encode(['error' => 'No se recibió ninguna imagen']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['image'];
|
||||
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
$maxSize = 5 * 1024 * 1024; // 5MB
|
||||
|
||||
// Límite de imágenes por usuario (basado en IP)
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
|
||||
$ip = explode(',', $ip)[0];
|
||||
|
||||
try {
|
||||
$stmt = db()->prepare("SELECT COUNT(*) FROM messages WHERE ip_address = ? AND type = 'image' AND created_at > DATE_SUB(NOW(), INTERVAL 6 HOUR)");
|
||||
$stmt->execute([$ip]);
|
||||
$count = $stmt->fetchColumn();
|
||||
|
||||
if ($count >= 10) {
|
||||
echo json_encode(['error' => 'Has alcanzado el límite de 10 imágenes cada 6 horas para evitar abusos']);
|
||||
exit;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Si falla la verificación, continuamos pero logueamos
|
||||
error_log("Error checking upload limit: " . $e->getMessage());
|
||||
}
|
||||
|
||||
if (!in_array($file['type'], $allowedTypes)) {
|
||||
echo json_encode(['error' => 'Formato de imagen no permitido (solo JPG, PNG, GIF, WEBP)']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($file['size'] > $maxSize) {
|
||||
echo json_encode(['error' => 'La imagen es demasiado grande (máximo 5MB)']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
|
||||
$filename = uniqid('img_', true) . '.' . $ext;
|
||||
$targetPath = __DIR__ . '/../uploads/' . $filename;
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
|
||||
$url = 'uploads/' . $filename;
|
||||
echo json_encode(['success' => true, 'url' => $url]);
|
||||
} else {
|
||||
echo json_encode(['error' => 'Error al guardar la imagen']);
|
||||
}
|
||||
208
index.php
208
index.php
@ -30,6 +30,7 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
<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">
|
||||
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js"></script>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
@ -584,42 +585,6 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
100% { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
|
||||
.fan-1 { color: #facc15 !important; font-weight: 800 !important; text-shadow: 0 0 10px rgba(250, 204, 21, 0.5); }
|
||||
.fan-2 { color: #cbd5e1 !important; font-weight: 700 !important; }
|
||||
.fan-3 { color: #fb923c !important; font-weight: 700 !important; }
|
||||
|
||||
.vip-badge {
|
||||
background: linear-gradient(45deg, #facc15, #fbbf24);
|
||||
color: #000;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.6rem;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
margin-left: 5px;
|
||||
box-shadow: 0 0 10px rgba(250, 204, 21, 0.5);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.color-picker-container {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 10px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 1rem;
|
||||
display: none; /* Hidden by default */
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border: 1px solid rgba(250, 204, 21, 0.3);
|
||||
}
|
||||
|
||||
@keyframes fan-entry {
|
||||
0% { transform: scale(0.8); opacity: 0; }
|
||||
50% { transform: scale(1.1); }
|
||||
100% { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 992px) {
|
||||
.app-container {
|
||||
@ -744,8 +709,8 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- Interaction Center: Live Chat & Rankings -->
|
||||
<section class="interaction-center" style="width: 100%; max-width: 850px; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; z-index: 10;">
|
||||
<!-- Interaction Center: Live Chat -->
|
||||
<section class="interaction-center" style="width: 100%; max-width: 600px; z-index: 10;">
|
||||
<!-- Live Web Chat -->
|
||||
<div class="glass-card chat-window" style="height: 500px; display: flex; flex-direction: column;">
|
||||
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: var(--primary-color);">
|
||||
@ -755,33 +720,21 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
<!-- Mensajes se cargarán aquí -->
|
||||
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Cargando mensajes...</div>
|
||||
</div>
|
||||
<div class="chat-input-area" style="display: flex; gap: 0.5rem;">
|
||||
<div class="chat-input-area" style="display: flex; gap: 0.5rem; position: relative;">
|
||||
<input type="hidden" id="chat-user">
|
||||
<button onclick="toggleEmojiPicker()" style="background: rgba(255,255,255,0.1); border: none; border-radius: 8px; color: white; padding: 0 0.5rem; cursor: pointer;">
|
||||
<i class="bi bi-emoji-smile"></i>
|
||||
</button>
|
||||
<button onclick="document.getElementById('chat-file').click()" style="background: rgba(255,255,255,0.1); border: none; border-radius: 8px; color: white; padding: 0 0.5rem; cursor: pointer;">
|
||||
<i class="bi bi-camera-fill"></i>
|
||||
</button>
|
||||
<input type="file" id="chat-file" style="display: none;" accept="image/*" onchange="uploadImage(this)">
|
||||
<input type="text" id="chat-msg" placeholder="Escribe un mensaje..." style="flex: 1; font-size: 0.8rem; padding: 0.5rem; border-radius: 8px; border: none; background: rgba(255,255,255,0.1); color: white;">
|
||||
<button onclick="sendChatMessage()" style="background: var(--primary-color); border: none; border-radius: 8px; color: white; padding: 0 1rem; cursor: pointer;">
|
||||
<i class="bi bi-send-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Top Fans / Rankings -->
|
||||
<div class="glass-card ranking-window" style="height: 500px; display: flex; flex-direction: column;">
|
||||
<h3 style="font-size: 1.2rem; margin-bottom: 1rem; color: #facc15;">
|
||||
<i class="bi bi-trophy-fill"></i> TOP FANS
|
||||
</h3>
|
||||
|
||||
<div id="fan-customization" class="color-picker-container">
|
||||
<span style="font-size: 0.8rem; font-weight: bold; color: #facc15;">🎨 COLOR VIP:</span>
|
||||
<input type="color" id="vip-color-input" onchange="updateCustomColor(this.value)" style="border: none; background: none; cursor: pointer; width: 30px; height: 30px; padding: 0;">
|
||||
<span style="font-size: 0.7rem; opacity: 0.8;">Elige tu color personalizado</span>
|
||||
</div>
|
||||
|
||||
<div id="top-fans-list" style="flex: 1; display: flex; flex-direction: column; gap: 1rem;">
|
||||
<!-- Fans se cargarán aquí -->
|
||||
<div style="opacity: 0.5; font-size: 0.9rem; text-align: center; margin-top: 2rem;">Calculando ranking...</div>
|
||||
</div>
|
||||
<div style="font-size: 0.75rem; opacity: 0.6; text-align: center; margin-top: 1rem; padding: 0.5rem; background: rgba(255,255,255,0.05); border-radius: 8px;">
|
||||
¡Dales "Like" a tus canciones favoritas para subir en el ranking!
|
||||
<emoji-picker id="emoji-picker" style="display: none; position: absolute; bottom: 50px; left: 0; z-index: 1000; --num-columns: 6; --category-button-size: 1.5rem; width: 300px; height: 350px;"></emoji-picker>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -1000,92 +953,49 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
const chatMessages = document.getElementById('chat-messages');
|
||||
const chatUser = document.getElementById('chat-user');
|
||||
const chatMsg = document.getElementById('chat-msg');
|
||||
const emojiPicker = document.getElementById('emoji-picker');
|
||||
let lastMessageCount = 0;
|
||||
let topFans = [];
|
||||
let welcomeSoundPlayed = false;
|
||||
|
||||
async function fetchTopFans() {
|
||||
try {
|
||||
const response = await fetch('api/get_top_fans.php');
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
topFans = data.fans;
|
||||
const list = document.getElementById('top-fans-list');
|
||||
list.innerHTML = '';
|
||||
|
||||
const currentUserName = document.getElementById('user-name').value.trim();
|
||||
const customizationBox = document.getElementById('fan-customization');
|
||||
let isTop3 = false;
|
||||
|
||||
data.fans.forEach((fan, index) => {
|
||||
const div = document.createElement('div');
|
||||
const medal = index === 0 ? '🥇' : (index === 1 ? '🥈' : (index === 2 ? '🥉' : '👤'));
|
||||
const scale = index === 0 ? '1.1' : '1';
|
||||
const opacity = 1 - (index * 0.1);
|
||||
|
||||
// Check if current user is in Top 3
|
||||
if (index < 3 && fan.username === currentUserName && currentUserName !== "") {
|
||||
isTop3 = true;
|
||||
if (fan.custom_color) {
|
||||
document.getElementById('vip-color-input').value = fan.custom_color;
|
||||
}
|
||||
}
|
||||
|
||||
// Welcome sound for #1 fan
|
||||
if (index === 0 && fan.username === currentUserName && !welcomeSoundPlayed && currentUserName !== "") {
|
||||
document.getElementById('welcome-sound').play().catch(e => console.log("Audio play blocked"));
|
||||
welcomeSoundPlayed = true;
|
||||
}
|
||||
|
||||
div.style.background = 'rgba(255,255,255,0.05)';
|
||||
div.style.padding = '0.8rem';
|
||||
div.style.borderRadius = '12px';
|
||||
div.style.display = 'flex';
|
||||
div.style.alignItems = 'center';
|
||||
div.style.gap = '10px';
|
||||
div.style.transform = `scale(${scale})`;
|
||||
div.style.opacity = opacity;
|
||||
div.style.border = index === 0 ? '1px solid #facc15' : '1px solid transparent';
|
||||
div.style.animation = fan.username === currentUserName ? 'fan-entry 0.5s ease-out' : 'none';
|
||||
|
||||
const vipBadge = index === 0 ? '<span class="vip-badge">VIP</span>' : '';
|
||||
const customColorStyle = fan.custom_color ? `color: ${fan.custom_color} !important;` : '';
|
||||
|
||||
div.innerHTML = `
|
||||
<div style="font-size: 1.5rem;">${medal}</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; font-size: 0.9rem; ${customColorStyle || (index === 0 ? 'color: #facc15' : 'white')}">${fan.username}${vipBadge}</div>
|
||||
<div style="font-size: 0.75rem; opacity: 0.6;">${fan.total_likes} Corazones repartidos</div>
|
||||
</div>
|
||||
`;
|
||||
list.appendChild(div);
|
||||
});
|
||||
|
||||
customizationBox.style.display = isTop3 ? 'flex' : 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ranking error:', error);
|
||||
}
|
||||
function toggleEmojiPicker() {
|
||||
emojiPicker.style.display = emojiPicker.style.display === 'none' ? 'block' : 'none';
|
||||
}
|
||||
|
||||
async function updateCustomColor(color) {
|
||||
const userName = document.getElementById('user-name').value.trim();
|
||||
if (!userName) return;
|
||||
emojiPicker.addEventListener('emoji-click', event => {
|
||||
chatMsg.value += event.detail.unicode;
|
||||
emojiPicker.style.display = 'none';
|
||||
chatMsg.focus();
|
||||
});
|
||||
|
||||
// Close emoji picker when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!emojiPicker.contains(e.target) && !e.target.closest('button[onclick="toggleEmojiPicker()"]')) {
|
||||
emojiPicker.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
async function uploadImage(input) {
|
||||
if (!input.files || !input.files[0]) return;
|
||||
|
||||
const file = input.files[0];
|
||||
const formData = new FormData();
|
||||
formData.append('image', file);
|
||||
|
||||
try {
|
||||
const response = await fetch('api/update_fan_color.php', {
|
||||
const response = await fetch('api/upload.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: userName, color: color })
|
||||
body: formData
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
fetchTopFans();
|
||||
fetchMessages();
|
||||
sendChatMessage(result.url, 'image');
|
||||
} else {
|
||||
alert(result.error || 'Error al subir la imagen');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error updating color:', e);
|
||||
} catch (error) {
|
||||
console.error('Upload error:', error);
|
||||
alert('Error de conexión al subir la imagen');
|
||||
}
|
||||
input.value = ''; // Reset input
|
||||
}
|
||||
|
||||
async function fetchMessages() {
|
||||
@ -1099,14 +1009,6 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
const div = document.createElement('div');
|
||||
const isLike = msg.message.includes('❤️');
|
||||
|
||||
// Determine fan class and VIP status
|
||||
let fanClass = '';
|
||||
const fanIndex = topFans.findIndex(f => f.username === msg.username);
|
||||
if (fanIndex === 0) fanClass = 'fan-1';
|
||||
else if (fanIndex === 1) fanClass = 'fan-2';
|
||||
else if (fanIndex === 2) fanClass = 'fan-3';
|
||||
|
||||
const vipBadge = fanIndex === 0 ? '<span class="vip-badge">VIP</span>' : '';
|
||||
const customColor = msg.custom_color ? `color: ${msg.custom_color} !important;` : '';
|
||||
|
||||
div.style.background = isLike ? 'rgba(255, 68, 68, 0.15)' : 'rgba(255,255,255,0.05)';
|
||||
@ -1114,11 +1016,18 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
div.style.borderRadius = '12px';
|
||||
div.style.borderLeft = `4px solid ${isLike ? '#ff4444' : (msg.username === currentUserName ? 'var(--primary-color)' : 'rgba(255,255,255,0.2)')}`;
|
||||
|
||||
let content = '';
|
||||
if (msg.type === 'image') {
|
||||
content = `<img src="${msg.message}" style="max-width: 100%; border-radius: 8px; margin-top: 5px; cursor: pointer;" onclick="window.open('${msg.message}', '_blank')">`;
|
||||
} else {
|
||||
content = `<div style="font-size: 0.85rem; line-height: 1.4; ${isLike ? 'font-weight: 600;' : ''}">${msg.message}</div>`;
|
||||
}
|
||||
|
||||
div.innerHTML = `
|
||||
<div class="${fanClass}" style="font-size: 0.7rem; font-weight: bold; ${customColor || (isLike ? 'color: #ff4444' : 'var(--primary-color)')}; margin-bottom: 2px;">
|
||||
${fanIndex === 0 ? '👑 ' : ''}${msg.username}${vipBadge}
|
||||
<div style="font-size: 0.7rem; font-weight: bold; ${customColor || (isLike ? 'color: #ff4444' : 'var(--primary-color)')}; margin-bottom: 2px;">
|
||||
${msg.username}
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; line-height: 1.4; ${isLike ? 'font-weight: 600;' : ''}">${msg.message}</div>
|
||||
${content}
|
||||
<div style="font-size: 0.6rem; opacity: 0.4; margin-top: 4px; text-align: right;">${new Date(msg.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</div>
|
||||
`;
|
||||
chatMessages.appendChild(div);
|
||||
@ -1130,12 +1039,12 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
}
|
||||
}
|
||||
|
||||
async function sendChatMessage() {
|
||||
async function sendChatMessage(msgContent = null, type = 'text') {
|
||||
const userNameInput = document.getElementById('user-name');
|
||||
const userPhoneInput = document.getElementById('user-phone');
|
||||
const user = userNameInput.value.trim();
|
||||
const phone = userPhoneInput.value.trim();
|
||||
const message = chatMsg.value.trim();
|
||||
const message = msgContent || chatMsg.value.trim();
|
||||
const phoneRegex = /^\+?[0-9]{7,15}$/;
|
||||
|
||||
if (user.length < 3) {
|
||||
@ -1162,11 +1071,11 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
const response = await fetch('api/chat.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user, message: message })
|
||||
body: JSON.stringify({ username: user, message: message, type: type })
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
chatMsg.value = '';
|
||||
if (!msgContent) chatMsg.value = '';
|
||||
fetchMessages();
|
||||
}
|
||||
} catch (error) {
|
||||
@ -1179,9 +1088,8 @@ $facebook_link = "https://www.facebook.com/profile.php?id=61587890927489";
|
||||
});
|
||||
|
||||
// Initial fetch and poll
|
||||
fetchTopFans().then(() => fetchMessages());
|
||||
fetchMessages();
|
||||
setInterval(fetchMessages, 3000);
|
||||
setInterval(fetchTopFans, 10000);
|
||||
// --- End Chat Functionality ---
|
||||
|
||||
async function likeSong() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user