Files
linearvoid/frontend/index.html
T

113 lines
4.9 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Linear Void - 24/7 Synchronized Channel</title>
<link rel="stylesheet" href="/src/style.css" />
</head>
<body class="lv-body">
<main class="viewer-shell" aria-label="Live player and chat">
<header class="viewer-header">
<div class="viewer-brand-group">
<div class="brand-badge" aria-hidden="true">LV</div>
<div>
<h1 class="viewer-title">Linear Void</h1>
<p class="viewer-subtitle">24/7 Synchronized Channel • Live</p>
</div>
</div>
<button id="chat-toggle" type="button" class="btn btn-secondary chat-toggle-btn" onclick="toggleChatPanel()" aria-controls="chat-panel" aria-expanded="true">
Hide Chat
</button>
</header>
<section class="viewer-content" aria-label="Live stream and chat layout">
<section class="player-stage" aria-label="Video stage">
<video id="player" class="player" controls autoplay muted playsinline></video>
<div id="now-playing" class="now-playing-overlay" aria-live="polite">
<span id="np-title">Loading...</span>
<span id="np-next" class="np-next"></span>
</div>
</section>
<aside id="chat-panel" class="chat-sidebar" aria-label="Chat panel">
<header class="chat-header">
<div class="chat-room-title">
<span class="chat-live-marker" aria-hidden="true">●</span>
<span id="room-name">Main Channel</span>
</div>
<div class="chat-header-actions">
<span id="chat-user-label" class="chat-user-label" hidden></span>
<button id="auth-toggle-btn" type="button" class="btn btn-secondary">Sign in</button>
<button id="auth-logout-btn" type="button" class="btn btn-secondary" hidden>Sign out</button> <button id="users-toggle-btn" type="button" class="btn btn-secondary" aria-controls="presence-panel" aria-expanded="true">Users</button> <button type="button" class="btn btn-secondary" onclick="togglePrivateDM()">New DM</button>
</div>
</header>
<div id="auth-panel" class="auth-panel" hidden>
<input id="auth-username" type="text" class="input" placeholder="Username" autocomplete="username" />
<input id="auth-password" type="password" class="input" placeholder="Password" autocomplete="current-password" />
<div class="button-row">
<button id="auth-login-btn" type="button" class="btn btn-primary">Log in</button>
<button id="auth-register-btn" type="button" class="btn btn-secondary">Register</button>
</div>
<p id="auth-status" class="status-line" aria-live="polite"></p>
</div>
<div id="dm-search-row" class="dm-search-row" hidden>
<input id="dm-search-input" type="text" class="input" placeholder="Search this conversation..." />
<button id="dm-search-btn" type="button" class="btn btn-secondary">Search</button>
</div>
<div id="presence-list" class="presence-list"></div>
</section>
<div class="chat-input-area">
<div class="chat-input-row">
<label for="message-input" class="sr-only">Message input</label>
<input id="message-input" type="text" placeholder="Type a message..." class="input" onkeydown="if (event.key === 'Enter') sendMessage();" />
<button type="button" class="btn btn-primary" onclick="sendMessage()">Send</button>
</div>
<p class="chat-note">Synced with video • Moderation active</p>
</div>
</aside>
</section>
</main>
<div id="reconnecting-overlay" class="reconnecting-overlay hidden" role="alert" aria-live="assertive">
<div class="reconnecting-spinner"></div>
<span id="reconnecting-text">Reconnecting...</span>
</div>
<script>
(function () {
// Load Matomo analytics when configured via the admin runtime config.
fetch("/api/matomo")
.then(function (r) {
return r.ok ? r.json() : null;
})
.then(function (cfg) {
if (!cfg || !cfg.matomoUrl || !cfg.matomoSiteId) return;
var _paq = (window._paq = window._paq || []);
_paq.push(["trackPageView"]);
_paq.push(["enableLinkTracking"]);
var base = String(cfg.matomoUrl).replace(/\/+$/, "");
_paq.push(["setTrackerUrl", base + "/matomo.php"]);
_paq.push(["setSiteId", String(cfg.matomoSiteId)]);
var d = document;
var g = d.createElement("script");
var s = d.getElementsByTagName("script")[0];
g.async = true;
g.src = base + "/matomo.js";
s.parentNode.insertBefore(g, s);
})
.catch(function () {
/* analytics is optional */
});
})();
</script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>