refactor: 重构禅音工具路径与配置,新增私人剪贴板技能
这是一次大型重构和功能新增: 1. 将原 zen_box 工具重命名为 web_zen_box,调整所有相关路径与配置 2. 新增 web_order_box 原生Web应用的完整资源与部署脚本 3. 新增私人剪贴板后端技能与配套测试脚本 4. 修复订单盒子APP的API地址配置,避免路径重复拼接 5. 新增本地开发跨域白名单支持localhost 6. 清理旧版zen_box的冗余文件
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="观空禅音">
|
||||
<meta name="theme-color" content="#060612">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.svg">
|
||||
<title>观空禅音</title>
|
||||
<link rel="stylesheet" href="zen_box.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Splash Screen -->
|
||||
<div class="splash" id="splash">
|
||||
<svg class="splash-icon" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="50" cy="44" r="32" stroke="#e8b86d" stroke-width="1.2" opacity="0.25"/>
|
||||
<ellipse cx="50" cy="84" rx="22" ry="4" fill="rgba(232,184,109,0.12)"/>
|
||||
<path d="M33 66 C24 65 16 70 14 78 C12 84 16 88 24 87 C32 86 42 79 44 72 L44 67 Z" fill="#e8e6f0"/>
|
||||
<path d="M67 66 C76 65 84 70 86 78 C88 84 84 88 76 87 C68 86 58 79 56 72 L56 67 Z" fill="#e8e6f0"/>
|
||||
<path d="M44 67 C44 67 40 58 40 50 C40 40 44 34 48 30 L50 29 L52 30 C56 34 60 40 60 50 C60 58 56 67 56 67 C53 74 47 74 44 67 Z" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="72" rx="10" ry="4" fill="#e8e6f0"/>
|
||||
<rect x="46" y="25" width="8" height="7" rx="2" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="17" rx="11" ry="12" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="6" rx="5" ry="4" fill="#e8e6f0"/>
|
||||
<path d="M34 36 Q28 33 28 29 Q28 25 34 22" stroke="#e8b86d" stroke-width="1.2" stroke-linecap="round" fill="none" opacity="0.7"/>
|
||||
<path d="M66 36 Q72 33 72 29 Q72 25 66 22" stroke="#e8b86d" stroke-width="1.2" stroke-linecap="round" fill="none" opacity="0.7"/>
|
||||
<circle cx="50" cy="7" r="1.5" fill="#e8b86d" opacity="0.8"/>
|
||||
</svg>
|
||||
<div class="splash-title">观空禅音</div>
|
||||
<div class="splash-sub">正在加载歌单与缓存...</div>
|
||||
<div class="splash-spinner"></div>
|
||||
</div>
|
||||
|
||||
<!-- Starfield Background -->
|
||||
<div class="starfield">
|
||||
<div class="stars-sm"></div>
|
||||
<div class="stars-md"></div>
|
||||
<div class="stars-lg"></div>
|
||||
</div>
|
||||
|
||||
<div class="app">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<div class="header-title">
|
||||
<svg class="header-icon" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="50" cy="44" r="32" stroke="#e8b86d" stroke-width="1.2" opacity="0.25"/>
|
||||
<ellipse cx="50" cy="84" rx="22" ry="4" fill="rgba(232,184,109,0.12)"/>
|
||||
<path d="M33 66 C24 65 16 70 14 78 C12 84 16 88 24 87 C32 86 42 79 44 72 L44 67 Z" fill="#e8e6f0"/>
|
||||
<path d="M67 66 C76 65 84 70 86 78 C88 84 84 88 76 87 C68 86 58 79 56 72 L56 67 Z" fill="#e8e6f0"/>
|
||||
<path d="M44 67 C44 67 40 58 40 50 C40 40 44 34 48 30 L50 29 L52 30 C56 34 60 40 60 50 C60 58 56 67 56 67 C53 74 47 74 44 67 Z" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="72" rx="10" ry="4" fill="#e8e6f0"/>
|
||||
<rect x="46" y="25" width="8" height="7" rx="2" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="17" rx="11" ry="12" fill="#e8e6f0"/>
|
||||
<ellipse cx="50" cy="6" rx="5" ry="4" fill="#e8e6f0"/>
|
||||
<path d="M34 36 Q28 33 28 29 Q28 25 34 22" stroke="#e8b86d" stroke-width="1.2" stroke-linecap="round" fill="none" opacity="0.7"/>
|
||||
<path d="M66 36 Q72 33 72 29 Q72 25 66 22" stroke="#e8b86d" stroke-width="1.2" stroke-linecap="round" fill="none" opacity="0.7"/>
|
||||
<circle cx="50" cy="7" r="1.5" fill="#e8b86d" opacity="0.8"/>
|
||||
</svg>
|
||||
观<span>空</span>禅音
|
||||
</div>
|
||||
<div class="header-count" id="trackCount">0 首</div>
|
||||
</div>
|
||||
|
||||
<!-- Zen Center -->
|
||||
<div class="zen-center">
|
||||
<div class="orbit-wrap">
|
||||
<div class="orbit-ring"></div>
|
||||
<div class="orbit-ring-2"></div>
|
||||
<div class="orbit-dot-1"></div>
|
||||
<div class="orbit-dot-2"></div>
|
||||
<div class="zen-glow" id="zenGlow"></div>
|
||||
<div class="zen-waves">
|
||||
<div class="zen-wave" id="zenWave0"></div>
|
||||
<div class="zen-wave" id="zenWave1"></div>
|
||||
<div class="zen-wave" id="zenWave2"></div>
|
||||
</div>
|
||||
<div class="zen-figure" id="zenFigure">
|
||||
<!-- Zen meditation figure — natural lotus posture, warm gold silhouette -->
|
||||
<svg viewBox="0 0 200 210" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<!-- Ground shadow -->
|
||||
<ellipse cx="100" cy="178" rx="44" ry="5.5" fill="rgba(232,184,109,0.08)"/>
|
||||
|
||||
<!-- === LOWER BODY: Full lotus base === -->
|
||||
<!-- Lap platform — wide, grounded oval -->
|
||||
<ellipse cx="100" cy="158" rx="46" ry="14" fill="#c8973e" opacity="0.70"/>
|
||||
|
||||
<!-- Left knee extending out and down -->
|
||||
<path d="M 54 150 C 44 152, 36 158, 36 165 C 36 171, 42 175, 52 174 C 60 173, 68 167, 72 160 C 74 155, 70 149, 64 148 Z" fill="#d4a045" opacity="0.78"/>
|
||||
|
||||
<!-- Right knee extending out and down -->
|
||||
<path d="M 146 150 C 156 152, 164 158, 164 165 C 164 171, 158 175, 148 174 C 140 173, 132 167, 128 160 C 126 155, 130 149, 136 148 Z" fill="#d4a045" opacity="0.78"/>
|
||||
|
||||
<!-- Left foot resting on right thigh — visible instep -->
|
||||
<path d="M 124 148 C 132 144, 142 145, 146 150 C 148 153, 145 157, 138 157 C 131 157, 124 153, 122 150 Z" fill="#c8973e" opacity="0.72"/>
|
||||
|
||||
<!-- Right foot resting on left thigh — visible instep -->
|
||||
<path d="M 76 148 C 68 144, 58 145, 54 150 C 52 153, 55 157, 62 157 C 69 157, 76 153, 78 150 Z" fill="#c8973e" opacity="0.72"/>
|
||||
|
||||
<!-- === TORSO: Upright, slightly tapered === -->
|
||||
<path d="
|
||||
M 72 152
|
||||
C 70 140, 69 126, 70 114
|
||||
C 71 102, 75 92, 82 85
|
||||
C 88 79, 94 77, 100 76
|
||||
C 106 77, 112 79, 118 85
|
||||
C 125 92, 129 102, 130 114
|
||||
C 131 126, 130 140, 128 152
|
||||
C 120 157, 110 160, 100 160
|
||||
C 90 160, 80 157, 72 152
|
||||
Z
|
||||
" fill="#e0a84e" opacity="0.88"/>
|
||||
|
||||
<!-- Chest line — subtle center crease -->
|
||||
<path d="M 100 88 C 99 108, 99 130, 100 152" stroke="#c8882a" stroke-width="0.8" opacity="0.18" stroke-linecap="round"/>
|
||||
|
||||
<!-- === ARMS: Draped down naturally to lap === -->
|
||||
<!-- Left upper arm — hangs from shoulder, angles inward -->
|
||||
<path d="M 70 114 C 64 116, 58 122, 56 130 C 54 136, 56 142, 62 146 C 68 148, 75 146, 78 140 C 74 136, 70 128, 70 118 Z" fill="#d4a045" opacity="0.82"/>
|
||||
|
||||
<!-- Right upper arm -->
|
||||
<path d="M 130 114 C 136 116, 142 122, 144 130 C 146 136, 144 142, 138 146 C 132 148, 125 146, 122 140 C 126 136, 130 128, 130 118 Z" fill="#d4a045" opacity="0.82"/>
|
||||
|
||||
<!-- === HANDS in dhyana mudra: left palm up, right resting on top === -->
|
||||
<!-- Left hand — palm up, fingers slightly curved -->
|
||||
<path d="M 84 154 C 80 152, 76 152, 75 155 C 74 158, 76 162, 82 163 C 88 164, 96 162, 98 158 C 98 155, 92 154, 84 154 Z" fill="#d4a045" opacity="0.80"/>
|
||||
<!-- Right hand resting on left, fingers forward -->
|
||||
<path d="M 102 152 C 98 150, 94 150, 92 153 C 90 156, 91 160, 96 162 C 102 163, 110 161, 114 157 C 116 154, 112 151, 106 151 Z" fill="#c8973e" opacity="0.78"/>
|
||||
<!-- Thumb tips touching — small oval -->
|
||||
<ellipse cx="99" cy="153" rx="4" ry="2.5" fill="#e8b86d" opacity="0.55"/>
|
||||
|
||||
<!-- === NECK: slim, natural === -->
|
||||
<path d="M 93 78 C 93 74, 96 70, 100 69 C 104 70, 107 74, 107 78 L 107 86 L 93 86 Z" fill="#e0a84e" opacity="0.88"/>
|
||||
|
||||
<!-- === HEAD: slightly bowed forward, serene === -->
|
||||
<!-- Head shape — slightly elongated, chin tucked -->
|
||||
<path d="
|
||||
M 82 54
|
||||
C 82 36, 90 26, 100 25
|
||||
C 110 26, 118 36, 118 54
|
||||
C 118 66, 112 74, 106 77
|
||||
L 100 79
|
||||
L 94 77
|
||||
C 88 74, 82 66, 82 54
|
||||
Z
|
||||
" fill="#e0a84e" opacity="0.88"/>
|
||||
|
||||
<!-- === HAIR: simple smooth cap === -->
|
||||
<path d="M 82 50 C 82 36, 90 26, 100 25 C 110 26, 118 36, 118 50 C 112 43, 106 39, 100 38 C 94 39, 88 43, 82 50 Z" fill="#b8812a" opacity="0.80"/>
|
||||
|
||||
<!-- === FACE: eyes closed, barely-there features === -->
|
||||
<!-- Brow ridge — very subtle -->
|
||||
<path d="M 89 53 Q 93 51, 97 53" stroke="#8a6020" stroke-width="0.8" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<path d="M 103 53 Q 107 51, 111 53" stroke="#8a6020" stroke-width="0.8" stroke-linecap="round" fill="none" opacity="0.35"/>
|
||||
<!-- Eyes closed — downward arc, peaceful -->
|
||||
<path d="M 89 57 Q 93 61, 97 57" stroke="#7a5010" stroke-width="1.4" stroke-linecap="round" fill="none" opacity="0.65"/>
|
||||
<path d="M 103 57 Q 107 61, 111 57" stroke="#7a5010" stroke-width="1.4" stroke-linecap="round" fill="none" opacity="0.65"/>
|
||||
<!-- Nose — single gentle hint -->
|
||||
<path d="M 100 62 C 99 65, 97 67, 97 68" stroke="#8a6020" stroke-width="1" stroke-linecap="round" fill="none" opacity="0.25"/>
|
||||
<!-- Lips — serene half-smile -->
|
||||
<path d="M 95 72 Q 100 75, 105 72" stroke="#8a6020" stroke-width="1.2" stroke-linecap="round" fill="none" opacity="0.30"/>
|
||||
|
||||
<!-- === CROWN CHAKRA: sahasrara point === -->
|
||||
<circle cx="100" cy="24" r="3.5" fill="rgba(232,184,109,0.20)"/>
|
||||
<circle cx="100" cy="24" r="1.8" fill="#e8b86d" opacity="0.75"/>
|
||||
<circle cx="100" cy="24" r="0.8" fill="#fff" opacity="0.60"/>
|
||||
|
||||
<!-- === SUBTLE INNER LIGHT: warm glow at heart center === -->
|
||||
<circle cx="100" cy="110" r="12" fill="rgba(232,184,109,0.04)"/>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Track Info -->
|
||||
<div class="track-info">
|
||||
<div class="track-title marquee-host" id="trackTitleHost">
|
||||
<div class="marquee-track" id="trackTitleTrack">
|
||||
<span class="marquee-copy marquee-copy-primary" id="trackTitle">未选择歌曲</span>
|
||||
<span class="marquee-gap" aria-hidden="true"></span>
|
||||
<span class="marquee-copy marquee-copy-duplicate" id="trackTitleDuplicate" aria-hidden="true">未选择歌曲</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="track-artist" id="trackArtist">—</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Control Bar -->
|
||||
<div class="bottom-bar">
|
||||
<div class="glass-bar">
|
||||
<!-- Progress -->
|
||||
<div class="progress-wrap">
|
||||
<input type="range" class="progress-bar" id="progressBar" min="0" max="100" value="0"
|
||||
oninput="onProgressInput(this.value)" onchange="onProgressChange(this.value)">
|
||||
<div class="time-row">
|
||||
<span id="timeCurrent">0:00</span>
|
||||
<span id="timeTotal">0:00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Controls -->
|
||||
<div class="controls">
|
||||
<button class="ctrl-btn" id="btnShuffle" onclick="toggleShuffle()" title="随机">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="16 1 21 3 21 8"></polyline>
|
||||
<path d="M4 4 C8 4 10 8 12 12 C14 16 16 20 20 20"></path>
|
||||
<polyline points="16 23 21 23 21 18"></polyline>
|
||||
<path d="M4 20 C8 20 10 16 12 12 C14 8 16 4 20 4"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="ctrl-btn" onclick="prevTrack()" title="上一首">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M6 6h2v12H6V6zm3.5 6 8.5 6V6l-8.5 6z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="play-btn" id="playBtn" onclick="togglePlay()" title="播放/暂停">
|
||||
<svg id="iconPlay" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M8 5v14l11-7z"></path>
|
||||
</svg>
|
||||
<svg id="iconPause" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" style="display:none">
|
||||
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="ctrl-btn" onclick="nextTrack()" title="下一首">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M16 6h2v12h-2V6zm-10 0v12l8.5-6L6 6z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="ctrl-btn" id="btnRepeat" onclick="cycleRepeat()" title="循环">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="17 1 21 5 17 9"></polyline><path d="M3 11V9a4 4 0 0 1 4-4h14"></path>
|
||||
<polyline points="7 23 3 19 7 15"></polyline><path d="M21 13v2a4 4 0 0 1-4 4H3"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Secondary row: playlist + settings -->
|
||||
<div class="secondary-controls">
|
||||
<button class="sec-btn" onclick="openSheet()" title="播放列表">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="8" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="8" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="8" y1="18" x2="21" y2="18"></line>
|
||||
<line x1="3" y1="6" x2="3.01" y2="6"></line>
|
||||
<line x1="3" y1="12" x2="3.01" y2="12"></line>
|
||||
<line x1="3" y1="18" x2="3.01" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="sec-btn" onclick="openSettings()" title="设置">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06A1.65 1.65 0 0 0 15 19.4a1.65 1.65 0 0 0-1 .6 1.65 1.65 0 0 1-2 0 1.65 1.65 0 0 0-1-.6 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-.6-1 1.65 1.65 0 0 1 0-2 1.65 1.65 0 0 0 .6-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-.6 1.65 1.65 0 0 1 2 0 1.65 1.65 0 0 0 1 .6 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9c0 .38.14.74.4 1a1.65 1.65 0 0 1 0 2c-.26.26-.4.62-.4 1z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Settings Modal -->
|
||||
<div class="settings-overlay" id="settingsOverlay" onclick="closeSettings()"></div>
|
||||
<div class="settings-panel" id="settingsPanel">
|
||||
<div class="settings-header">
|
||||
<div class="settings-title">设置</div>
|
||||
<button class="sheet-close" onclick="closeSettings()" title="关闭设置">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="settings-body">
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">账号</div>
|
||||
<div id="accountSection"></div>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">当前歌单</div>
|
||||
<select id="playlistSelect" class="setting-select"></select>
|
||||
<div class="setting-note">自动读取所有以 playlist.json 结尾的歌单,并记住你上次选择。</div>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">缓存对照</div>
|
||||
<div class="setting-summary" id="cacheSummary">正在检查缓存...</div>
|
||||
<div class="setting-note">按歌曲地址对照当前歌单与浏览器缓存,标记哪些已缓存、哪些未缓存。</div>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">缓存模式</div>
|
||||
<label class="setting-switch">
|
||||
<input type="checkbox" id="cacheOnlyToggle">
|
||||
<span>只用缓存听歌曲</span>
|
||||
</label>
|
||||
<div class="setting-note">开启后,切歌时只播放已下载的歌曲,未缓存的歌曲需先在播放列表下载。</div>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">缓存管理</div>
|
||||
<div class="cache-size-row">
|
||||
<span>已缓存大小</span>
|
||||
<span class="cache-size-value" id="cacheSizeText">正在统计...</span>
|
||||
</div>
|
||||
<button class="clear-cache-btn" id="btnClearCache" onclick="clearAllCache()">清除所有缓存</button>
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<div class="setting-label">播放记忆</div>
|
||||
<label class="setting-switch">
|
||||
<input type="checkbox" id="resumePlaybackToggle">
|
||||
<span>记住上次位置继续听</span>
|
||||
</label>
|
||||
<div class="setting-note">默认开启,下次打开时从上次暂停的位置继续播放</div>
|
||||
</div>
|
||||
<div class="about-card">
|
||||
<div class="about-head">
|
||||
<div class="about-name">观空禅音</div>
|
||||
<div class="about-sub">ZenVoid</div>
|
||||
</div>
|
||||
<div class="about-desc">这不是一款为了喧闹和效率而设计的播放器。它更像一处留白,让人愿意慢下来,听见一点安静。</div>
|
||||
<div class="about-desc">"ZenVoid"和"观空"都不是标准答案,只是我们尽力靠近这种感受的一种表达。希望它陪你在日常里,留一点空,听一点静。</div>
|
||||
<div class="about-version">v1.0.0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Playlist Sheet Overlay -->
|
||||
<div class="sheet-overlay" id="sheetOverlay" onclick="closeSheet()"></div>
|
||||
<div class="sheet" id="sheet">
|
||||
<div class="sheet-handle"></div>
|
||||
<div class="sheet-header">
|
||||
<div class="sheet-title">
|
||||
播放列表
|
||||
<span class="offline-badge" id="offlineBadge" style="display:none">离线模式</span>
|
||||
</div>
|
||||
<button class="sheet-close" onclick="closeSheet()">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sheet-list" id="sheetList">
|
||||
<div class="empty-state" id="emptyState">
|
||||
暂无曲目<br>
|
||||
<span style="font-size:12px;opacity:0.6">请将音乐文件添加至播放列表</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sheet-footer">
|
||||
<div class="sort-row">
|
||||
<button class="sort-btn" id="sortOriginal" onclick="applySort('original')">原始顺序</button>
|
||||
<button class="sort-btn" id="sortAsc" onclick="applySort('asc')">名称正序</button>
|
||||
<button class="sort-btn" id="sortDesc" onclick="applySort('desc')">名称倒序</button>
|
||||
</div>
|
||||
<button class="download-all-btn" id="btnDownloadAll" onclick="downloadAllTracks()">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
||||
<polyline points="7 10 12 15 17 10"></polyline>
|
||||
<line x1="12" y1="15" x2="12" y2="3"></line>
|
||||
</svg>
|
||||
<span id="btnDownloadAllText">一键下载所有</span>
|
||||
</button>
|
||||
<div class="batch-progress" id="batchProgress" style="display:none">
|
||||
<div class="batch-progress-title" id="batchProgressTitle">—</div>
|
||||
<div class="batch-progress-bar">
|
||||
<div class="batch-progress-fill" id="batchProgressFill"></div>
|
||||
</div>
|
||||
<div class="batch-progress-meta">
|
||||
<span id="batchProgressPct">0%</span>
|
||||
<span id="batchProgressCount">0/0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Login Overlay -->
|
||||
<div class="login-overlay" id="loginOverlay">
|
||||
<div class="login-card">
|
||||
<button class="sheet-close login-close" onclick="closeLoginOverlay()" title="关闭">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="login-title">登录</div>
|
||||
<div class="login-sub">登录后可跨设备同步你的配置</div>
|
||||
<input class="login-input" id="loginUsername" type="text" placeholder="账号" autocomplete="username">
|
||||
<input class="login-input" id="loginPassword" type="password" placeholder="密码" autocomplete="current-password">
|
||||
<div class="login-error" id="loginError"></div>
|
||||
<button class="login-btn" id="btnLogin" onclick="doLogin()">登 录</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<!-- Hidden Audio -->
|
||||
<audio id="audio" preload="metadata"></audio>
|
||||
|
||||
<script src="zen_box.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user