Files

107 lines
4.3 KiB
HTML
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.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#1f1147">
<title>BabyMobile Audio Manager</title>
<link rel="manifest" href="./manifest.webmanifest">
<link rel="icon" href="./icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="./icon.svg">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<header>
<div class="brand">
<img src="./icon.svg" alt="BabyMobile" width="28" height="28">
</div>
<div class="conn">
<span id="status-dot" class="dot"></span>
<span id="status-text">Not connected</span>
<button id="btn-connect" class="primary">Scan &amp; connect</button>
</div>
</header>
<div id="unsupported" class="banner" hidden>
⚠ This browser has no Web Bluetooth. Use <b>Chrome</b> or <b>Edge</b> on
Android / desktop, or the free <b>Bluefy</b> browser on iPhone/iPad.
</div>
<main>
<section class="card">
<h2>1 · Add audio</h2>
<div id="drop" class="drop">
<p>Tap or drop an audio file</p>
<small>WAV, MP3, M4A, OGG… — converted in your browser</small>
<input id="file" type="file" accept="audio/*" hidden>
</div>
<div class="opts">
<label>Format <select id="bits"></select></label>
<label>Rate <select id="rate"></select></label>
</div>
<div id="trim" class="trim" hidden>
<div class="wave-wrap">
<canvas id="wave" class="wave"></canvas>
<div id="trim-region" class="trim-region"></div>
<div id="handle-start" class="handle" role="slider" tabindex="0" aria-label="Clip start">
<span class="chev top"></span><span class="line"></span><span class="chev bot"></span>
</div>
<div id="handle-end" class="handle" role="slider" tabindex="0" aria-label="Clip end">
<span class="chev top"></span><span class="line"></span><span class="chev bot"></span>
</div>
</div>
<div class="trim-readout">
<span class="time-fields">
<input id="trim-start-s" class="time-in" type="number" min="0" step="0.01" inputmode="decimal" aria-label="Clip start seconds">
<span class="dash"></span>
<input id="trim-end-s" class="time-in" type="number" min="0" step="0.01" inputmode="decimal" aria-label="Clip end seconds">
<span class="unit">s</span>
</span>
<span id="trim-clip" class="clip">0.0s clip</span>
<button id="btn-preview" class="mini" disabled>▶ Preview</button>
</div>
<label class="level">This file's level
<input id="track-level" type="range" min="0" max="150" value="100">
<span id="track-level-val" class="unit">100%</span>
</label>
</div>
<p id="convert-info" class="info">No file selected.</p>
<div class="row">
<label>Upload to <select id="upload-slot" data-needs-conn disabled></select></label>
<button id="btn-upload" class="primary" data-needs-conn disabled>Upload</button>
</div>
<div class="progress"><div id="upload-bar" class="bar"></div></div>
</section>
<section class="card">
<div class="card-head">
<h2>Playback volume</h2>
<span id="volume-val" class="muted-val"></span>
</div>
<input id="volume" type="range" min="0" max="150" value="100" class="vol-slider" data-needs-conn disabled>
<p class="hint">Master volume on the device, saved across reboots. A file's own level is set above, before upload.</p>
</section>
<section class="card">
<div class="card-head">
<h2>Tracks on device</h2>
<button id="btn-refresh" class="mini" data-needs-conn disabled>↻ Refresh</button>
</div>
<p class="hint">Live from the device. Titles are remembered locally — the device stores audio, not names.</p>
<ul id="slots" class="slots"></ul>
</section>
<section class="card">
<h2>Log</h2>
<pre id="log" class="log"></pre>
</section>
</main>
<footer>
Client-side only · no data leaves your device · <a href="./README.md">about &amp; iOS setup</a>
</footer>
<script type="module" src="./app.js"></script>
</body>
</html>