betterncm-mac 0.1.0 → 0.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "betterncm-mac",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "BetterNCM II for NetEase Cloud Music on macOS, injected over the Chrome DevTools Protocol without modifying the app",
5
5
  "keywords": [
6
6
  "betterncm",
@@ -8,7 +8,8 @@ body.bncm-cover-paused #rnp-view .n-single .cdin {
8
8
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
9
9
  }
10
10
 
11
- body.bncm-roaming #rnp-view .am-music-controls .rnp-amll-playlist { display: none !important; }
11
+ /* roaming has one play mode: 减少推荐 takes the mode button's place */
12
+ body.bncm-roaming #rnp-view .am-music-controls .rnp-amll-play-mode { display: none !important; }
12
13
  body:not(.bncm-roaming) #rnp-view .am-music-controls .bncm-rnp-dislike { display: none !important; }
13
14
  #rnp-view .am-music-controls .bncm-rnp-dislike svg { width: 22px; height: 22px; }
14
15
 
@@ -15,10 +15,11 @@
15
15
  top: 56px;
16
16
  right: 14px;
17
17
  z-index: 1000; /* above #rnp-view (998) */
18
- width: min(488px, calc(100vw - 28px));
18
+ width: min(448px, calc(100vw - 28px)); /* as wide as the tab bar */
19
19
  /* one size whatever is shown: the groups scroll inside it */
20
20
  height: min(600px, calc(100vh - 70px));
21
21
  display: flex;
22
+ flex-direction: column;
22
23
  box-sizing: border-box;
23
24
  background: rgba(var(--bg), .5);
24
25
  -webkit-backdrop-filter: blur(40px) saturate(1.6);
@@ -51,29 +52,30 @@
51
52
  .bncm-settings [hidden] { display: none !important; }
52
53
  .bncm-settings svg { display: block; flex: none; }
53
54
 
54
- /* --- sidebar ------------------------------------------------------------------------------------ */
55
+ /* --- tab bar: one pill per group across the top; the column below gets the whole width -------- */
55
56
  .bncm-set-side {
56
57
  flex: none;
57
- width: 132px;
58
- padding: 12px 8px;
59
58
  display: flex;
60
- flex-direction: column;
59
+ justify-content: space-between;
61
60
  gap: 2px;
62
- background: rgba(var(--fg), .035);
63
- border-right: .5px solid var(--line);
61
+ padding: 10px 14px;
62
+ overflow: auto hidden;
63
+ scrollbar-width: none;
64
+ border-bottom: .5px solid var(--line);
64
65
  }
