139 lines
6.6 KiB
HTML
139 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/>
|
||
<title>Sphaira WebUSB File Transfer</title>
|
||
<link rel="icon" type="image/png" sizes="16x16" href="assets/icon_16.png">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="assets/icon_32.png">
|
||
<link rel="icon" type="image/png" sizes="48x48" href="assets/icon_48.png">
|
||
<link rel="apple-touch-icon" sizes="180x180" href="assets/icon_180.png">
|
||
<link rel="stylesheet" href="index.css">
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>Sphaira WebUSB File Transfer</h1>
|
||
|
||
<!-- Connection Toast Notification -->
|
||
<div id="connectionToast" class="connection-toast">
|
||
<span class="toast-icon">🔗</span>
|
||
<span id="toastMessage">Device Connected</span>
|
||
<button class="toast-close" id="toastClose">×</button>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>Step 1: Connect USB Device</h3>
|
||
<button id="connectBtn">Connect New USB Device</button>
|
||
<button id="disconnectBtn" disabled>Disconnect</button>
|
||
|
||
<div id="authorizedDevices" class="device-list" style="display: none;">
|
||
<h4 style="color: #32ffcf; margin-top: 0;">Previously Authorized Devices:</h4>
|
||
<div id="deviceListContainer"></div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- Step 2: Mode Selection -->
|
||
<div class="section">
|
||
<h3>Step 2: Select Mode</h3>
|
||
<label for="modeSelect" style="font-weight: 600; color: #bed0d6;">Choose transfer mode:</label>
|
||
<select id="modeSelect" class="custom-select" style="margin-left: 10px;">
|
||
<option value="upload">Upload (PC → Switch)</option>
|
||
<option value="download">Download (Switch → PC)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- Step 3: Upload (default) - File Selection -->
|
||
<div class="section" id="uploadStep3Section">
|
||
<h3>Step 3: Select Files to Transfer</h3>
|
||
<input type="file" id="fileInput" accept=".nsp, .xci, .nsz, .xcz" multiple class="hidden">
|
||
|
||
<div class="file-controls">
|
||
<button id="addFilesBtn" class="btn-add" disabled>Add Files</button>
|
||
<button id="clearQueueBtn" class="btn-clear" disabled>Clear Queue</button>
|
||
</div>
|
||
|
||
<div class="file-queue">
|
||
<div class="queue-header">
|
||
<span class="queue-title">File Queue</span>
|
||
<span class="queue-count" id="fileCount">0 files</span>
|
||
</div>
|
||
<div id="fileQueueList"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 3: Download - Folder Picker (hidden by default) -->
|
||
<div class="section" id="downloadStep3Section" style="display: none;">
|
||
<h3>Step 3: Select Download Destination</h3>
|
||
<button id="pickFolderBtn" class="btn-add">Pick Folder</button>
|
||
<span id="selectedFolderName" style="margin-left: 10px; color: #5cbeff;"></span>
|
||
</div>
|
||
|
||
<!-- Step 4: Upload - Transfer Files -->
|
||
<div class="section" id="uploadStep4Section">
|
||
<h3>Step 4: Transfer Files</h3>
|
||
<button id="sendBtn" disabled>Send Files</button>
|
||
<div id="transferProgress" class="device-info" style="display: none;">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||
<span id="progressTitle"><strong>Transfer Progress</strong></span>
|
||
<span id="progressCounter" style="color: #32ffcf; font-weight: 600;">0 / 0</span>
|
||
</div>
|
||
|
||
<div class="progress-bar-container" style="margin-bottom: 10px;">
|
||
<div class="progress-bar" style="height: 8px; background: #163951; border-radius: 4px; overflow: hidden;">
|
||
<div id="fileProgressBar" style="height: 100%; width: 0%; background: linear-gradient(90deg, #32ffcf, #5cbeff); transition: width 0.3s ease;"></div>
|
||
</div>
|
||
<div style="display: flex; justify-content: space-between; font-size: 0.8em; margin-top: 4px;">
|
||
<span id="progressPercentage">0%</span>
|
||
<span id="transferSpeed">0 MB/s</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Add time information -->
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 0.85em;">
|
||
<div>
|
||
<span style="color: #bed0d6;">Time Spent:</span>
|
||
<span id="timeSpent" style="color: #5cbeff; margin-left: 5px;">00:00</span>
|
||
</div>
|
||
<div>
|
||
<span style="color: #bed0d6;">Time Remaining:</span>
|
||
<span id="timeRemaining" style="color: #ffaa32; margin-left: 5px;">--:--</span>
|
||
</div>
|
||
<div>
|
||
<span style="color: #bed0d6;">Data Transferred:</span>
|
||
<span id="dataTransferred" style="color: #69ff8f; margin-left: 5px;">0 MB</span>
|
||
</div>
|
||
<div>
|
||
<span style="color: #bed0d6;">Speed:</span>
|
||
<span id="currentSpeed" style="color: #32ffcf; margin-left: 5px;">0 MB/s</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 4: Download - Spinner and status -->
|
||
<div class="section" id="downloadStep4Section" style="display: none;">
|
||
<h3>Step 4: Download Files</h3>
|
||
<div id="downloadSpinner" style="display:none;align-items:center;gap:10px;margin:18px 0 0 0;font-size:1.1em;">
|
||
<span class="spinner"></span>
|
||
<div id="downloadSpinnerTextWrap" style="display:flex;align-items:center;flex:1;min-width:0;">
|
||
<span id="downloadSpinnerText" style="overflow-x:auto;white-space:nowrap;display:block;min-width:0;flex:1;"></span>
|
||
<span id="downloadSpinnerSpeed" style="flex-shrink:0;margin-left:12px;color:#32ffcf;"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h3>Logs</h3>
|
||
<div id="logDiv" class="log"></div>
|
||
<div class="log-controls">
|
||
<button id="clearLogBtn" class="log-btn">Clear Log</button>
|
||
<button id="copyLogBtn" class="log-btn">Copy Log</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="index.js"></script>
|
||
</body>
|
||
</html>
|