Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> | |
| <title>Face Tracker — Reachy Mini</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="style.css"> | |
| </head> | |
| <body> | |
| <!-- Login View — also used for "Checking sign-in…" while authenticate() | |
| resolves on page load; the button text + handler are swapped. --> | |
| <div id="loginView" class="login-view"> | |
| <div class="login-card"> | |
| <div class="login-emoji">🪞</div> | |
| <h2>Face Tracker</h2> | |
| <p id="loginMessage">Checking sign-in…</p> | |
| <button class="btn-hf hidden" id="btnLogin">Sign in with Hugging Face</button> | |
| </div> | |
| </div> | |
| <!-- Main App --> | |
| <div id="mainApp" class="hidden"> | |
| <header class="header"> | |
| <div class="logo"> | |
| <span class="logo-emoji">🪞</span> | |
| <div class="logo-text">Face Tracker <span>· Reachy Mini</span></div> | |
| </div> | |
| <div class="user-section"> | |
| <div class="user-badge"><span id="username">@user</span></div> | |
| <button class="btn-logout" id="btnLogout">Sign out</button> | |
| </div> | |
| </header> | |
| <div class="app-container"> | |
| <!-- Robot picker (shown automatically after auto-connect, hidden once streaming). | |
| List is populated by the SDK's robotsChanged event. --> | |
| <div id="robotSelector" class="panel"> | |
| <div class="panel-header"> | |
| <span id="pickerHeader">Connecting…</span> | |
| </div> | |
| <div class="panel-content"> | |
| <div id="robotList" class="robot-list"> | |
| <div class="hint">Talking to the signaling server…</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Read-only view of the autonomous tracker running on Reachy. --> | |
| <div id="mimicryView" class="hidden"> | |
| <div class="video-pair"> | |
| <div class="video-cell"> | |
| <video id="localVideo" autoplay playsinline muted></video> | |
| <div class="cell-label">Reachy's view</div> | |
| </div> | |
| </div> | |
| <div class="panel"> | |
| <div class="panel-content"> | |
| <div class="master-row"> | |
| <div class="connection-badge"> | |
| <div class="status-indicator connected"></div> | |
| <span id="streamingStatus">Connecting to Reachy's camera…</span> | |
| </div> | |
| <div class="robot-name" id="robotName"></div> | |
| <div id="trackingStatus">Searching for a face…</div> | |
| <button class="btn btn-danger" id="btnStop">Close camera</button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="panel"> | |
| <div class="panel-header">Autonomous mode</div> | |
| <div class="panel-content"> | |
| Reachy searches the room when nobody is visible, locks onto the first face it finds, | |
| and follows that person until they leave. This behavior runs onboard the robot; | |
| this page is only a camera monitor. | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script type="module" src="./main.js"></script> | |
| </body> | |
| </html> | |