215 lines
10 KiB
PHP
215 lines
10 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
session_start();
|
|
require_once __DIR__ . '/db/config.php';
|
|
|
|
$pdo = db();
|
|
// Fetch settings
|
|
$stmt = $pdo->query("SELECT setting_key, setting_value FROM site_settings");
|
|
$settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
$head_ads = $settings['head_ads'] ?? '';
|
|
$body_ads = $settings['body_ads'] ?? '';
|
|
?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>TikTok Live AI Assistant</title>
|
|
<?php
|
|
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Real-time TikTok Live AI Comment Reader and Auto-Responder with TTS.';
|
|
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|
?>
|
|
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
<?php if ($projectImageUrl): ?>
|
|
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
<?php endif; ?>
|
|
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<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@400;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
|
|
|
|
<!-- Custom Head Scripts -->
|
|
<?= $head_ads ?>
|
|
</head>
|
|
<body class="bg-dark text-light">
|
|
|
|
<nav class="navbar navbar-expand-lg navbar-dark bg-black border-bottom border-secondary sticky-top">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand fw-bold d-flex align-items-center" href="/">
|
|
<span class="text-tiktok-cyan me-1">TikTok</span>
|
|
<span class="text-tiktok-red me-2">Live</span>
|
|
<span class="badge bg-danger rounded-pill pulse">AI LIVE</span>
|
|
</a>
|
|
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarMain">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
|
|
<div class="collapse navbar-collapse" id="navbarMain">
|
|
<div class="ms-auto d-flex align-items-center flex-column flex-lg-row">
|
|
<div id="connectionStatus" class="me-lg-3 my-2 my-lg-0 small text-secondary">
|
|
<span class="status-dot bg-secondary me-1"></span> Disconnected
|
|
</div>
|
|
|
|
<?php if (isset($_SESSION['user_id'])): ?>
|
|
<?php if (($_SESSION['role'] ?? 'user') === 'admin'): ?>
|
|
<a href="admin.php" class="nav-link text-tiktok-cyan me-lg-3 my-1 my-lg-0">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="bi bi-gear-fill me-1" viewBox="0 0 16 16">
|
|
<path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
|
|
</svg>
|
|
Admin
|
|
</a>
|
|
<?php endif; ?>
|
|
<span class="text-secondary small me-lg-3 my-1 my-lg-0">Hi, <?= htmlspecialchars($_SESSION['username']) ?></span>
|
|
<a href="logout.php" class="btn btn-outline-danger btn-sm my-1 my-lg-0">Logout</a>
|
|
<?php else: ?>
|
|
<a href="login.php" class="nav-link text-light me-lg-3 my-1 my-lg-0">Login</a>
|
|
<a href="register.php" class="btn btn-tiktok-cyan btn-sm my-1 my-lg-0">Register</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<main class="container py-4">
|
|
<div class="row g-4">
|
|
<!-- Left Column: Controls & Input -->
|
|
<div class="col-lg-4">
|
|
<!-- AI Avatar Improved -->
|
|
<div class="ai-avatar-container">
|
|
<div class="ai-avatar">
|
|
<img src="assets/images/ai_avatar.jpg" alt="AI Avatar">
|
|
<div class="ai-avatar-glow"></div>
|
|
<div class="ai-badge">AI ACTIVE</div>
|
|
</div>
|
|
<h4 class="mt-3 fw-bold text-tiktok-cyan">Your AI Assistant</h4>
|
|
<p class="text-secondary small">I am here to interact with your live stream audience!</p>
|
|
</div>
|
|
|
|
<div class="card bg-surface border-secondary h-100 shadow-sm">
|
|
<div class="card-body">
|
|
<h5 class="card-title mb-4 fw-bold">Configuration</h5>
|
|
|
|
<div class="mb-3">
|
|
<label for="tiktokUsername" class="form-label small text-secondary">TikTok Username</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-dark border-secondary text-secondary">@</span>
|
|
<input type="text" id="tiktokUsername" class="form-control bg-dark border-secondary text-light" placeholder="username" value="tiktok_star">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<button id="connectBtn" class="btn btn-tiktok-cyan w-100 fw-bold py-2 shadow-sm">Connect to Live</button>
|
|
<button id="disconnectBtn" class="btn btn-outline-danger w-100 fw-bold py-2 mt-2 shadow-sm d-none">Disconnect</button>
|
|
</div>
|
|
|
|
<hr class="border-secondary my-4">
|
|
|
|
<h6 class="mb-3 fw-bold">TTS Settings</h6>
|
|
<div class="mb-3">
|
|
<label for="voiceSelect" class="form-label small text-secondary">Voice</label>
|
|
<select id="voiceSelect" class="form-select bg-dark border-secondary text-light"></select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="rateRange" class="form-label small text-secondary">Speed: <span id="rateValue">1.0</span></label>
|
|
<input type="range" class="form-range" id="rateRange" min="0.5" max="2" step="0.1" value="1.0">
|
|
</div>
|
|
|
|
<div class="form-check form-switch mb-3">
|
|
<input class="form-check-input" type="checkbox" id="autoReplyToggle" checked>
|
|
<label class="form-check-label" for="autoReplyToggle">AI Auto-Reply</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column: Live Feed -->
|
|
<div class="col-lg-8">
|
|
<div class="card bg-surface border-secondary shadow-sm h-100">
|
|
<div class="card-header bg-transparent border-secondary d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0 fw-bold">Live Comment Feed</h5>
|
|
<span class="badge bg-dark border border-secondary text-secondary" id="commentCount">0 comments</span>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div id="commentFeed" class="comment-feed p-3 overflow-auto" style="height: 500px;">
|
|
<div class="text-center text-secondary py-5" id="emptyFeed">
|
|
<p>Enter a username and connect to start seeing live comments.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer bg-transparent border-secondary">
|
|
<div class="input-group">
|
|
<input type="text" id="manualComment" class="form-control bg-dark border-secondary text-light" placeholder="Simulate a comment...">
|
|
<button id="simulateBtn" class="btn btn-outline-tiktok-cyan">Simulate</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats / History -->
|
|
<div class="row g-4 mt-4">
|
|
<div class="col-12">
|
|
<div class="card bg-surface border-secondary shadow-sm">
|
|
<div class="card-header bg-transparent border-secondary">
|
|
<h5 class="mb-0 fw-bold">Recent AI Interactions</h5>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-dark table-hover mb-0">
|
|
<thead>
|
|
<tr class="border-secondary">
|
|
<th class="border-secondary text-secondary small">Time</th>
|
|
<th class="border-secondary text-secondary small">User</th>
|
|
<th class="border-secondary text-secondary small">Comment</th>
|
|
<th class="border-secondary text-secondary small">AI Reply</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="historyTableBody">
|
|
<?php
|
|
try {
|
|
$stmt = db()->query("SELECT * FROM tiktok_history ORDER BY created_at DESC LIMIT 5");
|
|
$rows = $stmt->fetchAll();
|
|
if (empty($rows)) {
|
|
echo '<tr><td colspan="4" class="text-center text-secondary py-4">No history yet.</td></tr>';
|
|
} else {
|
|
foreach ($rows as $row) {
|
|
echo "<tr class='border-secondary'>";
|
|
echo "<td class='text-secondary small'>" . date('H:i:s', strtotime($row['created_at'])) . "</td>";
|
|
echo "<td><strong>" . htmlspecialchars($row['comment_author']) . "</strong></td>";
|
|
echo "<td class='text-secondary'>" . htmlspecialchars($row['comment_text']) . "</td>";
|
|
echo "<td class='text-tiktok-cyan'>" . htmlspecialchars($row['ai_reply']) . "</td>";
|
|
echo "</tr>";
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
echo '<tr><td colspan="4" class="text-center text-danger py-4">Error loading history.</td></tr>';
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<footer class="text-center py-4 text-secondary small border-top border-secondary mt-5">
|
|
<p>© <?= date('Y') ?> TikTok Live AI Assistant. Built with LAMP + OpenAI.</p>
|
|
<p><a href="admin.php" class="text-secondary text-decoration-none">Admin Settings</a></p>
|
|
</footer>
|
|
|
|
<div id="toastContainer" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/main.js?v=<?= time() ?>"></script>
|
|
|
|
<!-- Custom Body Scripts -->
|
|
<?= $body_ads ?>
|
|
</body>
|
|
</html>
|