mirror of
https://github.com/hanxi/xiaomusic.git
synced 2026-06-01 12:15:48 +08:00
新增版本更新提示,UI做了调整,更加匹配后台缓存及为新功能做准备 (#893)
This commit is contained in:
457
xiaomusic/static/iwebplayer/iwebplayer.html
vendored
457
xiaomusic/static/iwebplayer/iwebplayer.html
vendored
@@ -238,31 +238,7 @@
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
.inline-save-btn {
|
||||
background: rgba(236, 72, 153, 0.1);
|
||||
color: var(--primary);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
flex-shrink: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, transform 0.1s, opacity 0.2s;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.inline-save-btn { background: rgba(236, 72, 153, 0.15); }
|
||||
}
|
||||
.inline-save-btn:active {
|
||||
opacity: 0.8;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
.inline-save-btn.show {
|
||||
display: flex;
|
||||
animation: fadeIn 0.2s;
|
||||
}
|
||||
|
||||
.playlist-container-search { flex: 0 0 auto !important; max-width: 160px; }
|
||||
|
||||
.search-inline-wrap {
|
||||
@@ -1075,8 +1051,7 @@
|
||||
|
||||
.text-mf { color: var(--primary) !important; }
|
||||
.text-lx { color: #10b981 !important; }
|
||||
.bg-mf { background: rgba(236, 72, 153, 0.1) !important; color: var(--primary) !important; }
|
||||
.bg-lx { background: rgba(16, 185, 129, 0.1) !important; color: #10b981 !important; }
|
||||
|
||||
li.select-option[data-value="LXServer"].active { color: #10b981 !important; }
|
||||
.lx-opts .select-option.active { color: #10b981 !important; background: var(--bg-color) !important; }
|
||||
@keyframes spin-hourglass { 100% { transform: rotate(180deg); } }
|
||||
@@ -1483,6 +1458,12 @@
|
||||
#voice-pane #radio-lx:checked::after { background-color: #10b981; }
|
||||
#voice-pane .radio-item:has(#radio-lx:checked) .radio-label { color: #10b981; }
|
||||
.radio-item:has(input[name="voice-strategy"]:checked) .radio-label { color: var(--primary); font-weight: bold; }
|
||||
|
||||
.select-option.disabled {
|
||||
color: var(--text-sub);
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -1509,7 +1490,7 @@
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:6px; vertical-align:-2px;"><path d="m21.64 3.68-1.25-1.25a1.92 1.92 0 0 0-2.71 0L4.54 15.57a1.92 1.92 0 0 0 0 2.71l1.25 1.25a1.92 1.92 0 0 0 2.71 0L21.64 6.39a1.92 1.92 0 0 0 0-2.71z"></path><path d="m14 7 3 3"></path><path d="M5 6v4"></path><path d="M19 14v4"></path><path d="M10 2v2"></path><path d="M7 8H3"></path><path d="M21 16h-4"></path><path d="M11 3H9"></path></svg> 批量定制
|
||||
</li>
|
||||
<li class="select-option" id="setting-download">
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:6px; vertical-align:-2px;"><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> 下载设置
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:6px; vertical-align:-2px;"><path d="M8 17l4 4 4-4"></path><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path></svg> 下载设置
|
||||
</li>
|
||||
<li class="select-option" id="setting-config">
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" style="margin-right:6px; vertical-align:-2px;"><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 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg> 后台配置
|
||||
@@ -1562,6 +1543,12 @@
|
||||
<div class="select-value" id="playlist-val" style="display: flex; align-items: center; width: 100%; border: none; background-color: transparent; height: 100%; box-shadow: none; padding: 0 24px 0 12px; margin: 0; line-height: normal; background-position: right 10px center;">加载中</div>
|
||||
<ul class="select-options" id="playlist-opts" style="width: 100%;"></ul>
|
||||
</div>
|
||||
|
||||
<div id="voice-playlist-refresh-wrap" style="display: none; height: 100%; align-items: center; flex-shrink: 0;">
|
||||
<div class="search-text-divider" style="width: 1px; height: 14px; background: var(--border); margin: 0 4px; flex-shrink: 0;"></div>
|
||||
<button class="search-text-btn" id="voice-playlist-refresh-btn" style="background: transparent; border: none; height: 100%; padding: 0 16px; font-size: 14px; font-weight: 600; color: var(--text-sub) !important; cursor: pointer; transition: all 0.15s ease; white-space: nowrap;">刷新</button>
|
||||
</div>
|
||||
|
||||
<div class="search-inline-wrap" id="search-inline-wrap" style="background: transparent; border: none; padding: 0; height: 100%; flex: 1;">
|
||||
<div style="width: 1px; height: 14px; background: var(--border); margin: 0 4px; flex-shrink: 0;"></div>
|
||||
<input type="text" id="search-input" placeholder="搜歌名..." autocomplete="off" style="padding: 0 8px; flex: 1; height: 100%;">
|
||||
@@ -1584,10 +1571,25 @@
|
||||
<ul class="select-options" id="mf-plugin-opts" style="min-width: 120px; right: 0;"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="custom-select" id="global-menu-1-container" style="flex: 0 0 auto; height: 100%; display: flex; align-items: center; padding-right: 4px;">
|
||||
<div style="width: 1px; height: 14px; background: var(--border); margin: 0 2px 0 6px; flex-shrink: 0;"></div>
|
||||
<div class="song-more-btn" id="global-menu-1-btn" title="列表操作" style="width: 30px; height: 30px; margin: 0; padding: 0;">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" stroke="none"><circle cx="12" cy="5" r="2"></circle><circle cx="12" cy="12" r="2"></circle><circle cx="12" cy="19" r="2"></circle></svg>
|
||||
</div>
|
||||
<ul class="select-options" id="global-menu-1-opts" style="right: 0; min-width: 130px; top: 100%;">
|
||||
<li class="select-option global-add-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" style="margin-right:8px; vertical-align:-3px;"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><path d="M12 6a6 6 0 0 0-6 6"></path></svg>创建/加入
|
||||
</li>
|
||||
<li class="select-option disabled global-dev-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:8px; vertical-align:-3px;"><path d="M8 17l4 4 4-4"></path><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path></svg>批量下载
|
||||
</li>
|
||||
<li class="select-option disabled global-dev-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:8px; vertical-align:-3px;"><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><line x1="12" y1="11" x2="16" y2="11"></line><line x1="12" y1="16" x2="16" y2="16"></line><line x1="8" y1="11" x2="8.01" y2="11"></line><line x1="8" y1="16" x2="8.01" y2="16"></line></svg>续播&调速
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="inline-save-btn" id="search-save" title="批量加入歌单">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12A9 9 0 1 0 12 21"></path><circle cx="12" cy="12" r="3"></circle><path d="M12 7a5 5 0 0 0-5 5"></path><line x1="19" y1="16" x2="19" y2="22"></line><line x1="16" y1="19" x2="22" y2="19"></line></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="search-inline-wrap" id="mf-search-wrap" style="flex: 0 0 36px; min-height: 36px; align-items: center; background: transparent; border: none; height: 36px; padding: 0; box-sizing: border-box; width: 100%; gap: 10px;">
|
||||
@@ -1602,21 +1604,36 @@
|
||||
</button>
|
||||
|
||||
<div class="search-text-group">
|
||||
<div id="mf-search-main-btns" style="display: flex; align-items: center; height: 100%;">
|
||||
<button class="search-text-btn" id="mf-search-btn">搜歌</button>
|
||||
<div class="search-text-divider" id="mf-search-divider"></div> <button class="search-text-btn" id="mf-search-playlist-btn">搜单</button>
|
||||
<div id="mf-search-main-btns" style="display: flex; align-items: center; height: 100%;">
|
||||
<button class="search-text-btn" id="mf-search-btn">搜歌</button>
|
||||
<div class="search-text-divider" id="mf-search-divider"></div> <button class="search-text-btn" id="mf-search-playlist-btn">搜单</button>
|
||||
</div>
|
||||
<button class="search-text-btn" id="mf-search-back-btn" style="display: none; padding: 0 20px;">返回</button>
|
||||
|
||||
<div class="search-text-divider" style="width: 1px; height: 14px; background: var(--border); margin: 0 2px; flex-shrink: 0; align-self: center;"></div>
|
||||
<div class="custom-select" id="global-menu-2-container" style="flex: 0 0 auto; height: 100%; display: flex; align-items: center; padding: 0 4px;">
|
||||
<div class="song-more-btn" id="global-menu-2-btn" title="列表操作" style="width: 28px; height: 28px; margin: 0; padding: 0;">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" stroke="none"><circle cx="12" cy="5" r="2"></circle><circle cx="12" cy="12" r="2"></circle><circle cx="12" cy="19" r="2"></circle></svg>
|
||||
</div>
|
||||
<ul class="select-options" id="global-menu-2-opts" style="right: 0; min-width: 130px; top: 100%;">
|
||||
<li class="select-option global-add-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" style="margin-right:8px; vertical-align:-3px;"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><path d="M12 6a6 6 0 0 0-6 6"></path></svg>创建/加入
|
||||
</li>
|
||||
<li class="select-option disabled global-dev-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:8px; vertical-align:-3px;"><path d="M8 17l4 4 4-4"></path><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path></svg>批量下载
|
||||
</li>
|
||||
<li class="select-option disabled global-dev-btn">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:8px; vertical-align:-3px;"><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><line x1="12" y1="11" x2="16" y2="11"></line><line x1="12" y1="16" x2="16" y2="16"></line><line x1="8" y1="11" x2="8.01" y2="11"></line><line x1="8" y1="16" x2="8.01" y2="16"></line></svg>续播&调速
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<button class="search-text-btn" id="mf-search-back-btn" style="display: none; padding: 0 20px;">返回</button>
|
||||
|
||||
<ul class="search-history-list" id="mf-search-history-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="search-history-list" id="mf-search-history-list"></ul>
|
||||
</div>
|
||||
|
||||
<button class="inline-save-btn" id="mf-search-save" title="批量加入歌单">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12A9 9 0 1 0 12 21"></path><circle cx="12" cy="12" r="3"></circle><path d="M12 7a5 5 0 0 0-5 5"></path><line x1="19" y1="16" x2="19" y2="22"></line><line x1="16" y1="19" x2="22" y2="19"></line></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading">正在加载音乐...</div>
|
||||
@@ -1721,6 +1738,7 @@
|
||||
<li>支持调用LX Server接口(搜歌曲/搜歌单)</li>
|
||||
<li>提供免签发Web App安装</li>
|
||||
</ul>
|
||||
<div id="remote-notice-wrapper" style="display: none; margin-top: 16px; margin-bottom: 16px;"></div>
|
||||
<div class="about-link">
|
||||
项目主页 / 更新地址:<br>
|
||||
<a href="https://github.com/birdstudy-nj/iWebPlayer" target="_blank" rel="noopener">https://github.com/birdstudy-nj/iWebPlayer</a>
|
||||
@@ -1890,7 +1908,7 @@
|
||||
<div class="about-header">
|
||||
<div class="about-title-wrap">
|
||||
<h2 style="font-size: 18px; font-weight: 800; margin-top: 4px; display: flex; align-items: center; gap: 6px;">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><path d="M12 6a6 6 0 0 0-6 6"></path></svg> 加入歌单
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle><path d="M12 6a6 6 0 0 0-6 6"></path></svg> 创建/加入歌单
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2136,8 +2154,9 @@
|
||||
/* ==========================================
|
||||
* 1. 核心配置与全局状态
|
||||
* ========================================== */
|
||||
const APP_VERSION = 'v1.7.5';
|
||||
const APP_VERSION = 'v1.7.6';
|
||||
const APP_LOGO = document.getElementById('app-logo')?.content || '';
|
||||
const PREDEFINED_PLAYLISTS = ['在线资源', '本地搜索', '所有电台', '所有歌曲', '最近新增', '收藏', '下载', 'cache_songs'];
|
||||
const LX_PLATFORMS_MAP = { 'tx': 'QQ', 'wy': '网易云', 'kg': '酷狗', 'kw': '酷我', 'mg': '咪咕' };
|
||||
const LX_BACKEND_NAMES = { 'tx': '小秋音乐', 'wy': '小芸音乐', 'kg': '小枸音乐', 'kw': '小蜗音乐', 'mg': '小蜜音乐' };
|
||||
const STANDARD_LX_KEYS = Object.keys(LX_PLATFORMS_MAP);
|
||||
@@ -2303,8 +2322,6 @@
|
||||
const searchClear = document.getElementById('search-clear');
|
||||
const mfSearchInput = document.getElementById('mf-search-input');
|
||||
const mfSearchClear = document.getElementById('mf-search-clear');
|
||||
const searchSaveBtn = document.getElementById('search-save');
|
||||
const mfSearchSaveBtn = document.getElementById('mf-search-save');
|
||||
|
||||
document.getElementById('setting-version-label').textContent = APP_VERSION;
|
||||
document.getElementById('about-version-label').textContent = APP_VERSION;
|
||||
@@ -2357,6 +2374,12 @@
|
||||
else if (name === '本地搜索') { icon = SVG_ICONS.search; displayName = '曲库搜索'; }
|
||||
else if (name === '下载') icon = SVG_ICONS.download;
|
||||
else if (name === '最近新增') { icon = SVG_ICONS.recent; displayName = '本地新增'; }
|
||||
|
||||
else if (name === 'cache_songs') {
|
||||
icon = `<svg viewBox="0 0 24 24" width="15" height="15" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path></svg>`;
|
||||
displayName = '缓存歌曲';
|
||||
}
|
||||
|
||||
else if (
|
||||
name === '_online_iwebplayer_search' ||
|
||||
name === '_online_play' ||
|
||||
@@ -2642,44 +2665,50 @@
|
||||
const mfSearchWrap = document.getElementById('mf-search-wrap');
|
||||
const mfPluginRow = document.getElementById('mf-plugin-row');
|
||||
const plContainer = document.getElementById('playlist-container');
|
||||
|
||||
if (playlistName !== '本地搜索' && searchSaveBtn) {
|
||||
searchSaveBtn.classList.remove('show');
|
||||
}
|
||||
const gm1Container = document.getElementById('global-menu-1-container');
|
||||
|
||||
if (playlistName === '本地搜索') {
|
||||
if (searchWrap) searchWrap.classList.add('show');
|
||||
if (mfSearchWrap) mfSearchWrap.classList.remove('show');
|
||||
if (mfPluginRow) mfPluginRow.classList.remove('show');
|
||||
if (plContainer) plContainer.classList.add('playlist-container-search');
|
||||
if (gm1Container) gm1Container.style.display = 'flex';
|
||||
|
||||
const savedSearch = localStorage.getItem('local_search_keyword') || '';
|
||||
if (searchInput) searchInput.value = savedSearch;
|
||||
if (savedSearch && searchClear) searchClear.classList.add('show');
|
||||
|
||||
} else if (playlistName === '在线资源') {
|
||||
|
||||
if (searchWrap) searchWrap.classList.remove('show');
|
||||
if (mfPluginRow) mfPluginRow.classList.add('show');
|
||||
if (plContainer) plContainer.classList.add('playlist-container-search');
|
||||
|
||||
if (mfSearchWrap) mfSearchWrap.classList.add('show');
|
||||
if (gm1Container) gm1Container.style.display = 'none';
|
||||
|
||||
const mfPluginContainer = document.getElementById('mf-plugin-container');
|
||||
if (mfPluginContainer) {
|
||||
mfPluginContainer.style.opacity = '1';
|
||||
mfPluginContainer.style.pointerEvents = 'auto';
|
||||
}
|
||||
|
||||
const currentEngineStr = document.getElementById('engine-val')?.dataset.value || 'MusicFree';
|
||||
if (typeof window.applyEngineUIAndState === 'function') {
|
||||
window.applyEngineUIAndState(currentEngineStr);
|
||||
}
|
||||
if (typeof window.applyEngineUIAndState === 'function') window.applyEngineUIAndState(currentEngineStr);
|
||||
} else {
|
||||
if (searchWrap) searchWrap.classList.remove('show');
|
||||
if (mfSearchWrap) mfSearchWrap.classList.remove('show');
|
||||
if (mfPluginRow) mfPluginRow.classList.remove('show');
|
||||
if (plContainer) plContainer.classList.remove('playlist-container-search');
|
||||
if (gm1Container) gm1Container.style.display = 'flex';
|
||||
}
|
||||
|
||||
// 控制语音搜索歌单、歌曲、歌手的“刷新”按钮显示状态
|
||||
const refreshWrap = document.getElementById('voice-playlist-refresh-wrap');
|
||||
const isVoicePlaylist = (
|
||||
playlistName === '_online_iwebplayer_search' ||
|
||||
playlistName === '_online_play' ||
|
||||
(playlistName.startsWith('_online_') && !playlistName.startsWith('_online_iwp_') && !playlistName.startsWith('_online_lx_') && !playlistName.startsWith('_online_mf_') && playlistName !== '_online_webPush')
|
||||
);
|
||||
if (refreshWrap) {
|
||||
refreshWrap.style.display = isVoicePlaylist ? 'flex' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3656,12 +3685,13 @@
|
||||
});
|
||||
|
||||
const allCleanKeys = Array.from(uniqueBaseNames);
|
||||
const predefinedOrder = ['在线资源', '本地搜索', '所有电台', '所有歌曲', '最近新增', '收藏', '下载'];
|
||||
const predefinedOrder = PREDEFINED_PLAYLISTS;
|
||||
const customKeys = [];
|
||||
|
||||
allCleanKeys.forEach(k => {
|
||||
if (predefinedOrder.includes(k)) return; // 排除系统默认歌单
|
||||
if (k === '_online_iwebplayer_search' || k === '_online_play' || k.startsWith('🎵') || (window.customPlaylistNames && window.customPlaylistNames.includes(k))) {
|
||||
if (k.startsWith('_online_')) return;
|
||||
if (k.startsWith('🎵') || (window.customPlaylistNames && window.customPlaylistNames.includes(k))) {
|
||||
customKeys.push(k);
|
||||
}
|
||||
});
|
||||
@@ -3806,13 +3836,7 @@
|
||||
|
||||
renderPlaylist();
|
||||
|
||||
if (currentPlaylist === '本地搜索' || currentPlaylist === '在线资源') {
|
||||
if (currentPlaylist === '本地搜索') {
|
||||
if (searchSaveBtn) searchSaveBtn.classList.toggle('show', songList.length > 0);
|
||||
} else if (currentPlaylist === '在线资源') {
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.toggle('show', songList.length > 0);
|
||||
}
|
||||
} else {
|
||||
if (currentPlaylist !== '本地搜索' && currentPlaylist !== '在线资源') {
|
||||
if (isOnlineObj) {
|
||||
try {
|
||||
const settingRes = await fetch(API.setting);
|
||||
@@ -4119,7 +4143,6 @@
|
||||
if (voiceOnlineSearchToggle) {
|
||||
voiceOnlineSearchToggle.addEventListener('change', async (e) => {
|
||||
const newState = e.target.checked;
|
||||
// 🌟 实时联动按钮状态
|
||||
updateVoiceSaveBtnState();
|
||||
|
||||
showToast(`⏳ 正在${newState ? '注入' : '移除'}全网搜索指令...`);
|
||||
@@ -4571,7 +4594,6 @@
|
||||
const searchOpt = document.querySelector('#playlist-opts .select-option[data-key="本地搜索"]');
|
||||
if (searchOpt) searchOpt.innerHTML = text;
|
||||
}
|
||||
if (searchSaveBtn) searchSaveBtn.classList.toggle('show', (!keyword ? false : (allPlaylists['本地搜索']||[]).length > 0));
|
||||
}
|
||||
|
||||
function initDeviceDropdown(devicesMap) {
|
||||
@@ -4720,11 +4742,10 @@
|
||||
|
||||
li.innerHTML = formatPlaylistText(key, window.getMergedSongList(key).length);
|
||||
|
||||
// 🌟 修改点:将点击回调改为 async 异步函数
|
||||
li.addEventListener('click', async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
// --- 🚀 新增:特殊歌单实时同步逻辑 ---
|
||||
// 特殊歌单实时同步逻辑 ---
|
||||
const isVoicePlaylist = (
|
||||
key === '_online_iwebplayer_search' ||
|
||||
key === '_online_play' ||
|
||||
@@ -4777,8 +4798,8 @@
|
||||
}
|
||||
};
|
||||
|
||||
const predefinedOrder = ['在线资源', '本地搜索', '所有电台', '所有歌曲', '最近新增', '收藏', '下载'];
|
||||
const hiddenPlaylists = ['全部', '_local_iwebplayer_search', '_online_webPush'];
|
||||
const predefinedOrder = PREDEFINED_PLAYLISTS;
|
||||
const hiddenPlaylists = ['全部', '_local_iwebplayer_search', '_online_webPush', 'cache_songs'];
|
||||
|
||||
if (window.getMergedSongList('其他').length === 0) hiddenPlaylists.push('其他');
|
||||
if (window.getMergedSongList('下载').length === 0) hiddenPlaylists.push('下载');
|
||||
@@ -4839,6 +4860,14 @@
|
||||
localFolderKeys.forEach(key => createOpt(key));
|
||||
}
|
||||
|
||||
if (allCleanKeys.includes('cache_songs')) {
|
||||
if (playlistOpts.lastElementChild) playlistOpts.lastElementChild.style.borderBottom = 'none';
|
||||
const sep = document.createElement('li');
|
||||
sep.style.cssText = 'height: 1px; background: var(--border); margin: 6px 16px; cursor: default; box-sizing: content-box;';
|
||||
playlistOpts.appendChild(sep);
|
||||
createOpt('cache_songs');
|
||||
}
|
||||
|
||||
if (defaultKey) {
|
||||
currentPlaylist = defaultKey;
|
||||
playlistVal.innerHTML = formatPlaylistText(defaultKey, window.getMergedSongList(defaultKey).length);
|
||||
@@ -5202,8 +5231,6 @@
|
||||
if (document.visibilityState === 'visible') {
|
||||
scrollToCurrentSong();
|
||||
|
||||
// 🌟 核心修复:监听从后台切回前台的瞬间
|
||||
// 如果是在本机模式,且有选中的歌曲,且发现 src 被后台清空了,立刻重新静默拉取!
|
||||
if (currentDid === "" && currentIndex !== -1) {
|
||||
const isSrcEmpty = !audioEl.src || audioEl.src === window.location.href || audioEl.src.includes('blob:');
|
||||
if (audioEl.paused && isSrcEmpty) {
|
||||
@@ -5221,6 +5248,11 @@
|
||||
const mfPluginContainer = document.getElementById('mf-plugin-container');
|
||||
const mfPluginVal = document.getElementById('mf-plugin-val');
|
||||
|
||||
const gm1Btn = document.getElementById('global-menu-1-btn');
|
||||
const gm1Opts = document.getElementById('global-menu-1-opts');
|
||||
const gm2Btn = document.getElementById('global-menu-2-btn');
|
||||
const gm2Opts = document.getElementById('global-menu-2-opts');
|
||||
|
||||
const closeAllDropdownsExcept = (exceptId) => {
|
||||
if (exceptId !== 'device-opts') deviceOpts.classList.remove('show');
|
||||
if (exceptId !== 'playlist-opts') playlistOpts.classList.remove('show');
|
||||
@@ -5228,10 +5260,42 @@
|
||||
if (exceptId !== 'mf-plugin-opts' && mfOpts) mfOpts.classList.remove('show');
|
||||
if (exceptId !== 'engine-opts' && engineOpts) engineOpts.classList.remove('show');
|
||||
|
||||
if (exceptId !== 'global-menu-1-opts' && gm1Opts) gm1Opts.classList.remove('show');
|
||||
if (exceptId !== 'global-menu-2-opts' && gm2Opts) gm2Opts.classList.remove('show');
|
||||
|
||||
const historyList = document.getElementById('mf-search-history-list');
|
||||
if (historyList) historyList.classList.remove('show');
|
||||
};
|
||||
|
||||
const checkGridMode = () => document.getElementById('playlist-grid')?.style.display !== 'none';
|
||||
|
||||
if (gm1Btn) {
|
||||
gm1Btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
closeAllDropdownsExcept('global-menu-1-opts');
|
||||
|
||||
// 动态给菜单 1 的“创建/加入”变灰
|
||||
document.querySelectorAll('#global-menu-1-opts .global-add-btn').forEach(btn => {
|
||||
checkGridMode() ? btn.classList.add('disabled') : btn.classList.remove('disabled');
|
||||
});
|
||||
|
||||
gm1Opts.classList.toggle('show');
|
||||
});
|
||||
}
|
||||
if (gm2Btn) {
|
||||
gm2Btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
closeAllDropdownsExcept('global-menu-2-opts');
|
||||
|
||||
// 动态给菜单 2 的“创建/加入”变灰
|
||||
document.querySelectorAll('#global-menu-2-opts .global-add-btn').forEach(btn => {
|
||||
checkGridMode() ? btn.classList.add('disabled') : btn.classList.remove('disabled');
|
||||
});
|
||||
|
||||
gm2Opts.classList.toggle('show');
|
||||
});
|
||||
}
|
||||
|
||||
deviceVal.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
closeAllDropdownsExcept('device-opts');
|
||||
@@ -5293,6 +5357,9 @@
|
||||
if (mfOpts && !e.target.closest('#mf-plugin-container')) mfOpts.classList.remove('show');
|
||||
if (engineOpts && !e.target.closest('#engine-container')) engineOpts.classList.remove('show');
|
||||
|
||||
if (gm1Opts && !e.target.closest('#global-menu-1-container')) gm1Opts.classList.remove('show');
|
||||
if (gm2Opts && !e.target.closest('#global-menu-2-container')) gm2Opts.classList.remove('show');
|
||||
|
||||
const historyList = document.getElementById('mf-search-history-list');
|
||||
if (historyList && !e.target.closest('#mf-search-input-wrap')) historyList.classList.remove('show');
|
||||
|
||||
@@ -5330,6 +5397,50 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 语音歌单快捷“刷新”数据交互核心
|
||||
const voiceRefreshBtn = document.getElementById('voice-playlist-refresh-btn');
|
||||
if (voiceRefreshBtn) {
|
||||
voiceRefreshBtn.addEventListener('click', async (e) => {
|
||||
e.stopPropagation();
|
||||
if (!currentPlaylist) return;
|
||||
|
||||
// 变成加载状态,防止用户鬼畜连击
|
||||
const originalHtml = voiceRefreshBtn.innerHTML;
|
||||
voiceRefreshBtn.innerHTML = "同步中...";
|
||||
voiceRefreshBtn.disabled = true;
|
||||
voiceRefreshBtn.style.opacity = "0.6";
|
||||
|
||||
try {
|
||||
// 1. 重新调用核心函数:从后台获取最新的全量曲库与状态
|
||||
await reloadGlobalData();
|
||||
|
||||
// 2. 刷新当前选中语音列表的数据池
|
||||
songList = window.getMergedSongList(currentPlaylist);
|
||||
|
||||
// 3. 重新渲染屏幕列表
|
||||
renderPlaylist();
|
||||
|
||||
// 4. 同步修正顶部选择框的数值和文案
|
||||
const newText = formatPlaylistText(currentPlaylist, songList.length);
|
||||
if (playlistVal) playlistVal.innerHTML = newText;
|
||||
|
||||
// 5. 更新下拉抽屉里对应选项的缓存文案
|
||||
const opt = document.querySelector(`#playlist-opts .select-option[data-key="${currentPlaylist}"]`);
|
||||
if (opt) opt.innerHTML = newText;
|
||||
|
||||
showToast("✅ 语音交互结果已同步更新");
|
||||
} catch (err) {
|
||||
console.error("语音歌单异步刷新失败:", err);
|
||||
showToast("❌ 同步失败,请稍后重试");
|
||||
} finally {
|
||||
// 还原按钮
|
||||
voiceRefreshBtn.innerHTML = originalHtml;
|
||||
voiceRefreshBtn.disabled = false;
|
||||
voiceRefreshBtn.style.opacity = "1";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settingRefreshBtn) {
|
||||
settingRefreshBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
@@ -5477,7 +5588,7 @@
|
||||
if (audioEl.paused) {
|
||||
audioEl.play();
|
||||
} else {
|
||||
// 🌟 给系统发通行证:证明这个暂停是 btn-play 触发的
|
||||
// 给系统发通行证:证明这个暂停是 btn-play 触发的
|
||||
window.isPageBtnPause = true;
|
||||
audioEl.pause();
|
||||
// 0.2秒后立刻销毁通行证,防止影响后续真实的锁屏暂停
|
||||
@@ -6020,7 +6131,7 @@
|
||||
const autoAddToggle = document.getElementById('voice-auto-add-toggle');
|
||||
if (autoAddToggle) autoAddToggle.checked = !!data.data.auto_add_song;
|
||||
|
||||
// 🌟 核心修改:从下拉框赋值改为勾选对应的单选按钮
|
||||
// 从下拉框赋值改为勾选对应的单选按钮
|
||||
const strategyVal = data.data.voice_playlist_strategy || 'default';
|
||||
const strategyRadio = document.querySelector(`input[name="voice-strategy"][value="${strategyVal}"]`);
|
||||
if (strategyRadio) strategyRadio.checked = true;
|
||||
@@ -6364,7 +6475,7 @@
|
||||
window.addOnlineSearchHistory = function(itemObj) {
|
||||
let history = JSON.parse(localStorage.getItem('online_search_history_list') || '[]');
|
||||
|
||||
// 🌟 核心优化:只有具体的歌单(detail)和分类标签(tag)才绑定平台身份!打字搜歌/搜单不绑定
|
||||
// 只有具体的歌单(detail)和分类标签(tag)才绑定平台身份!打字搜歌/搜单不绑定
|
||||
if (itemObj.type === 'detail' || itemObj.type === 'tag') {
|
||||
itemObj.engine = document.getElementById('engine-val')?.dataset.value || 'MusicFree';
|
||||
}
|
||||
@@ -6399,7 +6510,7 @@
|
||||
historyHtml = history.slice(0, 10).map((item, idx) => {
|
||||
if (item.type === 'detail' || item.type === 'tag') {
|
||||
const sourceName = LX_PLATFORMS_MAP[item.source] || item.source;
|
||||
// 🌟 渲染:根据 engine 属性给历史胶囊上色
|
||||
// 根据 engine 属性给历史胶囊上色
|
||||
const themeClass = item.engine === 'LXServer' ? 'lx-theme' : 'mf-theme';
|
||||
return `
|
||||
<li class="history-item" data-index="${idx}">
|
||||
@@ -6470,7 +6581,7 @@
|
||||
e.stopPropagation();
|
||||
const item = history[li.dataset.index];
|
||||
|
||||
// 🌟 核心优化:只有胶囊(具体歌单或标签)才强制切回它所属的引擎。关键词直接用当前引擎!
|
||||
// 只有胶囊(具体歌单或标签)才强制切回它所属的引擎。关键词直接用当前引擎!
|
||||
if ((item.type === 'detail' || item.type === 'tag') && item.engine) {
|
||||
window.applyEngineUIAndState(item.engine);
|
||||
}
|
||||
@@ -6615,11 +6726,10 @@
|
||||
document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input'));
|
||||
}
|
||||
|
||||
// 🌟 根据 apiType 切换胶囊颜色类名
|
||||
// 根据 apiType 切换胶囊颜色类名
|
||||
const currentEngine = apiType === 1 ? 'MusicFree' : 'LXServer';
|
||||
capsule.className = `search-tag-capsule ${apiType === 1 ? 'mf-theme' : 'lx-theme'}`;
|
||||
|
||||
// 🌟 核心修复:把你之前不小心弄丢的这行代码补回来!把点进去的具体歌单存入历史记录
|
||||
window.addOnlineSearchHistory({ type: 'detail', id: id, name: name, source: source });
|
||||
|
||||
// 控制提示词和清空搜歌文字
|
||||
@@ -6655,7 +6765,7 @@
|
||||
if (resJson.success && resJson.data && resJson.data.length > 0) {
|
||||
songList = resJson.data;
|
||||
|
||||
// 🌟 核心修复:在详情缓存里记录 engine
|
||||
// 在详情缓存里记录 engine
|
||||
localStorage.setItem('lx_detail_cache', JSON.stringify({
|
||||
engine: currentEngine, // 存入身份
|
||||
type: 'detail',
|
||||
@@ -6666,12 +6776,7 @@
|
||||
}));
|
||||
|
||||
if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(true);
|
||||
|
||||
renderPlaylist();
|
||||
|
||||
const mfSearchSaveBtn = document.getElementById('mf-search-save');
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.add('show');
|
||||
|
||||
const playlistVal = document.getElementById('playlist-val');
|
||||
const text = formatPlaylistText('在线资源', songList.length);
|
||||
if (playlistVal) playlistVal.innerHTML = text;
|
||||
@@ -6708,7 +6813,7 @@
|
||||
|
||||
const currentEngine = document.getElementById('engine-val')?.dataset.value || 'MusicFree';
|
||||
const apiType = currentEngine === 'LXServer' ? 2 : 1;
|
||||
// 🌟 加载 SVG 的动态颜色
|
||||
// 加载 SVG 的动态颜色
|
||||
const themeColor = currentEngine === 'LXServer' ? '#10b981' : 'var(--primary)';
|
||||
|
||||
// 核心判断:如果是打字搜歌单,处理历史记录和UI
|
||||
@@ -6727,7 +6832,6 @@
|
||||
}
|
||||
} else if (type === 'tag' && !isLoadMore) {
|
||||
localStorage.removeItem('lx_detail_cache');
|
||||
// 🌟 响应你的需求:仅仅清除旧的详情缓存,不再把标签当做历史记录存入
|
||||
}
|
||||
|
||||
// 胶囊(tag)直接走LX源地址,文字搜歌单(keyword)走XiaoMusic后端桥接!
|
||||
@@ -6745,7 +6849,7 @@
|
||||
window.hasMoreLxPlaylists = true;
|
||||
list.style.display = 'none';
|
||||
grid.style.display = 'grid';
|
||||
// 🌟 修复转圈动画颜色
|
||||
|
||||
grid.innerHTML = `<div style="text-align: center; padding: 60px; color: var(--text-sub); font-size: 14px; grid-column: 1 / -1;"><svg style="animation: spin-hourglass 1.5s cubic-bezier(0.4, 0, 0.2, 1) infinite; vertical-align:-3px; margin-right:6px; color: ${themeColor};" viewBox="0 0 24 24" width="18" height="18" stroke="currentColor" stroke-width="2" fill="none"><path d="M12 2v20"></path><path d="M5 2h14"></path><path d="M5 22h14"></path><path d="M5 6l7 6 7-6"></path><path d="M5 18l7-6 7 6"></path></svg>正在拉取歌单海报...</div>`;
|
||||
} else {
|
||||
window.currentLxPlaylistPage++;
|
||||
@@ -6787,7 +6891,7 @@
|
||||
|
||||
if (targetList.length < targetLimit) window.hasMoreLxPlaylists = false;
|
||||
|
||||
// 🌟 核心:存入专属的海报墙抽屉时带上引擎身份
|
||||
// 存入专属的海报墙抽屉时带上引擎身份
|
||||
localStorage.setItem('lx_grid_cache', JSON.stringify({
|
||||
engine: currentEngine, // 存入引擎身份
|
||||
type: type === 'keyword' ? 'playlist' : 'tag',
|
||||
@@ -6979,7 +7083,6 @@
|
||||
|
||||
renderPlaylist();
|
||||
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.add('show');
|
||||
const text = formatPlaylistText('在线资源', songList.length);
|
||||
playlistVal.innerHTML = text;
|
||||
const mfOpt = document.querySelector('#playlist-opts .select-option[data-key="在线资源"]');
|
||||
@@ -7086,7 +7189,7 @@
|
||||
}
|
||||
if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(false);
|
||||
|
||||
// 🌟 修复返回错乱:读取网格缓存的真实引擎身份,没记录就用当前引擎
|
||||
// 读取网格缓存的真实引擎身份,没记录就用当前引擎
|
||||
const targetEngine = gridCache.engine || document.getElementById('engine-val')?.dataset.value || 'MusicFree';
|
||||
window.applyEngineUIAndState(targetEngine);
|
||||
} else {
|
||||
@@ -7162,6 +7265,20 @@
|
||||
|
||||
const handleBulkAddClick = (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
// 触发点击时,顺手把菜单收起来
|
||||
const gm1Opts = document.getElementById('global-menu-1-opts');
|
||||
const gm2Opts = document.getElementById('global-menu-2-opts');
|
||||
if (gm1Opts) gm1Opts.classList.remove('show');
|
||||
if (gm2Opts) gm2Opts.classList.remove('show');
|
||||
|
||||
// 拦截“歌单海报墙(Grid)”模式的点击,弹出专属提示
|
||||
const isGridMode = document.getElementById('playlist-grid')?.style.display !== 'none';
|
||||
if (isGridMode) {
|
||||
showToast("⚠️ 需要进入歌曲列表模式");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!songList || songList.length === 0) { showToast("当前列表为空,无法加入"); return; }
|
||||
|
||||
if (window.skipAddConfirm && window.lastAddedPlaylist) {
|
||||
@@ -7169,12 +7286,43 @@
|
||||
return;
|
||||
}
|
||||
|
||||
window.pendingBulkAdd = true;
|
||||
window.pendingBulkAdd = true;window.pendingBulkAdd = true;
|
||||
window.pendingAddIndex = -1;
|
||||
|
||||
const nameSpan = document.getElementById('add-song-name');
|
||||
if (nameSpan) nameSpan.textContent = `当前列表 (共 ${songList.length} 首)`;
|
||||
|
||||
// 智能抓取当前上下文的名称,并预填到输入框中
|
||||
const newPlaylistInput = document.getElementById('add-new-playlist-input');
|
||||
if (newPlaylistInput) {
|
||||
let defaultName = currentPlaylist;
|
||||
|
||||
if (currentPlaylist === '在线资源') {
|
||||
// 如果是在线资源,优先抓取搜索胶囊里的完整名称(title存了未截断的全名)
|
||||
const capsule = document.getElementById('search-tag-capsule');
|
||||
if (capsule && capsule.title) {
|
||||
defaultName = capsule.title;
|
||||
} else if (capsule && capsule.innerText) {
|
||||
defaultName = capsule.innerText.trim();
|
||||
} else {
|
||||
const mfInput = document.getElementById('mf-search-input');
|
||||
if (mfInput && mfInput.value) defaultName = mfInput.value.trim();
|
||||
}
|
||||
} else if (currentPlaylist === '本地搜索') {
|
||||
// 如果是本地搜索,抓取搜索框里的关键词
|
||||
const localInput = document.getElementById('search-input');
|
||||
if (localInput && localInput.value) defaultName = localInput.value.trim();
|
||||
} else {
|
||||
// 如果是普通歌单,使用系统自带的解析函数去掉“🎵”等前缀
|
||||
if (typeof window.getDisplayPlaylistName === 'function') {
|
||||
defaultName = window.getDisplayPlaylistName(currentPlaylist);
|
||||
}
|
||||
}
|
||||
|
||||
// 将抓取到的名字填入输入框
|
||||
newPlaylistInput.value = defaultName;
|
||||
}
|
||||
|
||||
const listEl = document.getElementById('add-song-playlist-list');
|
||||
if (listEl) window.renderPlaylistRadioList(listEl);
|
||||
if (addSongModal) {
|
||||
@@ -7184,8 +7332,20 @@
|
||||
}
|
||||
};
|
||||
|
||||
if (searchSaveBtn) searchSaveBtn.addEventListener('click', handleBulkAddClick);
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.addEventListener('click', handleBulkAddClick);
|
||||
document.querySelectorAll('.global-add-btn').forEach(btn => {
|
||||
btn.addEventListener('click', handleBulkAddClick);
|
||||
});
|
||||
|
||||
document.querySelectorAll('.global-dev-btn').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const gm1Opts = document.getElementById('global-menu-1-opts');
|
||||
const gm2Opts = document.getElementById('global-menu-2-opts');
|
||||
if (gm1Opts) gm1Opts.classList.remove('show');
|
||||
if (gm2Opts) gm2Opts.classList.remove('show');
|
||||
showToast("努力开发中 🚀");
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -7309,7 +7469,6 @@
|
||||
const mfPluginVal = document.getElementById('mf-plugin-val');
|
||||
const mfPluginOpts = document.getElementById('mf-plugin-opts');
|
||||
const mfSearchBtn = document.getElementById('mf-search-btn');
|
||||
const mfSearchSaveBtn = document.getElementById('mf-search-save');
|
||||
|
||||
if (!engineVal || !engineOpts) return;
|
||||
engineVal.dataset.value = targetVal;
|
||||
@@ -7323,7 +7482,6 @@
|
||||
if (mfPluginVal) mfPluginVal.classList.remove('text-mf', 'text-lx');
|
||||
if (mfPluginOpts) mfPluginOpts.classList.remove('lx-opts');
|
||||
if (mfSearchBtn) mfSearchBtn.classList.remove('bg-mf', 'bg-lx');
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.remove('bg-mf', 'bg-lx');
|
||||
|
||||
const mfSearchInput = document.getElementById('mf-search-input');
|
||||
const mfSearchClear = document.getElementById('mf-search-clear');
|
||||
@@ -7337,13 +7495,11 @@
|
||||
engineVal.classList.add('text-lx');
|
||||
if (mfPluginVal) mfPluginVal.classList.add('text-lx');
|
||||
if (mfPluginOpts) mfPluginOpts.classList.add('lx-opts');
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.add('bg-lx');
|
||||
const currentSource = document.getElementById('mf-plugin-val')?.dataset.value || 'tx';
|
||||
if (typeof window.fetchLxTags === 'function') window.fetchLxTags(currentSource);
|
||||
} else {
|
||||
engineVal.classList.add('text-mf');
|
||||
if (mfPluginVal) mfPluginVal.classList.add('text-mf');
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.add('bg-mf');
|
||||
}
|
||||
|
||||
if (typeof renderSearchPluginDropdown === 'function') renderSearchPluginDropdown(targetVal);
|
||||
@@ -7360,7 +7516,7 @@
|
||||
if (playlistBtn) playlistBtn.style.display = 'block';
|
||||
if (searchDivider) searchDivider.style.display = 'block';
|
||||
|
||||
// 🌟 统一缓存恢复核心逻辑:双方都认同引擎身份牌
|
||||
// 统一缓存恢复核心逻辑:双方都认同引擎身份牌
|
||||
try {
|
||||
const detailCache = JSON.parse(localStorage.getItem('lx_detail_cache'));
|
||||
const gridCache = JSON.parse(localStorage.getItem('lx_grid_cache'));
|
||||
@@ -7490,8 +7646,6 @@
|
||||
const text = formatPlaylistText('在线资源', (window.lxPlaylistItems || []).length);
|
||||
if (playlistVal) playlistVal.innerHTML = text;
|
||||
}
|
||||
|
||||
if (mfSearchSaveBtn) mfSearchSaveBtn.classList.toggle('show', songList.length > 0 && mode !== 'playlist' && mode !== 'tag');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7658,9 +7812,106 @@
|
||||
window.migrateOldPlaylists(false);
|
||||
});
|
||||
|
||||
// GitHub 远端版本自动探针检测与云控配置
|
||||
function checkRemoteVersion() {
|
||||
// 拼接时间戳 t=... 强行打破 GitHub 静态文件的 CDN 缓存,确保获取最新数据
|
||||
const versionUrl = "https://raw.githubusercontent.com/birdstudy-nj/iWebPlayer/main/version.json?t=" + new Date().getTime();
|
||||
|
||||
fetch(versionUrl)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (!data) return;
|
||||
|
||||
// 1. 新版本红点菜单检测逻辑
|
||||
if (data.latest_version && data.latest_version !== APP_VERSION) {
|
||||
const optsUl = document.getElementById('settings-opts');
|
||||
if (optsUl) {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'select-option';
|
||||
li.id = 'setting-remote-update';
|
||||
const rocketSvg = `<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right:6px; vertical-align:-2px;"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"></path><path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"></path><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"></path><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"></path></svg>`;
|
||||
li.innerHTML = `${rocketSvg} 发现${data.latest_version}`;
|
||||
li.style.color = 'var(--primary)';
|
||||
li.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (data.download_url) window.open(data.download_url, '_blank');
|
||||
optsUl.classList.remove('show');
|
||||
});
|
||||
optsUl.appendChild(li);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 云控公告与二维码动态注入逻辑
|
||||
if (data.dynamic_notice && data.dynamic_notice.enable) {
|
||||
const noticeWrapper = document.getElementById('remote-notice-wrapper');
|
||||
if (noticeWrapper) {
|
||||
let htmlStr = '';
|
||||
|
||||
// 渲染标题
|
||||
if (data.dynamic_notice.title) {
|
||||
htmlStr += `<div style="font-size: 14px; font-weight: bold; margin-bottom: 6px; color: var(--text-main);">${data.dynamic_notice.title}</div>`;
|
||||
}
|
||||
// 渲染富文本内容
|
||||
if (data.dynamic_notice.html_content) {
|
||||
htmlStr += `<div style="font-size: 13.5px; line-height: 1.7; color: var(--text-sub); margin-bottom: 12px;">${data.dynamic_notice.html_content}</div>`;
|
||||
}
|
||||
// 渲染精致的二维码微卡片
|
||||
if (data.dynamic_notice.qr_code_url) {
|
||||
htmlStr += `
|
||||
<div style="display: flex; justify-content: center; margin-bottom: 4px;">
|
||||
<div style="background: var(--bg-color); border: 1px solid var(--border); border-radius: 12px; padding: 10px; width: 140px; height: 140px; box-shadow: 0 4px 10px rgba(0,0,0,0.02); display: flex; align-items: center; justify-content: center;">
|
||||
<img src="${data.dynamic_notice.qr_code_url}" alt="QR Code" style="width: 100%; height: 100%; object-fit: contain; border-radius: 6px;">
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
noticeWrapper.innerHTML = htmlStr;
|
||||
noticeWrapper.style.display = 'block'; // 彻底激活并显示
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => console.log("远端检测或配置拉取失败:", err));
|
||||
}
|
||||
|
||||
// 本地后端 HTML 版本静默探测与自动热更
|
||||
function checkLocalVersionUpdate() {
|
||||
// 发送一个带时间戳的请求,绕过 iOS 缓存,直接偷看后端服务器上真实的 HTML 源码
|
||||
fetch(window.location.pathname + '?t=' + Date.now(), { cache: 'no-store' })
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
// 用正则精准提取服务器上那份 HTML 里的 APP_VERSION
|
||||
const match = html.match(/const APP_VERSION = ['"](.*?)['"]/);
|
||||
if (match && match[1] && match[1] !== APP_VERSION) {
|
||||
const newVersion = match[1];
|
||||
const lastAttempt = localStorage.getItem('iwp_update_attempt');
|
||||
|
||||
if (lastAttempt !== newVersion) {
|
||||
// 第一次发现新版:记录并尝试强制刷新破除缓存
|
||||
localStorage.setItem('iwp_update_attempt', newVersion);
|
||||
showToast(`🚀 发现后端已更新至 ${newVersion},正在自动为您刷新...`, true);
|
||||
|
||||
setTimeout(() => {
|
||||
// 强制重载,尝试打破 iOS WebClip 的缓存层
|
||||
window.location.reload(true);
|
||||
}, 2000);
|
||||
} else {
|
||||
// 已经尝试过刷新,但页面依然是旧版,说明 iOS 发生了“底层缓存死锁”
|
||||
// 此时绝不能再刷新(防死循环),只弹窗提醒用户手动重装
|
||||
showToast(`⚠️ 后端已是 ${newVersion},但 iOS 缓存固化。请重新生成桌面配置!`, true);
|
||||
}
|
||||
} else if (match && match[1] === APP_VERSION) {
|
||||
// 如果版本一致,说明当前就是最新版,或者刚刚的热更成功了,清除防死循环标记
|
||||
localStorage.removeItem('iwp_update_attempt');
|
||||
}
|
||||
})
|
||||
.catch(err => console.log("本地更新探针检测失败:", err));
|
||||
}
|
||||
|
||||
async function init() {
|
||||
renderLogos();
|
||||
bindAllEvents();
|
||||
checkRemoteVersion();
|
||||
checkLocalVersionUpdate();
|
||||
|
||||
window.currentEngineType = 1; // 默认 1=MF, 2=LX
|
||||
|
||||
|
||||
Reference in New Issue
Block a user