- Add FIFO semaphore for per-hoster concurrency control - Add token-bucket speed limiter with abort signal support - Rewrite upload-manager with retry loop, speed monitoring, and rich progress events - Add per-hoster settings: retries, max speed, parallel count, restart below speed, time interval, max size - Add context menu with shutdown-after-finish (sleep/shutdown/restart), always-on-top - Add z-o-o-m-style queue table with 8 columns, status-colored rows, progress bars - Add debounced queue rendering with scroll position preservation - Add statusbar with global speed, total bytes, elapsed time - Fix speedMonitor interval leak on error and scoping bug - Fix throttle not respecting abort signal during cancellation - Fix combined signal listener cleanup - Bump version to 1.1.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
148 lines
5.9 KiB
HTML
148 lines
5.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline';">
|
|
<title>Multi-Hoster-Upload</title>
|
|
<link rel="stylesheet" href="styles.css">
|
|
</head>
|
|
<body>
|
|
<nav class="tab-bar">
|
|
<button class="tab active" data-view="upload">Upload</button>
|
|
<button class="tab" data-view="settings">Einstellungen</button>
|
|
<button class="tab" data-view="history">Verlauf</button>
|
|
<span class="version-label" id="versionLabel"></span>
|
|
</nav>
|
|
|
|
<div id="updateBanner" class="update-banner" style="display:none">
|
|
<span id="updateMessage"></span>
|
|
<button class="btn btn-sm btn-primary" id="installUpdateBtn">Update installieren</button>
|
|
<button class="btn btn-sm btn-secondary" id="dismissUpdateBtn">×</button>
|
|
</div>
|
|
|
|
<!-- Upload View -->
|
|
<div id="upload-view" class="view active">
|
|
<!-- Toolbar -->
|
|
<div class="upload-toolbar">
|
|
<div class="toolbar-left">
|
|
<div class="hoster-select" id="hosterSelect"></div>
|
|
</div>
|
|
<div class="toolbar-right">
|
|
<div class="health-check-inline">
|
|
<button class="btn btn-xs btn-secondary" id="runHealthCheckBtn" title="Hoster Check">Check</button>
|
|
<label class="auto-check-label" title="Auto-Check vor Upload">
|
|
<input type="checkbox" id="autoHealthCheckToggle" checked>
|
|
<span>Auto</span>
|
|
</label>
|
|
</div>
|
|
<button class="btn btn-xs btn-primary" id="addFilesBtn">+ Dateien</button>
|
|
<button class="btn btn-xs btn-success" id="startUploadBtn" disabled>Upload starten</button>
|
|
<button class="btn btn-xs btn-danger" id="cancelUploadBtn" style="display:none">Abbrechen</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health check results (collapsible) -->
|
|
<div class="health-check-results" id="healthCheckResults"></div>
|
|
|
|
<!-- Drop zone (shown when no files) -->
|
|
<div class="drop-zone" id="dropZone">
|
|
<div class="drop-icon">📁</div>
|
|
<p>Dateien hierher ziehen oder klicken</p>
|
|
</div>
|
|
|
|
<!-- Queue Table -->
|
|
<div class="queue-container" id="queueContainer" style="display:none">
|
|
<table class="queue-table" id="queueTable">
|
|
<thead>
|
|
<tr>
|
|
<th class="col-filename sortable" data-sort="filename">File name</th>
|
|
<th class="col-size sortable" data-sort="size">Uploaded / Size</th>
|
|
<th class="col-host sortable" data-sort="host">Host</th>
|
|
<th class="col-status sortable" data-sort="status">Status</th>
|
|
<th class="col-elapsed">Elapsed</th>
|
|
<th class="col-remaining">Remain.</th>
|
|
<th class="col-speed sortable" data-sort="speed">Speed</th>
|
|
<th class="col-progress">Progress</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="queueBody"></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Action bar below queue -->
|
|
<div class="queue-actions" id="queueActions" style="display:none">
|
|
<button class="btn btn-xs btn-primary" id="copyAllLinksBtn">Alle Links kopieren</button>
|
|
<button class="btn btn-xs btn-secondary" id="retryFailedBtn" style="display:none">Fehlgeschlagene erneut</button>
|
|
<button class="btn btn-xs btn-secondary" id="clearQueueBtn">Queue leeren</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Settings View -->
|
|
<div id="settings-view" class="view">
|
|
<div class="settings-container">
|
|
<h2>Hoster Konfiguration</h2>
|
|
<p class="settings-hint">API-Keys und Upload-Einstellungen pro Hoster.</p>
|
|
<div class="settings-hosters" id="settingsHosters"></div>
|
|
<button class="btn btn-primary" id="saveSettingsBtn">Alles Speichern</button>
|
|
<span class="save-feedback" id="saveFeedback"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- History View -->
|
|
<div id="history-view" class="view">
|
|
<div class="history-container">
|
|
<div class="history-header">
|
|
<h2>Upload Verlauf</h2>
|
|
<button class="btn btn-secondary" id="clearHistoryBtn">Verlauf loeschen</button>
|
|
</div>
|
|
<div id="historyContainer"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Context Menu -->
|
|
<div class="context-menu" id="contextMenu" style="display:none">
|
|
<div class="ctx-item" data-action="copy-links">Links kopieren</div>
|
|
<div class="ctx-item" data-action="retry-selected">Erneut versuchen</div>
|
|
<div class="ctx-item" data-action="delete-selected">Entfernen</div>
|
|
<div class="ctx-separator"></div>
|
|
<div class="ctx-item" data-action="copy-all-links">Alle Links kopieren</div>
|
|
<div class="ctx-item" data-action="delete-all">Alle entfernen</div>
|
|
<div class="ctx-separator"></div>
|
|
<div class="ctx-item ctx-submenu" data-action="shutdown">
|
|
Shutdown nach Finish
|
|
<div class="ctx-submenu-items">
|
|
<div class="ctx-item" data-action="shutdown-nothing">Nichts</div>
|
|
<div class="ctx-item" data-action="shutdown-sleep">Ruhezustand</div>
|
|
<div class="ctx-item" data-action="shutdown-shutdown">Herunterfahren</div>
|
|
<div class="ctx-item" data-action="shutdown-restart">Neustart</div>
|
|
</div>
|
|
</div>
|
|
<div class="ctx-item" data-action="always-on-top">Immer im Vordergrund</div>
|
|
</div>
|
|
|
|
<!-- Statusbar -->
|
|
<div class="statusbar" id="statusbar">
|
|
<span class="sb-state" id="sbState">Bereit</span>
|
|
<span class="sb-separator">|</span>
|
|
<span class="sb-speed" id="sbSpeed">0 kB/s</span>
|
|
<span class="sb-separator">|</span>
|
|
<span class="sb-total" id="sbTotal">0 B</span>
|
|
<span class="sb-separator">|</span>
|
|
<span class="sb-elapsed" id="sbElapsed">00:00:00</span>
|
|
</div>
|
|
|
|
<!-- Copy toast -->
|
|
<div class="copy-toast" id="copyToast"></div>
|
|
|
|
<!-- Shutdown countdown -->
|
|
<div class="shutdown-overlay" id="shutdownOverlay" style="display:none">
|
|
<div class="shutdown-box">
|
|
<p id="shutdownMessage">System wird heruntergefahren in <span id="shutdownSeconds">60</span>s...</p>
|
|
<button class="btn btn-danger" id="cancelShutdownBtn">Abbrechen</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|