Files

252 lines
10 KiB
HTML
Executable File

<!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="#16181d">
<title>DDC</title>
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/style.css">
<script src="/js/theme.js"></script>
<script type="module" src="/js/app.js"></script>
</head>
<body>
<section id="login-view" class="login-view" hidden>
<form id="login-form" class="card login-card">
<div class="login-brand">
<span class="brand-mark">DDC</span>
<p class="muted">Direct Download Client</p>
</div>
<label class="field">
<span>Username</span>
<input name="username" autocomplete="username" autocapitalize="off" required>
</label>
<label class="field">
<span>Password</span>
<input name="password" type="password" autocomplete="current-password" required>
</label>
<button type="submit" class="primary block">Sign in</button>
<p id="login-error" class="error" role="alert"></p>
</form>
</section>
<div id="app-view" class="app" hidden>
<header class="topbar">
<div class="topbar-inner">
<span class="brand-mark">DDC</span>
<span id="disk-status" class="chip"></span>
<div class="topbar-actions">
<button id="settings-button" type="button" class="ghost">Settings</button>
<button id="logout-button" type="button" class="ghost">Sign out</button>
</div>
</div>
</header>
<div id="connection-banner" class="banner" role="status" hidden></div>
<main class="content">
<section class="card">
<h2>New download</h2>
<form id="download-form" class="download-form">
<textarea id="download-urls" rows="2" placeholder="https://example.com/file.zip (one link per line, Ctrl+Enter to start)" autocomplete="off" autocapitalize="off" spellcheck="false" required></textarea>
<button type="submit" class="primary">Download</button>
</form>
<div class="download-options">
<label class="field">
<span>File name (optional, single link)</span>
<input id="download-name" placeholder="Keep the server name" autocomplete="off" autocapitalize="off">
</label>
<label class="field">
<span>Download to</span>
<select id="download-destination">
<option value="">Temporary folder (move later)</option>
</select>
</label>
<label class="field">
<span>Subfolder (optional)</span>
<input id="download-subfolder" placeholder="Movie Name (2024)" autocomplete="off" disabled>
</label>
</div>
<label class="checkbox">
<input id="auto-extract" type="checkbox" checked>
<span>Extract archives automatically</span>
</label>
<p id="download-error" class="error" role="alert"></p>
</section>
<section class="card">
<div class="list-toolbar">
<h2>Downloads</h2>
<div class="list-toolbar-actions">
<select id="job-filter" aria-label="Filter downloads">
<option value="all">All</option>
<option value="active">Active</option>
<option value="paused">Paused</option>
<option value="ready">Ready</option>
<option value="completed">Completed</option>
<option value="failed">Failed</option>
</select>
<button id="clear-completed-button" type="button" class="ghost small">Clear completed</button>
</div>
</div>
<ul id="job-list" class="job-list"></ul>
<p id="job-empty" class="empty-state">No downloads yet. Paste a link above to start.</p>
</section>
<section id="job-detail" class="card" hidden>
<div class="detail-header">
<h2 id="detail-title"></h2>
<button id="close-detail-button" type="button" class="ghost small">Close</button>
</div>
<div id="file-tree" class="file-tree"></div>
<p id="selection-summary" class="muted small-text"></p>
<div class="move-controls">
<label class="field">
<span>Destination</span>
<select id="library-select"></select>
</label>
<label class="field">
<span>Subfolder (optional)</span>
<input id="subfolder-input" placeholder="Movie Name (2024)" autocomplete="off">
</label>
</div>
<label class="checkbox">
<input id="cleanup-checkbox" type="checkbox" checked>
<span>Delete remaining temporary files after the move</span>
</label>
<button id="move-button" type="button" class="primary block-mobile" disabled>Move</button>
<p id="action-error" class="error" role="alert"></p>
</section>
<details id="history-card" class="card history-card">
<summary>
<span id="history-title">History</span>
</summary>
<ul id="history-list" class="history-list"></ul>
<p id="history-empty" class="empty-state">Moved files will be listed here.</p>
<button id="clear-history-button" type="button" class="ghost small">Clear history</button>
</details>
</main>
</div>
<dialog id="settings-dialog" class="sheet sheet-wide">
<form id="settings-form" class="sheet-form">
<header class="sheet-header">
<h2>Settings</h2>
<button id="settings-close" type="button" class="ghost small">Close</button>
</header>
<div class="sheet-body">
<section class="settings-section">
<div class="settings-intro">
<h3>Downloads</h3>
<p class="muted">How many files run at once and how fast each one downloads.</p>
</div>
<div class="settings-grid">
<label class="field">
<span>Parallel downloads</span>
<input id="setting-concurrent" type="number" inputmode="numeric" min="1" max="10" required>
<small class="field-hint">Downloads running at the same time (1 to 10).</small>
</label>
<label class="field">
<span>Connections per download</span>
<input id="setting-connections" type="number" inputmode="numeric" min="1" max="16" required>
<small class="field-hint">Parts fetched at once when the server allows it (1 to 16).</small>
</label>
</div>
</section>
<section class="settings-section">
<div class="settings-intro">
<h3>Safety</h3>
<p class="muted">Limits that protect the server.</p>
</div>
<div class="settings-grid">
<label class="field">
<span>Keep free on disk (GB)</span>
<input id="setting-min-free" type="number" inputmode="numeric" min="0" required>
<small class="field-hint">Downloads stop before free space drops below this.</small>
</label>
<label class="field">
<span>Allowed ports</span>
<input id="setting-ports" placeholder="80, 443" autocomplete="off">
<small class="field-hint">Comma separated, or * for any port.</small>
</label>
</div>
</section>
<section class="settings-section">
<div class="settings-intro">
<h3>After download</h3>
<p class="muted">Default choices for new downloads and moves.</p>
</div>
<div class="settings-stack">
<label class="checkbox">
<input id="setting-auto-extract" type="checkbox">
<span>Extract archives automatically</span>
</label>
<label class="checkbox">
<input id="setting-cleanup" type="checkbox">
<span>Delete temporary files after a move</span>
</label>
</div>
</section>
<section class="settings-section">
<div class="settings-intro">
<h3>Download paths</h3>
<p class="muted">Folders listed under "Saved paths" when you pick where a download goes.</p>
</div>
<label class="field">
<span>Folders, one per line</span>
<textarea id="setting-download-paths" rows="5" placeholder="/media/blob/TeaNet/Plex/Movies/Kids" autocomplete="off" autocapitalize="off" spellcheck="false"></textarea>
<small class="field-hint">Must be inside a destination root. Missing folders are created on first use.</small>
</label>
</section>
<section class="settings-section">
<div class="settings-intro">
<h3>This browser</h3>
<p class="muted">Saved only on this device.</p>
</div>
<div class="settings-stack">
<label class="field settings-narrow">
<span>Theme</span>
<select id="setting-theme">
<option value="system">System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<label class="checkbox">
<input id="setting-notifications" type="checkbox">
<span>Notify when downloads finish</span>
</label>
</div>
</section>
<section class="settings-section">
<div class="settings-intro">
<h3>Server</h3>
<p class="muted">Set in the server environment, read only.</p>
</div>
<dl class="info-list">
<dt>Download folder</dt>
<dd id="info-download-dir" class="mono"></dd>
<dt>Destination roots</dt>
<dd id="info-roots"></dd>
</dl>
</section>
<p id="settings-error" class="error" role="alert"></p>
</div>
<footer class="sheet-footer">
<button id="settings-cancel" type="button" class="ghost">Cancel</button>
<button type="submit" class="primary">Save</button>
</footer>
</form>
</dialog>
</body>
</html>