Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4285677
fix: enable lm-quick-search and sync quick search filter state
Jun 11, 2026
9ebb8e8
feat: 自动提示歌单更新
Jun 11, 2026
a6fd72e
chore: sync .dockerignore with upstream
Jun 11, 2026
d39ed8c
fix: reuse auto source switching for downloads
Jun 12, 2026
0621367
fix: cache lyrics for playlist server downloads
bobcc4 Jun 12, 2026
0a065ca
fix: sync naming pattern for download mode
bobcc4 Jun 13, 2026
a326328
fix: persist valid download concurrency setting
bobcc4 Jun 14, 2026
90070c0
Merge PR #232 local music quick search
bobcc4 Jun 14, 2026
1ba0230
Merge PR #233 auto playlist update
bobcc4 Jun 14, 2026
96809e7
Merge PR #234 download auto source switch
bobcc4 Jun 14, 2026
1fe9245
Merge PR #236 playlist download lyric cache
bobcc4 Jun 14, 2026
634fd4f
Merge PR #239 download mode naming pattern
bobcc4 Jun 14, 2026
c6989e5
Merge PR #240 download concurrency setting
bobcc4 Jun 14, 2026
c79bab7
fix: apply PR review suggestions
bobcc4 Jun 14, 2026
4e1ec92
fix: reset batch mode after batch actions
bobcc4 Jun 14, 2026
abebda1
fix: handle encoded proxied download URLs
bobcc4 Jun 14, 2026
ddf2104
fix: resolve external URLs for server downloads
bobcc4 Jun 14, 2026
b336bdc
fix: keep external url resolution for server downloads
bobcc4 Jun 14, 2026
2fd6ece
fix: copy existing cache to download folder
bobcc4 Jun 14, 2026
a5588f0
fix: preserve download naming and lyrics
bobcc4 Jun 14, 2026
fc7c795
fix: address review feedback
bobcc4 Jun 14, 2026
d07251a
fix: avoid duplicate cache writes during download fallback
bobcc4 Jun 14, 2026
c83fde6
fix: improve artist library batch downloads
bobcc4 Jun 16, 2026
b8ed6af
fix: stabilize large server download batches
bobcc4 Jun 16, 2026
97e76f8
fix: improve music download recovery
bobcc4 Jun 23, 2026
97ee489
Optimize large music list rendering
bobcc4 Jun 24, 2026
9f05fbf
fix: address pr review feedback
bobcc4 Jun 29, 2026
2676726
fix: address follow-up review feedback
bobcc4 Jun 29, 2026
95258a6
fix: address latest review feedback
bobcc4 Jun 29, 2026
9156ac1
fix: require admin auth for cache naming updates
bobcc4 Jun 29, 2026
268e14b
feat: add favorite sidebar ordering
bobcc4 Jul 1, 2026
b79377d
fix: resize favorites sidebar after list updates
bobcc4 Jul 4, 2026
4a7dd82
feat: support enhanced tx and wy qualities
bobcc4 Jul 9, 2026
825846d
fix: refine quality option labels
bobcc4 Jul 9, 2026
db8c021
fix: resolve quality file sizes on demand
bobcc4 Jul 9, 2026
29efea1
fix: sync local music quality filters
bobcc4 Jul 9, 2026
5e687d4
fix: show actual server cache quality
bobcc4 Jul 9, 2026
13850df
feat: download all artist album songs
bobcc4 Jul 10, 2026
d48684c
fix: preserve batch download tasks and quality
bobcc4 Jul 10, 2026
3e2951a
fix: prevent batch downloads from freezing the page
bobcc4 Jul 11, 2026
8d3e47b
feat: persist server download queue
bobcc4 Jul 11, 2026
6e59fc0
fix: stabilize artist batch downloads
bobcc4 Jul 11, 2026
948b8cc
fix: persist server download concurrency
bobcc4 Jul 11, 2026
3ff9f56
fix favorites selection and single download quality
bobcc4 Jul 11, 2026
ea98a0a
fix server download source fallback and quality size
bobcc4 Jul 11, 2026
e4fbbec
fix remote sizes for newly supported qualities
bobcc4 Jul 11, 2026
5a6e87d
feat: add per-album actions to artist albums
bobcc4 Jul 12, 2026
7ee84a6
feat: add downloads to favorite albums
bobcc4 Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .gitignore
Binary file not shown.
2 changes: 1 addition & 1 deletion public/js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
// 其余配置由服务端在运行时动态注入 (环境变量 > config.js > defaultConfig.ts)
// 服务端拦截 /js/config.js 请求, 读取此处版本号并合并服务端配置后返回
window.CONFIG = {
buildHash: 'c95106b',
buildHash: 'ba6046e',
version: 'v1.9.4',
};
1,044 changes: 806 additions & 238 deletions public/music/app.js

Large diffs are not rendered by default.

