Files
ytplayer/frontend/index.html

170 lines
6.8 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.0" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src 'self' https: data: asset: http://asset.localhost; media-src 'self' https: blob: asset: http://asset.localhost; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com data:; script-src 'self'; connect-src 'self' https: ipc: http://ipc.localhost;"
/>
<title>YT Player</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=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700;12..96,800&family=Hanken+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="app">
<!-- Sidebar -->
<aside class="sidebar">
<div class="brand">
<span class="brand-mark"></span> YT Player
</div>
<nav class="nav">
<button class="nav-item active" data-view="search">🔍 Search</button>
<button class="nav-item" data-view="history">🕘 History</button>
<button class="nav-item" data-view="settings">⚙ Settings</button>
</nav>
<div class="pl-header">
<span>Playlists</span>
<button id="newPlaylistBtn" class="icon-btn" title="New playlist"></button>
</div>
<div id="playlistList" class="playlist-list"></div>
<div class="sidebar-footer">
<label class="switch">
<input type="checkbox" id="audioOnlyToggle" />
<span>Audio-only mode</span>
</label>
</div>
</aside>
<!-- Main -->
<main class="main">
<header class="topbar">
<form id="searchForm" class="search-form">
<input
id="searchInput"
type="text"
placeholder="Search YouTube… (no login, no ads)"
autocomplete="off"
/>
<button type="submit" class="search-btn">Search</button>
</form>
</header>
<div class="body">
<!-- Player pane -->
<section id="playerPane" class="player-pane empty">
<div class="player-stage">
<video id="video" playsinline></video>
<audio id="audio"></audio>
<div id="artFallback" class="art-fallback hidden">
<img id="artImg" alt="" />
</div>
<div id="playerPlaceholder" class="player-placeholder">
<div class="hero">
<div class="ph-logo"></div>
<h1 class="hero-title">YT Player</h1>
<p class="hero-tagline">Ad-free YouTube — no login, no tracking. Search, play, and keep playlists right on your device.</p>
<div class="hero-pills">
<span class="hero-pill">No ads</span>
<span class="hero-pill">No sign-in</span>
<span class="hero-pill">Offline playlists</span>
</div>
<div class="hero-suggests">
<span class="hero-suggests-label">Try</span>
<button class="chip" data-q="lofi hip hop radio">lofi beats</button>
<button class="chip" data-q="live news">live news</button>
<button class="chip" data-q="relaxing music">relaxing music</button>
<button class="chip" data-q="podcast highlights">podcasts</button>
</div>
</div>
</div>
<div id="bufferSpinner" class="spinner hidden"></div>
</div>
<div id="controls" class="controls hidden">
<div class="seek-row">
<span id="curTime" class="time">0:00</span>
<input id="seek" class="seek" type="range" min="0" max="1000" value="0" />
<span id="durTime" class="time">0:00</span>
</div>
<div class="btn-row">
<button id="prevBtn" class="ctrl" title="Previous"></button>
<button id="playBtn" class="ctrl play" title="Play/Pause"></button>
<button id="nextBtn" class="ctrl" title="Next"></button>
<div class="vol">
<button id="muteBtn" class="ctrl" title="Mute">🔊</button>
<input id="volume" type="range" min="0" max="1" step="0.01" value="1" />
</div>
<div class="spacer"></div>
<label class="sel">
Speed
<select id="speedSelect">
<option value="0.5">0.5×</option>
<option value="0.75">0.75×</option>
<option value="1" selected>1×</option>
<option value="1.25">1.25×</option>
<option value="1.5">1.5×</option>
<option value="2">2×</option>
</select>
</label>
<label class="sel">
Quality
<select id="qualitySelect"></select>
</label>
<button id="fsBtn" class="ctrl" title="Fullscreen"></button>
</div>
</div>
<div id="nowPlayingMeta" class="now-meta hidden">
<div class="np-text">
<div class="np-title" id="npTitle"></div>
<div class="np-channel" id="npChannel"></div>
</div>
<div class="np-actions">
<button id="saveBtn" class="np-btn" title="Save this video for offline playback">⬇ Save</button>
<button id="addPlaylistBtn" class="np-btn" title="Add to a playlist"> Playlist</button>
</div>
</div>
</section>
<!-- List pane -->
<section class="list-pane">
<div class="list-header">
<h2 id="listTitle">Search</h2>
<div id="listActions" class="list-actions"></div>
</div>
<div id="status" class="status hidden"></div>
<div id="cards" class="cards"></div>
</section>
</div>
</main>
</div>
<!-- Generic modal -->
<div id="modal" class="modal-backdrop hidden">
<div class="modal">
<h3 id="modalTitle"></h3>
<div id="modalBody"></div>
<div class="modal-actions" id="modalActions"></div>
</div>
</div>
<div id="toast" class="toast hidden"></div>
<script src="app.js"></script>
</body>
</html>