Files
mediamark/ui/static/index.html
T
unkin-agent c129cb99fc
ci/woodpecker/pr/test Pipeline failed
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
Add the initial mediamark app
Single Go binary serving the API and an embedded keyboard-first UI for
promoting fafflix titles into the cheeztv kids tree via hardlinks.

- internal/library: hardlink sync, idempotent re-runs, drift reporting,
  strict single-path-element name validation as the traversal guard
- internal/arr: minimal sonarr/radarr v3 client with a 60s list cache and
  a key-brokered poster proxy
- internal/auth: server-side Authentik group enforcement on every route
- internal/server: library JSON API, art proxy, health probes, SPA
- ui: two-tile landing page, fuzzy-filtered title list, detail panel
- Makefile, Dockerfile, .woodpecker pipelines, pre-commit config
2026-08-29 21:27:09 +10:00

93 lines
3.8 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mediamark &mdash; Chart the Kids' Course</title>
<link rel="stylesheet" href="app.css">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E%F0%9F%8F%B4%3C/text%3E%3C/svg%3E">
</head>
<body>
<nav class="navbar">
<div class="container navbar-inner">
<a class="brand" href="#/"><span class="brand-mark">&#9875;</span> Mediamark</a>
<span class="brand-tag">stow the wholesome loot in cheeztv</span>
</div>
</nav>
<!-- Landing: two big square tiles -->
<div class="container view" id="view-home">
<header class="hero">
<h1>Which hold shall we raid?</h1>
<p class="lead">Pick a section, then mark the titles fit for the wee crew.</p>
</header>
<section class="app-grid app-grid-2" id="home-tiles" aria-label="sections">
<a class="app-tile" href="#/movies" data-section="movies" data-key="m">
<span class="app-tile-icon" aria-hidden="true">&#127916;</span>
<span class="app-tile-name">Movies</span>
<span class="app-tile-key">press <kbd>m</kbd></span>
</a>
<a class="app-tile" href="#/tvseries" data-section="tvseries" data-key="t">
<span class="app-tile-icon" aria-hidden="true">&#128250;</span>
<span class="app-tile-name">TV Series</span>
<span class="app-tile-key">press <kbd>t</kbd></span>
</a>
</section>
</div>
<!-- Section: search + filtered list -->
<div class="view hidden" id="view-section">
<div class="searchbar">
<div class="container searchbar-inner">
<a class="btn btn-back" href="#/" title="Back (Esc)">&#8592;</a>
<input class="form-control" id="search" type="search" autocomplete="off" spellcheck="false"
placeholder="Search titles&hellip;" aria-label="Search titles">
<span class="search-count muted" id="search-count"></span>
</div>
</div>
<div class="container">
<h2 class="section-title" id="section-title">Movies</h2>
<div class="title-list" id="title-list" role="listbox" aria-label="titles" tabindex="-1"></div>
<p class="muted empty hidden" id="list-empty">No titles match that search.</p>
</div>
</div>
<!-- Detail panel -->
<div class="container view hidden" id="view-detail">
<a class="btn btn-back btn-back-block" href="#" id="detail-back">&#8592; Back (Esc)</a>
<section class="panel">
<div class="panel-heading">
<span class="panel-icon" aria-hidden="true">&#127917;</span>
<h2 id="detail-title">Title</h2>
</div>
<div class="panel-body detail-body">
<div class="detail-art">
<img id="detail-poster" alt="" class="poster poster-lg hidden">
<div id="detail-noposter" class="poster poster-lg poster-placeholder">?</div>
</div>
<div class="detail-meta">
<p class="detail-facts" id="detail-facts"></p>
<p id="detail-overview" class="detail-overview"></p>
<dl class="detail-stats">
<dt>On disk</dt><dd id="detail-size">&mdash;</dd>
<dt>Files</dt><dd id="detail-files">&mdash;</dd>
<dt>cheeztv</dt><dd id="detail-marked">&mdash;</dd>
</dl>
<div class="detail-actions">
<button class="btn btn-primary" id="detail-toggle">Add to cheeztv</button>
<button class="btn btn-copy hidden" id="detail-sync">Sync new files</button>
</div>
</div>
</div>
</section>
</div>
<footer class="container keyhint">
<span id="keyhint-text"></span>
</footer>
<div id="toast" class="toast hidden"></div>
<script src="app.js"></script>
</body>
</html>