feat: add Goldfish Recap YouTube summary PWA
YouTube subtitles via OpenRouter become persistent, shareable recaps with timestamp jump links, PIN-protected creation, and Traefik deploy. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
<meta name="theme-color" content="#0B3D5C">
|
||||
<meta id="metaDescription" name="description" content="Goldfish Recap">
|
||||
<meta id="ogTitle" property="og:title" content="Goldfish Recap">
|
||||
<meta id="ogDescription" property="og:description" content="">
|
||||
<meta id="ogImage" property="og:image" content="">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
<title>Goldfish Recap</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="recapPage">
|
||||
<header class="topBar">
|
||||
<a href="/" class="backLink">← Alle Recaps</a>
|
||||
<button type="button" class="btn btn-ghost btn-sm" id="copyLinkBtn">Link kopieren</button>
|
||||
</header>
|
||||
|
||||
<main id="recapMain" class="recapMain" hidden>
|
||||
<div class="videoHero">
|
||||
<a id="thumbLink" href="#" target="_blank" rel="noopener">
|
||||
<img id="thumbImg" src="" alt="" class="thumb">
|
||||
</a>
|
||||
<div class="videoMeta">
|
||||
<span id="verdictBadge" class="verdictBadge"></span>
|
||||
<h1 id="videoTitle"></h1>
|
||||
<p id="channelName" class="channelName"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="card tldrCard">
|
||||
<h2>TL;DR</h2>
|
||||
<p id="tldrText"></p>
|
||||
<p id="vibeText" class="vibeText"></p>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Sprungmarken</h2>
|
||||
<p class="sectionHint">Klick = direkt zur Stelle auf YouTube. Für dein Goldfisch-Gehirn optimiert.</p>
|
||||
<div id="sectionsList" class="sectionsList"></div>
|
||||
</section>
|
||||
|
||||
<section class="card goldfishCard">
|
||||
<p id="goldfishNote"></p>
|
||||
</section>
|
||||
|
||||
<div class="adminRow" id="adminRow" hidden>
|
||||
<button type="button" class="btn btn-ghost" id="regenerateBtn">Neu generieren</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="loadingState" class="loadingState">
|
||||
<div class="spinner"></div>
|
||||
<p>Goldfisch lädt dein Recap…</p>
|
||||
</div>
|
||||
|
||||
<div id="errorState" class="errorState" hidden>
|
||||
<p id="errorText"></p>
|
||||
<a href="/" class="btn btn-primary">Zurück</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog id="pinModal" class="modal">
|
||||
<form method="dialog" id="pinForm" class="modalBody">
|
||||
<h2>PIN bitte</h2>
|
||||
<input type="password" id="pinInput" class="textInput pinInput" inputmode="numeric" autocomplete="off" placeholder="PIN" required>
|
||||
<p id="pinError" class="errorText" hidden></p>
|
||||
<div class="modalActions">
|
||||
<button type="button" class="btn btn-ghost" id="pinCancel">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-primary">Anmelden</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script type="module" src="/recap.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user