Files
tv-adb-remote/public/index.html
T
Claude 6db1db70a0 Add local ADB web remote for Android TV
Node/Express server shells out to adb (connect/pair/keyevent/text/app
launch) and serves a mobile-first installable PWA remote: power, mute,
input switch, volume/channel rockers, D-pad, media transport, text
entry, and one-tap streaming app launch. Supports multiple saved TVs
and the Android 11+ wireless-debugging pairing flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RSVyYcrjrbmrMKT85G4fyn
2026-09-26 12:40:01 +00:00

102 lines
4.5 KiB
HTML
Raw 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.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no" />
<title>TV Remote</title>
<meta name="theme-color" content="#0b0d12" />
<link rel="manifest" href="/manifest.json" />
<link rel="icon" href="/icons/icon-192.png" />
<link rel="apple-touch-icon" href="/icons/icon-192.png" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<header class="topbar">
<div class="device-picker">
<select id="deviceSelect" aria-label="Select TV"></select>
<span id="statusDot" class="status-dot" title="Connection status"></span>
</div>
<button id="settingsBtn" class="icon-btn" aria-label="Settings">⚙</button>
</header>
<main id="remote" class="remote">
<div class="row row-top">
<button class="btn btn-round" data-key="POWER" aria-label="Power">⏻</button>
<button class="btn btn-round" data-key="TV_INPUT" aria-label="Input">⇄</button>
<button class="btn btn-round" data-action="mute" aria-label="Mute">🔇</button>
</div>
<div class="dpad">
<button class="btn dpad-up" data-key="DPAD_UP" aria-label="Up">▲</button>
<button class="btn dpad-left" data-key="DPAD_LEFT" aria-label="Left">◀</button>
<button class="btn dpad-center" data-key="DPAD_CENTER" aria-label="OK">OK</button>
<button class="btn dpad-right" data-key="DPAD_RIGHT" aria-label="Right">▶</button>
<button class="btn dpad-down" data-key="DPAD_DOWN" aria-label="Down">▼</button>
</div>
<div class="row row-nav">
<button class="btn" data-key="BACK" aria-label="Back">⤺ Back</button>
<button class="btn" data-key="HOME" aria-label="Home">⌂ Home</button>
<button class="btn" data-key="MENU" aria-label="Menu">☰ Menu</button>
</div>
<div class="row row-vol-ch">
<div class="rocker" data-rocker="volume">
<span class="rocker-label">VOL</span>
<button class="btn rocker-btn" data-key="VOLUME_UP" aria-label="Volume up">+</button>
<button class="btn rocker-btn" data-key="VOLUME_DOWN" aria-label="Volume down">−</button>
</div>
<div class="rocker" data-rocker="channel">
<span class="rocker-label">CH</span>
<button class="btn rocker-btn" data-key="CHANNEL_UP" aria-label="Channel up">+</button>
<button class="btn rocker-btn" data-key="CHANNEL_DOWN" aria-label="Channel down">−</button>
</div>
</div>
<div class="row row-media">
<button class="btn" data-key="MEDIA_REWIND" aria-label="Rewind">⏪</button>
<button class="btn" data-key="MEDIA_PLAY_PAUSE" aria-label="Play/Pause">⏯</button>
<button class="btn" data-key="MEDIA_FAST_FORWARD" aria-label="Fast forward">⏩</button>
</div>
<form class="row row-search" id="searchForm">
<input id="searchInput" type="text" inputmode="text" placeholder="Type to search…" autocomplete="off" />
<button type="submit" class="btn">Send</button>
</form>
<div class="apps" id="appsRow"></div>
</main>
<dialog id="settingsDialog">
<h2>TVs</h2>
<ul id="deviceList" class="device-list"></ul>
<form id="addDeviceForm" class="add-device-form">
<input id="newDeviceName" type="text" placeholder="Name (e.g. Living Room)" autocomplete="off" />
<input id="newDeviceHost" type="text" placeholder="IP address (e.g. 192.168.1.50)" autocomplete="off" required />
<button type="submit" class="btn">Add TV</button>
</form>
<details class="pair-details">
<summary>Pair a new Android 11+ TV</summary>
<form id="pairForm" class="pair-form">
<p>On the TV: Settings → System → Developer options → Wireless debugging → Pair device with pairing code.</p>
<input id="pairHost" type="text" placeholder="Pairing IP:port (e.g. 192.168.1.50:41231)" autocomplete="off" required />
<input id="pairCode" type="text" inputmode="numeric" placeholder="6-digit code" autocomplete="off" required />
<button type="submit" class="btn">Pair</button>
</form>
</details>
<p id="settingsMessage" class="settings-message" role="status"></p>
<button id="closeSettings" class="btn btn-close">Close</button>
</dialog>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="/app.js"></script>
</body>
</html>