70 changes: 61 additions & 9 deletions public/music/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,23 @@ <h2 class="text-sm md:text-base font-bold t-text-main whitespace-nowrap">本地
<button
class="lm-filter-tag shrink-0 !text-[9px] !px-1.5 !py-0.5 md:!px-2 md:!py-1"
data-filter-value="flac24bit"
onclick="window.LocalMusicManager.toggleFilterTag('quality','flac24bit')">Hi-Res</button>
onclick="window.LocalMusicManager.toggleFilterTag('quality','flac24bit')">24bit</button>
<button
class="lm-filter-tag shrink-0 !text-[9px] !px-1.5 !py-0.5 md:!px-2 md:!py-1"
data-filter-value="hires"
onclick="window.LocalMusicManager.toggleFilterTag('quality','hires')">Hi-Res</button>
<button
class="lm-filter-tag shrink-0 !text-[9px] !px-1.5 !py-0.5 md:!px-2 md:!py-1"
data-filter-value="atmos"
onclick="window.LocalMusicManager.toggleFilterTag('quality','atmos')">Atmos</button>
<button
class="lm-filter-tag shrink-0 !text-[9px] !px-1.5 !py-0.5 md:!px-2 md:!py-1"
data-filter-value="atmos_plus"
onclick="window.LocalMusicManager.toggleFilterTag('quality','atmos_plus')">Atmos+</button>
<button
class="lm-filter-tag shrink-0 !text-[9px] !px-1.5 !py-0.5 md:!px-2 md:!py-1"
data-filter-value="master"
onclick="window.LocalMusicManager.toggleFilterTag('quality','master')">Master</button>
</div>
</div>

Expand Down Expand Up @@ -1299,6 +1315,18 @@ <h2 class="text-sm md:text-base font-bold t-text-main whitespace-nowrap">本地
<p class="font-bold tracking-wider">正在加载本地音乐...</p>
</div>
</div>
<div id="lm-pagination"
class="flex-shrink-0 flex items-center justify-center gap-2 md:gap-4 py-2 border-x border-b t-border-main rounded-b-xl t-bg-panel/80 hidden">
<button id="lm-page-prev" onclick="window.LocalMusicManager.changePage(-1)"
class="px-2 md:px-4 py-1.5 text-xs md:text-sm t-bg-main border t-border-main rounded-lg hover:t-bg-track disabled:opacity-40 disabled:cursor-not-allowed transition-colors">
<i class="fas fa-chevron-left md:mr-1"></i><span class="hidden sm:inline">上一页</span>
</button>
<span id="lm-page-info" class="text-[10px] md:text-sm t-text-muted font-medium">第 1 / 1 页</span>
<button id="lm-page-next" onclick="window.LocalMusicManager.changePage(1)"
class="px-2 md:px-4 py-1.5 text-xs md:text-sm t-bg-main border t-border-main rounded-lg hover:t-bg-track disabled:opacity-40 disabled:cursor-not-allowed transition-colors">
<span class="hidden sm:inline">下一页</span><i class="fas fa-chevron-right md:ml-1"></i>
</button>
</div>
</div>

<!-- Settings View -->
Expand Down Expand Up @@ -1402,10 +1430,14 @@ <h4 class="text-sm font-bold t-text-main flex items-center">
</h4>
<select id="quality-select" onchange="changeQualityPreference(this.value)"
class="lm-select !w-full !py-2">
<option value="128k">标准 128K (流畅)</option>
<option value="320k" selected>高品质 320K (推荐)</option>
<option value="flac">无损 FLAC</option>
<option value="flac24bit">无损 Hi-Res (最高)</option>
<option value="128k">标准音质</option>
<option value="320k" selected>高音质</option>
<option value="flac">无损音质</option>
<option value="flac24bit">24bit无损</option>
<option value="hires">高解析度</option>
<option value="atmos">空间音频</option>
<option value="atmos_plus">增强空间音频</option>
<option value="master">母带音质</option>
</select>
</div>

Expand Down Expand Up @@ -1562,13 +1594,13 @@ <h3 class="font-medium text-emerald-600 mb-4">网络设置</h3>
</span>
</div>
</div>
<select id="setting-download-concurrency" class="lm-select !w-20 !py-1">
<select id="setting-download-concurrency" class="lm-select !w-20 !py-1"
onchange="updateSetting('downloadConcurrency', parseInt(this.value))">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="3" selected>3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
</div>
Expand Down Expand Up @@ -1689,6 +1721,26 @@ <h3 class="font-medium text-emerald-600 mb-4">自动更新</h3>
</label>
</div>

