dsh-music-player 0.2.1 → 0.2.2

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.
Files changed (2) hide show
  1. package/lib/client.js +30 -7
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -321,15 +321,30 @@ window.__ModuleLoader__.load({
321
321
  const smoothCur = new Float32Array(SMOOTH_BARS);
322
322
  const smoothPeak = new Float32Array(SMOOTH_BARS);
323
323
  const targetBuf = new Float32Array(SMOOTH_BARS);
324
- // Accent color for the spectrum bars, read from the theme-derived
325
- // --dsh-music-accent (see PLAYER_CSS), cached once.
324
+ // Accent color for the spectrum bars. DSH defines its --dsw-alias-* theme
325
+ // tokens on <body> — never on :root — so --dsh-music-accent must be read
326
+ // from body (reading documentElement would always return the fallback and
327
+ // the bars would never follow the theme). The value is cached but the cache
328
+ // is invalidated whenever the theme changes at runtime: the ThemePresenter
329
+ // projects tokens + the dark attribute onto body, so a MutationObserver on
330
+ // body's style/dark-attribute keeps the bars tracking live brand changes.
326
331
  let accentColor = null;
332
+ let accentObserver = null;
333
+ function readAccent() {
334
+ const el = document.body || document.documentElement;
335
+ return getComputedStyle(el).getPropertyValue('--dsh-music-accent').trim() || '#2f9e6e';
336
+ }
327
337
  function currentAccent() {
328
- if (accentColor === null) {
329
- accentColor = getComputedStyle(document.documentElement).getPropertyValue('--dsh-music-accent').trim() || '#2f9e6e';
330
- }
338
+ if (accentColor === null) accentColor = readAccent();
331
339
  return accentColor;
332
340
  }
341
+ function watchAccent() {
342
+ if (accentObserver !== null) return accentObserver;
343
+ if (typeof MutationObserver === 'undefined') return null;
344
+ accentObserver = new MutationObserver(() => { accentColor = readAccent(); });
345
+ accentObserver.observe(document.body, { attributes: true, attributeFilter: ['style', 'data-ds-dark-theme'] });
346
+ return accentObserver;
347
+ }
333
348
  function drawBars(canvas, useCaps) {
334
349
  const c = canvas.getContext('2d');
335
350
  const w = canvas.width; const h = canvas.height;
@@ -1648,6 +1663,7 @@ window.__ModuleLoader__.load({
1648
1663
  attachAudioElements();
1649
1664
  const unbind = bindAudio();
1650
1665
  startRaf();
1666
+ const accentWatch = watchAccent();
1651
1667
  // Browsers auto-release a wake lock when the page is hidden; re-acquire
1652
1668
  // on return if playback is still running, and drop it on hide so we
1653
1669
  // don't hold it while the tab is backgrounded.
@@ -1667,6 +1683,8 @@ window.__ModuleLoader__.load({
1667
1683
  return () => {
1668
1684
  window.removeEventListener('pagehide', onPageHide);
1669
1685
  document.removeEventListener('visibilitychange', onVis); stopRaf(); unbind(); closeDecodeCtx(); releaseWakeLock();
1686
+ if (accentWatch !== null) accentWatch.disconnect();
1687
+ accentObserver = null;
1670
1688
  };
1671
1689
  }, 'music-player: audio + viz engine');
1672
1690
 
@@ -1740,8 +1758,13 @@ window.__ModuleLoader__.load({
1740
1758
  const PLAYER_CSS = '\n' +
1741
1759
  // Accent follows the host app's theme brand color (stable from the start —
1742
1760
  // no green-default-to-sampled-blue flash); green is only the fallback when
1743
- // the app exposes no brand color.
1744
- ':root { --dsh-music-accent: var(--dsw-alias-brand-primary, #2f9e6e); }\n' +
1761
+ // the app exposes no brand color. The alias must be declared on BODY, not
1762
+ // :root: DSH defines its --dsw-alias-* theme tokens on <body> only, and a
1763
+ // var() reference resolves against the element that declares it — on
1764
+ // :root (html) it cannot see body's tokens and would always fall back to
1765
+ // green. Declared on body, the reference resolves and children inherit
1766
+ // the theme's actual brand color.
1767
+ 'body { --dsh-music-accent: var(--dsw-alias-brand-primary, #2f9e6e); }\n' +
1745
1768
  '.dsh-music-bar-wrap { box-sizing: border-box; width: 100%; padding: 0 var(--dsh-composer-side-clearance, 16px); }\n' +
1746
1769
  '.dsh-music-bar { box-sizing: border-box; display: flex; align-items: center; gap: 8px; width: 100%; max-width: var(--dsh-composer-card-max-width, 780px); margin: 0 auto; padding: 4px 10px; font-size: 12px; color: var(--dsw-alias-label-secondary, #8a8f98); background: var(--dsw-alias-bg-layer-1, rgba(0,0,0,0.04)); border: 1px solid var(--dsw-alias-border-l1, rgba(128,128,128,0.2)); border-radius: 8px; }\n' +
1747
1770
  '.dsh-music-bar-idle { color: var(--dsw-alias-label-primary, #e6e6e6); font-weight: 500; display: inline-flex; align-items: center; }\n' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-music-player",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "DeepSeek Harness 本地音乐 + AI 讲书插件:Host 扫描音乐目录并以 HTTP 流式提供音频、解析 .txt 小说结构并经 MiMo TTS 合成朗读,浏览器侧提供播放条/播放面板/章节目录跳转/多声音选择/实时频谱,并注册 music_play 模型工具",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",