118 lines
6.5 KiB
HTML
118 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'none'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'none';">
|
|
<title>Alta Video Camera Proxy</title>
|
|
<link rel="stylesheet" href="styles.css">
|
|
</head>
|
|
<body>
|
|
<div class="app-container">
|
|
<div class="main-layout">
|
|
<aside class="devices-sidebar">
|
|
<div class="sidebar-header"><h2>Available Devices</h2></div>
|
|
<div id="deviceStatus" class="status-message" role="status" aria-live="polite"></div>
|
|
<div class="device-search-container">
|
|
<label class="visually-hidden" for="deviceSearch">Search cameras</label>
|
|
<input type="search" id="deviceSearch" placeholder="Search cameras..." class="device-search-input" autocomplete="off" aria-controls="deviceList">
|
|
<p id="deviceResults" class="tree-results" role="status" aria-live="polite">Connect to load cameras</p>
|
|
</div>
|
|
<div class="device-list-container">
|
|
<div id="deviceList" class="device-list virtual-tree" role="tree" tabindex="0" aria-label="Alta camera hierarchy" aria-activedescendant="" aria-describedby="deviceResults">
|
|
<div id="treeSpacer" class="virtual-tree-spacer">
|
|
<div id="treeWindow" class="virtual-tree-window">
|
|
<p class="placeholder-text">Connect through the paired Chrome extension to load devices</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<main class="main-content">
|
|
<div class="content-header">
|
|
<h1>Alta Video Camera Proxy</h1>
|
|
<button type="button" id="checkUpdateBtn" class="btn-update" title="Securely check GitPeji for a newer release">
|
|
<span class="update-icon">↻</span>
|
|
<span class="update-text">Check for Updates</span>
|
|
</button>
|
|
</div>
|
|
|
|
<section class="content-section">
|
|
<h2>API Connection</h2>
|
|
<div class="connection-status">
|
|
<div class="status-row">
|
|
<label>Status:</label>
|
|
<div class="status-indicator" id="statusIndicator">
|
|
<span class="status-dot offline"></span>
|
|
<span class="status-text">Disconnected</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="connection-controls">
|
|
<button type="button" id="disconnectBtn" class="btn-outline" disabled>Disconnect</button>
|
|
</div>
|
|
<div id="connectionStatus" class="status-message"></div>
|
|
</section>
|
|
|
|
<section class="content-section pairing-section">
|
|
<h2>Bridge Pairing</h2>
|
|
<p class="section-help">Only the committed APT Chrome extension can send a session. Pair it with a one-time secret.</p>
|
|
<div class="status-row">
|
|
<label>Pairing:</label>
|
|
<span id="pairingState" class="unpaired">Checking...</span>
|
|
</div>
|
|
<div id="pairingSecretRow" class="pairing-secret-row" style="display: none;">
|
|
<label for="pairingSecret">One-time secret:</label>
|
|
<input type="text" id="pairingSecret" readonly autocomplete="off" spellcheck="false">
|
|
<small>Paste this into the extension pairing settings now. APT will not show it again.</small>
|
|
</div>
|
|
<div class="proxy-buttons">
|
|
<button type="button" id="rotatePairingBtn" class="btn-primary">Generate / Rotate</button>
|
|
<button type="button" id="revokePairingBtn" class="btn-outline">Revoke</button>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="content-section">
|
|
<h2>Camera Proxy</h2>
|
|
<div class="proxy-controls">
|
|
<div class="input-row">
|
|
<label for="selectedDeviceId">Device UUID:</label>
|
|
<input type="text" id="selectedDeviceId" placeholder="Select a device from the list" readonly>
|
|
</div>
|
|
<div class="input-row">
|
|
<label for="altaUsername">Alta username / email:</label>
|
|
<input type="text" id="altaUsername" maxlength="254" placeholder="name@example.com" autocomplete="username" spellcheck="false">
|
|
</div>
|
|
<p class="section-help">The proxy helper opens a Windows console and prompts for your password and 2FA. APT never sends those secrets on its command line.</p>
|
|
<div class="proxy-buttons">
|
|
<button type="button" id="startProxyBtn" class="btn-primary" disabled>Start Proxy</button>
|
|
<button type="button" id="stopProxyBtn" class="btn-outline" disabled>Stop Proxy</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="updateNotice" class="update-modal-overlay" style="display: none;">
|
|
<div class="update-modal-card">
|
|
<div class="update-modal-header"><h3>Update Available</h3></div>
|
|
<div class="update-modal-body">
|
|
<p id="updateMessage" class="update-modal-message"></p>
|
|
</div>
|
|
<div class="update-modal-footer">
|
|
<button type="button" id="openReleasesBtn" class="btn-primary">Open GitPeji Releases</button>
|
|
<button type="button" id="dismissUpdateBtn" class="btn-outline">Later</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="renderer-controller.js"></script>
|
|
<script src="device-tree.js"></script>
|
|
<script src="sidebar-controller.js"></script>
|
|
<script src="sidebar-view.js"></script>
|
|
<script src="renderer.js"></script>
|
|
</body>
|
|
</html>
|