Files
Thomas a184c31cca Software
v0.0..1
2025-10-05 14:58:05 +02:00

141 lines
4.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/guard.php';
require_login();
require_once __DIR__ . '/api.php';
require_once __DIR__ . '/db.php';
$env = env_load(dirname(__DIR__) . '/.env');
$login = strtolower($env['TWITCH_CHANNEL'] ?? '');
$uid = $login ? get_user_id($login) : null;
$uptime = 'Offline';
$started_at = null;
// Cachet Helix-kald (20s) for hurtigere side-loads
if ($uid) {
$s = helix_get_cached('/streams', ['user_id' => $uid], 20);
if (($s['http'] ?? 0) === 200 && !empty($s['data']['data'][0])) {
$started_at = $s['data']['data'][0]['started_at'];
$t1 = new DateTime($started_at);
$t2 = new DateTime('now', new DateTimeZone('UTC'));
$diff = $t2->getTimestamp() - $t1->getTimestamp();
$uptime = sprintf('%02d:%02d', floor($diff / 3600), floor(($diff % 3600) / 60));
}
}
$db = db(); // bruger web/db.php (WAL + busy_timeout)
$bits_total = 0;
$cheerers = [];
$subs = [];
// Summér bits og list subs KUN hvis streamen kører
if ($started_at) {
$st = $db->prepare(
'SELECT user_name, SUM(value) AS bits
FROM events
WHERE type = "cheer" AND ts >= ?
GROUP BY user_name
ORDER BY bits DESC'
);
$st->execute([$started_at]);
$cheerers = $st->fetchAll(PDO::FETCH_ASSOC);
foreach ($cheerers as $c) {
$bits_total += (int)($c['bits'] ?? 0);
}
$st = $db->prepare(
'SELECT user_name
FROM events
WHERE (type = "sub" OR type = "subgift") AND ts >= ?
ORDER BY id DESC'
);
$st->execute([$started_at]);
$subs = $st->fetchAll(PDO::FETCH_ASSOC);
}
?>
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="utf-8">
<title>Dashboard</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrap">
<div class="card">
<div class="right"><a class="btn" href="logout.php">Log ud</a></div>
<h1>✨ Twitch PHP Bot Dashboard</h1>
<p>Uptime: <span class="badge"><?php echo htmlspecialchars($uptime); ?></span></p>
<p>
<a class="btn" href="timers.php">⏱️ Timers</a>
<a class="btn" href="poll.php">📊 Poll</a>
<a class="btn" href="giveaway.php">🎁 Giveaway</a>
<a class="btn" href="commands.php">⚙️ Kommandoer</a>
<a class="btn" href="permissions.php">🔐 Rettigheder</a>
<a class="btn" href="points.php" target="_blank">🏆 Loyalty Points</a>
<a class="btn" href="bets.php">💸 Bets</a>
<a class="btn" href="raffle.php">🎟️ Raffle</a>
<a class="btn" href="slots.php">🎰 Slots</a>
<a class="btn" href="eventsub_setup.php">⚡ EventSub</a>
<a class="btn" href="control.php?action=start">Start</a>
<a class="btn" href="control.php?action=stop">Stop</a>
<a class="btn" href="control.php?action=restart">Restart</a>
<a class="btn" href="send.php">Send test</a>
<a class="btn" href="validate.php" target="_blank">Validate token</a>
<a class="btn" href="log.php" target="_blank">Åbn fuld log</a>
<a class="btn" href="settings.php">⚙️ Indstillinger</a>
</p>
</div>
<div class="grid">
<div class="card">
<h3>Total bits (denne stream)</h3>
<p class="badge"><?php echo (int)$bits_total; ?></p>
<h4>Cheerers</h4>
<ul>
<?php foreach ($cheerers as $c): ?>
<li><?php echo htmlspecialchars($c['user_name']); ?> — <?php echo (int)$c['bits']; ?> bits</li>
<?php endforeach; ?>
</ul>
</div>
<div class="card">
<h3>Subs (denne stream)</h3>
<ul>
<?php foreach ($subs as $s): ?>
<li><?php echo htmlspecialchars($s['user_name']); ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="card">
<h3>Live log</h3>
<pre id="logpre">Indlæser...</pre>
<p class="small">SSE først; fallback til WebSocket (kræver <code>node ws_server.js</code>).</p>
</div>
</div>
<script>
(function(){
const pre = document.getElementById('logpre');
function setLog(t){ pre.textContent = t; }
if (!!window.EventSource) {
try {
const sse = new EventSource('events.php');
let used = false;
sse.addEventListener('log', (e) => {
used = true;
setLog(e.data.replaceAll('\\n', '\n'));
});
setTimeout(() => {
if (!used) { sse.close(); tryWS(); }
}, 2000);
return;
} catch (e) {}
}
tryWS();
funct