65
- .bncm-set-tab {
66
+ .bncm-set-side::-webkit-scrollbar { display: none; }
67
+ .bncm-settings .bncm-set-tab { /* over the button reset */
68
+ flex: none;
66
69
  display: flex;
67
70
  align-items: center;
68
- gap: 8px;
69
- height: 32px;
70
- padding: 0 10px;
71
- border-radius: 8px;
71
+ gap: 5px;
72
+ height: 28px;
73
+ padding: 0 11px 0 9px;
74
+ border-radius: 14px;
72
75
  color: var(--t2) !important;
73
76
  white-space: nowrap;
74
77
  }
75
- .bncm-set-tab svg { width: 17px; height: 17px; opacity: .85; }
76
- .bncm-set-tab span { overflow: hidden; text-overflow: ellipsis; }
78
+ .bncm-set-tab svg { width: 15px; height: 15px; opacity: .85; }
77
79
  .bncm-set-tab:hover { background: rgba(var(--fg), .06) !important; color: var(--t1) !important; }
78
80
  .bncm-set-tab.on { background: var(--fill2) !important; color: var(--t1) !important; font-weight: 500; }
79
81
  .bncm-set-tab.on svg { color: rgb(var(--ac)); opacity: 1; }
@@ -81,7 +83,7 @@
81
83
  /* --- pages -------------------------------------------------------------------------------------- */
82
84
  .bncm-set-main {
83
85
  flex: 1;
84
- min-width: 0;
86
+ min-height: 0;
85
87
  overflow: hidden auto;
86
88
  overscroll-behavior: contain;
87
89
  padding: 6px 14px 18px;
@@ -302,10 +304,9 @@
302
304
  body.rnp-light .bncm-settings, body.rnp-auto.rnp-system-light .bncm-settings { box-shadow: 0 16px 44px rgba(0, 0, 0, .18), 0 0 0 .5px rgba(0, 0, 0, .12); }
303
305
  body.rnp-light .bncm-set-danger, body.rnp-auto.rnp-system-light .bncm-set-danger { color: rgb(215, 0, 21) !important; }
304
306
 
305
- /* small windows: the sidebar keeps only its icons */
306
- @media (max-width: 600px) {
307
- .bncm-set-side { width: 48px; padding: 12px 6px; }
308
- .bncm-set-tab { justify-content: center; padding: 0; }
307
+ /* narrow windows: the tabs keep only their icons */
308
+ @media (max-width: 480px) {
309
+ .bncm-settings .bncm-set-tab { padding: 0 9px; }
309
310
  .bncm-set-tab span { display: none; }
310
311
  }
311
312
  @media (prefers-reduced-motion: reduce) {
@@ -103,7 +103,7 @@ const GROUPS = [
103
103
  ],
104
104
  },
105
105
  {
106
- id: 'cover', label: '封面与信息', sections: [
106
+ id: 'cover', label: '封面与信息', tab: '封面', sections: [
107
107
  {
108
108
  title: '封面', rows: [
109
109
  { type: 'seg', k: 'coverShape', label: '形状', options: SEG([['square', '方形'], ['round', '圆形']]) },
@@ -137,6 +137,7 @@ const GROUPS = [
137
137
  { type: 'info', label: '视觉设计', value: `RefinedNowPlayingNext ${RNPN_VERSION}` },
138
138
  { type: 'info', label: '作者', value: 'MiHN' },
139
139
  { type: 'info', label: '原作者', value: 'solstice23' },
140
+ { type: 'info', label: '性能与视觉优化', value: 'OyangDer' },
140
141
  { type: 'note', text: '歌词窗口沿用 RefinedNowPlayingNext 的界面设计(MIT 许可),以更省电的方式重新实现。' },
141
142
  ],
142
143
  },
@@ -161,7 +162,7 @@ let side = null;
161
162
  let main = null;
162
163
  let isOpen = false;
163
164
  let groupId = 'lyrics';
164
- let jumpUntil = 0; // while a jump scrolls, the sidebar keeps the group it was sent to
165
+ let jumpUntil = 0; // while a jump scrolls, the tab bar keeps the group it was sent to
165
166
  let swallowTimer = 0;
166
167
  const syncs = [];
167
168
  const S = () => state.settings || DEFAULTS;
@@ -541,12 +542,12 @@ function build() {
541
542
  root.hidden = true;
542
543
  root.setAttribute('role', 'dialog');
543
544
  root.setAttribute('aria-label', '设置');
544
- // every group in one scrolling column; the sidebar jumps to one and follows the scroll
545
+ // every group in one scrolling column; the tab bar above jumps to one and follows the scroll
545
546
  side = el('nav', 'bncm-set-side');
546
547
  side.setAttribute('aria-label', '设置分类');
547
548
  main = el('div', 'bncm-set-main');
548
549
  for (const g of GROUPS) {
549
- const tab = button('bncm-set-tab', `${ICONS[g.id]}<span>${g.label}</span>`);
550
+ const tab = button('bncm-set-tab', `${ICONS[g.id]}<span>${g.tab || g.label}</span>`);
550
551
  tab.dataset.g = g.id;
551
552
  tab.addEventListener('click', () => jumpTo(g.id));
552
553
  side.append(tab);
@@ -599,6 +600,8 @@ function markGroup(id) {
599
600
  const on = t.dataset.g === id;
600
601
  t.classList.toggle('on', on);
601
602
  if (on) t.setAttribute('aria-current', 'true'); else t.removeAttribute('aria-current');
603
+ // a bar too narrow for every tab scrolls the marked one into view
604
+ if (on && side.scrollWidth > side.clientWidth) t.scrollIntoView({ block: 'nearest', inline: 'nearest' });
602
605
  }
603
606
  }
604
607
 
@@ -438,7 +438,8 @@ function addDislike(collapse) {
438
438
  btn.setAttribute('aria-label', '减少推荐');
439
439
  // NCM's dislike opens a modal inside its own window, which this one covers
440
440
  btn.addEventListener('click', (e) => { e.stopPropagation(); send('dislike'); collapse(); });
441
- els.controls.append(btn);
441
+ // in the play mode's place, which roaming has no use for (compat.css swaps the two)
442
+ els.mode.after(btn);
442
443
  watch('dislikeIcon', (svg) => { btn.replaceChildren(...[safeSvg(svg)].filter(Boolean)); });
443
444
  }
444
445