dsh-music-panel 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/client.js +84 -37
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### 变更
|
|
6
|
+
|
|
7
|
+
- 移除主面板顶部「清空列表」按钮
|
|
8
|
+
- 正在播放行:品牌色高亮、3px 左侧竖条、标题品牌色加粗、播放均衡器动画(暂停时静止),封面遮罩常显暂停/播放图标
|
|
9
|
+
|
|
10
|
+
## 0.3.2
|
|
11
|
+
|
|
12
|
+
### 变更
|
|
13
|
+
|
|
14
|
+
- 播放顺序合并为三种互斥模式:顺序播放(播完停止)、随机播放(随机循环)、单曲循环;底栏、播放页、主面板 chips 三处按钮与图标同步
|
|
15
|
+
- 播放队列标题显示当前播放模式
|
|
16
|
+
- 旧状态归一化:升级后 `loop=all + order=list` 视为顺序播放
|
|
17
|
+
|
|
3
18
|
## 0.3.1
|
|
4
19
|
|
|
5
20
|
### 修复
|
package/client.js
CHANGED
|
@@ -80,6 +80,9 @@ window.__ModuleLoader__.load({
|
|
|
80
80
|
'page.done': '完成',
|
|
81
81
|
'page.clear': '清空列表',
|
|
82
82
|
'page.loopAll': '列表循环',
|
|
83
|
+
'page.modeSequence': '顺序播放',
|
|
84
|
+
'page.modeRandom': '随机播放',
|
|
85
|
+
'page.modeOne': '单曲循环',
|
|
83
86
|
'page.loopOne': '单曲循环',
|
|
84
87
|
'page.loopNone': '不循环',
|
|
85
88
|
'page.shuffle': '随机播放',
|
|
@@ -251,6 +254,9 @@ window.__ModuleLoader__.load({
|
|
|
251
254
|
'page.done': 'Done',
|
|
252
255
|
'page.clear': 'Clear list',
|
|
253
256
|
'page.loopAll': 'Repeat all',
|
|
257
|
+
'page.modeSequence': 'Play in order',
|
|
258
|
+
'page.modeRandom': 'Shuffle',
|
|
259
|
+
'page.modeOne': 'Repeat one',
|
|
254
260
|
'page.loopOne': 'Repeat one',
|
|
255
261
|
'page.loopNone': 'No repeat',
|
|
256
262
|
'page.shuffle': 'Shuffle',
|
|
@@ -996,6 +1002,50 @@ window.__ModuleLoader__.load({
|
|
|
996
1002
|
return order
|
|
997
1003
|
}
|
|
998
1004
|
|
|
1005
|
+
// Three playback modes, mapped onto the engine's loop/order pair:
|
|
1006
|
+
// sequence → in order, stop at the end
|
|
1007
|
+
// random → shuffled, looping
|
|
1008
|
+
// one → repeat the current track
|
|
1009
|
+
var PLAY_MODES = ['sequence', 'random', 'one']
|
|
1010
|
+
|
|
1011
|
+
function playModeOf(snap) {
|
|
1012
|
+
if (snap.loop === 'one') return 'one'
|
|
1013
|
+
if (snap.order === 'random') return 'random'
|
|
1014
|
+
return 'sequence'
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
function playModeLabel(mode) {
|
|
1018
|
+
return mode === 'one'
|
|
1019
|
+
? t('page.modeOne')
|
|
1020
|
+
: mode === 'random'
|
|
1021
|
+
? t('page.modeRandom')
|
|
1022
|
+
: t('page.modeSequence')
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
function playModeIcon(mode) {
|
|
1026
|
+
return mode === 'one' ? 'repeatOne' : mode === 'random' ? 'shuffle' : 'list'
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
function applyPlayMode(mode) {
|
|
1030
|
+
if (mode === 'one') {
|
|
1031
|
+
player.setLoop('one')
|
|
1032
|
+
player.setOrder('list')
|
|
1033
|
+
return
|
|
1034
|
+
}
|
|
1035
|
+
if (mode === 'random') {
|
|
1036
|
+
player.setLoop('all')
|
|
1037
|
+
player.setOrder('random')
|
|
1038
|
+
return
|
|
1039
|
+
}
|
|
1040
|
+
player.setLoop('none')
|
|
1041
|
+
player.setOrder('list')
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function cyclePlayMode(snap) {
|
|
1045
|
+
var current = playModeOf(snap)
|
|
1046
|
+
applyPlayMode(PLAY_MODES[(PLAY_MODES.indexOf(current) + 1) % PLAY_MODES.length])
|
|
1047
|
+
}
|
|
1048
|
+
|
|
999
1049
|
function nextIndexOf(index, order, size, randomOrder) {
|
|
1000
1050
|
if (size <= 1) return 0
|
|
1001
1051
|
if (order === 'random') {
|
|
@@ -1059,8 +1109,8 @@ window.__ModuleLoader__.load({
|
|
|
1059
1109
|
queue: [],
|
|
1060
1110
|
index: -1,
|
|
1061
1111
|
playing: false,
|
|
1062
|
-
loop: prefs.loop === 'one'
|
|
1063
|
-
order: prefs.order === 'random' ? 'random' : 'list',
|
|
1112
|
+
loop: prefs.loop === 'one' ? 'one' : 'none',
|
|
1113
|
+
order: prefs.order === 'random' && prefs.loop !== 'one' ? 'random' : 'list',
|
|
1064
1114
|
// Volume follows the system mixer: the plugin no longer exposes its own.
|
|
1065
1115
|
volume: 1,
|
|
1066
1116
|
muted: false,
|
|
@@ -1221,8 +1271,8 @@ window.__ModuleLoader__.load({
|
|
|
1221
1271
|
state = Object.assign({}, state, {
|
|
1222
1272
|
queue: queue,
|
|
1223
1273
|
index: index,
|
|
1224
|
-
loop: saved.loop === 'one'
|
|
1225
|
-
order: saved.order === 'random' ? 'random' : 'list',
|
|
1274
|
+
loop: saved.loop === 'one' ? 'one' : saved.order === 'random' ? 'all' : 'none',
|
|
1275
|
+
order: saved.order === 'random' && saved.loop !== 'one' ? 'random' : 'list',
|
|
1226
1276
|
currentTime: saved.positionSec > 0 ? saved.positionSec : 0,
|
|
1227
1277
|
duration: saved.durationSec > 0 ? saved.durationSec : 0,
|
|
1228
1278
|
playing: false,
|
|
@@ -2306,11 +2356,11 @@ window.__ModuleLoader__.load({
|
|
|
2306
2356
|
)
|
|
2307
2357
|
|
|
2308
2358
|
function cycleLoop() {
|
|
2309
|
-
|
|
2359
|
+
cyclePlayMode(snap)
|
|
2310
2360
|
}
|
|
2311
2361
|
|
|
2312
2362
|
function loopLabel() {
|
|
2313
|
-
return
|
|
2363
|
+
return playModeLabel(playModeOf(snap))
|
|
2314
2364
|
}
|
|
2315
2365
|
|
|
2316
2366
|
return h(
|
|
@@ -2623,7 +2673,7 @@ window.__ModuleLoader__.load({
|
|
|
2623
2673
|
h(
|
|
2624
2674
|
'button',
|
|
2625
2675
|
{ type: 'button', className: 'mu-icon-btn', title: loopLabel(), onClick: cycleLoop },
|
|
2626
|
-
icon(snap
|
|
2676
|
+
icon(playModeIcon(playModeOf(snap)), 18),
|
|
2627
2677
|
),
|
|
2628
2678
|
h(
|
|
2629
2679
|
'button',
|
|
@@ -3324,11 +3374,11 @@ window.__ModuleLoader__.load({
|
|
|
3324
3374
|
)
|
|
3325
3375
|
|
|
3326
3376
|
function cycleLoop() {
|
|
3327
|
-
|
|
3377
|
+
cyclePlayMode(snap)
|
|
3328
3378
|
}
|
|
3329
3379
|
|
|
3330
3380
|
function loopLabel() {
|
|
3331
|
-
return
|
|
3381
|
+
return playModeLabel(playModeOf(snap))
|
|
3332
3382
|
}
|
|
3333
3383
|
|
|
3334
3384
|
function toggleSelect(track) {
|
|
@@ -3591,8 +3641,16 @@ window.__ModuleLoader__.load({
|
|
|
3591
3641
|
h(
|
|
3592
3642
|
'div',
|
|
3593
3643
|
{ className: 'mu-row-title' },
|
|
3644
|
+
isCurrent
|
|
3645
|
+
? h(
|
|
3646
|
+
'span',
|
|
3647
|
+
{ className: 'mu-eq' + (snap.playing ? ' is-playing' : ''), 'aria-hidden': 'true' },
|
|
3648
|
+
h('i', null),
|
|
3649
|
+
h('i', null),
|
|
3650
|
+
h('i', null),
|
|
3651
|
+
)
|
|
3652
|
+
: null,
|
|
3594
3653
|
track.title,
|
|
3595
|
-
isCurrent ? h('span', { className: 'mu-playing-dot' }) : null,
|
|
3596
3654
|
),
|
|
3597
3655
|
h(
|
|
3598
3656
|
'div',
|
|
@@ -4445,7 +4503,7 @@ window.__ModuleLoader__.load({
|
|
|
4445
4503
|
h(
|
|
4446
4504
|
'button',
|
|
4447
4505
|
{ type: 'button', className: 'mu-chip', title: loopLabel(), onClick: cycleLoop },
|
|
4448
|
-
icon(snap
|
|
4506
|
+
icon(playModeIcon(playModeOf(snap)), 15),
|
|
4449
4507
|
h('span', null, loopLabel()),
|
|
4450
4508
|
),
|
|
4451
4509
|
h(
|
|
@@ -4460,28 +4518,6 @@ window.__ModuleLoader__.load({
|
|
|
4460
4518
|
icon('play', 13),
|
|
4461
4519
|
h('span', null, t('page.playAll')),
|
|
4462
4520
|
),
|
|
4463
|
-
h(
|
|
4464
|
-
'button',
|
|
4465
|
-
{
|
|
4466
|
-
type: 'button',
|
|
4467
|
-
className: 'mu-chip mu-chip-round' + (snap.order === 'random' ? ' is-on' : ''),
|
|
4468
|
-
title: t('page.shuffle'),
|
|
4469
|
-
onClick: function () {
|
|
4470
|
-
player.setOrder(snap.order === 'random' ? 'list' : 'random')
|
|
4471
|
-
},
|
|
4472
|
-
},
|
|
4473
|
-
icon('shuffle', 15),
|
|
4474
|
-
),
|
|
4475
|
-
h(
|
|
4476
|
-
'button',
|
|
4477
|
-
{
|
|
4478
|
-
type: 'button',
|
|
4479
|
-
className: 'mu-chip mu-chip-round',
|
|
4480
|
-
title: t('page.clear'),
|
|
4481
|
-
onClick: clearList,
|
|
4482
|
-
},
|
|
4483
|
-
icon('x', 15),
|
|
4484
|
-
),
|
|
4485
4521
|
selected.length > 0
|
|
4486
4522
|
? h(
|
|
4487
4523
|
'span',
|
|
@@ -4663,7 +4699,7 @@ window.__ModuleLoader__.load({
|
|
|
4663
4699
|
title: loopLabel(),
|
|
4664
4700
|
onClick: cycleLoop,
|
|
4665
4701
|
},
|
|
4666
|
-
icon(snap
|
|
4702
|
+
icon(playModeIcon(playModeOf(snap)), 17),
|
|
4667
4703
|
),
|
|
4668
4704
|
h(
|
|
4669
4705
|
'button',
|
|
@@ -4759,6 +4795,7 @@ window.__ModuleLoader__.load({
|
|
|
4759
4795
|
'div',
|
|
4760
4796
|
{ className: 'mu-pop-head' },
|
|
4761
4797
|
h('span', null, t('page.queue')),
|
|
4798
|
+
h('span', { className: 'mu-queue-mode' }, loopLabel()),
|
|
4762
4799
|
snap.queue.length > 0
|
|
4763
4800
|
? h(
|
|
4764
4801
|
'button',
|
|
@@ -5141,12 +5178,16 @@ window.__ModuleLoader__.load({
|
|
|
5141
5178
|
'.mu-btn-danger{background:var(--dsw-alias-state-error-primary,#c0392b);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:transparent}',
|
|
5142
5179
|
'.mu-btn-danger:hover{opacity:.9}',
|
|
5143
5180
|
'.mu-row:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.05))}',
|
|
5144
|
-
'.mu-row.is-current{background:rgba(244,244,245,.
|
|
5145
|
-
'.mu-row.is-current
|
|
5181
|
+
'.mu-row.is-current{background:rgba(244,244,245,.12);background:color-mix(in srgb,var(--dsw-alias-brand-primary,#f4f4f5) 12%,transparent);box-shadow:inset 3px 0 0 var(--dsw-alias-brand-primary,#f4f4f5);border-radius:var(--dsw-radius-md,8px)}',
|
|
5182
|
+
'.mu-row.is-current:hover{background:rgba(244,244,245,.16);background:color-mix(in srgb,var(--dsw-alias-brand-primary,#f4f4f5) 16%,transparent)}',
|
|
5183
|
+
'.mu-row.is-current .mu-row-title{color:var(--dsw-alias-brand-primary,#f4f4f5);font-weight:600}',
|
|
5184
|
+
'.mu-row.is-current .mu-row-sub,.mu-row.is-current .mu-row-album,.mu-row.is-current .mu-row-dur{color:var(--dsw-alias-label-secondary,#a1a1aa)}',
|
|
5146
5185
|
'.mu-row-play{position:relative;width:var(--mu-row-size,55px);height:var(--mu-row-size,55px);border:0;padding:0;background:transparent;cursor:pointer;border-radius:var(--dsw-radius-sm,6px);display:flex;align-items:center;justify-content:center}',
|
|
5147
5186
|
'.mu-row-playmask{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;border-radius:var(--dsw-radius-sm,6px);background:rgba(0,0,0,.45);color:#fff;opacity:0;transition:opacity .12s ease}',
|
|
5148
5187
|
'.mu-row-play:hover .mu-row-playmask,.mu-row.is-current .mu-row-playmask{opacity:1}',
|
|
5188
|
+
'.mu-row.is-current .mu-row-playmask{background:rgba(0,0,0,.35)}',
|
|
5149
5189
|
'.mu-row.is-selected{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.05))}',
|
|
5190
|
+
'.mu-row.is-current.is-selected{background:rgba(244,244,245,.12);background:color-mix(in srgb,var(--dsw-alias-brand-primary,#f4f4f5) 12%,transparent);box-shadow:inset 3px 0 0 var(--dsw-alias-brand-primary,#f4f4f5)}',
|
|
5150
5191
|
'.mu-row-actions{display:flex;align-items:center;justify-content:flex-end;gap:6px}',
|
|
5151
5192
|
'.mu-check{width:20px;height:20px;margin:0;padding:0;border:1.5px solid var(--dsw-alias-border-l3,rgba(255,255,255,.24));border-radius:50%;background:transparent;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex:none;opacity:0;transition:opacity .12s ease}',
|
|
5152
5193
|
'.mu-row:hover .mu-check,.mu-row.is-selected .mu-check,.mu-check:focus-visible{opacity:1}',
|
|
@@ -5156,7 +5197,12 @@ window.__ModuleLoader__.load({
|
|
|
5156
5197
|
'.mu-cover img{width:100%;height:100%;object-fit:cover;display:block}',
|
|
5157
5198
|
'.mu-row-main{min-width:0}',
|
|
5158
5199
|
'.mu-row-title{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
|
5159
|
-
'.mu-
|
|
5200
|
+
'.mu-eq{display:inline-flex;align-items:flex-end;gap:2px;height:12px;margin-right:8px;flex:none}',
|
|
5201
|
+
'.mu-eq i{display:block;width:2px;height:4px;border-radius:1px;background:var(--dsw-alias-brand-primary,#f4f4f5);opacity:.9}',
|
|
5202
|
+
'.mu-eq.is-playing i{animation:mu-eq-bounce .9s ease-in-out infinite}',
|
|
5203
|
+
'.mu-eq.is-playing i:nth-child(2){animation-delay:.15s}',
|
|
5204
|
+
'.mu-eq.is-playing i:nth-child(3){animation-delay:.3s}',
|
|
5205
|
+
'@keyframes mu-eq-bounce{0%,100%{height:4px}50%{height:12px}}',
|
|
5160
5206
|
'.mu-row-sub{display:flex;align-items:center;gap:6px;margin-top:1px;font-size:12px;color:var(--dsw-alias-label-secondary,#a1a1aa);min-width:0}',
|
|
5161
5207
|
'.mu-cd{flex:none;padding:0 4px;border-radius:var(--dsw-radius-xs,4px);border:.5px solid var(--dsw-alias-border-l2,rgba(255,255,255,.2));color:var(--dsw-alias-label-tertiary,#8a8a93);font-size:9px;font-weight:600;line-height:13px;letter-spacing:.4px}',
|
|
5162
5208
|
'.mu-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
|
@@ -5204,6 +5250,7 @@ window.__ModuleLoader__.load({
|
|
|
5204
5250
|
'.mu-pop-head{display:flex;align-items:center;justify-content:space-between;padding:10px 12px 6px;font-size:12px;font-weight:600}',
|
|
5205
5251
|
'.mu-pop-body{overflow-y:auto;padding:0 6px 8px}',
|
|
5206
5252
|
'.mu-queue-row{display:grid;grid-template-columns:26px minmax(0,1fr) minmax(0,70px) auto;align-items:center;gap:8px;padding:5px 8px;border-radius:var(--dsw-radius-sm,6px);font-size:12px;cursor:pointer}',
|
|
5253
|
+
'.mu-queue-mode{font-size:11px;color:var(--dsw-alias-label-tertiary,#8a8a93);padding:1px 6px;border-radius:999px;background:var(--dsw-alias-bg-layer-3,rgba(255,255,255,.06));white-space:nowrap}',
|
|
5207
5254
|
'.mu-queue-actions{display:inline-flex;align-items:center;gap:2px;justify-self:end}',
|
|
5208
5255
|
'.mu-queue-btn{width:20px;height:20px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--dsw-alias-label-tertiary,#8a8a93);font-size:12px;line-height:20px;cursor:pointer}',
|
|
5209
5256
|
'.mu-queue-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.06));color:var(--dsw-alias-label-primary,#f4f4f5)}',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-music-panel",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local music library for DeepSeek Harness: scan a folder, browse tracks with cover art and tags, and play through a sidebar-panel player with loop, shuffle and volume. · DSH 本地音乐插件:扫描音乐目录、读取封面与标签、侧栏入口 + 全屏播放器。",
|
|
6
6
|
"license": "MIT",
|