<div class="grid grid-cols-1 gap-3 md:grid-cols-[1fr_auto] md:items-center">
<div>
<div class="text-sm font-bold t-text-main">网络歌单自动检测间隔</div>
<div class="text-xs t-text-muted mt-1">输入值示例:30m / 6h / 1d,开启后自动检测并标记已更新歌单。</div>
</div>
<input id="setting-network-list-auto-check-interval" type="text"
class="w-full md:w-40 rounded-xl border t-border-main px-3 py-2 text-sm bg-transparent focus:outline-none focus:ring-2 focus:ring-emerald-500"
onchange="updateSetting('networkListAutoCheckInterval', this.value)">
</div>
<div class="flex items-center justify-between">
<div>
<div class="text-sm font-bold t-text-main">检查所有歌单更新</div>
<div class="text-xs t-text-muted mt-1">手动触发一次网络歌单更新检测,结果会在侧边栏中显示。</div>
</div>
<button type="button" onclick="checkNetworkListUpdates(true)"
class="px-4 py-2 rounded-xl bg-emerald-500 text-white text-sm font-medium hover:bg-emerald-600 transition-all">
立即检查
</button>
</div>

<!-- [Renamed] Save Settings to Server Toggle -->
<div class="flex items-center justify-between">
<div>
Expand Down Expand Up @@ -4745,4 +4797,4 @@ <h2 class="text-2xl font-black t-text-main text-center mb-4">项目使用声明<
<script src="app.js"></script>
</body>

</html>
</html>
43 changes: 27 additions & 16 deletions public/music/js/batch_pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ function refreshBatchUI() {
if (window.SongListManager) window.SongListManager.renderDetail();
} else if (artistHeader) {
// Artist Detail Mode
if (typeof loadArtistSongs === 'function' && window.currentArtistId) {
loadArtistSongs(window.currentArtistId, window.currentArtistOrder || 'hot');
if (window.currentArtistSongsCache) {
renderArtistSongsUI(window.currentArtistSongsCache);
} else if (typeof loadArtistSongs === 'function' && window.currentArtistId) {
loadArtistSongs(window.currentArtistId, window.currentArtistSource || 'wy', window.currentArtistOrder || 'hot');
}
} else {
// Fallback to main renderResults (for search view)
Expand Down Expand Up @@ -92,14 +94,10 @@ function selectAllVisible() {
updateBatchToolbar();
}

function deselectAll() {
function clearSelection() {
window.selectedItems.clear();
window.selectedSongObjects.clear();

const batchToolbar = document.getElementById('batch-toolbar');
const slToolbar = document.getElementById('sl-batch-toolbar');
const lbBatchToolbar = document.getElementById('lb-batch-toolbar');

// updateBatchToolbar() 会被调用,这里也主动清零防遗漏
const countEl = document.getElementById('batch-selected-count');
const slCountEl = document.getElementById('sl-batch-selected-count');
Expand All @@ -108,20 +106,33 @@ function deselectAll() {
if (slCountEl) slCountEl.textContent = '0';
if (lbCountEl) lbCountEl.textContent = '0';

// 重新渲染UI
refreshBatchUI();
if (window.LeaderboardManager && document.getElementById('view-leaderboard') && !document.getElementById('view-leaderboard').classList.contains('hidden')) {
window.LeaderboardManager.renderSongs();
}
updateBatchToolbar();
}

function exitBatchMode() {
window.batchMode = false;
clearSelection();

const batchToolbar = document.getElementById('batch-toolbar');
const slToolbar = document.getElementById('sl-batch-toolbar');
const lbBatchToolbar = document.getElementById('lb-batch-toolbar');

if (batchToolbar) batchToolbar.classList.add('hidden');
if (slToolbar) slToolbar.classList.add('hidden');
if (lbBatchToolbar) lbBatchToolbar.classList.add('hidden');

// 恢复被隐藏的分页控件 (在排行榜中)
const lbPagination = document.getElementById('lb-pagination');
if (lbPagination) lbPagination.classList.remove('hidden');
}

// 重新渲染UI
refreshBatchUI();
if (window.LeaderboardManager && document.getElementById('view-leaderboard') && !document.getElementById('view-leaderboard').classList.contains('hidden')) {
window.LeaderboardManager.renderSongs();
}
updateBatchToolbar();
function deselectAll() {
clearSelection();
}

function updateBatchToolbar() {
Expand Down Expand Up @@ -250,9 +261,7 @@ async function batchDeleteFromList() {
}

// Clear selection and exit batch mode
window.selectedItems.clear();
window.batchMode = false;
toggleBatchMode(); // Update UI
exitBatchMode();
}

// Helper: Get current active list ID
Expand Down Expand Up @@ -449,6 +458,8 @@ async function handleBatchCollect() {
window.handleBatchSelect = handleBatchSelect;
window.toggleBatchMode = toggleBatchMode;
window.selectAllVisible = selectAllVisible;
window.clearSelection = clearSelection;
window.exitBatchMode = exitBatchMode;
window.deselectAll = deselectAll;
window.batchDeleteFromList = batchDeleteFromList;
window.handleBatchCollect = handleBatchCollect;
Expand Down
Loading