- Voice enhancements, user management, payment method
This commit is contained in:
+4
-224
@@ -1,225 +1,5 @@
|
||||
<?php
|
||||
// archive-viewer.php — Browse archived chat logs
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
|
||||
$archiveDir = ROOT_DIR . '/' . getConfigVal('archive.archive_dir', 'archive');
|
||||
$days = [];
|
||||
if (is_dir($archiveDir)) {
|
||||
foreach (glob($archiveDir . '/*/*/*.sqlite') as $f) {
|
||||
if (preg_match('/(\d{4})\/(\d{2})\/(\d{2})\.sqlite$/', $f, $m)) {
|
||||
$days[] = "{$m[1]}-{$m[2]}-{$m[3]}";
|
||||
}
|
||||
}
|
||||
rsort($days);
|
||||
}
|
||||
|
||||
$selectedDay = $_GET['day'] ?? null;
|
||||
$archiveMessages = [];
|
||||
$archiveMeta = [];
|
||||
if ($selectedDay && preg_match('/^\d{4}-\d{2}-\d{2}$/', $selectedDay)) {
|
||||
[$y, $mo, $d] = explode('-', $selectedDay);
|
||||
$dbPath = ROOT_DIR . '/' . str_replace(
|
||||
['{year}', '{month}', '{day}'], [$y, $mo, $d],
|
||||
getConfigVal('database.archive_path')
|
||||
);
|
||||
if (file_exists($dbPath)) {
|
||||
$adb = getArchiveDB($y, $mo, $d);
|
||||
$archiveMessages = $adb->query("SELECT * FROM messages ORDER BY created_at ASC")->fetchAll(PDO::FETCH_ASSOC);
|
||||
$metaRows = $adb->query("SELECT key, value FROM archive_meta")->fetchAll(PDO::FETCH_ASSOC);
|
||||
foreach ($metaRows as $mr) $archiveMeta[$mr['key']] = $mr['value'];
|
||||
}
|
||||
}
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CYBERCHAT // ARCHIVE</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;600&family=Orbitron:wght@700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/cyberchat.css">
|
||||
<style>
|
||||
html, body {
|
||||
min-height: 100vh;
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
background: var(--bg0);
|
||||
padding: 20px 16px 40px;
|
||||
font-family: var(--ui);
|
||||
}
|
||||
|
||||
.arc-wrap { max-width: 920px; margin: 0 auto; }
|
||||
|
||||
.arc-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--bd);
|
||||
}
|
||||
|
||||
.arc-back {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
color: var(--b);
|
||||
text-decoration: none;
|
||||
letter-spacing: 1px;
|
||||
transition: color 0.14s;
|
||||
}
|
||||
.arc-back:hover { color: var(--g); }
|
||||
|
||||
.arc-title {
|
||||
font-family: var(--disp);
|
||||
font-size: 11px;
|
||||
letter-spacing: 3px;
|
||||
color: var(--b);
|
||||
}
|
||||
|
||||
.arc-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 1fr;
|
||||
gap: 16px;
|
||||
height: calc(100vh - 130px);
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.arc-sidebar, .arc-content {
|
||||
background: var(--bg1);
|
||||
border: 1px solid var(--bd);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.arc-sidebar-head, .arc-content-head {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--bd);
|
||||
font-family: var(--mono);
|
||||
font-size: 9px;
|
||||
letter-spacing: 2px;
|
||||
color: var(--t1);
|
||||
text-transform: uppercase;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.arc-days-list { overflow-y: auto; flex: 1; }
|
||||
|
||||
.arc-day-item {
|
||||
padding: 9px 14px;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
color: var(--t1);
|
||||
cursor: pointer;
|
||||
border-left: 2px solid transparent;
|
||||
transition: all 0.12s;
|
||||
}
|
||||
.arc-day-item:hover { color: var(--g); border-left-color: var(--g); background: rgba(0,255,159,0.04); }
|
||||
.arc-day-item.active { color: var(--b); border-left-color: var(--b); background: rgba(0,184,255,0.06); }
|
||||
|
||||
.arc-messages-list { overflow-y: auto; flex: 1; padding: 4px 0; }
|
||||
|
||||
.arc-msg {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
padding: 3px 12px;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
line-height: 1.65;
|
||||
}
|
||||
.arc-msg:hover { background: rgba(255,255,255,0.02); }
|
||||
.arc-msg-time { color: var(--t2); font-size: 9px; min-width: 44px; flex-shrink: 0; margin-right: 7px; }
|
||||
.arc-msg-user { font-weight: 600; font-size: 11px; flex-shrink: 0; min-width: 0; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.arc-msg-sep { color: var(--t2); margin: 0 7px; flex-shrink: 0; }
|
||||
.arc-msg-text { color: var(--t0); flex: 1; word-break: break-word; min-width: 0; }
|
||||
.arc-msg-text audio { width: min(300px, 100%); height: 30px; vertical-align: middle; }
|
||||
|
||||
.arc-empty {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--mono);
|
||||
font-size: 10px;
|
||||
color: var(--t2);
|
||||
letter-spacing: 1.5px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.arc-meta {
|
||||
font-family: var(--mono);
|
||||
font-size: 9px;
|
||||
color: var(--o);
|
||||
padding: 6px 12px;
|
||||
border-bottom: 1px solid var(--bd);
|
||||
letter-spacing: 0.5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.arc-grid { grid-template-columns: 1fr; grid-template-rows: auto 1fr; height: auto; }
|
||||
.arc-sidebar { height: 160px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="arc-wrap">
|
||||
<div class="arc-topbar">
|
||||
<a href="index.html" class="arc-back">◂ BACK TO CHAT</a>
|
||||
<span class="arc-title">// ARCHIVE VIEWER</span>
|
||||
</div>
|
||||
|
||||
<div class="arc-grid">
|
||||
<div class="arc-sidebar">
|
||||
<div class="arc-sidebar-head">// DAYS</div>
|
||||
<div class="arc-days-list">
|
||||
<?php if (empty($days)): ?>
|
||||
<div class="arc-empty">NO ARCHIVES YET</div>
|
||||
<?php else: foreach ($days as $day): ?>
|
||||
<div class="arc-day-item <?= $day === $selectedDay ? 'active' : '' ?>"
|
||||
onclick="location.href='?day=<?= htmlspecialchars($day) ?>'">
|
||||
<?= htmlspecialchars($day) ?>
|
||||
</div>
|
||||
<?php endforeach; endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arc-content">
|
||||
<div class="arc-content-head">// MESSAGES</div>
|
||||
<?php if (!$selectedDay): ?>
|
||||
<div class="arc-empty">SELECT A DAY FROM THE LIST</div>
|
||||
<?php elseif (empty($archiveMessages)): ?>
|
||||
<div class="arc-empty">NO MESSAGES FOR <?= htmlspecialchars($selectedDay) ?></div>
|
||||
<?php else: ?>
|
||||
<div class="arc-meta">
|
||||
// <?= htmlspecialchars($selectedDay) ?>
|
||||
| <?= count($archiveMessages) ?> MESSAGES
|
||||
<?php if (!empty($archiveMeta['archived_at'])): ?>
|
||||
| ARCHIVED <?= date('Y-m-d H:i', (int)$archiveMeta['archived_at']) ?> UTC
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="arc-messages-list">
|
||||
<?php foreach ($archiveMessages as $msg): ?>
|
||||
<div class="arc-msg">
|
||||
<span class="arc-msg-time"><?= date('H:i', (int)$msg['created_at']) ?></span>
|
||||
<span class="arc-msg-user" style="color:<?= htmlspecialchars($msg['color']) ?>"><?= htmlspecialchars($msg['username']) ?></span>
|
||||
<span class="arc-msg-sep">›</span>
|
||||
<span class="arc-msg-text">
|
||||
<?php if (($msg['message_type'] ?? 'text') === 'voice' && !empty($msg['voice_file'])): ?>
|
||||
<audio controls preload="metadata"
|
||||
src="<?= htmlspecialchars(trim((string)getConfigVal('voice.upload_dir', 'uploads/voice'), '/') . '/' . rawurlencode($msg['voice_file'])) ?>"></audio>
|
||||
<?php else: ?>
|
||||
<?= htmlspecialchars($msg['message']) ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
// Historical logs are private. The authenticated application renders only the
|
||||
// current user's entitled archive through api/archive.php.
|
||||
header('Location: index.html?view=archive', true, 302);
|
||||
exit;
|
||||
|
||||
Reference in New Issue
Block a user