From 4eed250767b7dd811e53d965ec89dd47dbae02f8 Mon Sep 17 00:00:00 2001 From: birdstudy-nj Date: Thu, 30 Apr 2026 18:25:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E7=AB=AF=E6=96=B0=E5=A2=9EMus?= =?UTF-8?q?icFree=E6=90=9C=E7=B4=A2=E6=AD=8C=E5=8D=95=E5=8A=9F=E8=83=BD=20?= =?UTF-8?q?(#849)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xiaomusic/static/iwebplayer/iwebplayer.html | 476 ++++++++++++-------- 1 file changed, 283 insertions(+), 193 deletions(-) diff --git a/xiaomusic/static/iwebplayer/iwebplayer.html b/xiaomusic/static/iwebplayer/iwebplayer.html index a921f62..1ac1f54 100644 --- a/xiaomusic/static/iwebplayer/iwebplayer.html +++ b/xiaomusic/static/iwebplayer/iwebplayer.html @@ -1339,12 +1339,9 @@ box-shadow: 0 4px 10px rgba(16, 185, 129, 0.3); } - .search-tag-capsule { +.search-tag-capsule { display: inline-flex; align-items: center; - background: rgba(16, 185, 129, 0.1); - color: #10b981; - border: 1px solid rgba(16, 185, 129, 0.3); font-size: 13px; padding: 2px 8px; border-radius: 10px; @@ -1352,7 +1349,19 @@ flex-shrink: 0; user-select: none; animation: fadeIn 0.15s ease-out; - } +} +/* LX Server 绿色主题 */ +.search-tag-capsule.lx-theme { + background: rgba(16, 185, 129, 0.1); + color: #10b981; + border: 1px solid rgba(16, 185, 129, 0.3); +} +/* MusicFree 紫红色主题 */ +.search-tag-capsule.mf-theme { + background: rgba(236, 72, 153, 0.1); + color: var(--primary); + border: 1px solid rgba(236, 72, 153, 0.3); +} .search-text-group { display: flex; @@ -2056,7 +2065,7 @@ /* ========================================== * 1. 核心配置与全局状态 * ========================================== */ - const APP_VERSION = 'v1.7.1'; + const APP_VERSION = 'v1.7.2'; const APP_LOGO = document.getElementById('app-logo')?.content || ''; const LX_PLATFORMS_MAP = { 'tx': 'QQ', 'wy': '网易云', 'kg': '酷狗', 'kw': '酷我', 'mg': '咪咕' }; const LX_BACKEND_NAMES = { 'tx': '小秋音乐', 'wy': '小芸音乐', 'kg': '小枸音乐', 'kw': '小蜗音乐', 'mg': '小蜜音乐' }; @@ -5008,7 +5017,20 @@ * ========================================== */ function bindAllEvents() { document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') scrollToCurrentSong(); + 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) { + console.log('🔙 App切回前台,检测到音频源为空,触发静默预热...'); + const resumeTime = parseFloat(localStorage.getItem('standalone_resume_time')) || 0; + playSong(currentIndex, false, resumeTime); + } + } + } }); const mfOpts = document.getElementById('mf-plugin-opts'); @@ -5269,8 +5291,16 @@ if (currentDid !== "") { playSong(currentIndex); } else { - if (audioEl.paused) audioEl.play(); - else audioEl.pause(); + // 如果 src 还在,执行正常的播放/暂停 + if (audioEl.paused) { + audioEl.play(); + } else { + // 🌟 给系统发通行证:证明这个暂停是 btn-play 触发的 + window.isPageBtnPause = true; + audioEl.pause(); + // 0.2秒后立刻销毁通行证,防止影响后续真实的锁屏暂停 + setTimeout(() => { window.isPageBtnPause = false; }, 200); + } } }); @@ -6121,9 +6151,15 @@ window.addOnlineSearchHistory = function(itemObj) { let history = JSON.parse(localStorage.getItem('online_search_history_list') || '[]'); - // 去重:如果是特定歌单,根据 id 和 source 去重;否则按 keyword 去重 + + // 🌟 核心优化:只有具体的歌单(detail)和分类标签(tag)才绑定平台身份!打字搜歌/搜单不绑定 + if (itemObj.type === 'detail' || itemObj.type === 'tag') { + itemObj.engine = document.getElementById('engine-val')?.dataset.value || 'MusicFree'; + } + history = history.filter(item => { if (itemObj.type === 'detail') return !(item.type === 'detail' && item.id === itemObj.id && item.source === itemObj.source); + if (itemObj.type === 'tag') return !(item.type === 'tag' && item.name === itemObj.name && item.source === itemObj.source); return !(item.type === itemObj.type && item.keyword === itemObj.keyword); }); history.unshift(itemObj); @@ -6151,9 +6187,11 @@ 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 属性给历史胶囊上色 + const themeClass = item.engine === 'LXServer' ? 'lx-theme' : 'mf-theme'; return `
  • -
    ${item.name} (${sourceName})
    +
    ${item.name} (${sourceName})
  • `; } else { let iconSvg = item.type === 'playlist' @@ -6182,7 +6220,6 @@ const sortList = window.lxTagsCache[source] || []; if (sortList.length > 0) { - if (window.currentLxSortId && !sortList.some(s => s.id == window.currentLxSortId)) window.currentLxSortId = null; const tagsHtml = sortList.map(item => `
    ${item.name}
    @@ -6197,7 +6234,7 @@ if (!capsule) { capsule = document.createElement('div'); capsule.id = 'search-tag-capsule'; - capsule.className = 'search-tag-capsule'; + capsule.className = 'search-tag-capsule lx-theme'; document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); } capsule.innerText = pill.innerText; @@ -6220,6 +6257,12 @@ li.addEventListener('click', (e) => { e.stopPropagation(); const item = history[li.dataset.index]; + + // 🌟 核心优化:只有胶囊(具体歌单或标签)才强制切回它所属的引擎。关键词直接用当前引擎! + if ((item.type === 'detail' || item.type === 'tag') && item.engine) { + window.applyEngineUIAndState(item.engine); + } + historyList.classList.remove('show'); if (item.type === 'detail') { const currentSource = document.getElementById('mf-plugin-val')?.dataset.value; @@ -6227,7 +6270,25 @@ const sourceOpt = document.querySelector(`#mf-plugin-opts .select-option[data-value="${item.source}"]`); if (sourceOpt) sourceOpt.click(); } - window.triggerPlaylistDetail(item.id, item.name, item.source); + window.triggerPlaylistDetail(item.id, item.name, item.source, item.engine === 'LXServer' ? 2 : 1); + } else if (item.type === 'tag') { + const currentSource = document.getElementById('mf-plugin-val')?.dataset.value; + if (currentSource !== item.source && currentSource !== 'all') { + const sourceOpt = document.querySelector(`#mf-plugin-opts .select-option[data-value="${item.source}"]`); + if (sourceOpt) sourceOpt.click(); + } + window.currentLxSortId = item.sortId || ''; + let capsule = document.getElementById('search-tag-capsule'); + if (!capsule) { + capsule = document.createElement('div'); + capsule.id = 'search-tag-capsule'; + capsule.className = `search-tag-capsule ${item.engine === 'LXServer' ? 'lx-theme' : 'mf-theme'}`; + document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); + } + capsule.innerText = item.name; + if (mfSearchInput) { mfSearchInput.placeholder = ''; mfSearchInput.value = ''; } + if (mfSearchClear) mfSearchClear.classList.add('show'); + window.doLxPlaylistSearch(false, 'tag'); } else { const capsule = document.getElementById('search-tag-capsule'); if (capsule) { capsule.remove(); window.currentLxSortId = null; mfSearchInput.placeholder = '搜全网资源...'; } @@ -6330,8 +6391,7 @@ // ========================================== // 点击特定歌单 -> 进详情 // ========================================== - window.triggerPlaylistDetail = async function(id, name, source) { - // 点击进歌单前,先记录当前在海报墙滚到了多高 + window.triggerPlaylistDetail = async function(id, name, source, apiType = 2) { localStorage.setItem('lx_grid_scroll_y', window.scrollY); let capsule = document.getElementById('search-tag-capsule'); @@ -6342,51 +6402,49 @@ document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); } + // 🌟 根据 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 }); + + // 控制提示词和清空搜歌文字 const searchBox = document.getElementById('mf-search-input-wrap'); - const boxWidth = searchBox ? searchBox.clientWidth : window.innerWidth; - let maxChars = 18; - if (boxWidth <= 370) { - // 如果搜索框本身的宽度被挤压到了 350 像素以内 - maxChars = 14; - } + const boxWidth = searchBox?.clientWidth || window.innerWidth; + let maxChars = (boxWidth <= 370 || window.innerWidth <= 480) ? 14 : 18; const shortName = name.length > maxChars ? name.substring(0, maxChars) + '...' : name; capsule.innerText = shortName; - capsule.title = name; // 鼠标悬停显示全名 - capsule.dataset.id = id; - capsule.dataset.source = source; - mfSearchInput.placeholder = ''; - mfSearchInput.value = ''; - // 进入歌单详情瞬间,不需要显示 X 按钮(由右侧返回按钮接管退路) - document.getElementById('mf-search-clear')?.classList.remove('show'); + capsule.title = name; + + if (mfSearchInput) { + mfSearchInput.placeholder = ''; + mfSearchInput.value = ''; + } + if (mfSearchClear) mfSearchClear.classList.add('show'); + + const historyList = document.getElementById('mf-search-history-list'); + if (historyList) historyList.classList.remove('show'); const grid = document.getElementById('playlist-grid'); const list = document.getElementById('playlist'); if (grid) grid.style.display = 'none'; if (list) { list.style.display = 'block'; - - list.innerHTML = '
    正在拉取歌单歌曲,请稍候...
    '; + list.innerHTML = '
    正在获取歌单详情...
    '; } + window.scrollTo({ top: 0, behavior: 'smooth' }); - window.addOnlineSearchHistory({ type: 'detail', name: name, id: id, source: source }); - - // 调用后端刚写好的真实接口 try { - // 请求参数:id, plugin(即source), api_type=2 (强制指定 LX Server) - const res = await fetch(`/api/search/online_playlist_detail?id=${encodeURIComponent(id)}&plugin=${encodeURIComponent(source)}&api_type=2`); + const res = await fetch(`/api/search/online_playlist_detail?id=${encodeURIComponent(id)}&plugin=${encodeURIComponent(source)}&api_type=${apiType}`); const resJson = await res.json(); if (resJson.success && resJson.data && resJson.data.length > 0) { - onlineMusicItems = resJson.data; - songList = [...onlineMusicItems]; - allPlaylists['在线资源'] = songList; + songList = resJson.data; - // 歌单详情是一次性全量返回,所以关闭分页功能 - currentSearchPage = 1; - hasMoreOnlineSearch = false; - - // 存入专属的详情抽屉 (lx_detail_cache) + // 🌟 核心修复:在详情缓存里记录 engine localStorage.setItem('lx_detail_cache', JSON.stringify({ + engine: currentEngine, // 存入身份 type: 'detail', keyword: name, page: 1, @@ -6435,6 +6493,11 @@ const sortId = window.currentLxSortId || ''; if (!window.lxBaseUrl && type === 'tag') return; + const currentEngine = document.getElementById('engine-val')?.dataset.value || 'MusicFree'; + const apiType = currentEngine === 'LXServer' ? 2 : 1; + // 🌟 加载 SVG 的动态颜色 + const themeColor = currentEngine === 'LXServer' ? '#10b981' : 'var(--primary)'; + // 核心判断:如果是打字搜歌单,处理历史记录和UI if (type === 'keyword') { if (!keyword) { showToast("请输入要搜索的歌单名"); return; } @@ -6450,28 +6513,27 @@ window.addOnlineSearchHistory({ type: 'playlist', keyword: keyword }); } } else if (type === 'tag' && !isLoadMore) { - // 如果是点击了历史记录里的分类标签,同样清空详情缓存 localStorage.removeItem('lx_detail_cache'); + // 🌟 响应你的需求:仅仅清除旧的详情缓存,不再把标签当做历史记录存入 } // 胶囊(tag)直接走LX源地址,文字搜歌单(keyword)走XiaoMusic后端桥接! const reqUrl = type === 'tag' ? `${window.lxBaseUrl}/music/songList/list?source=${source}&tagId=&sortId=${sortId}&page=${isLoadMore ? window.currentLxPlaylistPage + 1 : 1}` - : `/api/search/online_playlist?keyword=${encodeURIComponent(keyword)}&plugin=${source}&page=${isLoadMore ? window.currentLxPlaylistPage + 1 : 1}&api_type=2`; - + : `/api/search/online_playlist?keyword=${encodeURIComponent(keyword)}&plugin=${source}&page=${isLoadMore ? window.currentLxPlaylistPage + 1 : 1}&api_type=${apiType}`; window.isFetchingLxPlaylists = true; const grid = document.getElementById('playlist-grid'); const list = document.getElementById('playlist'); if (!isLoadMore) { - // 发起新的搜索或点标签时,重置滚动记录 localStorage.setItem('lx_grid_scroll_y', '0'); window.currentLxPlaylistPage = 1; window.hasMoreLxPlaylists = true; list.style.display = 'none'; grid.style.display = 'grid'; - grid.innerHTML = '
    正在拉取歌单海报...
    '; + // 🌟 修复转圈动画颜色 + grid.innerHTML = `
    正在拉取歌单海报...
    `; } else { window.currentLxPlaylistPage++; @@ -6487,25 +6549,34 @@ const res = await fetch(reqUrl, { headers }); const resJson = await res.json(); - const data = resJson.data || resJson; - if (data.list && data.list.length > 0) { - // 累加存储歌单列表,而不是只存当前页 + let targetList = []; + let targetLimit = 30; + + const dataObj = resJson.data || resJson; + + if (Array.isArray(dataObj)) { + targetList = dataObj; + } else if (dataObj && dataObj.list) { + targetList = dataObj.list; + targetLimit = dataObj.limit || 30; + } + + if (targetList && targetList.length > 0) { if (!isLoadMore) { - window.lxPlaylistItems = data.list; + window.lxPlaylistItems = targetList; grid.innerHTML = ''; } else { - window.lxPlaylistItems = [...(window.lxPlaylistItems || []), ...data.list]; - // 移除旧的加载按钮 + window.lxPlaylistItems = [...(window.lxPlaylistItems || []), ...targetList]; const oldMore = document.getElementById('lx-grid-load-more'); if (oldMore) oldMore.remove(); } - // 判断是否还有下一页 - if (data.list.length < (data.limit || 30)) window.hasMoreLxPlaylists = false; + if (targetList.length < targetLimit) window.hasMoreLxPlaylists = false; - // 存入专属的海报墙抽屉 (lx_grid_cache) + // 🌟 核心:存入专属的海报墙抽屉时带上引擎身份 localStorage.setItem('lx_grid_cache', JSON.stringify({ + engine: currentEngine, // 存入引擎身份 type: type === 'keyword' ? 'playlist' : 'tag', keyword: type === 'keyword' ? keyword : (document.getElementById('search-tag-capsule')?.textContent || ''), sortId: window.currentLxSortId, @@ -6514,21 +6585,32 @@ list: window.lxPlaylistItems })); - // 同时同步切换按钮 (隐藏返回,显示搜歌搜单) if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(false); - const html = data.list.map(item => { - const nameParts = item.name.split(/\|||/); + const html = targetList.map(item => { + const rawName = item.name || item.title || '未知歌单'; + const nameParts = rawName.split(/\|||/); const mainName = nameParts[0]; - const subName = nameParts.slice(1).join('·') || item.author || ''; - const playCount = item.play_count || '0'; + const subName = nameParts.slice(1).join('·') || item.author || item.artist || ''; - const songCount = item.total || item.song_count || item.trackCount || ''; + let playCount = item.play_count || item.playCount || '0'; + if (playCount > 10000) playCount = (playCount / 10000).toFixed(1) + '万'; + + const songCount = item.total || item.song_count || item.trackCount || item.worksNum || ''; const songCountHtml = songCount ? `
    共 ${songCount} 首
    ` : ''; + const coverImg = item.img || item.artwork || item.coverImg || item.pic || ''; + const itemSource = item.source || item.platform || source; + + let targetId = item.id; + if (apiType === 1) { + const jsonStr = JSON.stringify(item); + targetId = window.btoa(unescape(encodeURIComponent(jsonStr))); + } + return ` -
    - cover +
    + cover
    ${mainName}${subName ? '
    '+subName : ''}
    ${songCountHtml} @@ -6540,18 +6622,15 @@ }).join(''); grid.insertAdjacentHTML('beforeend', html); - if (data.list.length < (data.limit||30)) window.hasMoreLxPlaylists = false; + if (targetList.length < targetLimit) window.hasMoreLxPlaylists = false; - // 网格底部状态条 (Load More) 贯穿所有列! const moreDiv = document.createElement('div'); moreDiv.id = 'lx-grid-load-more'; - // 使用 grid-column: 1 / -1 让按钮强制独占一整行 moreDiv.style.cssText = 'grid-column: 1 / -1; text-align: center; padding: 15px 0 25px 0; color: var(--text-sub); font-size: 13px; cursor: pointer; display: flex; justify-content: center; margin-top: 10px;'; if (window.hasMoreLxPlaylists) { moreDiv.innerHTML = `
    点击加载下一页
    `; moreDiv.onclick = () => window.doLxPlaylistSearch(true); - // 极简动画反馈 moreDiv.onmousedown = () => { if(moreDiv.firstElementChild) moreDiv.firstElementChild.style.background = 'var(--bg-color)'; }; moreDiv.onmouseup = () => { if(moreDiv.firstElementChild) moreDiv.firstElementChild.style.background = 'var(--card-bg)'; }; } else { @@ -6573,7 +6652,7 @@ if (!isLoadMore) { grid.innerHTML = `
    广场接口获取失败,暂不支持或网络异常
    `; } else { - window.currentLxPlaylistPage--; // 回退页码防死锁 + window.currentLxPlaylistPage--; const oldMore = document.getElementById('lx-grid-load-more'); if (oldMore) oldMore.innerHTML = `
    加载失败,点击重试
    `; } @@ -6794,7 +6873,9 @@ } if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(false); - window.applyEngineUIAndState('LXServer'); + // 🌟 修复返回错乱:读取网格缓存的真实引擎身份,没记录就用当前引擎 + const targetEngine = gridCache.engine || document.getElementById('engine-val')?.dataset.value || 'MusicFree'; + window.applyEngineUIAndState(targetEngine); } else { if (mfSearchClear) mfSearchClear.click(); } @@ -6947,17 +7028,33 @@ window.renderLxGridFromCache = function(grid, list) { if (!grid || !list) return; + const currentEngine = document.getElementById('engine-val')?.dataset.value || 'MusicFree'; + const apiType = currentEngine === 'LXServer' ? 2 : 1; + grid.innerHTML = list.map(item => { - const nameParts = item.name.split(/\|||/); + const rawName = item.name || item.title || '未知歌单'; + const nameParts = rawName.split(/\|||/); const mainName = nameParts[0]; - const subName = nameParts.slice(1).join('·') || item.author || ''; - const playCount = item.play_count || '0'; - const songCount = item.total || item.song_count || item.trackCount || ''; + const subName = nameParts.slice(1).join('·') || item.author || item.artist || ''; + + let playCount = item.play_count || item.playCount || '0'; + if (playCount > 10000) playCount = (playCount / 10000).toFixed(1) + '万'; + + const songCount = item.total || item.song_count || item.trackCount || item.worksNum || ''; const songCountHtml = songCount ? `
    共 ${songCount} 首
    ` : ''; + const coverImg = item.img || item.artwork || item.coverImg || item.pic || ''; + const itemSource = item.source || item.platform || (document.getElementById('mf-plugin-val')?.dataset.value || 'tx'); + + let targetId = item.id; + if (apiType === 1) { + const jsonStr = JSON.stringify(item); + targetId = window.btoa(unescape(encodeURIComponent(jsonStr))); + } + return ` -
    - cover +
    + cover
    ${mainName}${subName ? '
    '+subName : ''}
    ${songCountHtml} @@ -6988,7 +7085,6 @@ if (savedY && savedY !== '0') { setTimeout(() => { window.scrollTo({ top: parseInt(savedY), behavior: 'instant' }); - // 恢复一次后即清除,防止下次进其他列表时莫名跳转 localStorage.setItem('lx_grid_scroll_y', '0'); }, 100); } @@ -7042,132 +7138,126 @@ let cacheList = []; let cacheKeyword = ''; let isCapsuleRestored = false; - let mode = 'song'; //提升作用域,用于末尾判断 + let mode = 'song'; const backendHistoryList = allPlaylists['_online_iwebplayer_search'] || []; const playlistBtn = document.getElementById('mf-search-playlist-btn'); const searchDivider = document.getElementById('mf-search-divider'); - if (playlistBtn) playlistBtn.style.display = (targetVal === 'LXServer' ? 'block' : 'none'); - if (searchDivider) searchDivider.style.display = (targetVal === 'LXServer' ? 'block' : 'none'); + if (playlistBtn) playlistBtn.style.display = 'block'; + if (searchDivider) searchDivider.style.display = 'block'; - if (targetVal === 'LXServer') { - try { - const detailCache = JSON.parse(localStorage.getItem('lx_detail_cache')); - const gridCache = JSON.parse(localStorage.getItem('lx_grid_cache')); - const oldSongCache = JSON.parse(localStorage.getItem('lx_online_search_cache')); + // 🌟 统一缓存恢复核心逻辑:双方都认同引擎身份牌 + try { + const detailCache = JSON.parse(localStorage.getItem('lx_detail_cache')); + const gridCache = JSON.parse(localStorage.getItem('lx_grid_cache')); + const lxSongCache = JSON.parse(localStorage.getItem('lx_online_search_cache')); + const mfSongCache = JSON.parse(localStorage.getItem('mf_online_search_cache')); - let activeCache = null; - if (detailCache) activeCache = detailCache; - else if (gridCache) activeCache = gridCache; - else if (oldSongCache && oldSongCache.type === 'song') activeCache = oldSongCache; + let activeCache = null; + // 只有身份对得上,才能恢复这个缓存! + if (detailCache && detailCache.engine === targetVal) activeCache = detailCache; + else if (gridCache && gridCache.engine === targetVal) activeCache = gridCache; + else if (targetVal === 'LXServer' && lxSongCache && lxSongCache.type === 'song') activeCache = lxSongCache; + else if (targetVal === 'MusicFree' && mfSongCache && mfSongCache.type === 'song') activeCache = mfSongCache; - if (activeCache) { - const cacheKeywordRaw = activeCache.keyword || ''; - currentSearchPage = activeCache.page || 1; - hasMoreOnlineSearch = activeCache.hasMore !== false; + if (activeCache) { + const cacheKeywordRaw = activeCache.keyword || ''; + currentSearchPage = activeCache.page || 1; + hasMoreOnlineSearch = activeCache.hasMore !== false; - mode = activeCache.type || 'song'; - localStorage.setItem('last_search_action', mode === 'tag' ? 'playlist' : mode); + mode = activeCache.type || 'song'; + localStorage.setItem('last_search_action', mode === 'tag' ? 'playlist' : mode); - const grid = document.getElementById('playlist-grid'); - const list = document.getElementById('playlist'); + const grid = document.getElementById('playlist-grid'); + const list = document.getElementById('playlist'); - if (mode === 'playlist' && currentPlaylist === '在线资源') { - if (grid) grid.style.display = 'grid'; - if (list) list.style.display = 'none'; + if (mode === 'playlist' && currentPlaylist === '在线资源') { + if (grid) grid.style.display = 'grid'; + if (list) list.style.display = 'none'; - const cachedPlList = activeCache.list || []; - if (cachedPlList.length > 0) { - window.currentLxPlaylistPage = activeCache.page || 1; - window.hasMoreLxPlaylists = activeCache.hasMore !== false; - window.currentLxSearchType = 'keyword'; - window.lxPlaylistItems = cachedPlList; - if (typeof window.renderLxGridFromCache === 'function') window.renderLxGridFromCache(grid, cachedPlList); - } else { - setTimeout(() => window.doLxPlaylistSearch(false, 'keyword'), 50); - } - cacheKeyword = cacheKeywordRaw; + const cachedPlList = activeCache.list || []; + if (cachedPlList.length > 0) { + window.currentLxPlaylistPage = activeCache.page || 1; + window.hasMoreLxPlaylists = activeCache.hasMore !== false; + window.currentLxSearchType = 'keyword'; + window.lxPlaylistItems = cachedPlList; + if (typeof window.renderLxGridFromCache === 'function') window.renderLxGridFromCache(grid, cachedPlList); + } else { + setTimeout(() => window.doLxPlaylistSearch(false, 'keyword'), 50); } - else if (mode === 'tag' && currentPlaylist === '在线资源') { - if (grid) grid.style.display = 'grid'; - if (list) list.style.display = 'none'; - - let capsule = document.getElementById('search-tag-capsule'); - if (!capsule) { - capsule = document.createElement('div'); - capsule.id = 'search-tag-capsule'; - capsule.className = 'search-tag-capsule'; - document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); - } - capsule.innerText = cacheKeywordRaw; - capsule.title = cacheKeywordRaw; - window.currentLxSortId = activeCache.sortId || ''; - - const cachedPlList = activeCache.list || []; - if (cachedPlList.length > 0) { - window.currentLxPlaylistPage = activeCache.page || 1; - window.hasMoreLxPlaylists = activeCache.hasMore !== false; - window.currentLxSearchType = 'tag'; - window.lxPlaylistItems = cachedPlList; - if (typeof window.renderLxGridFromCache === 'function') window.renderLxGridFromCache(grid, cachedPlList); - } else { - setTimeout(() => window.doLxPlaylistSearch(false, 'tag'), 50); - } - - if (mfSearchInput) { mfSearchInput.value = ''; mfSearchInput.placeholder = ''; } - cacheKeyword = ''; - isCapsuleRestored = true; - } - else if (mode === 'detail' && currentPlaylist === '在线资源') { - if (grid) grid.style.display = 'none'; - if (list) list.style.display = 'block'; - - let capsule = document.getElementById('search-tag-capsule'); - if (!capsule) { - capsule = document.createElement('div'); - capsule.id = 'search-tag-capsule'; - capsule.className = 'search-tag-capsule'; - document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); - } - const boxWidth = document.getElementById('mf-search-input-wrap')?.clientWidth || window.innerWidth; - let maxChars = (boxWidth <= 370 || window.innerWidth <= 480) ? 14 : 18; - const shortName = cacheKeywordRaw.length > maxChars ? cacheKeywordRaw.substring(0, maxChars) + '...' : cacheKeywordRaw; - capsule.innerText = shortName; - capsule.title = cacheKeywordRaw; - if (mfSearchInput) { mfSearchInput.value = ''; mfSearchInput.placeholder = ''; } - cacheList = activeCache.list || []; - cacheKeyword = ''; - isCapsuleRestored = true; - } - else { - if (grid) grid.style.display = 'none'; - if (list) list.style.display = 'block'; - cacheList = activeCache.list || []; - cacheKeyword = cacheKeywordRaw; - } - - if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(!!detailCache); + cacheKeyword = cacheKeywordRaw; } - } catch(e) {} - } else { - const grid = document.getElementById('playlist-grid'); - const list = document.getElementById('playlist'); - if (grid) grid.style.display = 'none'; - if (list) list.style.display = 'block'; - if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(false); + else if (mode === 'tag' && currentPlaylist === '在线资源') { + if (grid) grid.style.display = 'grid'; + if (list) list.style.display = 'none'; - try { - const mfCache = JSON.parse(localStorage.getItem('mf_online_search_cache')); - if (mfCache) { - cacheList = mfCache.list || []; - cacheKeyword = mfCache.keyword || ''; - currentSearchPage = mfCache.page || 1; - hasMoreOnlineSearch = mfCache.hasMore !== false; - localStorage.setItem('last_search_action', 'song'); + let capsule = document.getElementById('search-tag-capsule'); + if (!capsule) { + capsule = document.createElement('div'); + capsule.id = 'search-tag-capsule'; + // 根据引擎决定恢复出来的胶囊颜色 + capsule.className = `search-tag-capsule ${targetVal === 'LXServer' ? 'lx-theme' : 'mf-theme'}`; + document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); + } + capsule.innerText = cacheKeywordRaw; + capsule.title = cacheKeywordRaw; + window.currentLxSortId = activeCache.sortId || ''; + + const cachedPlList = activeCache.list || []; + if (cachedPlList.length > 0) { + window.currentLxPlaylistPage = activeCache.page || 1; + window.hasMoreLxPlaylists = activeCache.hasMore !== false; + window.currentLxSearchType = 'tag'; + window.lxPlaylistItems = cachedPlList; + if (typeof window.renderLxGridFromCache === 'function') window.renderLxGridFromCache(grid, cachedPlList); + } else { + setTimeout(() => window.doLxPlaylistSearch(false, 'tag'), 50); + } + + if (mfSearchInput) { mfSearchInput.value = ''; mfSearchInput.placeholder = ''; } + cacheKeyword = ''; + isCapsuleRestored = true; } - } catch(e) {} - } + else if (mode === 'detail' && currentPlaylist === '在线资源') { + if (grid) grid.style.display = 'none'; + if (list) list.style.display = 'block'; + + let capsule = document.getElementById('search-tag-capsule'); + if (!capsule) { + capsule = document.createElement('div'); + capsule.id = 'search-tag-capsule'; + // 根据引擎决定恢复出来的胶囊颜色 + capsule.className = `search-tag-capsule ${targetVal === 'LXServer' ? 'lx-theme' : 'mf-theme'}`; + document.getElementById('mf-search-input-wrap').insertBefore(capsule, document.getElementById('mf-search-input')); + } + const boxWidth = document.getElementById('mf-search-input-wrap')?.clientWidth || window.innerWidth; + let maxChars = (boxWidth <= 370 || window.innerWidth <= 480) ? 14 : 18; + const shortName = cacheKeywordRaw.length > maxChars ? cacheKeywordRaw.substring(0, maxChars) + '...' : cacheKeywordRaw; + capsule.innerText = shortName; + capsule.title = cacheKeywordRaw; + if (mfSearchInput) { mfSearchInput.value = ''; mfSearchInput.placeholder = ''; } + cacheList = activeCache.list || []; + cacheKeyword = ''; + isCapsuleRestored = true; + } + else { + if (grid) grid.style.display = 'none'; + if (list) list.style.display = 'block'; + cacheList = activeCache.list || []; + cacheKeyword = cacheKeywordRaw; + } + + if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(mode === 'detail'); + } else { + // 如果当前引擎没有任何缓存,重置为单曲视图 + const grid = document.getElementById('playlist-grid'); + const list = document.getElementById('playlist'); + if (grid) grid.style.display = 'none'; + if (list) list.style.display = 'block'; + if (typeof window.toggleSearchBackBtn === 'function') window.toggleSearchBackBtn(false); + } + } catch(e) {} if (currentDid !== "" && !cacheKeyword && !isCapsuleRestored && backendHistoryList.length > 0) { cacheList = backendHistoryList; @@ -7176,7 +7266,6 @@ if (mfSearchInput) mfSearchInput.value = cacheKeyword; if (mfSearchClear) mfSearchClear.classList.toggle('show', cacheKeyword.length > 0 || isCapsuleRestored); - // 只有在【非海报墙模式】且【当前是在线资源】时,才调用 renderPlaylist if (currentPlaylist === '在线资源') { if (mode !== 'playlist' && mode !== 'tag') { songList = cacheList; @@ -7184,7 +7273,6 @@ allPlaylists['在线资源'] = songList; renderPlaylist(); } else { - // 如果是海报墙模式,我们已经手动处理过 UI 了,只需要同步一下顶栏文字即可 const playlistVal = document.getElementById('playlist-val'); const text = formatPlaylistText('在线资源', (window.lxPlaylistItems || []).length); if (playlistVal) playlistVal.innerHTML = text; @@ -7629,8 +7717,11 @@ const isStandaloneMode = window.navigator.standalone || window.matchMedia('(display-mode: standalone)').matches; if (isStandaloneMode && audioEl) { audioEl.addEventListener('pause', () => { + // 🌟 核心结合点:如果是前端页面点击触发的暂停,直接放行,不执行清空! + if (window.isPageBtnPause) return; + if (audioEl.src && !audioEl.ended && currentDid === "") { - console.log('检测到 PWA 模式暂停,为防止死锁已清空音频源'); + console.log('检测到 PWA 模式暂停(非前端触发),为防止死锁已清空音频源'); const currentTime = audioEl.currentTime; audioEl.src = ""; audioEl.load(); @@ -7645,4 +7736,3 @@ -